summaryrefslogtreecommitdiff
path: root/target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch')
-rw-r--r--target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch143
1 files changed, 143 insertions, 0 deletions
diff --git a/target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch b/target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch
new file mode 100644
index 0000000000..d6ad3d4e9b
--- /dev/null
+++ b/target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch
@@ -0,0 +1,143 @@
+From 4751c1c74bc7b596db5de0c93be1a22a570145c0 Mon Sep 17 00:00:00 2001
+From: Ernst Schwab <eschwab@online.de>
+Date: Thu, 18 Feb 2010 12:47:46 +0100
+Subject: [PATCH] spi/mmc_spi: mmc_spi adaptations for SPI bus locking API
+
+Modification of the mmc_spi driver to use the SPI bus locking API.
+With this, the mmc_spi driver can be used together with other SPI
+devices on the same SPI bus. The exclusive access to the SPI bus is
+now managed in the SPI layer. The counting of chip selects in the probe
+function is no longer needed.
+
+Signed-off-by: Ernst Schwab <eschwab@online.de>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Tested-by: Matt Fleming <matt@console-pimps.org>
+Tested-by: Antonio Ospite <ospite@studenti.unina.it>
+---
+ drivers/mmc/host/mmc_spi.c | 59 ++++++++-----------------------------------
+ 1 files changed, 11 insertions(+), 48 deletions(-)
+
+--- a/drivers/mmc/host/mmc_spi.c
++++ b/drivers/mmc/host/mmc_spi.c
+@@ -182,7 +182,7 @@ mmc_spi_readbytes(struct mmc_spi_host *h
+ host->data_dma, sizeof(*host->data),
+ DMA_FROM_DEVICE);
+
+- status = spi_sync(host->spi, &host->readback);
++ status = spi_sync_locked(host->spi, &host->readback);
+
+ if (host->dma_dev)
+ dma_sync_single_for_cpu(host->dma_dev,
+@@ -541,7 +541,7 @@ mmc_spi_command_send(struct mmc_spi_host
+ host->data_dma, sizeof(*host->data),
+ DMA_BIDIRECTIONAL);
+ }
+- status = spi_sync(host->spi, &host->m);
++ status = spi_sync_locked(host->spi, &host->m);
+
+ if (host->dma_dev)
+ dma_sync_single_for_cpu(host->dma_dev,
+@@ -685,7 +685,7 @@ mmc_spi_writeblock(struct mmc_spi_host *
+ host->data_dma, sizeof(*scratch),
+ DMA_BIDIRECTIONAL);
+
+- status = spi_sync(spi, &host->m);
++ status = spi_sync_locked(spi, &host->m);
+
+ if (status != 0) {
+ dev_dbg(&spi->dev, "write error (%d)\n", status);
+@@ -822,7 +822,7 @@ mmc_spi_readblock(struct mmc_spi_host *h
+ DMA_FROM_DEVICE);
+ }
+
+- status = spi_sync(spi, &host->m);
++ status = spi_sync_locked(spi, &host->m);
+
+ if (host->dma_dev) {
+ dma_sync_single_for_cpu(host->dma_dev,
+@@ -1018,7 +1018,7 @@ mmc_spi_data_do(struct mmc_spi_host *hos
+ host->data_dma, sizeof(*scratch),
+ DMA_BIDIRECTIONAL);
+
+- tmp = spi_sync(spi, &host->m);
++ tmp = spi_sync_locked(spi, &host->m);
+
+ if (host->dma_dev)
+ dma_sync_single_for_cpu(host->dma_dev,
+@@ -1084,6 +1084,9 @@ static void mmc_spi_request(struct mmc_h
+ }
+ #endif
+
++ /* request exclusive bus access */
++ spi_bus_lock(host->spi->master);
++
+ /* issue command; then optionally data and stop */
+ status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL);
+ if (status == 0 && mrq->data) {
+@@ -1094,6 +1097,9 @@ static void mmc_spi_request(struct mmc_h
+ mmc_cs_off(host);
+ }
+
++ /* release the bus */
++ spi_bus_unlock(host->spi->master);
++
+ mmc_request_done(host->mmc, mrq);
+ }
+
+@@ -1290,23 +1296,6 @@ mmc_spi_detect_irq(int irq, void *mmc)
+ return IRQ_HANDLED;
+ }
+
+-struct count_children {
+- unsigned n;
+- struct bus_type *bus;
+-};
+-
+-static int maybe_count_child(struct device *dev, void *c)
+-{
+- struct count_children *ccp = c;
+-
+- if (dev->bus == ccp->bus) {
+- if (ccp->n)
+- return -EBUSY;
+- ccp->n++;
+- }
+- return 0;
+-}
+-
+ static int mmc_spi_probe(struct spi_device *spi)
+ {
+ void *ones;
+@@ -1338,32 +1327,6 @@ static int mmc_spi_probe(struct spi_devi
+ return status;
+ }
+
+- /* We can use the bus safely iff nobody else will interfere with us.
+- * Most commands consist of one SPI message to issue a command, then
+- * several more to collect its response, then possibly more for data
+- * transfer. Clocking access to other devices during that period will
+- * corrupt the command execution.
+- *
+- * Until we have software primitives which guarantee non-interference,
+- * we'll aim for a hardware-level guarantee.
+- *
+- * REVISIT we can't guarantee another device won't be added later...
+- */
+- if (spi->master->num_chipselect > 1) {
+- struct count_children cc;
+-
+- cc.n = 0;
+- cc.bus = spi->dev.bus;
+- status = device_for_each_child(spi->dev.parent, &cc,
+- maybe_count_child);
+- if (status < 0) {
+- dev_err(&spi->dev, "can't share SPI bus\n");
+- return status;
+- }
+-
+- dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n");
+- }
+-
+ /* We need a supply of ones to transmit. This is the only time
+ * the CPU touches these, so cache coherency isn't a concern.
+ *