summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/mmc_spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/mmc_spi.c')
-rw-r--r--drivers/mmc/host/mmc_spi.c397
1 files changed, 104 insertions, 293 deletions
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 10ba46b728e8..42936e248c55 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * mmc_spi.c - Access SD/MMC cards through SPI master controllers
+ * Access SD/MMC cards through SPI master controllers
*
* (C) Copyright 2005, Intec Automation,
* Mike Lavender (mike@steroidmicros)
@@ -8,28 +9,12 @@
* Hans-Peter Nilsson (hp@axis.com)
* (C) Copyright 2007, ATRON electronic GmbH,
* Jan Nikitenko <jan.nikitenko@gmail.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/bio.h>
-#include <linux/dma-mapping.h>
#include <linux/crc7.h>
#include <linux/crc-itu-t.h>
#include <linux/scatterlist.h>
@@ -41,7 +26,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/mmc_spi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
/* NOTES:
@@ -91,14 +76,8 @@
#define MMC_SPI_BLOCKSIZE 512
-
-/* These fixed timeouts come from the latest SD specs, which say to ignore
- * the CSD values. The R1B value is for card erase (e.g. the "I forgot the
- * card's password" scenario); it's mostly applied to STOP_TRANSMISSION after
- * reads which takes nowhere near that long. Older cards may be able to use
- * shorter timeouts ... but why bother?
- */
-#define r1b_timeout (HZ * 3)
+#define MMC_SPI_R1B_TIMEOUT_MS 3000
+#define MMC_SPI_INIT_TIMEOUT_MS 3000
/* One of the critical speed parameters is the amount of data which may
* be transferred in one command. If this value is too low, the SD card
@@ -139,19 +118,14 @@ struct mmc_spi_host {
struct spi_transfer status;
struct spi_message readback;
- /* underlying DMA-aware controller, or null */
- struct device *dma_dev;
-
/* buffer used for commands and for message "overhead" */
struct scratch *data;
- dma_addr_t data_dma;
/* Specs say to write ones most of the time, even when the card
* has no need to read its input data; and many cards won't care.
* This is our source of those ones.
*/
void *ones;
- dma_addr_t ones_dma;
};
@@ -167,11 +141,8 @@ static inline int mmc_cs_off(struct mmc_spi_host *host)
return spi_setup(host->spi);
}
-static int
-mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len)
+static int mmc_spi_readbytes(struct mmc_spi_host *host, unsigned int len)
{
- int status;
-
if (len > sizeof(*host->data)) {
WARN_ON(1);
return -EIO;
@@ -179,28 +150,16 @@ mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len)
host->status.len = len;
- if (host->dma_dev)
- dma_sync_single_for_device(host->dma_dev,
- host->data_dma, sizeof(*host->data),
- DMA_FROM_DEVICE);
-
- status = spi_sync_locked(host->spi, &host->readback);
-
- if (host->dma_dev)
- dma_sync_single_for_cpu(host->dma_dev,
- host->data_dma, sizeof(*host->data),
- DMA_FROM_DEVICE);
-
- return status;
+ return spi_sync_locked(host->spi, &host->readback);
}
static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout,
unsigned n, u8 byte)
{
- u8 *cp = host->data->status;
+ u8 *cp = host->data->status;
unsigned long start = jiffies;
- while (1) {
+ do {
int status;
unsigned i;
@@ -213,16 +172,9 @@ static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout,
return cp[i];
}
- if (time_is_before_jiffies(start + timeout))
- break;
-
- /* If we need long timeouts, we may release the CPU.
- * We use jiffies here because we want to have a relation
- * between elapsed time and the blocking of the scheduler.
- */
- if (time_is_before_jiffies(start+1))
- schedule();
- }
+ /* If we need long timeouts, we may release the CPU */
+ cond_resched();
+ } while (time_is_after_jiffies(start + timeout));
return -ETIMEDOUT;
}
@@ -262,6 +214,7 @@ static char *maptype(struct mmc_command *cmd)
static int mmc_spi_response_get(struct mmc_spi_host *host,
struct mmc_command *cmd, int cs_on)
{
+ unsigned long timeout_ms;
u8 *cp = host->data->status;
u8 *end = cp + host->t.len;
int value = 0;
@@ -269,10 +222,6 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
u8 leftover = 0;
unsigned short rotator;
int i;
- char tag[32];
-
- snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s",
- cmd->opcode, maptype(cmd));
/* Except for data block reads, the whole response will already
* be stored in the scratch buffer. It's somewhere after the
@@ -360,8 +309,11 @@ checkstatus:
/* maybe we read all the busy tokens already */
while (cp < end && *cp == 0)
cp++;
- if (cp == end)
- mmc_spi_wait_unbusy(host, r1b_timeout);
+ if (cp == end) {
+ timeout_ms = cmd->busy_timeout ? cmd->busy_timeout :
+ MMC_SPI_R1B_TIMEOUT_MS;
+ mmc_spi_wait_unbusy(host, msecs_to_jiffies(timeout_ms));
+ }
break;
/* SPI R2 == R1 + second status byte; SEND_STATUS
@@ -415,15 +367,16 @@ checkstatus:
default:
dev_dbg(&host->spi->dev, "bad response type %04x\n",
- mmc_spi_resp_type(cmd));
+ mmc_spi_resp_type(cmd));
if (value >= 0)
value = -EINVAL;
goto done;
}
if (value < 0)
- dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n",
- tag, cmd->resp[0], cmd->resp[1]);
+ dev_dbg(&host->spi->dev,
+ " ... CMD%d response SPI_%s: resp %04x %08x\n",
+ cmd->opcode, maptype(cmd), cmd->resp[0], cmd->resp[1]);
/* disable chipselect on errors and some success cases */
if (value >= 0 && cs_on)
@@ -467,8 +420,8 @@ mmc_spi_command_send(struct mmc_spi_host *host,
memset(cp, 0xff, sizeof(data->status));
cp[1] = 0x40 | cmd->opcode;
- put_unaligned_be32(cmd->arg, cp+2);
- cp[6] = crc7_be(0, cp+1, 5) | 0x01;
+ put_unaligned_be32(cmd->arg, cp + 2);
+ cp[6] = crc7_be(0, cp + 1, 5) | 0x01;
cp += 7;
/* Then, read up to 13 bytes (while writing all-ones):
@@ -520,7 +473,7 @@ mmc_spi_command_send(struct mmc_spi_host *host,
/* else: R1 (most commands) */
}
- dev_dbg(&host->spi->dev, " mmc_spi: CMD%d, resp %s\n",
+ dev_dbg(&host->spi->dev, " CMD%d, resp %s\n",
cmd->opcode, maptype(cmd));
/* send command, leaving chipselect active */
@@ -529,23 +482,11 @@ mmc_spi_command_send(struct mmc_spi_host *host,
t = &host->t;
memset(t, 0, sizeof(*t));
t->tx_buf = t->rx_buf = data->status;
- t->tx_dma = t->rx_dma = host->data_dma;
t->len = cp - data->status;
t->cs_change = 1;
spi_message_add_tail(t, &host->m);
- if (host->dma_dev) {
- host->m.is_dma_mapped = 1;
- dma_sync_single_for_device(host->dma_dev,
- host->data_dma, sizeof(*host->data),
- DMA_BIDIRECTIONAL);
- }
status = spi_sync_locked(host->spi, &host->m);
-
- if (host->dma_dev)
- dma_sync_single_for_cpu(host->dma_dev,
- host->data_dma, sizeof(*host->data),
- DMA_BIDIRECTIONAL);
if (status < 0) {
dev_dbg(&host->spi->dev, " ... write returned %d\n", status);
cmd->error = status;
@@ -563,28 +504,19 @@ mmc_spi_command_send(struct mmc_spi_host *host,
* We always provide TX data for data and CRC. The MMC/SD protocol
* requires us to write ones; but Linux defaults to writing zeroes;
* so we explicitly initialize it to all ones on RX paths.
- *
- * We also handle DMA mapping, so the underlying SPI controller does
- * not need to (re)do it for each message.
*/
static void
-mmc_spi_setup_data_message(
- struct mmc_spi_host *host,
- int multiple,
- enum dma_data_direction direction)
+mmc_spi_setup_data_message(struct mmc_spi_host *host, bool multiple, bool write)
{
struct spi_transfer *t;
struct scratch *scratch = host->data;
- dma_addr_t dma = host->data_dma;
spi_message_init(&host->m);
- if (dma)
- host->m.is_dma_mapped = 1;
/* for reads, readblock() skips 0xff bytes before finding
* the token; for writes, this transfer issues that token.
*/
- if (direction == DMA_TO_DEVICE) {
+ if (write) {
t = &host->token;
memset(t, 0, sizeof(*t));
t->len = 1;
@@ -593,8 +525,6 @@ mmc_spi_setup_data_message(
else
scratch->data_token = SPI_TOKEN_SINGLE;
t->tx_buf = &scratch->data_token;
- if (dma)
- t->tx_dma = dma + offsetof(struct scratch, data_token);
spi_message_add_tail(t, &host->m);
}
@@ -604,24 +534,18 @@ mmc_spi_setup_data_message(
t = &host->t;
memset(t, 0, sizeof(*t));
t->tx_buf = host->ones;
- t->tx_dma = host->ones_dma;
/* length and actual buffer info are written later */
spi_message_add_tail(t, &host->m);
t = &host->crc;
memset(t, 0, sizeof(*t));
t->len = 2;
- if (direction == DMA_TO_DEVICE) {
+ if (write) {
/* the actual CRC may get written later */
t->tx_buf = &scratch->crc_val;
- if (dma)
- t->tx_dma = dma + offsetof(struct scratch, crc_val);
} else {
t->tx_buf = host->ones;
- t->tx_dma = host->ones_dma;
t->rx_buf = &scratch->crc_val;
- if (dma)
- t->rx_dma = dma + offsetof(struct scratch, crc_val);
}
spi_message_add_tail(t, &host->m);
@@ -639,17 +563,12 @@ mmc_spi_setup_data_message(
* the next token (next data block, or STOP_TRAN). We can try to
* minimize I/O ops by using a single read to collect end-of-busy.
*/
- if (multiple || direction == DMA_TO_DEVICE) {
+ if (write) {
t = &host->early_status;
memset(t, 0, sizeof(*t));
- t->len = (direction == DMA_TO_DEVICE)
- ? sizeof(scratch->status)
- : 1;
+ t->len = sizeof(scratch->status);
t->tx_buf = host->ones;
- t->tx_dma = host->ones_dma;
t->rx_buf = scratch->status;
- if (dma)
- t->rx_dma = dma + offsetof(struct scratch, status);
t->cs_change = 1;
spi_message_add_tail(t, &host->m);
}
@@ -677,25 +596,14 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
u32 pattern;
if (host->mmc->use_spi_crc)
- scratch->crc_val = cpu_to_be16(
- crc_itu_t(0, t->tx_buf, t->len));
- if (host->dma_dev)
- dma_sync_single_for_device(host->dma_dev,
- host->data_dma, sizeof(*scratch),
- DMA_BIDIRECTIONAL);
+ scratch->crc_val = cpu_to_be16(crc_itu_t(0, t->tx_buf, t->len));
status = spi_sync_locked(spi, &host->m);
-
if (status != 0) {
dev_dbg(&spi->dev, "write error (%d)\n", status);
return status;
}
- if (host->dma_dev)
- dma_sync_single_for_cpu(host->dma_dev,
- host->data_dma, sizeof(*scratch),
- DMA_BIDIRECTIONAL);
-
/*
* Get the transmission data-response reply. It must follow
* immediately after the data block we transferred. This reply
@@ -744,8 +652,6 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
}
t->tx_buf += t->len;
- if (host->dma_dev)
- t->tx_dma += t->len;
/* Return when not busy. If we didn't collect that status yet,
* we'll need some more I/O.
@@ -809,24 +715,10 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
}
leftover = status << 1;
- if (host->dma_dev) {
- dma_sync_single_for_device(host->dma_dev,
- host->data_dma, sizeof(*scratch),
- DMA_BIDIRECTIONAL);
- dma_sync_single_for_device(host->dma_dev,
- t->rx_dma, t->len,
- DMA_FROM_DEVICE);
- }
-
status = spi_sync_locked(spi, &host->m);
-
- if (host->dma_dev) {
- dma_sync_single_for_cpu(host->dma_dev,
- host->data_dma, sizeof(*scratch),
- DMA_BIDIRECTIONAL);
- dma_sync_single_for_cpu(host->dma_dev,
- t->rx_dma, t->len,
- DMA_FROM_DEVICE);
+ if (status < 0) {
+ dev_dbg(&spi->dev, "read error %d\n", status);
+ return status;
}
if (bitshift) {
@@ -855,16 +747,14 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
be16_to_cpus(&scratch->crc_val);
if (scratch->crc_val != crc) {
- dev_dbg(&spi->dev, "read - crc error: crc_val=0x%04x, "
- "computed=0x%04x len=%d\n",
- scratch->crc_val, crc, t->len);
+ dev_dbg(&spi->dev,
+ "read - crc error: crc_val=0x%04x, computed=0x%04x len=%d\n",
+ scratch->crc_val, crc, t->len);
return -EILSEQ;
}
}
t->rx_buf += t->len;
- if (host->dma_dev)
- t->rx_dma += t->len;
return 0;
}
@@ -879,17 +769,16 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
struct mmc_data *data, u32 blk_size)
{
struct spi_device *spi = host->spi;
- struct device *dma_dev = host->dma_dev;
struct spi_transfer *t;
- enum dma_data_direction direction;
struct scatterlist *sg;
unsigned n_sg;
- int multiple = (data->blocks > 1);
+ bool multiple = (data->blocks > 1);
+ bool write = (data->flags & MMC_DATA_WRITE);
+ const char *write_or_read = write ? "write" : "read";
u32 clock_rate;
unsigned long timeout;
- direction = mmc_get_dma_dir(data);
- mmc_spi_setup_data_message(host, multiple, direction);
+ mmc_spi_setup_data_message(host, multiple, write);
t = &host->t;
if (t->speed_hz)
@@ -897,44 +786,21 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
else
clock_rate = spi->max_speed_hz;
- timeout = data->timeout_ns +
+ timeout = data->timeout_ns / 1000 +
data->timeout_clks * 1000000 / clock_rate;
- timeout = usecs_to_jiffies((unsigned int)(timeout / 1000)) + 1;
+ timeout = usecs_to_jiffies((unsigned int)timeout) + 1;
/* Handle scatterlist segments one at a time, with synch for
* each 512-byte block
*/
- for (sg = data->sg, n_sg = data->sg_len; n_sg; n_sg--, sg++) {
+ for_each_sg(data->sg, sg, data->sg_len, n_sg) {
int status = 0;
- dma_addr_t dma_addr = 0;
void *kmap_addr;
unsigned length = sg->length;
- enum dma_data_direction dir = direction;
-
- /* set up dma mapping for controller drivers that might
- * use DMA ... though they may fall back to PIO
- */
- if (dma_dev) {
- /* never invalidate whole *shared* pages ... */
- if ((sg->offset != 0 || length != PAGE_SIZE)
- && dir == DMA_FROM_DEVICE)
- dir = DMA_BIDIRECTIONAL;
-
- dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
- PAGE_SIZE, dir);
- if (dma_mapping_error(dma_dev, dma_addr)) {
- data->error = -EFAULT;
- break;
- }
- if (direction == DMA_TO_DEVICE)
- t->tx_dma = dma_addr + sg->offset;
- else
- t->rx_dma = dma_addr + sg->offset;
- }
/* allow pio too; we don't allow highmem */
kmap_addr = kmap(sg_page(sg));
- if (direction == DMA_TO_DEVICE)
+ if (write)
t->tx_buf = kmap_addr + sg->offset;
else
t->rx_buf = kmap_addr + sg->offset;
@@ -943,14 +809,9 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
while (length) {
t->len = min(length, blk_size);
- dev_dbg(&host->spi->dev,
- " mmc_spi: %s block, %d bytes\n",
- (direction == DMA_TO_DEVICE)
- ? "write"
- : "read",
- t->len);
+ dev_dbg(&spi->dev, " %s block, %d bytes\n", write_or_read, t->len);
- if (direction == DMA_TO_DEVICE)
+ if (write)
status = mmc_spi_writeblock(host, t, timeout);
else
status = mmc_spi_readblock(host, t, timeout);
@@ -965,18 +826,15 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
}
/* discard mappings */
- if (direction == DMA_FROM_DEVICE)
- flush_kernel_dcache_page(sg_page(sg));
+ if (write)
+ /* nothing to do */;
+ else
+ flush_dcache_page(sg_page(sg));
kunmap(sg_page(sg));
- if (dma_dev)
- dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
if (status < 0) {
data->error = status;
- dev_dbg(&spi->dev, "%s status %d\n",
- (direction == DMA_TO_DEVICE)
- ? "write" : "read",
- status);
+ dev_dbg(&spi->dev, "%s status %d\n", write_or_read, status);
break;
}
}
@@ -987,12 +845,12 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
* that can affect the STOP_TRAN logic. Complete (and current)
* MMC specs should sort that out before Linux starts using CMD23.
*/
- if (direction == DMA_TO_DEVICE && multiple) {
+ if (write && multiple) {
struct scratch *scratch = host->data;
int tmp;
const unsigned statlen = sizeof(scratch->status);
- dev_dbg(&spi->dev, " mmc_spi: STOP_TRAN\n");
+ dev_dbg(&spi->dev, " STOP_TRAN\n");
/* Tweak the per-block message we set up earlier by morphing
* it to hold single buffer with the token followed by some
@@ -1007,21 +865,9 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
scratch->status[0] = SPI_TOKEN_STOP_TRAN;
host->early_status.tx_buf = host->early_status.rx_buf;
- host->early_status.tx_dma = host->early_status.rx_dma;
host->early_status.len = statlen;
- if (host->dma_dev)
- dma_sync_single_for_device(host->dma_dev,
- host->data_dma, sizeof(*scratch),
- DMA_BIDIRECTIONAL);
-
tmp = spi_sync_locked(spi, &host->m);
-
- if (host->dma_dev)
- dma_sync_single_for_cpu(host->dma_dev,
- host->data_dma, sizeof(*scratch),
- DMA_BIDIRECTIONAL);
-
if (tmp < 0) {
if (!data->error)
data->error = tmp;
@@ -1084,7 +930,7 @@ static void mmc_spi_request(struct mmc_host *mmc, struct mmc_request *mrq)
#endif
/* request exclusive bus access */
- spi_bus_lock(host->spi->master);
+ spi_bus_lock(host->spi->controller);
crc_recover:
/* issue command; then optionally data and stop */
@@ -1116,7 +962,7 @@ crc_recover:
}
/* release the bus */
- spi_bus_unlock(host->spi->master);
+ spi_bus_unlock(host->spi->controller);
mmc_request_done(host->mmc, mrq);
}
@@ -1134,7 +980,7 @@ static void mmc_spi_initsequence(struct mmc_spi_host *host)
/* Try to be very sure any previous command has completed;
* wait till not-busy, skip debris from any old commands.
*/
- mmc_spi_wait_unbusy(host, r1b_timeout);
+ mmc_spi_wait_unbusy(host, msecs_to_jiffies(MMC_SPI_INIT_TIMEOUT_MS));
mmc_spi_readbytes(host, 10);
/*
@@ -1150,17 +996,22 @@ static void mmc_spi_initsequence(struct mmc_spi_host *host)
* SPI protocol. Another is that when chipselect is released while
* the card returns BUSY status, the clock must issue several cycles
* with chipselect high before the card will stop driving its output.
+ *
+ * SPI_CS_HIGH means "asserted" here. In some cases like when using
+ * GPIOs for chip select, SPI_CS_HIGH is set but this will be logically
+ * inverted by gpiolib, so if we want to ascertain to drive it high
+ * we should toggle the default with an XOR as we do here.
*/
- host->spi->mode |= SPI_CS_HIGH;
+ host->spi->mode ^= SPI_CS_HIGH;
if (spi_setup(host->spi) != 0) {
/* Just warn; most cards work without it. */
dev_warn(&host->spi->dev,
"can't change chip-select polarity\n");
- host->spi->mode &= ~SPI_CS_HIGH;
+ host->spi->mode ^= SPI_CS_HIGH;
} else {
mmc_spi_readbytes(host, 18);
- host->spi->mode &= ~SPI_CS_HIGH;
+ host->spi->mode ^= SPI_CS_HIGH;
if (spi_setup(host->spi) != 0) {
/* Wot, we can't get the same setup we had before? */
dev_err(&host->spi->dev,
@@ -1188,7 +1039,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
canpower = host->pdata && host->pdata->setpower;
- dev_dbg(&host->spi->dev, "mmc_spi: power %s (%d)%s\n",
+ dev_dbg(&host->spi->dev, "power %s (%d)%s\n",
mmc_powerstring(ios->power_mode),
ios->vdd,
canpower ? ", can switch" : "");
@@ -1249,8 +1100,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
mres = spi_setup(host->spi);
if (mres < 0)
dev_dbg(&host->spi->dev,
- "switch back to SPI mode 3"
- " failed\n");
+ "switch back to SPI mode 3 failed\n");
}
}
@@ -1262,8 +1112,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
host->spi->max_speed_hz = ios->clock;
status = spi_setup(host->spi);
- dev_dbg(&host->spi->dev,
- "mmc_spi: clock to %d Hz, %d\n",
+ dev_dbg(&host->spi->dev, " clock to %d Hz, %d\n",
host->spi->max_speed_hz, status);
}
}
@@ -1303,7 +1152,7 @@ static int mmc_spi_probe(struct spi_device *spi)
/* We rely on full duplex transfers, mostly to reduce
* per-transfer overheads (by making fewer transfers).
*/
- if (spi->master->flags & SPI_MASTER_HALF_DUPLEX)
+ if (spi->controller->flags & SPI_CONTROLLER_HALF_DUPLEX)
return -EINVAL;
/* MMC and SD specs only seem to care that sampling is on the
@@ -1336,7 +1185,7 @@ static int mmc_spi_probe(struct spi_device *spi)
goto nomem;
memset(ones, 0xff, MMC_SPI_BLOCKSIZE);
- mmc = mmc_alloc_host(sizeof(*host), &spi->dev);
+ mmc = devm_mmc_alloc_host(&spi->dev, sizeof(*host));
if (!mmc)
goto nomem;
@@ -1356,7 +1205,10 @@ static int mmc_spi_probe(struct spi_device *spi)
* that's the only reason not to use a few MHz for f_min (until
* the upper layer reads the target frequency from the CSD).
*/
- mmc->f_min = 400000;
+ if (spi->controller->min_speed_hz > 400000)
+ dev_warn(&spi->dev,"Controller unable to reduce bus clock to 400 KHz\n");
+
+ mmc->f_min = max(spi->controller->min_speed_hz, 400000);
mmc->f_max = spi->max_speed_hz;
host = mmc_priv(mmc);
@@ -1365,6 +1217,8 @@ static int mmc_spi_probe(struct spi_device *spi)
host->ones = ones;
+ dev_set_drvdata(&spi->dev, mmc);
+
/* Platform data is used to hook up things like card sensing
* and power switching gpios.
*/
@@ -1381,40 +1235,17 @@ static int mmc_spi_probe(struct spi_device *spi)
host->powerup_msecs = 250;
}
- dev_set_drvdata(&spi->dev, mmc);
-
- /* preallocate dma buffers */
+ /* Preallocate buffers */
host->data = kmalloc(sizeof(*host->data), GFP_KERNEL);
if (!host->data)
goto fail_nobuf1;
- if (spi->master->dev.parent->dma_mask) {
- struct device *dev = spi->master->dev.parent;
-
- host->dma_dev = dev;
- host->ones_dma = dma_map_single(dev, ones,
- MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
- if (dma_mapping_error(dev, host->ones_dma))
- goto fail_ones_dma;
- host->data_dma = dma_map_single(dev, host->data,
- sizeof(*host->data), DMA_BIDIRECTIONAL);
- if (dma_mapping_error(dev, host->data_dma))
- goto fail_data_dma;
-
- dma_sync_single_for_cpu(host->dma_dev,
- host->data_dma, sizeof(*host->data),
- DMA_BIDIRECTIONAL);
- }
-
/* setup message for status/busy readback */
spi_message_init(&host->readback);
- host->readback.is_dma_mapped = (host->dma_dev != NULL);
spi_message_add_tail(&host->status, &host->readback);
host->status.tx_buf = host->ones;
- host->status.tx_dma = host->ones_dma;
host->status.rx_buf = &host->data->status;
- host->status.rx_dma = host->data_dma + offsetof(struct scratch, status);
host->status.cs_change = 1;
/* register card detect irq */
@@ -1432,15 +1263,15 @@ static int mmc_spi_probe(struct spi_device *spi)
status = mmc_add_host(mmc);
if (status != 0)
- goto fail_add_host;
+ goto fail_glue_init;
/*
* Index 0 is card detect
* Old boardfiles were specifying 1 ms as debounce
*/
- status = mmc_gpiod_request_cd(mmc, NULL, 0, false, 1, NULL);
+ status = mmc_gpiod_request_cd(mmc, NULL, 0, false, 1000);
if (status == -EPROBE_DEFER)
- goto fail_add_host;
+ goto fail_gpiod_request;
if (!status) {
/*
* The platform has a CD GPIO signal that may support
@@ -1450,17 +1281,17 @@ static int mmc_spi_probe(struct spi_device *spi)
mmc->caps &= ~MMC_CAP_NEEDS_POLL;
mmc_gpiod_request_cd_irq(mmc);
}
+ mmc_detect_change(mmc, 0);
/* Index 1 is write protect/read only */
- status = mmc_gpiod_request_ro(mmc, NULL, 1, false, 0, NULL);
+ status = mmc_gpiod_request_ro(mmc, NULL, 1, 0);
if (status == -EPROBE_DEFER)
- goto fail_add_host;
+ goto fail_gpiod_request;
if (!status)
has_ro = true;
- dev_info(&spi->dev, "SD/MMC host %s%s%s%s%s\n",
+ dev_info(&spi->dev, "SD/MMC host %s%s%s%s\n",
dev_name(&mmc->class_dev),
- host->dma_dev ? "" : ", no DMA",
has_ro ? "" : ", no WP",
(host->pdata && host->pdata->setpower)
? "" : ", no poweroff",
@@ -1468,62 +1299,42 @@ static int mmc_spi_probe(struct spi_device *spi)
? ", cd polling" : "");
return 0;
-fail_add_host:
- mmc_remove_host (mmc);
+fail_gpiod_request:
+ mmc_remove_host(mmc);
fail_glue_init:
- if (host->dma_dev)
- dma_unmap_single(host->dma_dev, host->data_dma,
- sizeof(*host->data), DMA_BIDIRECTIONAL);
-fail_data_dma:
- if (host->dma_dev)
- dma_unmap_single(host->dma_dev, host->ones_dma,
- MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
-fail_ones_dma:
kfree(host->data);
-
fail_nobuf1:
- mmc_free_host(mmc);
mmc_spi_put_pdata(spi);
- dev_set_drvdata(&spi->dev, NULL);
-
nomem:
kfree(ones);
return status;
}
-static int mmc_spi_remove(struct spi_device *spi)
+static void mmc_spi_remove(struct spi_device *spi)
{
struct mmc_host *mmc = dev_get_drvdata(&spi->dev);
- struct mmc_spi_host *host;
-
- if (mmc) {
- host = mmc_priv(mmc);
-
- /* prevent new mmc_detect_change() calls */
- if (host->pdata && host->pdata->exit)
- host->pdata->exit(&spi->dev, mmc);
+ struct mmc_spi_host *host = mmc_priv(mmc);
- mmc_remove_host(mmc);
+ /* prevent new mmc_detect_change() calls */
+ if (host->pdata && host->pdata->exit)
+ host->pdata->exit(&spi->dev, mmc);
- if (host->dma_dev) {
- dma_unmap_single(host->dma_dev, host->ones_dma,
- MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
- dma_unmap_single(host->dma_dev, host->data_dma,
- sizeof(*host->data), DMA_BIDIRECTIONAL);
- }
+ mmc_remove_host(mmc);
- kfree(host->data);
- kfree(host->ones);
+ kfree(host->data);
+ kfree(host->ones);
- spi->max_speed_hz = mmc->f_max;
- mmc_free_host(mmc);
- mmc_spi_put_pdata(spi);
- dev_set_drvdata(&spi->dev, NULL);
- }
- return 0;
+ spi->max_speed_hz = mmc->f_max;
+ mmc_spi_put_pdata(spi);
}
+static const struct spi_device_id mmc_spi_dev_ids[] = {
+ { "mmc-spi-slot"},
+ { },
+};
+MODULE_DEVICE_TABLE(spi, mmc_spi_dev_ids);
+
static const struct of_device_id mmc_spi_of_match_table[] = {
{ .compatible = "mmc-spi-slot", },
{},
@@ -1535,14 +1346,14 @@ static struct spi_driver mmc_spi_driver = {
.name = "mmc_spi",
.of_match_table = mmc_spi_of_match_table,
},
+ .id_table = mmc_spi_dev_ids,
.probe = mmc_spi_probe,
.remove = mmc_spi_remove,
};
module_spi_driver(mmc_spi_driver);
-MODULE_AUTHOR("Mike Lavender, David Brownell, "
- "Hans-Peter Nilsson, Jan Nikitenko");
+MODULE_AUTHOR("Mike Lavender, David Brownell, Hans-Peter Nilsson, Jan Nikitenko");
MODULE_DESCRIPTION("SPI SD/MMC host driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("spi:mmc_spi");