aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/amba-pl022.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:56:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:56:02 -0400
commitb061c59c27e0385e53c961d9fbd18c1c078d9823 (patch)
tree56240ef8e98e9e4712ee58aa8e6e3d51f6ab001f /drivers/spi/amba-pl022.c
parent99f4065bac7b8c3f829334b4218a5c2e68cbe440 (diff)
parent568a60eda2e90a11bb3d7f8ef3f6800e9b60d4e5 (diff)
Merge branch 'spi/next' of git://git.secretlab.ca/git/linux-2.6
* 'spi/next' of git://git.secretlab.ca/git/linux-2.6: (34 commits) spi/dw_spi: move dw_spi.h into drivers/spi spi/dw_spi: Fix missing header gpio/langwell: Clear edge bit before handling gpio/langwell: Simplify demux loop gpio/langwell: Convert irq name space gpio/langwell: Fix broken irq_eoi change. gpio; Make Intel chipset gpio drivers depend on x86 gpio/cs5535-gpio: Fix section mismatch spi/rtc-{ds1390,ds3234,m41t94}: Use spi_get_drvdata() for SPI devices spi/davinci: Support DMA transfers larger than 65535 words spi/davinci: Use correct length parameter to dma_map_single calls gpio: Use __devexit at necessary places gpio: add MODULE_DEVICE_TABLE to pch_gpio and ml_ioh_gpio gpio/mcp23s08: support mcp23s17 variant of_mmc_spi: add card detect irq support spi/omap_mcspi: catch xfers of non-multiple SPI word size spi/omap_mcspi: Off-by-one error in finding the right divisor gpio/pca953x: Fix wrong pointer type spi/pl022: rid dangling labels spi: add support for SuperH SPI ...
Diffstat (limited to 'drivers/spi/amba-pl022.c')
-rw-r--r--drivers/spi/amba-pl022.c73
1 files changed, 39 insertions, 34 deletions
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index 95e58c70a2c9..5c2b092a915e 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -329,15 +329,16 @@ struct vendor_data {
329/** 329/**
330 * struct pl022 - This is the private SSP driver data structure 330 * struct pl022 - This is the private SSP driver data structure
331 * @adev: AMBA device model hookup 331 * @adev: AMBA device model hookup
332 * @vendor: Vendor data for the IP block 332 * @vendor: vendor data for the IP block
333 * @phybase: The physical memory where the SSP device resides 333 * @phybase: the physical memory where the SSP device resides
334 * @virtbase: The virtual memory where the SSP is mapped 334 * @virtbase: the virtual memory where the SSP is mapped
335 * @clk: outgoing clock "SPICLK" for the SPI bus
335 * @master: SPI framework hookup 336 * @master: SPI framework hookup
336 * @master_info: controller-specific data from machine setup 337 * @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 338 * @workqueue: a workqueue on which any spi_message request is queued
339 * @pump_messages: work struct for scheduling work to the workqueue
340 * @queue_lock: spinlock to syncronise access to message queue
341 * @queue: message queue
341 * @busy: workqueue is busy 342 * @busy: workqueue is busy
342 * @running: workqueue is running 343 * @running: workqueue is running
343 * @pump_transfers: Tasklet used in Interrupt Transfer mode 344 * @pump_transfers: Tasklet used in Interrupt Transfer mode
@@ -348,8 +349,14 @@ struct vendor_data {
348 * @tx_end: end position in TX buffer to be read 349 * @tx_end: end position in TX buffer to be read
349 * @rx: current position in RX buffer to be written 350 * @rx: current position in RX buffer to be written
350 * @rx_end: end position in RX buffer to be written 351 * @rx_end: end position in RX buffer to be written
351 * @readingtype: the type of read currently going on 352 * @read: the type of read currently going on
352 * @writingtype: the type or write currently going on 353 * @write: the type of write currently going on
354 * @exp_fifo_level: expected FIFO level
355 * @dma_rx_channel: optional channel for RX DMA
356 * @dma_tx_channel: optional channel for TX DMA
357 * @sgt_rx: scattertable for the RX transfer
358 * @sgt_tx: scattertable for the TX transfer
359 * @dummypage: a dummy page used for driving data on the bus with DMA
353 */ 360 */
354struct pl022 { 361struct pl022 {
355 struct amba_device *adev; 362 struct amba_device *adev;
@@ -397,8 +404,8 @@ struct pl022 {
397 * @cpsr: Value of Clock prescale register 404 * @cpsr: Value of Clock prescale register
398 * @n_bytes: how many bytes(power of 2) reqd for a given data width of client 405 * @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 406 * @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 407 * @read: function ptr to be used to read when doing xfer for this chip
408 * @write: function ptr to be used to write when doing xfer for this chip
402 * @cs_control: chip select callback provided by chip 409 * @cs_control: chip select callback provided by chip
403 * @xfer_type: polling/interrupt/DMA 410 * @xfer_type: polling/interrupt/DMA
404 * 411 *
@@ -508,9 +515,10 @@ static void giveback(struct pl022 *pl022)
508 msg->state = NULL; 515 msg->state = NULL;
509 if (msg->complete) 516 if (msg->complete)
510 msg->complete(msg->context); 517 msg->complete(msg->context);
511 /* This message is completed, so let's turn off the clocks! */ 518 /* This message is completed, so let's turn off the clocks & power */
512 clk_disable(pl022->clk); 519 clk_disable(pl022->clk);
513 amba_pclk_disable(pl022->adev); 520 amba_pclk_disable(pl022->adev);
521 amba_vcore_disable(pl022->adev);
514} 522}
515 523
516/** 524/**
@@ -917,7 +925,6 @@ static int configure_dma(struct pl022 *pl022)
917 struct dma_chan *txchan = pl022->dma_tx_channel; 925 struct dma_chan *txchan = pl022->dma_tx_channel;
918 struct dma_async_tx_descriptor *rxdesc; 926 struct dma_async_tx_descriptor *rxdesc;
919 struct dma_async_tx_descriptor *txdesc; 927 struct dma_async_tx_descriptor *txdesc;
920 dma_cookie_t cookie;
921 928
922 /* Check that the channels are available */ 929 /* Check that the channels are available */
923 if (!rxchan || !txchan) 930 if (!rxchan || !txchan)
@@ -962,10 +969,8 @@ static int configure_dma(struct pl022 *pl022)
962 tx_conf.dst_addr_width = rx_conf.src_addr_width; 969 tx_conf.dst_addr_width = rx_conf.src_addr_width;
963 BUG_ON(rx_conf.src_addr_width != tx_conf.dst_addr_width); 970 BUG_ON(rx_conf.src_addr_width != tx_conf.dst_addr_width);
964 971
965 rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG, 972 dmaengine_slave_config(rxchan, &rx_conf);
966 (unsigned long) &rx_conf); 973 dmaengine_slave_config(txchan, &tx_conf);
967 txchan->device->device_control(txchan, DMA_SLAVE_CONFIG,
968 (unsigned long) &tx_conf);
969 974
970 /* Create sglists for the transfers */ 975 /* Create sglists for the transfers */
971 pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1; 976 pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1;
@@ -1018,23 +1023,17 @@ static int configure_dma(struct pl022 *pl022)
1018 rxdesc->callback_param = pl022; 1023 rxdesc->callback_param = pl022;
1019 1024
1020 /* Submit and fire RX and TX with TX last so we're ready to read! */ 1025 /* Submit and fire RX and TX with TX last so we're ready to read! */
1021 cookie = rxdesc->tx_submit(rxdesc); 1026 dmaengine_submit(rxdesc);
1022 if (dma_submit_error(cookie)) 1027 dmaengine_submit(txdesc);
1023 goto err_submit_rx; 1028 dma_async_issue_pending(rxchan);
1024 cookie = txdesc->tx_submit(txdesc); 1029 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 1030
1030 return 0; 1031 return 0;
1031 1032
1032err_submit_tx:
1033err_submit_rx:
1034err_txdesc: 1033err_txdesc:
1035 txchan->device->device_control(txchan, DMA_TERMINATE_ALL, 0); 1034 dmaengine_terminate_all(txchan);
1036err_rxdesc: 1035err_rxdesc:
1037 rxchan->device->device_control(rxchan, DMA_TERMINATE_ALL, 0); 1036 dmaengine_terminate_all(rxchan);
1038 dma_unmap_sg(txchan->device->dev, pl022->sgt_tx.sgl, 1037 dma_unmap_sg(txchan->device->dev, pl022->sgt_tx.sgl,
1039 pl022->sgt_tx.nents, DMA_TO_DEVICE); 1038 pl022->sgt_tx.nents, DMA_TO_DEVICE);
1040err_tx_sgmap: 1039err_tx_sgmap:
@@ -1101,8 +1100,8 @@ static void terminate_dma(struct pl022 *pl022)
1101 struct dma_chan *rxchan = pl022->dma_rx_channel; 1100 struct dma_chan *rxchan = pl022->dma_rx_channel;
1102 struct dma_chan *txchan = pl022->dma_tx_channel; 1101 struct dma_chan *txchan = pl022->dma_tx_channel;
1103 1102
1104 rxchan->device->device_control(rxchan, DMA_TERMINATE_ALL, 0); 1103 dmaengine_terminate_all(rxchan);
1105 txchan->device->device_control(txchan, DMA_TERMINATE_ALL, 0); 1104 dmaengine_terminate_all(txchan);
1106 unmap_free_dma_scatter(pl022); 1105 unmap_free_dma_scatter(pl022);
1107} 1106}
1108 1107
@@ -1482,9 +1481,11 @@ static void pump_messages(struct work_struct *work)
1482 /* Setup the SPI using the per chip configuration */ 1481 /* Setup the SPI using the per chip configuration */
1483 pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); 1482 pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi);
1484 /* 1483 /*
1485 * We enable the clocks here, then the clocks will be disabled when 1484 * We enable the core voltage and clocks here, then the clocks
1486 * giveback() is called in each method (poll/interrupt/DMA) 1485 * and core will be disabled when giveback() is called in each method
1486 * (poll/interrupt/DMA)
1487 */ 1487 */
1488 amba_vcore_enable(pl022->adev);
1488 amba_pclk_enable(pl022->adev); 1489 amba_pclk_enable(pl022->adev);
1489 clk_enable(pl022->clk); 1490 clk_enable(pl022->clk);
1490 restore_state(pl022); 1491 restore_state(pl022);
@@ -1910,8 +1911,6 @@ static int pl022_setup(struct spi_device *spi)
1910 && ((pl022->master_info)->enable_dma)) { 1911 && ((pl022->master_info)->enable_dma)) {
1911 chip->enable_dma = true; 1912 chip->enable_dma = true;
1912 dev_dbg(&spi->dev, "DMA mode set in controller state\n"); 1913 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, 1914 SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED,
1916 SSP_DMACR_MASK_RXDMAE, 0); 1915 SSP_DMACR_MASK_RXDMAE, 0);
1917 SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED, 1916 SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED,
@@ -2130,8 +2129,12 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
2130 goto err_spi_register; 2129 goto err_spi_register;
2131 } 2130 }
2132 dev_dbg(dev, "probe succeded\n"); 2131 dev_dbg(dev, "probe succeded\n");
2133 /* Disable the silicon block pclk and clock it when needed */ 2132 /*
2133 * Disable the silicon block pclk and any voltage domain and just
2134 * power it up and clock it when it's needed
2135 */
2134 amba_pclk_disable(adev); 2136 amba_pclk_disable(adev);
2137 amba_vcore_disable(adev);
2135 return 0; 2138 return 0;
2136 2139
2137 err_spi_register: 2140 err_spi_register:
@@ -2196,9 +2199,11 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state)
2196 return status; 2199 return status;
2197 } 2200 }
2198 2201
2202 amba_vcore_enable(adev);
2199 amba_pclk_enable(adev); 2203 amba_pclk_enable(adev);
2200 load_ssp_default_config(pl022); 2204 load_ssp_default_config(pl022);
2201 amba_pclk_disable(adev); 2205 amba_pclk_disable(adev);
2206 amba_vcore_disable(adev);
2202 dev_dbg(&adev->dev, "suspended\n"); 2207 dev_dbg(&adev->dev, "suspended\n");
2203 return 0; 2208 return 0;
2204} 2209}