diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-21 13:32:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-21 13:32:00 -0400 |
commit | 5f0e685f316a1de6d3af8b23eaf46651faca32ab (patch) | |
tree | af1ed231b7fcfc65b146be59a0aee699aa9f6353 /drivers/spi/spi-pl022.c | |
parent | f8974cb71310a05632aada76be6a27576d61e609 (diff) | |
parent | 87bf5ab82884c829366914aaa813cc8b07b9fe58 (diff) |
Merge tag 'spi-for-linus' of git://git.secretlab.ca/git/linux-2.6
Pull SPI changes for v3.4 from Grant Likely:
"Mostly a bunch of new drivers and driver bug fixes; but this also
includes a few patches that create a core message queue infrastructure
for the spi subsystem instead of making each driver open code it."
* tag 'spi-for-linus' of git://git.secretlab.ca/git/linux-2.6: (34 commits)
spi/fsl-espi: Make sure pm is within 2..32
spi/fsl-espi: make the clock computation easier to read
spi: sh-hspi: modify write/read method
spi: sh-hspi: control spi clock more correctly
spi: sh-hspi: convert to using core message queue
spi: s3c64xx: Fix build
spi: s3c64xx: remove unnecessary callback msg->complete
spi: remove redundant variable assignment
spi: release lock on error path in spi_pump_messages()
spi: Compatibility with direction which is used in samsung DMA operation
spi-topcliff-pch: add recovery processing in case wait-event timeout
spi-topcliff-pch: supports a spi mode setup and bit order setup by IO control
spi-topcliff-pch: Fix issue for transmitting over 4KByte
spi-topcliff-pch: Modify pci-bus number dynamically to get DMA device info
spi/imx: simplify error handling to free gpios
spi: Convert to DEFINE_PCI_DEVICE_TABLE
spi: add Broadcom BCM63xx SPI controller driver
SPI: add CSR SiRFprimaII SPI controller driver
spi-topcliff-pch: fix -Wuninitialized warning
spi: Mark spi_register_board_info() __devinit
...
Diffstat (limited to 'drivers/spi/spi-pl022.c')
-rw-r--r-- | drivers/spi/spi-pl022.c | 286 |
1 files changed, 57 insertions, 229 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index f37ad2271ad5..dc8485d1e883 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -29,7 +29,6 @@ | |||
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> | ||
33 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
34 | #include <linux/clk.h> | 33 | #include <linux/clk.h> |
35 | #include <linux/err.h> | 34 | #include <linux/err.h> |
@@ -330,12 +329,13 @@ struct vendor_data { | |||
330 | * @clk: outgoing clock "SPICLK" for the SPI bus | 329 | * @clk: outgoing clock "SPICLK" for the SPI bus |
331 | * @master: SPI framework hookup | 330 | * @master: SPI framework hookup |
332 | * @master_info: controller-specific data from machine setup | 331 | * @master_info: controller-specific data from machine setup |
333 | * @workqueue: a workqueue on which any spi_message request is queued | 332 | * @kworker: thread struct for message pump |
334 | * @pump_messages: work struct for scheduling work to the workqueue | 333 | * @kworker_task: pointer to task for message pump kworker thread |
334 | * @pump_messages: work struct for scheduling work to the message pump | ||
335 | * @queue_lock: spinlock to syncronise access to message queue | 335 | * @queue_lock: spinlock to syncronise access to message queue |
336 | * @queue: message queue | 336 | * @queue: message queue |
337 | * @busy: workqueue is busy | 337 | * @busy: message pump is busy |
338 | * @running: workqueue is running | 338 | * @running: message pump is running |
339 | * @pump_transfers: Tasklet used in Interrupt Transfer mode | 339 | * @pump_transfers: Tasklet used in Interrupt Transfer mode |
340 | * @cur_msg: Pointer to current spi_message being processed | 340 | * @cur_msg: Pointer to current spi_message being processed |
341 | * @cur_transfer: Pointer to current spi_transfer | 341 | * @cur_transfer: Pointer to current spi_transfer |
@@ -365,14 +365,7 @@ struct pl022 { | |||
365 | struct clk *clk; | 365 | struct clk *clk; |
366 | struct spi_master *master; | 366 | struct spi_master *master; |
367 | struct pl022_ssp_controller *master_info; | 367 | struct pl022_ssp_controller *master_info; |
368 | /* Driver message queue */ | 368 | /* Message per-transfer pump */ |
369 | struct workqueue_struct *workqueue; | ||
370 | struct work_struct pump_messages; | ||
371 | spinlock_t queue_lock; | ||
372 | struct list_head queue; | ||
373 | bool busy; | ||
374 | bool running; | ||
375 | /* Message transfer pump */ | ||
376 | struct tasklet_struct pump_transfers; | 369 | struct tasklet_struct pump_transfers; |
377 | struct spi_message *cur_msg; | 370 | struct spi_message *cur_msg; |
378 | struct spi_transfer *cur_transfer; | 371 | struct spi_transfer *cur_transfer; |
@@ -394,6 +387,7 @@ struct pl022 { | |||
394 | struct sg_table sgt_rx; | 387 | struct sg_table sgt_rx; |
395 | struct sg_table sgt_tx; | 388 | struct sg_table sgt_tx; |
396 | char *dummypage; | 389 | char *dummypage; |
390 | bool dma_running; | ||
397 | #endif | 391 | #endif |
398 | }; | 392 | }; |
399 | 393 | ||
@@ -448,8 +442,6 @@ static void null_cs_control(u32 command) | |||
448 | static void giveback(struct pl022 *pl022) | 442 | static void giveback(struct pl022 *pl022) |
449 | { | 443 | { |
450 | struct spi_transfer *last_transfer; | 444 | struct spi_transfer *last_transfer; |
451 | unsigned long flags; | ||
452 | struct spi_message *msg; | ||
453 | pl022->next_msg_cs_active = false; | 445 | pl022->next_msg_cs_active = false; |
454 | 446 | ||
455 | last_transfer = list_entry(pl022->cur_msg->transfers.prev, | 447 | last_transfer = list_entry(pl022->cur_msg->transfers.prev, |
@@ -477,15 +469,8 @@ static void giveback(struct pl022 *pl022) | |||
477 | * sent the current message could be unloaded, which | 469 | * sent the current message could be unloaded, which |
478 | * could invalidate the cs_control() callback... | 470 | * could invalidate the cs_control() callback... |
479 | */ | 471 | */ |
480 | |||
481 | /* get a pointer to the next message, if any */ | 472 | /* get a pointer to the next message, if any */ |
482 | spin_lock_irqsave(&pl022->queue_lock, flags); | 473 | next_msg = spi_get_next_queued_message(pl022->master); |
483 | if (list_empty(&pl022->queue)) | ||
484 | next_msg = NULL; | ||
485 | else | ||
486 | next_msg = list_entry(pl022->queue.next, | ||
487 | struct spi_message, queue); | ||
488 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
489 | 474 | ||
490 | /* | 475 | /* |
491 | * see if the next and current messages point | 476 | * see if the next and current messages point |
@@ -497,19 +482,13 @@ static void giveback(struct pl022 *pl022) | |||
497 | pl022->cur_chip->cs_control(SSP_CHIP_DESELECT); | 482 | pl022->cur_chip->cs_control(SSP_CHIP_DESELECT); |
498 | else | 483 | else |
499 | pl022->next_msg_cs_active = true; | 484 | pl022->next_msg_cs_active = true; |
485 | |||
500 | } | 486 | } |
501 | 487 | ||
502 | spin_lock_irqsave(&pl022->queue_lock, flags); | ||
503 | msg = pl022->cur_msg; | ||
504 | pl022->cur_msg = NULL; | 488 | pl022->cur_msg = NULL; |
505 | pl022->cur_transfer = NULL; | 489 | pl022->cur_transfer = NULL; |
506 | pl022->cur_chip = NULL; | 490 | pl022->cur_chip = NULL; |
507 | queue_work(pl022->workqueue, &pl022->pump_messages); | 491 | spi_finalize_current_message(pl022->master); |
508 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
509 | |||
510 | msg->state = NULL; | ||
511 | if (msg->complete) | ||
512 | msg->complete(msg->context); | ||
513 | } | 492 | } |
514 | 493 | ||
515 | /** | 494 | /** |
@@ -1063,6 +1042,7 @@ static int configure_dma(struct pl022 *pl022) | |||
1063 | dmaengine_submit(txdesc); | 1042 | dmaengine_submit(txdesc); |
1064 | dma_async_issue_pending(rxchan); | 1043 | dma_async_issue_pending(rxchan); |
1065 | dma_async_issue_pending(txchan); | 1044 | dma_async_issue_pending(txchan); |
1045 | pl022->dma_running = true; | ||
1066 | 1046 | ||
1067 | return 0; | 1047 | return 0; |
1068 | 1048 | ||
@@ -1141,11 +1121,12 @@ static void terminate_dma(struct pl022 *pl022) | |||
1141 | dmaengine_terminate_all(rxchan); | 1121 | dmaengine_terminate_all(rxchan); |
1142 | dmaengine_terminate_all(txchan); | 1122 | dmaengine_terminate_all(txchan); |
1143 | unmap_free_dma_scatter(pl022); | 1123 | unmap_free_dma_scatter(pl022); |
1124 | pl022->dma_running = false; | ||
1144 | } | 1125 | } |
1145 | 1126 | ||
1146 | static void pl022_dma_remove(struct pl022 *pl022) | 1127 | static void pl022_dma_remove(struct pl022 *pl022) |
1147 | { | 1128 | { |
1148 | if (pl022->busy) | 1129 | if (pl022->dma_running) |
1149 | terminate_dma(pl022); | 1130 | terminate_dma(pl022); |
1150 | if (pl022->dma_tx_channel) | 1131 | if (pl022->dma_tx_channel) |
1151 | dma_release_channel(pl022->dma_tx_channel); | 1132 | dma_release_channel(pl022->dma_tx_channel); |
@@ -1493,73 +1474,20 @@ out: | |||
1493 | return; | 1474 | return; |
1494 | } | 1475 | } |
1495 | 1476 | ||
1496 | /** | 1477 | static int pl022_transfer_one_message(struct spi_master *master, |
1497 | * pump_messages - Workqueue function which processes spi message queue | 1478 | struct spi_message *msg) |
1498 | * @data: pointer to private data of SSP driver | ||
1499 | * | ||
1500 | * This function checks if there is any spi message in the queue that | ||
1501 | * needs processing and delegate control to appropriate function | ||
1502 | * do_polling_transfer()/do_interrupt_dma_transfer() | ||
1503 | * based on the kind of the transfer | ||
1504 | * | ||
1505 | */ | ||
1506 | static void pump_messages(struct work_struct *work) | ||
1507 | { | 1479 | { |
1508 | struct pl022 *pl022 = | 1480 | struct pl022 *pl022 = spi_master_get_devdata(master); |
1509 | container_of(work, struct pl022, pump_messages); | ||
1510 | unsigned long flags; | ||
1511 | bool was_busy = false; | ||
1512 | |||
1513 | /* Lock queue and check for queue work */ | ||
1514 | spin_lock_irqsave(&pl022->queue_lock, flags); | ||
1515 | if (list_empty(&pl022->queue) || !pl022->running) { | ||
1516 | if (pl022->busy) { | ||
1517 | /* nothing more to do - disable spi/ssp and power off */ | ||
1518 | writew((readw(SSP_CR1(pl022->virtbase)) & | ||
1519 | (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); | ||
1520 | |||
1521 | if (pl022->master_info->autosuspend_delay > 0) { | ||
1522 | pm_runtime_mark_last_busy(&pl022->adev->dev); | ||
1523 | pm_runtime_put_autosuspend(&pl022->adev->dev); | ||
1524 | } else { | ||
1525 | pm_runtime_put(&pl022->adev->dev); | ||
1526 | } | ||
1527 | } | ||
1528 | pl022->busy = false; | ||
1529 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1530 | return; | ||
1531 | } | ||
1532 | |||
1533 | /* Make sure we are not already running a message */ | ||
1534 | if (pl022->cur_msg) { | ||
1535 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1536 | return; | ||
1537 | } | ||
1538 | /* Extract head of queue */ | ||
1539 | pl022->cur_msg = | ||
1540 | list_entry(pl022->queue.next, struct spi_message, queue); | ||
1541 | |||
1542 | list_del_init(&pl022->cur_msg->queue); | ||
1543 | if (pl022->busy) | ||
1544 | was_busy = true; | ||
1545 | else | ||
1546 | pl022->busy = true; | ||
1547 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1548 | 1481 | ||
1549 | /* Initial message state */ | 1482 | /* Initial message state */ |
1550 | pl022->cur_msg->state = STATE_START; | 1483 | pl022->cur_msg = msg; |
1551 | pl022->cur_transfer = list_entry(pl022->cur_msg->transfers.next, | 1484 | msg->state = STATE_START; |
1552 | struct spi_transfer, transfer_list); | 1485 | |
1486 | pl022->cur_transfer = list_entry(msg->transfers.next, | ||
1487 | struct spi_transfer, transfer_list); | ||
1553 | 1488 | ||
1554 | /* Setup the SPI using the per chip configuration */ | 1489 | /* Setup the SPI using the per chip configuration */ |
1555 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); | 1490 | pl022->cur_chip = spi_get_ctldata(msg->spi); |
1556 | if (!was_busy) | ||
1557 | /* | ||
1558 | * We enable the core voltage and clocks here, then the clocks | ||
1559 | * and core will be disabled when this workqueue is run again | ||
1560 | * and there is no more work to be done. | ||
1561 | */ | ||
1562 | pm_runtime_get_sync(&pl022->adev->dev); | ||
1563 | 1491 | ||
1564 | restore_state(pl022); | 1492 | restore_state(pl022); |
1565 | flush(pl022); | 1493 | flush(pl022); |
@@ -1568,95 +1496,37 @@ static void pump_messages(struct work_struct *work) | |||
1568 | do_polling_transfer(pl022); | 1496 | do_polling_transfer(pl022); |
1569 | else | 1497 | else |
1570 | do_interrupt_dma_transfer(pl022); | 1498 | do_interrupt_dma_transfer(pl022); |
1571 | } | ||
1572 | |||
1573 | static int __init init_queue(struct pl022 *pl022) | ||
1574 | { | ||
1575 | INIT_LIST_HEAD(&pl022->queue); | ||
1576 | spin_lock_init(&pl022->queue_lock); | ||
1577 | |||
1578 | pl022->running = false; | ||
1579 | pl022->busy = false; | ||
1580 | |||
1581 | tasklet_init(&pl022->pump_transfers, pump_transfers, | ||
1582 | (unsigned long)pl022); | ||
1583 | |||
1584 | INIT_WORK(&pl022->pump_messages, pump_messages); | ||
1585 | pl022->workqueue = create_singlethread_workqueue( | ||
1586 | dev_name(pl022->master->dev.parent)); | ||
1587 | if (pl022->workqueue == NULL) | ||
1588 | return -EBUSY; | ||
1589 | 1499 | ||
1590 | return 0; | 1500 | return 0; |
1591 | } | 1501 | } |
1592 | 1502 | ||
1593 | static int start_queue(struct pl022 *pl022) | 1503 | static int pl022_prepare_transfer_hardware(struct spi_master *master) |
1594 | { | 1504 | { |
1595 | unsigned long flags; | 1505 | struct pl022 *pl022 = spi_master_get_devdata(master); |
1596 | |||
1597 | spin_lock_irqsave(&pl022->queue_lock, flags); | ||
1598 | |||
1599 | if (pl022->running || pl022->busy) { | ||
1600 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1601 | return -EBUSY; | ||
1602 | } | ||
1603 | |||
1604 | pl022->running = true; | ||
1605 | pl022->cur_msg = NULL; | ||
1606 | pl022->cur_transfer = NULL; | ||
1607 | pl022->cur_chip = NULL; | ||
1608 | pl022->next_msg_cs_active = false; | ||
1609 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1610 | |||
1611 | queue_work(pl022->workqueue, &pl022->pump_messages); | ||
1612 | 1506 | ||
1507 | /* | ||
1508 | * Just make sure we have all we need to run the transfer by syncing | ||
1509 | * with the runtime PM framework. | ||
1510 | */ | ||
1511 | pm_runtime_get_sync(&pl022->adev->dev); | ||
1613 | return 0; | 1512 | return 0; |
1614 | } | 1513 | } |
1615 | 1514 | ||
1616 | static int stop_queue(struct pl022 *pl022) | 1515 | static int pl022_unprepare_transfer_hardware(struct spi_master *master) |
1617 | { | 1516 | { |
1618 | unsigned long flags; | 1517 | struct pl022 *pl022 = spi_master_get_devdata(master); |
1619 | unsigned limit = 500; | ||
1620 | int status = 0; | ||
1621 | 1518 | ||
1622 | spin_lock_irqsave(&pl022->queue_lock, flags); | 1519 | /* nothing more to do - disable spi/ssp and power off */ |
1520 | writew((readw(SSP_CR1(pl022->virtbase)) & | ||
1521 | (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); | ||
1623 | 1522 | ||
1624 | /* This is a bit lame, but is optimized for the common execution path. | 1523 | if (pl022->master_info->autosuspend_delay > 0) { |
1625 | * A wait_queue on the pl022->busy could be used, but then the common | 1524 | pm_runtime_mark_last_busy(&pl022->adev->dev); |
1626 | * execution path (pump_messages) would be required to call wake_up or | 1525 | pm_runtime_put_autosuspend(&pl022->adev->dev); |
1627 | * friends on every SPI message. Do this instead */ | 1526 | } else { |
1628 | while ((!list_empty(&pl022->queue) || pl022->busy) && limit--) { | 1527 | pm_runtime_put(&pl022->adev->dev); |
1629 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1630 | msleep(10); | ||
1631 | spin_lock_irqsave(&pl022->queue_lock, flags); | ||
1632 | } | 1528 | } |
1633 | 1529 | ||
1634 | if (!list_empty(&pl022->queue) || pl022->busy) | ||
1635 | status = -EBUSY; | ||
1636 | else | ||
1637 | pl022->running = false; | ||
1638 | |||
1639 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1640 | |||
1641 | return status; | ||
1642 | } | ||
1643 | |||
1644 | static int destroy_queue(struct pl022 *pl022) | ||
1645 | { | ||
1646 | int status; | ||
1647 | |||
1648 | status = stop_queue(pl022); | ||
1649 | /* we are unloading the module or failing to load (only two calls | ||
1650 | * to this routine), and neither call can handle a return value. | ||
1651 | * However, destroy_workqueue calls flush_workqueue, and that will | ||
1652 | * block until all work is done. If the reason that stop_queue | ||
1653 | * timed out is that the work will never finish, then it does no | ||
1654 | * good to call destroy_workqueue, so return anyway. */ | ||
1655 | if (status != 0) | ||
1656 | return status; | ||
1657 | |||
1658 | destroy_workqueue(pl022->workqueue); | ||
1659 | |||
1660 | return 0; | 1530 | return 0; |
1661 | } | 1531 | } |
1662 | 1532 | ||
@@ -1776,38 +1646,6 @@ static int verify_controller_parameters(struct pl022 *pl022, | |||
1776 | return 0; | 1646 | return 0; |
1777 | } | 1647 | } |
1778 | 1648 | ||
1779 | /** | ||
1780 | * pl022_transfer - transfer function registered to SPI master framework | ||
1781 | * @spi: spi device which is requesting transfer | ||
1782 | * @msg: spi message which is to handled is queued to driver queue | ||
1783 | * | ||
1784 | * This function is registered to the SPI framework for this SPI master | ||
1785 | * controller. It will queue the spi_message in the queue of driver if | ||
1786 | * the queue is not stopped and return. | ||
1787 | */ | ||
1788 | static int pl022_transfer(struct spi_device *spi, struct spi_message *msg) | ||
1789 | { | ||
1790 | struct pl022 *pl022 = spi_master_get_devdata(spi->master); | ||
1791 | unsigned long flags; | ||
1792 | |||
1793 | spin_lock_irqsave(&pl022->queue_lock, flags); | ||
1794 | |||
1795 | if (!pl022->running) { | ||
1796 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1797 | return -ESHUTDOWN; | ||
1798 | } | ||
1799 | msg->actual_length = 0; | ||
1800 | msg->status = -EINPROGRESS; | ||
1801 | msg->state = STATE_START; | ||
1802 | |||
1803 | list_add_tail(&msg->queue, &pl022->queue); | ||
1804 | if (pl022->running && !pl022->busy) | ||
1805 | queue_work(pl022->workqueue, &pl022->pump_messages); | ||
1806 | |||
1807 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | ||
1808 | return 0; | ||
1809 | } | ||
1810 | |||
1811 | static inline u32 spi_rate(u32 rate, u16 cpsdvsr, u16 scr) | 1649 | static inline u32 spi_rate(u32 rate, u16 cpsdvsr, u16 scr) |
1812 | { | 1650 | { |
1813 | return rate / (cpsdvsr * (1 + scr)); | 1651 | return rate / (cpsdvsr * (1 + scr)); |
@@ -2170,7 +2008,10 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2170 | master->num_chipselect = platform_info->num_chipselect; | 2008 | master->num_chipselect = platform_info->num_chipselect; |
2171 | master->cleanup = pl022_cleanup; | 2009 | master->cleanup = pl022_cleanup; |
2172 | master->setup = pl022_setup; | 2010 | master->setup = pl022_setup; |
2173 | master->transfer = pl022_transfer; | 2011 | master->prepare_transfer_hardware = pl022_prepare_transfer_hardware; |
2012 | master->transfer_one_message = pl022_transfer_one_message; | ||
2013 | master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware; | ||
2014 | master->rt = platform_info->rt; | ||
2174 | 2015 | ||
2175 | /* | 2016 | /* |
2176 | * Supports mode 0-3, loopback, and active low CS. Transfers are | 2017 | * Supports mode 0-3, loopback, and active low CS. Transfers are |
@@ -2214,6 +2055,10 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2214 | goto err_no_clk_en; | 2055 | goto err_no_clk_en; |
2215 | } | 2056 | } |
2216 | 2057 | ||
2058 | /* Initialize transfer pump */ | ||
2059 | tasklet_init(&pl022->pump_transfers, pump_transfers, | ||
2060 | (unsigned long)pl022); | ||
2061 | |||
2217 | /* Disable SSP */ | 2062 | /* Disable SSP */ |
2218 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), | 2063 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), |
2219 | SSP_CR1(pl022->virtbase)); | 2064 | SSP_CR1(pl022->virtbase)); |
@@ -2233,17 +2078,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2233 | platform_info->enable_dma = 0; | 2078 | platform_info->enable_dma = 0; |
2234 | } | 2079 | } |
2235 | 2080 | ||
2236 | /* Initialize and start queue */ | ||
2237 | status = init_queue(pl022); | ||
2238 | if (status != 0) { | ||
2239 | dev_err(&adev->dev, "probe - problem initializing queue\n"); | ||
2240 | goto err_init_queue; | ||
2241 | } | ||
2242 | status = start_queue(pl022); | ||
2243 | if (status != 0) { | ||
2244 | dev_err(&adev->dev, "probe - problem starting queue\n"); | ||
2245 | goto err_start_queue; | ||
2246 | } | ||
2247 | /* Register with the SPI framework */ | 2081 | /* Register with the SPI framework */ |
2248 | amba_set_drvdata(adev, pl022); | 2082 | amba_set_drvdata(adev, pl022); |
2249 | status = spi_register_master(master); | 2083 | status = spi_register_master(master); |
@@ -2269,9 +2103,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2269 | return 0; | 2103 | return 0; |
2270 | 2104 | ||
2271 | err_spi_register: | 2105 | err_spi_register: |
2272 | err_start_queue: | ||
2273 | err_init_queue: | ||
2274 | destroy_queue(pl022); | ||
2275 | if (platform_info->enable_dma) | 2106 | if (platform_info->enable_dma) |
2276 | pl022_dma_remove(pl022); | 2107 | pl022_dma_remove(pl022); |
2277 | 2108 | ||
@@ -2307,9 +2138,6 @@ pl022_remove(struct amba_device *adev) | |||
2307 | */ | 2138 | */ |
2308 | pm_runtime_get_noresume(&adev->dev); | 2139 | pm_runtime_get_noresume(&adev->dev); |
2309 | 2140 | ||
2310 | /* Remove the queue */ | ||
2311 | if (destroy_queue(pl022) != 0) | ||
2312 | dev_err(&adev->dev, "queue remove failed\n"); | ||
2313 | load_ssp_default_config(pl022); | 2141 | load_ssp_default_config(pl022); |
2314 | if (pl022->master_info->enable_dma) | 2142 | if (pl022->master_info->enable_dma) |
2315 | pl022_dma_remove(pl022); | 2143 | pl022_dma_remove(pl022); |
@@ -2331,12 +2159,12 @@ pl022_remove(struct amba_device *adev) | |||
2331 | static int pl022_suspend(struct device *dev) | 2159 | static int pl022_suspend(struct device *dev) |
2332 | { | 2160 | { |
2333 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2161 | struct pl022 *pl022 = dev_get_drvdata(dev); |
2334 | int status = 0; | 2162 | int ret; |
2335 | 2163 | ||
2336 | status = stop_queue(pl022); | 2164 | ret = spi_master_suspend(pl022->master); |
2337 | if (status) { | 2165 | if (ret) { |
2338 | dev_warn(dev, "suspend cannot stop queue\n"); | 2166 | dev_warn(dev, "cannot suspend master\n"); |
2339 | return status; | 2167 | return ret; |
2340 | } | 2168 | } |
2341 | 2169 | ||
2342 | dev_dbg(dev, "suspended\n"); | 2170 | dev_dbg(dev, "suspended\n"); |
@@ -2346,16 +2174,16 @@ static int pl022_suspend(struct device *dev) | |||
2346 | static int pl022_resume(struct device *dev) | 2174 | static int pl022_resume(struct device *dev) |
2347 | { | 2175 | { |
2348 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2176 | struct pl022 *pl022 = dev_get_drvdata(dev); |
2349 | int status = 0; | 2177 | int ret; |
2350 | 2178 | ||
2351 | /* Start the queue running */ | 2179 | /* Start the queue running */ |
2352 | status = start_queue(pl022); | 2180 | ret = spi_master_resume(pl022->master); |
2353 | if (status) | 2181 | if (ret) |
2354 | dev_err(dev, "problem starting queue (%d)\n", status); | 2182 | dev_err(dev, "problem starting queue (%d)\n", ret); |
2355 | else | 2183 | else |
2356 | dev_dbg(dev, "resumed\n"); | 2184 | dev_dbg(dev, "resumed\n"); |
2357 | 2185 | ||
2358 | return status; | 2186 | return ret; |
2359 | } | 2187 | } |
2360 | #endif /* CONFIG_PM */ | 2188 | #endif /* CONFIG_PM */ |
2361 | 2189 | ||