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.
6 spi: bcm2708: add device tree support
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.
12 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
14 BCM2708: don't register SPI controller when using DT
16 The device for the SPI controller is in the Device Tree.
17 Only register the device when not using DT.
19 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
21 spi: bcm2835: make driver available on ARCH_BCM2708
23 Make this driver available on ARCH_BCM2708
25 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
27 bcm2708: Remove the prohibition on mixing SPIDEV and DT
29 spi-bcm2708: Prepare for Common Clock Framework migration
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.
35 Also add a missing clk_disable_unprepare() in the probe error path.
37 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
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
48 --- a/arch/arm/mach-bcm2708/Kconfig
49 +++ b/arch/arm/mach-bcm2708/Kconfig
50 @@ -35,4 +35,11 @@ config BCM2708_NOL2CACHE
52 Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt.
54 +config BCM2708_SPIDEV
55 + bool "Bind spidev to SPI0 master"
56 + depends on MACH_BCM2708
60 + Binds spidev driver to the SPI0 master
62 --- a/arch/arm/mach-bcm2708/bcm2708.c
63 +++ b/arch/arm/mach-bcm2708/bcm2708.c
66 #include <linux/module.h>
67 #include <linux/of_platform.h>
68 +#include <linux/spi/spi.h>
69 #include <linux/gpio/machine.h>
71 #include <linux/version.h>
72 @@ -505,6 +506,50 @@ static struct platform_device bcm2708_al
76 +static struct resource bcm2708_spi_resources[] = {
79 + .end = SPI0_BASE + SZ_256 - 1,
80 + .flags = IORESOURCE_MEM,
84 + .flags = IORESOURCE_IRQ,
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",
93 + .num_resources = ARRAY_SIZE(bcm2708_spi_resources),
94 + .resource = bcm2708_spi_resources,
96 + .dma_mask = &bcm2708_spi_dmamask,
97 + .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)},
100 +#ifdef CONFIG_BCM2708_SPIDEV
101 +static struct spi_board_info bcm2708_spi_devices[] = {
102 +#ifdef CONFIG_SPI_SPIDEV
104 + .modalias = "spidev",
105 + .max_speed_hz = 500000,
108 + .mode = SPI_MODE_0,
110 + .modalias = "spidev",
111 + .max_speed_hz = 500000,
114 + .mode = SPI_MODE_0,
120 static struct platform_device bcm2835_thermal_device = {
121 .name = "bcm2835_thermal",
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]);
127 + bcm_register_device_dt(&bcm2708_spi_device);
129 bcm_register_device_dt(&bcm2835_thermal_device);
132 @@ -665,6 +712,12 @@ void __init bcm2708_init(void)
134 system_rev = boardrev;
135 system_serial_low = serial;
137 +#ifdef CONFIG_BCM2708_SPIDEV
139 + spi_register_board_info(bcm2708_spi_devices,
140 + ARRAY_SIZE(bcm2708_spi_devices));
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
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>
154 #include <linux/version.h>
155 @@ -525,6 +526,50 @@ static struct platform_device bcm2708_al
159 +static struct resource bcm2708_spi_resources[] = {
161 + .start = SPI0_BASE,
162 + .end = SPI0_BASE + SZ_256 - 1,
163 + .flags = IORESOURCE_MEM,
167 + .flags = IORESOURCE_IRQ,
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",
176 + .num_resources = ARRAY_SIZE(bcm2708_spi_resources),
177 + .resource = bcm2708_spi_resources,
179 + .dma_mask = &bcm2708_spi_dmamask,
180 + .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)},
183 +#ifdef CONFIG_BCM2708_SPIDEV
184 +static struct spi_board_info bcm2708_spi_devices[] = {
185 +#ifdef CONFIG_SPI_SPIDEV
187 + .modalias = "spidev",
188 + .max_speed_hz = 500000,
191 + .mode = SPI_MODE_0,
193 + .modalias = "spidev",
194 + .max_speed_hz = 500000,
197 + .mode = SPI_MODE_0,
203 static struct platform_device bcm2835_thermal_device = {
204 .name = "bcm2835_thermal",
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]);
210 + bcm_register_device_dt(&bcm2708_spi_device);
212 bcm_register_device_dt(&bcm2835_thermal_device);
215 @@ -685,6 +732,12 @@ void __init bcm2709_init(void)
217 system_rev = boardrev;
218 system_serial_low = serial;
220 +#ifdef CONFIG_BCM2708_SPIDEV
222 + spi_register_board_info(bcm2708_spi_devices,
223 + ARRAY_SIZE(bcm2708_spi_devices));
228 --- a/drivers/spi/Kconfig
229 +++ b/drivers/spi/Kconfig
230 @@ -77,7 +77,7 @@ config SPI_ATMEL
233 tristate "BCM2835 SPI controller"
234 - depends on ARCH_BCM2835 || COMPILE_TEST
235 + depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST
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
244 + tristate "BCM2708 SPI controller driver (SPI0)"
245 + depends on MACH_BCM2708 || MACH_BCM2709
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
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
265 +++ b/drivers/spi/spi-bcm2708.c
268 + * Driver for Broadcom BCM2708 SPI Controllers
270 + * Copyright (C) 2012 Chris Boot
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
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.
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.
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.
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>
305 +/* SPI register offsets */
307 +#define SPI_FIFO 0x04
308 +#define SPI_CLK 0x08
309 +#define SPI_DLEN 0x0c
310 +#define SPI_LTOH 0x10
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
339 +#define SPI_TIMEOUT_MS 150
341 +#define DRV_NAME "bcm2708_spi"
343 +struct bcm2708_spi {
345 + void __iomem *base;
350 + struct list_head queue;
351 + struct workqueue_struct *workq;
352 + struct work_struct work;
353 + struct completion done;
360 +struct bcm2708_spi_state {
366 + * This function sets the ALT mode on the SPI pins so that we can use them with
367 + * the SPI hardware.
369 + * FIXME: This is a hack. Use pinmux / pinctrl.
371 +static void bcm2708_init_pinmode(void)
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))
377 + u32 *gpio = ioremap(GPIO_BASE, SZ_16K);
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 */
391 +static inline u32 bcm2708_rd(struct bcm2708_spi *bs, unsigned reg)
393 + return readl(bs->base + reg);
396 +static inline void bcm2708_wr(struct bcm2708_spi *bs, unsigned reg, u32 val)
398 + writel(val, bs->base + reg);
401 +static inline void bcm2708_rd_fifo(struct bcm2708_spi *bs, int len)
406 + byte = bcm2708_rd(bs, SPI_FIFO);
408 + *bs->rx_buf++ = byte;
412 +static inline void bcm2708_wr_fifo(struct bcm2708_spi *bs, int len)
420 + if (unlikely(bcm2708_rd(bs, SPI_CS) & SPI_CS_LEN)) {
422 + if (unlikely(len % 2)) {
423 + printk(KERN_ERR"bcm2708_wr_fifo: length must be even, skipping.\n");
429 + val = *(const u16 *)bs->tx_buf;
433 + bcm2708_wr(bs, SPI_FIFO, val);
441 + byte = bs->tx_buf ? *bs->tx_buf++ : 0;
442 + bcm2708_wr(bs, SPI_FIFO, byte);
447 +static irqreturn_t bcm2708_spi_interrupt(int irq, void *dev_id)
449 + struct spi_master *master = dev_id;
450 + struct bcm2708_spi *bs = spi_master_get_devdata(master);
453 + spin_lock(&bs->lock);
455 + cs = bcm2708_rd(bs, SPI_CS);
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);
466 + /* drain RX FIFO */
467 + while (cs & SPI_CS_RXD) {
468 + bcm2708_rd_fifo(bs, 1);
469 + cs = bcm2708_rd(bs, SPI_CS);
472 + /* wake up our bh */
473 + complete(&bs->done);
475 + } else if (cs & SPI_CS_RXR) {
476 + /* read 12 bytes of data */
477 + bcm2708_rd_fifo(bs, 12);
479 + /* write up to 12 bytes */
480 + bcm2708_wr_fifo(bs, 12);
483 + spin_unlock(&bs->lock);
485 + return IRQ_HANDLED;
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)
492 + struct bcm2708_spi *bs = spi_master_get_devdata(master);
494 + unsigned long bus_hz;
497 + bus_hz = clk_get_rate(bs->clk);
499 + if (hz >= bus_hz) {
500 + cdiv = 2; /* bus_hz / 2 is as fast as we can go */
502 + cdiv = DIV_ROUND_UP(bus_hz, hz);
504 + /* CDIV must be a power of 2, so round up */
505 + cdiv = roundup_pow_of_two(cdiv);
507 + if (cdiv > 65536) {
509 + "setup: %d Hz too slow, cdiv %u; min %ld Hz\n",
510 + hz, cdiv, bus_hz / 65536);
512 + } else if (cdiv == 65536) {
514 + } else if (cdiv == 1) {
515 + cdiv = 2; /* 1 gets rounded down to 0; == 65536 */
525 + /* Reading in LoSSI mode is a special case. See 'BCM2835 ARM Peripherals' datasheet */
529 + dev_dbg(dev, "setup: invalid bits_per_word %u (must be 8 or 9)\n",
534 + if (mode & SPI_CPOL)
536 + if (mode & SPI_CPHA)
539 + if (!(mode & SPI_NO_CS)) {
540 + if (mode & SPI_CS_HIGH) {
541 + cs |= SPI_CS_CSPOL;
542 + cs |= SPI_CS_CSPOL0 << csel;
547 + cs |= SPI_CS_CS_10 | SPI_CS_CS_01;
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);
562 +static int bcm2708_process_transfer(struct bcm2708_spi *bs,
563 + struct spi_message *msg, struct spi_transfer *xfer)
565 + struct spi_device *spi = msg->spi;
566 + struct bcm2708_spi_state state, *stp;
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);
584 + stp = spi->controller_state;
587 + reinit_completion(&bs->done);
588 + bs->tx_buf = xfer->tx_buf;
589 + bs->rx_buf = xfer->rx_buf;
590 + bs->len = xfer->len;
592 + cs = stp->cs | SPI_CS_INTR | SPI_CS_INTD | SPI_CS_TA;
594 + bcm2708_wr(bs, SPI_CLK, stp->cdiv);
595 + bcm2708_wr(bs, SPI_CS, cs);
597 + ret = wait_for_completion_timeout(&bs->done,
598 + msecs_to_jiffies(SPI_TIMEOUT_MS));
600 + dev_err(&spi->dev, "transfer timed out\n");
604 + if (xfer->delay_usecs)
605 + udelay(xfer->delay_usecs);
607 + if (list_is_last(&xfer->transfer_list, &msg->transfers) ||
609 + /* clear TA and interrupt flags */
610 + bcm2708_wr(bs, SPI_CS, stp->cs);
613 + msg->actual_length += (xfer->len - bs->len);
618 +static void bcm2708_work(struct work_struct *work)
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;
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);
632 + list_for_each_entry(xfer, &msg->transfers, transfer_list) {
633 + status = bcm2708_process_transfer(bs, msg, xfer);
638 + msg->status = status;
639 + msg->complete(msg->context);
641 + spin_lock_irqsave(&bs->lock, flags);
643 + spin_unlock_irqrestore(&bs->lock, flags);
646 +static int bcm2708_spi_setup(struct spi_device *spi)
648 + struct bcm2708_spi *bs = spi_master_get_devdata(spi->master);
649 + struct bcm2708_spi_state *state;
655 + if (!(spi->mode & SPI_NO_CS) &&
656 + (spi->chip_select > spi->master->num_chipselect)) {
658 + "setup: invalid chipselect %u (%u defined)\n",
659 + spi->chip_select, spi->master->num_chipselect);
663 + state = spi->controller_state;
665 + state = kzalloc(sizeof(*state), GFP_KERNEL);
669 + spi->controller_state = state;
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);
677 + spi->controller_state = NULL;
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);
689 +static int bcm2708_spi_transfer(struct spi_device *spi, struct spi_message *msg)
691 + struct bcm2708_spi *bs = spi_master_get_devdata(spi->master);
692 + struct spi_transfer *xfer;
694 + unsigned long flags;
696 + if (unlikely(list_empty(&msg->transfers)))
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");
708 + if (!xfer->bits_per_word || xfer->speed_hz)
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);
720 + msg->status = -EINPROGRESS;
721 + msg->actual_length = 0;
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);
731 +static void bcm2708_spi_cleanup(struct spi_device *spi)
733 + if (spi->controller_state) {
734 + kfree(spi->controller_state);
735 + spi->controller_state = NULL;
739 +static int bcm2708_spi_probe(struct platform_device *pdev)
741 + struct resource *regs;
742 + int irq, err = -ENOMEM;
744 + struct spi_master *master;
745 + struct bcm2708_spi *bs;
747 + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
749 + dev_err(&pdev->dev, "could not get IO memory\n");
753 + irq = platform_get_irq(pdev, 0);
755 + dev_err(&pdev->dev, "could not get IRQ\n");
759 + clk = clk_get(&pdev->dev, NULL);
761 + dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk));
762 + return PTR_ERR(clk);
765 + bcm2708_init_pinmode();
767 + master = spi_alloc_master(&pdev->dev, sizeof(*bs));
769 + dev_err(&pdev->dev, "spi_alloc_master() failed\n");
773 + /* the spi->mode bits understood by this driver: */
774 + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS;
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);
784 + bs = spi_master_get_devdata(master);
786 + spin_lock_init(&bs->lock);
787 + INIT_LIST_HEAD(&bs->queue);
788 + init_completion(&bs->done);
789 + INIT_WORK(&bs->work, bcm2708_work);
791 + bs->base = ioremap(regs->start, resource_size(regs));
793 + dev_err(&pdev->dev, "could not remap memory\n");
794 + goto out_master_put;
797 + bs->workq = create_singlethread_workqueue(dev_name(&pdev->dev));
799 + dev_err(&pdev->dev, "could not create workqueue\n");
805 + bs->stopping = false;
807 + err = request_irq(irq, bcm2708_spi_interrupt, 0, dev_name(&pdev->dev),
810 + dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
811 + goto out_workqueue;
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);
818 + err = spi_register_master(master);
820 + dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
824 + dev_info(&pdev->dev, "SPI Controller at 0x%08lx (irq %d)\n",
825 + (unsigned long)regs->start, irq);
830 + free_irq(bs->irq, master);
831 + clk_disable_unprepare(bs->clk);
833 + destroy_workqueue(bs->workq);
837 + spi_master_put(master);
843 +static int bcm2708_spi_remove(struct platform_device *pdev)
845 + struct spi_master *master = platform_get_drvdata(pdev);
846 + struct bcm2708_spi *bs = spi_master_get_devdata(master);
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);
854 + flush_work(&bs->work);
856 + clk_disable_unprepare(bs->clk);
858 + free_irq(bs->irq, master);
861 + spi_unregister_master(master);
866 +static const struct of_device_id bcm2708_spi_match[] = {
867 + { .compatible = "brcm,bcm2708-spi", },
870 +MODULE_DEVICE_TABLE(of, bcm2708_spi_match);
872 +static struct platform_driver bcm2708_spi_driver = {
875 + .owner = THIS_MODULE,
876 + .of_match_table = bcm2708_spi_match,
878 + .probe = bcm2708_spi_probe,
879 + .remove = bcm2708_spi_remove,
883 +static int __init bcm2708_spi_init(void)
885 + return platform_driver_probe(&bcm2708_spi_driver, bcm2708_spi_probe);
887 +module_init(bcm2708_spi_init);
889 +static void __exit bcm2708_spi_exit(void)
891 + platform_driver_unregister(&bcm2708_spi_driver);
893 +module_exit(bcm2708_spi_exit);
896 +//module_platform_driver(bcm2708_spi_driver);
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);