diff options
Diffstat (limited to 'drivers/spi')
30 files changed, 2416 insertions, 399 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index bb233a9cbad2..fc14b8dea0d7 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -53,6 +53,12 @@ if SPI_MASTER | |||
53 | 53 | ||
54 | comment "SPI Master Controller Drivers" | 54 | comment "SPI Master Controller Drivers" |
55 | 55 | ||
56 | config SPI_ALTERA | ||
57 | tristate "Altera SPI Controller" | ||
58 | select SPI_BITBANG | ||
59 | help | ||
60 | This is the driver for the Altera SPI Controller. | ||
61 | |||
56 | config SPI_ATH79 | 62 | config SPI_ATH79 |
57 | tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver" | 63 | tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver" |
58 | depends on ATH79 && GENERIC_GPIO | 64 | depends on ATH79 && GENERIC_GPIO |
@@ -161,13 +167,13 @@ config SPI_IMX_VER_0_0 | |||
161 | def_bool y if SOC_IMX21 || SOC_IMX27 | 167 | def_bool y if SOC_IMX21 || SOC_IMX27 |
162 | 168 | ||
163 | config SPI_IMX_VER_0_4 | 169 | config SPI_IMX_VER_0_4 |
164 | def_bool y if ARCH_MX31 | 170 | def_bool y if SOC_IMX31 |
165 | 171 | ||
166 | config SPI_IMX_VER_0_7 | 172 | config SPI_IMX_VER_0_7 |
167 | def_bool y if ARCH_MX25 || ARCH_MX35 || ARCH_MX51 || ARCH_MX53 | 173 | def_bool y if ARCH_MX25 || SOC_IMX35 || SOC_IMX51 || SOC_IMX53 |
168 | 174 | ||
169 | config SPI_IMX_VER_2_3 | 175 | config SPI_IMX_VER_2_3 |
170 | def_bool y if ARCH_MX51 || ARCH_MX53 | 176 | def_bool y if SOC_IMX51 || SOC_IMX53 |
171 | 177 | ||
172 | config SPI_IMX | 178 | config SPI_IMX |
173 | tristate "Freescale i.MX SPI controllers" | 179 | tristate "Freescale i.MX SPI controllers" |
@@ -231,6 +237,13 @@ config SPI_FSL_ESPI | |||
231 | From MPC8536, 85xx platform uses the controller, and all P10xx, | 237 | From MPC8536, 85xx platform uses the controller, and all P10xx, |
232 | P20xx, P30xx,P40xx, P50xx uses this controller. | 238 | P20xx, P30xx,P40xx, P50xx uses this controller. |
233 | 239 | ||
240 | config SPI_OC_TINY | ||
241 | tristate "OpenCores tiny SPI" | ||
242 | depends on GENERIC_GPIO | ||
243 | select SPI_BITBANG | ||
244 | help | ||
245 | This is the driver for OpenCores tiny SPI master controller. | ||
246 | |||
234 | config SPI_OMAP_UWIRE | 247 | config SPI_OMAP_UWIRE |
235 | tristate "OMAP1 MicroWire" | 248 | tristate "OMAP1 MicroWire" |
236 | depends on ARCH_OMAP1 | 249 | depends on ARCH_OMAP1 |
@@ -330,6 +343,12 @@ config SPI_SH_MSIOF | |||
330 | help | 343 | help |
331 | SPI driver for SuperH MSIOF blocks. | 344 | SPI driver for SuperH MSIOF blocks. |
332 | 345 | ||
346 | config SPI_SH | ||
347 | tristate "SuperH SPI controller" | ||
348 | depends on SUPERH | ||
349 | help | ||
350 | SPI driver for SuperH SPI blocks. | ||
351 | |||
333 | config SPI_SH_SCI | 352 | config SPI_SH_SCI |
334 | tristate "SuperH SCI SPI controller" | 353 | tristate "SuperH SCI SPI controller" |
335 | depends on SUPERH | 354 | depends on SUPERH |
@@ -350,6 +369,16 @@ config SPI_TEGRA | |||
350 | help | 369 | help |
351 | SPI driver for NVidia Tegra SoCs | 370 | SPI driver for NVidia Tegra SoCs |
352 | 371 | ||
372 | config SPI_TI_SSP | ||
373 | tristate "TI Sequencer Serial Port - SPI Support" | ||
374 | depends on MFD_TI_SSP | ||
375 | help | ||
376 | This selects an SPI master implementation using a TI sequencer | ||
377 | serial port. | ||
378 | |||
379 | To compile this driver as a module, choose M here: the | ||
380 | module will be called ti-ssp-spi. | ||
381 | |||
353 | config SPI_TOPCLIFF_PCH | 382 | config SPI_TOPCLIFF_PCH |
354 | tristate "Topcliff PCH SPI Controller" | 383 | tristate "Topcliff PCH SPI Controller" |
355 | depends on PCI | 384 | depends on PCI |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 86d1b5f9bbd9..fd2fc5f6505f 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -9,6 +9,7 @@ ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG | |||
9 | obj-$(CONFIG_SPI_MASTER) += spi.o | 9 | obj-$(CONFIG_SPI_MASTER) += spi.o |
10 | 10 | ||
11 | # SPI master controller drivers (bus) | 11 | # SPI master controller drivers (bus) |
12 | obj-$(CONFIG_SPI_ALTERA) += spi_altera.o | ||
12 | obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o | 13 | obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o |
13 | obj-$(CONFIG_SPI_ATH79) += ath79_spi.o | 14 | obj-$(CONFIG_SPI_ATH79) += ath79_spi.o |
14 | obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o | 15 | obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o |
@@ -27,6 +28,7 @@ obj-$(CONFIG_SPI_IMX) += spi_imx.o | |||
27 | obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o | 28 | obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o |
28 | obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o | 29 | obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o |
29 | obj-$(CONFIG_SPI_PXA2XX_PCI) += pxa2xx_spi_pci.o | 30 | obj-$(CONFIG_SPI_PXA2XX_PCI) += pxa2xx_spi_pci.o |
31 | obj-$(CONFIG_SPI_OC_TINY) += spi_oc_tiny.o | ||
30 | obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o | 32 | obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o |
31 | obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o | 33 | obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o |
32 | obj-$(CONFIG_SPI_OMAP_100K) += omap_spi_100k.o | 34 | obj-$(CONFIG_SPI_OMAP_100K) += omap_spi_100k.o |
@@ -43,9 +45,11 @@ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o | |||
43 | obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o | 45 | obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o |
44 | obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o | 46 | obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o |
45 | obj-$(CONFIG_SPI_TEGRA) += spi_tegra.o | 47 | obj-$(CONFIG_SPI_TEGRA) += spi_tegra.o |
48 | obj-$(CONFIG_SPI_TI_SSP) += ti-ssp-spi.o | ||
46 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi_topcliff_pch.o | 49 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi_topcliff_pch.o |
47 | obj-$(CONFIG_SPI_TXX9) += spi_txx9.o | 50 | obj-$(CONFIG_SPI_TXX9) += spi_txx9.o |
48 | obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o | 51 | obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o |
52 | obj-$(CONFIG_SPI_SH) += spi_sh.o | ||
49 | obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o | 53 | obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o |
50 | obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o | 54 | obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o |
51 | obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o | 55 | obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o |
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index 71a1219a995d..5a4e0afb9ad6 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c | |||
@@ -324,20 +324,22 @@ struct vendor_data { | |||
324 | bool unidir; | 324 | bool unidir; |
325 | bool extended_cr; | 325 | bool extended_cr; |
326 | bool pl023; | 326 | bool pl023; |
327 | bool loopback; | ||
327 | }; | 328 | }; |
328 | 329 | ||
329 | /** | 330 | /** |
330 | * struct pl022 - This is the private SSP driver data structure | 331 | * struct pl022 - This is the private SSP driver data structure |
331 | * @adev: AMBA device model hookup | 332 | * @adev: AMBA device model hookup |
332 | * @vendor: Vendor data for the IP block | 333 | * @vendor: vendor data for the IP block |
333 | * @phybase: The physical memory where the SSP device resides | 334 | * @phybase: the physical memory where the SSP device resides |
334 | * @virtbase: The virtual memory where the SSP is mapped | 335 | * @virtbase: the virtual memory where the SSP is mapped |
336 | * @clk: outgoing clock "SPICLK" for the SPI bus | ||
335 | * @master: SPI framework hookup | 337 | * @master: SPI framework hookup |
336 | * @master_info: controller-specific data from machine setup | 338 | * @master_info: controller-specific data from machine setup |
337 | * @regs: SSP controller register's virtual address | ||
338 | * @pump_messages: Work struct for scheduling work to the workqueue | ||
339 | * @lock: spinlock to syncronise access to driver data | ||
340 | * @workqueue: a workqueue on which any spi_message request is queued | 339 | * @workqueue: a workqueue on which any spi_message request is queued |
340 | * @pump_messages: work struct for scheduling work to the workqueue | ||
341 | * @queue_lock: spinlock to syncronise access to message queue | ||
342 | * @queue: message queue | ||
341 | * @busy: workqueue is busy | 343 | * @busy: workqueue is busy |
342 | * @running: workqueue is running | 344 | * @running: workqueue is running |
343 | * @pump_transfers: Tasklet used in Interrupt Transfer mode | 345 | * @pump_transfers: Tasklet used in Interrupt Transfer mode |
@@ -348,8 +350,14 @@ struct vendor_data { | |||
348 | * @tx_end: end position in TX buffer to be read | 350 | * @tx_end: end position in TX buffer to be read |
349 | * @rx: current position in RX buffer to be written | 351 | * @rx: current position in RX buffer to be written |
350 | * @rx_end: end position in RX buffer to be written | 352 | * @rx_end: end position in RX buffer to be written |
351 | * @readingtype: the type of read currently going on | 353 | * @read: the type of read currently going on |
352 | * @writingtype: the type or write currently going on | 354 | * @write: the type of write currently going on |
355 | * @exp_fifo_level: expected FIFO level | ||
356 | * @dma_rx_channel: optional channel for RX DMA | ||
357 | * @dma_tx_channel: optional channel for TX DMA | ||
358 | * @sgt_rx: scattertable for the RX transfer | ||
359 | * @sgt_tx: scattertable for the TX transfer | ||
360 | * @dummypage: a dummy page used for driving data on the bus with DMA | ||
353 | */ | 361 | */ |
354 | struct pl022 { | 362 | struct pl022 { |
355 | struct amba_device *adev; | 363 | struct amba_device *adev; |
@@ -397,8 +405,8 @@ struct pl022 { | |||
397 | * @cpsr: Value of Clock prescale register | 405 | * @cpsr: Value of Clock prescale register |
398 | * @n_bytes: how many bytes(power of 2) reqd for a given data width of client | 406 | * @n_bytes: how many bytes(power of 2) reqd for a given data width of client |
399 | * @enable_dma: Whether to enable DMA or not | 407 | * @enable_dma: Whether to enable DMA or not |
400 | * @write: function ptr to be used to write when doing xfer for this chip | ||
401 | * @read: function ptr to be used to read when doing xfer for this chip | 408 | * @read: function ptr to be used to read when doing xfer for this chip |
409 | * @write: function ptr to be used to write when doing xfer for this chip | ||
402 | * @cs_control: chip select callback provided by chip | 410 | * @cs_control: chip select callback provided by chip |
403 | * @xfer_type: polling/interrupt/DMA | 411 | * @xfer_type: polling/interrupt/DMA |
404 | * | 412 | * |
@@ -508,9 +516,10 @@ static void giveback(struct pl022 *pl022) | |||
508 | msg->state = NULL; | 516 | msg->state = NULL; |
509 | if (msg->complete) | 517 | if (msg->complete) |
510 | msg->complete(msg->context); | 518 | msg->complete(msg->context); |
511 | /* This message is completed, so let's turn off the clocks! */ | 519 | /* This message is completed, so let's turn off the clocks & power */ |
512 | clk_disable(pl022->clk); | 520 | clk_disable(pl022->clk); |
513 | amba_pclk_disable(pl022->adev); | 521 | amba_pclk_disable(pl022->adev); |
522 | amba_vcore_disable(pl022->adev); | ||
514 | } | 523 | } |
515 | 524 | ||
516 | /** | 525 | /** |
@@ -917,7 +926,6 @@ static int configure_dma(struct pl022 *pl022) | |||
917 | struct dma_chan *txchan = pl022->dma_tx_channel; | 926 | struct dma_chan *txchan = pl022->dma_tx_channel; |
918 | struct dma_async_tx_descriptor *rxdesc; | 927 | struct dma_async_tx_descriptor *rxdesc; |
919 | struct dma_async_tx_descriptor *txdesc; | 928 | struct dma_async_tx_descriptor *txdesc; |
920 | dma_cookie_t cookie; | ||
921 | 929 | ||
922 | /* Check that the channels are available */ | 930 | /* Check that the channels are available */ |
923 | if (!rxchan || !txchan) | 931 | if (!rxchan || !txchan) |
@@ -962,10 +970,8 @@ static int configure_dma(struct pl022 *pl022) | |||
962 | tx_conf.dst_addr_width = rx_conf.src_addr_width; | 970 | tx_conf.dst_addr_width = rx_conf.src_addr_width; |
963 | BUG_ON(rx_conf.src_addr_width != tx_conf.dst_addr_width); | 971 | BUG_ON(rx_conf.src_addr_width != tx_conf.dst_addr_width); |
964 | 972 | ||
965 | rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG, | 973 | dmaengine_slave_config(rxchan, &rx_conf); |
966 | (unsigned long) &rx_conf); | 974 | dmaengine_slave_config(txchan, &tx_conf); |
967 | txchan->device->device_control(txchan, DMA_SLAVE_CONFIG, | ||
968 | (unsigned long) &tx_conf); | ||
969 | 975 | ||
970 | /* Create sglists for the transfers */ | 976 | /* Create sglists for the transfers */ |
971 | pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1; | 977 | pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1; |
@@ -1018,23 +1024,17 @@ static int configure_dma(struct pl022 *pl022) | |||
1018 | rxdesc->callback_param = pl022; | 1024 | rxdesc->callback_param = pl022; |
1019 | 1025 | ||
1020 | /* Submit and fire RX and TX with TX last so we're ready to read! */ | 1026 | /* Submit and fire RX and TX with TX last so we're ready to read! */ |
1021 | cookie = rxdesc->tx_submit(rxdesc); | 1027 | dmaengine_submit(rxdesc); |
1022 | if (dma_submit_error(cookie)) | 1028 | dmaengine_submit(txdesc); |
1023 | goto err_submit_rx; | 1029 | dma_async_issue_pending(rxchan); |
1024 | cookie = txdesc->tx_submit(txdesc); | 1030 | dma_async_issue_pending(txchan); |
1025 | if (dma_submit_error(cookie)) | ||
1026 | goto err_submit_tx; | ||
1027 | rxchan->device->device_issue_pending(rxchan); | ||
1028 | txchan->device->device_issue_pending(txchan); | ||
1029 | 1031 | ||
1030 | return 0; | 1032 | return 0; |
1031 | 1033 | ||
1032 | err_submit_tx: | ||
1033 | err_submit_rx: | ||
1034 | err_txdesc: | 1034 | err_txdesc: |
1035 | txchan->device->device_control(txchan, DMA_TERMINATE_ALL, 0); | 1035 | dmaengine_terminate_all(txchan); |
1036 | err_rxdesc: | 1036 | err_rxdesc: |
1037 | rxchan->device->device_control(rxchan, DMA_TERMINATE_ALL, 0); | 1037 | dmaengine_terminate_all(rxchan); |
1038 | dma_unmap_sg(txchan->device->dev, pl022->sgt_tx.sgl, | 1038 | dma_unmap_sg(txchan->device->dev, pl022->sgt_tx.sgl, |
1039 | pl022->sgt_tx.nents, DMA_TO_DEVICE); | 1039 | pl022->sgt_tx.nents, DMA_TO_DEVICE); |
1040 | err_tx_sgmap: | 1040 | err_tx_sgmap: |
@@ -1101,8 +1101,8 @@ static void terminate_dma(struct pl022 *pl022) | |||
1101 | struct dma_chan *rxchan = pl022->dma_rx_channel; | 1101 | struct dma_chan *rxchan = pl022->dma_rx_channel; |
1102 | struct dma_chan *txchan = pl022->dma_tx_channel; | 1102 | struct dma_chan *txchan = pl022->dma_tx_channel; |
1103 | 1103 | ||
1104 | rxchan->device->device_control(rxchan, DMA_TERMINATE_ALL, 0); | 1104 | dmaengine_terminate_all(rxchan); |
1105 | txchan->device->device_control(txchan, DMA_TERMINATE_ALL, 0); | 1105 | dmaengine_terminate_all(txchan); |
1106 | unmap_free_dma_scatter(pl022); | 1106 | unmap_free_dma_scatter(pl022); |
1107 | } | 1107 | } |
1108 | 1108 | ||
@@ -1482,9 +1482,11 @@ static void pump_messages(struct work_struct *work) | |||
1482 | /* Setup the SPI using the per chip configuration */ | 1482 | /* Setup the SPI using the per chip configuration */ |
1483 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); | 1483 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); |
1484 | /* | 1484 | /* |
1485 | * We enable the clocks here, then the clocks will be disabled when | 1485 | * We enable the core voltage and clocks here, then the clocks |
1486 | * giveback() is called in each method (poll/interrupt/DMA) | 1486 | * and core will be disabled when giveback() is called in each method |
1487 | * (poll/interrupt/DMA) | ||
1487 | */ | 1488 | */ |
1489 | amba_vcore_enable(pl022->adev); | ||
1488 | amba_pclk_enable(pl022->adev); | 1490 | amba_pclk_enable(pl022->adev); |
1489 | clk_enable(pl022->clk); | 1491 | clk_enable(pl022->clk); |
1490 | restore_state(pl022); | 1492 | restore_state(pl022); |
@@ -1910,8 +1912,6 @@ static int pl022_setup(struct spi_device *spi) | |||
1910 | && ((pl022->master_info)->enable_dma)) { | 1912 | && ((pl022->master_info)->enable_dma)) { |
1911 | chip->enable_dma = true; | 1913 | chip->enable_dma = true; |
1912 | dev_dbg(&spi->dev, "DMA mode set in controller state\n"); | 1914 | dev_dbg(&spi->dev, "DMA mode set in controller state\n"); |
1913 | if (status < 0) | ||
1914 | goto err_config_params; | ||
1915 | SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED, | 1915 | SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED, |
1916 | SSP_DMACR_MASK_RXDMAE, 0); | 1916 | SSP_DMACR_MASK_RXDMAE, 0); |
1917 | SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED, | 1917 | SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED, |
@@ -1984,7 +1984,7 @@ static int pl022_setup(struct spi_device *spi) | |||
1984 | 1984 | ||
1985 | SSP_WRITE_BITS(chip->cr0, clk_freq.scr, SSP_CR0_MASK_SCR, 8); | 1985 | SSP_WRITE_BITS(chip->cr0, clk_freq.scr, SSP_CR0_MASK_SCR, 8); |
1986 | /* Loopback is available on all versions except PL023 */ | 1986 | /* Loopback is available on all versions except PL023 */ |
1987 | if (!pl022->vendor->pl023) { | 1987 | if (pl022->vendor->loopback) { |
1988 | if (spi->mode & SPI_LOOP) | 1988 | if (spi->mode & SPI_LOOP) |
1989 | tmp = LOOPBACK_ENABLED; | 1989 | tmp = LOOPBACK_ENABLED; |
1990 | else | 1990 | else |
@@ -2021,7 +2021,7 @@ static void pl022_cleanup(struct spi_device *spi) | |||
2021 | 2021 | ||
2022 | 2022 | ||
2023 | static int __devinit | 2023 | static int __devinit |
2024 | pl022_probe(struct amba_device *adev, struct amba_id *id) | 2024 | pl022_probe(struct amba_device *adev, const struct amba_id *id) |
2025 | { | 2025 | { |
2026 | struct device *dev = &adev->dev; | 2026 | struct device *dev = &adev->dev; |
2027 | struct pl022_ssp_controller *platform_info = adev->dev.platform_data; | 2027 | struct pl022_ssp_controller *platform_info = adev->dev.platform_data; |
@@ -2130,8 +2130,12 @@ pl022_probe(struct amba_device *adev, struct amba_id *id) | |||
2130 | goto err_spi_register; | 2130 | goto err_spi_register; |
2131 | } | 2131 | } |
2132 | dev_dbg(dev, "probe succeded\n"); | 2132 | dev_dbg(dev, "probe succeded\n"); |
2133 | /* Disable the silicon block pclk and clock it when needed */ | 2133 | /* |
2134 | * Disable the silicon block pclk and any voltage domain and just | ||
2135 | * power it up and clock it when it's needed | ||
2136 | */ | ||
2134 | amba_pclk_disable(adev); | 2137 | amba_pclk_disable(adev); |
2138 | amba_vcore_disable(adev); | ||
2135 | return 0; | 2139 | return 0; |
2136 | 2140 | ||
2137 | err_spi_register: | 2141 | err_spi_register: |
@@ -2196,9 +2200,11 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state) | |||
2196 | return status; | 2200 | return status; |
2197 | } | 2201 | } |
2198 | 2202 | ||
2203 | amba_vcore_enable(adev); | ||
2199 | amba_pclk_enable(adev); | 2204 | amba_pclk_enable(adev); |
2200 | load_ssp_default_config(pl022); | 2205 | load_ssp_default_config(pl022); |
2201 | amba_pclk_disable(adev); | 2206 | amba_pclk_disable(adev); |
2207 | amba_vcore_disable(adev); | ||
2202 | dev_dbg(&adev->dev, "suspended\n"); | 2208 | dev_dbg(&adev->dev, "suspended\n"); |
2203 | return 0; | 2209 | return 0; |
2204 | } | 2210 | } |
@@ -2228,6 +2234,7 @@ static struct vendor_data vendor_arm = { | |||
2228 | .unidir = false, | 2234 | .unidir = false, |
2229 | .extended_cr = false, | 2235 | .extended_cr = false, |
2230 | .pl023 = false, | 2236 | .pl023 = false, |
2237 | .loopback = true, | ||
2231 | }; | 2238 | }; |
2232 | 2239 | ||
2233 | 2240 | ||
@@ -2237,6 +2244,7 @@ static struct vendor_data vendor_st = { | |||
2237 | .unidir = false, | 2244 | .unidir = false, |
2238 | .extended_cr = true, | 2245 | .extended_cr = true, |
2239 | .pl023 = false, | 2246 | .pl023 = false, |
2247 | .loopback = true, | ||
2240 | }; | 2248 | }; |
2241 | 2249 | ||
2242 | static struct vendor_data vendor_st_pl023 = { | 2250 | static struct vendor_data vendor_st_pl023 = { |
@@ -2245,6 +2253,16 @@ static struct vendor_data vendor_st_pl023 = { | |||
2245 | .unidir = false, | 2253 | .unidir = false, |
2246 | .extended_cr = true, | 2254 | .extended_cr = true, |
2247 | .pl023 = true, | 2255 | .pl023 = true, |
2256 | .loopback = false, | ||
2257 | }; | ||
2258 | |||
2259 | static struct vendor_data vendor_db5500_pl023 = { | ||
2260 | .fifodepth = 32, | ||
2261 | .max_bpw = 32, | ||
2262 | .unidir = false, | ||
2263 | .extended_cr = true, | ||
2264 | .pl023 = true, | ||
2265 | .loopback = true, | ||
2248 | }; | 2266 | }; |
2249 | 2267 | ||
2250 | static struct amba_id pl022_ids[] = { | 2268 | static struct amba_id pl022_ids[] = { |
@@ -2278,6 +2296,11 @@ static struct amba_id pl022_ids[] = { | |||
2278 | .mask = 0xffffffff, | 2296 | .mask = 0xffffffff, |
2279 | .data = &vendor_st_pl023, | 2297 | .data = &vendor_st_pl023, |
2280 | }, | 2298 | }, |
2299 | { | ||
2300 | .id = 0x10080023, | ||
2301 | .mask = 0xffffffff, | ||
2302 | .data = &vendor_db5500_pl023, | ||
2303 | }, | ||
2281 | { 0, 0 }, | 2304 | { 0, 0 }, |
2282 | }; | 2305 | }; |
2283 | 2306 | ||
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 6beab99bf95b..1f0ed8005c91 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c | |||
@@ -571,6 +571,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
571 | unsigned long tx_reg, rx_reg; | 571 | unsigned long tx_reg, rx_reg; |
572 | struct edmacc_param param; | 572 | struct edmacc_param param; |
573 | void *rx_buf; | 573 | void *rx_buf; |
574 | int b, c; | ||
574 | 575 | ||
575 | dma = &dspi->dma; | 576 | dma = &dspi->dma; |
576 | 577 | ||
@@ -591,22 +592,38 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
591 | 592 | ||
592 | if (t->tx_buf) { | 593 | if (t->tx_buf) { |
593 | t->tx_dma = dma_map_single(&spi->dev, (void *)t->tx_buf, | 594 | t->tx_dma = dma_map_single(&spi->dev, (void *)t->tx_buf, |
594 | dspi->wcount, DMA_TO_DEVICE); | 595 | t->len, DMA_TO_DEVICE); |
595 | if (dma_mapping_error(&spi->dev, t->tx_dma)) { | 596 | if (dma_mapping_error(&spi->dev, t->tx_dma)) { |
596 | dev_dbg(sdev, "Unable to DMA map %d bytes" | 597 | dev_dbg(sdev, "Unable to DMA map %d bytes" |
597 | "TX buffer\n", dspi->wcount); | 598 | "TX buffer\n", t->len); |
598 | return -ENOMEM; | 599 | return -ENOMEM; |
599 | } | 600 | } |
600 | } | 601 | } |
601 | 602 | ||
603 | /* | ||
604 | * If number of words is greater than 65535, then we need | ||
605 | * to configure a 3 dimension transfer. Use the BCNTRLD | ||
606 | * feature to allow for transfers that aren't even multiples | ||
607 | * of 65535 (or any other possible b size) by first transferring | ||
608 | * the remainder amount then grabbing the next N blocks of | ||
609 | * 65535 words. | ||
610 | */ | ||
611 | |||
612 | c = dspi->wcount / (SZ_64K - 1); /* N 65535 Blocks */ | ||
613 | b = dspi->wcount - c * (SZ_64K - 1); /* Remainder */ | ||
614 | if (b) | ||
615 | c++; | ||
616 | else | ||
617 | b = SZ_64K - 1; | ||
618 | |||
602 | param.opt = TCINTEN | EDMA_TCC(dma->tx_channel); | 619 | param.opt = TCINTEN | EDMA_TCC(dma->tx_channel); |
603 | param.src = t->tx_buf ? t->tx_dma : tx_reg; | 620 | param.src = t->tx_buf ? t->tx_dma : tx_reg; |
604 | param.a_b_cnt = dspi->wcount << 16 | data_type; | 621 | param.a_b_cnt = b << 16 | data_type; |
605 | param.dst = tx_reg; | 622 | param.dst = tx_reg; |
606 | param.src_dst_bidx = t->tx_buf ? data_type : 0; | 623 | param.src_dst_bidx = t->tx_buf ? data_type : 0; |
607 | param.link_bcntrld = 0xffff; | 624 | param.link_bcntrld = 0xffffffff; |
608 | param.src_dst_cidx = 0; | 625 | param.src_dst_cidx = t->tx_buf ? data_type : 0; |
609 | param.ccnt = 1; | 626 | param.ccnt = c; |
610 | edma_write_slot(dma->tx_channel, ¶m); | 627 | edma_write_slot(dma->tx_channel, ¶m); |
611 | edma_link(dma->tx_channel, dma->dummy_param_slot); | 628 | edma_link(dma->tx_channel, dma->dummy_param_slot); |
612 | 629 | ||
@@ -624,7 +641,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
624 | 641 | ||
625 | if (t->rx_buf) { | 642 | if (t->rx_buf) { |
626 | rx_buf = t->rx_buf; | 643 | rx_buf = t->rx_buf; |
627 | rx_buf_count = dspi->rcount; | 644 | rx_buf_count = t->len; |
628 | } else { | 645 | } else { |
629 | rx_buf = dspi->rx_tmp_buf; | 646 | rx_buf = dspi->rx_tmp_buf; |
630 | rx_buf_count = sizeof(dspi->rx_tmp_buf); | 647 | rx_buf_count = sizeof(dspi->rx_tmp_buf); |
@@ -636,19 +653,19 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
636 | dev_dbg(sdev, "Couldn't DMA map a %d bytes RX buffer\n", | 653 | dev_dbg(sdev, "Couldn't DMA map a %d bytes RX buffer\n", |
637 | rx_buf_count); | 654 | rx_buf_count); |
638 | if (t->tx_buf) | 655 | if (t->tx_buf) |
639 | dma_unmap_single(NULL, t->tx_dma, dspi->wcount, | 656 | dma_unmap_single(NULL, t->tx_dma, t->len, |
640 | DMA_TO_DEVICE); | 657 | DMA_TO_DEVICE); |
641 | return -ENOMEM; | 658 | return -ENOMEM; |
642 | } | 659 | } |
643 | 660 | ||
644 | param.opt = TCINTEN | EDMA_TCC(dma->rx_channel); | 661 | param.opt = TCINTEN | EDMA_TCC(dma->rx_channel); |
645 | param.src = rx_reg; | 662 | param.src = rx_reg; |
646 | param.a_b_cnt = dspi->rcount << 16 | data_type; | 663 | param.a_b_cnt = b << 16 | data_type; |
647 | param.dst = t->rx_dma; | 664 | param.dst = t->rx_dma; |
648 | param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16; | 665 | param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16; |
649 | param.link_bcntrld = 0xffff; | 666 | param.link_bcntrld = 0xffffffff; |
650 | param.src_dst_cidx = 0; | 667 | param.src_dst_cidx = (t->rx_buf ? data_type : 0) << 16; |
651 | param.ccnt = 1; | 668 | param.ccnt = c; |
652 | edma_write_slot(dma->rx_channel, ¶m); | 669 | edma_write_slot(dma->rx_channel, ¶m); |
653 | 670 | ||
654 | if (pdata->cshold_bug) | 671 | if (pdata->cshold_bug) |
@@ -675,7 +692,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
675 | if (spicfg->io_type == SPI_IO_TYPE_DMA) { | 692 | if (spicfg->io_type == SPI_IO_TYPE_DMA) { |
676 | 693 | ||
677 | if (t->tx_buf) | 694 | if (t->tx_buf) |
678 | dma_unmap_single(NULL, t->tx_dma, dspi->wcount, | 695 | dma_unmap_single(NULL, t->tx_dma, t->len, |
679 | DMA_TO_DEVICE); | 696 | DMA_TO_DEVICE); |
680 | 697 | ||
681 | dma_unmap_single(NULL, t->rx_dma, rx_buf_count, | 698 | dma_unmap_single(NULL, t->rx_dma, rx_buf_count, |
@@ -790,7 +807,6 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
790 | struct resource *r, *mem; | 807 | struct resource *r, *mem; |
791 | resource_size_t dma_rx_chan = SPI_NO_RESOURCE; | 808 | resource_size_t dma_rx_chan = SPI_NO_RESOURCE; |
792 | resource_size_t dma_tx_chan = SPI_NO_RESOURCE; | 809 | resource_size_t dma_tx_chan = SPI_NO_RESOURCE; |
793 | resource_size_t dma_eventq = SPI_NO_RESOURCE; | ||
794 | int i = 0, ret = 0; | 810 | int i = 0, ret = 0; |
795 | u32 spipc0; | 811 | u32 spipc0; |
796 | 812 | ||
@@ -878,17 +894,13 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
878 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | 894 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); |
879 | if (r) | 895 | if (r) |
880 | dma_tx_chan = r->start; | 896 | dma_tx_chan = r->start; |
881 | r = platform_get_resource(pdev, IORESOURCE_DMA, 2); | ||
882 | if (r) | ||
883 | dma_eventq = r->start; | ||
884 | 897 | ||
885 | dspi->bitbang.txrx_bufs = davinci_spi_bufs; | 898 | dspi->bitbang.txrx_bufs = davinci_spi_bufs; |
886 | if (dma_rx_chan != SPI_NO_RESOURCE && | 899 | if (dma_rx_chan != SPI_NO_RESOURCE && |
887 | dma_tx_chan != SPI_NO_RESOURCE && | 900 | dma_tx_chan != SPI_NO_RESOURCE) { |
888 | dma_eventq != SPI_NO_RESOURCE) { | ||
889 | dspi->dma.rx_channel = dma_rx_chan; | 901 | dspi->dma.rx_channel = dma_rx_chan; |
890 | dspi->dma.tx_channel = dma_tx_chan; | 902 | dspi->dma.tx_channel = dma_tx_chan; |
891 | dspi->dma.eventq = dma_eventq; | 903 | dspi->dma.eventq = pdata->dma_event_q; |
892 | 904 | ||
893 | ret = davinci_spi_request_dma(dspi); | 905 | ret = davinci_spi_request_dma(dspi); |
894 | if (ret) | 906 | if (ret) |
@@ -897,7 +909,7 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
897 | dev_info(&pdev->dev, "DMA: supported\n"); | 909 | dev_info(&pdev->dev, "DMA: supported\n"); |
898 | dev_info(&pdev->dev, "DMA: RX channel: %d, TX channel: %d, " | 910 | dev_info(&pdev->dev, "DMA: RX channel: %d, TX channel: %d, " |
899 | "event queue: %d\n", dma_rx_chan, dma_tx_chan, | 911 | "event queue: %d\n", dma_rx_chan, dma_tx_chan, |
900 | dma_eventq); | 912 | pdata->dma_event_q); |
901 | } | 913 | } |
902 | 914 | ||
903 | dspi->get_rx = davinci_spi_rx_buf_u8; | 915 | dspi->get_rx = davinci_spi_rx_buf_u8; |
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index 22af77f98816..9a6196461b27 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c | |||
@@ -22,10 +22,10 @@ | |||
22 | #include <linux/highmem.h> | 22 | #include <linux/highmem.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | |||
26 | #include <linux/spi/dw_spi.h> | ||
27 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
28 | 26 | ||
27 | #include "dw_spi.h" | ||
28 | |||
29 | #ifdef CONFIG_DEBUG_FS | 29 | #ifdef CONFIG_DEBUG_FS |
30 | #include <linux/debugfs.h> | 30 | #include <linux/debugfs.h> |
31 | #endif | 31 | #endif |
diff --git a/drivers/spi/dw_spi.h b/drivers/spi/dw_spi.h new file mode 100644 index 000000000000..fb0bce564844 --- /dev/null +++ b/drivers/spi/dw_spi.h | |||
@@ -0,0 +1,234 @@ | |||
1 | #ifndef DW_SPI_HEADER_H | ||
2 | #define DW_SPI_HEADER_H | ||
3 | |||
4 | #include <linux/io.h> | ||
5 | #include <linux/scatterlist.h> | ||
6 | |||
7 | /* Bit fields in CTRLR0 */ | ||
8 | #define SPI_DFS_OFFSET 0 | ||
9 | |||
10 | #define SPI_FRF_OFFSET 4 | ||
11 | #define SPI_FRF_SPI 0x0 | ||
12 | #define SPI_FRF_SSP 0x1 | ||
13 | #define SPI_FRF_MICROWIRE 0x2 | ||
14 | #define SPI_FRF_RESV 0x3 | ||
15 | |||
16 | #define SPI_MODE_OFFSET 6 | ||
17 | #define SPI_SCPH_OFFSET 6 | ||
18 | #define SPI_SCOL_OFFSET 7 | ||
19 | |||
20 | #define SPI_TMOD_OFFSET 8 | ||
21 | #define SPI_TMOD_MASK (0x3 << SPI_TMOD_OFFSET) | ||
22 | #define SPI_TMOD_TR 0x0 /* xmit & recv */ | ||
23 | #define SPI_TMOD_TO 0x1 /* xmit only */ | ||
24 | #define SPI_TMOD_RO 0x2 /* recv only */ | ||
25 | #define SPI_TMOD_EPROMREAD 0x3 /* eeprom read mode */ | ||
26 | |||
27 | #define SPI_SLVOE_OFFSET 10 | ||
28 | #define SPI_SRL_OFFSET 11 | ||
29 | #define SPI_CFS_OFFSET 12 | ||
30 | |||
31 | /* Bit fields in SR, 7 bits */ | ||
32 | #define SR_MASK 0x7f /* cover 7 bits */ | ||
33 | #define SR_BUSY (1 << 0) | ||
34 | #define SR_TF_NOT_FULL (1 << 1) | ||
35 | #define SR_TF_EMPT (1 << 2) | ||
36 | #define SR_RF_NOT_EMPT (1 << 3) | ||
37 | #define SR_RF_FULL (1 << 4) | ||
38 | #define SR_TX_ERR (1 << 5) | ||
39 | #define SR_DCOL (1 << 6) | ||
40 | |||
41 | /* Bit fields in ISR, IMR, RISR, 7 bits */ | ||
42 | #define SPI_INT_TXEI (1 << 0) | ||
43 | #define SPI_INT_TXOI (1 << 1) | ||
44 | #define SPI_INT_RXUI (1 << 2) | ||
45 | #define SPI_INT_RXOI (1 << 3) | ||
46 | #define SPI_INT_RXFI (1 << 4) | ||
47 | #define SPI_INT_MSTI (1 << 5) | ||
48 | |||
49 | /* TX RX interrupt level threshhold, max can be 256 */ | ||
50 | #define SPI_INT_THRESHOLD 32 | ||
51 | |||
52 | enum dw_ssi_type { | ||
53 | SSI_MOTO_SPI = 0, | ||
54 | SSI_TI_SSP, | ||
55 | SSI_NS_MICROWIRE, | ||
56 | }; | ||
57 | |||
58 | struct dw_spi_reg { | ||
59 | u32 ctrl0; | ||
60 | u32 ctrl1; | ||
61 | u32 ssienr; | ||
62 | u32 mwcr; | ||
63 | u32 ser; | ||
64 | u32 baudr; | ||
65 | u32 txfltr; | ||
66 | u32 rxfltr; | ||
67 | u32 txflr; | ||
68 | u32 rxflr; | ||
69 | u32 sr; | ||
70 | u32 imr; | ||
71 | u32 isr; | ||
72 | u32 risr; | ||
73 | u32 txoicr; | ||
74 | u32 rxoicr; | ||
75 | u32 rxuicr; | ||
76 | u32 msticr; | ||
77 | u32 icr; | ||
78 | u32 dmacr; | ||
79 | u32 dmatdlr; | ||
80 | u32 dmardlr; | ||
81 | u32 idr; | ||
82 | u32 version; | ||
83 | u32 dr; /* Currently oper as 32 bits, | ||
84 | though only low 16 bits matters */ | ||
85 | } __packed; | ||
86 | |||
87 | struct dw_spi; | ||
88 | struct dw_spi_dma_ops { | ||
89 | int (*dma_init)(struct dw_spi *dws); | ||
90 | void (*dma_exit)(struct dw_spi *dws); | ||
91 | int (*dma_transfer)(struct dw_spi *dws, int cs_change); | ||
92 | }; | ||
93 | |||
94 | struct dw_spi { | ||
95 | struct spi_master *master; | ||
96 | struct spi_device *cur_dev; | ||
97 | struct device *parent_dev; | ||
98 | enum dw_ssi_type type; | ||
99 | |||
100 | void __iomem *regs; | ||
101 | unsigned long paddr; | ||
102 | u32 iolen; | ||
103 | int irq; | ||
104 | u32 fifo_len; /* depth of the FIFO buffer */ | ||
105 | u32 max_freq; /* max bus freq supported */ | ||
106 | |||
107 | u16 bus_num; | ||
108 | u16 num_cs; /* supported slave numbers */ | ||
109 | |||
110 | /* Driver message queue */ | ||
111 | struct workqueue_struct *workqueue; | ||
112 | struct work_struct pump_messages; | ||
113 | spinlock_t lock; | ||
114 | struct list_head queue; | ||
115 | int busy; | ||
116 | int run; | ||
117 | |||
118 | /* Message Transfer pump */ | ||
119 | struct tasklet_struct pump_transfers; | ||
120 | |||
121 | /* Current message transfer state info */ | ||
122 | struct spi_message *cur_msg; | ||
123 | struct spi_transfer *cur_transfer; | ||
124 | struct chip_data *cur_chip; | ||
125 | struct chip_data *prev_chip; | ||
126 | size_t len; | ||
127 | void *tx; | ||
128 | void *tx_end; | ||
129 | void *rx; | ||
130 | void *rx_end; | ||
131 | int dma_mapped; | ||
132 | dma_addr_t rx_dma; | ||
133 | dma_addr_t tx_dma; | ||
134 | size_t rx_map_len; | ||
135 | size_t tx_map_len; | ||
136 | u8 n_bytes; /* current is a 1/2 bytes op */ | ||
137 | u8 max_bits_per_word; /* maxim is 16b */ | ||
138 | u32 dma_width; | ||
139 | int cs_change; | ||
140 | int (*write)(struct dw_spi *dws); | ||
141 | int (*read)(struct dw_spi *dws); | ||
142 | irqreturn_t (*transfer_handler)(struct dw_spi *dws); | ||
143 | void (*cs_control)(u32 command); | ||
144 | |||
145 | /* Dma info */ | ||
146 | int dma_inited; | ||
147 | struct dma_chan *txchan; | ||
148 | struct scatterlist tx_sgl; | ||
149 | struct dma_chan *rxchan; | ||
150 | struct scatterlist rx_sgl; | ||
151 | int dma_chan_done; | ||
152 | struct device *dma_dev; | ||
153 | dma_addr_t dma_addr; /* phy address of the Data register */ | ||
154 | struct dw_spi_dma_ops *dma_ops; | ||
155 | void *dma_priv; /* platform relate info */ | ||
156 | struct pci_dev *dmac; | ||
157 | |||
158 | /* Bus interface info */ | ||
159 | void *priv; | ||
160 | #ifdef CONFIG_DEBUG_FS | ||
161 | struct dentry *debugfs; | ||
162 | #endif | ||
163 | }; | ||
164 | |||
165 | #define dw_readl(dw, name) \ | ||
166 | __raw_readl(&(((struct dw_spi_reg *)dw->regs)->name)) | ||
167 | #define dw_writel(dw, name, val) \ | ||
168 | __raw_writel((val), &(((struct dw_spi_reg *)dw->regs)->name)) | ||
169 | #define dw_readw(dw, name) \ | ||
170 | __raw_readw(&(((struct dw_spi_reg *)dw->regs)->name)) | ||
171 | #define dw_writew(dw, name, val) \ | ||
172 | __raw_writew((val), &(((struct dw_spi_reg *)dw->regs)->name)) | ||
173 | |||
174 | static inline void spi_enable_chip(struct dw_spi *dws, int enable) | ||
175 | { | ||
176 | dw_writel(dws, ssienr, (enable ? 1 : 0)); | ||
177 | } | ||
178 | |||
179 | static inline void spi_set_clk(struct dw_spi *dws, u16 div) | ||
180 | { | ||
181 | dw_writel(dws, baudr, div); | ||
182 | } | ||
183 | |||
184 | static inline void spi_chip_sel(struct dw_spi *dws, u16 cs) | ||
185 | { | ||
186 | if (cs > dws->num_cs) | ||
187 | return; | ||
188 | |||
189 | if (dws->cs_control) | ||
190 | dws->cs_control(1); | ||
191 | |||
192 | dw_writel(dws, ser, 1 << cs); | ||
193 | } | ||
194 | |||
195 | /* Disable IRQ bits */ | ||
196 | static inline void spi_mask_intr(struct dw_spi *dws, u32 mask) | ||
197 | { | ||
198 | u32 new_mask; | ||
199 | |||
200 | new_mask = dw_readl(dws, imr) & ~mask; | ||
201 | dw_writel(dws, imr, new_mask); | ||
202 | } | ||
203 | |||
204 | /* Enable IRQ bits */ | ||
205 | static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) | ||
206 | { | ||
207 | u32 new_mask; | ||
208 | |||
209 | new_mask = dw_readl(dws, imr) | mask; | ||
210 | dw_writel(dws, imr, new_mask); | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * Each SPI slave device to work with dw_api controller should | ||
215 | * has such a structure claiming its working mode (PIO/DMA etc), | ||
216 | * which can be save in the "controller_data" member of the | ||
217 | * struct spi_device | ||
218 | */ | ||
219 | struct dw_spi_chip { | ||
220 | u8 poll_mode; /* 0 for contoller polling mode */ | ||
221 | u8 type; /* SPI/SSP/Micrwire */ | ||
222 | u8 enable_dma; | ||
223 | void (*cs_control)(u32 command); | ||
224 | }; | ||
225 | |||
226 | extern int dw_spi_add_host(struct dw_spi *dws); | ||
227 | extern void dw_spi_remove_host(struct dw_spi *dws); | ||
228 | extern int dw_spi_suspend_host(struct dw_spi *dws); | ||
229 | extern int dw_spi_resume_host(struct dw_spi *dws); | ||
230 | extern void dw_spi_xfer_done(struct dw_spi *dws); | ||
231 | |||
232 | /* platform related setup */ | ||
233 | extern int dw_spi_mid_init(struct dw_spi *dws); /* Intel MID platforms */ | ||
234 | #endif /* DW_SPI_HEADER_H */ | ||
diff --git a/drivers/spi/dw_spi_mid.c b/drivers/spi/dw_spi_mid.c index c91c966e0717..489178243d88 100644 --- a/drivers/spi/dw_spi_mid.c +++ b/drivers/spi/dw_spi_mid.c | |||
@@ -22,7 +22,8 @@ | |||
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
25 | #include <linux/spi/dw_spi.h> | 25 | |
26 | #include "dw_spi.h" | ||
26 | 27 | ||
27 | #ifdef CONFIG_SPI_DW_MID_DMA | 28 | #ifdef CONFIG_SPI_DW_MID_DMA |
28 | #include <linux/intel_mid_dma.h> | 29 | #include <linux/intel_mid_dma.h> |
diff --git a/drivers/spi/dw_spi_mmio.c b/drivers/spi/dw_spi_mmio.c index 2fa012c109bc..e0e813dad150 100644 --- a/drivers/spi/dw_spi_mmio.c +++ b/drivers/spi/dw_spi_mmio.c | |||
@@ -13,8 +13,10 @@ | |||
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/spi/dw_spi.h> | ||
17 | #include <linux/spi/spi.h> | 16 | #include <linux/spi/spi.h> |
17 | #include <linux/scatterlist.h> | ||
18 | |||
19 | #include "dw_spi.h" | ||
18 | 20 | ||
19 | #define DRIVER_NAME "dw_spi_mmio" | 21 | #define DRIVER_NAME "dw_spi_mmio" |
20 | 22 | ||
diff --git a/drivers/spi/dw_spi_pci.c b/drivers/spi/dw_spi_pci.c index 49ec3aa1219f..ad260aa5e526 100644 --- a/drivers/spi/dw_spi_pci.c +++ b/drivers/spi/dw_spi_pci.c | |||
@@ -20,9 +20,10 @@ | |||
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/spi/dw_spi.h> | ||
24 | #include <linux/spi/spi.h> | 23 | #include <linux/spi/spi.h> |
25 | 24 | ||
25 | #include "dw_spi.h" | ||
26 | |||
26 | #define DRIVER_NAME "dw_spi_pci" | 27 | #define DRIVER_NAME "dw_spi_pci" |
27 | 28 | ||
28 | struct dw_spi_pci { | 29 | struct dw_spi_pci { |
diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c index 77d9e7ee8b27..6a5b4238fb6b 100644 --- a/drivers/spi/mpc512x_psc_spi.c +++ b/drivers/spi/mpc512x_psc_spi.c | |||
@@ -507,8 +507,7 @@ static int __devexit mpc512x_psc_spi_do_remove(struct device *dev) | |||
507 | return 0; | 507 | return 0; |
508 | } | 508 | } |
509 | 509 | ||
510 | static int __devinit mpc512x_psc_spi_of_probe(struct platform_device *op, | 510 | static int __devinit mpc512x_psc_spi_of_probe(struct platform_device *op) |
511 | const struct of_device_id *match) | ||
512 | { | 511 | { |
513 | const u32 *regaddr_p; | 512 | const u32 *regaddr_p; |
514 | u64 regaddr64, size64; | 513 | u64 regaddr64, size64; |
@@ -551,7 +550,7 @@ static struct of_device_id mpc512x_psc_spi_of_match[] = { | |||
551 | 550 | ||
552 | MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match); | 551 | MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match); |
553 | 552 | ||
554 | static struct of_platform_driver mpc512x_psc_spi_of_driver = { | 553 | static struct platform_driver mpc512x_psc_spi_of_driver = { |
555 | .probe = mpc512x_psc_spi_of_probe, | 554 | .probe = mpc512x_psc_spi_of_probe, |
556 | .remove = __devexit_p(mpc512x_psc_spi_of_remove), | 555 | .remove = __devexit_p(mpc512x_psc_spi_of_remove), |
557 | .driver = { | 556 | .driver = { |
@@ -563,13 +562,13 @@ static struct of_platform_driver mpc512x_psc_spi_of_driver = { | |||
563 | 562 | ||
564 | static int __init mpc512x_psc_spi_init(void) | 563 | static int __init mpc512x_psc_spi_init(void) |
565 | { | 564 | { |
566 | return of_register_platform_driver(&mpc512x_psc_spi_of_driver); | 565 | return platform_driver_register(&mpc512x_psc_spi_of_driver); |
567 | } | 566 | } |
568 | module_init(mpc512x_psc_spi_init); | 567 | module_init(mpc512x_psc_spi_init); |
569 | 568 | ||
570 | static void __exit mpc512x_psc_spi_exit(void) | 569 | static void __exit mpc512x_psc_spi_exit(void) |
571 | { | 570 | { |
572 | of_unregister_platform_driver(&mpc512x_psc_spi_of_driver); | 571 | platform_driver_unregister(&mpc512x_psc_spi_of_driver); |
573 | } | 572 | } |
574 | module_exit(mpc512x_psc_spi_exit); | 573 | module_exit(mpc512x_psc_spi_exit); |
575 | 574 | ||
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 8a904c1c8485..e30baf0852ac 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c | |||
@@ -450,8 +450,7 @@ free_master: | |||
450 | return ret; | 450 | return ret; |
451 | } | 451 | } |
452 | 452 | ||
453 | static int __devinit mpc52xx_psc_spi_of_probe(struct platform_device *op, | 453 | static int __devinit mpc52xx_psc_spi_of_probe(struct platform_device *op) |
454 | const struct of_device_id *match) | ||
455 | { | 454 | { |
456 | const u32 *regaddr_p; | 455 | const u32 *regaddr_p; |
457 | u64 regaddr64, size64; | 456 | u64 regaddr64, size64; |
@@ -503,7 +502,7 @@ static const struct of_device_id mpc52xx_psc_spi_of_match[] = { | |||
503 | 502 | ||
504 | MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match); | 503 | MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match); |
505 | 504 | ||
506 | static struct of_platform_driver mpc52xx_psc_spi_of_driver = { | 505 | static struct platform_driver mpc52xx_psc_spi_of_driver = { |
507 | .probe = mpc52xx_psc_spi_of_probe, | 506 | .probe = mpc52xx_psc_spi_of_probe, |
508 | .remove = __devexit_p(mpc52xx_psc_spi_of_remove), | 507 | .remove = __devexit_p(mpc52xx_psc_spi_of_remove), |
509 | .driver = { | 508 | .driver = { |
@@ -515,13 +514,13 @@ static struct of_platform_driver mpc52xx_psc_spi_of_driver = { | |||
515 | 514 | ||
516 | static int __init mpc52xx_psc_spi_init(void) | 515 | static int __init mpc52xx_psc_spi_init(void) |
517 | { | 516 | { |
518 | return of_register_platform_driver(&mpc52xx_psc_spi_of_driver); | 517 | return platform_driver_register(&mpc52xx_psc_spi_of_driver); |
519 | } | 518 | } |
520 | module_init(mpc52xx_psc_spi_init); | 519 | module_init(mpc52xx_psc_spi_init); |
521 | 520 | ||
522 | static void __exit mpc52xx_psc_spi_exit(void) | 521 | static void __exit mpc52xx_psc_spi_exit(void) |
523 | { | 522 | { |
524 | of_unregister_platform_driver(&mpc52xx_psc_spi_of_driver); | 523 | platform_driver_unregister(&mpc52xx_psc_spi_of_driver); |
525 | } | 524 | } |
526 | module_exit(mpc52xx_psc_spi_exit); | 525 | module_exit(mpc52xx_psc_spi_exit); |
527 | 526 | ||
diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index 84439f655601..015a974bed72 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c | |||
@@ -390,8 +390,7 @@ static int mpc52xx_spi_transfer(struct spi_device *spi, struct spi_message *m) | |||
390 | /* | 390 | /* |
391 | * OF Platform Bus Binding | 391 | * OF Platform Bus Binding |
392 | */ | 392 | */ |
393 | static int __devinit mpc52xx_spi_probe(struct platform_device *op, | 393 | static int __devinit mpc52xx_spi_probe(struct platform_device *op) |
394 | const struct of_device_id *match) | ||
395 | { | 394 | { |
396 | struct spi_master *master; | 395 | struct spi_master *master; |
397 | struct mpc52xx_spi *ms; | 396 | struct mpc52xx_spi *ms; |
@@ -556,7 +555,7 @@ static const struct of_device_id mpc52xx_spi_match[] __devinitconst = { | |||
556 | }; | 555 | }; |
557 | MODULE_DEVICE_TABLE(of, mpc52xx_spi_match); | 556 | MODULE_DEVICE_TABLE(of, mpc52xx_spi_match); |
558 | 557 | ||
559 | static struct of_platform_driver mpc52xx_spi_of_driver = { | 558 | static struct platform_driver mpc52xx_spi_of_driver = { |
560 | .driver = { | 559 | .driver = { |
561 | .name = "mpc52xx-spi", | 560 | .name = "mpc52xx-spi", |
562 | .owner = THIS_MODULE, | 561 | .owner = THIS_MODULE, |
@@ -568,13 +567,13 @@ static struct of_platform_driver mpc52xx_spi_of_driver = { | |||
568 | 567 | ||
569 | static int __init mpc52xx_spi_init(void) | 568 | static int __init mpc52xx_spi_init(void) |
570 | { | 569 | { |
571 | return of_register_platform_driver(&mpc52xx_spi_of_driver); | 570 | return platform_driver_register(&mpc52xx_spi_of_driver); |
572 | } | 571 | } |
573 | module_init(mpc52xx_spi_init); | 572 | module_init(mpc52xx_spi_init); |
574 | 573 | ||
575 | static void __exit mpc52xx_spi_exit(void) | 574 | static void __exit mpc52xx_spi_exit(void) |
576 | { | 575 | { |
577 | of_unregister_platform_driver(&mpc52xx_spi_of_driver); | 576 | platform_driver_unregister(&mpc52xx_spi_of_driver); |
578 | } | 577 | } |
579 | module_exit(mpc52xx_spi_exit); | 578 | module_exit(mpc52xx_spi_exit); |
580 | 579 | ||
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index abb1ffbf3d20..6f86ba0175ac 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2005, 2006 Nokia Corporation | 4 | * Copyright (C) 2005, 2006 Nokia Corporation |
5 | * Author: Samuel Ortiz <samuel.ortiz@nokia.com> and | 5 | * Author: Samuel Ortiz <samuel.ortiz@nokia.com> and |
6 | * Juha Yrjölä <juha.yrjola@nokia.com> | 6 | * Juha Yrj�l� <juha.yrjola@nokia.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/clk.h> | 33 | #include <linux/clk.h> |
34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/pm_runtime.h> | ||
36 | 37 | ||
37 | #include <linux/spi/spi.h> | 38 | #include <linux/spi/spi.h> |
38 | 39 | ||
@@ -46,7 +47,6 @@ | |||
46 | #define OMAP2_MCSPI_MAX_CTRL 4 | 47 | #define OMAP2_MCSPI_MAX_CTRL 4 |
47 | 48 | ||
48 | #define OMAP2_MCSPI_REVISION 0x00 | 49 | #define OMAP2_MCSPI_REVISION 0x00 |
49 | #define OMAP2_MCSPI_SYSCONFIG 0x10 | ||
50 | #define OMAP2_MCSPI_SYSSTATUS 0x14 | 50 | #define OMAP2_MCSPI_SYSSTATUS 0x14 |
51 | #define OMAP2_MCSPI_IRQSTATUS 0x18 | 51 | #define OMAP2_MCSPI_IRQSTATUS 0x18 |
52 | #define OMAP2_MCSPI_IRQENABLE 0x1c | 52 | #define OMAP2_MCSPI_IRQENABLE 0x1c |
@@ -63,13 +63,6 @@ | |||
63 | 63 | ||
64 | /* per-register bitmasks: */ | 64 | /* per-register bitmasks: */ |
65 | 65 | ||
66 | #define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE BIT(4) | ||
67 | #define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2) | ||
68 | #define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE BIT(0) | ||
69 | #define OMAP2_MCSPI_SYSCONFIG_SOFTRESET BIT(1) | ||
70 | |||
71 | #define OMAP2_MCSPI_SYSSTATUS_RESETDONE BIT(0) | ||
72 | |||
73 | #define OMAP2_MCSPI_MODULCTRL_SINGLE BIT(0) | 66 | #define OMAP2_MCSPI_MODULCTRL_SINGLE BIT(0) |
74 | #define OMAP2_MCSPI_MODULCTRL_MS BIT(2) | 67 | #define OMAP2_MCSPI_MODULCTRL_MS BIT(2) |
75 | #define OMAP2_MCSPI_MODULCTRL_STEST BIT(3) | 68 | #define OMAP2_MCSPI_MODULCTRL_STEST BIT(3) |
@@ -122,13 +115,12 @@ struct omap2_mcspi { | |||
122 | spinlock_t lock; | 115 | spinlock_t lock; |
123 | struct list_head msg_queue; | 116 | struct list_head msg_queue; |
124 | struct spi_master *master; | 117 | struct spi_master *master; |
125 | struct clk *ick; | ||
126 | struct clk *fck; | ||
127 | /* Virtual base address of the controller */ | 118 | /* Virtual base address of the controller */ |
128 | void __iomem *base; | 119 | void __iomem *base; |
129 | unsigned long phys; | 120 | unsigned long phys; |
130 | /* SPI1 has 4 channels, while SPI2 has 2 */ | 121 | /* SPI1 has 4 channels, while SPI2 has 2 */ |
131 | struct omap2_mcspi_dma *dma_channels; | 122 | struct omap2_mcspi_dma *dma_channels; |
123 | struct device *dev; | ||
132 | }; | 124 | }; |
133 | 125 | ||
134 | struct omap2_mcspi_cs { | 126 | struct omap2_mcspi_cs { |
@@ -144,7 +136,6 @@ struct omap2_mcspi_cs { | |||
144 | * corresponding registers are modified. | 136 | * corresponding registers are modified. |
145 | */ | 137 | */ |
146 | struct omap2_mcspi_regs { | 138 | struct omap2_mcspi_regs { |
147 | u32 sysconfig; | ||
148 | u32 modulctrl; | 139 | u32 modulctrl; |
149 | u32 wakeupenable; | 140 | u32 wakeupenable; |
150 | struct list_head cs; | 141 | struct list_head cs; |
@@ -268,9 +259,6 @@ static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) | |||
268 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL, | 259 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL, |
269 | omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl); | 260 | omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl); |
270 | 261 | ||
271 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG, | ||
272 | omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig); | ||
273 | |||
274 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, | 262 | mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, |
275 | omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable); | 263 | omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable); |
276 | 264 | ||
@@ -280,20 +268,12 @@ static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) | |||
280 | } | 268 | } |
281 | static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi) | 269 | static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi) |
282 | { | 270 | { |
283 | clk_disable(mcspi->ick); | 271 | pm_runtime_put_sync(mcspi->dev); |
284 | clk_disable(mcspi->fck); | ||
285 | } | 272 | } |
286 | 273 | ||
287 | static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) | 274 | static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) |
288 | { | 275 | { |
289 | if (clk_enable(mcspi->ick)) | 276 | return pm_runtime_get_sync(mcspi->dev); |
290 | return -ENODEV; | ||
291 | if (clk_enable(mcspi->fck)) | ||
292 | return -ENODEV; | ||
293 | |||
294 | omap2_mcspi_restore_ctx(mcspi); | ||
295 | |||
296 | return 0; | ||
297 | } | 277 | } |
298 | 278 | ||
299 | static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) | 279 | static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) |
@@ -487,6 +467,9 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
487 | rx_reg = base + OMAP2_MCSPI_RX0; | 467 | rx_reg = base + OMAP2_MCSPI_RX0; |
488 | chstat_reg = base + OMAP2_MCSPI_CHSTAT0; | 468 | chstat_reg = base + OMAP2_MCSPI_CHSTAT0; |
489 | 469 | ||
470 | if (c < (word_len>>3)) | ||
471 | return 0; | ||
472 | |||
490 | if (word_len <= 8) { | 473 | if (word_len <= 8) { |
491 | u8 *rx; | 474 | u8 *rx; |
492 | const u8 *tx; | 475 | const u8 *tx; |
@@ -581,7 +564,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
581 | dev_vdbg(&spi->dev, "read-%d %04x\n", | 564 | dev_vdbg(&spi->dev, "read-%d %04x\n", |
582 | word_len, *(rx - 1)); | 565 | word_len, *(rx - 1)); |
583 | } | 566 | } |
584 | } while (c); | 567 | } while (c >= 2); |
585 | } else if (word_len <= 32) { | 568 | } else if (word_len <= 32) { |
586 | u32 *rx; | 569 | u32 *rx; |
587 | const u32 *tx; | 570 | const u32 *tx; |
@@ -628,7 +611,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
628 | dev_vdbg(&spi->dev, "read-%d %08x\n", | 611 | dev_vdbg(&spi->dev, "read-%d %08x\n", |
629 | word_len, *(rx - 1)); | 612 | word_len, *(rx - 1)); |
630 | } | 613 | } |
631 | } while (c); | 614 | } while (c >= 4); |
632 | } | 615 | } |
633 | 616 | ||
634 | /* for TX_ONLY mode, be sure all words have shifted out */ | 617 | /* for TX_ONLY mode, be sure all words have shifted out */ |
@@ -651,6 +634,17 @@ out: | |||
651 | return count - c; | 634 | return count - c; |
652 | } | 635 | } |
653 | 636 | ||
637 | static u32 omap2_mcspi_calc_divisor(u32 speed_hz) | ||
638 | { | ||
639 | u32 div; | ||
640 | |||
641 | for (div = 0; div < 15; div++) | ||
642 | if (speed_hz >= (OMAP2_MCSPI_MAX_FREQ >> div)) | ||
643 | return div; | ||
644 | |||
645 | return 15; | ||
646 | } | ||
647 | |||
654 | /* called only when no transfer is active to this device */ | 648 | /* called only when no transfer is active to this device */ |
655 | static int omap2_mcspi_setup_transfer(struct spi_device *spi, | 649 | static int omap2_mcspi_setup_transfer(struct spi_device *spi, |
656 | struct spi_transfer *t) | 650 | struct spi_transfer *t) |
@@ -673,12 +667,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
673 | if (t && t->speed_hz) | 667 | if (t && t->speed_hz) |
674 | speed_hz = t->speed_hz; | 668 | speed_hz = t->speed_hz; |
675 | 669 | ||
676 | if (speed_hz) { | 670 | speed_hz = min_t(u32, speed_hz, OMAP2_MCSPI_MAX_FREQ); |
677 | while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div)) | 671 | div = omap2_mcspi_calc_divisor(speed_hz); |
678 | > speed_hz) | ||
679 | div++; | ||
680 | } else | ||
681 | div = 15; | ||
682 | 672 | ||
683 | l = mcspi_cached_chconf0(spi); | 673 | l = mcspi_cached_chconf0(spi); |
684 | 674 | ||
@@ -715,7 +705,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
715 | mcspi_write_chconf0(spi, l); | 705 | mcspi_write_chconf0(spi, l); |
716 | 706 | ||
717 | dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", | 707 | dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", |
718 | OMAP2_MCSPI_MAX_FREQ / (1 << div), | 708 | OMAP2_MCSPI_MAX_FREQ >> div, |
719 | (spi->mode & SPI_CPHA) ? "trailing" : "leading", | 709 | (spi->mode & SPI_CPHA) ? "trailing" : "leading", |
720 | (spi->mode & SPI_CPOL) ? "inverted" : "normal"); | 710 | (spi->mode & SPI_CPOL) ? "inverted" : "normal"); |
721 | 711 | ||
@@ -819,8 +809,9 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
819 | return ret; | 809 | return ret; |
820 | } | 810 | } |
821 | 811 | ||
822 | if (omap2_mcspi_enable_clocks(mcspi)) | 812 | ret = omap2_mcspi_enable_clocks(mcspi); |
823 | return -ENODEV; | 813 | if (ret < 0) |
814 | return ret; | ||
824 | 815 | ||
825 | ret = omap2_mcspi_setup_transfer(spi, NULL); | 816 | ret = omap2_mcspi_setup_transfer(spi, NULL); |
826 | omap2_mcspi_disable_clocks(mcspi); | 817 | omap2_mcspi_disable_clocks(mcspi); |
@@ -863,10 +854,11 @@ static void omap2_mcspi_work(struct work_struct *work) | |||
863 | struct omap2_mcspi *mcspi; | 854 | struct omap2_mcspi *mcspi; |
864 | 855 | ||
865 | mcspi = container_of(work, struct omap2_mcspi, work); | 856 | mcspi = container_of(work, struct omap2_mcspi, work); |
866 | spin_lock_irq(&mcspi->lock); | ||
867 | 857 | ||
868 | if (omap2_mcspi_enable_clocks(mcspi)) | 858 | if (omap2_mcspi_enable_clocks(mcspi) < 0) |
869 | goto out; | 859 | return; |
860 | |||
861 | spin_lock_irq(&mcspi->lock); | ||
870 | 862 | ||
871 | /* We only enable one channel at a time -- the one whose message is | 863 | /* We only enable one channel at a time -- the one whose message is |
872 | * at the head of the queue -- although this controller would gladly | 864 | * at the head of the queue -- although this controller would gladly |
@@ -979,10 +971,9 @@ static void omap2_mcspi_work(struct work_struct *work) | |||
979 | spin_lock_irq(&mcspi->lock); | 971 | spin_lock_irq(&mcspi->lock); |
980 | } | 972 | } |
981 | 973 | ||
982 | omap2_mcspi_disable_clocks(mcspi); | ||
983 | |||
984 | out: | ||
985 | spin_unlock_irq(&mcspi->lock); | 974 | spin_unlock_irq(&mcspi->lock); |
975 | |||
976 | omap2_mcspi_disable_clocks(mcspi); | ||
986 | } | 977 | } |
987 | 978 | ||
988 | static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) | 979 | static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) |
@@ -1015,10 +1006,10 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) | |||
1015 | t->bits_per_word); | 1006 | t->bits_per_word); |
1016 | return -EINVAL; | 1007 | return -EINVAL; |
1017 | } | 1008 | } |
1018 | if (t->speed_hz && t->speed_hz < OMAP2_MCSPI_MAX_FREQ/(1<<16)) { | 1009 | if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) { |
1019 | dev_dbg(&spi->dev, "%d Hz max exceeds %d\n", | 1010 | dev_dbg(&spi->dev, "speed_hz %d below minimum %d Hz\n", |
1020 | t->speed_hz, | 1011 | t->speed_hz, |
1021 | OMAP2_MCSPI_MAX_FREQ/(1<<16)); | 1012 | OMAP2_MCSPI_MAX_FREQ >> 15); |
1022 | return -EINVAL; | 1013 | return -EINVAL; |
1023 | } | 1014 | } |
1024 | 1015 | ||
@@ -1058,25 +1049,15 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) | |||
1058 | return 0; | 1049 | return 0; |
1059 | } | 1050 | } |
1060 | 1051 | ||
1061 | static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi) | 1052 | static int __init omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) |
1062 | { | 1053 | { |
1063 | struct spi_master *master = mcspi->master; | 1054 | struct spi_master *master = mcspi->master; |
1064 | u32 tmp; | 1055 | u32 tmp; |
1056 | int ret = 0; | ||
1065 | 1057 | ||
1066 | if (omap2_mcspi_enable_clocks(mcspi)) | 1058 | ret = omap2_mcspi_enable_clocks(mcspi); |
1067 | return -1; | 1059 | if (ret < 0) |
1068 | 1060 | return ret; | |
1069 | mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, | ||
1070 | OMAP2_MCSPI_SYSCONFIG_SOFTRESET); | ||
1071 | do { | ||
1072 | tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS); | ||
1073 | } while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE)); | ||
1074 | |||
1075 | tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE | | ||
1076 | OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP | | ||
1077 | OMAP2_MCSPI_SYSCONFIG_SMARTIDLE; | ||
1078 | mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp); | ||
1079 | omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp; | ||
1080 | 1061 | ||
1081 | tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN; | 1062 | tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN; |
1082 | mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp); | 1063 | mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp); |
@@ -1087,91 +1068,26 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi) | |||
1087 | return 0; | 1068 | return 0; |
1088 | } | 1069 | } |
1089 | 1070 | ||
1090 | static u8 __initdata spi1_rxdma_id [] = { | 1071 | static int omap_mcspi_runtime_resume(struct device *dev) |
1091 | OMAP24XX_DMA_SPI1_RX0, | 1072 | { |
1092 | OMAP24XX_DMA_SPI1_RX1, | 1073 | struct omap2_mcspi *mcspi; |
1093 | OMAP24XX_DMA_SPI1_RX2, | 1074 | struct spi_master *master; |
1094 | OMAP24XX_DMA_SPI1_RX3, | ||
1095 | }; | ||
1096 | |||
1097 | static u8 __initdata spi1_txdma_id [] = { | ||
1098 | OMAP24XX_DMA_SPI1_TX0, | ||
1099 | OMAP24XX_DMA_SPI1_TX1, | ||
1100 | OMAP24XX_DMA_SPI1_TX2, | ||
1101 | OMAP24XX_DMA_SPI1_TX3, | ||
1102 | }; | ||
1103 | |||
1104 | static u8 __initdata spi2_rxdma_id[] = { | ||
1105 | OMAP24XX_DMA_SPI2_RX0, | ||
1106 | OMAP24XX_DMA_SPI2_RX1, | ||
1107 | }; | ||
1108 | |||
1109 | static u8 __initdata spi2_txdma_id[] = { | ||
1110 | OMAP24XX_DMA_SPI2_TX0, | ||
1111 | OMAP24XX_DMA_SPI2_TX1, | ||
1112 | }; | ||
1113 | |||
1114 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) \ | ||
1115 | || defined(CONFIG_ARCH_OMAP4) | ||
1116 | static u8 __initdata spi3_rxdma_id[] = { | ||
1117 | OMAP24XX_DMA_SPI3_RX0, | ||
1118 | OMAP24XX_DMA_SPI3_RX1, | ||
1119 | }; | ||
1120 | 1075 | ||
1121 | static u8 __initdata spi3_txdma_id[] = { | 1076 | master = dev_get_drvdata(dev); |
1122 | OMAP24XX_DMA_SPI3_TX0, | 1077 | mcspi = spi_master_get_devdata(master); |
1123 | OMAP24XX_DMA_SPI3_TX1, | 1078 | omap2_mcspi_restore_ctx(mcspi); |
1124 | }; | ||
1125 | #endif | ||
1126 | 1079 | ||
1127 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) | 1080 | return 0; |
1128 | static u8 __initdata spi4_rxdma_id[] = { | 1081 | } |
1129 | OMAP34XX_DMA_SPI4_RX0, | ||
1130 | }; | ||
1131 | 1082 | ||
1132 | static u8 __initdata spi4_txdma_id[] = { | ||
1133 | OMAP34XX_DMA_SPI4_TX0, | ||
1134 | }; | ||
1135 | #endif | ||
1136 | 1083 | ||
1137 | static int __init omap2_mcspi_probe(struct platform_device *pdev) | 1084 | static int __init omap2_mcspi_probe(struct platform_device *pdev) |
1138 | { | 1085 | { |
1139 | struct spi_master *master; | 1086 | struct spi_master *master; |
1087 | struct omap2_mcspi_platform_config *pdata = pdev->dev.platform_data; | ||
1140 | struct omap2_mcspi *mcspi; | 1088 | struct omap2_mcspi *mcspi; |
1141 | struct resource *r; | 1089 | struct resource *r; |
1142 | int status = 0, i; | 1090 | int status = 0, i; |
1143 | const u8 *rxdma_id, *txdma_id; | ||
1144 | unsigned num_chipselect; | ||
1145 | |||
1146 | switch (pdev->id) { | ||
1147 | case 1: | ||
1148 | rxdma_id = spi1_rxdma_id; | ||
1149 | txdma_id = spi1_txdma_id; | ||
1150 | num_chipselect = 4; | ||
1151 | break; | ||
1152 | case 2: | ||
1153 | rxdma_id = spi2_rxdma_id; | ||
1154 | txdma_id = spi2_txdma_id; | ||
1155 | num_chipselect = 2; | ||
1156 | break; | ||
1157 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) \ | ||
1158 | || defined(CONFIG_ARCH_OMAP4) | ||
1159 | case 3: | ||
1160 | rxdma_id = spi3_rxdma_id; | ||
1161 | txdma_id = spi3_txdma_id; | ||
1162 | num_chipselect = 2; | ||
1163 | break; | ||
1164 | #endif | ||
1165 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) | ||
1166 | case 4: | ||
1167 | rxdma_id = spi4_rxdma_id; | ||
1168 | txdma_id = spi4_txdma_id; | ||
1169 | num_chipselect = 1; | ||
1170 | break; | ||
1171 | #endif | ||
1172 | default: | ||
1173 | return -EINVAL; | ||
1174 | } | ||
1175 | 1091 | ||
1176 | master = spi_alloc_master(&pdev->dev, sizeof *mcspi); | 1092 | master = spi_alloc_master(&pdev->dev, sizeof *mcspi); |
1177 | if (master == NULL) { | 1093 | if (master == NULL) { |
@@ -1188,7 +1104,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
1188 | master->setup = omap2_mcspi_setup; | 1104 | master->setup = omap2_mcspi_setup; |
1189 | master->transfer = omap2_mcspi_transfer; | 1105 | master->transfer = omap2_mcspi_transfer; |
1190 | master->cleanup = omap2_mcspi_cleanup; | 1106 | master->cleanup = omap2_mcspi_cleanup; |
1191 | master->num_chipselect = num_chipselect; | 1107 | master->num_chipselect = pdata->num_cs; |
1192 | 1108 | ||
1193 | dev_set_drvdata(&pdev->dev, master); | 1109 | dev_set_drvdata(&pdev->dev, master); |
1194 | 1110 | ||
@@ -1206,49 +1122,62 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
1206 | goto err1; | 1122 | goto err1; |
1207 | } | 1123 | } |
1208 | 1124 | ||
1125 | r->start += pdata->regs_offset; | ||
1126 | r->end += pdata->regs_offset; | ||
1209 | mcspi->phys = r->start; | 1127 | mcspi->phys = r->start; |
1210 | mcspi->base = ioremap(r->start, r->end - r->start + 1); | 1128 | mcspi->base = ioremap(r->start, r->end - r->start + 1); |
1211 | if (!mcspi->base) { | 1129 | if (!mcspi->base) { |
1212 | dev_dbg(&pdev->dev, "can't ioremap MCSPI\n"); | 1130 | dev_dbg(&pdev->dev, "can't ioremap MCSPI\n"); |
1213 | status = -ENOMEM; | 1131 | status = -ENOMEM; |
1214 | goto err1aa; | 1132 | goto err2; |
1215 | } | 1133 | } |
1216 | 1134 | ||
1135 | mcspi->dev = &pdev->dev; | ||
1217 | INIT_WORK(&mcspi->work, omap2_mcspi_work); | 1136 | INIT_WORK(&mcspi->work, omap2_mcspi_work); |
1218 | 1137 | ||
1219 | spin_lock_init(&mcspi->lock); | 1138 | spin_lock_init(&mcspi->lock); |
1220 | INIT_LIST_HEAD(&mcspi->msg_queue); | 1139 | INIT_LIST_HEAD(&mcspi->msg_queue); |
1221 | INIT_LIST_HEAD(&omap2_mcspi_ctx[master->bus_num - 1].cs); | 1140 | INIT_LIST_HEAD(&omap2_mcspi_ctx[master->bus_num - 1].cs); |
1222 | 1141 | ||
1223 | mcspi->ick = clk_get(&pdev->dev, "ick"); | ||
1224 | if (IS_ERR(mcspi->ick)) { | ||
1225 | dev_dbg(&pdev->dev, "can't get mcspi_ick\n"); | ||
1226 | status = PTR_ERR(mcspi->ick); | ||
1227 | goto err1a; | ||
1228 | } | ||
1229 | mcspi->fck = clk_get(&pdev->dev, "fck"); | ||
1230 | if (IS_ERR(mcspi->fck)) { | ||
1231 | dev_dbg(&pdev->dev, "can't get mcspi_fck\n"); | ||
1232 | status = PTR_ERR(mcspi->fck); | ||
1233 | goto err2; | ||
1234 | } | ||
1235 | |||
1236 | mcspi->dma_channels = kcalloc(master->num_chipselect, | 1142 | mcspi->dma_channels = kcalloc(master->num_chipselect, |
1237 | sizeof(struct omap2_mcspi_dma), | 1143 | sizeof(struct omap2_mcspi_dma), |
1238 | GFP_KERNEL); | 1144 | GFP_KERNEL); |
1239 | 1145 | ||
1240 | if (mcspi->dma_channels == NULL) | 1146 | if (mcspi->dma_channels == NULL) |
1241 | goto err3; | 1147 | goto err2; |
1148 | |||
1149 | for (i = 0; i < master->num_chipselect; i++) { | ||
1150 | char dma_ch_name[14]; | ||
1151 | struct resource *dma_res; | ||
1152 | |||
1153 | sprintf(dma_ch_name, "rx%d", i); | ||
1154 | dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, | ||
1155 | dma_ch_name); | ||
1156 | if (!dma_res) { | ||
1157 | dev_dbg(&pdev->dev, "cannot get DMA RX channel\n"); | ||
1158 | status = -ENODEV; | ||
1159 | break; | ||
1160 | } | ||
1242 | 1161 | ||
1243 | for (i = 0; i < num_chipselect; i++) { | ||
1244 | mcspi->dma_channels[i].dma_rx_channel = -1; | 1162 | mcspi->dma_channels[i].dma_rx_channel = -1; |
1245 | mcspi->dma_channels[i].dma_rx_sync_dev = rxdma_id[i]; | 1163 | mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start; |
1164 | sprintf(dma_ch_name, "tx%d", i); | ||
1165 | dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, | ||
1166 | dma_ch_name); | ||
1167 | if (!dma_res) { | ||
1168 | dev_dbg(&pdev->dev, "cannot get DMA TX channel\n"); | ||
1169 | status = -ENODEV; | ||
1170 | break; | ||
1171 | } | ||
1172 | |||
1246 | mcspi->dma_channels[i].dma_tx_channel = -1; | 1173 | mcspi->dma_channels[i].dma_tx_channel = -1; |
1247 | mcspi->dma_channels[i].dma_tx_sync_dev = txdma_id[i]; | 1174 | mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start; |
1248 | } | 1175 | } |
1249 | 1176 | ||
1250 | if (omap2_mcspi_reset(mcspi) < 0) | 1177 | pm_runtime_enable(&pdev->dev); |
1251 | goto err4; | 1178 | |
1179 | if (status || omap2_mcspi_master_setup(mcspi) < 0) | ||
1180 | goto err3; | ||
1252 | 1181 | ||
1253 | status = spi_register_master(master); | 1182 | status = spi_register_master(master); |
1254 | if (status < 0) | 1183 | if (status < 0) |
@@ -1257,17 +1186,13 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
1257 | return status; | 1186 | return status; |
1258 | 1187 | ||
1259 | err4: | 1188 | err4: |
1260 | kfree(mcspi->dma_channels); | 1189 | spi_master_put(master); |
1261 | err3: | 1190 | err3: |
1262 | clk_put(mcspi->fck); | 1191 | kfree(mcspi->dma_channels); |
1263 | err2: | 1192 | err2: |
1264 | clk_put(mcspi->ick); | ||
1265 | err1a: | ||
1266 | iounmap(mcspi->base); | ||
1267 | err1aa: | ||
1268 | release_mem_region(r->start, (r->end - r->start) + 1); | 1193 | release_mem_region(r->start, (r->end - r->start) + 1); |
1194 | iounmap(mcspi->base); | ||
1269 | err1: | 1195 | err1: |
1270 | spi_master_put(master); | ||
1271 | return status; | 1196 | return status; |
1272 | } | 1197 | } |
1273 | 1198 | ||
@@ -1283,9 +1208,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) | |||
1283 | mcspi = spi_master_get_devdata(master); | 1208 | mcspi = spi_master_get_devdata(master); |
1284 | dma_channels = mcspi->dma_channels; | 1209 | dma_channels = mcspi->dma_channels; |
1285 | 1210 | ||
1286 | clk_put(mcspi->fck); | 1211 | omap2_mcspi_disable_clocks(mcspi); |
1287 | clk_put(mcspi->ick); | ||
1288 | |||
1289 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1212 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1290 | release_mem_region(r->start, (r->end - r->start) + 1); | 1213 | release_mem_region(r->start, (r->end - r->start) + 1); |
1291 | 1214 | ||
@@ -1336,6 +1259,7 @@ static int omap2_mcspi_resume(struct device *dev) | |||
1336 | 1259 | ||
1337 | static const struct dev_pm_ops omap2_mcspi_pm_ops = { | 1260 | static const struct dev_pm_ops omap2_mcspi_pm_ops = { |
1338 | .resume = omap2_mcspi_resume, | 1261 | .resume = omap2_mcspi_resume, |
1262 | .runtime_resume = omap_mcspi_runtime_resume, | ||
1339 | }; | 1263 | }; |
1340 | 1264 | ||
1341 | static struct platform_driver omap2_mcspi_driver = { | 1265 | static struct platform_driver omap2_mcspi_driver = { |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 95928833855b..a429b01d0285 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -1557,9 +1557,7 @@ static int __devinit pxa2xx_spi_probe(struct platform_device *pdev) | |||
1557 | drv_data->ssp = ssp; | 1557 | drv_data->ssp = ssp; |
1558 | 1558 | ||
1559 | master->dev.parent = &pdev->dev; | 1559 | master->dev.parent = &pdev->dev; |
1560 | #ifdef CONFIG_OF | ||
1561 | master->dev.of_node = pdev->dev.of_node; | 1560 | master->dev.of_node = pdev->dev.of_node; |
1562 | #endif | ||
1563 | /* the spi->mode bits understood by this driver: */ | 1561 | /* the spi->mode bits understood by this driver: */ |
1564 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 1562 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
1565 | 1563 | ||
diff --git a/drivers/spi/pxa2xx_spi_pci.c b/drivers/spi/pxa2xx_spi_pci.c index 351d8a375b57..378e504f89eb 100644 --- a/drivers/spi/pxa2xx_spi_pci.c +++ b/drivers/spi/pxa2xx_spi_pci.c | |||
@@ -7,10 +7,9 @@ | |||
7 | #include <linux/of_device.h> | 7 | #include <linux/of_device.h> |
8 | #include <linux/spi/pxa2xx_spi.h> | 8 | #include <linux/spi/pxa2xx_spi.h> |
9 | 9 | ||
10 | struct awesome_struct { | 10 | struct ce4100_info { |
11 | struct ssp_device ssp; | 11 | struct ssp_device ssp; |
12 | struct platform_device spi_pdev; | 12 | struct platform_device *spi_pdev; |
13 | struct pxa2xx_spi_master spi_pdata; | ||
14 | }; | 13 | }; |
15 | 14 | ||
16 | static DEFINE_MUTEX(ssp_lock); | 15 | static DEFINE_MUTEX(ssp_lock); |
@@ -51,23 +50,15 @@ void pxa_ssp_free(struct ssp_device *ssp) | |||
51 | } | 50 | } |
52 | EXPORT_SYMBOL_GPL(pxa_ssp_free); | 51 | EXPORT_SYMBOL_GPL(pxa_ssp_free); |
53 | 52 | ||
54 | static void plat_dev_release(struct device *dev) | ||
55 | { | ||
56 | struct awesome_struct *as = container_of(dev, | ||
57 | struct awesome_struct, spi_pdev.dev); | ||
58 | |||
59 | of_device_node_put(&as->spi_pdev.dev); | ||
60 | } | ||
61 | |||
62 | static int __devinit ce4100_spi_probe(struct pci_dev *dev, | 53 | static int __devinit ce4100_spi_probe(struct pci_dev *dev, |
63 | const struct pci_device_id *ent) | 54 | const struct pci_device_id *ent) |
64 | { | 55 | { |
65 | int ret; | 56 | int ret; |
66 | resource_size_t phys_beg; | 57 | resource_size_t phys_beg; |
67 | resource_size_t phys_len; | 58 | resource_size_t phys_len; |
68 | struct awesome_struct *spi_info; | 59 | struct ce4100_info *spi_info; |
69 | struct platform_device *pdev; | 60 | struct platform_device *pdev; |
70 | struct pxa2xx_spi_master *spi_pdata; | 61 | struct pxa2xx_spi_master spi_pdata; |
71 | struct ssp_device *ssp; | 62 | struct ssp_device *ssp; |
72 | 63 | ||
73 | ret = pci_enable_device(dev); | 64 | ret = pci_enable_device(dev); |
@@ -84,33 +75,28 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, | |||
84 | return ret; | 75 | return ret; |
85 | } | 76 | } |
86 | 77 | ||
78 | pdev = platform_device_alloc("pxa2xx-spi", dev->devfn); | ||
87 | spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); | 79 | spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); |
88 | if (!spi_info) { | 80 | if (!pdev || !spi_info ) { |
89 | ret = -ENOMEM; | 81 | ret = -ENOMEM; |
90 | goto err_kz; | 82 | goto err_nomem; |
91 | } | 83 | } |
92 | ssp = &spi_info->ssp; | 84 | memset(&spi_pdata, 0, sizeof(spi_pdata)); |
93 | pdev = &spi_info->spi_pdev; | 85 | spi_pdata.num_chipselect = dev->devfn; |
94 | spi_pdata = &spi_info->spi_pdata; | ||
95 | 86 | ||
96 | pdev->name = "pxa2xx-spi"; | 87 | ret = platform_device_add_data(pdev, &spi_pdata, sizeof(spi_pdata)); |
97 | pdev->id = dev->devfn; | 88 | if (ret) |
98 | pdev->dev.parent = &dev->dev; | 89 | goto err_nomem; |
99 | pdev->dev.platform_data = &spi_info->spi_pdata; | ||
100 | 90 | ||
101 | #ifdef CONFIG_OF | 91 | pdev->dev.parent = &dev->dev; |
102 | pdev->dev.of_node = dev->dev.of_node; | 92 | pdev->dev.of_node = dev->dev.of_node; |
103 | #endif | 93 | ssp = &spi_info->ssp; |
104 | pdev->dev.release = plat_dev_release; | ||
105 | |||
106 | spi_pdata->num_chipselect = dev->devfn; | ||
107 | |||
108 | ssp->phys_base = pci_resource_start(dev, 0); | 94 | ssp->phys_base = pci_resource_start(dev, 0); |
109 | ssp->mmio_base = ioremap(phys_beg, phys_len); | 95 | ssp->mmio_base = ioremap(phys_beg, phys_len); |
110 | if (!ssp->mmio_base) { | 96 | if (!ssp->mmio_base) { |
111 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); | 97 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); |
112 | ret = -EIO; | 98 | ret = -EIO; |
113 | goto err_remap; | 99 | goto err_nomem; |
114 | } | 100 | } |
115 | ssp->irq = dev->irq; | 101 | ssp->irq = dev->irq; |
116 | ssp->port_id = pdev->id; | 102 | ssp->port_id = pdev->id; |
@@ -122,7 +108,7 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, | |||
122 | 108 | ||
123 | pci_set_drvdata(dev, spi_info); | 109 | pci_set_drvdata(dev, spi_info); |
124 | 110 | ||
125 | ret = platform_device_register(pdev); | 111 | ret = platform_device_add(pdev); |
126 | if (ret) | 112 | if (ret) |
127 | goto err_dev_add; | 113 | goto err_dev_add; |
128 | 114 | ||
@@ -135,27 +121,21 @@ err_dev_add: | |||
135 | mutex_unlock(&ssp_lock); | 121 | mutex_unlock(&ssp_lock); |
136 | iounmap(ssp->mmio_base); | 122 | iounmap(ssp->mmio_base); |
137 | 123 | ||
138 | err_remap: | 124 | err_nomem: |
139 | kfree(spi_info); | ||
140 | |||
141 | err_kz: | ||
142 | release_mem_region(phys_beg, phys_len); | 125 | release_mem_region(phys_beg, phys_len); |
143 | 126 | platform_device_put(pdev); | |
127 | kfree(spi_info); | ||
144 | return ret; | 128 | return ret; |
145 | } | 129 | } |
146 | 130 | ||
147 | static void __devexit ce4100_spi_remove(struct pci_dev *dev) | 131 | static void __devexit ce4100_spi_remove(struct pci_dev *dev) |
148 | { | 132 | { |
149 | struct awesome_struct *spi_info; | 133 | struct ce4100_info *spi_info; |
150 | struct platform_device *pdev; | ||
151 | struct ssp_device *ssp; | 134 | struct ssp_device *ssp; |
152 | 135 | ||
153 | spi_info = pci_get_drvdata(dev); | 136 | spi_info = pci_get_drvdata(dev); |
154 | |||
155 | ssp = &spi_info->ssp; | 137 | ssp = &spi_info->ssp; |
156 | pdev = &spi_info->spi_pdev; | 138 | platform_device_unregister(spi_info->spi_pdev); |
157 | |||
158 | platform_device_unregister(pdev); | ||
159 | 139 | ||
160 | iounmap(ssp->mmio_base); | 140 | iounmap(ssp->mmio_base); |
161 | release_mem_region(pci_resource_start(dev, 0), | 141 | release_mem_region(pci_resource_start(dev, 0), |
@@ -171,7 +151,6 @@ static void __devexit ce4100_spi_remove(struct pci_dev *dev) | |||
171 | } | 151 | } |
172 | 152 | ||
173 | static struct pci_device_id ce4100_spi_devices[] __devinitdata = { | 153 | static struct pci_device_id ce4100_spi_devices[] __devinitdata = { |
174 | |||
175 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, | 154 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, |
176 | { }, | 155 | { }, |
177 | }; | 156 | }; |
diff --git a/drivers/spi/spi_altera.c b/drivers/spi/spi_altera.c new file mode 100644 index 000000000000..4813a63ce6fb --- /dev/null +++ b/drivers/spi/spi_altera.c | |||
@@ -0,0 +1,339 @@ | |||
1 | /* | ||
2 | * Altera SPI driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw> | ||
5 | * | ||
6 | * Based on spi_s3c24xx.c, which is: | ||
7 | * Copyright (c) 2006 Ben Dooks | ||
8 | * Copyright (c) 2006 Simtec Electronics | ||
9 | * Ben Dooks <ben@simtec.co.uk> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/init.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/spi/spi.h> | ||
21 | #include <linux/spi/spi_bitbang.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/of.h> | ||
24 | |||
25 | #define DRV_NAME "spi_altera" | ||
26 | |||
27 | #define ALTERA_SPI_RXDATA 0 | ||
28 | #define ALTERA_SPI_TXDATA 4 | ||
29 | #define ALTERA_SPI_STATUS 8 | ||
30 | #define ALTERA_SPI_CONTROL 12 | ||
31 | #define ALTERA_SPI_SLAVE_SEL 20 | ||
32 | |||
33 | #define ALTERA_SPI_STATUS_ROE_MSK 0x8 | ||
34 | #define ALTERA_SPI_STATUS_TOE_MSK 0x10 | ||
35 | #define ALTERA_SPI_STATUS_TMT_MSK 0x20 | ||
36 | #define ALTERA_SPI_STATUS_TRDY_MSK 0x40 | ||
37 | #define ALTERA_SPI_STATUS_RRDY_MSK 0x80 | ||
38 | #define ALTERA_SPI_STATUS_E_MSK 0x100 | ||
39 | |||
40 | #define ALTERA_SPI_CONTROL_IROE_MSK 0x8 | ||
41 | #define ALTERA_SPI_CONTROL_ITOE_MSK 0x10 | ||
42 | #define ALTERA_SPI_CONTROL_ITRDY_MSK 0x40 | ||
43 | #define ALTERA_SPI_CONTROL_IRRDY_MSK 0x80 | ||
44 | #define ALTERA_SPI_CONTROL_IE_MSK 0x100 | ||
45 | #define ALTERA_SPI_CONTROL_SSO_MSK 0x400 | ||
46 | |||
47 | struct altera_spi { | ||
48 | /* bitbang has to be first */ | ||
49 | struct spi_bitbang bitbang; | ||
50 | struct completion done; | ||
51 | |||
52 | void __iomem *base; | ||
53 | int irq; | ||
54 | int len; | ||
55 | int count; | ||
56 | int bytes_per_word; | ||
57 | unsigned long imr; | ||
58 | |||
59 | /* data buffers */ | ||
60 | const unsigned char *tx; | ||
61 | unsigned char *rx; | ||
62 | }; | ||
63 | |||
64 | static inline struct altera_spi *altera_spi_to_hw(struct spi_device *sdev) | ||
65 | { | ||
66 | return spi_master_get_devdata(sdev->master); | ||
67 | } | ||
68 | |||
69 | static void altera_spi_chipsel(struct spi_device *spi, int value) | ||
70 | { | ||
71 | struct altera_spi *hw = altera_spi_to_hw(spi); | ||
72 | |||
73 | if (spi->mode & SPI_CS_HIGH) { | ||
74 | switch (value) { | ||
75 | case BITBANG_CS_INACTIVE: | ||
76 | writel(1 << spi->chip_select, | ||
77 | hw->base + ALTERA_SPI_SLAVE_SEL); | ||
78 | hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK; | ||
79 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); | ||
80 | break; | ||
81 | |||
82 | case BITBANG_CS_ACTIVE: | ||
83 | hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK; | ||
84 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); | ||
85 | writel(0, hw->base + ALTERA_SPI_SLAVE_SEL); | ||
86 | break; | ||
87 | } | ||
88 | } else { | ||
89 | switch (value) { | ||
90 | case BITBANG_CS_INACTIVE: | ||
91 | hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK; | ||
92 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); | ||
93 | break; | ||
94 | |||
95 | case BITBANG_CS_ACTIVE: | ||
96 | writel(1 << spi->chip_select, | ||
97 | hw->base + ALTERA_SPI_SLAVE_SEL); | ||
98 | hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK; | ||
99 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | |||
105 | static int altera_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) | ||
106 | { | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int altera_spi_setup(struct spi_device *spi) | ||
111 | { | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static inline unsigned int hw_txbyte(struct altera_spi *hw, int count) | ||
116 | { | ||
117 | if (hw->tx) { | ||
118 | switch (hw->bytes_per_word) { | ||
119 | case 1: | ||
120 | return hw->tx[count]; | ||
121 | case 2: | ||
122 | return (hw->tx[count * 2] | ||
123 | | (hw->tx[count * 2 + 1] << 8)); | ||
124 | } | ||
125 | } | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | ||
130 | { | ||
131 | struct altera_spi *hw = altera_spi_to_hw(spi); | ||
132 | |||
133 | hw->tx = t->tx_buf; | ||
134 | hw->rx = t->rx_buf; | ||
135 | hw->count = 0; | ||
136 | hw->bytes_per_word = (t->bits_per_word ? : spi->bits_per_word) / 8; | ||
137 | hw->len = t->len / hw->bytes_per_word; | ||
138 | |||
139 | if (hw->irq >= 0) { | ||
140 | /* enable receive interrupt */ | ||
141 | hw->imr |= ALTERA_SPI_CONTROL_IRRDY_MSK; | ||
142 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); | ||
143 | |||
144 | /* send the first byte */ | ||
145 | writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA); | ||
146 | |||
147 | wait_for_completion(&hw->done); | ||
148 | /* disable receive interrupt */ | ||
149 | hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK; | ||
150 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); | ||
151 | } else { | ||
152 | /* send the first byte */ | ||
153 | writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA); | ||
154 | |||
155 | while (1) { | ||
156 | unsigned int rxd; | ||
157 | |||
158 | while (!(readl(hw->base + ALTERA_SPI_STATUS) & | ||
159 | ALTERA_SPI_STATUS_RRDY_MSK)) | ||
160 | cpu_relax(); | ||
161 | |||
162 | rxd = readl(hw->base + ALTERA_SPI_RXDATA); | ||
163 | if (hw->rx) { | ||
164 | switch (hw->bytes_per_word) { | ||
165 | case 1: | ||
166 | hw->rx[hw->count] = rxd; | ||
167 | break; | ||
168 | case 2: | ||
169 | hw->rx[hw->count * 2] = rxd; | ||
170 | hw->rx[hw->count * 2 + 1] = rxd >> 8; | ||
171 | break; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | hw->count++; | ||
176 | |||
177 | if (hw->count < hw->len) | ||
178 | writel(hw_txbyte(hw, hw->count), | ||
179 | hw->base + ALTERA_SPI_TXDATA); | ||
180 | else | ||
181 | break; | ||
182 | } | ||
183 | |||
184 | } | ||
185 | |||
186 | return hw->count * hw->bytes_per_word; | ||
187 | } | ||
188 | |||
189 | static irqreturn_t altera_spi_irq(int irq, void *dev) | ||
190 | { | ||
191 | struct altera_spi *hw = dev; | ||
192 | unsigned int rxd; | ||
193 | |||
194 | rxd = readl(hw->base + ALTERA_SPI_RXDATA); | ||
195 | if (hw->rx) { | ||
196 | switch (hw->bytes_per_word) { | ||
197 | case 1: | ||
198 | hw->rx[hw->count] = rxd; | ||
199 | break; | ||
200 | case 2: | ||
201 | hw->rx[hw->count * 2] = rxd; | ||
202 | hw->rx[hw->count * 2 + 1] = rxd >> 8; | ||
203 | break; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | hw->count++; | ||
208 | |||
209 | if (hw->count < hw->len) | ||
210 | writel(hw_txbyte(hw, hw->count), hw->base + ALTERA_SPI_TXDATA); | ||
211 | else | ||
212 | complete(&hw->done); | ||
213 | |||
214 | return IRQ_HANDLED; | ||
215 | } | ||
216 | |||
217 | static int __devinit altera_spi_probe(struct platform_device *pdev) | ||
218 | { | ||
219 | struct altera_spi_platform_data *platp = pdev->dev.platform_data; | ||
220 | struct altera_spi *hw; | ||
221 | struct spi_master *master; | ||
222 | struct resource *res; | ||
223 | int err = -ENODEV; | ||
224 | |||
225 | master = spi_alloc_master(&pdev->dev, sizeof(struct altera_spi)); | ||
226 | if (!master) | ||
227 | return err; | ||
228 | |||
229 | /* setup the master state. */ | ||
230 | master->bus_num = pdev->id; | ||
231 | master->num_chipselect = 16; | ||
232 | master->mode_bits = SPI_CS_HIGH; | ||
233 | master->setup = altera_spi_setup; | ||
234 | |||
235 | hw = spi_master_get_devdata(master); | ||
236 | platform_set_drvdata(pdev, hw); | ||
237 | |||
238 | /* setup the state for the bitbang driver */ | ||
239 | hw->bitbang.master = spi_master_get(master); | ||
240 | if (!hw->bitbang.master) | ||
241 | return err; | ||
242 | hw->bitbang.setup_transfer = altera_spi_setupxfer; | ||
243 | hw->bitbang.chipselect = altera_spi_chipsel; | ||
244 | hw->bitbang.txrx_bufs = altera_spi_txrx; | ||
245 | |||
246 | /* find and map our resources */ | ||
247 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
248 | if (!res) | ||
249 | goto exit_busy; | ||
250 | if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), | ||
251 | pdev->name)) | ||
252 | goto exit_busy; | ||
253 | hw->base = devm_ioremap_nocache(&pdev->dev, res->start, | ||
254 | resource_size(res)); | ||
255 | if (!hw->base) | ||
256 | goto exit_busy; | ||
257 | /* program defaults into the registers */ | ||
258 | hw->imr = 0; /* disable spi interrupts */ | ||
259 | writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); | ||
260 | writel(0, hw->base + ALTERA_SPI_STATUS); /* clear status reg */ | ||
261 | if (readl(hw->base + ALTERA_SPI_STATUS) & ALTERA_SPI_STATUS_RRDY_MSK) | ||
262 | readl(hw->base + ALTERA_SPI_RXDATA); /* flush rxdata */ | ||
263 | /* irq is optional */ | ||
264 | hw->irq = platform_get_irq(pdev, 0); | ||
265 | if (hw->irq >= 0) { | ||
266 | init_completion(&hw->done); | ||
267 | err = devm_request_irq(&pdev->dev, hw->irq, altera_spi_irq, 0, | ||
268 | pdev->name, hw); | ||
269 | if (err) | ||
270 | goto exit; | ||
271 | } | ||
272 | /* find platform data */ | ||
273 | if (!platp) | ||
274 | hw->bitbang.master->dev.of_node = pdev->dev.of_node; | ||
275 | |||
276 | /* register our spi controller */ | ||
277 | err = spi_bitbang_start(&hw->bitbang); | ||
278 | if (err) | ||
279 | goto exit; | ||
280 | dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq); | ||
281 | |||
282 | return 0; | ||
283 | |||
284 | exit_busy: | ||
285 | err = -EBUSY; | ||
286 | exit: | ||
287 | platform_set_drvdata(pdev, NULL); | ||
288 | spi_master_put(master); | ||
289 | return err; | ||
290 | } | ||
291 | |||
292 | static int __devexit altera_spi_remove(struct platform_device *dev) | ||
293 | { | ||
294 | struct altera_spi *hw = platform_get_drvdata(dev); | ||
295 | struct spi_master *master = hw->bitbang.master; | ||
296 | |||
297 | spi_bitbang_stop(&hw->bitbang); | ||
298 | platform_set_drvdata(dev, NULL); | ||
299 | spi_master_put(master); | ||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | #ifdef CONFIG_OF | ||
304 | static const struct of_device_id altera_spi_match[] = { | ||
305 | { .compatible = "ALTR,spi-1.0", }, | ||
306 | {}, | ||
307 | }; | ||
308 | MODULE_DEVICE_TABLE(of, altera_spi_match); | ||
309 | #else /* CONFIG_OF */ | ||
310 | #define altera_spi_match NULL | ||
311 | #endif /* CONFIG_OF */ | ||
312 | |||
313 | static struct platform_driver altera_spi_driver = { | ||
314 | .probe = altera_spi_probe, | ||
315 | .remove = __devexit_p(altera_spi_remove), | ||
316 | .driver = { | ||
317 | .name = DRV_NAME, | ||
318 | .owner = THIS_MODULE, | ||
319 | .pm = NULL, | ||
320 | .of_match_table = altera_spi_match, | ||
321 | }, | ||
322 | }; | ||
323 | |||
324 | static int __init altera_spi_init(void) | ||
325 | { | ||
326 | return platform_driver_register(&altera_spi_driver); | ||
327 | } | ||
328 | module_init(altera_spi_init); | ||
329 | |||
330 | static void __exit altera_spi_exit(void) | ||
331 | { | ||
332 | platform_driver_unregister(&altera_spi_driver); | ||
333 | } | ||
334 | module_exit(altera_spi_exit); | ||
335 | |||
336 | MODULE_DESCRIPTION("Altera SPI driver"); | ||
337 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); | ||
338 | MODULE_LICENSE("GPL"); | ||
339 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 3f223511127b..a28462486df8 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -425,6 +425,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) | |||
425 | struct bfin_spi_slave_data *chip = drv_data->cur_chip; | 425 | struct bfin_spi_slave_data *chip = drv_data->cur_chip; |
426 | struct spi_message *msg = drv_data->cur_msg; | 426 | struct spi_message *msg = drv_data->cur_msg; |
427 | int n_bytes = drv_data->n_bytes; | 427 | int n_bytes = drv_data->n_bytes; |
428 | int loop = 0; | ||
428 | 429 | ||
429 | /* wait until transfer finished. */ | 430 | /* wait until transfer finished. */ |
430 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 431 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
@@ -435,10 +436,15 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) | |||
435 | /* last read */ | 436 | /* last read */ |
436 | if (drv_data->rx) { | 437 | if (drv_data->rx) { |
437 | dev_dbg(&drv_data->pdev->dev, "last read\n"); | 438 | dev_dbg(&drv_data->pdev->dev, "last read\n"); |
438 | if (n_bytes == 2) | 439 | if (n_bytes % 2) { |
439 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 440 | u16 *buf = (u16 *)drv_data->rx; |
440 | else if (n_bytes == 1) | 441 | for (loop = 0; loop < n_bytes / 2; loop++) |
441 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 442 | *buf++ = read_RDBR(drv_data); |
443 | } else { | ||
444 | u8 *buf = (u8 *)drv_data->rx; | ||
445 | for (loop = 0; loop < n_bytes; loop++) | ||
446 | *buf++ = read_RDBR(drv_data); | ||
447 | } | ||
442 | drv_data->rx += n_bytes; | 448 | drv_data->rx += n_bytes; |
443 | } | 449 | } |
444 | 450 | ||
@@ -458,29 +464,53 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) | |||
458 | if (drv_data->rx && drv_data->tx) { | 464 | if (drv_data->rx && drv_data->tx) { |
459 | /* duplex */ | 465 | /* duplex */ |
460 | dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n"); | 466 | dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n"); |
461 | if (drv_data->n_bytes == 2) { | 467 | if (n_bytes % 2) { |
462 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 468 | u16 *buf = (u16 *)drv_data->rx; |
463 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 469 | u16 *buf2 = (u16 *)drv_data->tx; |
464 | } else if (drv_data->n_bytes == 1) { | 470 | for (loop = 0; loop < n_bytes / 2; loop++) { |
465 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 471 | *buf++ = read_RDBR(drv_data); |
466 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 472 | write_TDBR(drv_data, *buf2++); |
473 | } | ||
474 | } else { | ||
475 | u8 *buf = (u8 *)drv_data->rx; | ||
476 | u8 *buf2 = (u8 *)drv_data->tx; | ||
477 | for (loop = 0; loop < n_bytes; loop++) { | ||
478 | *buf++ = read_RDBR(drv_data); | ||
479 | write_TDBR(drv_data, *buf2++); | ||
480 | } | ||
467 | } | 481 | } |
468 | } else if (drv_data->rx) { | 482 | } else if (drv_data->rx) { |
469 | /* read */ | 483 | /* read */ |
470 | dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n"); | 484 | dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n"); |
471 | if (drv_data->n_bytes == 2) | 485 | if (n_bytes % 2) { |
472 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 486 | u16 *buf = (u16 *)drv_data->rx; |
473 | else if (drv_data->n_bytes == 1) | 487 | for (loop = 0; loop < n_bytes / 2; loop++) { |
474 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 488 | *buf++ = read_RDBR(drv_data); |
475 | write_TDBR(drv_data, chip->idle_tx_val); | 489 | write_TDBR(drv_data, chip->idle_tx_val); |
490 | } | ||
491 | } else { | ||
492 | u8 *buf = (u8 *)drv_data->rx; | ||
493 | for (loop = 0; loop < n_bytes; loop++) { | ||
494 | *buf++ = read_RDBR(drv_data); | ||
495 | write_TDBR(drv_data, chip->idle_tx_val); | ||
496 | } | ||
497 | } | ||
476 | } else if (drv_data->tx) { | 498 | } else if (drv_data->tx) { |
477 | /* write */ | 499 | /* write */ |
478 | dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n"); | 500 | dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n"); |
479 | bfin_spi_dummy_read(drv_data); | 501 | if (n_bytes % 2) { |
480 | if (drv_data->n_bytes == 2) | 502 | u16 *buf = (u16 *)drv_data->tx; |
481 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 503 | for (loop = 0; loop < n_bytes / 2; loop++) { |
482 | else if (drv_data->n_bytes == 1) | 504 | read_RDBR(drv_data); |
483 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 505 | write_TDBR(drv_data, *buf++); |
506 | } | ||
507 | } else { | ||
508 | u8 *buf = (u8 *)drv_data->tx; | ||
509 | for (loop = 0; loop < n_bytes; loop++) { | ||
510 | read_RDBR(drv_data); | ||
511 | write_TDBR(drv_data, *buf++); | ||
512 | } | ||
513 | } | ||
484 | } | 514 | } |
485 | 515 | ||
486 | if (drv_data->tx) | 516 | if (drv_data->tx) |
@@ -623,6 +653,7 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
623 | message->state = bfin_spi_next_transfer(drv_data); | 653 | message->state = bfin_spi_next_transfer(drv_data); |
624 | /* Schedule next transfer tasklet */ | 654 | /* Schedule next transfer tasklet */ |
625 | tasklet_schedule(&drv_data->pump_transfers); | 655 | tasklet_schedule(&drv_data->pump_transfers); |
656 | return; | ||
626 | } | 657 | } |
627 | 658 | ||
628 | if (transfer->tx_buf != NULL) { | 659 | if (transfer->tx_buf != NULL) { |
@@ -651,16 +682,16 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
651 | 682 | ||
652 | /* Bits per word setup */ | 683 | /* Bits per word setup */ |
653 | bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; | 684 | bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; |
654 | if (bits_per_word == 8) { | 685 | if ((bits_per_word > 0) && (bits_per_word % 16 == 0)) { |
655 | drv_data->n_bytes = 1; | 686 | drv_data->n_bytes = bits_per_word/8; |
656 | drv_data->len = transfer->len; | ||
657 | cr_width = 0; | ||
658 | drv_data->ops = &bfin_bfin_spi_transfer_ops_u8; | ||
659 | } else if (bits_per_word == 16) { | ||
660 | drv_data->n_bytes = 2; | ||
661 | drv_data->len = (transfer->len) >> 1; | 687 | drv_data->len = (transfer->len) >> 1; |
662 | cr_width = BIT_CTL_WORDSIZE; | 688 | cr_width = BIT_CTL_WORDSIZE; |
663 | drv_data->ops = &bfin_bfin_spi_transfer_ops_u16; | 689 | drv_data->ops = &bfin_bfin_spi_transfer_ops_u16; |
690 | } else if ((bits_per_word > 0) && (bits_per_word % 8 == 0)) { | ||
691 | drv_data->n_bytes = bits_per_word/8; | ||
692 | drv_data->len = transfer->len; | ||
693 | cr_width = 0; | ||
694 | drv_data->ops = &bfin_bfin_spi_transfer_ops_u8; | ||
664 | } else { | 695 | } else { |
665 | dev_err(&drv_data->pdev->dev, "transfer: unsupported bits_per_word\n"); | 696 | dev_err(&drv_data->pdev->dev, "transfer: unsupported bits_per_word\n"); |
666 | message->status = -EINVAL; | 697 | message->status = -EINVAL; |
@@ -815,10 +846,19 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
815 | if (drv_data->tx == NULL) | 846 | if (drv_data->tx == NULL) |
816 | write_TDBR(drv_data, chip->idle_tx_val); | 847 | write_TDBR(drv_data, chip->idle_tx_val); |
817 | else { | 848 | else { |
818 | if (bits_per_word == 8) | 849 | int loop; |
819 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 850 | if (bits_per_word % 16 == 0) { |
820 | else | 851 | u16 *buf = (u16 *)drv_data->tx; |
821 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 852 | for (loop = 0; loop < bits_per_word / 16; |
853 | loop++) { | ||
854 | write_TDBR(drv_data, *buf++); | ||
855 | } | ||
856 | } else if (bits_per_word % 8 == 0) { | ||
857 | u8 *buf = (u8 *)drv_data->tx; | ||
858 | for (loop = 0; loop < bits_per_word / 8; loop++) | ||
859 | write_TDBR(drv_data, *buf++); | ||
860 | } | ||
861 | |||
822 | drv_data->tx += drv_data->n_bytes; | 862 | drv_data->tx += drv_data->n_bytes; |
823 | } | 863 | } |
824 | 864 | ||
@@ -1031,7 +1071,7 @@ static int bfin_spi_setup(struct spi_device *spi) | |||
1031 | chip->ctl_reg &= bfin_ctl_reg; | 1071 | chip->ctl_reg &= bfin_ctl_reg; |
1032 | } | 1072 | } |
1033 | 1073 | ||
1034 | if (spi->bits_per_word != 8 && spi->bits_per_word != 16) { | 1074 | if (spi->bits_per_word % 8) { |
1035 | dev_err(&spi->dev, "%d bits_per_word is not supported\n", | 1075 | dev_err(&spi->dev, "%d bits_per_word is not supported\n", |
1036 | spi->bits_per_word); | 1076 | spi->bits_per_word); |
1037 | goto error; | 1077 | goto error; |
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index 8b55724d5f39..14a63f6010d1 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c | |||
@@ -259,10 +259,6 @@ static void bitbang_work(struct work_struct *work) | |||
259 | struct spi_bitbang *bitbang = | 259 | struct spi_bitbang *bitbang = |
260 | container_of(work, struct spi_bitbang, work); | 260 | container_of(work, struct spi_bitbang, work); |
261 | unsigned long flags; | 261 | unsigned long flags; |
262 | int (*setup_transfer)(struct spi_device *, | ||
263 | struct spi_transfer *); | ||
264 | |||
265 | setup_transfer = bitbang->setup_transfer; | ||
266 | 262 | ||
267 | spin_lock_irqsave(&bitbang->lock, flags); | 263 | spin_lock_irqsave(&bitbang->lock, flags); |
268 | bitbang->busy = 1; | 264 | bitbang->busy = 1; |
@@ -300,11 +296,7 @@ static void bitbang_work(struct work_struct *work) | |||
300 | 296 | ||
301 | /* init (-1) or override (1) transfer params */ | 297 | /* init (-1) or override (1) transfer params */ |
302 | if (do_setup != 0) { | 298 | if (do_setup != 0) { |
303 | if (!setup_transfer) { | 299 | status = bitbang->setup_transfer(spi, t); |
304 | status = -ENOPROTOOPT; | ||
305 | break; | ||
306 | } | ||
307 | status = setup_transfer(spi, t); | ||
308 | if (status < 0) | 300 | if (status < 0) |
309 | break; | 301 | break; |
310 | if (do_setup == -1) | 302 | if (do_setup == -1) |
@@ -465,6 +457,9 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) | |||
465 | } | 457 | } |
466 | } else if (!bitbang->master->setup) | 458 | } else if (!bitbang->master->setup) |
467 | return -EINVAL; | 459 | return -EINVAL; |
460 | if (bitbang->master->transfer == spi_bitbang_transfer && | ||
461 | !bitbang->setup_transfer) | ||
462 | return -EINVAL; | ||
468 | 463 | ||
469 | /* this task is the only thing to touch the SPI bits */ | 464 | /* this task is the only thing to touch the SPI bits */ |
470 | bitbang->busy = 0; | 465 | bitbang->busy = 0; |
diff --git a/drivers/spi/spi_fsl_espi.c b/drivers/spi/spi_fsl_espi.c index a99e2333b949..900e921ab80e 100644 --- a/drivers/spi/spi_fsl_espi.c +++ b/drivers/spi/spi_fsl_espi.c | |||
@@ -685,8 +685,7 @@ static int of_fsl_espi_get_chipselects(struct device *dev) | |||
685 | return 0; | 685 | return 0; |
686 | } | 686 | } |
687 | 687 | ||
688 | static int __devinit of_fsl_espi_probe(struct platform_device *ofdev, | 688 | static int __devinit of_fsl_espi_probe(struct platform_device *ofdev) |
689 | const struct of_device_id *ofid) | ||
690 | { | 689 | { |
691 | struct device *dev = &ofdev->dev; | 690 | struct device *dev = &ofdev->dev; |
692 | struct device_node *np = ofdev->dev.of_node; | 691 | struct device_node *np = ofdev->dev.of_node; |
@@ -695,7 +694,7 @@ static int __devinit of_fsl_espi_probe(struct platform_device *ofdev, | |||
695 | struct resource irq; | 694 | struct resource irq; |
696 | int ret = -ENOMEM; | 695 | int ret = -ENOMEM; |
697 | 696 | ||
698 | ret = of_mpc8xxx_spi_probe(ofdev, ofid); | 697 | ret = of_mpc8xxx_spi_probe(ofdev); |
699 | if (ret) | 698 | if (ret) |
700 | return ret; | 699 | return ret; |
701 | 700 | ||
@@ -736,7 +735,7 @@ static const struct of_device_id of_fsl_espi_match[] = { | |||
736 | }; | 735 | }; |
737 | MODULE_DEVICE_TABLE(of, of_fsl_espi_match); | 736 | MODULE_DEVICE_TABLE(of, of_fsl_espi_match); |
738 | 737 | ||
739 | static struct of_platform_driver fsl_espi_driver = { | 738 | static struct platform_driver fsl_espi_driver = { |
740 | .driver = { | 739 | .driver = { |
741 | .name = "fsl_espi", | 740 | .name = "fsl_espi", |
742 | .owner = THIS_MODULE, | 741 | .owner = THIS_MODULE, |
@@ -748,13 +747,13 @@ static struct of_platform_driver fsl_espi_driver = { | |||
748 | 747 | ||
749 | static int __init fsl_espi_init(void) | 748 | static int __init fsl_espi_init(void) |
750 | { | 749 | { |
751 | return of_register_platform_driver(&fsl_espi_driver); | 750 | return platform_driver_register(&fsl_espi_driver); |
752 | } | 751 | } |
753 | module_init(fsl_espi_init); | 752 | module_init(fsl_espi_init); |
754 | 753 | ||
755 | static void __exit fsl_espi_exit(void) | 754 | static void __exit fsl_espi_exit(void) |
756 | { | 755 | { |
757 | of_unregister_platform_driver(&fsl_espi_driver); | 756 | platform_driver_unregister(&fsl_espi_driver); |
758 | } | 757 | } |
759 | module_exit(fsl_espi_exit); | 758 | module_exit(fsl_espi_exit); |
760 | 759 | ||
diff --git a/drivers/spi/spi_fsl_lib.c b/drivers/spi/spi_fsl_lib.c index 5cd741fdb5c3..ff59f42ae990 100644 --- a/drivers/spi/spi_fsl_lib.c +++ b/drivers/spi/spi_fsl_lib.c | |||
@@ -189,8 +189,7 @@ int __devexit mpc8xxx_spi_remove(struct device *dev) | |||
189 | return 0; | 189 | return 0; |
190 | } | 190 | } |
191 | 191 | ||
192 | int __devinit of_mpc8xxx_spi_probe(struct platform_device *ofdev, | 192 | int __devinit of_mpc8xxx_spi_probe(struct platform_device *ofdev) |
193 | const struct of_device_id *ofid) | ||
194 | { | 193 | { |
195 | struct device *dev = &ofdev->dev; | 194 | struct device *dev = &ofdev->dev; |
196 | struct device_node *np = ofdev->dev.of_node; | 195 | struct device_node *np = ofdev->dev.of_node; |
diff --git a/drivers/spi/spi_fsl_lib.h b/drivers/spi/spi_fsl_lib.h index 281e060977cd..cbe881b9ea76 100644 --- a/drivers/spi/spi_fsl_lib.h +++ b/drivers/spi/spi_fsl_lib.h | |||
@@ -118,7 +118,6 @@ extern const char *mpc8xxx_spi_strmode(unsigned int flags); | |||
118 | extern int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, | 118 | extern int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, |
119 | unsigned int irq); | 119 | unsigned int irq); |
120 | extern int mpc8xxx_spi_remove(struct device *dev); | 120 | extern int mpc8xxx_spi_remove(struct device *dev); |
121 | extern int of_mpc8xxx_spi_probe(struct platform_device *ofdev, | 121 | extern int of_mpc8xxx_spi_probe(struct platform_device *ofdev); |
122 | const struct of_device_id *ofid); | ||
123 | 122 | ||
124 | #endif /* __SPI_FSL_LIB_H__ */ | 123 | #endif /* __SPI_FSL_LIB_H__ */ |
diff --git a/drivers/spi/spi_fsl_spi.c b/drivers/spi/spi_fsl_spi.c index 7ca52d3ae8f8..7963c9b49566 100644 --- a/drivers/spi/spi_fsl_spi.c +++ b/drivers/spi/spi_fsl_spi.c | |||
@@ -1042,8 +1042,7 @@ static int of_fsl_spi_free_chipselects(struct device *dev) | |||
1042 | return 0; | 1042 | return 0; |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | static int __devinit of_fsl_spi_probe(struct platform_device *ofdev, | 1045 | static int __devinit of_fsl_spi_probe(struct platform_device *ofdev) |
1046 | const struct of_device_id *ofid) | ||
1047 | { | 1046 | { |
1048 | struct device *dev = &ofdev->dev; | 1047 | struct device *dev = &ofdev->dev; |
1049 | struct device_node *np = ofdev->dev.of_node; | 1048 | struct device_node *np = ofdev->dev.of_node; |
@@ -1052,7 +1051,7 @@ static int __devinit of_fsl_spi_probe(struct platform_device *ofdev, | |||
1052 | struct resource irq; | 1051 | struct resource irq; |
1053 | int ret = -ENOMEM; | 1052 | int ret = -ENOMEM; |
1054 | 1053 | ||
1055 | ret = of_mpc8xxx_spi_probe(ofdev, ofid); | 1054 | ret = of_mpc8xxx_spi_probe(ofdev); |
1056 | if (ret) | 1055 | if (ret) |
1057 | return ret; | 1056 | return ret; |
1058 | 1057 | ||
@@ -1100,7 +1099,7 @@ static const struct of_device_id of_fsl_spi_match[] = { | |||
1100 | }; | 1099 | }; |
1101 | MODULE_DEVICE_TABLE(of, of_fsl_spi_match); | 1100 | MODULE_DEVICE_TABLE(of, of_fsl_spi_match); |
1102 | 1101 | ||
1103 | static struct of_platform_driver of_fsl_spi_driver = { | 1102 | static struct platform_driver of_fsl_spi_driver = { |
1104 | .driver = { | 1103 | .driver = { |
1105 | .name = "fsl_spi", | 1104 | .name = "fsl_spi", |
1106 | .owner = THIS_MODULE, | 1105 | .owner = THIS_MODULE, |
@@ -1177,13 +1176,13 @@ static void __exit legacy_driver_unregister(void) {} | |||
1177 | static int __init fsl_spi_init(void) | 1176 | static int __init fsl_spi_init(void) |
1178 | { | 1177 | { |
1179 | legacy_driver_register(); | 1178 | legacy_driver_register(); |
1180 | return of_register_platform_driver(&of_fsl_spi_driver); | 1179 | return platform_driver_register(&of_fsl_spi_driver); |
1181 | } | 1180 | } |
1182 | module_init(fsl_spi_init); | 1181 | module_init(fsl_spi_init); |
1183 | 1182 | ||
1184 | static void __exit fsl_spi_exit(void) | 1183 | static void __exit fsl_spi_exit(void) |
1185 | { | 1184 | { |
1186 | of_unregister_platform_driver(&of_fsl_spi_driver); | 1185 | platform_driver_unregister(&of_fsl_spi_driver); |
1187 | legacy_driver_unregister(); | 1186 | legacy_driver_unregister(); |
1188 | } | 1187 | } |
1189 | module_exit(fsl_spi_exit); | 1188 | module_exit(fsl_spi_exit); |
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 1cf9d5faabf4..69d6dba67c19 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c | |||
@@ -174,7 +174,7 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, | |||
174 | #define SPI_IMX2_3_CTRL 0x08 | 174 | #define SPI_IMX2_3_CTRL 0x08 |
175 | #define SPI_IMX2_3_CTRL_ENABLE (1 << 0) | 175 | #define SPI_IMX2_3_CTRL_ENABLE (1 << 0) |
176 | #define SPI_IMX2_3_CTRL_XCH (1 << 2) | 176 | #define SPI_IMX2_3_CTRL_XCH (1 << 2) |
177 | #define SPI_IMX2_3_CTRL_MODE(cs) (1 << ((cs) + 4)) | 177 | #define SPI_IMX2_3_CTRL_MODE_MASK (0xf << 4) |
178 | #define SPI_IMX2_3_CTRL_POSTDIV_OFFSET 8 | 178 | #define SPI_IMX2_3_CTRL_POSTDIV_OFFSET 8 |
179 | #define SPI_IMX2_3_CTRL_PREDIV_OFFSET 12 | 179 | #define SPI_IMX2_3_CTRL_PREDIV_OFFSET 12 |
180 | #define SPI_IMX2_3_CTRL_CS(cs) ((cs) << 18) | 180 | #define SPI_IMX2_3_CTRL_CS(cs) ((cs) << 18) |
@@ -253,8 +253,14 @@ static int __maybe_unused spi_imx2_3_config(struct spi_imx_data *spi_imx, | |||
253 | { | 253 | { |
254 | u32 ctrl = SPI_IMX2_3_CTRL_ENABLE, cfg = 0; | 254 | u32 ctrl = SPI_IMX2_3_CTRL_ENABLE, cfg = 0; |
255 | 255 | ||
256 | /* set master mode */ | 256 | /* |
257 | ctrl |= SPI_IMX2_3_CTRL_MODE(config->cs); | 257 | * The hardware seems to have a race condition when changing modes. The |
258 | * current assumption is that the selection of the channel arrives | ||
259 | * earlier in the hardware than the mode bits when they are written at | ||
260 | * the same time. | ||
261 | * So set master mode for all channels as we do not support slave mode. | ||
262 | */ | ||
263 | ctrl |= SPI_IMX2_3_CTRL_MODE_MASK; | ||
258 | 264 | ||
259 | /* set clock speed */ | 265 | /* set clock speed */ |
260 | ctrl |= spi_imx2_3_clkdiv(spi_imx->spi_clk, config->speed_hz); | 266 | ctrl |= spi_imx2_3_clkdiv(spi_imx->spi_clk, config->speed_hz); |
diff --git a/drivers/spi/spi_oc_tiny.c b/drivers/spi/spi_oc_tiny.c new file mode 100644 index 000000000000..f1bde66cea19 --- /dev/null +++ b/drivers/spi/spi_oc_tiny.c | |||
@@ -0,0 +1,425 @@ | |||
1 | /* | ||
2 | * OpenCores tiny SPI master driver | ||
3 | * | ||
4 | * http://opencores.org/project,tiny_spi | ||
5 | * | ||
6 | * Copyright (C) 2011 Thomas Chou <thomas@wytron.com.tw> | ||
7 | * | ||
8 | * Based on spi_s3c24xx.c, which is: | ||
9 | * Copyright (c) 2006 Ben Dooks | ||
10 | * Copyright (c) 2006 Simtec Electronics | ||
11 | * Ben Dooks <ben@simtec.co.uk> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 as | ||
15 | * published by the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/spi/spi.h> | ||
23 | #include <linux/spi/spi_bitbang.h> | ||
24 | #include <linux/spi/spi_oc_tiny.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/of.h> | ||
28 | |||
29 | #define DRV_NAME "spi_oc_tiny" | ||
30 | |||
31 | #define TINY_SPI_RXDATA 0 | ||
32 | #define TINY_SPI_TXDATA 4 | ||
33 | #define TINY_SPI_STATUS 8 | ||
34 | #define TINY_SPI_CONTROL 12 | ||
35 | #define TINY_SPI_BAUD 16 | ||
36 | |||
37 | #define TINY_SPI_STATUS_TXE 0x1 | ||
38 | #define TINY_SPI_STATUS_TXR 0x2 | ||
39 | |||
40 | struct tiny_spi { | ||
41 | /* bitbang has to be first */ | ||
42 | struct spi_bitbang bitbang; | ||
43 | struct completion done; | ||
44 | |||
45 | void __iomem *base; | ||
46 | int irq; | ||
47 | unsigned int freq; | ||
48 | unsigned int baudwidth; | ||
49 | unsigned int baud; | ||
50 | unsigned int speed_hz; | ||
51 | unsigned int mode; | ||
52 | unsigned int len; | ||
53 | unsigned int txc, rxc; | ||
54 | const u8 *txp; | ||
55 | u8 *rxp; | ||
56 | unsigned int gpio_cs_count; | ||
57 | int *gpio_cs; | ||
58 | }; | ||
59 | |||
60 | static inline struct tiny_spi *tiny_spi_to_hw(struct spi_device *sdev) | ||
61 | { | ||
62 | return spi_master_get_devdata(sdev->master); | ||
63 | } | ||
64 | |||
65 | static unsigned int tiny_spi_baud(struct spi_device *spi, unsigned int hz) | ||
66 | { | ||
67 | struct tiny_spi *hw = tiny_spi_to_hw(spi); | ||
68 | |||
69 | return min(DIV_ROUND_UP(hw->freq, hz * 2), (1U << hw->baudwidth)) - 1; | ||
70 | } | ||
71 | |||
72 | static void tiny_spi_chipselect(struct spi_device *spi, int is_active) | ||
73 | { | ||
74 | struct tiny_spi *hw = tiny_spi_to_hw(spi); | ||
75 | |||
76 | if (hw->gpio_cs_count) { | ||
77 | gpio_set_value(hw->gpio_cs[spi->chip_select], | ||
78 | (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static int tiny_spi_setup_transfer(struct spi_device *spi, | ||
83 | struct spi_transfer *t) | ||
84 | { | ||
85 | struct tiny_spi *hw = tiny_spi_to_hw(spi); | ||
86 | unsigned int baud = hw->baud; | ||
87 | |||
88 | if (t) { | ||
89 | if (t->speed_hz && t->speed_hz != hw->speed_hz) | ||
90 | baud = tiny_spi_baud(spi, t->speed_hz); | ||
91 | } | ||
92 | writel(baud, hw->base + TINY_SPI_BAUD); | ||
93 | writel(hw->mode, hw->base + TINY_SPI_CONTROL); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int tiny_spi_setup(struct spi_device *spi) | ||
98 | { | ||
99 | struct tiny_spi *hw = tiny_spi_to_hw(spi); | ||
100 | |||
101 | if (spi->max_speed_hz != hw->speed_hz) { | ||
102 | hw->speed_hz = spi->max_speed_hz; | ||
103 | hw->baud = tiny_spi_baud(spi, hw->speed_hz); | ||
104 | } | ||
105 | hw->mode = spi->mode & (SPI_CPOL | SPI_CPHA); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static inline void tiny_spi_wait_txr(struct tiny_spi *hw) | ||
110 | { | ||
111 | while (!(readb(hw->base + TINY_SPI_STATUS) & | ||
112 | TINY_SPI_STATUS_TXR)) | ||
113 | cpu_relax(); | ||
114 | } | ||
115 | |||
116 | static inline void tiny_spi_wait_txe(struct tiny_spi *hw) | ||
117 | { | ||
118 | while (!(readb(hw->base + TINY_SPI_STATUS) & | ||
119 | TINY_SPI_STATUS_TXE)) | ||
120 | cpu_relax(); | ||
121 | } | ||
122 | |||
123 | static int tiny_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | ||
124 | { | ||
125 | struct tiny_spi *hw = tiny_spi_to_hw(spi); | ||
126 | const u8 *txp = t->tx_buf; | ||
127 | u8 *rxp = t->rx_buf; | ||
128 | unsigned int i; | ||
129 | |||
130 | if (hw->irq >= 0) { | ||
131 | /* use intrrupt driven data transfer */ | ||
132 | hw->len = t->len; | ||
133 | hw->txp = t->tx_buf; | ||
134 | hw->rxp = t->rx_buf; | ||
135 | hw->txc = 0; | ||
136 | hw->rxc = 0; | ||
137 | |||
138 | /* send the first byte */ | ||
139 | if (t->len > 1) { | ||
140 | writeb(hw->txp ? *hw->txp++ : 0, | ||
141 | hw->base + TINY_SPI_TXDATA); | ||
142 | hw->txc++; | ||
143 | writeb(hw->txp ? *hw->txp++ : 0, | ||
144 | hw->base + TINY_SPI_TXDATA); | ||
145 | hw->txc++; | ||
146 | writeb(TINY_SPI_STATUS_TXR, hw->base + TINY_SPI_STATUS); | ||
147 | } else { | ||
148 | writeb(hw->txp ? *hw->txp++ : 0, | ||
149 | hw->base + TINY_SPI_TXDATA); | ||
150 | hw->txc++; | ||
151 | writeb(TINY_SPI_STATUS_TXE, hw->base + TINY_SPI_STATUS); | ||
152 | } | ||
153 | |||
154 | wait_for_completion(&hw->done); | ||
155 | } else if (txp && rxp) { | ||
156 | /* we need to tighten the transfer loop */ | ||
157 | writeb(*txp++, hw->base + TINY_SPI_TXDATA); | ||
158 | if (t->len > 1) { | ||
159 | writeb(*txp++, hw->base + TINY_SPI_TXDATA); | ||
160 | for (i = 2; i < t->len; i++) { | ||
161 | u8 rx, tx = *txp++; | ||
162 | tiny_spi_wait_txr(hw); | ||
163 | rx = readb(hw->base + TINY_SPI_TXDATA); | ||
164 | writeb(tx, hw->base + TINY_SPI_TXDATA); | ||
165 | *rxp++ = rx; | ||
166 | } | ||
167 | tiny_spi_wait_txr(hw); | ||
168 | *rxp++ = readb(hw->base + TINY_SPI_TXDATA); | ||
169 | } | ||
170 | tiny_spi_wait_txe(hw); | ||
171 | *rxp++ = readb(hw->base + TINY_SPI_RXDATA); | ||
172 | } else if (rxp) { | ||
173 | writeb(0, hw->base + TINY_SPI_TXDATA); | ||
174 | if (t->len > 1) { | ||
175 | writeb(0, | ||
176 | hw->base + TINY_SPI_TXDATA); | ||
177 | for (i = 2; i < t->len; i++) { | ||
178 | u8 rx; | ||
179 | tiny_spi_wait_txr(hw); | ||
180 | rx = readb(hw->base + TINY_SPI_TXDATA); | ||
181 | writeb(0, hw->base + TINY_SPI_TXDATA); | ||
182 | *rxp++ = rx; | ||
183 | } | ||
184 | tiny_spi_wait_txr(hw); | ||
185 | *rxp++ = readb(hw->base + TINY_SPI_TXDATA); | ||
186 | } | ||
187 | tiny_spi_wait_txe(hw); | ||
188 | *rxp++ = readb(hw->base + TINY_SPI_RXDATA); | ||
189 | } else if (txp) { | ||
190 | writeb(*txp++, hw->base + TINY_SPI_TXDATA); | ||
191 | if (t->len > 1) { | ||
192 | writeb(*txp++, hw->base + TINY_SPI_TXDATA); | ||
193 | for (i = 2; i < t->len; i++) { | ||
194 | u8 tx = *txp++; | ||
195 | tiny_spi_wait_txr(hw); | ||
196 | writeb(tx, hw->base + TINY_SPI_TXDATA); | ||
197 | } | ||
198 | } | ||
199 | tiny_spi_wait_txe(hw); | ||
200 | } else { | ||
201 | writeb(0, hw->base + TINY_SPI_TXDATA); | ||
202 | if (t->len > 1) { | ||
203 | writeb(0, hw->base + TINY_SPI_TXDATA); | ||
204 | for (i = 2; i < t->len; i++) { | ||
205 | tiny_spi_wait_txr(hw); | ||
206 | writeb(0, hw->base + TINY_SPI_TXDATA); | ||
207 | } | ||
208 | } | ||
209 | tiny_spi_wait_txe(hw); | ||
210 | } | ||
211 | return t->len; | ||
212 | } | ||
213 | |||
214 | static irqreturn_t tiny_spi_irq(int irq, void *dev) | ||
215 | { | ||
216 | struct tiny_spi *hw = dev; | ||
217 | |||
218 | writeb(0, hw->base + TINY_SPI_STATUS); | ||
219 | if (hw->rxc + 1 == hw->len) { | ||
220 | if (hw->rxp) | ||
221 | *hw->rxp++ = readb(hw->base + TINY_SPI_RXDATA); | ||
222 | hw->rxc++; | ||
223 | complete(&hw->done); | ||
224 | } else { | ||
225 | if (hw->rxp) | ||
226 | *hw->rxp++ = readb(hw->base + TINY_SPI_TXDATA); | ||
227 | hw->rxc++; | ||
228 | if (hw->txc < hw->len) { | ||
229 | writeb(hw->txp ? *hw->txp++ : 0, | ||
230 | hw->base + TINY_SPI_TXDATA); | ||
231 | hw->txc++; | ||
232 | writeb(TINY_SPI_STATUS_TXR, | ||
233 | hw->base + TINY_SPI_STATUS); | ||
234 | } else { | ||
235 | writeb(TINY_SPI_STATUS_TXE, | ||
236 | hw->base + TINY_SPI_STATUS); | ||
237 | } | ||
238 | } | ||
239 | return IRQ_HANDLED; | ||
240 | } | ||
241 | |||
242 | #ifdef CONFIG_OF | ||
243 | #include <linux/of_gpio.h> | ||
244 | |||
245 | static int __devinit tiny_spi_of_probe(struct platform_device *pdev) | ||
246 | { | ||
247 | struct tiny_spi *hw = platform_get_drvdata(pdev); | ||
248 | struct device_node *np = pdev->dev.of_node; | ||
249 | unsigned int i; | ||
250 | const __be32 *val; | ||
251 | int len; | ||
252 | |||
253 | if (!np) | ||
254 | return 0; | ||
255 | hw->gpio_cs_count = of_gpio_count(np); | ||
256 | if (hw->gpio_cs_count) { | ||
257 | hw->gpio_cs = devm_kzalloc(&pdev->dev, | ||
258 | hw->gpio_cs_count * sizeof(unsigned int), | ||
259 | GFP_KERNEL); | ||
260 | if (!hw->gpio_cs) | ||
261 | return -ENOMEM; | ||
262 | } | ||
263 | for (i = 0; i < hw->gpio_cs_count; i++) { | ||
264 | hw->gpio_cs[i] = of_get_gpio_flags(np, i, NULL); | ||
265 | if (hw->gpio_cs[i] < 0) | ||
266 | return -ENODEV; | ||
267 | } | ||
268 | hw->bitbang.master->dev.of_node = pdev->dev.of_node; | ||
269 | val = of_get_property(pdev->dev.of_node, | ||
270 | "clock-frequency", &len); | ||
271 | if (val && len >= sizeof(__be32)) | ||
272 | hw->freq = be32_to_cpup(val); | ||
273 | val = of_get_property(pdev->dev.of_node, "baud-width", &len); | ||
274 | if (val && len >= sizeof(__be32)) | ||
275 | hw->baudwidth = be32_to_cpup(val); | ||
276 | return 0; | ||
277 | } | ||
278 | #else /* !CONFIG_OF */ | ||
279 | static int __devinit tiny_spi_of_probe(struct platform_device *pdev) | ||
280 | { | ||
281 | return 0; | ||
282 | } | ||
283 | #endif /* CONFIG_OF */ | ||
284 | |||
285 | static int __devinit tiny_spi_probe(struct platform_device *pdev) | ||
286 | { | ||
287 | struct tiny_spi_platform_data *platp = pdev->dev.platform_data; | ||
288 | struct tiny_spi *hw; | ||
289 | struct spi_master *master; | ||
290 | struct resource *res; | ||
291 | unsigned int i; | ||
292 | int err = -ENODEV; | ||
293 | |||
294 | master = spi_alloc_master(&pdev->dev, sizeof(struct tiny_spi)); | ||
295 | if (!master) | ||
296 | return err; | ||
297 | |||
298 | /* setup the master state. */ | ||
299 | master->bus_num = pdev->id; | ||
300 | master->num_chipselect = 255; | ||
301 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | ||
302 | master->setup = tiny_spi_setup; | ||
303 | |||
304 | hw = spi_master_get_devdata(master); | ||
305 | platform_set_drvdata(pdev, hw); | ||
306 | |||
307 | /* setup the state for the bitbang driver */ | ||
308 | hw->bitbang.master = spi_master_get(master); | ||
309 | if (!hw->bitbang.master) | ||
310 | return err; | ||
311 | hw->bitbang.setup_transfer = tiny_spi_setup_transfer; | ||
312 | hw->bitbang.chipselect = tiny_spi_chipselect; | ||
313 | hw->bitbang.txrx_bufs = tiny_spi_txrx_bufs; | ||
314 | |||
315 | /* find and map our resources */ | ||
316 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
317 | if (!res) | ||
318 | goto exit_busy; | ||
319 | if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), | ||
320 | pdev->name)) | ||
321 | goto exit_busy; | ||
322 | hw->base = devm_ioremap_nocache(&pdev->dev, res->start, | ||
323 | resource_size(res)); | ||
324 | if (!hw->base) | ||
325 | goto exit_busy; | ||
326 | /* irq is optional */ | ||
327 | hw->irq = platform_get_irq(pdev, 0); | ||
328 | if (hw->irq >= 0) { | ||
329 | init_completion(&hw->done); | ||
330 | err = devm_request_irq(&pdev->dev, hw->irq, tiny_spi_irq, 0, | ||
331 | pdev->name, hw); | ||
332 | if (err) | ||
333 | goto exit; | ||
334 | } | ||
335 | /* find platform data */ | ||
336 | if (platp) { | ||
337 | hw->gpio_cs_count = platp->gpio_cs_count; | ||
338 | hw->gpio_cs = platp->gpio_cs; | ||
339 | if (platp->gpio_cs_count && !platp->gpio_cs) | ||
340 | goto exit_busy; | ||
341 | hw->freq = platp->freq; | ||
342 | hw->baudwidth = platp->baudwidth; | ||
343 | } else { | ||
344 | err = tiny_spi_of_probe(pdev); | ||
345 | if (err) | ||
346 | goto exit; | ||
347 | } | ||
348 | for (i = 0; i < hw->gpio_cs_count; i++) { | ||
349 | err = gpio_request(hw->gpio_cs[i], dev_name(&pdev->dev)); | ||
350 | if (err) | ||
351 | goto exit_gpio; | ||
352 | gpio_direction_output(hw->gpio_cs[i], 1); | ||
353 | } | ||
354 | hw->bitbang.master->num_chipselect = max(1U, hw->gpio_cs_count); | ||
355 | |||
356 | /* register our spi controller */ | ||
357 | err = spi_bitbang_start(&hw->bitbang); | ||
358 | if (err) | ||
359 | goto exit; | ||
360 | dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq); | ||
361 | |||
362 | return 0; | ||
363 | |||
364 | exit_gpio: | ||
365 | while (i-- > 0) | ||
366 | gpio_free(hw->gpio_cs[i]); | ||
367 | exit_busy: | ||
368 | err = -EBUSY; | ||
369 | exit: | ||
370 | platform_set_drvdata(pdev, NULL); | ||
371 | spi_master_put(master); | ||
372 | return err; | ||
373 | } | ||
374 | |||
375 | static int __devexit tiny_spi_remove(struct platform_device *pdev) | ||
376 | { | ||
377 | struct tiny_spi *hw = platform_get_drvdata(pdev); | ||
378 | struct spi_master *master = hw->bitbang.master; | ||
379 | unsigned int i; | ||
380 | |||
381 | spi_bitbang_stop(&hw->bitbang); | ||
382 | for (i = 0; i < hw->gpio_cs_count; i++) | ||
383 | gpio_free(hw->gpio_cs[i]); | ||
384 | platform_set_drvdata(pdev, NULL); | ||
385 | spi_master_put(master); | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | #ifdef CONFIG_OF | ||
390 | static const struct of_device_id tiny_spi_match[] = { | ||
391 | { .compatible = "opencores,tiny-spi-rtlsvn2", }, | ||
392 | {}, | ||
393 | }; | ||
394 | MODULE_DEVICE_TABLE(of, tiny_spi_match); | ||
395 | #else /* CONFIG_OF */ | ||
396 | #define tiny_spi_match NULL | ||
397 | #endif /* CONFIG_OF */ | ||
398 | |||
399 | static struct platform_driver tiny_spi_driver = { | ||
400 | .probe = tiny_spi_probe, | ||
401 | .remove = __devexit_p(tiny_spi_remove), | ||
402 | .driver = { | ||
403 | .name = DRV_NAME, | ||
404 | .owner = THIS_MODULE, | ||
405 | .pm = NULL, | ||
406 | .of_match_table = tiny_spi_match, | ||
407 | }, | ||
408 | }; | ||
409 | |||
410 | static int __init tiny_spi_init(void) | ||
411 | { | ||
412 | return platform_driver_register(&tiny_spi_driver); | ||
413 | } | ||
414 | module_init(tiny_spi_init); | ||
415 | |||
416 | static void __exit tiny_spi_exit(void) | ||
417 | { | ||
418 | platform_driver_unregister(&tiny_spi_driver); | ||
419 | } | ||
420 | module_exit(tiny_spi_exit); | ||
421 | |||
422 | MODULE_DESCRIPTION("OpenCores tiny SPI driver"); | ||
423 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); | ||
424 | MODULE_LICENSE("GPL"); | ||
425 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c index 80e172d3e72a..2a298c029194 100644 --- a/drivers/spi/spi_ppc4xx.c +++ b/drivers/spi/spi_ppc4xx.c | |||
@@ -390,8 +390,7 @@ static void free_gpios(struct ppc4xx_spi *hw) | |||
390 | /* | 390 | /* |
391 | * platform_device layer stuff... | 391 | * platform_device layer stuff... |
392 | */ | 392 | */ |
393 | static int __init spi_ppc4xx_of_probe(struct platform_device *op, | 393 | static int __init spi_ppc4xx_of_probe(struct platform_device *op) |
394 | const struct of_device_id *match) | ||
395 | { | 394 | { |
396 | struct ppc4xx_spi *hw; | 395 | struct ppc4xx_spi *hw; |
397 | struct spi_master *master; | 396 | struct spi_master *master; |
@@ -586,7 +585,7 @@ static const struct of_device_id spi_ppc4xx_of_match[] = { | |||
586 | 585 | ||
587 | MODULE_DEVICE_TABLE(of, spi_ppc4xx_of_match); | 586 | MODULE_DEVICE_TABLE(of, spi_ppc4xx_of_match); |
588 | 587 | ||
589 | static struct of_platform_driver spi_ppc4xx_of_driver = { | 588 | static struct platform_driver spi_ppc4xx_of_driver = { |
590 | .probe = spi_ppc4xx_of_probe, | 589 | .probe = spi_ppc4xx_of_probe, |
591 | .remove = __exit_p(spi_ppc4xx_of_remove), | 590 | .remove = __exit_p(spi_ppc4xx_of_remove), |
592 | .driver = { | 591 | .driver = { |
@@ -598,13 +597,13 @@ static struct of_platform_driver spi_ppc4xx_of_driver = { | |||
598 | 597 | ||
599 | static int __init spi_ppc4xx_init(void) | 598 | static int __init spi_ppc4xx_init(void) |
600 | { | 599 | { |
601 | return of_register_platform_driver(&spi_ppc4xx_of_driver); | 600 | return platform_driver_register(&spi_ppc4xx_of_driver); |
602 | } | 601 | } |
603 | module_init(spi_ppc4xx_init); | 602 | module_init(spi_ppc4xx_init); |
604 | 603 | ||
605 | static void __exit spi_ppc4xx_exit(void) | 604 | static void __exit spi_ppc4xx_exit(void) |
606 | { | 605 | { |
607 | of_unregister_platform_driver(&spi_ppc4xx_of_driver); | 606 | platform_driver_unregister(&spi_ppc4xx_of_driver); |
608 | } | 607 | } |
609 | module_exit(spi_ppc4xx_exit); | 608 | module_exit(spi_ppc4xx_exit); |
610 | 609 | ||
diff --git a/drivers/spi/spi_sh.c b/drivers/spi/spi_sh.c new file mode 100644 index 000000000000..869a07d375d6 --- /dev/null +++ b/drivers/spi/spi_sh.c | |||
@@ -0,0 +1,543 @@ | |||
1 | /* | ||
2 | * SH SPI bus driver | ||
3 | * | ||
4 | * Copyright (C) 2011 Renesas Solutions Corp. | ||
5 | * | ||
6 | * Based on pxa2xx_spi.c: | ||
7 | * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/timer.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/list.h> | ||
31 | #include <linux/workqueue.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/io.h> | ||
35 | #include <linux/spi/spi.h> | ||
36 | |||
37 | #define SPI_SH_TBR 0x00 | ||
38 | #define SPI_SH_RBR 0x00 | ||
39 | #define SPI_SH_CR1 0x08 | ||
40 | #define SPI_SH_CR2 0x10 | ||
41 | #define SPI_SH_CR3 0x18 | ||
42 | #define SPI_SH_CR4 0x20 | ||
43 | #define SPI_SH_CR5 0x28 | ||
44 | |||
45 | /* CR1 */ | ||
46 | #define SPI_SH_TBE 0x80 | ||
47 | #define SPI_SH_TBF 0x40 | ||
48 | #define SPI_SH_RBE 0x20 | ||
49 | #define SPI_SH_RBF 0x10 | ||
50 | #define SPI_SH_PFONRD 0x08 | ||
51 | #define SPI_SH_SSDB 0x04 | ||
52 | #define SPI_SH_SSD 0x02 | ||
53 | #define SPI_SH_SSA 0x01 | ||
54 | |||
55 | /* CR2 */ | ||
56 | #define SPI_SH_RSTF 0x80 | ||
57 | #define SPI_SH_LOOPBK 0x40 | ||
58 | #define SPI_SH_CPOL 0x20 | ||
59 | #define SPI_SH_CPHA 0x10 | ||
60 | #define SPI_SH_L1M0 0x08 | ||
61 | |||
62 | /* CR3 */ | ||
63 | #define SPI_SH_MAX_BYTE 0xFF | ||
64 | |||
65 | /* CR4 */ | ||
66 | #define SPI_SH_TBEI 0x80 | ||
67 | #define SPI_SH_TBFI 0x40 | ||
68 | #define SPI_SH_RBEI 0x20 | ||
69 | #define SPI_SH_RBFI 0x10 | ||
70 | #define SPI_SH_WPABRT 0x04 | ||
71 | #define SPI_SH_SSS 0x01 | ||
72 | |||
73 | /* CR8 */ | ||
74 | #define SPI_SH_P1L0 0x80 | ||
75 | #define SPI_SH_PP1L0 0x40 | ||
76 | #define SPI_SH_MUXI 0x20 | ||
77 | #define SPI_SH_MUXIRQ 0x10 | ||
78 | |||
79 | #define SPI_SH_FIFO_SIZE 32 | ||
80 | #define SPI_SH_SEND_TIMEOUT (3 * HZ) | ||
81 | #define SPI_SH_RECEIVE_TIMEOUT (HZ >> 3) | ||
82 | |||
83 | #undef DEBUG | ||
84 | |||
85 | struct spi_sh_data { | ||
86 | void __iomem *addr; | ||
87 | int irq; | ||
88 | struct spi_master *master; | ||
89 | struct list_head queue; | ||
90 | struct workqueue_struct *workqueue; | ||
91 | struct work_struct ws; | ||
92 | unsigned long cr1; | ||
93 | wait_queue_head_t wait; | ||
94 | spinlock_t lock; | ||
95 | }; | ||
96 | |||
97 | static void spi_sh_write(struct spi_sh_data *ss, unsigned long data, | ||
98 | unsigned long offset) | ||
99 | { | ||
100 | writel(data, ss->addr + offset); | ||
101 | } | ||
102 | |||
103 | static unsigned long spi_sh_read(struct spi_sh_data *ss, unsigned long offset) | ||
104 | { | ||
105 | return readl(ss->addr + offset); | ||
106 | } | ||
107 | |||
108 | static void spi_sh_set_bit(struct spi_sh_data *ss, unsigned long val, | ||
109 | unsigned long offset) | ||
110 | { | ||
111 | unsigned long tmp; | ||
112 | |||
113 | tmp = spi_sh_read(ss, offset); | ||
114 | tmp |= val; | ||
115 | spi_sh_write(ss, tmp, offset); | ||
116 | } | ||
117 | |||
118 | static void spi_sh_clear_bit(struct spi_sh_data *ss, unsigned long val, | ||
119 | unsigned long offset) | ||
120 | { | ||
121 | unsigned long tmp; | ||
122 | |||
123 | tmp = spi_sh_read(ss, offset); | ||
124 | tmp &= ~val; | ||
125 | spi_sh_write(ss, tmp, offset); | ||
126 | } | ||
127 | |||
128 | static void clear_fifo(struct spi_sh_data *ss) | ||
129 | { | ||
130 | spi_sh_set_bit(ss, SPI_SH_RSTF, SPI_SH_CR2); | ||
131 | spi_sh_clear_bit(ss, SPI_SH_RSTF, SPI_SH_CR2); | ||
132 | } | ||
133 | |||
134 | static int spi_sh_wait_receive_buffer(struct spi_sh_data *ss) | ||
135 | { | ||
136 | int timeout = 100000; | ||
137 | |||
138 | while (spi_sh_read(ss, SPI_SH_CR1) & SPI_SH_RBE) { | ||
139 | udelay(10); | ||
140 | if (timeout-- < 0) | ||
141 | return -ETIMEDOUT; | ||
142 | } | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static int spi_sh_wait_write_buffer_empty(struct spi_sh_data *ss) | ||
147 | { | ||
148 | int timeout = 100000; | ||
149 | |||
150 | while (!(spi_sh_read(ss, SPI_SH_CR1) & SPI_SH_TBE)) { | ||
151 | udelay(10); | ||
152 | if (timeout-- < 0) | ||
153 | return -ETIMEDOUT; | ||
154 | } | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg, | ||
159 | struct spi_transfer *t) | ||
160 | { | ||
161 | int i, retval = 0; | ||
162 | int remain = t->len; | ||
163 | int cur_len; | ||
164 | unsigned char *data; | ||
165 | unsigned long tmp; | ||
166 | long ret; | ||
167 | |||
168 | if (t->len) | ||
169 | spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1); | ||
170 | |||
171 | data = (unsigned char *)t->tx_buf; | ||
172 | while (remain > 0) { | ||
173 | cur_len = min(SPI_SH_FIFO_SIZE, remain); | ||
174 | for (i = 0; i < cur_len && | ||
175 | !(spi_sh_read(ss, SPI_SH_CR4) & | ||
176 | SPI_SH_WPABRT) && | ||
177 | !(spi_sh_read(ss, SPI_SH_CR1) & SPI_SH_TBF); | ||
178 | i++) | ||
179 | spi_sh_write(ss, (unsigned long)data[i], SPI_SH_TBR); | ||
180 | |||
181 | if (spi_sh_read(ss, SPI_SH_CR4) & SPI_SH_WPABRT) { | ||
182 | /* Abort SPI operation */ | ||
183 | spi_sh_set_bit(ss, SPI_SH_WPABRT, SPI_SH_CR4); | ||
184 | retval = -EIO; | ||
185 | break; | ||
186 | } | ||
187 | |||
188 | cur_len = i; | ||
189 | |||
190 | remain -= cur_len; | ||
191 | data += cur_len; | ||
192 | |||
193 | if (remain > 0) { | ||
194 | ss->cr1 &= ~SPI_SH_TBE; | ||
195 | spi_sh_set_bit(ss, SPI_SH_TBE, SPI_SH_CR4); | ||
196 | ret = wait_event_interruptible_timeout(ss->wait, | ||
197 | ss->cr1 & SPI_SH_TBE, | ||
198 | SPI_SH_SEND_TIMEOUT); | ||
199 | if (ret == 0 && !(ss->cr1 & SPI_SH_TBE)) { | ||
200 | printk(KERN_ERR "%s: timeout\n", __func__); | ||
201 | return -ETIMEDOUT; | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | if (list_is_last(&t->transfer_list, &mesg->transfers)) { | ||
207 | tmp = spi_sh_read(ss, SPI_SH_CR1); | ||
208 | tmp = tmp & ~(SPI_SH_SSD | SPI_SH_SSDB); | ||
209 | spi_sh_write(ss, tmp, SPI_SH_CR1); | ||
210 | spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1); | ||
211 | |||
212 | ss->cr1 &= ~SPI_SH_TBE; | ||
213 | spi_sh_set_bit(ss, SPI_SH_TBE, SPI_SH_CR4); | ||
214 | ret = wait_event_interruptible_timeout(ss->wait, | ||
215 | ss->cr1 & SPI_SH_TBE, | ||
216 | SPI_SH_SEND_TIMEOUT); | ||
217 | if (ret == 0 && (ss->cr1 & SPI_SH_TBE)) { | ||
218 | printk(KERN_ERR "%s: timeout\n", __func__); | ||
219 | return -ETIMEDOUT; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | return retval; | ||
224 | } | ||
225 | |||
226 | static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg, | ||
227 | struct spi_transfer *t) | ||
228 | { | ||
229 | int i; | ||
230 | int remain = t->len; | ||
231 | int cur_len; | ||
232 | unsigned char *data; | ||
233 | unsigned long tmp; | ||
234 | long ret; | ||
235 | |||
236 | if (t->len > SPI_SH_MAX_BYTE) | ||
237 | spi_sh_write(ss, SPI_SH_MAX_BYTE, SPI_SH_CR3); | ||
238 | else | ||
239 | spi_sh_write(ss, t->len, SPI_SH_CR3); | ||
240 | |||
241 | tmp = spi_sh_read(ss, SPI_SH_CR1); | ||
242 | tmp = tmp & ~(SPI_SH_SSD | SPI_SH_SSDB); | ||
243 | spi_sh_write(ss, tmp, SPI_SH_CR1); | ||
244 | spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1); | ||
245 | |||
246 | spi_sh_wait_write_buffer_empty(ss); | ||
247 | |||
248 | data = (unsigned char *)t->rx_buf; | ||
249 | while (remain > 0) { | ||
250 | if (remain >= SPI_SH_FIFO_SIZE) { | ||
251 | ss->cr1 &= ~SPI_SH_RBF; | ||
252 | spi_sh_set_bit(ss, SPI_SH_RBF, SPI_SH_CR4); | ||
253 | ret = wait_event_interruptible_timeout(ss->wait, | ||
254 | ss->cr1 & SPI_SH_RBF, | ||
255 | SPI_SH_RECEIVE_TIMEOUT); | ||
256 | if (ret == 0 && | ||
257 | spi_sh_read(ss, SPI_SH_CR1) & SPI_SH_RBE) { | ||
258 | printk(KERN_ERR "%s: timeout\n", __func__); | ||
259 | return -ETIMEDOUT; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | cur_len = min(SPI_SH_FIFO_SIZE, remain); | ||
264 | for (i = 0; i < cur_len; i++) { | ||
265 | if (spi_sh_wait_receive_buffer(ss)) | ||
266 | break; | ||
267 | data[i] = (unsigned char)spi_sh_read(ss, SPI_SH_RBR); | ||
268 | } | ||
269 | |||
270 | remain -= cur_len; | ||
271 | data += cur_len; | ||
272 | } | ||
273 | |||
274 | /* deassert CS when SPI is receiving. */ | ||
275 | if (t->len > SPI_SH_MAX_BYTE) { | ||
276 | clear_fifo(ss); | ||
277 | spi_sh_write(ss, 1, SPI_SH_CR3); | ||
278 | } else { | ||
279 | spi_sh_write(ss, 0, SPI_SH_CR3); | ||
280 | } | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static void spi_sh_work(struct work_struct *work) | ||
286 | { | ||
287 | struct spi_sh_data *ss = container_of(work, struct spi_sh_data, ws); | ||
288 | struct spi_message *mesg; | ||
289 | struct spi_transfer *t; | ||
290 | unsigned long flags; | ||
291 | int ret; | ||
292 | |||
293 | pr_debug("%s: enter\n", __func__); | ||
294 | |||
295 | spin_lock_irqsave(&ss->lock, flags); | ||
296 | while (!list_empty(&ss->queue)) { | ||
297 | mesg = list_entry(ss->queue.next, struct spi_message, queue); | ||
298 | list_del_init(&mesg->queue); | ||
299 | |||
300 | spin_unlock_irqrestore(&ss->lock, flags); | ||
301 | list_for_each_entry(t, &mesg->transfers, transfer_list) { | ||
302 | pr_debug("tx_buf = %p, rx_buf = %p\n", | ||
303 | t->tx_buf, t->rx_buf); | ||
304 | pr_debug("len = %d, delay_usecs = %d\n", | ||
305 | t->len, t->delay_usecs); | ||
306 | |||
307 | if (t->tx_buf) { | ||
308 | ret = spi_sh_send(ss, mesg, t); | ||
309 | if (ret < 0) | ||
310 | goto error; | ||
311 | } | ||
312 | if (t->rx_buf) { | ||
313 | ret = spi_sh_receive(ss, mesg, t); | ||
314 | if (ret < 0) | ||
315 | goto error; | ||
316 | } | ||
317 | mesg->actual_length += t->len; | ||
318 | } | ||
319 | spin_lock_irqsave(&ss->lock, flags); | ||
320 | |||
321 | mesg->status = 0; | ||
322 | mesg->complete(mesg->context); | ||
323 | } | ||
324 | |||
325 | clear_fifo(ss); | ||
326 | spi_sh_set_bit(ss, SPI_SH_SSD, SPI_SH_CR1); | ||
327 | udelay(100); | ||
328 | |||
329 | spi_sh_clear_bit(ss, SPI_SH_SSA | SPI_SH_SSDB | SPI_SH_SSD, | ||
330 | SPI_SH_CR1); | ||
331 | |||
332 | clear_fifo(ss); | ||
333 | |||
334 | spin_unlock_irqrestore(&ss->lock, flags); | ||
335 | |||
336 | return; | ||
337 | |||
338 | error: | ||
339 | mesg->status = ret; | ||
340 | mesg->complete(mesg->context); | ||
341 | |||
342 | spi_sh_clear_bit(ss, SPI_SH_SSA | SPI_SH_SSDB | SPI_SH_SSD, | ||
343 | SPI_SH_CR1); | ||
344 | clear_fifo(ss); | ||
345 | |||
346 | } | ||
347 | |||
348 | static int spi_sh_setup(struct spi_device *spi) | ||
349 | { | ||
350 | struct spi_sh_data *ss = spi_master_get_devdata(spi->master); | ||
351 | |||
352 | if (!spi->bits_per_word) | ||
353 | spi->bits_per_word = 8; | ||
354 | |||
355 | pr_debug("%s: enter\n", __func__); | ||
356 | |||
357 | spi_sh_write(ss, 0xfe, SPI_SH_CR1); /* SPI sycle stop */ | ||
358 | spi_sh_write(ss, 0x00, SPI_SH_CR1); /* CR1 init */ | ||
359 | spi_sh_write(ss, 0x00, SPI_SH_CR3); /* CR3 init */ | ||
360 | |||
361 | clear_fifo(ss); | ||
362 | |||
363 | /* 1/8 clock */ | ||
364 | spi_sh_write(ss, spi_sh_read(ss, SPI_SH_CR2) | 0x07, SPI_SH_CR2); | ||
365 | udelay(10); | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static int spi_sh_transfer(struct spi_device *spi, struct spi_message *mesg) | ||
371 | { | ||
372 | struct spi_sh_data *ss = spi_master_get_devdata(spi->master); | ||
373 | unsigned long flags; | ||
374 | |||
375 | pr_debug("%s: enter\n", __func__); | ||
376 | pr_debug("\tmode = %02x\n", spi->mode); | ||
377 | |||
378 | spin_lock_irqsave(&ss->lock, flags); | ||
379 | |||
380 | mesg->actual_length = 0; | ||
381 | mesg->status = -EINPROGRESS; | ||
382 | |||
383 | spi_sh_clear_bit(ss, SPI_SH_SSA, SPI_SH_CR1); | ||
384 | |||
385 | list_add_tail(&mesg->queue, &ss->queue); | ||
386 | queue_work(ss->workqueue, &ss->ws); | ||
387 | |||
388 | spin_unlock_irqrestore(&ss->lock, flags); | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static void spi_sh_cleanup(struct spi_device *spi) | ||
394 | { | ||
395 | struct spi_sh_data *ss = spi_master_get_devdata(spi->master); | ||
396 | |||
397 | pr_debug("%s: enter\n", __func__); | ||
398 | |||
399 | spi_sh_clear_bit(ss, SPI_SH_SSA | SPI_SH_SSDB | SPI_SH_SSD, | ||
400 | SPI_SH_CR1); | ||
401 | } | ||
402 | |||
403 | static irqreturn_t spi_sh_irq(int irq, void *_ss) | ||
404 | { | ||
405 | struct spi_sh_data *ss = (struct spi_sh_data *)_ss; | ||
406 | unsigned long cr1; | ||
407 | |||
408 | cr1 = spi_sh_read(ss, SPI_SH_CR1); | ||
409 | if (cr1 & SPI_SH_TBE) | ||
410 | ss->cr1 |= SPI_SH_TBE; | ||
411 | if (cr1 & SPI_SH_TBF) | ||
412 | ss->cr1 |= SPI_SH_TBF; | ||
413 | if (cr1 & SPI_SH_RBE) | ||
414 | ss->cr1 |= SPI_SH_RBE; | ||
415 | if (cr1 & SPI_SH_RBF) | ||
416 | ss->cr1 |= SPI_SH_RBF; | ||
417 | |||
418 | if (ss->cr1) { | ||
419 | spi_sh_clear_bit(ss, ss->cr1, SPI_SH_CR4); | ||
420 | wake_up(&ss->wait); | ||
421 | } | ||
422 | |||
423 | return IRQ_HANDLED; | ||
424 | } | ||
425 | |||
426 | static int __devexit spi_sh_remove(struct platform_device *pdev) | ||
427 | { | ||
428 | struct spi_sh_data *ss = dev_get_drvdata(&pdev->dev); | ||
429 | |||
430 | destroy_workqueue(ss->workqueue); | ||
431 | free_irq(ss->irq, ss); | ||
432 | iounmap(ss->addr); | ||
433 | spi_master_put(ss->master); | ||
434 | |||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | static int __devinit spi_sh_probe(struct platform_device *pdev) | ||
439 | { | ||
440 | struct resource *res; | ||
441 | struct spi_master *master; | ||
442 | struct spi_sh_data *ss; | ||
443 | int ret, irq; | ||
444 | |||
445 | /* get base addr */ | ||
446 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
447 | if (unlikely(res == NULL)) { | ||
448 | dev_err(&pdev->dev, "invalid resource\n"); | ||
449 | return -EINVAL; | ||
450 | } | ||
451 | |||
452 | irq = platform_get_irq(pdev, 0); | ||
453 | if (irq < 0) { | ||
454 | dev_err(&pdev->dev, "platform_get_irq error\n"); | ||
455 | return -ENODEV; | ||
456 | } | ||
457 | |||
458 | master = spi_alloc_master(&pdev->dev, sizeof(struct spi_sh_data)); | ||
459 | if (master == NULL) { | ||
460 | dev_err(&pdev->dev, "spi_alloc_master error.\n"); | ||
461 | return -ENOMEM; | ||
462 | } | ||
463 | |||
464 | ss = spi_master_get_devdata(master); | ||
465 | dev_set_drvdata(&pdev->dev, ss); | ||
466 | |||
467 | ss->irq = irq; | ||
468 | ss->master = master; | ||
469 | ss->addr = ioremap(res->start, resource_size(res)); | ||
470 | if (ss->addr == NULL) { | ||
471 | dev_err(&pdev->dev, "ioremap error.\n"); | ||
472 | ret = -ENOMEM; | ||
473 | goto error1; | ||
474 | } | ||
475 | INIT_LIST_HEAD(&ss->queue); | ||
476 | spin_lock_init(&ss->lock); | ||
477 | INIT_WORK(&ss->ws, spi_sh_work); | ||
478 | init_waitqueue_head(&ss->wait); | ||
479 | ss->workqueue = create_singlethread_workqueue( | ||
480 | dev_name(master->dev.parent)); | ||
481 | if (ss->workqueue == NULL) { | ||
482 | dev_err(&pdev->dev, "create workqueue error\n"); | ||
483 | ret = -EBUSY; | ||
484 | goto error2; | ||
485 | } | ||
486 | |||
487 | ret = request_irq(irq, spi_sh_irq, IRQF_DISABLED, "spi_sh", ss); | ||
488 | if (ret < 0) { | ||
489 | dev_err(&pdev->dev, "request_irq error\n"); | ||
490 | goto error3; | ||
491 | } | ||
492 | |||
493 | master->num_chipselect = 2; | ||
494 | master->bus_num = pdev->id; | ||
495 | master->setup = spi_sh_setup; | ||
496 | master->transfer = spi_sh_transfer; | ||
497 | master->cleanup = spi_sh_cleanup; | ||
498 | |||
499 | ret = spi_register_master(master); | ||
500 | if (ret < 0) { | ||
501 | printk(KERN_ERR "spi_register_master error.\n"); | ||
502 | goto error4; | ||
503 | } | ||
504 | |||
505 | return 0; | ||
506 | |||
507 | error4: | ||
508 | free_irq(irq, ss); | ||
509 | error3: | ||
510 | destroy_workqueue(ss->workqueue); | ||
511 | error2: | ||
512 | iounmap(ss->addr); | ||
513 | error1: | ||
514 | spi_master_put(master); | ||
515 | |||
516 | return ret; | ||
517 | } | ||
518 | |||
519 | static struct platform_driver spi_sh_driver = { | ||
520 | .probe = spi_sh_probe, | ||
521 | .remove = __devexit_p(spi_sh_remove), | ||
522 | .driver = { | ||
523 | .name = "sh_spi", | ||
524 | .owner = THIS_MODULE, | ||
525 | }, | ||
526 | }; | ||
527 | |||
528 | static int __init spi_sh_init(void) | ||
529 | { | ||
530 | return platform_driver_register(&spi_sh_driver); | ||
531 | } | ||
532 | module_init(spi_sh_init); | ||
533 | |||
534 | static void __exit spi_sh_exit(void) | ||
535 | { | ||
536 | platform_driver_unregister(&spi_sh_driver); | ||
537 | } | ||
538 | module_exit(spi_sh_exit); | ||
539 | |||
540 | MODULE_DESCRIPTION("SH SPI bus driver"); | ||
541 | MODULE_LICENSE("GPL"); | ||
542 | MODULE_AUTHOR("Yoshihiro Shimoda"); | ||
543 | MODULE_ALIAS("platform:sh_spi"); | ||
diff --git a/drivers/spi/spi_sh_msiof.c b/drivers/spi/spi_sh_msiof.c index 56f60c8ea0ab..e00d94b22250 100644 --- a/drivers/spi/spi_sh_msiof.c +++ b/drivers/spi/spi_sh_msiof.c | |||
@@ -9,22 +9,22 @@ | |||
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/bitmap.h> |
13 | #include <linux/init.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/completion.h> | ||
14 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/err.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/init.h> | ||
15 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/io.h> | ||
21 | #include <linux/kernel.h> | ||
16 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
17 | #include <linux/completion.h> | ||
18 | #include <linux/pm_runtime.h> | 23 | #include <linux/pm_runtime.h> |
19 | #include <linux/gpio.h> | ||
20 | #include <linux/bitmap.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/err.h> | ||
24 | 24 | ||
25 | #include <linux/spi/sh_msiof.h> | ||
25 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
26 | #include <linux/spi/spi_bitbang.h> | 27 | #include <linux/spi/spi_bitbang.h> |
27 | #include <linux/spi/sh_msiof.h> | ||
28 | 28 | ||
29 | #include <asm/unaligned.h> | 29 | #include <asm/unaligned.h> |
30 | 30 | ||
@@ -67,7 +67,7 @@ struct sh_msiof_spi_priv { | |||
67 | #define STR_TEOF (1 << 23) | 67 | #define STR_TEOF (1 << 23) |
68 | #define STR_REOF (1 << 7) | 68 | #define STR_REOF (1 << 7) |
69 | 69 | ||
70 | static unsigned long sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs) | 70 | static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs) |
71 | { | 71 | { |
72 | switch (reg_offs) { | 72 | switch (reg_offs) { |
73 | case TSCR: | 73 | case TSCR: |
@@ -79,7 +79,7 @@ static unsigned long sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs) | |||
79 | } | 79 | } |
80 | 80 | ||
81 | static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs, | 81 | static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs, |
82 | unsigned long value) | 82 | u32 value) |
83 | { | 83 | { |
84 | switch (reg_offs) { | 84 | switch (reg_offs) { |
85 | case TSCR: | 85 | case TSCR: |
@@ -93,10 +93,10 @@ static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs, | |||
93 | } | 93 | } |
94 | 94 | ||
95 | static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p, | 95 | static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p, |
96 | unsigned long clr, unsigned long set) | 96 | u32 clr, u32 set) |
97 | { | 97 | { |
98 | unsigned long mask = clr | set; | 98 | u32 mask = clr | set; |
99 | unsigned long data; | 99 | u32 data; |
100 | int k; | 100 | int k; |
101 | 101 | ||
102 | data = sh_msiof_read(p, CTR); | 102 | data = sh_msiof_read(p, CTR); |
@@ -166,10 +166,10 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, | |||
166 | } | 166 | } |
167 | 167 | ||
168 | static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, | 168 | static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, |
169 | int cpol, int cpha, | 169 | u32 cpol, u32 cpha, |
170 | int tx_hi_z, int lsb_first) | 170 | u32 tx_hi_z, u32 lsb_first) |
171 | { | 171 | { |
172 | unsigned long tmp; | 172 | u32 tmp; |
173 | int edge; | 173 | int edge; |
174 | 174 | ||
175 | /* | 175 | /* |
@@ -187,7 +187,7 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, | |||
187 | tmp |= cpol << 30; /* TSCKIZ */ | 187 | tmp |= cpol << 30; /* TSCKIZ */ |
188 | tmp |= cpol << 28; /* RSCKIZ */ | 188 | tmp |= cpol << 28; /* RSCKIZ */ |
189 | 189 | ||
190 | edge = cpol ? cpha : !cpha; | 190 | edge = cpol ^ !cpha; |
191 | 191 | ||
192 | tmp |= edge << 27; /* TEDG */ | 192 | tmp |= edge << 27; /* TEDG */ |
193 | tmp |= edge << 26; /* REDG */ | 193 | tmp |= edge << 26; /* REDG */ |
@@ -197,11 +197,9 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, | |||
197 | 197 | ||
198 | static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p, | 198 | static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p, |
199 | const void *tx_buf, void *rx_buf, | 199 | const void *tx_buf, void *rx_buf, |
200 | int bits, int words) | 200 | u32 bits, u32 words) |
201 | { | 201 | { |
202 | unsigned long dr2; | 202 | u32 dr2 = ((bits - 1) << 24) | ((words - 1) << 16); |
203 | |||
204 | dr2 = ((bits - 1) << 24) | ((words - 1) << 16); | ||
205 | 203 | ||
206 | if (tx_buf) | 204 | if (tx_buf) |
207 | sh_msiof_write(p, TMDR2, dr2); | 205 | sh_msiof_write(p, TMDR2, dr2); |
@@ -222,7 +220,7 @@ static void sh_msiof_reset_str(struct sh_msiof_spi_priv *p) | |||
222 | static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p, | 220 | static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p, |
223 | const void *tx_buf, int words, int fs) | 221 | const void *tx_buf, int words, int fs) |
224 | { | 222 | { |
225 | const unsigned char *buf_8 = tx_buf; | 223 | const u8 *buf_8 = tx_buf; |
226 | int k; | 224 | int k; |
227 | 225 | ||
228 | for (k = 0; k < words; k++) | 226 | for (k = 0; k < words; k++) |
@@ -232,7 +230,7 @@ static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p, | |||
232 | static void sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv *p, | 230 | static void sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv *p, |
233 | const void *tx_buf, int words, int fs) | 231 | const void *tx_buf, int words, int fs) |
234 | { | 232 | { |
235 | const unsigned short *buf_16 = tx_buf; | 233 | const u16 *buf_16 = tx_buf; |
236 | int k; | 234 | int k; |
237 | 235 | ||
238 | for (k = 0; k < words; k++) | 236 | for (k = 0; k < words; k++) |
@@ -242,7 +240,7 @@ static void sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv *p, | |||
242 | static void sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv *p, | 240 | static void sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv *p, |
243 | const void *tx_buf, int words, int fs) | 241 | const void *tx_buf, int words, int fs) |
244 | { | 242 | { |
245 | const unsigned short *buf_16 = tx_buf; | 243 | const u16 *buf_16 = tx_buf; |
246 | int k; | 244 | int k; |
247 | 245 | ||
248 | for (k = 0; k < words; k++) | 246 | for (k = 0; k < words; k++) |
@@ -252,7 +250,7 @@ static void sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv *p, | |||
252 | static void sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv *p, | 250 | static void sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv *p, |
253 | const void *tx_buf, int words, int fs) | 251 | const void *tx_buf, int words, int fs) |
254 | { | 252 | { |
255 | const unsigned int *buf_32 = tx_buf; | 253 | const u32 *buf_32 = tx_buf; |
256 | int k; | 254 | int k; |
257 | 255 | ||
258 | for (k = 0; k < words; k++) | 256 | for (k = 0; k < words; k++) |
@@ -262,17 +260,37 @@ static void sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv *p, | |||
262 | static void sh_msiof_spi_write_fifo_32u(struct sh_msiof_spi_priv *p, | 260 | static void sh_msiof_spi_write_fifo_32u(struct sh_msiof_spi_priv *p, |
263 | const void *tx_buf, int words, int fs) | 261 | const void *tx_buf, int words, int fs) |
264 | { | 262 | { |
265 | const unsigned int *buf_32 = tx_buf; | 263 | const u32 *buf_32 = tx_buf; |
266 | int k; | 264 | int k; |
267 | 265 | ||
268 | for (k = 0; k < words; k++) | 266 | for (k = 0; k < words; k++) |
269 | sh_msiof_write(p, TFDR, get_unaligned(&buf_32[k]) << fs); | 267 | sh_msiof_write(p, TFDR, get_unaligned(&buf_32[k]) << fs); |
270 | } | 268 | } |
271 | 269 | ||
270 | static void sh_msiof_spi_write_fifo_s32(struct sh_msiof_spi_priv *p, | ||
271 | const void *tx_buf, int words, int fs) | ||
272 | { | ||
273 | const u32 *buf_32 = tx_buf; | ||
274 | int k; | ||
275 | |||
276 | for (k = 0; k < words; k++) | ||
277 | sh_msiof_write(p, TFDR, swab32(buf_32[k] << fs)); | ||
278 | } | ||
279 | |||
280 | static void sh_msiof_spi_write_fifo_s32u(struct sh_msiof_spi_priv *p, | ||
281 | const void *tx_buf, int words, int fs) | ||
282 | { | ||
283 | const u32 *buf_32 = tx_buf; | ||
284 | int k; | ||
285 | |||
286 | for (k = 0; k < words; k++) | ||
287 | sh_msiof_write(p, TFDR, swab32(get_unaligned(&buf_32[k]) << fs)); | ||
288 | } | ||
289 | |||
272 | static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p, | 290 | static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p, |
273 | void *rx_buf, int words, int fs) | 291 | void *rx_buf, int words, int fs) |
274 | { | 292 | { |
275 | unsigned char *buf_8 = rx_buf; | 293 | u8 *buf_8 = rx_buf; |
276 | int k; | 294 | int k; |
277 | 295 | ||
278 | for (k = 0; k < words; k++) | 296 | for (k = 0; k < words; k++) |
@@ -282,7 +300,7 @@ static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p, | |||
282 | static void sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv *p, | 300 | static void sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv *p, |
283 | void *rx_buf, int words, int fs) | 301 | void *rx_buf, int words, int fs) |
284 | { | 302 | { |
285 | unsigned short *buf_16 = rx_buf; | 303 | u16 *buf_16 = rx_buf; |
286 | int k; | 304 | int k; |
287 | 305 | ||
288 | for (k = 0; k < words; k++) | 306 | for (k = 0; k < words; k++) |
@@ -292,7 +310,7 @@ static void sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv *p, | |||
292 | static void sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv *p, | 310 | static void sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv *p, |
293 | void *rx_buf, int words, int fs) | 311 | void *rx_buf, int words, int fs) |
294 | { | 312 | { |
295 | unsigned short *buf_16 = rx_buf; | 313 | u16 *buf_16 = rx_buf; |
296 | int k; | 314 | int k; |
297 | 315 | ||
298 | for (k = 0; k < words; k++) | 316 | for (k = 0; k < words; k++) |
@@ -302,7 +320,7 @@ static void sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv *p, | |||
302 | static void sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv *p, | 320 | static void sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv *p, |
303 | void *rx_buf, int words, int fs) | 321 | void *rx_buf, int words, int fs) |
304 | { | 322 | { |
305 | unsigned int *buf_32 = rx_buf; | 323 | u32 *buf_32 = rx_buf; |
306 | int k; | 324 | int k; |
307 | 325 | ||
308 | for (k = 0; k < words; k++) | 326 | for (k = 0; k < words; k++) |
@@ -312,19 +330,40 @@ static void sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv *p, | |||
312 | static void sh_msiof_spi_read_fifo_32u(struct sh_msiof_spi_priv *p, | 330 | static void sh_msiof_spi_read_fifo_32u(struct sh_msiof_spi_priv *p, |
313 | void *rx_buf, int words, int fs) | 331 | void *rx_buf, int words, int fs) |
314 | { | 332 | { |
315 | unsigned int *buf_32 = rx_buf; | 333 | u32 *buf_32 = rx_buf; |
316 | int k; | 334 | int k; |
317 | 335 | ||
318 | for (k = 0; k < words; k++) | 336 | for (k = 0; k < words; k++) |
319 | put_unaligned(sh_msiof_read(p, RFDR) >> fs, &buf_32[k]); | 337 | put_unaligned(sh_msiof_read(p, RFDR) >> fs, &buf_32[k]); |
320 | } | 338 | } |
321 | 339 | ||
340 | static void sh_msiof_spi_read_fifo_s32(struct sh_msiof_spi_priv *p, | ||
341 | void *rx_buf, int words, int fs) | ||
342 | { | ||
343 | u32 *buf_32 = rx_buf; | ||
344 | int k; | ||
345 | |||
346 | for (k = 0; k < words; k++) | ||
347 | buf_32[k] = swab32(sh_msiof_read(p, RFDR) >> fs); | ||
348 | } | ||
349 | |||
350 | static void sh_msiof_spi_read_fifo_s32u(struct sh_msiof_spi_priv *p, | ||
351 | void *rx_buf, int words, int fs) | ||
352 | { | ||
353 | u32 *buf_32 = rx_buf; | ||
354 | int k; | ||
355 | |||
356 | for (k = 0; k < words; k++) | ||
357 | put_unaligned(swab32(sh_msiof_read(p, RFDR) >> fs), &buf_32[k]); | ||
358 | } | ||
359 | |||
322 | static int sh_msiof_spi_bits(struct spi_device *spi, struct spi_transfer *t) | 360 | static int sh_msiof_spi_bits(struct spi_device *spi, struct spi_transfer *t) |
323 | { | 361 | { |
324 | int bits; | 362 | int bits; |
325 | 363 | ||
326 | bits = t ? t->bits_per_word : 0; | 364 | bits = t ? t->bits_per_word : 0; |
327 | bits = bits ? bits : spi->bits_per_word; | 365 | if (!bits) |
366 | bits = spi->bits_per_word; | ||
328 | return bits; | 367 | return bits; |
329 | } | 368 | } |
330 | 369 | ||
@@ -334,7 +373,8 @@ static unsigned long sh_msiof_spi_hz(struct spi_device *spi, | |||
334 | unsigned long hz; | 373 | unsigned long hz; |
335 | 374 | ||
336 | hz = t ? t->speed_hz : 0; | 375 | hz = t ? t->speed_hz : 0; |
337 | hz = hz ? hz : spi->max_speed_hz; | 376 | if (!hz) |
377 | hz = spi->max_speed_hz; | ||
338 | return hz; | 378 | return hz; |
339 | } | 379 | } |
340 | 380 | ||
@@ -468,9 +508,17 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
468 | int bytes_done; | 508 | int bytes_done; |
469 | int words; | 509 | int words; |
470 | int n; | 510 | int n; |
511 | bool swab; | ||
471 | 512 | ||
472 | bits = sh_msiof_spi_bits(spi, t); | 513 | bits = sh_msiof_spi_bits(spi, t); |
473 | 514 | ||
515 | if (bits <= 8 && t->len > 15 && !(t->len & 3)) { | ||
516 | bits = 32; | ||
517 | swab = true; | ||
518 | } else { | ||
519 | swab = false; | ||
520 | } | ||
521 | |||
474 | /* setup bytes per word and fifo read/write functions */ | 522 | /* setup bytes per word and fifo read/write functions */ |
475 | if (bits <= 8) { | 523 | if (bits <= 8) { |
476 | bytes_per_word = 1; | 524 | bytes_per_word = 1; |
@@ -487,6 +535,17 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
487 | rx_fifo = sh_msiof_spi_read_fifo_16u; | 535 | rx_fifo = sh_msiof_spi_read_fifo_16u; |
488 | else | 536 | else |
489 | rx_fifo = sh_msiof_spi_read_fifo_16; | 537 | rx_fifo = sh_msiof_spi_read_fifo_16; |
538 | } else if (swab) { | ||
539 | bytes_per_word = 4; | ||
540 | if ((unsigned long)t->tx_buf & 0x03) | ||
541 | tx_fifo = sh_msiof_spi_write_fifo_s32u; | ||
542 | else | ||
543 | tx_fifo = sh_msiof_spi_write_fifo_s32; | ||
544 | |||
545 | if ((unsigned long)t->rx_buf & 0x03) | ||
546 | rx_fifo = sh_msiof_spi_read_fifo_s32u; | ||
547 | else | ||
548 | rx_fifo = sh_msiof_spi_read_fifo_s32; | ||
490 | } else { | 549 | } else { |
491 | bytes_per_word = 4; | 550 | bytes_per_word = 4; |
492 | if ((unsigned long)t->tx_buf & 0x03) | 551 | if ((unsigned long)t->tx_buf & 0x03) |
@@ -509,9 +568,11 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
509 | bytes_done = 0; | 568 | bytes_done = 0; |
510 | 569 | ||
511 | while (bytes_done < t->len) { | 570 | while (bytes_done < t->len) { |
571 | void *rx_buf = t->rx_buf ? t->rx_buf + bytes_done : NULL; | ||
572 | const void *tx_buf = t->tx_buf ? t->tx_buf + bytes_done : NULL; | ||
512 | n = sh_msiof_spi_txrx_once(p, tx_fifo, rx_fifo, | 573 | n = sh_msiof_spi_txrx_once(p, tx_fifo, rx_fifo, |
513 | t->tx_buf + bytes_done, | 574 | tx_buf, |
514 | t->rx_buf + bytes_done, | 575 | rx_buf, |
515 | words, bits); | 576 | words, bits); |
516 | if (n < 0) | 577 | if (n < 0) |
517 | break; | 578 | break; |
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 603428213d21..d9fd86211365 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
31 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/compat.h> | ||
33 | 34 | ||
34 | #include <linux/spi/spi.h> | 35 | #include <linux/spi/spi.h> |
35 | #include <linux/spi/spidev.h> | 36 | #include <linux/spi/spidev.h> |
@@ -471,6 +472,16 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
471 | return retval; | 472 | return retval; |
472 | } | 473 | } |
473 | 474 | ||
475 | #ifdef CONFIG_COMPAT | ||
476 | static long | ||
477 | spidev_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
478 | { | ||
479 | return spidev_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); | ||
480 | } | ||
481 | #else | ||
482 | #define spidev_compat_ioctl NULL | ||
483 | #endif /* CONFIG_COMPAT */ | ||
484 | |||
474 | static int spidev_open(struct inode *inode, struct file *filp) | 485 | static int spidev_open(struct inode *inode, struct file *filp) |
475 | { | 486 | { |
476 | struct spidev_data *spidev; | 487 | struct spidev_data *spidev; |
@@ -543,6 +554,7 @@ static const struct file_operations spidev_fops = { | |||
543 | .write = spidev_write, | 554 | .write = spidev_write, |
544 | .read = spidev_read, | 555 | .read = spidev_read, |
545 | .unlocked_ioctl = spidev_ioctl, | 556 | .unlocked_ioctl = spidev_ioctl, |
557 | .compat_ioctl = spidev_compat_ioctl, | ||
546 | .open = spidev_open, | 558 | .open = spidev_open, |
547 | .release = spidev_release, | 559 | .release = spidev_release, |
548 | .llseek = no_llseek, | 560 | .llseek = no_llseek, |
diff --git a/drivers/spi/ti-ssp-spi.c b/drivers/spi/ti-ssp-spi.c new file mode 100644 index 000000000000..ee22795c7973 --- /dev/null +++ b/drivers/spi/ti-ssp-spi.c | |||
@@ -0,0 +1,402 @@ | |||
1 | /* | ||
2 | * Sequencer Serial Port (SSP) based SPI master driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments 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 as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/completion.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/spi/spi.h> | ||
27 | #include <linux/mfd/ti_ssp.h> | ||
28 | |||
29 | #define MODE_BITS (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH) | ||
30 | |||
31 | struct ti_ssp_spi { | ||
32 | struct spi_master *master; | ||
33 | struct device *dev; | ||
34 | spinlock_t lock; | ||
35 | struct list_head msg_queue; | ||
36 | struct completion complete; | ||
37 | bool shutdown; | ||
38 | struct workqueue_struct *workqueue; | ||
39 | struct work_struct work; | ||
40 | u8 mode, bpw; | ||
41 | int cs_active; | ||
42 | u32 pc_en, pc_dis, pc_wr, pc_rd; | ||
43 | void (*select)(int cs); | ||
44 | }; | ||
45 | |||
46 | static u32 ti_ssp_spi_rx(struct ti_ssp_spi *hw) | ||
47 | { | ||
48 | u32 ret; | ||
49 | |||
50 | ti_ssp_run(hw->dev, hw->pc_rd, 0, &ret); | ||
51 | return ret; | ||
52 | } | ||
53 | |||
54 | static void ti_ssp_spi_tx(struct ti_ssp_spi *hw, u32 data) | ||
55 | { | ||
56 | ti_ssp_run(hw->dev, hw->pc_wr, data << (32 - hw->bpw), NULL); | ||
57 | } | ||
58 | |||
59 | static int ti_ssp_spi_txrx(struct ti_ssp_spi *hw, struct spi_message *msg, | ||
60 | struct spi_transfer *t) | ||
61 | { | ||
62 | int count; | ||
63 | |||
64 | if (hw->bpw <= 8) { | ||
65 | u8 *rx = t->rx_buf; | ||
66 | const u8 *tx = t->tx_buf; | ||
67 | |||
68 | for (count = 0; count < t->len; count += 1) { | ||
69 | if (t->tx_buf) | ||
70 | ti_ssp_spi_tx(hw, *tx++); | ||
71 | if (t->rx_buf) | ||
72 | *rx++ = ti_ssp_spi_rx(hw); | ||
73 | } | ||
74 | } else if (hw->bpw <= 16) { | ||
75 | u16 *rx = t->rx_buf; | ||
76 | const u16 *tx = t->tx_buf; | ||
77 | |||
78 | for (count = 0; count < t->len; count += 2) { | ||
79 | if (t->tx_buf) | ||
80 | ti_ssp_spi_tx(hw, *tx++); | ||
81 | if (t->rx_buf) | ||
82 | *rx++ = ti_ssp_spi_rx(hw); | ||
83 | } | ||
84 | } else { | ||
85 | u32 *rx = t->rx_buf; | ||
86 | const u32 *tx = t->tx_buf; | ||
87 | |||
88 | for (count = 0; count < t->len; count += 4) { | ||
89 | if (t->tx_buf) | ||
90 | ti_ssp_spi_tx(hw, *tx++); | ||
91 | if (t->rx_buf) | ||
92 | *rx++ = ti_ssp_spi_rx(hw); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | msg->actual_length += count; /* bytes transferred */ | ||
97 | |||
98 | dev_dbg(&msg->spi->dev, "xfer %s%s, %d bytes, %d bpw, count %d%s\n", | ||
99 | t->tx_buf ? "tx" : "", t->rx_buf ? "rx" : "", t->len, | ||
100 | hw->bpw, count, (count < t->len) ? " (under)" : ""); | ||
101 | |||
102 | return (count < t->len) ? -EIO : 0; /* left over data */ | ||
103 | } | ||
104 | |||
105 | static void ti_ssp_spi_chip_select(struct ti_ssp_spi *hw, int cs_active) | ||
106 | { | ||
107 | cs_active = !!cs_active; | ||
108 | if (cs_active == hw->cs_active) | ||
109 | return; | ||
110 | ti_ssp_run(hw->dev, cs_active ? hw->pc_en : hw->pc_dis, 0, NULL); | ||
111 | hw->cs_active = cs_active; | ||
112 | } | ||
113 | |||
114 | #define __SHIFT_OUT(bits) (SSP_OPCODE_SHIFT | SSP_OUT_MODE | \ | ||
115 | cs_en | clk | SSP_COUNT((bits) * 2 - 1)) | ||
116 | #define __SHIFT_IN(bits) (SSP_OPCODE_SHIFT | SSP_IN_MODE | \ | ||
117 | cs_en | clk | SSP_COUNT((bits) * 2 - 1)) | ||
118 | |||
119 | static int ti_ssp_spi_setup_transfer(struct ti_ssp_spi *hw, u8 bpw, u8 mode) | ||
120 | { | ||
121 | int error, idx = 0; | ||
122 | u32 seqram[16]; | ||
123 | u32 cs_en, cs_dis, clk; | ||
124 | u32 topbits, botbits; | ||
125 | |||
126 | mode &= MODE_BITS; | ||
127 | if (mode == hw->mode && bpw == hw->bpw) | ||
128 | return 0; | ||
129 | |||
130 | cs_en = (mode & SPI_CS_HIGH) ? SSP_CS_HIGH : SSP_CS_LOW; | ||
131 | cs_dis = (mode & SPI_CS_HIGH) ? SSP_CS_LOW : SSP_CS_HIGH; | ||
132 | clk = (mode & SPI_CPOL) ? SSP_CLK_HIGH : SSP_CLK_LOW; | ||
133 | |||
134 | /* Construct instructions */ | ||
135 | |||
136 | /* Disable Chip Select */ | ||
137 | hw->pc_dis = idx; | ||
138 | seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_dis | clk; | ||
139 | seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_dis | clk; | ||
140 | |||
141 | /* Enable Chip Select */ | ||
142 | hw->pc_en = idx; | ||
143 | seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_en | clk; | ||
144 | seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; | ||
145 | |||
146 | /* Reads and writes need to be split for bpw > 16 */ | ||
147 | topbits = (bpw > 16) ? 16 : bpw; | ||
148 | botbits = bpw - topbits; | ||
149 | |||
150 | /* Write */ | ||
151 | hw->pc_wr = idx; | ||
152 | seqram[idx++] = __SHIFT_OUT(topbits) | SSP_ADDR_REG; | ||
153 | if (botbits) | ||
154 | seqram[idx++] = __SHIFT_OUT(botbits) | SSP_DATA_REG; | ||
155 | seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; | ||
156 | |||
157 | /* Read */ | ||
158 | hw->pc_rd = idx; | ||
159 | if (botbits) | ||
160 | seqram[idx++] = __SHIFT_IN(botbits) | SSP_ADDR_REG; | ||
161 | seqram[idx++] = __SHIFT_IN(topbits) | SSP_DATA_REG; | ||
162 | seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; | ||
163 | |||
164 | error = ti_ssp_load(hw->dev, 0, seqram, idx); | ||
165 | if (error < 0) | ||
166 | return error; | ||
167 | |||
168 | error = ti_ssp_set_mode(hw->dev, ((mode & SPI_CPHA) ? | ||
169 | 0 : SSP_EARLY_DIN)); | ||
170 | if (error < 0) | ||
171 | return error; | ||
172 | |||
173 | hw->bpw = bpw; | ||
174 | hw->mode = mode; | ||
175 | |||
176 | return error; | ||
177 | } | ||
178 | |||
179 | static void ti_ssp_spi_work(struct work_struct *work) | ||
180 | { | ||
181 | struct ti_ssp_spi *hw = container_of(work, struct ti_ssp_spi, work); | ||
182 | |||
183 | spin_lock(&hw->lock); | ||
184 | |||
185 | while (!list_empty(&hw->msg_queue)) { | ||
186 | struct spi_message *m; | ||
187 | struct spi_device *spi; | ||
188 | struct spi_transfer *t = NULL; | ||
189 | int status = 0; | ||
190 | |||
191 | m = container_of(hw->msg_queue.next, struct spi_message, | ||
192 | queue); | ||
193 | |||
194 | list_del_init(&m->queue); | ||
195 | |||
196 | spin_unlock(&hw->lock); | ||
197 | |||
198 | spi = m->spi; | ||
199 | |||
200 | if (hw->select) | ||
201 | hw->select(spi->chip_select); | ||
202 | |||
203 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
204 | int bpw = spi->bits_per_word; | ||
205 | int xfer_status; | ||
206 | |||
207 | if (t->bits_per_word) | ||
208 | bpw = t->bits_per_word; | ||
209 | |||
210 | if (ti_ssp_spi_setup_transfer(hw, bpw, spi->mode) < 0) | ||
211 | break; | ||
212 | |||
213 | ti_ssp_spi_chip_select(hw, 1); | ||
214 | |||
215 | xfer_status = ti_ssp_spi_txrx(hw, m, t); | ||
216 | if (xfer_status < 0) | ||
217 | status = xfer_status; | ||
218 | |||
219 | if (t->delay_usecs) | ||
220 | udelay(t->delay_usecs); | ||
221 | |||
222 | if (t->cs_change) | ||
223 | ti_ssp_spi_chip_select(hw, 0); | ||
224 | } | ||
225 | |||
226 | ti_ssp_spi_chip_select(hw, 0); | ||
227 | m->status = status; | ||
228 | m->complete(m->context); | ||
229 | |||
230 | spin_lock(&hw->lock); | ||
231 | } | ||
232 | |||
233 | if (hw->shutdown) | ||
234 | complete(&hw->complete); | ||
235 | |||
236 | spin_unlock(&hw->lock); | ||
237 | } | ||
238 | |||
239 | static int ti_ssp_spi_setup(struct spi_device *spi) | ||
240 | { | ||
241 | if (spi->bits_per_word > 32) | ||
242 | return -EINVAL; | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m) | ||
248 | { | ||
249 | struct ti_ssp_spi *hw; | ||
250 | struct spi_transfer *t; | ||
251 | int error = 0; | ||
252 | |||
253 | m->actual_length = 0; | ||
254 | m->status = -EINPROGRESS; | ||
255 | |||
256 | hw = spi_master_get_devdata(spi->master); | ||
257 | |||
258 | if (list_empty(&m->transfers) || !m->complete) | ||
259 | return -EINVAL; | ||
260 | |||
261 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
262 | if (t->len && !(t->rx_buf || t->tx_buf)) { | ||
263 | dev_err(&spi->dev, "invalid xfer, no buffer\n"); | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
267 | if (t->len && t->rx_buf && t->tx_buf) { | ||
268 | dev_err(&spi->dev, "invalid xfer, full duplex\n"); | ||
269 | return -EINVAL; | ||
270 | } | ||
271 | |||
272 | if (t->bits_per_word > 32) { | ||
273 | dev_err(&spi->dev, "invalid xfer width %d\n", | ||
274 | t->bits_per_word); | ||
275 | return -EINVAL; | ||
276 | } | ||
277 | } | ||
278 | |||
279 | spin_lock(&hw->lock); | ||
280 | if (hw->shutdown) { | ||
281 | error = -ESHUTDOWN; | ||
282 | goto error_unlock; | ||
283 | } | ||
284 | list_add_tail(&m->queue, &hw->msg_queue); | ||
285 | queue_work(hw->workqueue, &hw->work); | ||
286 | error_unlock: | ||
287 | spin_unlock(&hw->lock); | ||
288 | return error; | ||
289 | } | ||
290 | |||
291 | static int __devinit ti_ssp_spi_probe(struct platform_device *pdev) | ||
292 | { | ||
293 | const struct ti_ssp_spi_data *pdata; | ||
294 | struct ti_ssp_spi *hw; | ||
295 | struct spi_master *master; | ||
296 | struct device *dev = &pdev->dev; | ||
297 | int error = 0; | ||
298 | |||
299 | pdata = dev->platform_data; | ||
300 | if (!pdata) { | ||
301 | dev_err(dev, "platform data not found\n"); | ||
302 | return -EINVAL; | ||
303 | } | ||
304 | |||
305 | master = spi_alloc_master(dev, sizeof(struct ti_ssp_spi)); | ||
306 | if (!master) { | ||
307 | dev_err(dev, "cannot allocate SPI master\n"); | ||
308 | return -ENOMEM; | ||
309 | } | ||
310 | |||
311 | hw = spi_master_get_devdata(master); | ||
312 | platform_set_drvdata(pdev, hw); | ||
313 | |||
314 | hw->master = master; | ||
315 | hw->dev = dev; | ||
316 | hw->select = pdata->select; | ||
317 | |||
318 | spin_lock_init(&hw->lock); | ||
319 | init_completion(&hw->complete); | ||
320 | INIT_LIST_HEAD(&hw->msg_queue); | ||
321 | INIT_WORK(&hw->work, ti_ssp_spi_work); | ||
322 | |||
323 | hw->workqueue = create_singlethread_workqueue(dev_name(dev)); | ||
324 | if (!hw->workqueue) { | ||
325 | error = -ENOMEM; | ||
326 | dev_err(dev, "work queue creation failed\n"); | ||
327 | goto error_wq; | ||
328 | } | ||
329 | |||
330 | error = ti_ssp_set_iosel(hw->dev, pdata->iosel); | ||
331 | if (error < 0) { | ||
332 | dev_err(dev, "io setup failed\n"); | ||
333 | goto error_iosel; | ||
334 | } | ||
335 | |||
336 | master->bus_num = pdev->id; | ||
337 | master->num_chipselect = pdata->num_cs; | ||
338 | master->mode_bits = MODE_BITS; | ||
339 | master->flags = SPI_MASTER_HALF_DUPLEX; | ||
340 | master->setup = ti_ssp_spi_setup; | ||
341 | master->transfer = ti_ssp_spi_transfer; | ||
342 | |||
343 | error = spi_register_master(master); | ||
344 | if (error) { | ||
345 | dev_err(dev, "master registration failed\n"); | ||
346 | goto error_reg; | ||
347 | } | ||
348 | |||
349 | return 0; | ||
350 | |||
351 | error_reg: | ||
352 | error_iosel: | ||
353 | destroy_workqueue(hw->workqueue); | ||
354 | error_wq: | ||
355 | spi_master_put(master); | ||
356 | return error; | ||
357 | } | ||
358 | |||
359 | static int __devexit ti_ssp_spi_remove(struct platform_device *pdev) | ||
360 | { | ||
361 | struct ti_ssp_spi *hw = platform_get_drvdata(pdev); | ||
362 | int error; | ||
363 | |||
364 | hw->shutdown = 1; | ||
365 | while (!list_empty(&hw->msg_queue)) { | ||
366 | error = wait_for_completion_interruptible(&hw->complete); | ||
367 | if (error < 0) { | ||
368 | hw->shutdown = 0; | ||
369 | return error; | ||
370 | } | ||
371 | } | ||
372 | destroy_workqueue(hw->workqueue); | ||
373 | spi_unregister_master(hw->master); | ||
374 | |||
375 | return 0; | ||
376 | } | ||
377 | |||
378 | static struct platform_driver ti_ssp_spi_driver = { | ||
379 | .probe = ti_ssp_spi_probe, | ||
380 | .remove = __devexit_p(ti_ssp_spi_remove), | ||
381 | .driver = { | ||
382 | .name = "ti-ssp-spi", | ||
383 | .owner = THIS_MODULE, | ||
384 | }, | ||
385 | }; | ||
386 | |||
387 | static int __init ti_ssp_spi_init(void) | ||
388 | { | ||
389 | return platform_driver_register(&ti_ssp_spi_driver); | ||
390 | } | ||
391 | module_init(ti_ssp_spi_init); | ||
392 | |||
393 | static void __exit ti_ssp_spi_exit(void) | ||
394 | { | ||
395 | platform_driver_unregister(&ti_ssp_spi_driver); | ||
396 | } | ||
397 | module_exit(ti_ssp_spi_exit); | ||
398 | |||
399 | MODULE_DESCRIPTION("SSP SPI Master"); | ||
400 | MODULE_AUTHOR("Cyril Chemparathy"); | ||
401 | MODULE_LICENSE("GPL"); | ||
402 | MODULE_ALIAS("platform:ti-ssp-spi"); | ||
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 7adaef62a991..c69c6f2c2c5c 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/mfd/core.h> | ||
21 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
22 | #include <linux/spi/spi_bitbang.h> | 23 | #include <linux/spi/spi_bitbang.h> |
23 | #include <linux/spi/xilinx_spi.h> | 24 | #include <linux/spi/xilinx_spi.h> |
@@ -351,14 +352,12 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id) | |||
351 | return IRQ_HANDLED; | 352 | return IRQ_HANDLED; |
352 | } | 353 | } |
353 | 354 | ||
354 | #ifdef CONFIG_OF | ||
355 | static const struct of_device_id xilinx_spi_of_match[] = { | 355 | static const struct of_device_id xilinx_spi_of_match[] = { |
356 | { .compatible = "xlnx,xps-spi-2.00.a", }, | 356 | { .compatible = "xlnx,xps-spi-2.00.a", }, |
357 | { .compatible = "xlnx,xps-spi-2.00.b", }, | 357 | { .compatible = "xlnx,xps-spi-2.00.b", }, |
358 | {} | 358 | {} |
359 | }; | 359 | }; |
360 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); | 360 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); |
361 | #endif | ||
362 | 361 | ||
363 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, | 362 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, |
364 | u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word) | 363 | u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word) |
@@ -394,9 +393,7 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, | |||
394 | 393 | ||
395 | master->bus_num = bus_num; | 394 | master->bus_num = bus_num; |
396 | master->num_chipselect = num_cs; | 395 | master->num_chipselect = num_cs; |
397 | #ifdef CONFIG_OF | ||
398 | master->dev.of_node = dev->of_node; | 396 | master->dev.of_node = dev->of_node; |
399 | #endif | ||
400 | 397 | ||
401 | xspi->mem = *mem; | 398 | xspi->mem = *mem; |
402 | xspi->irq = irq; | 399 | xspi->irq = irq; |
@@ -474,7 +471,7 @@ static int __devinit xilinx_spi_probe(struct platform_device *dev) | |||
474 | struct spi_master *master; | 471 | struct spi_master *master; |
475 | u8 i; | 472 | u8 i; |
476 | 473 | ||
477 | pdata = dev->dev.platform_data; | 474 | pdata = mfd_get_data(dev); |
478 | if (pdata) { | 475 | if (pdata) { |
479 | num_cs = pdata->num_chipselect; | 476 | num_cs = pdata->num_chipselect; |
480 | little_endian = pdata->little_endian; | 477 | little_endian = pdata->little_endian; |
@@ -539,9 +536,7 @@ static struct platform_driver xilinx_spi_driver = { | |||
539 | .driver = { | 536 | .driver = { |
540 | .name = XILINX_SPI_NAME, | 537 | .name = XILINX_SPI_NAME, |
541 | .owner = THIS_MODULE, | 538 | .owner = THIS_MODULE, |
542 | #ifdef CONFIG_OF | ||
543 | .of_match_table = xilinx_spi_of_match, | 539 | .of_match_table = xilinx_spi_of_match, |
544 | #endif | ||
545 | }, | 540 | }, |
546 | }; | 541 | }; |
547 | 542 | ||