diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/spi/spi-pl022.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/spi/spi-pl022.c')
-rw-r--r-- | drivers/spi/spi-pl022.c | 920 |
1 files changed, 426 insertions, 494 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index b0fe393c882..730b4a37b82 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * A driver for the ARM PL022 PrimeCell SSP/SPI bus master. | 2 | * A driver for the ARM PL022 PrimeCell SSP/SPI bus master. |
3 | * | 3 | * |
4 | * Copyright (C) 2008-2012 ST-Ericsson AB | 4 | * Copyright (C) 2008-2009 ST-Ericsson AB |
5 | * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. | 5 | * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. |
6 | * | 6 | * |
7 | * Author: Linus Walleij <linus.walleij@stericsson.com> | 7 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/spi/spi.h> | 31 | #include <linux/spi/spi.h> |
32 | #include <linux/workqueue.h> | ||
32 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
33 | #include <linux/clk.h> | 34 | #include <linux/clk.h> |
34 | #include <linux/err.h> | 35 | #include <linux/err.h> |
@@ -40,9 +41,6 @@ | |||
40 | #include <linux/dma-mapping.h> | 41 | #include <linux/dma-mapping.h> |
41 | #include <linux/scatterlist.h> | 42 | #include <linux/scatterlist.h> |
42 | #include <linux/pm_runtime.h> | 43 | #include <linux/pm_runtime.h> |
43 | #include <linux/gpio.h> | ||
44 | #include <linux/of_gpio.h> | ||
45 | #include <linux/pinctrl/consumer.h> | ||
46 | 44 | ||
47 | /* | 45 | /* |
48 | * This macro is used to define some register default values. | 46 | * This macro is used to define some register default values. |
@@ -115,6 +113,7 @@ | |||
115 | #define SSP_CR0_MASK_CSS_ST (0x1FUL << 16) | 113 | #define SSP_CR0_MASK_CSS_ST (0x1FUL << 16) |
116 | #define SSP_CR0_MASK_FRF_ST (0x3UL << 21) | 114 | #define SSP_CR0_MASK_FRF_ST (0x3UL << 21) |
117 | 115 | ||
116 | |||
118 | /* | 117 | /* |
119 | * SSP Control Register 0 - SSP_CR1 | 118 | * SSP Control Register 0 - SSP_CR1 |
120 | */ | 119 | */ |
@@ -284,6 +283,7 @@ | |||
284 | 283 | ||
285 | #define SPI_POLLING_TIMEOUT 1000 | 284 | #define SPI_POLLING_TIMEOUT 1000 |
286 | 285 | ||
286 | |||
287 | /* | 287 | /* |
288 | * The type of reading going on on this chip | 288 | * The type of reading going on on this chip |
289 | */ | 289 | */ |
@@ -332,21 +332,16 @@ struct vendor_data { | |||
332 | * @clk: outgoing clock "SPICLK" for the SPI bus | 332 | * @clk: outgoing clock "SPICLK" for the SPI bus |
333 | * @master: SPI framework hookup | 333 | * @master: SPI framework hookup |
334 | * @master_info: controller-specific data from machine setup | 334 | * @master_info: controller-specific data from machine setup |
335 | * @kworker: thread struct for message pump | 335 | * @workqueue: a workqueue on which any spi_message request is queued |
336 | * @kworker_task: pointer to task for message pump kworker thread | 336 | * @pump_messages: work struct for scheduling work to the workqueue |
337 | * @pump_messages: work struct for scheduling work to the message pump | ||
338 | * @queue_lock: spinlock to syncronise access to message queue | 337 | * @queue_lock: spinlock to syncronise access to message queue |
339 | * @queue: message queue | 338 | * @queue: message queue |
340 | * @busy: message pump is busy | 339 | * @busy: workqueue is busy |
341 | * @running: message pump is running | 340 | * @running: workqueue is running |
342 | * @pump_transfers: Tasklet used in Interrupt Transfer mode | 341 | * @pump_transfers: Tasklet used in Interrupt Transfer mode |
343 | * @cur_msg: Pointer to current spi_message being processed | 342 | * @cur_msg: Pointer to current spi_message being processed |
344 | * @cur_transfer: Pointer to current spi_transfer | 343 | * @cur_transfer: Pointer to current spi_transfer |
345 | * @cur_chip: pointer to current clients chip(assigned from controller_state) | 344 | * @cur_chip: pointer to current clients chip(assigned from controller_state) |
346 | * @next_msg_cs_active: the next message in the queue has been examined | ||
347 | * and it was found that it uses the same chip select as the previous | ||
348 | * message, so we left it active after the previous transfer, and it's | ||
349 | * active already. | ||
350 | * @tx: current position in TX buffer to be read | 345 | * @tx: current position in TX buffer to be read |
351 | * @tx_end: end position in TX buffer to be read | 346 | * @tx_end: end position in TX buffer to be read |
352 | * @rx: current position in RX buffer to be written | 347 | * @rx: current position in RX buffer to be written |
@@ -359,8 +354,6 @@ struct vendor_data { | |||
359 | * @sgt_rx: scattertable for the RX transfer | 354 | * @sgt_rx: scattertable for the RX transfer |
360 | * @sgt_tx: scattertable for the TX transfer | 355 | * @sgt_tx: scattertable for the TX transfer |
361 | * @dummypage: a dummy page used for driving data on the bus with DMA | 356 | * @dummypage: a dummy page used for driving data on the bus with DMA |
362 | * @cur_cs: current chip select (gpio) | ||
363 | * @chipselects: list of chipselects (gpios) | ||
364 | */ | 357 | */ |
365 | struct pl022 { | 358 | struct pl022 { |
366 | struct amba_device *adev; | 359 | struct amba_device *adev; |
@@ -368,19 +361,20 @@ struct pl022 { | |||
368 | resource_size_t phybase; | 361 | resource_size_t phybase; |
369 | void __iomem *virtbase; | 362 | void __iomem *virtbase; |
370 | struct clk *clk; | 363 | struct clk *clk; |
371 | /* Two optional pin states - default & sleep */ | ||
372 | struct pinctrl *pinctrl; | ||
373 | struct pinctrl_state *pins_default; | ||
374 | struct pinctrl_state *pins_idle; | ||
375 | struct pinctrl_state *pins_sleep; | ||
376 | struct spi_master *master; | 364 | struct spi_master *master; |
377 | struct pl022_ssp_controller *master_info; | 365 | struct pl022_ssp_controller *master_info; |
378 | /* Message per-transfer pump */ | 366 | /* Driver message queue */ |
367 | struct workqueue_struct *workqueue; | ||
368 | struct work_struct pump_messages; | ||
369 | spinlock_t queue_lock; | ||
370 | struct list_head queue; | ||
371 | bool busy; | ||
372 | bool running; | ||
373 | /* Message transfer pump */ | ||
379 | struct tasklet_struct pump_transfers; | 374 | struct tasklet_struct pump_transfers; |
380 | struct spi_message *cur_msg; | 375 | struct spi_message *cur_msg; |
381 | struct spi_transfer *cur_transfer; | 376 | struct spi_transfer *cur_transfer; |
382 | struct chip_data *cur_chip; | 377 | struct chip_data *cur_chip; |
383 | bool next_msg_cs_active; | ||
384 | void *tx; | 378 | void *tx; |
385 | void *tx_end; | 379 | void *tx_end; |
386 | void *rx; | 380 | void *rx; |
@@ -397,10 +391,7 @@ struct pl022 { | |||
397 | struct sg_table sgt_rx; | 391 | struct sg_table sgt_rx; |
398 | struct sg_table sgt_tx; | 392 | struct sg_table sgt_tx; |
399 | char *dummypage; | 393 | char *dummypage; |
400 | bool dma_running; | ||
401 | #endif | 394 | #endif |
402 | int cur_cs; | ||
403 | int *chipselects; | ||
404 | }; | 395 | }; |
405 | 396 | ||
406 | /** | 397 | /** |
@@ -445,14 +436,6 @@ static void null_cs_control(u32 command) | |||
445 | pr_debug("pl022: dummy chip select control, CS=0x%x\n", command); | 436 | pr_debug("pl022: dummy chip select control, CS=0x%x\n", command); |
446 | } | 437 | } |
447 | 438 | ||
448 | static void pl022_cs_control(struct pl022 *pl022, u32 command) | ||
449 | { | ||
450 | if (gpio_is_valid(pl022->cur_cs)) | ||
451 | gpio_set_value(pl022->cur_cs, command); | ||
452 | else | ||
453 | pl022->cur_chip->cs_control(command); | ||
454 | } | ||
455 | |||
456 | /** | 439 | /** |
457 | * giveback - current spi_message is over, schedule next message and call | 440 | * giveback - current spi_message is over, schedule next message and call |
458 | * callback of this message. Assumes that caller already | 441 | * callback of this message. Assumes that caller already |
@@ -462,9 +445,25 @@ static void pl022_cs_control(struct pl022 *pl022, u32 command) | |||
462 | static void giveback(struct pl022 *pl022) | 445 | static void giveback(struct pl022 *pl022) |
463 | { | 446 | { |
464 | struct spi_transfer *last_transfer; | 447 | struct spi_transfer *last_transfer; |
465 | pl022->next_msg_cs_active = false; | 448 | unsigned long flags; |
449 | struct spi_message *msg; | ||
450 | void (*curr_cs_control) (u32 command); | ||
451 | |||
452 | /* | ||
453 | * This local reference to the chip select function | ||
454 | * is needed because we set curr_chip to NULL | ||
455 | * as a step toward termininating the message. | ||
456 | */ | ||
457 | curr_cs_control = pl022->cur_chip->cs_control; | ||
458 | spin_lock_irqsave(&pl022->queue_lock, flags); | ||
459 | msg = pl022->cur_msg; | ||
460 | pl022->cur_msg = NULL; | ||
461 | pl022->cur_transfer = NULL; | ||
462 | pl022->cur_chip = NULL; | ||
463 | queue_work(pl022->workqueue, &pl022->pump_messages); | ||
464 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
466 | 465 | ||
467 | last_transfer = list_entry(pl022->cur_msg->transfers.prev, | 466 | last_transfer = list_entry(msg->transfers.prev, |
468 | struct spi_transfer, | 467 | struct spi_transfer, |
469 | transfer_list); | 468 | transfer_list); |
470 | 469 | ||
@@ -476,44 +475,50 @@ static void giveback(struct pl022 *pl022) | |||
476 | */ | 475 | */ |
477 | udelay(last_transfer->delay_usecs); | 476 | udelay(last_transfer->delay_usecs); |
478 | 477 | ||
479 | if (!last_transfer->cs_change) { | 478 | /* |
479 | * Drop chip select UNLESS cs_change is true or we are returning | ||
480 | * a message with an error, or next message is for another chip | ||
481 | */ | ||
482 | if (!last_transfer->cs_change) | ||
483 | curr_cs_control(SSP_CHIP_DESELECT); | ||
484 | else { | ||
480 | struct spi_message *next_msg; | 485 | struct spi_message *next_msg; |
481 | 486 | ||
482 | /* | 487 | /* Holding of cs was hinted, but we need to make sure |
483 | * cs_change was not set. We can keep the chip select | 488 | * the next message is for the same chip. Don't waste |
484 | * enabled if there is message in the queue and it is | 489 | * time with the following tests unless this was hinted. |
485 | * for the same spi device. | ||
486 | * | 490 | * |
487 | * We cannot postpone this until pump_messages, because | 491 | * We cannot postpone this until pump_messages, because |
488 | * after calling msg->complete (below) the driver that | 492 | * after calling msg->complete (below) the driver that |
489 | * sent the current message could be unloaded, which | 493 | * sent the current message could be unloaded, which |
490 | * could invalidate the cs_control() callback... | 494 | * could invalidate the cs_control() callback... |
491 | */ | 495 | */ |
492 | /* get a pointer to the next message, if any */ | ||
493 | next_msg = spi_get_next_queued_message(pl022->master); | ||
494 | 496 | ||
495 | /* | 497 | /* get a pointer to the next message, if any */ |
496 | * see if the next and current messages point | 498 | spin_lock_irqsave(&pl022->queue_lock, flags); |
497 | * to the same spi device. | 499 | if (list_empty(&pl022->queue)) |
498 | */ | ||
499 | if (next_msg && next_msg->spi != pl022->cur_msg->spi) | ||
500 | next_msg = NULL; | 500 | next_msg = NULL; |
501 | if (!next_msg || pl022->cur_msg->state == STATE_ERROR) | ||
502 | pl022_cs_control(pl022, SSP_CHIP_DESELECT); | ||
503 | else | 501 | else |
504 | pl022->next_msg_cs_active = true; | 502 | next_msg = list_entry(pl022->queue.next, |
503 | struct spi_message, queue); | ||
504 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
505 | 505 | ||
506 | /* see if the next and current messages point | ||
507 | * to the same chip | ||
508 | */ | ||
509 | if (next_msg && next_msg->spi != msg->spi) | ||
510 | next_msg = NULL; | ||
511 | if (!next_msg || msg->state == STATE_ERROR) | ||
512 | curr_cs_control(SSP_CHIP_DESELECT); | ||
506 | } | 513 | } |
507 | 514 | msg->state = NULL; | |
508 | pl022->cur_msg = NULL; | 515 | if (msg->complete) |
509 | pl022->cur_transfer = NULL; | 516 | msg->complete(msg->context); |
510 | pl022->cur_chip = NULL; | 517 | /* This message is completed, so let's turn off the clocks & power */ |
511 | spi_finalize_current_message(pl022->master); | 518 | clk_disable(pl022->clk); |
512 | 519 | amba_pclk_disable(pl022->adev); | |
513 | /* disable the SPI/SSP operation */ | 520 | amba_vcore_disable(pl022->adev); |
514 | writew((readw(SSP_CR1(pl022->virtbase)) & | 521 | pm_runtime_put(&pl022->adev->dev); |
515 | (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); | ||
516 | |||
517 | } | 522 | } |
518 | 523 | ||
519 | /** | 524 | /** |
@@ -747,6 +752,7 @@ static void readwriter(struct pl022 *pl022) | |||
747 | */ | 752 | */ |
748 | } | 753 | } |
749 | 754 | ||
755 | |||
750 | /** | 756 | /** |
751 | * next_transfer - Move to the Next transfer in the current spi message | 757 | * next_transfer - Move to the Next transfer in the current spi message |
752 | * @pl022: SSP driver private data structure | 758 | * @pl022: SSP driver private data structure |
@@ -838,7 +844,8 @@ static void dma_callback(void *data) | |||
838 | /* Update total bytes transferred */ | 844 | /* Update total bytes transferred */ |
839 | msg->actual_length += pl022->cur_transfer->len; | 845 | msg->actual_length += pl022->cur_transfer->len; |
840 | if (pl022->cur_transfer->cs_change) | 846 | if (pl022->cur_transfer->cs_change) |
841 | pl022_cs_control(pl022, SSP_CHIP_DESELECT); | 847 | pl022->cur_chip-> |
848 | cs_control(SSP_CHIP_DESELECT); | ||
842 | 849 | ||
843 | /* Move to next transfer */ | 850 | /* Move to next transfer */ |
844 | msg->state = next_transfer(pl022); | 851 | msg->state = next_transfer(pl022); |
@@ -903,13 +910,11 @@ static int configure_dma(struct pl022 *pl022) | |||
903 | { | 910 | { |
904 | struct dma_slave_config rx_conf = { | 911 | struct dma_slave_config rx_conf = { |
905 | .src_addr = SSP_DR(pl022->phybase), | 912 | .src_addr = SSP_DR(pl022->phybase), |
906 | .direction = DMA_DEV_TO_MEM, | 913 | .direction = DMA_FROM_DEVICE, |
907 | .device_fc = false, | ||
908 | }; | 914 | }; |
909 | struct dma_slave_config tx_conf = { | 915 | struct dma_slave_config tx_conf = { |
910 | .dst_addr = SSP_DR(pl022->phybase), | 916 | .dst_addr = SSP_DR(pl022->phybase), |
911 | .direction = DMA_MEM_TO_DEV, | 917 | .direction = DMA_TO_DEVICE, |
912 | .device_fc = false, | ||
913 | }; | 918 | }; |
914 | unsigned int pages; | 919 | unsigned int pages; |
915 | int ret; | 920 | int ret; |
@@ -1014,14 +1019,14 @@ static int configure_dma(struct pl022 *pl022) | |||
1014 | dmaengine_slave_config(txchan, &tx_conf); | 1019 | dmaengine_slave_config(txchan, &tx_conf); |
1015 | 1020 | ||
1016 | /* Create sglists for the transfers */ | 1021 | /* Create sglists for the transfers */ |
1017 | pages = DIV_ROUND_UP(pl022->cur_transfer->len, PAGE_SIZE); | 1022 | pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1; |
1018 | dev_dbg(&pl022->adev->dev, "using %d pages for transfer\n", pages); | 1023 | dev_dbg(&pl022->adev->dev, "using %d pages for transfer\n", pages); |
1019 | 1024 | ||
1020 | ret = sg_alloc_table(&pl022->sgt_rx, pages, GFP_ATOMIC); | 1025 | ret = sg_alloc_table(&pl022->sgt_rx, pages, GFP_KERNEL); |
1021 | if (ret) | 1026 | if (ret) |
1022 | goto err_alloc_rx_sg; | 1027 | goto err_alloc_rx_sg; |
1023 | 1028 | ||
1024 | ret = sg_alloc_table(&pl022->sgt_tx, pages, GFP_ATOMIC); | 1029 | ret = sg_alloc_table(&pl022->sgt_tx, pages, GFP_KERNEL); |
1025 | if (ret) | 1030 | if (ret) |
1026 | goto err_alloc_tx_sg; | 1031 | goto err_alloc_tx_sg; |
1027 | 1032 | ||
@@ -1043,18 +1048,18 @@ static int configure_dma(struct pl022 *pl022) | |||
1043 | goto err_tx_sgmap; | 1048 | goto err_tx_sgmap; |
1044 | 1049 | ||
1045 | /* Send both scatterlists */ | 1050 | /* Send both scatterlists */ |
1046 | rxdesc = dmaengine_prep_slave_sg(rxchan, | 1051 | rxdesc = rxchan->device->device_prep_slave_sg(rxchan, |
1047 | pl022->sgt_rx.sgl, | 1052 | pl022->sgt_rx.sgl, |
1048 | rx_sglen, | 1053 | rx_sglen, |
1049 | DMA_DEV_TO_MEM, | 1054 | DMA_FROM_DEVICE, |
1050 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 1055 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
1051 | if (!rxdesc) | 1056 | if (!rxdesc) |
1052 | goto err_rxdesc; | 1057 | goto err_rxdesc; |
1053 | 1058 | ||
1054 | txdesc = dmaengine_prep_slave_sg(txchan, | 1059 | txdesc = txchan->device->device_prep_slave_sg(txchan, |
1055 | pl022->sgt_tx.sgl, | 1060 | pl022->sgt_tx.sgl, |
1056 | tx_sglen, | 1061 | tx_sglen, |
1057 | DMA_MEM_TO_DEV, | 1062 | DMA_TO_DEVICE, |
1058 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 1063 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
1059 | if (!txdesc) | 1064 | if (!txdesc) |
1060 | goto err_txdesc; | 1065 | goto err_txdesc; |
@@ -1068,7 +1073,6 @@ static int configure_dma(struct pl022 *pl022) | |||
1068 | dmaengine_submit(txdesc); | 1073 | dmaengine_submit(txdesc); |
1069 | dma_async_issue_pending(rxchan); | 1074 | dma_async_issue_pending(rxchan); |
1070 | dma_async_issue_pending(txchan); | 1075 | dma_async_issue_pending(txchan); |
1071 | pl022->dma_running = true; | ||
1072 | 1076 | ||
1073 | return 0; | 1077 | return 0; |
1074 | 1078 | ||
@@ -1089,7 +1093,7 @@ err_alloc_rx_sg: | |||
1089 | return -ENOMEM; | 1093 | return -ENOMEM; |
1090 | } | 1094 | } |
1091 | 1095 | ||
1092 | static int pl022_dma_probe(struct pl022 *pl022) | 1096 | static int __init pl022_dma_probe(struct pl022 *pl022) |
1093 | { | 1097 | { |
1094 | dma_cap_mask_t mask; | 1098 | dma_cap_mask_t mask; |
1095 | 1099 | ||
@@ -1147,12 +1151,11 @@ static void terminate_dma(struct pl022 *pl022) | |||
1147 | dmaengine_terminate_all(rxchan); | 1151 | dmaengine_terminate_all(rxchan); |
1148 | dmaengine_terminate_all(txchan); | 1152 | dmaengine_terminate_all(txchan); |
1149 | unmap_free_dma_scatter(pl022); | 1153 | unmap_free_dma_scatter(pl022); |
1150 | pl022->dma_running = false; | ||
1151 | } | 1154 | } |
1152 | 1155 | ||
1153 | static void pl022_dma_remove(struct pl022 *pl022) | 1156 | static void pl022_dma_remove(struct pl022 *pl022) |
1154 | { | 1157 | { |
1155 | if (pl022->dma_running) | 1158 | if (pl022->busy) |
1156 | terminate_dma(pl022); | 1159 | terminate_dma(pl022); |
1157 | if (pl022->dma_tx_channel) | 1160 | if (pl022->dma_tx_channel) |
1158 | dma_release_channel(pl022->dma_tx_channel); | 1161 | dma_release_channel(pl022->dma_tx_channel); |
@@ -1247,9 +1250,9 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id) | |||
1247 | 1250 | ||
1248 | if ((pl022->tx == pl022->tx_end) && (flag == 0)) { | 1251 | if ((pl022->tx == pl022->tx_end) && (flag == 0)) { |
1249 | flag = 1; | 1252 | flag = 1; |
1250 | /* Disable Transmit interrupt, enable receive interrupt */ | 1253 | /* Disable Transmit interrupt */ |
1251 | writew((readw(SSP_IMSC(pl022->virtbase)) & | 1254 | writew(readw(SSP_IMSC(pl022->virtbase)) & |
1252 | ~SSP_IMSC_MASK_TXIM) | SSP_IMSC_MASK_RXIM, | 1255 | (~SSP_IMSC_MASK_TXIM), |
1253 | SSP_IMSC(pl022->virtbase)); | 1256 | SSP_IMSC(pl022->virtbase)); |
1254 | } | 1257 | } |
1255 | 1258 | ||
@@ -1271,7 +1274,8 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id) | |||
1271 | /* Update total bytes transferred */ | 1274 | /* Update total bytes transferred */ |
1272 | msg->actual_length += pl022->cur_transfer->len; | 1275 | msg->actual_length += pl022->cur_transfer->len; |
1273 | if (pl022->cur_transfer->cs_change) | 1276 | if (pl022->cur_transfer->cs_change) |
1274 | pl022_cs_control(pl022, SSP_CHIP_DESELECT); | 1277 | pl022->cur_chip-> |
1278 | cs_control(SSP_CHIP_DESELECT); | ||
1275 | /* Move to next transfer */ | 1279 | /* Move to next transfer */ |
1276 | msg->state = next_transfer(pl022); | 1280 | msg->state = next_transfer(pl022); |
1277 | tasklet_schedule(&pl022->pump_transfers); | 1281 | tasklet_schedule(&pl022->pump_transfers); |
@@ -1354,9 +1358,9 @@ static void pump_transfers(unsigned long data) | |||
1354 | */ | 1358 | */ |
1355 | udelay(previous->delay_usecs); | 1359 | udelay(previous->delay_usecs); |
1356 | 1360 | ||
1357 | /* Reselect chip select only if cs_change was requested */ | 1361 | /* Drop chip select only if cs_change is requested */ |
1358 | if (previous->cs_change) | 1362 | if (previous->cs_change) |
1359 | pl022_cs_control(pl022, SSP_CHIP_SELECT); | 1363 | pl022->cur_chip->cs_control(SSP_CHIP_SELECT); |
1360 | } else { | 1364 | } else { |
1361 | /* STATE_START */ | 1365 | /* STATE_START */ |
1362 | message->state = STATE_RUNNING; | 1366 | message->state = STATE_RUNNING; |
@@ -1381,22 +1385,15 @@ static void pump_transfers(unsigned long data) | |||
1381 | } | 1385 | } |
1382 | 1386 | ||
1383 | err_config_dma: | 1387 | err_config_dma: |
1384 | /* enable all interrupts except RX */ | 1388 | writew(ENABLE_ALL_INTERRUPTS, SSP_IMSC(pl022->virtbase)); |
1385 | writew(ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM, SSP_IMSC(pl022->virtbase)); | ||
1386 | } | 1389 | } |
1387 | 1390 | ||
1388 | static void do_interrupt_dma_transfer(struct pl022 *pl022) | 1391 | static void do_interrupt_dma_transfer(struct pl022 *pl022) |
1389 | { | 1392 | { |
1390 | /* | 1393 | u32 irqflags = ENABLE_ALL_INTERRUPTS; |
1391 | * Default is to enable all interrupts except RX - | ||
1392 | * this will be enabled once TX is complete | ||
1393 | */ | ||
1394 | u32 irqflags = ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM; | ||
1395 | |||
1396 | /* Enable target chip, if not already active */ | ||
1397 | if (!pl022->next_msg_cs_active) | ||
1398 | pl022_cs_control(pl022, SSP_CHIP_SELECT); | ||
1399 | 1394 | ||
1395 | /* Enable target chip */ | ||
1396 | pl022->cur_chip->cs_control(SSP_CHIP_SELECT); | ||
1400 | if (set_up_next_transfer(pl022, pl022->cur_transfer)) { | 1397 | if (set_up_next_transfer(pl022, pl022->cur_transfer)) { |
1401 | /* Error path */ | 1398 | /* Error path */ |
1402 | pl022->cur_msg->state = STATE_ERROR; | 1399 | pl022->cur_msg->state = STATE_ERROR; |
@@ -1447,12 +1444,11 @@ static void do_polling_transfer(struct pl022 *pl022) | |||
1447 | if (previous->delay_usecs) | 1444 | if (previous->delay_usecs) |
1448 | udelay(previous->delay_usecs); | 1445 | udelay(previous->delay_usecs); |
1449 | if (previous->cs_change) | 1446 | if (previous->cs_change) |
1450 | pl022_cs_control(pl022, SSP_CHIP_SELECT); | 1447 | pl022->cur_chip->cs_control(SSP_CHIP_SELECT); |
1451 | } else { | 1448 | } else { |
1452 | /* STATE_START */ | 1449 | /* STATE_START */ |
1453 | message->state = STATE_RUNNING; | 1450 | message->state = STATE_RUNNING; |
1454 | if (!pl022->next_msg_cs_active) | 1451 | pl022->cur_chip->cs_control(SSP_CHIP_SELECT); |
1455 | pl022_cs_control(pl022, SSP_CHIP_SELECT); | ||
1456 | } | 1452 | } |
1457 | 1453 | ||
1458 | /* Configuration Changing Per Transfer */ | 1454 | /* Configuration Changing Per Transfer */ |
@@ -1484,7 +1480,7 @@ static void do_polling_transfer(struct pl022 *pl022) | |||
1484 | /* Update total byte transferred */ | 1480 | /* Update total byte transferred */ |
1485 | message->actual_length += pl022->cur_transfer->len; | 1481 | message->actual_length += pl022->cur_transfer->len; |
1486 | if (pl022->cur_transfer->cs_change) | 1482 | if (pl022->cur_transfer->cs_change) |
1487 | pl022_cs_control(pl022, SSP_CHIP_DESELECT); | 1483 | pl022->cur_chip->cs_control(SSP_CHIP_DESELECT); |
1488 | /* Move to next transfer */ | 1484 | /* Move to next transfer */ |
1489 | message->state = next_transfer(pl022); | 1485 | message->state = next_transfer(pl022); |
1490 | } | 1486 | } |
@@ -1499,22 +1495,59 @@ out: | |||
1499 | return; | 1495 | return; |
1500 | } | 1496 | } |
1501 | 1497 | ||
1502 | static int pl022_transfer_one_message(struct spi_master *master, | 1498 | /** |
1503 | struct spi_message *msg) | 1499 | * pump_messages - Workqueue function which processes spi message queue |
1500 | * @data: pointer to private data of SSP driver | ||
1501 | * | ||
1502 | * This function checks if there is any spi message in the queue that | ||
1503 | * needs processing and delegate control to appropriate function | ||
1504 | * do_polling_transfer()/do_interrupt_dma_transfer() | ||
1505 | * based on the kind of the transfer | ||
1506 | * | ||
1507 | */ | ||
1508 | static void pump_messages(struct work_struct *work) | ||
1504 | { | 1509 | { |
1505 | struct pl022 *pl022 = spi_master_get_devdata(master); | 1510 | struct pl022 *pl022 = |
1511 | container_of(work, struct pl022, pump_messages); | ||
1512 | unsigned long flags; | ||
1513 | |||
1514 | /* Lock queue and check for queue work */ | ||
1515 | spin_lock_irqsave(&pl022->queue_lock, flags); | ||
1516 | if (list_empty(&pl022->queue) || !pl022->running) { | ||
1517 | pl022->busy = false; | ||
1518 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1519 | return; | ||
1520 | } | ||
1521 | /* Make sure we are not already running a message */ | ||
1522 | if (pl022->cur_msg) { | ||
1523 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1524 | return; | ||
1525 | } | ||
1526 | /* Extract head of queue */ | ||
1527 | pl022->cur_msg = | ||
1528 | list_entry(pl022->queue.next, struct spi_message, queue); | ||
1506 | 1529 | ||
1507 | /* Initial message state */ | 1530 | list_del_init(&pl022->cur_msg->queue); |
1508 | pl022->cur_msg = msg; | 1531 | pl022->busy = true; |
1509 | msg->state = STATE_START; | 1532 | spin_unlock_irqrestore(&pl022->queue_lock, flags); |
1510 | 1533 | ||
1511 | pl022->cur_transfer = list_entry(msg->transfers.next, | 1534 | /* Initial message state */ |
1512 | struct spi_transfer, transfer_list); | 1535 | pl022->cur_msg->state = STATE_START; |
1536 | pl022->cur_transfer = list_entry(pl022->cur_msg->transfers.next, | ||
1537 | struct spi_transfer, | ||
1538 | transfer_list); | ||
1513 | 1539 | ||
1514 | /* Setup the SPI using the per chip configuration */ | 1540 | /* Setup the SPI using the per chip configuration */ |
1515 | pl022->cur_chip = spi_get_ctldata(msg->spi); | 1541 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); |
1516 | pl022->cur_cs = pl022->chipselects[msg->spi->chip_select]; | 1542 | /* |
1517 | 1543 | * We enable the core voltage and clocks here, then the clocks | |
1544 | * and core will be disabled when giveback() is called in each method | ||
1545 | * (poll/interrupt/DMA) | ||
1546 | */ | ||
1547 | pm_runtime_get_sync(&pl022->adev->dev); | ||
1548 | amba_vcore_enable(pl022->adev); | ||
1549 | amba_pclk_enable(pl022->adev); | ||
1550 | clk_enable(pl022->clk); | ||
1518 | restore_state(pl022); | 1551 | restore_state(pl022); |
1519 | flush(pl022); | 1552 | flush(pl022); |
1520 | 1553 | ||
@@ -1522,37 +1555,97 @@ static int pl022_transfer_one_message(struct spi_master *master, | |||
1522 | do_polling_transfer(pl022); | 1555 | do_polling_transfer(pl022); |
1523 | else | 1556 | else |
1524 | do_interrupt_dma_transfer(pl022); | 1557 | do_interrupt_dma_transfer(pl022); |
1558 | } | ||
1559 | |||
1560 | |||
1561 | static int __init init_queue(struct pl022 *pl022) | ||
1562 | { | ||
1563 | INIT_LIST_HEAD(&pl022->queue); | ||
1564 | spin_lock_init(&pl022->queue_lock); | ||
1565 | |||
1566 | pl022->running = false; | ||
1567 | pl022->busy = false; | ||
1568 | |||
1569 | tasklet_init(&pl022->pump_transfers, | ||
1570 | pump_transfers, (unsigned long)pl022); | ||
1571 | |||
1572 | INIT_WORK(&pl022->pump_messages, pump_messages); | ||
1573 | pl022->workqueue = create_singlethread_workqueue( | ||
1574 | dev_name(pl022->master->dev.parent)); | ||
1575 | if (pl022->workqueue == NULL) | ||
1576 | return -EBUSY; | ||
1525 | 1577 | ||
1526 | return 0; | 1578 | return 0; |
1527 | } | 1579 | } |
1528 | 1580 | ||
1529 | static int pl022_prepare_transfer_hardware(struct spi_master *master) | 1581 | |
1582 | static int start_queue(struct pl022 *pl022) | ||
1530 | { | 1583 | { |
1531 | struct pl022 *pl022 = spi_master_get_devdata(master); | 1584 | unsigned long flags; |
1585 | |||
1586 | spin_lock_irqsave(&pl022->queue_lock, flags); | ||
1587 | |||
1588 | if (pl022->running || pl022->busy) { | ||
1589 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1590 | return -EBUSY; | ||
1591 | } | ||
1592 | |||
1593 | pl022->running = true; | ||
1594 | pl022->cur_msg = NULL; | ||
1595 | pl022->cur_transfer = NULL; | ||
1596 | pl022->cur_chip = NULL; | ||
1597 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1598 | |||
1599 | queue_work(pl022->workqueue, &pl022->pump_messages); | ||
1532 | 1600 | ||
1533 | /* | ||
1534 | * Just make sure we have all we need to run the transfer by syncing | ||
1535 | * with the runtime PM framework. | ||
1536 | */ | ||
1537 | pm_runtime_get_sync(&pl022->adev->dev); | ||
1538 | return 0; | 1601 | return 0; |
1539 | } | 1602 | } |
1540 | 1603 | ||
1541 | static int pl022_unprepare_transfer_hardware(struct spi_master *master) | 1604 | |
1605 | static int stop_queue(struct pl022 *pl022) | ||
1542 | { | 1606 | { |
1543 | struct pl022 *pl022 = spi_master_get_devdata(master); | 1607 | unsigned long flags; |
1608 | unsigned limit = 500; | ||
1609 | int status = 0; | ||
1544 | 1610 | ||
1545 | /* nothing more to do - disable spi/ssp and power off */ | 1611 | spin_lock_irqsave(&pl022->queue_lock, flags); |
1546 | writew((readw(SSP_CR1(pl022->virtbase)) & | ||
1547 | (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); | ||
1548 | 1612 | ||
1549 | if (pl022->master_info->autosuspend_delay > 0) { | 1613 | /* This is a bit lame, but is optimized for the common execution path. |
1550 | pm_runtime_mark_last_busy(&pl022->adev->dev); | 1614 | * A wait_queue on the pl022->busy could be used, but then the common |
1551 | pm_runtime_put_autosuspend(&pl022->adev->dev); | 1615 | * execution path (pump_messages) would be required to call wake_up or |
1552 | } else { | 1616 | * friends on every SPI message. Do this instead */ |
1553 | pm_runtime_put(&pl022->adev->dev); | 1617 | while ((!list_empty(&pl022->queue) || pl022->busy) && limit--) { |
1618 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1619 | msleep(10); | ||
1620 | spin_lock_irqsave(&pl022->queue_lock, flags); | ||
1554 | } | 1621 | } |
1555 | 1622 | ||
1623 | if (!list_empty(&pl022->queue) || pl022->busy) | ||
1624 | status = -EBUSY; | ||
1625 | else | ||
1626 | pl022->running = false; | ||
1627 | |||
1628 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1629 | |||
1630 | return status; | ||
1631 | } | ||
1632 | |||
1633 | static int destroy_queue(struct pl022 *pl022) | ||
1634 | { | ||
1635 | int status; | ||
1636 | |||
1637 | status = stop_queue(pl022); | ||
1638 | /* we are unloading the module or failing to load (only two calls | ||
1639 | * to this routine), and neither call can handle a return value. | ||
1640 | * However, destroy_workqueue calls flush_workqueue, and that will | ||
1641 | * block until all work is done. If the reason that stop_queue | ||
1642 | * timed out is that the work will never finish, then it does no | ||
1643 | * good to call destroy_workqueue, so return anyway. */ | ||
1644 | if (status != 0) | ||
1645 | return status; | ||
1646 | |||
1647 | destroy_workqueue(pl022->workqueue); | ||
1648 | |||
1556 | return 0; | 1649 | return 0; |
1557 | } | 1650 | } |
1558 | 1651 | ||
@@ -1672,87 +1765,103 @@ static int verify_controller_parameters(struct pl022 *pl022, | |||
1672 | return 0; | 1765 | return 0; |
1673 | } | 1766 | } |
1674 | 1767 | ||
1675 | static inline u32 spi_rate(u32 rate, u16 cpsdvsr, u16 scr) | 1768 | /** |
1769 | * pl022_transfer - transfer function registered to SPI master framework | ||
1770 | * @spi: spi device which is requesting transfer | ||
1771 | * @msg: spi message which is to handled is queued to driver queue | ||
1772 | * | ||
1773 | * This function is registered to the SPI framework for this SPI master | ||
1774 | * controller. It will queue the spi_message in the queue of driver if | ||
1775 | * the queue is not stopped and return. | ||
1776 | */ | ||
1777 | static int pl022_transfer(struct spi_device *spi, struct spi_message *msg) | ||
1676 | { | 1778 | { |
1677 | return rate / (cpsdvsr * (1 + scr)); | 1779 | struct pl022 *pl022 = spi_master_get_devdata(spi->master); |
1780 | unsigned long flags; | ||
1781 | |||
1782 | spin_lock_irqsave(&pl022->queue_lock, flags); | ||
1783 | |||
1784 | if (!pl022->running) { | ||
1785 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1786 | return -ESHUTDOWN; | ||
1787 | } | ||
1788 | msg->actual_length = 0; | ||
1789 | msg->status = -EINPROGRESS; | ||
1790 | msg->state = STATE_START; | ||
1791 | |||
1792 | list_add_tail(&msg->queue, &pl022->queue); | ||
1793 | if (pl022->running && !pl022->busy) | ||
1794 | queue_work(pl022->workqueue, &pl022->pump_messages); | ||
1795 | |||
1796 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1797 | return 0; | ||
1678 | } | 1798 | } |
1679 | 1799 | ||
1680 | static int calculate_effective_freq(struct pl022 *pl022, int freq, struct | 1800 | static int calculate_effective_freq(struct pl022 *pl022, |
1681 | ssp_clock_params * clk_freq) | 1801 | int freq, |
1802 | struct ssp_clock_params *clk_freq) | ||
1682 | { | 1803 | { |
1683 | /* Lets calculate the frequency parameters */ | 1804 | /* Lets calculate the frequency parameters */ |
1684 | u16 cpsdvsr = CPSDVR_MIN, scr = SCR_MIN; | 1805 | u16 cpsdvsr = 2; |
1685 | u32 rate, max_tclk, min_tclk, best_freq = 0, best_cpsdvsr = 0, | 1806 | u16 scr = 0; |
1686 | best_scr = 0, tmp, found = 0; | 1807 | bool freq_found = false; |
1808 | u32 rate; | ||
1809 | u32 max_tclk; | ||
1810 | u32 min_tclk; | ||
1687 | 1811 | ||
1688 | rate = clk_get_rate(pl022->clk); | 1812 | rate = clk_get_rate(pl022->clk); |
1689 | /* cpsdvscr = 2 & scr 0 */ | 1813 | /* cpsdvscr = 2 & scr 0 */ |
1690 | max_tclk = spi_rate(rate, CPSDVR_MIN, SCR_MIN); | 1814 | max_tclk = (rate / (CPSDVR_MIN * (1 + SCR_MIN))); |
1691 | /* cpsdvsr = 254 & scr = 255 */ | 1815 | /* cpsdvsr = 254 & scr = 255 */ |
1692 | min_tclk = spi_rate(rate, CPSDVR_MAX, SCR_MAX); | 1816 | min_tclk = (rate / (CPSDVR_MAX * (1 + SCR_MAX))); |
1693 | 1817 | ||
1694 | if (freq > max_tclk) | 1818 | if ((freq <= max_tclk) && (freq >= min_tclk)) { |
1695 | dev_warn(&pl022->adev->dev, | 1819 | while (cpsdvsr <= CPSDVR_MAX && !freq_found) { |
1696 | "Max speed that can be programmed is %d Hz, you requested %d\n", | 1820 | while (scr <= SCR_MAX && !freq_found) { |
1697 | max_tclk, freq); | 1821 | if ((rate / |
1698 | 1822 | (cpsdvsr * (1 + scr))) > freq) | |
1699 | if (freq < min_tclk) { | 1823 | scr += 1; |
1700 | dev_err(&pl022->adev->dev, | 1824 | else { |
1701 | "Requested frequency: %d Hz is less than minimum possible %d Hz\n", | 1825 | /* |
1702 | freq, min_tclk); | 1826 | * This bool is made true when |
1703 | return -EINVAL; | 1827 | * effective frequency >= |
1704 | } | 1828 | * target frequency is found |
1705 | 1829 | */ | |
1706 | /* | 1830 | freq_found = true; |
1707 | * best_freq will give closest possible available rate (<= requested | 1831 | if ((rate / |
1708 | * freq) for all values of scr & cpsdvsr. | 1832 | (cpsdvsr * (1 + scr))) != freq) { |
1709 | */ | 1833 | if (scr == SCR_MIN) { |
1710 | while ((cpsdvsr <= CPSDVR_MAX) && !found) { | 1834 | cpsdvsr -= 2; |
1711 | while (scr <= SCR_MAX) { | 1835 | scr = SCR_MAX; |
1712 | tmp = spi_rate(rate, cpsdvsr, scr); | 1836 | } else |
1713 | 1837 | scr -= 1; | |
1714 | if (tmp > freq) { | 1838 | } |
1715 | /* we need lower freq */ | 1839 | } |
1716 | scr++; | ||
1717 | continue; | ||
1718 | } | 1840 | } |
1719 | 1841 | if (!freq_found) { | |
1720 | /* | 1842 | cpsdvsr += 2; |
1721 | * If found exact value, mark found and break. | 1843 | scr = SCR_MIN; |
1722 | * If found more closer value, update and break. | ||
1723 | */ | ||
1724 | if (tmp > best_freq) { | ||
1725 | best_freq = tmp; | ||
1726 | best_cpsdvsr = cpsdvsr; | ||
1727 | best_scr = scr; | ||
1728 | |||
1729 | if (tmp == freq) | ||
1730 | found = 1; | ||
1731 | } | 1844 | } |
1732 | /* | ||
1733 | * increased scr will give lower rates, which are not | ||
1734 | * required | ||
1735 | */ | ||
1736 | break; | ||
1737 | } | 1845 | } |
1738 | cpsdvsr += 2; | 1846 | if (cpsdvsr != 0) { |
1739 | scr = SCR_MIN; | 1847 | dev_dbg(&pl022->adev->dev, |
1848 | "SSP Effective Frequency is %u\n", | ||
1849 | (rate / (cpsdvsr * (1 + scr)))); | ||
1850 | clk_freq->cpsdvsr = (u8) (cpsdvsr & 0xFF); | ||
1851 | clk_freq->scr = (u8) (scr & 0xFF); | ||
1852 | dev_dbg(&pl022->adev->dev, | ||
1853 | "SSP cpsdvsr = %d, scr = %d\n", | ||
1854 | clk_freq->cpsdvsr, clk_freq->scr); | ||
1855 | } | ||
1856 | } else { | ||
1857 | dev_err(&pl022->adev->dev, | ||
1858 | "controller data is incorrect: out of range frequency"); | ||
1859 | return -EINVAL; | ||
1740 | } | 1860 | } |
1741 | |||
1742 | WARN(!best_freq, "pl022: Matching cpsdvsr and scr not found for %d Hz rate \n", | ||
1743 | freq); | ||
1744 | |||
1745 | clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF); | ||
1746 | clk_freq->scr = (u8) (best_scr & 0xFF); | ||
1747 | dev_dbg(&pl022->adev->dev, | ||
1748 | "SSP Target Frequency is: %u, Effective Frequency is %u\n", | ||
1749 | freq, best_freq); | ||
1750 | dev_dbg(&pl022->adev->dev, "SSP cpsdvsr = %d, scr = %d\n", | ||
1751 | clk_freq->cpsdvsr, clk_freq->scr); | ||
1752 | |||
1753 | return 0; | 1861 | return 0; |
1754 | } | 1862 | } |
1755 | 1863 | ||
1864 | |||
1756 | /* | 1865 | /* |
1757 | * A piece of default chip info unless the platform | 1866 | * A piece of default chip info unless the platform |
1758 | * supplies it. | 1867 | * supplies it. |
@@ -1770,6 +1879,7 @@ static const struct pl022_config_chip pl022_default_chip_info = { | |||
1770 | .cs_control = null_cs_control, | 1879 | .cs_control = null_cs_control, |
1771 | }; | 1880 | }; |
1772 | 1881 | ||
1882 | |||
1773 | /** | 1883 | /** |
1774 | * pl022_setup - setup function registered to SPI master framework | 1884 | * pl022_setup - setup function registered to SPI master framework |
1775 | * @spi: spi device which is requesting setup | 1885 | * @spi: spi device which is requesting setup |
@@ -1785,14 +1895,12 @@ static const struct pl022_config_chip pl022_default_chip_info = { | |||
1785 | static int pl022_setup(struct spi_device *spi) | 1895 | static int pl022_setup(struct spi_device *spi) |
1786 | { | 1896 | { |
1787 | struct pl022_config_chip const *chip_info; | 1897 | struct pl022_config_chip const *chip_info; |
1788 | struct pl022_config_chip chip_info_dt; | ||
1789 | struct chip_data *chip; | 1898 | struct chip_data *chip; |
1790 | struct ssp_clock_params clk_freq = { .cpsdvsr = 0, .scr = 0}; | 1899 | struct ssp_clock_params clk_freq = {0, }; |
1791 | int status = 0; | 1900 | int status = 0; |
1792 | struct pl022 *pl022 = spi_master_get_devdata(spi->master); | 1901 | struct pl022 *pl022 = spi_master_get_devdata(spi->master); |
1793 | unsigned int bits = spi->bits_per_word; | 1902 | unsigned int bits = spi->bits_per_word; |
1794 | u32 tmp; | 1903 | u32 tmp; |
1795 | struct device_node *np = spi->dev.of_node; | ||
1796 | 1904 | ||
1797 | if (!spi->max_speed_hz) | 1905 | if (!spi->max_speed_hz) |
1798 | return -EINVAL; | 1906 | return -EINVAL; |
@@ -1815,32 +1923,10 @@ static int pl022_setup(struct spi_device *spi) | |||
1815 | chip_info = spi->controller_data; | 1923 | chip_info = spi->controller_data; |
1816 | 1924 | ||
1817 | if (chip_info == NULL) { | 1925 | if (chip_info == NULL) { |
1818 | if (np) { | 1926 | chip_info = &pl022_default_chip_info; |
1819 | chip_info_dt = pl022_default_chip_info; | 1927 | /* spi_board_info.controller_data not is supplied */ |
1820 | 1928 | dev_dbg(&spi->dev, | |
1821 | chip_info_dt.hierarchy = SSP_MASTER; | 1929 | "using default controller_data settings\n"); |
1822 | of_property_read_u32(np, "pl022,interface", | ||
1823 | &chip_info_dt.iface); | ||
1824 | of_property_read_u32(np, "pl022,com-mode", | ||
1825 | &chip_info_dt.com_mode); | ||
1826 | of_property_read_u32(np, "pl022,rx-level-trig", | ||
1827 | &chip_info_dt.rx_lev_trig); | ||
1828 | of_property_read_u32(np, "pl022,tx-level-trig", | ||
1829 | &chip_info_dt.tx_lev_trig); | ||
1830 | of_property_read_u32(np, "pl022,ctrl-len", | ||
1831 | &chip_info_dt.ctrl_len); | ||
1832 | of_property_read_u32(np, "pl022,wait-state", | ||
1833 | &chip_info_dt.wait_state); | ||
1834 | of_property_read_u32(np, "pl022,duplex", | ||
1835 | &chip_info_dt.duplex); | ||
1836 | |||
1837 | chip_info = &chip_info_dt; | ||
1838 | } else { | ||
1839 | chip_info = &pl022_default_chip_info; | ||
1840 | /* spi_board_info.controller_data not is supplied */ | ||
1841 | dev_dbg(&spi->dev, | ||
1842 | "using default controller_data settings\n"); | ||
1843 | } | ||
1844 | } else | 1930 | } else |
1845 | dev_dbg(&spi->dev, | 1931 | dev_dbg(&spi->dev, |
1846 | "using user supplied controller_data settings\n"); | 1932 | "using user supplied controller_data settings\n"); |
@@ -1870,6 +1956,7 @@ static int pl022_setup(struct spi_device *spi) | |||
1870 | goto err_config_params; | 1956 | goto err_config_params; |
1871 | } | 1957 | } |
1872 | 1958 | ||
1959 | |||
1873 | status = verify_controller_parameters(pl022, chip_info); | 1960 | status = verify_controller_parameters(pl022, chip_info); |
1874 | if (status) { | 1961 | if (status) { |
1875 | dev_err(&spi->dev, "controller data is incorrect"); | 1962 | dev_err(&spi->dev, "controller data is incorrect"); |
@@ -1883,18 +1970,14 @@ static int pl022_setup(struct spi_device *spi) | |||
1883 | chip->xfer_type = chip_info->com_mode; | 1970 | chip->xfer_type = chip_info->com_mode; |
1884 | if (!chip_info->cs_control) { | 1971 | if (!chip_info->cs_control) { |
1885 | chip->cs_control = null_cs_control; | 1972 | chip->cs_control = null_cs_control; |
1886 | if (!gpio_is_valid(pl022->chipselects[spi->chip_select])) | 1973 | dev_warn(&spi->dev, |
1887 | dev_warn(&spi->dev, | 1974 | "chip select function is NULL for this chip\n"); |
1888 | "invalid chip select\n"); | ||
1889 | } else | 1975 | } else |
1890 | chip->cs_control = chip_info->cs_control; | 1976 | chip->cs_control = chip_info->cs_control; |
1891 | 1977 | ||
1892 | /* Check bits per word with vendor specific range */ | 1978 | if (bits <= 3) { |
1893 | if ((bits <= 3) || (bits > pl022->vendor->max_bpw)) { | 1979 | /* PL022 doesn't support less than 4-bits */ |
1894 | status = -ENOTSUPP; | 1980 | status = -ENOTSUPP; |
1895 | dev_err(&spi->dev, "illegal data size for this controller!\n"); | ||
1896 | dev_err(&spi->dev, "This controller can only handle 4 <= n <= %d bit words\n", | ||
1897 | pl022->vendor->max_bpw); | ||
1898 | goto err_config_params; | 1981 | goto err_config_params; |
1899 | } else if (bits <= 8) { | 1982 | } else if (bits <= 8) { |
1900 | dev_dbg(&spi->dev, "4 <= n <=8 bits per word\n"); | 1983 | dev_dbg(&spi->dev, "4 <= n <=8 bits per word\n"); |
@@ -1907,10 +1990,20 @@ static int pl022_setup(struct spi_device *spi) | |||
1907 | chip->read = READING_U16; | 1990 | chip->read = READING_U16; |
1908 | chip->write = WRITING_U16; | 1991 | chip->write = WRITING_U16; |
1909 | } else { | 1992 | } else { |
1910 | dev_dbg(&spi->dev, "17 <= n <= 32 bits per word\n"); | 1993 | if (pl022->vendor->max_bpw >= 32) { |
1911 | chip->n_bytes = 4; | 1994 | dev_dbg(&spi->dev, "17 <= n <= 32 bits per word\n"); |
1912 | chip->read = READING_U32; | 1995 | chip->n_bytes = 4; |
1913 | chip->write = WRITING_U32; | 1996 | chip->read = READING_U32; |
1997 | chip->write = WRITING_U32; | ||
1998 | } else { | ||
1999 | dev_err(&spi->dev, | ||
2000 | "illegal data size for this controller!\n"); | ||
2001 | dev_err(&spi->dev, | ||
2002 | "a standard pl022 can only handle " | ||
2003 | "1 <= n <= 16 bit words\n"); | ||
2004 | status = -ENOTSUPP; | ||
2005 | goto err_config_params; | ||
2006 | } | ||
1914 | } | 2007 | } |
1915 | 2008 | ||
1916 | /* Now Initialize all register settings required for this chip */ | 2009 | /* Now Initialize all register settings required for this chip */ |
@@ -2003,8 +2096,7 @@ static int pl022_setup(struct spi_device *spi) | |||
2003 | } | 2096 | } |
2004 | SSP_WRITE_BITS(chip->cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1); | 2097 | SSP_WRITE_BITS(chip->cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1); |
2005 | SSP_WRITE_BITS(chip->cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2); | 2098 | SSP_WRITE_BITS(chip->cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2); |
2006 | SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD, | 2099 | SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD, 3); |
2007 | 3); | ||
2008 | 2100 | ||
2009 | /* Save controller_state */ | 2101 | /* Save controller_state */ |
2010 | spi_set_ctldata(spi, chip); | 2102 | spi_set_ctldata(spi, chip); |
@@ -2030,65 +2122,30 @@ static void pl022_cleanup(struct spi_device *spi) | |||
2030 | kfree(chip); | 2122 | kfree(chip); |
2031 | } | 2123 | } |
2032 | 2124 | ||
2033 | static struct pl022_ssp_controller * | ||
2034 | pl022_platform_data_dt_get(struct device *dev) | ||
2035 | { | ||
2036 | struct device_node *np = dev->of_node; | ||
2037 | struct pl022_ssp_controller *pd; | ||
2038 | u32 tmp; | ||
2039 | |||
2040 | if (!np) { | ||
2041 | dev_err(dev, "no dt node defined\n"); | ||
2042 | return NULL; | ||
2043 | } | ||
2044 | |||
2045 | pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL); | ||
2046 | if (!pd) { | ||
2047 | dev_err(dev, "cannot allocate platform data memory\n"); | ||
2048 | return NULL; | ||
2049 | } | ||
2050 | |||
2051 | pd->bus_id = -1; | ||
2052 | of_property_read_u32(np, "num-cs", &tmp); | ||
2053 | pd->num_chipselect = tmp; | ||
2054 | of_property_read_u32(np, "pl022,autosuspend-delay", | ||
2055 | &pd->autosuspend_delay); | ||
2056 | pd->rt = of_property_read_bool(np, "pl022,rt"); | ||
2057 | |||
2058 | return pd; | ||
2059 | } | ||
2060 | 2125 | ||
2061 | static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | 2126 | static int __devinit |
2127 | pl022_probe(struct amba_device *adev, const struct amba_id *id) | ||
2062 | { | 2128 | { |
2063 | struct device *dev = &adev->dev; | 2129 | struct device *dev = &adev->dev; |
2064 | struct pl022_ssp_controller *platform_info = adev->dev.platform_data; | 2130 | struct pl022_ssp_controller *platform_info = adev->dev.platform_data; |
2065 | struct spi_master *master; | 2131 | struct spi_master *master; |
2066 | struct pl022 *pl022 = NULL; /*Data for this driver */ | 2132 | struct pl022 *pl022 = NULL; /*Data for this driver */ |
2067 | struct device_node *np = adev->dev.of_node; | 2133 | int status = 0; |
2068 | int status = 0, i, num_cs; | ||
2069 | 2134 | ||
2070 | dev_info(&adev->dev, | 2135 | dev_info(&adev->dev, |
2071 | "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid); | 2136 | "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid); |
2072 | if (!platform_info && IS_ENABLED(CONFIG_OF)) | 2137 | if (platform_info == NULL) { |
2073 | platform_info = pl022_platform_data_dt_get(dev); | 2138 | dev_err(&adev->dev, "probe - no platform data supplied\n"); |
2074 | 2139 | status = -ENODEV; | |
2075 | if (!platform_info) { | 2140 | goto err_no_pdata; |
2076 | dev_err(dev, "probe: no platform data defined\n"); | ||
2077 | return -ENODEV; | ||
2078 | } | ||
2079 | |||
2080 | if (platform_info->num_chipselect) { | ||
2081 | num_cs = platform_info->num_chipselect; | ||
2082 | } else { | ||
2083 | dev_err(dev, "probe: no chip select defined\n"); | ||
2084 | return -ENODEV; | ||
2085 | } | 2141 | } |
2086 | 2142 | ||
2087 | /* Allocate master with space for data */ | 2143 | /* Allocate master with space for data */ |
2088 | master = spi_alloc_master(dev, sizeof(struct pl022)); | 2144 | master = spi_alloc_master(dev, sizeof(struct pl022)); |
2089 | if (master == NULL) { | 2145 | if (master == NULL) { |
2090 | dev_err(&adev->dev, "probe - cannot alloc SPI master\n"); | 2146 | dev_err(&adev->dev, "probe - cannot alloc SPI master\n"); |
2091 | return -ENOMEM; | 2147 | status = -ENOMEM; |
2148 | goto err_no_master; | ||
2092 | } | 2149 | } |
2093 | 2150 | ||
2094 | pl022 = spi_master_get_devdata(master); | 2151 | pl022 = spi_master_get_devdata(master); |
@@ -2096,76 +2153,16 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2096 | pl022->master_info = platform_info; | 2153 | pl022->master_info = platform_info; |
2097 | pl022->adev = adev; | 2154 | pl022->adev = adev; |
2098 | pl022->vendor = id->data; | 2155 | pl022->vendor = id->data; |
2099 | pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int), | ||
2100 | GFP_KERNEL); | ||
2101 | |||
2102 | pl022->pinctrl = devm_pinctrl_get(dev); | ||
2103 | if (IS_ERR(pl022->pinctrl)) { | ||
2104 | status = PTR_ERR(pl022->pinctrl); | ||
2105 | goto err_no_pinctrl; | ||
2106 | } | ||
2107 | |||
2108 | pl022->pins_default = pinctrl_lookup_state(pl022->pinctrl, | ||
2109 | PINCTRL_STATE_DEFAULT); | ||
2110 | /* enable pins to be muxed in and configured */ | ||
2111 | if (!IS_ERR(pl022->pins_default)) { | ||
2112 | status = pinctrl_select_state(pl022->pinctrl, | ||
2113 | pl022->pins_default); | ||
2114 | if (status) | ||
2115 | dev_err(dev, "could not set default pins\n"); | ||
2116 | } else | ||
2117 | dev_err(dev, "could not get default pinstate\n"); | ||
2118 | |||
2119 | pl022->pins_idle = pinctrl_lookup_state(pl022->pinctrl, | ||
2120 | PINCTRL_STATE_IDLE); | ||
2121 | if (IS_ERR(pl022->pins_idle)) | ||
2122 | dev_dbg(dev, "could not get idle pinstate\n"); | ||
2123 | |||
2124 | pl022->pins_sleep = pinctrl_lookup_state(pl022->pinctrl, | ||
2125 | PINCTRL_STATE_SLEEP); | ||
2126 | if (IS_ERR(pl022->pins_sleep)) | ||
2127 | dev_dbg(dev, "could not get sleep pinstate\n"); | ||
2128 | 2156 | ||
2129 | /* | 2157 | /* |
2130 | * Bus Number Which has been Assigned to this SSP controller | 2158 | * Bus Number Which has been Assigned to this SSP controller |
2131 | * on this board | 2159 | * on this board |
2132 | */ | 2160 | */ |
2133 | master->bus_num = platform_info->bus_id; | 2161 | master->bus_num = platform_info->bus_id; |
2134 | master->num_chipselect = num_cs; | 2162 | master->num_chipselect = platform_info->num_chipselect; |
2135 | master->cleanup = pl022_cleanup; | 2163 | master->cleanup = pl022_cleanup; |
2136 | master->setup = pl022_setup; | 2164 | master->setup = pl022_setup; |
2137 | master->prepare_transfer_hardware = pl022_prepare_transfer_hardware; | 2165 | master->transfer = pl022_transfer; |
2138 | master->transfer_one_message = pl022_transfer_one_message; | ||
2139 | master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware; | ||
2140 | master->rt = platform_info->rt; | ||
2141 | master->dev.of_node = dev->of_node; | ||
2142 | |||
2143 | if (platform_info->num_chipselect && platform_info->chipselects) { | ||
2144 | for (i = 0; i < num_cs; i++) | ||
2145 | pl022->chipselects[i] = platform_info->chipselects[i]; | ||
2146 | } else if (IS_ENABLED(CONFIG_OF)) { | ||
2147 | for (i = 0; i < num_cs; i++) { | ||
2148 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); | ||
2149 | |||
2150 | if (cs_gpio == -EPROBE_DEFER) { | ||
2151 | status = -EPROBE_DEFER; | ||
2152 | goto err_no_gpio; | ||
2153 | } | ||
2154 | |||
2155 | pl022->chipselects[i] = cs_gpio; | ||
2156 | |||
2157 | if (gpio_is_valid(cs_gpio)) { | ||
2158 | if (devm_gpio_request(dev, cs_gpio, "ssp-pl022")) | ||
2159 | dev_err(&adev->dev, | ||
2160 | "could not request %d gpio\n", | ||
2161 | cs_gpio); | ||
2162 | else if (gpio_direction_output(cs_gpio, 1)) | ||
2163 | dev_err(&adev->dev, | ||
2164 | "could set gpio %d as output\n", | ||
2165 | cs_gpio); | ||
2166 | } | ||
2167 | } | ||
2168 | } | ||
2169 | 2166 | ||
2170 | /* | 2167 | /* |
2171 | * Supports mode 0-3, loopback, and active low CS. Transfers are | 2168 | * Supports mode 0-3, loopback, and active low CS. Transfers are |
@@ -2182,45 +2179,30 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2182 | goto err_no_ioregion; | 2179 | goto err_no_ioregion; |
2183 | 2180 | ||
2184 | pl022->phybase = adev->res.start; | 2181 | pl022->phybase = adev->res.start; |
2185 | pl022->virtbase = devm_ioremap(dev, adev->res.start, | 2182 | pl022->virtbase = ioremap(adev->res.start, resource_size(&adev->res)); |
2186 | resource_size(&adev->res)); | ||
2187 | if (pl022->virtbase == NULL) { | 2183 | if (pl022->virtbase == NULL) { |
2188 | status = -ENOMEM; | 2184 | status = -ENOMEM; |
2189 | goto err_no_ioremap; | 2185 | goto err_no_ioremap; |
2190 | } | 2186 | } |
2191 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", | 2187 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", |
2192 | adev->res.start, pl022->virtbase); | 2188 | adev->res.start, pl022->virtbase); |
2189 | pm_runtime_enable(dev); | ||
2190 | pm_runtime_resume(dev); | ||
2193 | 2191 | ||
2194 | pl022->clk = devm_clk_get(&adev->dev, NULL); | 2192 | pl022->clk = clk_get(&adev->dev, NULL); |
2195 | if (IS_ERR(pl022->clk)) { | 2193 | if (IS_ERR(pl022->clk)) { |
2196 | status = PTR_ERR(pl022->clk); | 2194 | status = PTR_ERR(pl022->clk); |
2197 | dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n"); | 2195 | dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n"); |
2198 | goto err_no_clk; | 2196 | goto err_no_clk; |
2199 | } | 2197 | } |
2200 | 2198 | ||
2201 | status = clk_prepare(pl022->clk); | ||
2202 | if (status) { | ||
2203 | dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n"); | ||
2204 | goto err_clk_prep; | ||
2205 | } | ||
2206 | |||
2207 | status = clk_enable(pl022->clk); | ||
2208 | if (status) { | ||
2209 | dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n"); | ||
2210 | goto err_no_clk_en; | ||
2211 | } | ||
2212 | |||
2213 | /* Initialize transfer pump */ | ||
2214 | tasklet_init(&pl022->pump_transfers, pump_transfers, | ||
2215 | (unsigned long)pl022); | ||
2216 | |||
2217 | /* Disable SSP */ | 2199 | /* Disable SSP */ |
2218 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), | 2200 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), |
2219 | SSP_CR1(pl022->virtbase)); | 2201 | SSP_CR1(pl022->virtbase)); |
2220 | load_ssp_default_config(pl022); | 2202 | load_ssp_default_config(pl022); |
2221 | 2203 | ||
2222 | status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler, | 2204 | status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022", |
2223 | 0, "pl022", pl022); | 2205 | pl022); |
2224 | if (status < 0) { | 2206 | if (status < 0) { |
2225 | dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status); | 2207 | dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status); |
2226 | goto err_no_irq; | 2208 | goto err_no_irq; |
@@ -2233,6 +2215,17 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2233 | platform_info->enable_dma = 0; | 2215 | platform_info->enable_dma = 0; |
2234 | } | 2216 | } |
2235 | 2217 | ||
2218 | /* Initialize and start queue */ | ||
2219 | status = init_queue(pl022); | ||
2220 | if (status != 0) { | ||
2221 | dev_err(&adev->dev, "probe - problem initializing queue\n"); | ||
2222 | goto err_init_queue; | ||
2223 | } | ||
2224 | status = start_queue(pl022); | ||
2225 | if (status != 0) { | ||
2226 | dev_err(&adev->dev, "probe - problem starting queue\n"); | ||
2227 | goto err_start_queue; | ||
2228 | } | ||
2236 | /* Register with the SPI framework */ | 2229 | /* Register with the SPI framework */ |
2237 | amba_set_drvdata(adev, pl022); | 2230 | amba_set_drvdata(adev, pl022); |
2238 | status = spi_register_master(master); | 2231 | status = spi_register_master(master); |
@@ -2242,39 +2235,35 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2242 | goto err_spi_register; | 2235 | goto err_spi_register; |
2243 | } | 2236 | } |
2244 | dev_dbg(dev, "probe succeeded\n"); | 2237 | dev_dbg(dev, "probe succeeded\n"); |
2245 | 2238 | /* | |
2246 | /* let runtime pm put suspend */ | 2239 | * Disable the silicon block pclk and any voltage domain and just |
2247 | if (platform_info->autosuspend_delay > 0) { | 2240 | * power it up and clock it when it's needed |
2248 | dev_info(&adev->dev, | 2241 | */ |
2249 | "will use autosuspend for runtime pm, delay %dms\n", | 2242 | amba_pclk_disable(adev); |
2250 | platform_info->autosuspend_delay); | 2243 | amba_vcore_disable(adev); |
2251 | pm_runtime_set_autosuspend_delay(dev, | ||
2252 | platform_info->autosuspend_delay); | ||
2253 | pm_runtime_use_autosuspend(dev); | ||
2254 | } | ||
2255 | pm_runtime_put(dev); | ||
2256 | |||
2257 | return 0; | 2244 | return 0; |
2258 | 2245 | ||
2259 | err_spi_register: | 2246 | err_spi_register: |
2260 | if (platform_info->enable_dma) | 2247 | err_start_queue: |
2261 | pl022_dma_remove(pl022); | 2248 | err_init_queue: |
2249 | destroy_queue(pl022); | ||
2250 | pl022_dma_remove(pl022); | ||
2251 | free_irq(adev->irq[0], pl022); | ||
2252 | pm_runtime_disable(&adev->dev); | ||
2262 | err_no_irq: | 2253 | err_no_irq: |
2263 | clk_disable(pl022->clk); | 2254 | clk_put(pl022->clk); |
2264 | err_no_clk_en: | ||
2265 | clk_unprepare(pl022->clk); | ||
2266 | err_clk_prep: | ||
2267 | err_no_clk: | 2255 | err_no_clk: |
2256 | iounmap(pl022->virtbase); | ||
2268 | err_no_ioremap: | 2257 | err_no_ioremap: |
2269 | amba_release_regions(adev); | 2258 | amba_release_regions(adev); |
2270 | err_no_ioregion: | 2259 | err_no_ioregion: |
2271 | err_no_gpio: | ||
2272 | err_no_pinctrl: | ||
2273 | spi_master_put(master); | 2260 | spi_master_put(master); |
2261 | err_no_master: | ||
2262 | err_no_pdata: | ||
2274 | return status; | 2263 | return status; |
2275 | } | 2264 | } |
2276 | 2265 | ||
2277 | static int | 2266 | static int __devexit |
2278 | pl022_remove(struct amba_device *adev) | 2267 | pl022_remove(struct amba_device *adev) |
2279 | { | 2268 | { |
2280 | struct pl022 *pl022 = amba_get_drvdata(adev); | 2269 | struct pl022 *pl022 = amba_get_drvdata(adev); |
@@ -2282,137 +2271,63 @@ pl022_remove(struct amba_device *adev) | |||
2282 | if (!pl022) | 2271 | if (!pl022) |
2283 | return 0; | 2272 | return 0; |
2284 | 2273 | ||
2285 | /* | 2274 | /* Remove the queue */ |
2286 | * undo pm_runtime_put() in probe. I assume that we're not | 2275 | if (destroy_queue(pl022) != 0) |
2287 | * accessing the primecell here. | 2276 | dev_err(&adev->dev, "queue remove failed\n"); |
2288 | */ | ||
2289 | pm_runtime_get_noresume(&adev->dev); | ||
2290 | |||
2291 | load_ssp_default_config(pl022); | 2277 | load_ssp_default_config(pl022); |
2292 | if (pl022->master_info->enable_dma) | 2278 | pl022_dma_remove(pl022); |
2293 | pl022_dma_remove(pl022); | 2279 | free_irq(adev->irq[0], pl022); |
2294 | |||
2295 | clk_disable(pl022->clk); | 2280 | clk_disable(pl022->clk); |
2296 | clk_unprepare(pl022->clk); | 2281 | clk_put(pl022->clk); |
2282 | iounmap(pl022->virtbase); | ||
2297 | amba_release_regions(adev); | 2283 | amba_release_regions(adev); |
2298 | tasklet_disable(&pl022->pump_transfers); | 2284 | tasklet_disable(&pl022->pump_transfers); |
2299 | spi_unregister_master(pl022->master); | 2285 | spi_unregister_master(pl022->master); |
2286 | spi_master_put(pl022->master); | ||
2300 | amba_set_drvdata(adev, NULL); | 2287 | amba_set_drvdata(adev, NULL); |
2301 | return 0; | 2288 | return 0; |
2302 | } | 2289 | } |
2303 | 2290 | ||
2304 | #if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME) | 2291 | #ifdef CONFIG_PM |
2305 | /* | 2292 | static int pl022_suspend(struct amba_device *adev, pm_message_t state) |
2306 | * These two functions are used from both suspend/resume and | ||
2307 | * the runtime counterparts to handle external resources like | ||
2308 | * clocks, pins and regulators when going to sleep. | ||
2309 | */ | ||
2310 | static void pl022_suspend_resources(struct pl022 *pl022, bool runtime) | ||
2311 | { | 2293 | { |
2312 | int ret; | 2294 | struct pl022 *pl022 = amba_get_drvdata(adev); |
2313 | struct pinctrl_state *pins_state; | 2295 | int status = 0; |
2314 | |||
2315 | clk_disable(pl022->clk); | ||
2316 | |||
2317 | pins_state = runtime ? pl022->pins_idle : pl022->pins_sleep; | ||
2318 | /* Optionally let pins go into sleep states */ | ||
2319 | if (!IS_ERR(pins_state)) { | ||
2320 | ret = pinctrl_select_state(pl022->pinctrl, pins_state); | ||
2321 | if (ret) | ||
2322 | dev_err(&pl022->adev->dev, "could not set %s pins\n", | ||
2323 | runtime ? "idle" : "sleep"); | ||
2324 | } | ||
2325 | } | ||
2326 | |||
2327 | static void pl022_resume_resources(struct pl022 *pl022, bool runtime) | ||
2328 | { | ||
2329 | int ret; | ||
2330 | |||
2331 | /* Optionaly enable pins to be muxed in and configured */ | ||
2332 | /* First go to the default state */ | ||
2333 | if (!IS_ERR(pl022->pins_default)) { | ||
2334 | ret = pinctrl_select_state(pl022->pinctrl, pl022->pins_default); | ||
2335 | if (ret) | ||
2336 | dev_err(&pl022->adev->dev, | ||
2337 | "could not set default pins\n"); | ||
2338 | } | ||
2339 | |||
2340 | if (!runtime) { | ||
2341 | /* Then let's idle the pins until the next transfer happens */ | ||
2342 | if (!IS_ERR(pl022->pins_idle)) { | ||
2343 | ret = pinctrl_select_state(pl022->pinctrl, | ||
2344 | pl022->pins_idle); | ||
2345 | if (ret) | ||
2346 | dev_err(&pl022->adev->dev, | ||
2347 | "could not set idle pins\n"); | ||
2348 | } | ||
2349 | } | ||
2350 | |||
2351 | clk_enable(pl022->clk); | ||
2352 | } | ||
2353 | #endif | ||
2354 | |||
2355 | #ifdef CONFIG_SUSPEND | ||
2356 | static int pl022_suspend(struct device *dev) | ||
2357 | { | ||
2358 | struct pl022 *pl022 = dev_get_drvdata(dev); | ||
2359 | int ret; | ||
2360 | 2296 | ||
2361 | ret = spi_master_suspend(pl022->master); | 2297 | status = stop_queue(pl022); |
2362 | if (ret) { | 2298 | if (status) { |
2363 | dev_warn(dev, "cannot suspend master\n"); | 2299 | dev_warn(&adev->dev, "suspend cannot stop queue\n"); |
2364 | return ret; | 2300 | return status; |
2365 | } | 2301 | } |
2366 | 2302 | ||
2367 | pm_runtime_get_sync(dev); | 2303 | amba_vcore_enable(adev); |
2368 | pl022_suspend_resources(pl022, false); | 2304 | amba_pclk_enable(adev); |
2369 | 2305 | load_ssp_default_config(pl022); | |
2370 | dev_dbg(dev, "suspended\n"); | 2306 | amba_pclk_disable(adev); |
2307 | amba_vcore_disable(adev); | ||
2308 | dev_dbg(&adev->dev, "suspended\n"); | ||
2371 | return 0; | 2309 | return 0; |
2372 | } | 2310 | } |
2373 | 2311 | ||
2374 | static int pl022_resume(struct device *dev) | 2312 | static int pl022_resume(struct amba_device *adev) |
2375 | { | 2313 | { |
2376 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2314 | struct pl022 *pl022 = amba_get_drvdata(adev); |
2377 | int ret; | 2315 | int status = 0; |
2378 | |||
2379 | pl022_resume_resources(pl022, false); | ||
2380 | pm_runtime_put(dev); | ||
2381 | 2316 | ||
2382 | /* Start the queue running */ | 2317 | /* Start the queue running */ |
2383 | ret = spi_master_resume(pl022->master); | 2318 | status = start_queue(pl022); |
2384 | if (ret) | 2319 | if (status) |
2385 | dev_err(dev, "problem starting queue (%d)\n", ret); | 2320 | dev_err(&adev->dev, "problem starting queue (%d)\n", status); |
2386 | else | 2321 | else |
2387 | dev_dbg(dev, "resumed\n"); | 2322 | dev_dbg(&adev->dev, "resumed\n"); |
2388 | 2323 | ||
2389 | return ret; | 2324 | return status; |
2390 | } | 2325 | } |
2326 | #else | ||
2327 | #define pl022_suspend NULL | ||
2328 | #define pl022_resume NULL | ||
2391 | #endif /* CONFIG_PM */ | 2329 | #endif /* CONFIG_PM */ |
2392 | 2330 | ||
2393 | #ifdef CONFIG_PM_RUNTIME | ||
2394 | static int pl022_runtime_suspend(struct device *dev) | ||
2395 | { | ||
2396 | struct pl022 *pl022 = dev_get_drvdata(dev); | ||
2397 | |||
2398 | pl022_suspend_resources(pl022, true); | ||
2399 | return 0; | ||
2400 | } | ||
2401 | |||
2402 | static int pl022_runtime_resume(struct device *dev) | ||
2403 | { | ||
2404 | struct pl022 *pl022 = dev_get_drvdata(dev); | ||
2405 | |||
2406 | pl022_resume_resources(pl022, true); | ||
2407 | return 0; | ||
2408 | } | ||
2409 | #endif | ||
2410 | |||
2411 | static const struct dev_pm_ops pl022_dev_pm_ops = { | ||
2412 | SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume) | ||
2413 | SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL) | ||
2414 | }; | ||
2415 | |||
2416 | static struct vendor_data vendor_arm = { | 2331 | static struct vendor_data vendor_arm = { |
2417 | .fifodepth = 8, | 2332 | .fifodepth = 8, |
2418 | .max_bpw = 16, | 2333 | .max_bpw = 16, |
@@ -2422,6 +2337,7 @@ static struct vendor_data vendor_arm = { | |||
2422 | .loopback = true, | 2337 | .loopback = true, |
2423 | }; | 2338 | }; |
2424 | 2339 | ||
2340 | |||
2425 | static struct vendor_data vendor_st = { | 2341 | static struct vendor_data vendor_st = { |
2426 | .fifodepth = 32, | 2342 | .fifodepth = 32, |
2427 | .max_bpw = 32, | 2343 | .max_bpw = 32, |
@@ -2440,6 +2356,15 @@ static struct vendor_data vendor_st_pl023 = { | |||
2440 | .loopback = false, | 2356 | .loopback = false, |
2441 | }; | 2357 | }; |
2442 | 2358 | ||
2359 | static struct vendor_data vendor_db5500_pl023 = { | ||
2360 | .fifodepth = 32, | ||
2361 | .max_bpw = 32, | ||
2362 | .unidir = false, | ||
2363 | .extended_cr = true, | ||
2364 | .pl023 = true, | ||
2365 | .loopback = true, | ||
2366 | }; | ||
2367 | |||
2443 | static struct amba_id pl022_ids[] = { | 2368 | static struct amba_id pl022_ids[] = { |
2444 | { | 2369 | { |
2445 | /* | 2370 | /* |
@@ -2467,35 +2392,42 @@ static struct amba_id pl022_ids[] = { | |||
2467 | * and 32 locations deep TX/RX FIFO but no extended | 2392 | * and 32 locations deep TX/RX FIFO but no extended |
2468 | * CR0/CR1 register | 2393 | * CR0/CR1 register |
2469 | */ | 2394 | */ |
2470 | .id = 0x00080023, | 2395 | .id = 0x00080023, |
2396 | .mask = 0xffffffff, | ||
2397 | .data = &vendor_st_pl023, | ||
2398 | }, | ||
2399 | { | ||
2400 | .id = 0x10080023, | ||
2471 | .mask = 0xffffffff, | 2401 | .mask = 0xffffffff, |
2472 | .data = &vendor_st_pl023, | 2402 | .data = &vendor_db5500_pl023, |
2473 | }, | 2403 | }, |
2474 | { 0, 0 }, | 2404 | { 0, 0 }, |
2475 | }; | 2405 | }; |
2476 | 2406 | ||
2477 | MODULE_DEVICE_TABLE(amba, pl022_ids); | ||
2478 | |||
2479 | static struct amba_driver pl022_driver = { | 2407 | static struct amba_driver pl022_driver = { |
2480 | .drv = { | 2408 | .drv = { |
2481 | .name = "ssp-pl022", | 2409 | .name = "ssp-pl022", |
2482 | .pm = &pl022_dev_pm_ops, | ||
2483 | }, | 2410 | }, |
2484 | .id_table = pl022_ids, | 2411 | .id_table = pl022_ids, |
2485 | .probe = pl022_probe, | 2412 | .probe = pl022_probe, |
2486 | .remove = pl022_remove, | 2413 | .remove = __devexit_p(pl022_remove), |
2414 | .suspend = pl022_suspend, | ||
2415 | .resume = pl022_resume, | ||
2487 | }; | 2416 | }; |
2488 | 2417 | ||
2418 | |||
2489 | static int __init pl022_init(void) | 2419 | static int __init pl022_init(void) |
2490 | { | 2420 | { |
2491 | return amba_driver_register(&pl022_driver); | 2421 | return amba_driver_register(&pl022_driver); |
2492 | } | 2422 | } |
2423 | |||
2493 | subsys_initcall(pl022_init); | 2424 | subsys_initcall(pl022_init); |
2494 | 2425 | ||
2495 | static void __exit pl022_exit(void) | 2426 | static void __exit pl022_exit(void) |
2496 | { | 2427 | { |
2497 | amba_driver_unregister(&pl022_driver); | 2428 | amba_driver_unregister(&pl022_driver); |
2498 | } | 2429 | } |
2430 | |||
2499 | module_exit(pl022_exit); | 2431 | module_exit(pl022_exit); |
2500 | 2432 | ||
2501 | MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); | 2433 | MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); |