brcm2708: switch to linux 4.4 and update patches
[openwrt.git] / target / linux / brcm2708 / patches-4.1 / 0019-Add-Chris-Boot-s-spi-driver.patch
1 From 8edd3a0cf1bd93eef48524a6b7e6a3c88582dc3b Mon Sep 17 00:00:00 2001
2 From: popcornmix <popcornmix@gmail.com>
3 Date: Wed, 17 Jun 2015 15:41:33 +0100
4 Subject: [PATCH 019/222] Add Chris Boot's spi driver.
5
6 spi: bcm2708: add device tree support
7
8 Add DT support to driver and add to .dtsi file.
9 Setup pins and spidev in .dts file.
10 SPI is disabled by default.
11
12 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
13
14 BCM2708: don't register SPI controller when using DT
15
16 The device for the SPI controller is in the Device Tree.
17 Only register the device when not using DT.
18
19 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
20
21 spi: bcm2835: make driver available on ARCH_BCM2708
22
23 Make this driver available on ARCH_BCM2708
24
25 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
26
27 bcm2708: Remove the prohibition on mixing SPIDEV and DT
28
29 spi-bcm2708: Prepare for Common Clock Framework migration
30
31 As part of migrating to use the Common Clock Framework, replace clk_enable()
32 with clk_prepare_enable() and clk_disable() with clk_disable_unprepare().
33 This does not affect behaviour under the current clock implementation.
34
35 Also add a missing clk_disable_unprepare() in the probe error path.
36
37 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
38 ---
39  arch/arm/mach-bcm2708/Kconfig   |   7 +
40  arch/arm/mach-bcm2708/bcm2708.c |  53 ++++
41  arch/arm/mach-bcm2709/bcm2709.c |  53 ++++
42  drivers/spi/Kconfig             |  10 +-
43  drivers/spi/Makefile            |   1 +
44  drivers/spi/spi-bcm2708.c       | 635 ++++++++++++++++++++++++++++++++++++++++
45  6 files changed, 758 insertions(+), 1 deletion(-)
46  create mode 100644 drivers/spi/spi-bcm2708.c
47
48 --- a/arch/arm/mach-bcm2708/Kconfig
49 +++ b/arch/arm/mach-bcm2708/Kconfig
50 @@ -35,4 +35,11 @@ config BCM2708_NOL2CACHE
51          help
52            Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt.
53  
54 +config BCM2708_SPIDEV
55 +       bool "Bind spidev to SPI0 master"
56 +       depends on MACH_BCM2708
57 +       depends on SPI
58 +       default y
59 +       help
60 +         Binds spidev driver to the SPI0 master
61  endmenu
62 --- a/arch/arm/mach-bcm2708/bcm2708.c
63 +++ b/arch/arm/mach-bcm2708/bcm2708.c
64 @@ -34,6 +34,7 @@
65  #include <linux/io.h>
66  #include <linux/module.h>
67  #include <linux/of_platform.h>
68 +#include <linux/spi/spi.h>
69  #include <linux/gpio/machine.h>
70  
71  #include <linux/version.h>
72 @@ -505,6 +506,50 @@ static struct platform_device bcm2708_al
73                },
74  };
75  
76 +static struct resource bcm2708_spi_resources[] = {
77 +       {
78 +               .start = SPI0_BASE,
79 +               .end = SPI0_BASE + SZ_256 - 1,
80 +               .flags = IORESOURCE_MEM,
81 +       }, {
82 +               .start = IRQ_SPI,
83 +               .end = IRQ_SPI,
84 +               .flags = IORESOURCE_IRQ,
85 +       }
86 +};
87 +
88 +
89 +static u64 bcm2708_spi_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
90 +static struct platform_device bcm2708_spi_device = {
91 +       .name = "bcm2708_spi",
92 +       .id = 0,
93 +       .num_resources = ARRAY_SIZE(bcm2708_spi_resources),
94 +       .resource = bcm2708_spi_resources,
95 +       .dev = {
96 +               .dma_mask = &bcm2708_spi_dmamask,
97 +               .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)},
98 +};
99 +
100 +#ifdef CONFIG_BCM2708_SPIDEV
101 +static struct spi_board_info bcm2708_spi_devices[] = {
102 +#ifdef CONFIG_SPI_SPIDEV
103 +       {
104 +               .modalias = "spidev",
105 +               .max_speed_hz = 500000,
106 +               .bus_num = 0,
107 +               .chip_select = 0,
108 +               .mode = SPI_MODE_0,
109 +       }, {
110 +               .modalias = "spidev",
111 +               .max_speed_hz = 500000,
112 +               .bus_num = 0,
113 +               .chip_select = 1,
114 +               .mode = SPI_MODE_0,
115 +       }
116 +#endif
117 +};
118 +#endif
119 +
120  static struct platform_device bcm2835_thermal_device = {
121         .name = "bcm2835_thermal",
122  };
123 @@ -655,6 +700,8 @@ void __init bcm2708_init(void)
124         for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++)
125                 bcm_register_device_dt(&bcm2708_alsa_devices[i]);
126  
127 +       bcm_register_device_dt(&bcm2708_spi_device);
128 +
129         bcm_register_device_dt(&bcm2835_thermal_device);
130  
131         if (!use_dt) {
132 @@ -665,6 +712,12 @@ void __init bcm2708_init(void)
133         }
134         system_rev = boardrev;
135         system_serial_low = serial;
136 +
137 +#ifdef CONFIG_BCM2708_SPIDEV
138 +       if (!use_dt)
139 +           spi_register_board_info(bcm2708_spi_devices,
140 +                                   ARRAY_SIZE(bcm2708_spi_devices));
141 +#endif
142  }
143  
144  static void timer_set_mode(enum clock_event_mode mode,
145 --- a/arch/arm/mach-bcm2709/bcm2709.c
146 +++ b/arch/arm/mach-bcm2709/bcm2709.c
147 @@ -34,6 +34,7 @@
148  #include <linux/io.h>
149  #include <linux/module.h>
150  #include <linux/of_platform.h>
151 +#include <linux/spi/spi.h>
152  #include <linux/gpio/machine.h>
153  
154  #include <linux/version.h>
155 @@ -525,6 +526,50 @@ static struct platform_device bcm2708_al
156                },
157  };
158  
159 +static struct resource bcm2708_spi_resources[] = {
160 +       {
161 +               .start = SPI0_BASE,
162 +               .end = SPI0_BASE + SZ_256 - 1,
163 +               .flags = IORESOURCE_MEM,
164 +       }, {
165 +               .start = IRQ_SPI,
166 +               .end = IRQ_SPI,
167 +               .flags = IORESOURCE_IRQ,
168 +       }
169 +};
170 +
171 +
172 +static u64 bcm2708_spi_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
173 +static struct platform_device bcm2708_spi_device = {
174 +       .name = "bcm2708_spi",
175 +       .id = 0,
176 +       .num_resources = ARRAY_SIZE(bcm2708_spi_resources),
177 +       .resource = bcm2708_spi_resources,
178 +       .dev = {
179 +               .dma_mask = &bcm2708_spi_dmamask,
180 +               .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)},
181 +};
182 +
183 +#ifdef CONFIG_BCM2708_SPIDEV
184 +static struct spi_board_info bcm2708_spi_devices[] = {
185 +#ifdef CONFIG_SPI_SPIDEV
186 +       {
187 +               .modalias = "spidev",
188 +               .max_speed_hz = 500000,
189 +               .bus_num = 0,
190 +               .chip_select = 0,
191 +               .mode = SPI_MODE_0,
192 +       }, {
193 +               .modalias = "spidev",
194 +               .max_speed_hz = 500000,
195 +               .bus_num = 0,
196 +               .chip_select = 1,
197 +               .mode = SPI_MODE_0,
198 +       }
199 +#endif
200 +};
201 +#endif
202 +
203  static struct platform_device bcm2835_thermal_device = {
204         .name = "bcm2835_thermal",
205  };
206 @@ -675,6 +720,8 @@ void __init bcm2709_init(void)
207         for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++)
208                 bcm_register_device_dt(&bcm2708_alsa_devices[i]);
209  
210 +       bcm_register_device_dt(&bcm2708_spi_device);
211 +
212         bcm_register_device_dt(&bcm2835_thermal_device);
213  
214         if (!use_dt) {
215 @@ -685,6 +732,12 @@ void __init bcm2709_init(void)
216         }
217         system_rev = boardrev;
218         system_serial_low = serial;
219 +
220 +#ifdef CONFIG_BCM2708_SPIDEV
221 +       if (!use_dt)
222 +           spi_register_board_info(bcm2708_spi_devices,
223 +                                   ARRAY_SIZE(bcm2708_spi_devices));
224 +#endif
225  }
226  
227  #ifdef SYSTEM_TIMER
228 --- a/drivers/spi/Kconfig
229 +++ b/drivers/spi/Kconfig
230 @@ -77,7 +77,7 @@ config SPI_ATMEL
231  
232  config SPI_BCM2835
233         tristate "BCM2835 SPI controller"
234 -       depends on ARCH_BCM2835 || COMPILE_TEST
235 +       depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST
236         depends on GPIOLIB
237         help
238           This selects a driver for the Broadcom BCM2835 SPI master.
239 @@ -87,6 +87,14 @@ config SPI_BCM2835
240           is for the regular SPI controller. Slave mode operation is not also
241           not supported.
242  
243 +config SPI_BCM2708
244 +       tristate "BCM2708 SPI controller driver (SPI0)"
245 +       depends on MACH_BCM2708 || MACH_BCM2709
246 +       help
247 +         This selects a driver for the Broadcom BCM2708 SPI master (SPI0). This
248 +         driver is not compatible with the "Universal SPI Master" or the SPI slave
249 +         device.
250 +
251  config SPI_BFIN5XX
252         tristate "SPI controller driver for ADI Blackfin5xx"
253         depends on BLACKFIN && !BF60x
254 --- a/drivers/spi/Makefile
255 +++ b/drivers/spi/Makefile
256 @@ -20,6 +20,7 @@ obj-$(CONFIG_SPI_BCM63XX)             += spi-bcm63x
257  obj-$(CONFIG_SPI_BCM63XX_HSSPI)                += spi-bcm63xx-hsspi.o
258  obj-$(CONFIG_SPI_BFIN5XX)              += spi-bfin5xx.o
259  obj-$(CONFIG_SPI_ADI_V3)                += spi-adi-v3.o
260 +obj-$(CONFIG_SPI_BCM2708)              += spi-bcm2708.o
261  obj-$(CONFIG_SPI_BFIN_SPORT)           += spi-bfin-sport.o
262  obj-$(CONFIG_SPI_BITBANG)              += spi-bitbang.o
263  obj-$(CONFIG_SPI_BUTTERFLY)            += spi-butterfly.o
264 --- /dev/null
265 +++ b/drivers/spi/spi-bcm2708.c
266 @@ -0,0 +1,635 @@
267 +/*
268 + * Driver for Broadcom BCM2708 SPI Controllers
269 + *
270 + * Copyright (C) 2012 Chris Boot
271 + *
272 + * This driver is inspired by:
273 + * spi-ath79.c, Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
274 + * spi-atmel.c, Copyright (C) 2006 Atmel Corporation
275 + *
276 + * This program is free software; you can redistribute it and/or modify
277 + * it under the terms of the GNU General Public License as published by
278 + * the Free Software Foundation; either version 2 of the License, or
279 + * (at your option) any later version.
280 + *
281 + * This program is distributed in the hope that it will be useful,
282 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
283 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
284 + * GNU General Public License for more details.
285 + *
286 + * You should have received a copy of the GNU General Public License
287 + * along with this program; if not, write to the Free Software
288 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
289 + */
290 +
291 +#include <linux/kernel.h>
292 +#include <linux/module.h>
293 +#include <linux/spinlock.h>
294 +#include <linux/clk.h>
295 +#include <linux/err.h>
296 +#include <linux/platform_device.h>
297 +#include <linux/io.h>
298 +#include <linux/spi/spi.h>
299 +#include <linux/interrupt.h>
300 +#include <linux/delay.h>
301 +#include <linux/log2.h>
302 +#include <linux/sched.h>
303 +#include <linux/wait.h>
304 +
305 +/* SPI register offsets */
306 +#define SPI_CS                 0x00
307 +#define SPI_FIFO               0x04
308 +#define SPI_CLK                        0x08
309 +#define SPI_DLEN               0x0c
310 +#define SPI_LTOH               0x10
311 +#define SPI_DC                 0x14
312 +
313 +/* Bitfields in CS */
314 +#define SPI_CS_LEN_LONG                0x02000000
315 +#define SPI_CS_DMA_LEN         0x01000000
316 +#define SPI_CS_CSPOL2          0x00800000
317 +#define SPI_CS_CSPOL1          0x00400000
318 +#define SPI_CS_CSPOL0          0x00200000
319 +#define SPI_CS_RXF             0x00100000
320 +#define SPI_CS_RXR             0x00080000
321 +#define SPI_CS_TXD             0x00040000
322 +#define SPI_CS_RXD             0x00020000
323 +#define SPI_CS_DONE            0x00010000
324 +#define SPI_CS_LEN             0x00002000
325 +#define SPI_CS_REN             0x00001000
326 +#define SPI_CS_ADCS            0x00000800
327 +#define SPI_CS_INTR            0x00000400
328 +#define SPI_CS_INTD            0x00000200
329 +#define SPI_CS_DMAEN           0x00000100
330 +#define SPI_CS_TA              0x00000080
331 +#define SPI_CS_CSPOL           0x00000040
332 +#define SPI_CS_CLEAR_RX                0x00000020
333 +#define SPI_CS_CLEAR_TX                0x00000010
334 +#define SPI_CS_CPOL            0x00000008
335 +#define SPI_CS_CPHA            0x00000004
336 +#define SPI_CS_CS_10           0x00000002
337 +#define SPI_CS_CS_01           0x00000001
338 +
339 +#define SPI_TIMEOUT_MS 150
340 +
341 +#define DRV_NAME       "bcm2708_spi"
342 +
343 +struct bcm2708_spi {
344 +       spinlock_t lock;
345 +       void __iomem *base;
346 +       int irq;
347 +       struct clk *clk;
348 +       bool stopping;
349 +
350 +       struct list_head queue;
351 +       struct workqueue_struct *workq;
352 +       struct work_struct work;
353 +       struct completion done;
354 +
355 +       const u8 *tx_buf;
356 +       u8 *rx_buf;
357 +       int len;
358 +};
359 +
360 +struct bcm2708_spi_state {
361 +       u32 cs;
362 +       u16 cdiv;
363 +};
364 +
365 +/*
366 + * This function sets the ALT mode on the SPI pins so that we can use them with
367 + * the SPI hardware.
368 + *
369 + * FIXME: This is a hack. Use pinmux / pinctrl.
370 + */
371 +static void bcm2708_init_pinmode(void)
372 +{
373 +#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
374 +#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
375 +
376 +       int pin;
377 +       u32 *gpio = ioremap(GPIO_BASE, SZ_16K);
378 +
379 +       /* SPI is on GPIO 7..11 */
380 +       for (pin = 7; pin <= 11; pin++) {
381 +               INP_GPIO(pin);          /* set mode to GPIO input first */
382 +               SET_GPIO_ALT(pin, 0);   /* set mode to ALT 0 */
383 +       }
384 +
385 +       iounmap(gpio);
386 +
387 +#undef INP_GPIO
388 +#undef SET_GPIO_ALT
389 +}
390 +
391 +static inline u32 bcm2708_rd(struct bcm2708_spi *bs, unsigned reg)
392 +{
393 +       return readl(bs->base + reg);
394 +}
395 +
396 +static inline void bcm2708_wr(struct bcm2708_spi *bs, unsigned reg, u32 val)
397 +{
398 +       writel(val, bs->base + reg);
399 +}
400 +
401 +static inline void bcm2708_rd_fifo(struct bcm2708_spi *bs, int len)
402 +{
403 +       u8 byte;
404 +
405 +       while (len--) {
406 +               byte = bcm2708_rd(bs, SPI_FIFO);
407 +               if (bs->rx_buf)
408 +                       *bs->rx_buf++ = byte;
409 +       }
410 +}
411 +
412 +static inline void bcm2708_wr_fifo(struct bcm2708_spi *bs, int len)
413 +{
414 +       u8 byte;
415 +       u16 val;
416 +
417 +       if (len > bs->len)
418 +               len = bs->len;
419 +
420 +       if (unlikely(bcm2708_rd(bs, SPI_CS) & SPI_CS_LEN)) {
421 +               /* LoSSI mode */
422 +               if (unlikely(len % 2)) {
423 +                       printk(KERN_ERR"bcm2708_wr_fifo: length must be even, skipping.\n");
424 +                       bs->len = 0;
425 +                       return;
426 +               }
427 +               while (len) {
428 +                       if (bs->tx_buf) {
429 +                               val = *(const u16 *)bs->tx_buf;
430 +                               bs->tx_buf += 2;
431 +                       } else
432 +                               val = 0;
433 +                       bcm2708_wr(bs, SPI_FIFO, val);
434 +                       bs->len -= 2;
435 +                       len -= 2;
436 +               }
437 +               return;
438 +       }
439 +
440 +       while (len--) {
441 +               byte = bs->tx_buf ? *bs->tx_buf++ : 0;
442 +               bcm2708_wr(bs, SPI_FIFO, byte);
443 +               bs->len--;
444 +       }
445 +}
446 +
447 +static irqreturn_t bcm2708_spi_interrupt(int irq, void *dev_id)
448 +{
449 +       struct spi_master *master = dev_id;
450 +       struct bcm2708_spi *bs = spi_master_get_devdata(master);
451 +       u32 cs;
452 +
453 +       spin_lock(&bs->lock);
454 +
455 +       cs = bcm2708_rd(bs, SPI_CS);
456 +
457 +       if (cs & SPI_CS_DONE) {
458 +               if (bs->len) { /* first interrupt in a transfer */
459 +                       /* fill the TX fifo with up to 16 bytes */
460 +                       bcm2708_wr_fifo(bs, 16);
461 +               } else { /* transfer complete */
462 +                       /* disable interrupts */
463 +                       cs &= ~(SPI_CS_INTR | SPI_CS_INTD);
464 +                       bcm2708_wr(bs, SPI_CS, cs);
465 +
466 +                       /* drain RX FIFO */
467 +                       while (cs & SPI_CS_RXD) {
468 +                               bcm2708_rd_fifo(bs, 1);
469 +                               cs = bcm2708_rd(bs, SPI_CS);
470 +                       }
471 +
472 +                       /* wake up our bh */
473 +                       complete(&bs->done);
474 +               }
475 +       } else if (cs & SPI_CS_RXR) {
476 +               /* read 12 bytes of data */
477 +               bcm2708_rd_fifo(bs, 12);
478 +
479 +               /* write up to 12 bytes */
480 +               bcm2708_wr_fifo(bs, 12);
481 +       }
482 +
483 +       spin_unlock(&bs->lock);
484 +
485 +       return IRQ_HANDLED;
486 +}
487 +
488 +static int bcm2708_setup_state(struct spi_master *master,
489 +               struct device *dev, struct bcm2708_spi_state *state,
490 +               u32 hz, u8 csel, u8 mode, u8 bpw)
491 +{
492 +       struct bcm2708_spi *bs = spi_master_get_devdata(master);
493 +       int cdiv;
494 +       unsigned long bus_hz;
495 +       u32 cs = 0;
496 +
497 +       bus_hz = clk_get_rate(bs->clk);
498 +
499 +       if (hz >= bus_hz) {
500 +               cdiv = 2; /* bus_hz / 2 is as fast as we can go */
501 +       } else if (hz) {
502 +               cdiv = DIV_ROUND_UP(bus_hz, hz);
503 +
504 +               /* CDIV must be a power of 2, so round up */
505 +               cdiv = roundup_pow_of_two(cdiv);
506 +
507 +               if (cdiv > 65536) {
508 +                       dev_dbg(dev,
509 +                               "setup: %d Hz too slow, cdiv %u; min %ld Hz\n",
510 +                               hz, cdiv, bus_hz / 65536);
511 +                       return -EINVAL;
512 +               } else if (cdiv == 65536) {
513 +                       cdiv = 0;
514 +               } else if (cdiv == 1) {
515 +                       cdiv = 2; /* 1 gets rounded down to 0; == 65536 */
516 +               }
517 +       } else {
518 +               cdiv = 0;
519 +       }
520 +
521 +       switch (bpw) {
522 +       case 8:
523 +               break;
524 +       case 9:
525 +               /* Reading in LoSSI mode is a special case. See 'BCM2835 ARM Peripherals' datasheet */
526 +               cs |= SPI_CS_LEN;
527 +               break;
528 +       default:
529 +               dev_dbg(dev, "setup: invalid bits_per_word %u (must be 8 or 9)\n",
530 +                       bpw);
531 +               return -EINVAL;
532 +       }
533 +
534 +       if (mode & SPI_CPOL)
535 +               cs |= SPI_CS_CPOL;
536 +       if (mode & SPI_CPHA)
537 +               cs |= SPI_CS_CPHA;
538 +
539 +       if (!(mode & SPI_NO_CS)) {
540 +               if (mode & SPI_CS_HIGH) {
541 +                       cs |= SPI_CS_CSPOL;
542 +                       cs |= SPI_CS_CSPOL0 << csel;
543 +               }
544 +
545 +               cs |= csel;
546 +       } else {
547 +               cs |= SPI_CS_CS_10 | SPI_CS_CS_01;
548 +       }
549 +
550 +       if (state) {
551 +               state->cs = cs;
552 +               state->cdiv = cdiv;
553 +               dev_dbg(dev, "setup: want %d Hz; "
554 +                       "bus_hz=%lu / cdiv=%u == %lu Hz; "
555 +                       "mode %u: cs 0x%08X\n",
556 +                       hz, bus_hz, cdiv, bus_hz/cdiv, mode, cs);
557 +       }
558 +
559 +       return 0;
560 +}
561 +
562 +static int bcm2708_process_transfer(struct bcm2708_spi *bs,
563 +               struct spi_message *msg, struct spi_transfer *xfer)
564 +{
565 +       struct spi_device *spi = msg->spi;
566 +       struct bcm2708_spi_state state, *stp;
567 +       int ret;
568 +       u32 cs;
569 +
570 +       if (bs->stopping)
571 +               return -ESHUTDOWN;
572 +
573 +       if (xfer->bits_per_word || xfer->speed_hz) {
574 +               ret = bcm2708_setup_state(spi->master, &spi->dev, &state,
575 +                       xfer->speed_hz ? xfer->speed_hz : spi->max_speed_hz,
576 +                       spi->chip_select, spi->mode,
577 +                       xfer->bits_per_word ? xfer->bits_per_word :
578 +                               spi->bits_per_word);
579 +               if (ret)
580 +                       return ret;
581 +
582 +               stp = &state;
583 +       } else {
584 +               stp = spi->controller_state;
585 +       }
586 +
587 +       reinit_completion(&bs->done);
588 +       bs->tx_buf = xfer->tx_buf;
589 +       bs->rx_buf = xfer->rx_buf;
590 +       bs->len = xfer->len;
591 +
592 +       cs = stp->cs | SPI_CS_INTR | SPI_CS_INTD | SPI_CS_TA;
593 +
594 +       bcm2708_wr(bs, SPI_CLK, stp->cdiv);
595 +       bcm2708_wr(bs, SPI_CS, cs);
596 +
597 +       ret = wait_for_completion_timeout(&bs->done,
598 +                       msecs_to_jiffies(SPI_TIMEOUT_MS));
599 +       if (ret == 0) {
600 +               dev_err(&spi->dev, "transfer timed out\n");
601 +               return -ETIMEDOUT;
602 +       }
603 +
604 +       if (xfer->delay_usecs)
605 +               udelay(xfer->delay_usecs);
606 +
607 +       if (list_is_last(&xfer->transfer_list, &msg->transfers) ||
608 +                       xfer->cs_change) {
609 +               /* clear TA and interrupt flags */
610 +               bcm2708_wr(bs, SPI_CS, stp->cs);
611 +       }
612 +
613 +       msg->actual_length += (xfer->len - bs->len);
614 +
615 +       return 0;
616 +}
617 +
618 +static void bcm2708_work(struct work_struct *work)
619 +{
620 +       struct bcm2708_spi *bs = container_of(work, struct bcm2708_spi, work);
621 +       unsigned long flags;
622 +       struct spi_message *msg;
623 +       struct spi_transfer *xfer;
624 +       int status = 0;
625 +
626 +       spin_lock_irqsave(&bs->lock, flags);
627 +       while (!list_empty(&bs->queue)) {
628 +               msg = list_first_entry(&bs->queue, struct spi_message, queue);
629 +               list_del_init(&msg->queue);
630 +               spin_unlock_irqrestore(&bs->lock, flags);
631 +
632 +               list_for_each_entry(xfer, &msg->transfers, transfer_list) {
633 +                       status = bcm2708_process_transfer(bs, msg, xfer);
634 +                       if (status)
635 +                               break;
636 +               }
637 +
638 +               msg->status = status;
639 +               msg->complete(msg->context);
640 +
641 +               spin_lock_irqsave(&bs->lock, flags);
642 +       }
643 +       spin_unlock_irqrestore(&bs->lock, flags);
644 +}
645 +
646 +static int bcm2708_spi_setup(struct spi_device *spi)
647 +{
648 +       struct bcm2708_spi *bs = spi_master_get_devdata(spi->master);
649 +       struct bcm2708_spi_state *state;
650 +       int ret;
651 +
652 +       if (bs->stopping)
653 +               return -ESHUTDOWN;
654 +
655 +       if (!(spi->mode & SPI_NO_CS) &&
656 +                       (spi->chip_select > spi->master->num_chipselect)) {
657 +               dev_dbg(&spi->dev,
658 +                       "setup: invalid chipselect %u (%u defined)\n",
659 +                       spi->chip_select, spi->master->num_chipselect);
660 +               return -EINVAL;
661 +       }
662 +
663 +       state = spi->controller_state;
664 +       if (!state) {
665 +               state = kzalloc(sizeof(*state), GFP_KERNEL);
666 +               if (!state)
667 +                       return -ENOMEM;
668 +
669 +               spi->controller_state = state;
670 +       }
671 +
672 +       ret = bcm2708_setup_state(spi->master, &spi->dev, state,
673 +               spi->max_speed_hz, spi->chip_select, spi->mode,
674 +               spi->bits_per_word);
675 +       if (ret < 0) {
676 +               kfree(state);
677 +               spi->controller_state = NULL;
678 +                return ret;
679 +       }
680 +
681 +       dev_dbg(&spi->dev,
682 +               "setup: cd %d: %d Hz, bpw %u, mode 0x%x -> CS=%08x CDIV=%04x\n",
683 +               spi->chip_select, spi->max_speed_hz, spi->bits_per_word,
684 +               spi->mode, state->cs, state->cdiv);
685 +
686 +       return 0;
687 +}
688 +
689 +static int bcm2708_spi_transfer(struct spi_device *spi, struct spi_message *msg)
690 +{
691 +       struct bcm2708_spi *bs = spi_master_get_devdata(spi->master);
692 +       struct spi_transfer *xfer;
693 +       int ret;
694 +       unsigned long flags;
695 +
696 +       if (unlikely(list_empty(&msg->transfers)))
697 +               return -EINVAL;
698 +
699 +       if (bs->stopping)
700 +               return -ESHUTDOWN;
701 +
702 +       list_for_each_entry(xfer, &msg->transfers, transfer_list) {
703 +               if (!(xfer->tx_buf || xfer->rx_buf) && xfer->len) {
704 +                       dev_dbg(&spi->dev, "missing rx or tx buf\n");
705 +                       return -EINVAL;
706 +               }
707 +
708 +               if (!xfer->bits_per_word || xfer->speed_hz)
709 +                       continue;
710 +
711 +               ret = bcm2708_setup_state(spi->master, &spi->dev, NULL,
712 +                       xfer->speed_hz ? xfer->speed_hz : spi->max_speed_hz,
713 +                       spi->chip_select, spi->mode,
714 +                       xfer->bits_per_word ? xfer->bits_per_word :
715 +                               spi->bits_per_word);
716 +               if (ret)
717 +                       return ret;
718 +       }
719 +
720 +       msg->status = -EINPROGRESS;
721 +       msg->actual_length = 0;
722 +
723 +       spin_lock_irqsave(&bs->lock, flags);
724 +       list_add_tail(&msg->queue, &bs->queue);
725 +       queue_work(bs->workq, &bs->work);
726 +       spin_unlock_irqrestore(&bs->lock, flags);
727 +
728 +       return 0;
729 +}
730 +
731 +static void bcm2708_spi_cleanup(struct spi_device *spi)
732 +{
733 +       if (spi->controller_state) {
734 +               kfree(spi->controller_state);
735 +               spi->controller_state = NULL;
736 +       }
737 +}
738 +
739 +static int bcm2708_spi_probe(struct platform_device *pdev)
740 +{
741 +       struct resource *regs;
742 +       int irq, err = -ENOMEM;
743 +       struct clk *clk;
744 +       struct spi_master *master;
745 +       struct bcm2708_spi *bs;
746 +
747 +       regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
748 +       if (!regs) {
749 +               dev_err(&pdev->dev, "could not get IO memory\n");
750 +               return -ENXIO;
751 +       }
752 +
753 +       irq = platform_get_irq(pdev, 0);
754 +       if (irq < 0) {
755 +               dev_err(&pdev->dev, "could not get IRQ\n");
756 +               return irq;
757 +       }
758 +
759 +       clk = clk_get(&pdev->dev, NULL);
760 +       if (IS_ERR(clk)) {
761 +               dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk));
762 +               return PTR_ERR(clk);
763 +       }
764 +
765 +       bcm2708_init_pinmode();
766 +
767 +       master = spi_alloc_master(&pdev->dev, sizeof(*bs));
768 +       if (!master) {
769 +               dev_err(&pdev->dev, "spi_alloc_master() failed\n");
770 +               goto out_clk_put;
771 +       }
772 +
773 +       /* the spi->mode bits understood by this driver: */
774 +       master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS;
775 +
776 +       master->bus_num = pdev->id;
777 +       master->num_chipselect = 3;
778 +       master->setup = bcm2708_spi_setup;
779 +       master->transfer = bcm2708_spi_transfer;
780 +       master->cleanup = bcm2708_spi_cleanup;
781 +       master->dev.of_node = pdev->dev.of_node;
782 +       platform_set_drvdata(pdev, master);
783 +
784 +       bs = spi_master_get_devdata(master);
785 +
786 +       spin_lock_init(&bs->lock);
787 +       INIT_LIST_HEAD(&bs->queue);
788 +       init_completion(&bs->done);
789 +       INIT_WORK(&bs->work, bcm2708_work);
790 +
791 +       bs->base = ioremap(regs->start, resource_size(regs));
792 +       if (!bs->base) {
793 +               dev_err(&pdev->dev, "could not remap memory\n");
794 +               goto out_master_put;
795 +       }
796 +
797 +       bs->workq = create_singlethread_workqueue(dev_name(&pdev->dev));
798 +       if (!bs->workq) {
799 +               dev_err(&pdev->dev, "could not create workqueue\n");
800 +               goto out_iounmap;
801 +       }
802 +
803 +       bs->irq = irq;
804 +       bs->clk = clk;
805 +       bs->stopping = false;
806 +
807 +       err = request_irq(irq, bcm2708_spi_interrupt, 0, dev_name(&pdev->dev),
808 +                       master);
809 +       if (err) {
810 +               dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
811 +               goto out_workqueue;
812 +       }
813 +
814 +       /* initialise the hardware */
815 +       clk_prepare_enable(clk);
816 +       bcm2708_wr(bs, SPI_CS, SPI_CS_REN | SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX);
817 +
818 +       err = spi_register_master(master);
819 +       if (err) {
820 +               dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
821 +               goto out_free_irq;
822 +       }
823 +
824 +       dev_info(&pdev->dev, "SPI Controller at 0x%08lx (irq %d)\n",
825 +               (unsigned long)regs->start, irq);
826 +
827 +       return 0;
828 +
829 +out_free_irq:
830 +       free_irq(bs->irq, master);
831 +       clk_disable_unprepare(bs->clk);
832 +out_workqueue:
833 +       destroy_workqueue(bs->workq);
834 +out_iounmap:
835 +       iounmap(bs->base);
836 +out_master_put:
837 +       spi_master_put(master);
838 +out_clk_put:
839 +       clk_put(clk);
840 +       return err;
841 +}
842 +
843 +static int bcm2708_spi_remove(struct platform_device *pdev)
844 +{
845 +       struct spi_master *master = platform_get_drvdata(pdev);
846 +       struct bcm2708_spi *bs = spi_master_get_devdata(master);
847 +
848 +       /* reset the hardware and block queue progress */
849 +       spin_lock_irq(&bs->lock);
850 +       bs->stopping = true;
851 +       bcm2708_wr(bs, SPI_CS, SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX);
852 +       spin_unlock_irq(&bs->lock);
853 +
854 +       flush_work(&bs->work);
855 +
856 +       clk_disable_unprepare(bs->clk);
857 +       clk_put(bs->clk);
858 +       free_irq(bs->irq, master);
859 +       iounmap(bs->base);
860 +
861 +       spi_unregister_master(master);
862 +
863 +       return 0;
864 +}
865 +
866 +static const struct of_device_id bcm2708_spi_match[] = {
867 +       { .compatible = "brcm,bcm2708-spi", },
868 +       {}
869 +};
870 +MODULE_DEVICE_TABLE(of, bcm2708_spi_match);
871 +
872 +static struct platform_driver bcm2708_spi_driver = {
873 +       .driver         = {
874 +               .name   = DRV_NAME,
875 +               .owner  = THIS_MODULE,
876 +               .of_match_table = bcm2708_spi_match,
877 +       },
878 +       .probe          = bcm2708_spi_probe,
879 +       .remove         = bcm2708_spi_remove,
880 +};
881 +
882 +
883 +static int __init bcm2708_spi_init(void)
884 +{
885 +       return platform_driver_probe(&bcm2708_spi_driver, bcm2708_spi_probe);
886 +}
887 +module_init(bcm2708_spi_init);
888 +
889 +static void __exit bcm2708_spi_exit(void)
890 +{
891 +       platform_driver_unregister(&bcm2708_spi_driver);
892 +}
893 +module_exit(bcm2708_spi_exit);
894 +
895 +
896 +//module_platform_driver(bcm2708_spi_driver);
897 +
898 +MODULE_DESCRIPTION("SPI controller driver for Broadcom BCM2708");
899 +MODULE_AUTHOR("Chris Boot <bootc@bootc.net>");
900 +MODULE_LICENSE("GPL v2");
901 +MODULE_ALIAS("platform:" DRV_NAME);