kernel: update 3.18 to 3.18.1
[openwrt.git] / target / linux / generic / patches-3.3 / 132-solos-dma.patch
1 commit b4bd8ad9bb311e8536f726f7a633620ccd358cde
2 Author: David Woodhouse <dwmw2@infradead.org>
3 Date:   Thu May 24 04:58:27 2012 +0000
4
5     solos-pci: Fix DMA support
6     
7     DMA support has finally made its way to the top of the TODO list, having
8     realised that a Geode using MMIO can't keep up with two ADSL2+ lines
9     each running at 21Mb/s.
10     
11     This patch fixes a couple of bugs in the DMA support in the driver, so
12     once the corresponding FPGA update is complete and tested everything
13     should work properly.
14     
15     We weren't storing the currently-transmitting skb, so we were never
16     unmapping it and never freeing/popping it when the TX was done.
17     And the addition of pci_set_master() is fairly self-explanatory.
18     
19     Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
20     Cc: stable@kernel.org
21     Signed-off-by: David S. Miller <davem@davemloft.net>
22
23 commit 152a2a8b5e1d4cbe91a7c66f1028db15164a3766
24 Author: David Woodhouse <David.Woodhouse@intel.com>
25 Date:   Wed Dec 19 11:01:21 2012 +0000
26
27     solos-pci: ensure all TX packets are aligned to 4 bytes
28     
29     The FPGA can't handled unaligned DMA (yet). So copy into an aligned buffer,
30     if skb->data isn't suitably aligned.
31     
32     Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
33     Signed-off-by: David S. Miller <davem@davemloft.net>
34
35 commit 13af816469db3449c072afbae6c4c1bd9ccecccb
36 Author: Nathan Williams <nathan@traverse.com.au>
37 Date:   Wed Dec 19 11:01:20 2012 +0000
38
39     solos-pci: add firmware upgrade support for new models
40     
41     Signed-off-by: Nathan Williams <nathan@traverse.com.au>
42     Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
43     Signed-off-by: David S. Miller <davem@davemloft.net>
44
45 commit 7fbdadb5e951e4f0c0fc991ff5f50295568786e6
46 Author: Nathan Williams <nathan@traverse.com.au>
47 Date:   Wed Dec 19 11:01:19 2012 +0000
48
49     solos-pci: remove superfluous debug output
50     
51     Signed-off-by: Nathan Williams <nathan@traverse.com.au>
52     Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
53     Signed-off-by: David S. Miller <davem@davemloft.net>
54
55 commit f9baad02e7411d9f38d5ebe1a1cdcde4ceec100d
56 Author: Nathan Williams <nathan@traverse.com.au>
57 Date:   Wed Dec 19 11:01:18 2012 +0000
58
59     solos-pci: add GPIO support for newer versions on Geos board
60     
61     dwmw2: Tidy up a little, simpler matching on which GPIO is being accessed,
62            only register on newer boards, register under PCI device instead of
63            duplicating them under each ATM device.
64     
65     Signed-off-by: Nathan Williams <nathan@traverse.com.au>
66     Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
67     Signed-off-by: David S. Miller <davem@davemloft.net>
68
69 commit cae49ede00ec3d0cda290b03fee55b72b49efc11
70 Author: David Woodhouse <dwmw2@infradead.org>
71 Date:   Tue Dec 11 14:57:14 2012 +0000
72
73     solos-pci: fix double-free of TX skb in DMA mode
74     
75     We weren't clearing card->tx_skb[port] when processing the TX done interrupt.
76     If there wasn't another skb ready to transmit immediately, this led to a
77     double-free because we'd free it *again* next time we did have a packet to
78     send.
79     
80     Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
81     Cc: stable@kernel.org
82     Signed-off-by: David S. Miller <davem@davemloft.net>
83
84 ==
85 There is a typo here so we do a double lock instead of an unlock.
86
87 Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
88 ---
89 Only needed in linux-next.  Introduced in f9baad02e7411d9 [14/17]
90 solos-pci: add GPIO support for newer versions on Geos board
91
92
93 --- a/drivers/atm/solos-pci.c
94 +++ b/drivers/atm/solos-pci.c
95 @@ -42,7 +42,8 @@
96  #include <linux/swab.h>
97  #include <linux/slab.h>
98  
99 -#define VERSION "0.07"
100 +#define VERSION "1.04"
101 +#define DRIVER_VERSION 0x01
102  #define PTAG "solos-pci"
103  
104  #define CONFIG_RAM_SIZE        128
105 @@ -56,16 +57,21 @@
106  #define FLASH_BUSY     0x60
107  #define FPGA_MODE      0x5C
108  #define FLASH_MODE     0x58
109 +#define GPIO_STATUS    0x54
110 +#define DRIVER_VER     0x50
111  #define TX_DMA_ADDR(port)      (0x40 + (4 * (port)))
112  #define RX_DMA_ADDR(port)      (0x30 + (4 * (port)))
113  
114  #define DATA_RAM_SIZE  32768
115  #define BUF_SIZE       2048
116  #define OLD_BUF_SIZE   4096 /* For FPGA versions <= 2*/
117 -#define FPGA_PAGE      528 /* FPGA flash page size*/
118 -#define SOLOS_PAGE     512 /* Solos flash page size*/
119 -#define FPGA_BLOCK     (FPGA_PAGE * 8) /* FPGA flash block size*/
120 -#define SOLOS_BLOCK    (SOLOS_PAGE * 8) /* Solos flash block size*/
121 +/* Old boards use ATMEL AD45DB161D flash */
122 +#define ATMEL_FPGA_PAGE        528 /* FPGA flash page size*/
123 +#define ATMEL_SOLOS_PAGE       512 /* Solos flash page size*/
124 +#define ATMEL_FPGA_BLOCK       (ATMEL_FPGA_PAGE * 8) /* FPGA block size*/
125 +#define ATMEL_SOLOS_BLOCK      (ATMEL_SOLOS_PAGE * 8) /* Solos block size*/
126 +/* Current boards use M25P/M25PE SPI flash */
127 +#define SPI_FLASH_BLOCK        (256 * 64)
128  
129  #define RX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2)
130  #define TX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2 + (card->buffer_size))
131 @@ -123,11 +129,14 @@ struct solos_card {
132         struct sk_buff_head cli_queue[4];
133         struct sk_buff *tx_skb[4];
134         struct sk_buff *rx_skb[4];
135 +       unsigned char *dma_bounce;
136         wait_queue_head_t param_wq;
137         wait_queue_head_t fw_wq;
138         int using_dma;
139 +       int dma_alignment;
140         int fpga_version;
141         int buffer_size;
142 +       int atmel_flash;
143  };
144  
145  
146 @@ -452,7 +461,6 @@ static ssize_t console_show(struct devic
147  
148         len = skb->len;
149         memcpy(buf, skb->data, len);
150 -       dev_dbg(&card->dev->dev, "len: %d\n", len);
151  
152         kfree_skb(skb);
153         return len;
154 @@ -499,6 +507,78 @@ static ssize_t console_store(struct devi
155         return err?:count;
156  }
157  
158 +struct geos_gpio_attr {
159 +       struct device_attribute attr;
160 +       int offset;
161 +};
162 +
163 +#define SOLOS_GPIO_ATTR(_name, _mode, _show, _store, _offset)  \
164 +       struct geos_gpio_attr gpio_attr_##_name = {             \
165 +               .attr = __ATTR(_name, _mode, _show, _store),    \
166 +               .offset = _offset }
167 +
168 +static ssize_t geos_gpio_store(struct device *dev, struct device_attribute *attr,
169 +                              const char *buf, size_t count)
170 +{
171 +       struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
172 +       struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
173 +       struct solos_card *card = pci_get_drvdata(pdev);
174 +       uint32_t data32;
175 +
176 +       if (count != 1 && (count != 2 || buf[1] != '\n'))
177 +               return -EINVAL;
178 +
179 +       spin_lock_irq(&card->param_queue_lock);
180 +       data32 = ioread32(card->config_regs + GPIO_STATUS);
181 +       if (buf[0] == '1') {
182 +               data32 |= 1 << gattr->offset;
183 +               iowrite32(data32, card->config_regs + GPIO_STATUS);
184 +       } else if (buf[0] == '0') {
185 +               data32 &= ~(1 << gattr->offset);
186 +               iowrite32(data32, card->config_regs + GPIO_STATUS);
187 +       } else {
188 +               count = -EINVAL;
189 +       }
190 +       spin_unlock_irq(&card->param_queue_lock);
191 +       return count;
192 +}
193 +
194 +static ssize_t geos_gpio_show(struct device *dev, struct device_attribute *attr,
195 +                             char *buf)
196 +{
197 +       struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
198 +       struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
199 +       struct solos_card *card = pci_get_drvdata(pdev);
200 +       uint32_t data32;
201 +
202 +       data32 = ioread32(card->config_regs + GPIO_STATUS);
203 +       data32 = (data32 >> gattr->offset) & 1;
204 +
205 +       return sprintf(buf, "%d\n", data32);
206 +}
207 +
208 +static ssize_t hardware_show(struct device *dev, struct device_attribute *attr,
209 +                            char *buf)
210 +{
211 +       struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
212 +       struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
213 +       struct solos_card *card = pci_get_drvdata(pdev);
214 +       uint32_t data32;
215 +
216 +       data32 = ioread32(card->config_regs + GPIO_STATUS);
217 +       switch (gattr->offset) {
218 +       case 0:
219 +               /* HardwareVersion */
220 +               data32 = data32 & 0x1F;
221 +               break;
222 +       case 1:
223 +               /* HardwareVariant */
224 +               data32 = (data32 >> 5) & 0x0F;
225 +               break;
226 +       }
227 +       return sprintf(buf, "%d\n", data32);
228 +}
229 +
230  static DEVICE_ATTR(console, 0644, console_show, console_store);
231  
232  
233 @@ -507,6 +587,14 @@ static DEVICE_ATTR(console, 0644, consol
234  
235  #include "solos-attrlist.c"
236  
237 +static SOLOS_GPIO_ATTR(GPIO1, 0644, geos_gpio_show, geos_gpio_store, 9);
238 +static SOLOS_GPIO_ATTR(GPIO2, 0644, geos_gpio_show, geos_gpio_store, 10);
239 +static SOLOS_GPIO_ATTR(GPIO3, 0644, geos_gpio_show, geos_gpio_store, 11);
240 +static SOLOS_GPIO_ATTR(GPIO4, 0644, geos_gpio_show, geos_gpio_store, 12);
241 +static SOLOS_GPIO_ATTR(GPIO5, 0644, geos_gpio_show, geos_gpio_store, 13);
242 +static SOLOS_GPIO_ATTR(PushButton, 0444, geos_gpio_show, NULL, 14);
243 +static SOLOS_GPIO_ATTR(HardwareVersion, 0444, hardware_show, NULL, 0);
244 +static SOLOS_GPIO_ATTR(HardwareVariant, 0444, hardware_show, NULL, 1);
245  #undef SOLOS_ATTR_RO
246  #undef SOLOS_ATTR_RW
247  
248 @@ -523,6 +611,23 @@ static struct attribute_group solos_attr
249         .name = "parameters",
250  };
251  
252 +static struct attribute *gpio_attrs[] = {
253 +       &gpio_attr_GPIO1.attr.attr,
254 +       &gpio_attr_GPIO2.attr.attr,
255 +       &gpio_attr_GPIO3.attr.attr,
256 +       &gpio_attr_GPIO4.attr.attr,
257 +       &gpio_attr_GPIO5.attr.attr,
258 +       &gpio_attr_PushButton.attr.attr,
259 +       &gpio_attr_HardwareVersion.attr.attr,
260 +       &gpio_attr_HardwareVariant.attr.attr,
261 +       NULL
262 +};
263 +
264 +static struct attribute_group gpio_attr_group = {
265 +       .attrs = gpio_attrs,
266 +       .name = "gpio",
267 +};
268 +
269  static int flash_upgrade(struct solos_card *card, int chip)
270  {
271         const struct firmware *fw;
272 @@ -534,16 +639,25 @@ static int flash_upgrade(struct solos_ca
273         switch (chip) {
274         case 0:
275                 fw_name = "solos-FPGA.bin";
276 -               blocksize = FPGA_BLOCK;
277 +               if (card->atmel_flash)
278 +                       blocksize = ATMEL_FPGA_BLOCK;
279 +               else
280 +                       blocksize = SPI_FLASH_BLOCK;
281                 break;
282         case 1:
283                 fw_name = "solos-Firmware.bin";
284 -               blocksize = SOLOS_BLOCK;
285 +               if (card->atmel_flash)
286 +                       blocksize = ATMEL_SOLOS_BLOCK;
287 +               else
288 +                       blocksize = SPI_FLASH_BLOCK;
289                 break;
290         case 2:
291                 if (card->fpga_version > LEGACY_BUFFERS){
292                         fw_name = "solos-db-FPGA.bin";
293 -                       blocksize = FPGA_BLOCK;
294 +                       if (card->atmel_flash)
295 +                               blocksize = ATMEL_FPGA_BLOCK;
296 +                       else
297 +                               blocksize = SPI_FLASH_BLOCK;
298                 } else {
299                         dev_info(&card->dev->dev, "FPGA version doesn't support"
300                                         " daughter board upgrades\n");
301 @@ -553,7 +667,10 @@ static int flash_upgrade(struct solos_ca
302         case 3:
303                 if (card->fpga_version > LEGACY_BUFFERS){
304                         fw_name = "solos-Firmware.bin";
305 -                       blocksize = SOLOS_BLOCK;
306 +                       if (card->atmel_flash)
307 +                               blocksize = ATMEL_SOLOS_BLOCK;
308 +                       else
309 +                               blocksize = SPI_FLASH_BLOCK;
310                 } else {
311                         dev_info(&card->dev->dev, "FPGA version doesn't support"
312                                         " daughter board upgrades\n");
313 @@ -569,6 +686,9 @@ static int flash_upgrade(struct solos_ca
314  
315         dev_info(&card->dev->dev, "Flash upgrade starting\n");
316  
317 +       /* New FPGAs require driver version before permitting flash upgrades */
318 +       iowrite32(DRIVER_VERSION, card->config_regs + DRIVER_VER);
319 +
320         numblocks = fw->size / blocksize;
321         dev_info(&card->dev->dev, "Firmware size: %zd\n", fw->size);
322         dev_info(&card->dev->dev, "Number of blocks: %d\n", numblocks);
323 @@ -598,9 +718,13 @@ static int flash_upgrade(struct solos_ca
324                 /* dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n"); */
325                 iowrite32(((chip * 2) + 1), card->config_regs + FLASH_MODE);
326  
327 -               /* Copy block to buffer, swapping each 16 bits */
328 +               /* Copy block to buffer, swapping each 16 bits for Atmel flash */
329                 for(i = 0; i < blocksize; i += 4) {
330 -                       uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i));
331 +                       uint32_t word;
332 +                       if (card->atmel_flash)
333 +                               word = swahb32p((uint32_t *)(fw->data + offset + i));
334 +                       else
335 +                               word = *(uint32_t *)(fw->data + offset + i);
336                         if(card->fpga_version > LEGACY_BUFFERS)
337                                 iowrite32(word, FLASH_BUF + i);
338                         else
339 @@ -945,10 +1069,11 @@ static uint32_t fpga_tx(struct solos_car
340         for (port = 0; tx_pending; tx_pending >>= 1, port++) {
341                 if (tx_pending & 1) {
342                         struct sk_buff *oldskb = card->tx_skb[port];
343 -                       if (oldskb)
344 +                       if (oldskb) {
345                                 pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr,
346                                                  oldskb->len, PCI_DMA_TODEVICE);
347 -
348 +                               card->tx_skb[port] = NULL;
349 +                       }
350                         spin_lock(&card->tx_queue_lock);
351                         skb = skb_dequeue(&card->tx_queue[port]);
352                         if (!skb)
353 @@ -960,8 +1085,14 @@ static uint32_t fpga_tx(struct solos_car
354                                 tx_started |= 1 << port;
355                                 oldskb = skb; /* We're done with this skb already */
356                         } else if (skb && card->using_dma) {
357 -                               SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data,
358 +                               unsigned char *data = skb->data;
359 +                               if ((unsigned long)data & card->dma_alignment) {
360 +                                       data = card->dma_bounce + (BUF_SIZE * port);
361 +                                       memcpy(data, skb->data, skb->len);
362 +                               }
363 +                               SKB_CB(skb)->dma_addr = pci_map_single(card->dev, data,
364                                                                        skb->len, PCI_DMA_TODEVICE);
365 +                               card->tx_skb[port] = skb;
366                                 iowrite32(SKB_CB(skb)->dma_addr,
367                                           card->config_regs + TX_DMA_ADDR(port));
368                         }
369 @@ -1133,17 +1264,33 @@ static int fpga_probe(struct pci_dev *de
370                 db_fpga_upgrade = db_firmware_upgrade = 0;
371         }
372  
373 -       if (card->fpga_version >= DMA_SUPPORTED){
374 +       /* Stopped using Atmel flash after 0.03-38 */
375 +       if (fpga_ver < 39)
376 +               card->atmel_flash = 1;
377 +       else
378 +               card->atmel_flash = 0;
379 +
380 +       data32 = ioread32(card->config_regs + PORTS);
381 +       card->nr_ports = (data32 & 0x000000FF);
382 +
383 +       if (card->fpga_version >= DMA_SUPPORTED) {
384 +               pci_set_master(dev);
385                 card->using_dma = 1;
386 +               if (1) { /* All known FPGA versions so far */
387 +                       card->dma_alignment = 3;
388 +                       card->dma_bounce = kmalloc(card->nr_ports * BUF_SIZE, GFP_KERNEL);
389 +                       if (!card->dma_bounce) {
390 +                               dev_warn(&card->dev->dev, "Failed to allocate DMA bounce buffers\n");
391 +                               /* Fallback to MMIO doesn't work */
392 +                               goto out_unmap_both;
393 +                       }
394 +               }
395         } else {
396                 card->using_dma = 0;
397                 /* Set RX empty flag for all ports */
398                 iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
399         }
400  
401 -       data32 = ioread32(card->config_regs + PORTS);
402 -       card->nr_ports = (data32 & 0x000000FF);
403 -
404         pci_set_drvdata(dev, card);
405  
406         tasklet_init(&card->tlet, solos_bh, (unsigned long)card);
407 @@ -1178,6 +1325,10 @@ static int fpga_probe(struct pci_dev *de
408         if (err)
409                 goto out_free_irq;
410  
411 +       if (card->fpga_version >= DMA_SUPPORTED &&
412 +           sysfs_create_group(&card->dev->dev.kobj, &gpio_attr_group))
413 +               dev_err(&card->dev->dev, "Could not register parameter group for GPIOs\n");
414 +
415         return 0;
416  
417   out_free_irq:
418 @@ -1186,6 +1337,7 @@ static int fpga_probe(struct pci_dev *de
419         tasklet_kill(&card->tlet);
420         
421   out_unmap_both:
422 +       kfree(card->dma_bounce);
423         pci_set_drvdata(dev, NULL);
424         pci_iounmap(dev, card->buffers);
425   out_unmap_config:
426 @@ -1288,11 +1440,16 @@ static void fpga_remove(struct pci_dev *
427         iowrite32(1, card->config_regs + FPGA_MODE);
428         (void)ioread32(card->config_regs + FPGA_MODE); 
429  
430 +       if (card->fpga_version >= DMA_SUPPORTED)
431 +               sysfs_remove_group(&card->dev->dev.kobj, &gpio_attr_group);
432 +
433         atm_remove(card);
434  
435         free_irq(dev->irq, card);
436         tasklet_kill(&card->tlet);
437  
438 +       kfree(card->dma_bounce);
439 +
440         /* Release device from reset */
441         iowrite32(0, card->config_regs + FPGA_MODE);
442         (void)ioread32(card->config_regs + FPGA_MODE);