diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/Kconfig | 9 | ||||
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/spi-altera.c | 34 | ||||
-rw-r--r-- | drivers/spi/spi-atmel.c | 36 | ||||
-rw-r--r-- | drivers/spi/spi-bcm2835.c | 10 | ||||
-rw-r--r-- | drivers/spi/spi-bfin-v3.c | 971 | ||||
-rw-r--r-- | drivers/spi/spi-bitbang.c | 260 | ||||
-rw-r--r-- | drivers/spi/spi-davinci.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-oc-tiny.c | 22 | ||||
-rw-r--r-- | drivers/spi/spi-s3c64xx.c | 3 |
10 files changed, 1138 insertions, 210 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9da1ffadfd80..f3cc865df17b 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -88,10 +88,17 @@ config SPI_BCM2835 | |||
88 | 88 | ||
89 | config SPI_BFIN5XX | 89 | config SPI_BFIN5XX |
90 | tristate "SPI controller driver for ADI Blackfin5xx" | 90 | tristate "SPI controller driver for ADI Blackfin5xx" |
91 | depends on BLACKFIN | 91 | depends on BLACKFIN && !BF60x |
92 | help | 92 | help |
93 | This is the SPI controller master driver for Blackfin 5xx processor. | 93 | This is the SPI controller master driver for Blackfin 5xx processor. |
94 | 94 | ||
95 | config SPI_BFIN_V3 | ||
96 | tristate "SPI controller v3 for Blackfin" | ||
97 | depends on BF60x | ||
98 | help | ||
99 | This is the SPI controller v3 master driver | ||
100 | found on Blackfin 60x processor. | ||
101 | |||
95 | config SPI_BFIN_SPORT | 102 | config SPI_BFIN_SPORT |
96 | tristate "SPI bus via Blackfin SPORT" | 103 | tristate "SPI bus via Blackfin SPORT" |
97 | depends on BLACKFIN | 104 | depends on BLACKFIN |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 33f9c09561e7..7c4170263cd8 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -17,6 +17,7 @@ obj-$(CONFIG_SPI_AU1550) += spi-au1550.o | |||
17 | obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o | 17 | obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o |
18 | obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o | 18 | obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o |
19 | obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o | 19 | obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o |
20 | obj-$(CONFIG_SPI_BFIN_V3) += spi-bfin-v3.o | ||
20 | obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o | 21 | obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o |
21 | obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o | 22 | obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o |
22 | obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o | 23 | obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o |
diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c index 8a6bb37910da..156eb888655e 100644 --- a/drivers/spi/spi-altera.c +++ b/drivers/spi/spi-altera.c | |||
@@ -124,7 +124,7 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
124 | hw->tx = t->tx_buf; | 124 | hw->tx = t->tx_buf; |
125 | hw->rx = t->rx_buf; | 125 | hw->rx = t->rx_buf; |
126 | hw->count = 0; | 126 | hw->count = 0; |
127 | hw->bytes_per_word = t->bits_per_word / 8; | 127 | hw->bytes_per_word = DIV_ROUND_UP(t->bits_per_word, 8); |
128 | hw->len = t->len / hw->bytes_per_word; | 128 | hw->len = t->len / hw->bytes_per_word; |
129 | 129 | ||
130 | if (hw->irq >= 0) { | 130 | if (hw->irq >= 0) { |
@@ -140,12 +140,12 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
140 | hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK; | 140 | hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK; |
141 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); | 141 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); |
142 | } else { | 142 | } else { |
143 | /* send the first byte */ | 143 | while (hw->count < hw->len) { |
144 | writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA); | ||
145 | |||
146 | while (1) { | ||
147 | unsigned int rxd; | 144 | unsigned int rxd; |
148 | 145 | ||
146 | writel(hw_txbyte(hw, hw->count), | ||
147 | hw->base + ALTERA_SPI_TXDATA); | ||
148 | |||
149 | while (!(readl(hw->base + ALTERA_SPI_STATUS) & | 149 | while (!(readl(hw->base + ALTERA_SPI_STATUS) & |
150 | ALTERA_SPI_STATUS_RRDY_MSK)) | 150 | ALTERA_SPI_STATUS_RRDY_MSK)) |
151 | cpu_relax(); | 151 | cpu_relax(); |
@@ -164,14 +164,7 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
164 | } | 164 | } |
165 | 165 | ||
166 | hw->count++; | 166 | hw->count++; |
167 | |||
168 | if (hw->count < hw->len) | ||
169 | writel(hw_txbyte(hw, hw->count), | ||
170 | hw->base + ALTERA_SPI_TXDATA); | ||
171 | else | ||
172 | break; | ||
173 | } | 167 | } |
174 | |||
175 | } | 168 | } |
176 | 169 | ||
177 | return hw->count * hw->bytes_per_word; | 170 | return hw->count * hw->bytes_per_word; |
@@ -234,15 +227,11 @@ static int altera_spi_probe(struct platform_device *pdev) | |||
234 | 227 | ||
235 | /* find and map our resources */ | 228 | /* find and map our resources */ |
236 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 229 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
237 | if (!res) | 230 | hw->base = devm_ioremap_resource(&pdev->dev, res); |
238 | goto exit_busy; | 231 | if (IS_ERR(hw->base)) { |
239 | if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), | 232 | err = PTR_ERR(hw->base); |
240 | pdev->name)) | 233 | goto exit; |
241 | goto exit_busy; | 234 | } |
242 | hw->base = devm_ioremap_nocache(&pdev->dev, res->start, | ||
243 | resource_size(res)); | ||
244 | if (!hw->base) | ||
245 | goto exit_busy; | ||
246 | /* program defaults into the registers */ | 235 | /* program defaults into the registers */ |
247 | hw->imr = 0; /* disable spi interrupts */ | 236 | hw->imr = 0; /* disable spi interrupts */ |
248 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); | 237 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); |
@@ -269,9 +258,6 @@ static int altera_spi_probe(struct platform_device *pdev) | |||
269 | dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq); | 258 | dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq); |
270 | 259 | ||
271 | return 0; | 260 | return 0; |
272 | |||
273 | exit_busy: | ||
274 | err = -EBUSY; | ||
275 | exit: | 261 | exit: |
276 | spi_master_put(master); | 262 | spi_master_put(master); |
277 | return err; | 263 | return err; |
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index ea1ec009f44d..fd7cc566095a 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c | |||
@@ -360,12 +360,12 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) | |||
360 | gpio_set_value(asd->npcs_pin, !active); | 360 | gpio_set_value(asd->npcs_pin, !active); |
361 | } | 361 | } |
362 | 362 | ||
363 | static void atmel_spi_lock(struct atmel_spi *as) | 363 | static void atmel_spi_lock(struct atmel_spi *as) __acquires(&as->lock) |
364 | { | 364 | { |
365 | spin_lock_irqsave(&as->lock, as->flags); | 365 | spin_lock_irqsave(&as->lock, as->flags); |
366 | } | 366 | } |
367 | 367 | ||
368 | static void atmel_spi_unlock(struct atmel_spi *as) | 368 | static void atmel_spi_unlock(struct atmel_spi *as) __releases(&as->lock) |
369 | { | 369 | { |
370 | spin_unlock_irqrestore(&as->lock, as->flags); | 370 | spin_unlock_irqrestore(&as->lock, as->flags); |
371 | } | 371 | } |
@@ -629,9 +629,9 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, | |||
629 | goto err_dma; | 629 | goto err_dma; |
630 | 630 | ||
631 | dev_dbg(master->dev.parent, | 631 | dev_dbg(master->dev.parent, |
632 | " start dma xfer %p: len %u tx %p/%08x rx %p/%08x\n", | 632 | " start dma xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", |
633 | xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, | 633 | xfer, xfer->len, xfer->tx_buf, (unsigned long long)xfer->tx_dma, |
634 | xfer->rx_buf, xfer->rx_dma); | 634 | xfer->rx_buf, (unsigned long long)xfer->rx_dma); |
635 | 635 | ||
636 | /* Enable relevant interrupts */ | 636 | /* Enable relevant interrupts */ |
637 | spi_writel(as, IER, SPI_BIT(OVRES)); | 637 | spi_writel(as, IER, SPI_BIT(OVRES)); |
@@ -732,9 +732,10 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, | |||
732 | spi_writel(as, TCR, len); | 732 | spi_writel(as, TCR, len); |
733 | 733 | ||
734 | dev_dbg(&msg->spi->dev, | 734 | dev_dbg(&msg->spi->dev, |
735 | " start xfer %p: len %u tx %p/%08x rx %p/%08x\n", | 735 | " start xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", |
736 | xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, | 736 | xfer, xfer->len, xfer->tx_buf, |
737 | xfer->rx_buf, xfer->rx_dma); | 737 | (unsigned long long)xfer->tx_dma, xfer->rx_buf, |
738 | (unsigned long long)xfer->rx_dma); | ||
738 | } else { | 739 | } else { |
739 | xfer = as->next_transfer; | 740 | xfer = as->next_transfer; |
740 | remaining = as->next_remaining_bytes; | 741 | remaining = as->next_remaining_bytes; |
@@ -771,9 +772,10 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, | |||
771 | spi_writel(as, TNCR, len); | 772 | spi_writel(as, TNCR, len); |
772 | 773 | ||
773 | dev_dbg(&msg->spi->dev, | 774 | dev_dbg(&msg->spi->dev, |
774 | " next xfer %p: len %u tx %p/%08x rx %p/%08x\n", | 775 | " next xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", |
775 | xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, | 776 | xfer, xfer->len, xfer->tx_buf, |
776 | xfer->rx_buf, xfer->rx_dma); | 777 | (unsigned long long)xfer->tx_dma, xfer->rx_buf, |
778 | (unsigned long long)xfer->rx_dma); | ||
777 | ieval = SPI_BIT(ENDRX) | SPI_BIT(OVRES); | 779 | ieval = SPI_BIT(ENDRX) | SPI_BIT(OVRES); |
778 | } else { | 780 | } else { |
779 | spi_writel(as, RNCR, 0); | 781 | spi_writel(as, RNCR, 0); |
@@ -1579,7 +1581,9 @@ static int atmel_spi_probe(struct platform_device *pdev) | |||
1579 | goto out_unmap_regs; | 1581 | goto out_unmap_regs; |
1580 | 1582 | ||
1581 | /* Initialize the hardware */ | 1583 | /* Initialize the hardware */ |
1582 | clk_enable(clk); | 1584 | ret = clk_prepare_enable(clk); |
1585 | if (ret) | ||
1586 | goto out_unmap_regs; | ||
1583 | spi_writel(as, CR, SPI_BIT(SWRST)); | 1587 | spi_writel(as, CR, SPI_BIT(SWRST)); |
1584 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | 1588 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ |
1585 | if (as->caps.has_wdrbt) { | 1589 | if (as->caps.has_wdrbt) { |
@@ -1609,7 +1613,7 @@ out_free_dma: | |||
1609 | 1613 | ||
1610 | spi_writel(as, CR, SPI_BIT(SWRST)); | 1614 | spi_writel(as, CR, SPI_BIT(SWRST)); |
1611 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | 1615 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ |
1612 | clk_disable(clk); | 1616 | clk_disable_unprepare(clk); |
1613 | free_irq(irq, master); | 1617 | free_irq(irq, master); |
1614 | out_unmap_regs: | 1618 | out_unmap_regs: |
1615 | iounmap(as->regs); | 1619 | iounmap(as->regs); |
@@ -1661,7 +1665,7 @@ static int atmel_spi_remove(struct platform_device *pdev) | |||
1661 | dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer, | 1665 | dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer, |
1662 | as->buffer_dma); | 1666 | as->buffer_dma); |
1663 | 1667 | ||
1664 | clk_disable(as->clk); | 1668 | clk_disable_unprepare(as->clk); |
1665 | clk_put(as->clk); | 1669 | clk_put(as->clk); |
1666 | free_irq(as->irq, master); | 1670 | free_irq(as->irq, master); |
1667 | iounmap(as->regs); | 1671 | iounmap(as->regs); |
@@ -1678,7 +1682,7 @@ static int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
1678 | struct spi_master *master = platform_get_drvdata(pdev); | 1682 | struct spi_master *master = platform_get_drvdata(pdev); |
1679 | struct atmel_spi *as = spi_master_get_devdata(master); | 1683 | struct atmel_spi *as = spi_master_get_devdata(master); |
1680 | 1684 | ||
1681 | clk_disable(as->clk); | 1685 | clk_disable_unprepare(as->clk); |
1682 | return 0; | 1686 | return 0; |
1683 | } | 1687 | } |
1684 | 1688 | ||
@@ -1687,7 +1691,7 @@ static int atmel_spi_resume(struct platform_device *pdev) | |||
1687 | struct spi_master *master = platform_get_drvdata(pdev); | 1691 | struct spi_master *master = platform_get_drvdata(pdev); |
1688 | struct atmel_spi *as = spi_master_get_devdata(master); | 1692 | struct atmel_spi *as = spi_master_get_devdata(master); |
1689 | 1693 | ||
1690 | clk_enable(as->clk); | 1694 | return clk_prepare_enable(as->clk); |
1691 | return 0; | 1695 | return 0; |
1692 | } | 1696 | } |
1693 | 1697 | ||
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index a4185e492321..52c81481c5c7 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c | |||
@@ -314,7 +314,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) | |||
314 | platform_set_drvdata(pdev, master); | 314 | platform_set_drvdata(pdev, master); |
315 | 315 | ||
316 | master->mode_bits = BCM2835_SPI_MODE_BITS; | 316 | master->mode_bits = BCM2835_SPI_MODE_BITS; |
317 | master->bits_per_word_mask = BIT(8 - 1); | 317 | master->bits_per_word_mask = SPI_BPW_MASK(8); |
318 | master->bus_num = -1; | 318 | master->bus_num = -1; |
319 | master->num_chipselect = 3; | 319 | master->num_chipselect = 3; |
320 | master->transfer_one_message = bcm2835_spi_transfer_one; | 320 | master->transfer_one_message = bcm2835_spi_transfer_one; |
@@ -325,12 +325,6 @@ static int bcm2835_spi_probe(struct platform_device *pdev) | |||
325 | init_completion(&bs->done); | 325 | init_completion(&bs->done); |
326 | 326 | ||
327 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 327 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
328 | if (!res) { | ||
329 | dev_err(&pdev->dev, "could not get memory resource\n"); | ||
330 | err = -ENODEV; | ||
331 | goto out_master_put; | ||
332 | } | ||
333 | |||
334 | bs->regs = devm_ioremap_resource(&pdev->dev, res); | 328 | bs->regs = devm_ioremap_resource(&pdev->dev, res); |
335 | if (IS_ERR(bs->regs)) { | 329 | if (IS_ERR(bs->regs)) { |
336 | err = PTR_ERR(bs->regs); | 330 | err = PTR_ERR(bs->regs); |
@@ -383,7 +377,7 @@ out_master_put: | |||
383 | 377 | ||
384 | static int bcm2835_spi_remove(struct platform_device *pdev) | 378 | static int bcm2835_spi_remove(struct platform_device *pdev) |
385 | { | 379 | { |
386 | struct spi_master *master = platform_get_drvdata(pdev); | 380 | struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); |
387 | struct bcm2835_spi *bs = spi_master_get_devdata(master); | 381 | struct bcm2835_spi *bs = spi_master_get_devdata(master); |
388 | 382 | ||
389 | free_irq(bs->irq, master); | 383 | free_irq(bs->irq, master); |
diff --git a/drivers/spi/spi-bfin-v3.c b/drivers/spi/spi-bfin-v3.c new file mode 100644 index 000000000000..914f9fe1ec99 --- /dev/null +++ b/drivers/spi/spi-bfin-v3.c | |||
@@ -0,0 +1,971 @@ | |||
1 | /* | ||
2 | * Analog Devices SPI3 controller driver | ||
3 | * | ||
4 | * Copyright (c) 2013 Analog Devices Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/delay.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/dma-mapping.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/spi/spi.h> | ||
29 | #include <linux/types.h> | ||
30 | |||
31 | #include <asm/bfin_spi3.h> | ||
32 | #include <asm/cacheflush.h> | ||
33 | #include <asm/dma.h> | ||
34 | #include <asm/portmux.h> | ||
35 | |||
36 | enum bfin_spi_state { | ||
37 | START_STATE, | ||
38 | RUNNING_STATE, | ||
39 | DONE_STATE, | ||
40 | ERROR_STATE | ||
41 | }; | ||
42 | |||
43 | struct bfin_spi_master; | ||
44 | |||
45 | struct bfin_spi_transfer_ops { | ||
46 | void (*write) (struct bfin_spi_master *); | ||
47 | void (*read) (struct bfin_spi_master *); | ||
48 | void (*duplex) (struct bfin_spi_master *); | ||
49 | }; | ||
50 | |||
51 | /* runtime info for spi master */ | ||
52 | struct bfin_spi_master { | ||
53 | /* SPI framework hookup */ | ||
54 | struct spi_master *master; | ||
55 | |||
56 | /* Regs base of SPI controller */ | ||
57 | struct bfin_spi_regs __iomem *regs; | ||
58 | |||
59 | /* Pin request list */ | ||
60 | u16 *pin_req; | ||
61 | |||
62 | /* Message Transfer pump */ | ||
63 | struct tasklet_struct pump_transfers; | ||
64 | |||
65 | /* Current message transfer state info */ | ||
66 | struct spi_message *cur_msg; | ||
67 | struct spi_transfer *cur_transfer; | ||
68 | struct bfin_spi_device *cur_chip; | ||
69 | unsigned transfer_len; | ||
70 | |||
71 | /* transfer buffer */ | ||
72 | void *tx; | ||
73 | void *tx_end; | ||
74 | void *rx; | ||
75 | void *rx_end; | ||
76 | |||
77 | /* dma info */ | ||
78 | unsigned int tx_dma; | ||
79 | unsigned int rx_dma; | ||
80 | dma_addr_t tx_dma_addr; | ||
81 | dma_addr_t rx_dma_addr; | ||
82 | unsigned long dummy_buffer; /* used in unidirectional transfer */ | ||
83 | unsigned long tx_dma_size; | ||
84 | unsigned long rx_dma_size; | ||
85 | int tx_num; | ||
86 | int rx_num; | ||
87 | |||
88 | /* store register value for suspend/resume */ | ||
89 | u32 control; | ||
90 | u32 ssel; | ||
91 | |||
92 | unsigned long sclk; | ||
93 | enum bfin_spi_state state; | ||
94 | |||
95 | const struct bfin_spi_transfer_ops *ops; | ||
96 | }; | ||
97 | |||
98 | struct bfin_spi_device { | ||
99 | u32 control; | ||
100 | u32 clock; | ||
101 | u32 ssel; | ||
102 | |||
103 | u8 cs; | ||
104 | u16 cs_chg_udelay; /* Some devices require > 255usec delay */ | ||
105 | u32 cs_gpio; | ||
106 | u32 tx_dummy_val; /* tx value for rx only transfer */ | ||
107 | bool enable_dma; | ||
108 | const struct bfin_spi_transfer_ops *ops; | ||
109 | }; | ||
110 | |||
111 | static void bfin_spi_enable(struct bfin_spi_master *drv_data) | ||
112 | { | ||
113 | bfin_write_or(&drv_data->regs->control, SPI_CTL_EN); | ||
114 | } | ||
115 | |||
116 | static void bfin_spi_disable(struct bfin_spi_master *drv_data) | ||
117 | { | ||
118 | bfin_write_and(&drv_data->regs->control, ~SPI_CTL_EN); | ||
119 | } | ||
120 | |||
121 | /* Caculate the SPI_CLOCK register value based on input HZ */ | ||
122 | static u32 hz_to_spi_clock(u32 sclk, u32 speed_hz) | ||
123 | { | ||
124 | u32 spi_clock = sclk / speed_hz; | ||
125 | |||
126 | if (spi_clock) | ||
127 | spi_clock--; | ||
128 | return spi_clock; | ||
129 | } | ||
130 | |||
131 | static int bfin_spi_flush(struct bfin_spi_master *drv_data) | ||
132 | { | ||
133 | unsigned long limit = loops_per_jiffy << 1; | ||
134 | |||
135 | /* wait for stop and clear stat */ | ||
136 | while (!(bfin_read(&drv_data->regs->status) & SPI_STAT_SPIF) && --limit) | ||
137 | cpu_relax(); | ||
138 | |||
139 | bfin_write(&drv_data->regs->status, 0xFFFFFFFF); | ||
140 | |||
141 | return limit; | ||
142 | } | ||
143 | |||
144 | /* Chip select operation functions for cs_change flag */ | ||
145 | static void bfin_spi_cs_active(struct bfin_spi_master *drv_data, struct bfin_spi_device *chip) | ||
146 | { | ||
147 | if (likely(chip->cs < MAX_CTRL_CS)) | ||
148 | bfin_write_and(&drv_data->regs->ssel, ~chip->ssel); | ||
149 | else | ||
150 | gpio_set_value(chip->cs_gpio, 0); | ||
151 | } | ||
152 | |||
153 | static void bfin_spi_cs_deactive(struct bfin_spi_master *drv_data, | ||
154 | struct bfin_spi_device *chip) | ||
155 | { | ||
156 | if (likely(chip->cs < MAX_CTRL_CS)) | ||
157 | bfin_write_or(&drv_data->regs->ssel, chip->ssel); | ||
158 | else | ||
159 | gpio_set_value(chip->cs_gpio, 1); | ||
160 | |||
161 | /* Move delay here for consistency */ | ||
162 | if (chip->cs_chg_udelay) | ||
163 | udelay(chip->cs_chg_udelay); | ||
164 | } | ||
165 | |||
166 | /* enable or disable the pin muxed by GPIO and SPI CS to work as SPI CS */ | ||
167 | static inline void bfin_spi_cs_enable(struct bfin_spi_master *drv_data, | ||
168 | struct bfin_spi_device *chip) | ||
169 | { | ||
170 | if (chip->cs < MAX_CTRL_CS) | ||
171 | bfin_write_or(&drv_data->regs->ssel, chip->ssel >> 8); | ||
172 | } | ||
173 | |||
174 | static inline void bfin_spi_cs_disable(struct bfin_spi_master *drv_data, | ||
175 | struct bfin_spi_device *chip) | ||
176 | { | ||
177 | if (chip->cs < MAX_CTRL_CS) | ||
178 | bfin_write_and(&drv_data->regs->ssel, ~(chip->ssel >> 8)); | ||
179 | } | ||
180 | |||
181 | /* stop controller and re-config current chip*/ | ||
182 | static void bfin_spi_restore_state(struct bfin_spi_master *drv_data) | ||
183 | { | ||
184 | struct bfin_spi_device *chip = drv_data->cur_chip; | ||
185 | |||
186 | /* Clear status and disable clock */ | ||
187 | bfin_write(&drv_data->regs->status, 0xFFFFFFFF); | ||
188 | bfin_write(&drv_data->regs->rx_control, 0x0); | ||
189 | bfin_write(&drv_data->regs->tx_control, 0x0); | ||
190 | bfin_spi_disable(drv_data); | ||
191 | |||
192 | SSYNC(); | ||
193 | |||
194 | /* Load the registers */ | ||
195 | bfin_write(&drv_data->regs->control, chip->control); | ||
196 | bfin_write(&drv_data->regs->clock, chip->clock); | ||
197 | |||
198 | bfin_spi_enable(drv_data); | ||
199 | drv_data->tx_num = drv_data->rx_num = 0; | ||
200 | /* we always choose tx transfer initiate */ | ||
201 | bfin_write(&drv_data->regs->rx_control, SPI_RXCTL_REN); | ||
202 | bfin_write(&drv_data->regs->tx_control, | ||
203 | SPI_TXCTL_TEN | SPI_TXCTL_TTI); | ||
204 | bfin_spi_cs_active(drv_data, chip); | ||
205 | } | ||
206 | |||
207 | /* discard invalid rx data and empty rfifo */ | ||
208 | static inline void dummy_read(struct bfin_spi_master *drv_data) | ||
209 | { | ||
210 | while (!(bfin_read(&drv_data->regs->status) & SPI_STAT_RFE)) | ||
211 | bfin_read(&drv_data->regs->rfifo); | ||
212 | } | ||
213 | |||
214 | static void bfin_spi_u8_write(struct bfin_spi_master *drv_data) | ||
215 | { | ||
216 | dummy_read(drv_data); | ||
217 | while (drv_data->tx < drv_data->tx_end) { | ||
218 | bfin_write(&drv_data->regs->tfifo, (*(u8 *)(drv_data->tx++))); | ||
219 | while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) | ||
220 | cpu_relax(); | ||
221 | bfin_read(&drv_data->regs->rfifo); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | static void bfin_spi_u8_read(struct bfin_spi_master *drv_data) | ||
226 | { | ||
227 | u32 tx_val = drv_data->cur_chip->tx_dummy_val; | ||
228 | |||
229 | dummy_read(drv_data); | ||
230 | while (drv_data->rx < drv_data->rx_end) { | ||
231 | bfin_write(&drv_data->regs->tfifo, tx_val); | ||
232 | while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) | ||
233 | cpu_relax(); | ||
234 | *(u8 *)(drv_data->rx++) = bfin_read(&drv_data->regs->rfifo); | ||
235 | } | ||
236 | } | ||
237 | |||
238 | static void bfin_spi_u8_duplex(struct bfin_spi_master *drv_data) | ||
239 | { | ||
240 | dummy_read(drv_data); | ||
241 | while (drv_data->rx < drv_data->rx_end) { | ||
242 | bfin_write(&drv_data->regs->tfifo, (*(u8 *)(drv_data->tx++))); | ||
243 | while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) | ||
244 | cpu_relax(); | ||
245 | *(u8 *)(drv_data->rx++) = bfin_read(&drv_data->regs->rfifo); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | static const struct bfin_spi_transfer_ops bfin_bfin_spi_transfer_ops_u8 = { | ||
250 | .write = bfin_spi_u8_write, | ||
251 | .read = bfin_spi_u8_read, | ||
252 | .duplex = bfin_spi_u8_duplex, | ||
253 | }; | ||
254 | |||
255 | static void bfin_spi_u16_write(struct bfin_spi_master *drv_data) | ||
256 | { | ||
257 | dummy_read(drv_data); | ||
258 | while (drv_data->tx < drv_data->tx_end) { | ||
259 | bfin_write(&drv_data->regs->tfifo, (*(u16 *)drv_data->tx)); | ||
260 | drv_data->tx += 2; | ||
261 | while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) | ||
262 | cpu_relax(); | ||
263 | bfin_read(&drv_data->regs->rfifo); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | static void bfin_spi_u16_read(struct bfin_spi_master *drv_data) | ||
268 | { | ||
269 | u32 tx_val = drv_data->cur_chip->tx_dummy_val; | ||
270 | |||
271 | dummy_read(drv_data); | ||
272 | while (drv_data->rx < drv_data->rx_end) { | ||
273 | bfin_write(&drv_data->regs->tfifo, tx_val); | ||
274 | while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) | ||
275 | cpu_relax(); | ||
276 | *(u16 *)drv_data->rx = bfin_read(&drv_data->regs->rfifo); | ||
277 | drv_data->rx += 2; | ||
278 | } | ||
279 | } | ||
280 | |||
281 | static void bfin_spi_u16_duplex(struct bfin_spi_master *drv_data) | ||
282 | { | ||
283 | dummy_read(drv_data); | ||
284 | while (drv_data->rx < drv_data->rx_end) { | ||
285 | bfin_write(&drv_data->regs->tfifo, (*(u16 *)drv_data->tx)); | ||
286 | drv_data->tx += 2; | ||
287 | while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) | ||
288 | cpu_relax(); | ||
289 | *(u16 *)drv_data->rx = bfin_read(&drv_data->regs->rfifo); | ||
290 | drv_data->rx += 2; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | static const struct bfin_spi_transfer_ops bfin_bfin_spi_transfer_ops_u16 = { | ||
295 | .write = bfin_spi_u16_write, | ||
296 | .read = bfin_spi_u16_read, | ||
297 | .duplex = bfin_spi_u16_duplex, | ||
298 | }; | ||
299 | |||
300 | static void bfin_spi_u32_write(struct bfin_spi_master *drv_data) | ||
301 | { | ||
302 | dummy_read(drv_data); | ||
303 | while (drv_data->tx < drv_data->tx_end) { | ||
304 | bfin_write(&drv_data->regs->tfifo, (*(u32 *)drv_data->tx)); | ||
305 | drv_data->tx += 4; | ||
306 | while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) | ||
307 | cpu_relax(); | ||
308 | bfin_read(&drv_data->regs->rfifo); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | static void bfin_spi_u32_read(struct bfin_spi_master *drv_data) | ||
313 | { | ||
314 | u32 tx_val = drv_data->cur_chip->tx_dummy_val; | ||
315 | |||
316 | dummy_read(drv_data); | ||
317 | while (drv_data->rx < drv_data->rx_end) { | ||
318 | bfin_write(&drv_data->regs->tfifo, tx_val); | ||
319 | while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) | ||
320 | cpu_relax(); | ||
321 | *(u32 *)drv_data->rx = bfin_read(&drv_data->regs->rfifo); | ||
322 | drv_data->rx += 4; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | static void bfin_spi_u32_duplex(struct bfin_spi_master *drv_data) | ||
327 | { | ||
328 | dummy_read(drv_data); | ||
329 | while (drv_data->rx < drv_data->rx_end) { | ||
330 | bfin_write(&drv_data->regs->tfifo, (*(u32 *)drv_data->tx)); | ||
331 | drv_data->tx += 4; | ||
332 | while (bfin_read(&drv_data->regs->status) & SPI_STAT_RFE) | ||
333 | cpu_relax(); | ||
334 | *(u32 *)drv_data->rx = bfin_read(&drv_data->regs->rfifo); | ||
335 | drv_data->rx += 4; | ||
336 | } | ||
337 | } | ||
338 | |||
339 | static const struct bfin_spi_transfer_ops bfin_bfin_spi_transfer_ops_u32 = { | ||
340 | .write = bfin_spi_u32_write, | ||
341 | .read = bfin_spi_u32_read, | ||
342 | .duplex = bfin_spi_u32_duplex, | ||
343 | }; | ||
344 | |||
345 | |||
346 | /* test if there is more transfer to be done */ | ||
347 | static void bfin_spi_next_transfer(struct bfin_spi_master *drv) | ||
348 | { | ||
349 | struct spi_message *msg = drv->cur_msg; | ||
350 | struct spi_transfer *t = drv->cur_transfer; | ||
351 | |||
352 | /* Move to next transfer */ | ||
353 | if (t->transfer_list.next != &msg->transfers) { | ||
354 | drv->cur_transfer = list_entry(t->transfer_list.next, | ||
355 | struct spi_transfer, transfer_list); | ||
356 | drv->state = RUNNING_STATE; | ||
357 | } else { | ||
358 | drv->state = DONE_STATE; | ||
359 | drv->cur_transfer = NULL; | ||
360 | } | ||
361 | } | ||
362 | |||
363 | static void bfin_spi_giveback(struct bfin_spi_master *drv_data) | ||
364 | { | ||
365 | struct bfin_spi_device *chip = drv_data->cur_chip; | ||
366 | |||
367 | bfin_spi_cs_deactive(drv_data, chip); | ||
368 | spi_finalize_current_message(drv_data->master); | ||
369 | } | ||
370 | |||
371 | static int bfin_spi_setup_transfer(struct bfin_spi_master *drv) | ||
372 | { | ||
373 | struct spi_transfer *t = drv->cur_transfer; | ||
374 | u32 cr, cr_width; | ||
375 | |||
376 | if (t->tx_buf) { | ||
377 | drv->tx = (void *)t->tx_buf; | ||
378 | drv->tx_end = drv->tx + t->len; | ||
379 | } else { | ||
380 | drv->tx = NULL; | ||
381 | } | ||
382 | |||
383 | if (t->rx_buf) { | ||
384 | drv->rx = t->rx_buf; | ||
385 | drv->rx_end = drv->rx + t->len; | ||
386 | } else { | ||
387 | drv->rx = NULL; | ||
388 | } | ||
389 | |||
390 | drv->transfer_len = t->len; | ||
391 | |||
392 | /* bits per word setup */ | ||
393 | switch (t->bits_per_word) { | ||
394 | case 8: | ||
395 | cr_width = SPI_CTL_SIZE08; | ||
396 | drv->ops = &bfin_bfin_spi_transfer_ops_u8; | ||
397 | break; | ||
398 | case 16: | ||
399 | cr_width = SPI_CTL_SIZE16; | ||
400 | drv->ops = &bfin_bfin_spi_transfer_ops_u16; | ||
401 | break; | ||
402 | case 32: | ||
403 | cr_width = SPI_CTL_SIZE32; | ||
404 | drv->ops = &bfin_bfin_spi_transfer_ops_u32; | ||
405 | break; | ||
406 | default: | ||
407 | return -EINVAL; | ||
408 | } | ||
409 | cr = bfin_read(&drv->regs->control) & ~SPI_CTL_SIZE; | ||
410 | cr |= cr_width; | ||
411 | bfin_write(&drv->regs->control, cr); | ||
412 | |||
413 | /* speed setup */ | ||
414 | bfin_write(&drv->regs->clock, | ||
415 | hz_to_spi_clock(drv->sclk, t->speed_hz)); | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | static int bfin_spi_dma_xfer(struct bfin_spi_master *drv_data) | ||
420 | { | ||
421 | struct spi_transfer *t = drv_data->cur_transfer; | ||
422 | struct spi_message *msg = drv_data->cur_msg; | ||
423 | struct bfin_spi_device *chip = drv_data->cur_chip; | ||
424 | u32 dma_config; | ||
425 | unsigned long word_count, word_size; | ||
426 | void *tx_buf, *rx_buf; | ||
427 | |||
428 | switch (t->bits_per_word) { | ||
429 | case 8: | ||
430 | dma_config = WDSIZE_8 | PSIZE_8; | ||
431 | word_count = drv_data->transfer_len; | ||
432 | word_size = 1; | ||
433 | break; | ||
434 | case 16: | ||
435 | dma_config = WDSIZE_16 | PSIZE_16; | ||
436 | word_count = drv_data->transfer_len / 2; | ||
437 | word_size = 2; | ||
438 | break; | ||
439 | default: | ||
440 | dma_config = WDSIZE_32 | PSIZE_32; | ||
441 | word_count = drv_data->transfer_len / 4; | ||
442 | word_size = 4; | ||
443 | break; | ||
444 | } | ||
445 | |||
446 | if (!drv_data->rx) { | ||
447 | tx_buf = drv_data->tx; | ||
448 | rx_buf = &drv_data->dummy_buffer; | ||
449 | drv_data->tx_dma_size = drv_data->transfer_len; | ||
450 | drv_data->rx_dma_size = sizeof(drv_data->dummy_buffer); | ||
451 | set_dma_x_modify(drv_data->tx_dma, word_size); | ||
452 | set_dma_x_modify(drv_data->rx_dma, 0); | ||
453 | } else if (!drv_data->tx) { | ||
454 | drv_data->dummy_buffer = chip->tx_dummy_val; | ||
455 | tx_buf = &drv_data->dummy_buffer; | ||
456 | rx_buf = drv_data->rx; | ||
457 | drv_data->tx_dma_size = sizeof(drv_data->dummy_buffer); | ||
458 | drv_data->rx_dma_size = drv_data->transfer_len; | ||
459 | set_dma_x_modify(drv_data->tx_dma, 0); | ||
460 | set_dma_x_modify(drv_data->rx_dma, word_size); | ||
461 | } else { | ||
462 | tx_buf = drv_data->tx; | ||
463 | rx_buf = drv_data->rx; | ||
464 | drv_data->tx_dma_size = drv_data->rx_dma_size | ||
465 | = drv_data->transfer_len; | ||
466 | set_dma_x_modify(drv_data->tx_dma, word_size); | ||
467 | set_dma_x_modify(drv_data->rx_dma, word_size); | ||
468 | } | ||
469 | |||
470 | drv_data->tx_dma_addr = dma_map_single(&msg->spi->dev, | ||
471 | (void *)tx_buf, | ||
472 | drv_data->tx_dma_size, | ||
473 | DMA_TO_DEVICE); | ||
474 | if (dma_mapping_error(&msg->spi->dev, | ||
475 | drv_data->tx_dma_addr)) | ||
476 | return -ENOMEM; | ||
477 | |||
478 | drv_data->rx_dma_addr = dma_map_single(&msg->spi->dev, | ||
479 | (void *)rx_buf, | ||
480 | drv_data->rx_dma_size, | ||
481 | DMA_FROM_DEVICE); | ||
482 | if (dma_mapping_error(&msg->spi->dev, | ||
483 | drv_data->rx_dma_addr)) { | ||
484 | dma_unmap_single(&msg->spi->dev, | ||
485 | drv_data->tx_dma_addr, | ||
486 | drv_data->tx_dma_size, | ||
487 | DMA_TO_DEVICE); | ||
488 | return -ENOMEM; | ||
489 | } | ||
490 | |||
491 | dummy_read(drv_data); | ||
492 | set_dma_x_count(drv_data->tx_dma, word_count); | ||
493 | set_dma_x_count(drv_data->rx_dma, word_count); | ||
494 | set_dma_start_addr(drv_data->tx_dma, drv_data->tx_dma_addr); | ||
495 | set_dma_start_addr(drv_data->rx_dma, drv_data->rx_dma_addr); | ||
496 | dma_config |= DMAFLOW_STOP | RESTART | DI_EN; | ||
497 | set_dma_config(drv_data->tx_dma, dma_config); | ||
498 | set_dma_config(drv_data->rx_dma, dma_config | WNR); | ||
499 | enable_dma(drv_data->tx_dma); | ||
500 | enable_dma(drv_data->rx_dma); | ||
501 | SSYNC(); | ||
502 | |||
503 | bfin_write(&drv_data->regs->rx_control, SPI_RXCTL_REN | SPI_RXCTL_RDR_NE); | ||
504 | SSYNC(); | ||
505 | bfin_write(&drv_data->regs->tx_control, | ||
506 | SPI_TXCTL_TEN | SPI_TXCTL_TTI | SPI_TXCTL_TDR_NF); | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static int bfin_spi_pio_xfer(struct bfin_spi_master *drv_data) | ||
512 | { | ||
513 | struct spi_message *msg = drv_data->cur_msg; | ||
514 | |||
515 | if (!drv_data->rx) { | ||
516 | /* write only half duplex */ | ||
517 | drv_data->ops->write(drv_data); | ||
518 | if (drv_data->tx != drv_data->tx_end) | ||
519 | return -EIO; | ||
520 | } else if (!drv_data->tx) { | ||
521 | /* read only half duplex */ | ||
522 | drv_data->ops->read(drv_data); | ||
523 | if (drv_data->rx != drv_data->rx_end) | ||
524 | return -EIO; | ||
525 | } else { | ||
526 | /* full duplex mode */ | ||
527 | drv_data->ops->duplex(drv_data); | ||
528 | if (drv_data->tx != drv_data->tx_end) | ||
529 | return -EIO; | ||
530 | } | ||
531 | |||
532 | if (!bfin_spi_flush(drv_data)) | ||
533 | return -EIO; | ||
534 | msg->actual_length += drv_data->transfer_len; | ||
535 | tasklet_schedule(&drv_data->pump_transfers); | ||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | static void bfin_spi_pump_transfers(unsigned long data) | ||
540 | { | ||
541 | struct bfin_spi_master *drv_data = (struct bfin_spi_master *)data; | ||
542 | struct spi_message *msg = NULL; | ||
543 | struct spi_transfer *t = NULL; | ||
544 | struct bfin_spi_device *chip = NULL; | ||
545 | int ret; | ||
546 | |||
547 | /* Get current state information */ | ||
548 | msg = drv_data->cur_msg; | ||
549 | t = drv_data->cur_transfer; | ||
550 | chip = drv_data->cur_chip; | ||
551 | |||
552 | /* Handle for abort */ | ||
553 | if (drv_data->state == ERROR_STATE) { | ||
554 | msg->status = -EIO; | ||
555 | bfin_spi_giveback(drv_data); | ||
556 | return; | ||
557 | } | ||
558 | |||
559 | if (drv_data->state == RUNNING_STATE) { | ||
560 | if (t->delay_usecs) | ||
561 | udelay(t->delay_usecs); | ||
562 | if (t->cs_change) | ||
563 | bfin_spi_cs_deactive(drv_data, chip); | ||
564 | bfin_spi_next_transfer(drv_data); | ||
565 | t = drv_data->cur_transfer; | ||
566 | } | ||
567 | /* Handle end of message */ | ||
568 | if (drv_data->state == DONE_STATE) { | ||
569 | msg->status = 0; | ||
570 | bfin_spi_giveback(drv_data); | ||
571 | return; | ||
572 | } | ||
573 | |||
574 | if ((t->len == 0) || (t->tx_buf == NULL && t->rx_buf == NULL)) { | ||
575 | /* Schedule next transfer tasklet */ | ||
576 | tasklet_schedule(&drv_data->pump_transfers); | ||
577 | return; | ||
578 | } | ||
579 | |||
580 | ret = bfin_spi_setup_transfer(drv_data); | ||
581 | if (ret) { | ||
582 | msg->status = ret; | ||
583 | bfin_spi_giveback(drv_data); | ||
584 | } | ||
585 | |||
586 | bfin_write(&drv_data->regs->status, 0xFFFFFFFF); | ||
587 | bfin_spi_cs_active(drv_data, chip); | ||
588 | drv_data->state = RUNNING_STATE; | ||
589 | |||
590 | if (chip->enable_dma) | ||
591 | ret = bfin_spi_dma_xfer(drv_data); | ||
592 | else | ||
593 | ret = bfin_spi_pio_xfer(drv_data); | ||
594 | if (ret) { | ||
595 | msg->status = ret; | ||
596 | bfin_spi_giveback(drv_data); | ||
597 | } | ||
598 | } | ||
599 | |||
600 | static int bfin_spi_transfer_one_message(struct spi_master *master, | ||
601 | struct spi_message *m) | ||
602 | { | ||
603 | struct bfin_spi_master *drv_data = spi_master_get_devdata(master); | ||
604 | |||
605 | drv_data->cur_msg = m; | ||
606 | drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); | ||
607 | bfin_spi_restore_state(drv_data); | ||
608 | |||
609 | drv_data->state = START_STATE; | ||
610 | drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, | ||
611 | struct spi_transfer, transfer_list); | ||
612 | |||
613 | tasklet_schedule(&drv_data->pump_transfers); | ||
614 | return 0; | ||
615 | } | ||
616 | |||
617 | #define MAX_SPI_SSEL 7 | ||
618 | |||
619 | static const u16 ssel[][MAX_SPI_SSEL] = { | ||
620 | {P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3, | ||
621 | P_SPI0_SSEL4, P_SPI0_SSEL5, | ||
622 | P_SPI0_SSEL6, P_SPI0_SSEL7}, | ||
623 | |||
624 | {P_SPI1_SSEL1, P_SPI1_SSEL2, P_SPI1_SSEL3, | ||
625 | P_SPI1_SSEL4, P_SPI1_SSEL5, | ||
626 | P_SPI1_SSEL6, P_SPI1_SSEL7}, | ||
627 | |||
628 | {P_SPI2_SSEL1, P_SPI2_SSEL2, P_SPI2_SSEL3, | ||
629 | P_SPI2_SSEL4, P_SPI2_SSEL5, | ||
630 | P_SPI2_SSEL6, P_SPI2_SSEL7}, | ||
631 | }; | ||
632 | |||
633 | static int bfin_spi_setup(struct spi_device *spi) | ||
634 | { | ||
635 | struct bfin_spi_master *drv_data = spi_master_get_devdata(spi->master); | ||
636 | struct bfin_spi_device *chip = spi_get_ctldata(spi); | ||
637 | u32 bfin_ctl_reg = SPI_CTL_ODM | SPI_CTL_PSSE; | ||
638 | int ret = -EINVAL; | ||
639 | |||
640 | if (!chip) { | ||
641 | struct bfin_spi3_chip *chip_info = spi->controller_data; | ||
642 | |||
643 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
644 | if (!chip) { | ||
645 | dev_err(&spi->dev, "can not allocate chip data\n"); | ||
646 | return -ENOMEM; | ||
647 | } | ||
648 | if (chip_info) { | ||
649 | if (chip_info->control & ~bfin_ctl_reg) { | ||
650 | dev_err(&spi->dev, | ||
651 | "do not set bits that the SPI framework manages\n"); | ||
652 | goto error; | ||
653 | } | ||
654 | chip->control = chip_info->control; | ||
655 | chip->cs_chg_udelay = chip_info->cs_chg_udelay; | ||
656 | chip->tx_dummy_val = chip_info->tx_dummy_val; | ||
657 | chip->enable_dma = chip_info->enable_dma; | ||
658 | } | ||
659 | chip->cs = spi->chip_select; | ||
660 | if (chip->cs < MAX_CTRL_CS) { | ||
661 | chip->ssel = (1 << chip->cs) << 8; | ||
662 | ret = peripheral_request(ssel[spi->master->bus_num] | ||
663 | [chip->cs-1], dev_name(&spi->dev)); | ||
664 | if (ret) { | ||
665 | dev_err(&spi->dev, "peripheral_request() error\n"); | ||
666 | goto error; | ||
667 | } | ||
668 | } else { | ||
669 | chip->cs_gpio = chip->cs - MAX_CTRL_CS; | ||
670 | ret = gpio_request_one(chip->cs_gpio, GPIOF_OUT_INIT_HIGH, | ||
671 | dev_name(&spi->dev)); | ||
672 | if (ret) { | ||
673 | dev_err(&spi->dev, "gpio_request_one() error\n"); | ||
674 | goto error; | ||
675 | } | ||
676 | } | ||
677 | spi_set_ctldata(spi, chip); | ||
678 | } | ||
679 | |||
680 | /* force a default base state */ | ||
681 | chip->control &= bfin_ctl_reg; | ||
682 | |||
683 | if (spi->mode & SPI_CPOL) | ||
684 | chip->control |= SPI_CTL_CPOL; | ||
685 | if (spi->mode & SPI_CPHA) | ||
686 | chip->control |= SPI_CTL_CPHA; | ||
687 | if (spi->mode & SPI_LSB_FIRST) | ||
688 | chip->control |= SPI_CTL_LSBF; | ||
689 | chip->control |= SPI_CTL_MSTR; | ||
690 | /* we choose software to controll cs */ | ||
691 | chip->control &= ~SPI_CTL_ASSEL; | ||
692 | |||
693 | chip->clock = hz_to_spi_clock(drv_data->sclk, spi->max_speed_hz); | ||
694 | |||
695 | bfin_spi_cs_enable(drv_data, chip); | ||
696 | bfin_spi_cs_deactive(drv_data, chip); | ||
697 | |||
698 | return 0; | ||
699 | error: | ||
700 | if (chip) { | ||
701 | kfree(chip); | ||
702 | spi_set_ctldata(spi, NULL); | ||
703 | } | ||
704 | |||
705 | return ret; | ||
706 | } | ||
707 | |||
708 | static void bfin_spi_cleanup(struct spi_device *spi) | ||
709 | { | ||
710 | struct bfin_spi_device *chip = spi_get_ctldata(spi); | ||
711 | struct bfin_spi_master *drv_data = spi_master_get_devdata(spi->master); | ||
712 | |||
713 | if (!chip) | ||
714 | return; | ||
715 | |||
716 | if (chip->cs < MAX_CTRL_CS) { | ||
717 | peripheral_free(ssel[spi->master->bus_num] | ||
718 | [chip->cs-1]); | ||
719 | bfin_spi_cs_disable(drv_data, chip); | ||
720 | } else { | ||
721 | gpio_free(chip->cs_gpio); | ||
722 | } | ||
723 | |||
724 | kfree(chip); | ||
725 | spi_set_ctldata(spi, NULL); | ||
726 | } | ||
727 | |||
728 | static irqreturn_t bfin_spi_tx_dma_isr(int irq, void *dev_id) | ||
729 | { | ||
730 | struct bfin_spi_master *drv_data = dev_id; | ||
731 | u32 dma_stat = get_dma_curr_irqstat(drv_data->tx_dma); | ||
732 | |||
733 | clear_dma_irqstat(drv_data->tx_dma); | ||
734 | if (dma_stat & DMA_DONE) { | ||
735 | drv_data->tx_num++; | ||
736 | } else { | ||
737 | dev_err(&drv_data->master->dev, | ||
738 | "spi tx dma error: %d\n", dma_stat); | ||
739 | if (drv_data->tx) | ||
740 | drv_data->state = ERROR_STATE; | ||
741 | } | ||
742 | bfin_write_and(&drv_data->regs->tx_control, ~SPI_TXCTL_TDR_NF); | ||
743 | return IRQ_HANDLED; | ||
744 | } | ||
745 | |||
746 | static irqreturn_t bfin_spi_rx_dma_isr(int irq, void *dev_id) | ||
747 | { | ||
748 | struct bfin_spi_master *drv_data = dev_id; | ||
749 | struct spi_message *msg = drv_data->cur_msg; | ||
750 | u32 dma_stat = get_dma_curr_irqstat(drv_data->rx_dma); | ||
751 | |||
752 | clear_dma_irqstat(drv_data->rx_dma); | ||
753 | if (dma_stat & DMA_DONE) { | ||
754 | drv_data->rx_num++; | ||
755 | /* we may fail on tx dma */ | ||
756 | if (drv_data->state != ERROR_STATE) | ||
757 | msg->actual_length += drv_data->transfer_len; | ||
758 | } else { | ||
759 | drv_data->state = ERROR_STATE; | ||
760 | dev_err(&drv_data->master->dev, | ||
761 | "spi rx dma error: %d\n", dma_stat); | ||
762 | } | ||
763 | bfin_write(&drv_data->regs->tx_control, 0); | ||
764 | bfin_write(&drv_data->regs->rx_control, 0); | ||
765 | if (drv_data->rx_num != drv_data->tx_num) | ||
766 | dev_dbg(&drv_data->master->dev, | ||
767 | "dma interrupt missing: tx=%d,rx=%d\n", | ||
768 | drv_data->tx_num, drv_data->rx_num); | ||
769 | tasklet_schedule(&drv_data->pump_transfers); | ||
770 | return IRQ_HANDLED; | ||
771 | } | ||
772 | |||
773 | static int bfin_spi_probe(struct platform_device *pdev) | ||
774 | { | ||
775 | struct device *dev = &pdev->dev; | ||
776 | struct bfin_spi3_master *info = dev->platform_data; | ||
777 | struct spi_master *master; | ||
778 | struct bfin_spi_master *drv_data; | ||
779 | struct resource *mem, *res; | ||
780 | unsigned int tx_dma, rx_dma; | ||
781 | unsigned long sclk; | ||
782 | int ret; | ||
783 | |||
784 | if (!info) { | ||
785 | dev_err(dev, "platform data missing!\n"); | ||
786 | return -ENODEV; | ||
787 | } | ||
788 | |||
789 | sclk = get_sclk1(); | ||
790 | if (!sclk) { | ||
791 | dev_err(dev, "can not get sclk1\n"); | ||
792 | return -ENXIO; | ||
793 | } | ||
794 | |||
795 | /* get register base and tx/rx dma */ | ||
796 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
797 | if (!mem) { | ||
798 | dev_err(dev, "can not get register base\n"); | ||
799 | return -ENXIO; | ||
800 | } | ||
801 | |||
802 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
803 | if (!res) { | ||
804 | dev_err(dev, "can not get tx dma resource\n"); | ||
805 | return -ENXIO; | ||
806 | } | ||
807 | tx_dma = res->start; | ||
808 | |||
809 | res = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
810 | if (!res) { | ||
811 | dev_err(dev, "can not get rx dma resource\n"); | ||
812 | return -ENXIO; | ||
813 | } | ||
814 | rx_dma = res->start; | ||
815 | |||
816 | /* allocate master with space for drv_data */ | ||
817 | master = spi_alloc_master(dev, sizeof(*drv_data)); | ||
818 | if (!master) { | ||
819 | dev_err(dev, "can not alloc spi_master\n"); | ||
820 | return -ENOMEM; | ||
821 | } | ||
822 | platform_set_drvdata(pdev, master); | ||
823 | |||
824 | /* the mode bits supported by this driver */ | ||
825 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; | ||
826 | |||
827 | master->bus_num = pdev->id; | ||
828 | master->num_chipselect = info->num_chipselect; | ||
829 | master->cleanup = bfin_spi_cleanup; | ||
830 | master->setup = bfin_spi_setup; | ||
831 | master->transfer_one_message = bfin_spi_transfer_one_message; | ||
832 | master->bits_per_word_mask = BIT(32 - 1) | BIT(16 - 1) | BIT(8 - 1); | ||
833 | |||
834 | drv_data = spi_master_get_devdata(master); | ||
835 | drv_data->master = master; | ||
836 | drv_data->tx_dma = tx_dma; | ||
837 | drv_data->rx_dma = rx_dma; | ||
838 | drv_data->pin_req = info->pin_req; | ||
839 | drv_data->sclk = sclk; | ||
840 | |||
841 | drv_data->regs = devm_ioremap_resource(dev, mem); | ||
842 | if (IS_ERR(drv_data->regs)) { | ||
843 | ret = PTR_ERR(drv_data->regs); | ||
844 | goto err_put_master; | ||
845 | } | ||
846 | |||
847 | /* request tx and rx dma */ | ||
848 | ret = request_dma(tx_dma, "SPI_TX_DMA"); | ||
849 | if (ret) { | ||
850 | dev_err(dev, "can not request SPI TX DMA channel\n"); | ||
851 | goto err_put_master; | ||
852 | } | ||
853 | set_dma_callback(tx_dma, bfin_spi_tx_dma_isr, drv_data); | ||
854 | |||
855 | ret = request_dma(rx_dma, "SPI_RX_DMA"); | ||
856 | if (ret) { | ||
857 | dev_err(dev, "can not request SPI RX DMA channel\n"); | ||
858 | goto err_free_tx_dma; | ||
859 | } | ||
860 | set_dma_callback(drv_data->rx_dma, bfin_spi_rx_dma_isr, drv_data); | ||
861 | |||
862 | /* request CLK, MOSI and MISO */ | ||
863 | ret = peripheral_request_list(drv_data->pin_req, "bfin-spi3"); | ||
864 | if (ret < 0) { | ||
865 | dev_err(dev, "can not request spi pins\n"); | ||
866 | goto err_free_rx_dma; | ||
867 | } | ||
868 | |||
869 | bfin_write(&drv_data->regs->control, SPI_CTL_MSTR | SPI_CTL_CPHA); | ||
870 | bfin_write(&drv_data->regs->ssel, 0x0000FE00); | ||
871 | bfin_write(&drv_data->regs->delay, 0x0); | ||
872 | |||
873 | tasklet_init(&drv_data->pump_transfers, | ||
874 | bfin_spi_pump_transfers, (unsigned long)drv_data); | ||
875 | /* register with the SPI framework */ | ||
876 | ret = spi_register_master(master); | ||
877 | if (ret) { | ||
878 | dev_err(dev, "can not register spi master\n"); | ||
879 | goto err_free_peripheral; | ||
880 | } | ||
881 | |||
882 | return ret; | ||
883 | |||
884 | err_free_peripheral: | ||
885 | peripheral_free_list(drv_data->pin_req); | ||
886 | err_free_rx_dma: | ||
887 | free_dma(rx_dma); | ||
888 | err_free_tx_dma: | ||
889 | free_dma(tx_dma); | ||
890 | err_put_master: | ||
891 | spi_master_put(master); | ||
892 | |||
893 | return ret; | ||
894 | } | ||
895 | |||
896 | static int bfin_spi_remove(struct platform_device *pdev) | ||
897 | { | ||
898 | struct spi_master *master = platform_get_drvdata(pdev); | ||
899 | struct bfin_spi_master *drv_data = spi_master_get_devdata(master); | ||
900 | |||
901 | bfin_spi_disable(drv_data); | ||
902 | |||
903 | peripheral_free_list(drv_data->pin_req); | ||
904 | free_dma(drv_data->rx_dma); | ||
905 | free_dma(drv_data->tx_dma); | ||
906 | |||
907 | spi_unregister_master(drv_data->master); | ||
908 | return 0; | ||
909 | } | ||
910 | |||
911 | #ifdef CONFIG_PM | ||
912 | static int bfin_spi_suspend(struct device *dev) | ||
913 | { | ||
914 | struct spi_master *master = dev_get_drvdata(dev); | ||
915 | struct bfin_spi_master *drv_data = spi_master_get_devdata(master); | ||
916 | |||
917 | spi_master_suspend(master); | ||
918 | |||
919 | drv_data->control = bfin_read(&drv_data->regs->control); | ||
920 | drv_data->ssel = bfin_read(&drv_data->regs->ssel); | ||
921 | |||
922 | bfin_write(&drv_data->regs->control, SPI_CTL_MSTR | SPI_CTL_CPHA); | ||
923 | bfin_write(&drv_data->regs->ssel, 0x0000FE00); | ||
924 | dma_disable_irq(drv_data->rx_dma); | ||
925 | dma_disable_irq(drv_data->tx_dma); | ||
926 | |||
927 | return 0; | ||
928 | } | ||
929 | |||
930 | static int bfin_spi_resume(struct device *dev) | ||
931 | { | ||
932 | struct spi_master *master = dev_get_drvdata(dev); | ||
933 | struct bfin_spi_master *drv_data = spi_master_get_devdata(master); | ||
934 | int ret = 0; | ||
935 | |||
936 | /* bootrom may modify spi and dma status when resume in spi boot mode */ | ||
937 | disable_dma(drv_data->rx_dma); | ||
938 | |||
939 | dma_enable_irq(drv_data->rx_dma); | ||
940 | dma_enable_irq(drv_data->tx_dma); | ||
941 | bfin_write(&drv_data->regs->control, drv_data->control); | ||
942 | bfin_write(&drv_data->regs->ssel, drv_data->ssel); | ||
943 | |||
944 | ret = spi_master_resume(master); | ||
945 | if (ret) { | ||
946 | free_dma(drv_data->rx_dma); | ||
947 | free_dma(drv_data->tx_dma); | ||
948 | } | ||
949 | |||
950 | return ret; | ||
951 | } | ||
952 | #endif | ||
953 | static const struct dev_pm_ops bfin_spi_pm_ops = { | ||
954 | SET_SYSTEM_SLEEP_PM_OPS(bfin_spi_suspend, bfin_spi_resume) | ||
955 | }; | ||
956 | |||
957 | MODULE_ALIAS("platform:bfin-spi3"); | ||
958 | static struct platform_driver bfin_spi_driver = { | ||
959 | .driver = { | ||
960 | .name = "bfin-spi3", | ||
961 | .owner = THIS_MODULE, | ||
962 | .pm = &bfin_spi_pm_ops, | ||
963 | }, | ||
964 | .remove = bfin_spi_remove, | ||
965 | }; | ||
966 | |||
967 | module_platform_driver_probe(bfin_spi_driver, bfin_spi_probe); | ||
968 | |||
969 | MODULE_DESCRIPTION("Analog Devices SPI3 controller driver"); | ||
970 | MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>"); | ||
971 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index a63d7da3bfe2..e3946e44e076 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c | |||
@@ -255,150 +255,140 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
255 | * Drivers can provide word-at-a-time i/o primitives, or provide | 255 | * Drivers can provide word-at-a-time i/o primitives, or provide |
256 | * transfer-at-a-time ones to leverage dma or fifo hardware. | 256 | * transfer-at-a-time ones to leverage dma or fifo hardware. |
257 | */ | 257 | */ |
258 | static void bitbang_work(struct work_struct *work) | 258 | |
259 | static int spi_bitbang_prepare_hardware(struct spi_master *spi) | ||
259 | { | 260 | { |
260 | struct spi_bitbang *bitbang = | 261 | struct spi_bitbang *bitbang; |
261 | container_of(work, struct spi_bitbang, work); | ||
262 | unsigned long flags; | 262 | unsigned long flags; |
263 | struct spi_message *m, *_m; | 263 | |
264 | bitbang = spi_master_get_devdata(spi); | ||
264 | 265 | ||
265 | spin_lock_irqsave(&bitbang->lock, flags); | 266 | spin_lock_irqsave(&bitbang->lock, flags); |
266 | bitbang->busy = 1; | 267 | bitbang->busy = 1; |
267 | list_for_each_entry_safe(m, _m, &bitbang->queue, queue) { | 268 | spin_unlock_irqrestore(&bitbang->lock, flags); |
268 | struct spi_device *spi; | ||
269 | unsigned nsecs; | ||
270 | struct spi_transfer *t = NULL; | ||
271 | unsigned tmp; | ||
272 | unsigned cs_change; | ||
273 | int status; | ||
274 | int do_setup = -1; | ||
275 | |||
276 | list_del(&m->queue); | ||
277 | spin_unlock_irqrestore(&bitbang->lock, flags); | ||
278 | |||
279 | /* FIXME this is made-up ... the correct value is known to | ||
280 | * word-at-a-time bitbang code, and presumably chipselect() | ||
281 | * should enforce these requirements too? | ||
282 | */ | ||
283 | nsecs = 100; | ||
284 | 269 | ||
285 | spi = m->spi; | 270 | return 0; |
286 | tmp = 0; | 271 | } |
287 | cs_change = 1; | ||
288 | status = 0; | ||
289 | 272 | ||
290 | list_for_each_entry (t, &m->transfers, transfer_list) { | 273 | static int spi_bitbang_transfer_one(struct spi_master *master, |
291 | 274 | struct spi_message *m) | |
292 | /* override speed or wordsize? */ | 275 | { |
293 | if (t->speed_hz || t->bits_per_word) | 276 | struct spi_bitbang *bitbang; |
294 | do_setup = 1; | 277 | unsigned nsecs; |
295 | 278 | struct spi_transfer *t = NULL; | |
296 | /* init (-1) or override (1) transfer params */ | 279 | unsigned cs_change; |
297 | if (do_setup != 0) { | 280 | int status; |
298 | status = bitbang->setup_transfer(spi, t); | 281 | int do_setup = -1; |
299 | if (status < 0) | 282 | struct spi_device *spi = m->spi; |
300 | break; | 283 | |
301 | if (do_setup == -1) | 284 | bitbang = spi_master_get_devdata(master); |
302 | do_setup = 0; | 285 | |
303 | } | 286 | /* FIXME this is made-up ... the correct value is known to |
304 | 287 | * word-at-a-time bitbang code, and presumably chipselect() | |
305 | /* set up default clock polarity, and activate chip; | 288 | * should enforce these requirements too? |
306 | * this implicitly updates clock and spi modes as | 289 | */ |
307 | * previously recorded for this device via setup(). | 290 | nsecs = 100; |
308 | * (and also deselects any other chip that might be | ||
309 | * selected ...) | ||
310 | */ | ||
311 | if (cs_change) { | ||
312 | bitbang->chipselect(spi, BITBANG_CS_ACTIVE); | ||
313 | ndelay(nsecs); | ||
314 | } | ||
315 | cs_change = t->cs_change; | ||
316 | if (!t->tx_buf && !t->rx_buf && t->len) { | ||
317 | status = -EINVAL; | ||
318 | break; | ||
319 | } | ||
320 | 291 | ||
321 | /* transfer data. the lower level code handles any | 292 | cs_change = 1; |
322 | * new dma mappings it needs. our caller always gave | 293 | status = 0; |
323 | * us dma-safe buffers. | 294 | |
324 | */ | 295 | list_for_each_entry (t, &m->transfers, transfer_list) { |
325 | if (t->len) { | 296 | |
326 | /* REVISIT dma API still needs a designated | 297 | /* override speed or wordsize? */ |
327 | * DMA_ADDR_INVALID; ~0 might be better. | 298 | if (t->speed_hz || t->bits_per_word) |
328 | */ | 299 | do_setup = 1; |
329 | if (!m->is_dma_mapped) | 300 | |
330 | t->rx_dma = t->tx_dma = 0; | 301 | /* init (-1) or override (1) transfer params */ |
331 | status = bitbang->txrx_bufs(spi, t); | 302 | if (do_setup != 0) { |
332 | } | 303 | status = bitbang->setup_transfer(spi, t); |
333 | if (status > 0) | 304 | if (status < 0) |
334 | m->actual_length += status; | ||
335 | if (status != t->len) { | ||
336 | /* always report some kind of error */ | ||
337 | if (status >= 0) | ||
338 | status = -EREMOTEIO; | ||
339 | break; | 305 | break; |
340 | } | 306 | if (do_setup == -1) |
341 | status = 0; | 307 | do_setup = 0; |
342 | |||
343 | /* protocol tweaks before next transfer */ | ||
344 | if (t->delay_usecs) | ||
345 | udelay(t->delay_usecs); | ||
346 | |||
347 | if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) { | ||
348 | /* sometimes a short mid-message deselect of the chip | ||
349 | * may be needed to terminate a mode or command | ||
350 | */ | ||
351 | ndelay(nsecs); | ||
352 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); | ||
353 | ndelay(nsecs); | ||
354 | } | ||
355 | } | 308 | } |
356 | 309 | ||
357 | m->status = status; | 310 | /* set up default clock polarity, and activate chip; |
358 | m->complete(m->context); | 311 | * this implicitly updates clock and spi modes as |
312 | * previously recorded for this device via setup(). | ||
313 | * (and also deselects any other chip that might be | ||
314 | * selected ...) | ||
315 | */ | ||
316 | if (cs_change) { | ||
317 | bitbang->chipselect(spi, BITBANG_CS_ACTIVE); | ||
318 | ndelay(nsecs); | ||
319 | } | ||
320 | cs_change = t->cs_change; | ||
321 | if (!t->tx_buf && !t->rx_buf && t->len) { | ||
322 | status = -EINVAL; | ||
323 | break; | ||
324 | } | ||
359 | 325 | ||
360 | /* normally deactivate chipselect ... unless no error and | 326 | /* transfer data. the lower level code handles any |
361 | * cs_change has hinted that the next message will probably | 327 | * new dma mappings it needs. our caller always gave |
362 | * be for this chip too. | 328 | * us dma-safe buffers. |
363 | */ | 329 | */ |
364 | if (!(status == 0 && cs_change)) { | 330 | if (t->len) { |
331 | /* REVISIT dma API still needs a designated | ||
332 | * DMA_ADDR_INVALID; ~0 might be better. | ||
333 | */ | ||
334 | if (!m->is_dma_mapped) | ||
335 | t->rx_dma = t->tx_dma = 0; | ||
336 | status = bitbang->txrx_bufs(spi, t); | ||
337 | } | ||
338 | if (status > 0) | ||
339 | m->actual_length += status; | ||
340 | if (status != t->len) { | ||
341 | /* always report some kind of error */ | ||
342 | if (status >= 0) | ||
343 | status = -EREMOTEIO; | ||
344 | break; | ||
345 | } | ||
346 | status = 0; | ||
347 | |||
348 | /* protocol tweaks before next transfer */ | ||
349 | if (t->delay_usecs) | ||
350 | udelay(t->delay_usecs); | ||
351 | |||
352 | if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) { | ||
353 | /* sometimes a short mid-message deselect of the chip | ||
354 | * may be needed to terminate a mode or command | ||
355 | */ | ||
365 | ndelay(nsecs); | 356 | ndelay(nsecs); |
366 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); | 357 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); |
367 | ndelay(nsecs); | 358 | ndelay(nsecs); |
368 | } | 359 | } |
360 | } | ||
361 | |||
362 | m->status = status; | ||
369 | 363 | ||
370 | spin_lock_irqsave(&bitbang->lock, flags); | 364 | /* normally deactivate chipselect ... unless no error and |
365 | * cs_change has hinted that the next message will probably | ||
366 | * be for this chip too. | ||
367 | */ | ||
368 | if (!(status == 0 && cs_change)) { | ||
369 | ndelay(nsecs); | ||
370 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); | ||
371 | ndelay(nsecs); | ||
371 | } | 372 | } |
372 | bitbang->busy = 0; | 373 | |
373 | spin_unlock_irqrestore(&bitbang->lock, flags); | 374 | spi_finalize_current_message(master); |
375 | |||
376 | return status; | ||
374 | } | 377 | } |
375 | 378 | ||
376 | /** | 379 | static int spi_bitbang_unprepare_hardware(struct spi_master *spi) |
377 | * spi_bitbang_transfer - default submit to transfer queue | ||
378 | */ | ||
379 | int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m) | ||
380 | { | 380 | { |
381 | struct spi_bitbang *bitbang; | 381 | struct spi_bitbang *bitbang; |
382 | unsigned long flags; | 382 | unsigned long flags; |
383 | int status = 0; | ||
384 | 383 | ||
385 | m->actual_length = 0; | 384 | bitbang = spi_master_get_devdata(spi); |
386 | m->status = -EINPROGRESS; | ||
387 | |||
388 | bitbang = spi_master_get_devdata(spi->master); | ||
389 | 385 | ||
390 | spin_lock_irqsave(&bitbang->lock, flags); | 386 | spin_lock_irqsave(&bitbang->lock, flags); |
391 | if (!spi->max_speed_hz) | 387 | bitbang->busy = 0; |
392 | status = -ENETDOWN; | ||
393 | else { | ||
394 | list_add_tail(&m->queue, &bitbang->queue); | ||
395 | queue_work(bitbang->workqueue, &bitbang->work); | ||
396 | } | ||
397 | spin_unlock_irqrestore(&bitbang->lock, flags); | 388 | spin_unlock_irqrestore(&bitbang->lock, flags); |
398 | 389 | ||
399 | return status; | 390 | return 0; |
400 | } | 391 | } |
401 | EXPORT_SYMBOL_GPL(spi_bitbang_transfer); | ||
402 | 392 | ||
403 | /*----------------------------------------------------------------------*/ | 393 | /*----------------------------------------------------------------------*/ |
404 | 394 | ||
@@ -428,20 +418,22 @@ EXPORT_SYMBOL_GPL(spi_bitbang_transfer); | |||
428 | int spi_bitbang_start(struct spi_bitbang *bitbang) | 418 | int spi_bitbang_start(struct spi_bitbang *bitbang) |
429 | { | 419 | { |
430 | struct spi_master *master = bitbang->master; | 420 | struct spi_master *master = bitbang->master; |
431 | int status; | ||
432 | 421 | ||
433 | if (!master || !bitbang->chipselect) | 422 | if (!master || !bitbang->chipselect) |
434 | return -EINVAL; | 423 | return -EINVAL; |
435 | 424 | ||
436 | INIT_WORK(&bitbang->work, bitbang_work); | ||
437 | spin_lock_init(&bitbang->lock); | 425 | spin_lock_init(&bitbang->lock); |
438 | INIT_LIST_HEAD(&bitbang->queue); | ||
439 | 426 | ||
440 | if (!master->mode_bits) | 427 | if (!master->mode_bits) |
441 | master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; | 428 | master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; |
442 | 429 | ||
443 | if (!master->transfer) | 430 | if (master->transfer || master->transfer_one_message) |
444 | master->transfer = spi_bitbang_transfer; | 431 | return -EINVAL; |
432 | |||
433 | master->prepare_transfer_hardware = spi_bitbang_prepare_hardware; | ||
434 | master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware; | ||
435 | master->transfer_one_message = spi_bitbang_transfer_one; | ||
436 | |||
445 | if (!bitbang->txrx_bufs) { | 437 | if (!bitbang->txrx_bufs) { |
446 | bitbang->use_dma = 0; | 438 | bitbang->use_dma = 0; |
447 | bitbang->txrx_bufs = spi_bitbang_bufs; | 439 | bitbang->txrx_bufs = spi_bitbang_bufs; |
@@ -452,34 +444,12 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) | |||
452 | master->setup = spi_bitbang_setup; | 444 | master->setup = spi_bitbang_setup; |
453 | master->cleanup = spi_bitbang_cleanup; | 445 | master->cleanup = spi_bitbang_cleanup; |
454 | } | 446 | } |
455 | } else if (!master->setup) | ||
456 | return -EINVAL; | ||
457 | if (master->transfer == spi_bitbang_transfer && | ||
458 | !bitbang->setup_transfer) | ||
459 | return -EINVAL; | ||
460 | |||
461 | /* this task is the only thing to touch the SPI bits */ | ||
462 | bitbang->busy = 0; | ||
463 | bitbang->workqueue = create_singlethread_workqueue( | ||
464 | dev_name(master->dev.parent)); | ||
465 | if (bitbang->workqueue == NULL) { | ||
466 | status = -EBUSY; | ||
467 | goto err1; | ||
468 | } | 447 | } |
469 | 448 | ||
470 | /* driver may get busy before register() returns, especially | 449 | /* driver may get busy before register() returns, especially |
471 | * if someone registered boardinfo for devices | 450 | * if someone registered boardinfo for devices |
472 | */ | 451 | */ |
473 | status = spi_register_master(master); | 452 | return spi_register_master(master); |
474 | if (status < 0) | ||
475 | goto err2; | ||
476 | |||
477 | return status; | ||
478 | |||
479 | err2: | ||
480 | destroy_workqueue(bitbang->workqueue); | ||
481 | err1: | ||
482 | return status; | ||
483 | } | 453 | } |
484 | EXPORT_SYMBOL_GPL(spi_bitbang_start); | 454 | EXPORT_SYMBOL_GPL(spi_bitbang_start); |
485 | 455 | ||
@@ -490,10 +460,6 @@ int spi_bitbang_stop(struct spi_bitbang *bitbang) | |||
490 | { | 460 | { |
491 | spi_unregister_master(bitbang->master); | 461 | spi_unregister_master(bitbang->master); |
492 | 462 | ||
493 | WARN_ON(!list_empty(&bitbang->queue)); | ||
494 | |||
495 | destroy_workqueue(bitbang->workqueue); | ||
496 | |||
497 | return 0; | 463 | return 0; |
498 | } | 464 | } |
499 | EXPORT_SYMBOL_GPL(spi_bitbang_stop); | 465 | EXPORT_SYMBOL_GPL(spi_bitbang_stop); |
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 222d3e37fc28..707966bd5610 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
@@ -609,7 +609,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
609 | else | 609 | else |
610 | buf = (void *)t->tx_buf; | 610 | buf = (void *)t->tx_buf; |
611 | t->tx_dma = dma_map_single(&spi->dev, buf, | 611 | t->tx_dma = dma_map_single(&spi->dev, buf, |
612 | t->len, DMA_FROM_DEVICE); | 612 | t->len, DMA_TO_DEVICE); |
613 | if (!t->tx_dma) { | 613 | if (!t->tx_dma) { |
614 | ret = -EFAULT; | 614 | ret = -EFAULT; |
615 | goto err_tx_map; | 615 | goto err_tx_map; |
diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c index 58deb79d046b..d36ba907743d 100644 --- a/drivers/spi/spi-oc-tiny.c +++ b/drivers/spi/spi-oc-tiny.c | |||
@@ -315,15 +315,11 @@ static int tiny_spi_probe(struct platform_device *pdev) | |||
315 | 315 | ||
316 | /* find and map our resources */ | 316 | /* find and map our resources */ |
317 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 317 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
318 | if (!res) | 318 | hw->base = devm_ioremap_resource(&pdev->dev, res); |
319 | goto exit_busy; | 319 | if (IS_ERR(hw->base)) { |
320 | if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), | 320 | err = PTR_ERR(hw->base); |
321 | pdev->name)) | 321 | goto exit; |
322 | goto exit_busy; | 322 | } |
323 | hw->base = devm_ioremap_nocache(&pdev->dev, res->start, | ||
324 | resource_size(res)); | ||
325 | if (!hw->base) | ||
326 | goto exit_busy; | ||
327 | /* irq is optional */ | 323 | /* irq is optional */ |
328 | hw->irq = platform_get_irq(pdev, 0); | 324 | hw->irq = platform_get_irq(pdev, 0); |
329 | if (hw->irq >= 0) { | 325 | if (hw->irq >= 0) { |
@@ -337,8 +333,10 @@ static int tiny_spi_probe(struct platform_device *pdev) | |||
337 | if (platp) { | 333 | if (platp) { |
338 | hw->gpio_cs_count = platp->gpio_cs_count; | 334 | hw->gpio_cs_count = platp->gpio_cs_count; |
339 | hw->gpio_cs = platp->gpio_cs; | 335 | hw->gpio_cs = platp->gpio_cs; |
340 | if (platp->gpio_cs_count && !platp->gpio_cs) | 336 | if (platp->gpio_cs_count && !platp->gpio_cs) { |
341 | goto exit_busy; | 337 | err = -EBUSY; |
338 | goto exit; | ||
339 | } | ||
342 | hw->freq = platp->freq; | 340 | hw->freq = platp->freq; |
343 | hw->baudwidth = platp->baudwidth; | 341 | hw->baudwidth = platp->baudwidth; |
344 | } else { | 342 | } else { |
@@ -365,8 +363,6 @@ static int tiny_spi_probe(struct platform_device *pdev) | |||
365 | exit_gpio: | 363 | exit_gpio: |
366 | while (i-- > 0) | 364 | while (i-- > 0) |
367 | gpio_free(hw->gpio_cs[i]); | 365 | gpio_free(hw->gpio_cs[i]); |
368 | exit_busy: | ||
369 | err = -EBUSY; | ||
370 | exit: | 366 | exit: |
371 | spi_master_put(master); | 367 | spi_master_put(master); |
372 | return err; | 368 | return err; |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index eb53df27e7ea..63e2070c6c14 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
@@ -434,6 +434,9 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) | |||
434 | dma_cap_mask_t mask; | 434 | dma_cap_mask_t mask; |
435 | int ret; | 435 | int ret; |
436 | 436 | ||
437 | if (is_polling(sdd)) | ||
438 | return 0; | ||
439 | |||
437 | dma_cap_zero(mask); | 440 | dma_cap_zero(mask); |
438 | dma_cap_set(DMA_SLAVE, mask); | 441 | dma_cap_set(DMA_SLAVE, mask); |
439 | 442 | ||