ar71xx: UBNT Secondary MAC address duplicate fix
[openwrt.git] / target / linux / generic / patches-2.6.33 / 911-backport-mmc_spi-use-spi-bus-locking-api.patch
1 From 4751c1c74bc7b596db5de0c93be1a22a570145c0 Mon Sep 17 00:00:00 2001
2 From: Ernst Schwab <eschwab@online.de>
3 Date: Thu, 18 Feb 2010 12:47:46 +0100
4 Subject: [PATCH] spi/mmc_spi: mmc_spi adaptations for SPI bus locking API
5
6 Modification of the mmc_spi driver to use the SPI bus locking API.
7 With this, the mmc_spi driver can be used together with other SPI
8 devices on the same SPI bus. The exclusive access to the SPI bus is
9 now managed in the SPI layer. The counting of chip selects in the probe
10 function is no longer needed.
11
12 Signed-off-by: Ernst Schwab <eschwab@online.de>
13 Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
14 Tested-by: Matt Fleming <matt@console-pimps.org>
15 Tested-by: Antonio Ospite <ospite@studenti.unina.it>
16 ---
17  drivers/mmc/host/mmc_spi.c |   59 ++++++++-----------------------------------
18  1 files changed, 11 insertions(+), 48 deletions(-)
19
20 --- a/drivers/mmc/host/mmc_spi.c
21 +++ b/drivers/mmc/host/mmc_spi.c
22 @@ -181,7 +181,7 @@ mmc_spi_readbytes(struct mmc_spi_host *h
23                                 host->data_dma, sizeof(*host->data),
24                                 DMA_FROM_DEVICE);
25  
26 -       status = spi_sync(host->spi, &host->readback);
27 +       status = spi_sync_locked(host->spi, &host->readback);
28  
29         if (host->dma_dev)
30                 dma_sync_single_for_cpu(host->dma_dev,
31 @@ -540,7 +540,7 @@ mmc_spi_command_send(struct mmc_spi_host
32                                 host->data_dma, sizeof(*host->data),
33                                 DMA_BIDIRECTIONAL);
34         }
35 -       status = spi_sync(host->spi, &host->m);
36 +       status = spi_sync_locked(host->spi, &host->m);
37  
38         if (host->dma_dev)
39                 dma_sync_single_for_cpu(host->dma_dev,
40 @@ -684,7 +684,7 @@ mmc_spi_writeblock(struct mmc_spi_host *
41                                 host->data_dma, sizeof(*scratch),
42                                 DMA_BIDIRECTIONAL);
43  
44 -       status = spi_sync(spi, &host->m);
45 +       status = spi_sync_locked(spi, &host->m);
46  
47         if (status != 0) {
48                 dev_dbg(&spi->dev, "write error (%d)\n", status);
49 @@ -821,7 +821,7 @@ mmc_spi_readblock(struct mmc_spi_host *h
50                                 DMA_FROM_DEVICE);
51         }
52  
53 -       status = spi_sync(spi, &host->m);
54 +       status = spi_sync_locked(spi, &host->m);
55  
56         if (host->dma_dev) {
57                 dma_sync_single_for_cpu(host->dma_dev,
58 @@ -1017,7 +1017,7 @@ mmc_spi_data_do(struct mmc_spi_host *hos
59                                         host->data_dma, sizeof(*scratch),
60                                         DMA_BIDIRECTIONAL);
61  
62 -               tmp = spi_sync(spi, &host->m);
63 +               tmp = spi_sync_locked(spi, &host->m);
64  
65                 if (host->dma_dev)
66                         dma_sync_single_for_cpu(host->dma_dev,
67 @@ -1083,6 +1083,9 @@ static void mmc_spi_request(struct mmc_h
68         }
69  #endif
70  
71 +       /* request exclusive bus access */
72 +       spi_bus_lock(host->spi->master);
73 +
74         /* issue command; then optionally data and stop */
75         status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL);
76         if (status == 0 && mrq->data) {
77 @@ -1093,6 +1096,9 @@ static void mmc_spi_request(struct mmc_h
78                         mmc_cs_off(host);
79         }
80  
81 +       /* release the bus */
82 +       spi_bus_unlock(host->spi->master);
83 +
84         mmc_request_done(host->mmc, mrq);
85  }
86  
87 @@ -1289,23 +1295,6 @@ mmc_spi_detect_irq(int irq, void *mmc)
88         return IRQ_HANDLED;
89  }
90  
91 -struct count_children {
92 -       unsigned        n;
93 -       struct bus_type *bus;
94 -};
95 -
96 -static int maybe_count_child(struct device *dev, void *c)
97 -{
98 -       struct count_children *ccp = c;
99 -
100 -       if (dev->bus == ccp->bus) {
101 -               if (ccp->n)
102 -                       return -EBUSY;
103 -               ccp->n++;
104 -       }
105 -       return 0;
106 -}
107 -
108  static int mmc_spi_probe(struct spi_device *spi)
109  {
110         void                    *ones;
111 @@ -1337,32 +1326,6 @@ static int mmc_spi_probe(struct spi_devi
112                 return status;
113         }
114  
115 -       /* We can use the bus safely iff nobody else will interfere with us.
116 -        * Most commands consist of one SPI message to issue a command, then
117 -        * several more to collect its response, then possibly more for data
118 -        * transfer.  Clocking access to other devices during that period will
119 -        * corrupt the command execution.
120 -        *
121 -        * Until we have software primitives which guarantee non-interference,
122 -        * we'll aim for a hardware-level guarantee.
123 -        *
124 -        * REVISIT we can't guarantee another device won't be added later...
125 -        */
126 -       if (spi->master->num_chipselect > 1) {
127 -               struct count_children cc;
128 -
129 -               cc.n = 0;
130 -               cc.bus = spi->dev.bus;
131 -               status = device_for_each_child(spi->dev.parent, &cc,
132 -                               maybe_count_child);
133 -               if (status < 0) {
134 -                       dev_err(&spi->dev, "can't share SPI bus\n");
135 -                       return status;
136 -               }
137 -
138 -               dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n");
139 -       }
140 -
141         /* We need a supply of ones to transmit.  This is the only time
142          * the CPU touches these, so cache coherency isn't a concern.
143          *