x86: remove old references to kmod-acpi-button
[openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0175-bcm2835-sdhost-Only-claim-one-DMA-channel.patch
1 From 06c169985c0884ce67377c79d27383e23f41e2cd Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Mon, 7 Mar 2016 16:46:39 +0000
4 Subject: [PATCH 175/180] bcm2835-sdhost: Only claim one DMA channel
5
6 With both MMC controllers enabled there are few DMA channels left. The
7 bcm2835-sdhost driver only uses DMA in one direction at a time, so it
8 doesn't need to claim two channels.
9
10 See: https://github.com/raspberrypi/linux/issues/1327
11
12 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
13 ---
14  arch/arm/boot/dts/bcm2708_common.dtsi |  5 +--
15  drivers/mmc/host/bcm2835-sdhost.c     | 70 ++++++++++++++++++++++++-----------
16  2 files changed, 50 insertions(+), 25 deletions(-)
17
18 --- a/arch/arm/boot/dts/bcm2708_common.dtsi
19 +++ b/arch/arm/boot/dts/bcm2708_common.dtsi
20 @@ -136,9 +136,8 @@
21                         reg = <0x7e202000 0x100>;
22                         interrupts = <2 24>;
23                         clocks = <&clk_core>;
24 -                       dmas = <&dma 13>,
25 -                              <&dma 13>;
26 -                       dma-names = "tx", "rx";
27 +                       dmas = <&dma 13>;
28 +                       dma-names = "rx-tx";
29                         brcm,overclock-50 = <0>;
30                         brcm,pio-limit = <1>;
31                         status = "disabled";
32 --- a/drivers/mmc/host/bcm2835-sdhost.c
33 +++ b/drivers/mmc/host/bcm2835-sdhost.c
34 @@ -185,9 +185,10 @@ struct bcm2835_host {
35         unsigned int                    debug:1;                /* Enable debug output */
36  
37         /*DMA part*/
38 -       struct dma_chan                 *dma_chan_rx;           /* DMA channel for reads */
39 -       struct dma_chan                 *dma_chan_tx;           /* DMA channel for writes */
40 -       struct dma_chan                 *dma_chan;              /* Channel in used */
41 +       struct dma_chan                 *dma_chan_rxtx;         /* DMA channel for reads and writes */
42 +       struct dma_chan                 *dma_chan;              /* Channel in use */
43 +       struct dma_slave_config         dma_cfg_rx;
44 +       struct dma_slave_config         dma_cfg_tx;
45         struct dma_async_tx_descriptor  *dma_desc;
46         u32                             dma_dir;
47         u32                             drain_words;
48 @@ -771,12 +772,11 @@ static void bcm2835_sdhost_prepare_dma(s
49         log_event("PRD<", (u32)data, 0);
50         pr_debug("bcm2835_sdhost_prepare_dma()\n");
51  
52 +       dma_chan = host->dma_chan_rxtx;
53         if (data->flags & MMC_DATA_READ) {
54 -               dma_chan = host->dma_chan_rx;
55                 dir_data = DMA_FROM_DEVICE;
56                 dir_slave = DMA_DEV_TO_MEM;
57         } else {
58 -               dma_chan = host->dma_chan_tx;
59                 dir_data = DMA_TO_DEVICE;
60                 dir_slave = DMA_MEM_TO_DEV;
61         }
62 @@ -813,6 +813,12 @@ static void bcm2835_sdhost_prepare_dma(s
63                 host->drain_words = len/4;
64         }
65  
66 +       /* The parameters have already been validated, so this will not fail */
67 +       (void)dmaengine_slave_config(dma_chan,
68 +                                    (dir_data == DMA_FROM_DEVICE) ?
69 +                                    &host->dma_cfg_rx :
70 +                                    &host->dma_cfg_tx);
71 +
72         len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
73                          dir_data);
74  
75 @@ -1805,28 +1811,46 @@ int bcm2835_sdhost_add_host(struct bcm28
76         spin_lock_init(&host->lock);
77  
78         if (host->allow_dma) {
79 -               if (IS_ERR_OR_NULL(host->dma_chan_tx) ||
80 -                   IS_ERR_OR_NULL(host->dma_chan_rx)) {
81 -                       pr_err("%s: unable to initialise DMA channels. "
82 +               if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) {
83 +                       pr_err("%s: unable to initialise DMA channel. "
84                                "Falling back to PIO\n",
85                                mmc_hostname(mmc));
86                         host->use_dma = false;
87                 } else {
88 -                       host->use_dma = true;
89 -
90                         cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
91                         cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
92                         cfg.slave_id = 13;              /* DREQ channel */
93  
94 +                       /* Validate the slave configurations */
95 +
96                         cfg.direction = DMA_MEM_TO_DEV;
97                         cfg.src_addr = 0;
98                         cfg.dst_addr = host->bus_addr + SDDATA;
99 -                       ret = dmaengine_slave_config(host->dma_chan_tx, &cfg);
100  
101 -                       cfg.direction = DMA_DEV_TO_MEM;
102 -                       cfg.src_addr = host->bus_addr + SDDATA;
103 -                       cfg.dst_addr = 0;
104 -                       ret = dmaengine_slave_config(host->dma_chan_rx, &cfg);
105 +                       ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg);
106 +
107 +                       if (ret == 0) {
108 +                               host->dma_cfg_tx = cfg;
109 +
110 +                               cfg.direction = DMA_DEV_TO_MEM;
111 +                               cfg.src_addr = host->bus_addr + SDDATA;
112 +                               cfg.dst_addr = 0;
113 +
114 +                               ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg);
115 +                       }
116 +
117 +                       if (ret == 0) {
118 +                               host->dma_cfg_rx = cfg;
119 +
120 +                               host->use_dma = true;
121 +                       } else {
122 +                               pr_err("%s: unable to configure DMA channel. "
123 +                                      "Falling back to PIO\n",
124 +                                      mmc_hostname(mmc));
125 +                               dma_release_channel(host->dma_chan_rxtx);
126 +                               host->dma_chan_rxtx = NULL;
127 +                               host->use_dma = false;
128 +                       }
129                 }
130         } else {
131                 host->use_dma = false;
132 @@ -1948,19 +1972,21 @@ static int bcm2835_sdhost_probe(struct p
133  
134         if (host->allow_dma) {
135                 if (node) {
136 -                       host->dma_chan_tx =
137 -                               dma_request_slave_channel(dev, "tx");
138 -                       host->dma_chan_rx =
139 -                               dma_request_slave_channel(dev, "rx");
140 +                       host->dma_chan_rxtx =
141 +                               dma_request_slave_channel(dev, "rx-tx");
142 +                       if (!host->dma_chan_rxtx)
143 +                               host->dma_chan_rxtx =
144 +                                       dma_request_slave_channel(dev, "tx");
145 +                       if (!host->dma_chan_rxtx)
146 +                               host->dma_chan_rxtx =
147 +                                       dma_request_slave_channel(dev, "rx");
148                 } else {
149                         dma_cap_mask_t mask;
150  
151                         dma_cap_zero(mask);
152                         /* we don't care about the channel, any would work */
153                         dma_cap_set(DMA_SLAVE, mask);
154 -                       host->dma_chan_tx =
155 -                               dma_request_channel(mask, NULL, NULL);
156 -                       host->dma_chan_rx =
157 +                       host->dma_chan_rxtx =
158                                 dma_request_channel(mask, NULL, NULL);
159                 }
160         }