kernel: add solos-pci update for 3.3
[openwrt/staging/dedeckeh.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);