diff options
Diffstat (limited to 'drivers/spi/spi-pl022.c')
-rw-r--r-- | drivers/spi/spi-pl022.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index b4038f97f6b0..d165c0bfcab5 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -512,8 +512,6 @@ static void giveback(struct pl022 *pl022) | |||
512 | msg->state = NULL; | 512 | msg->state = NULL; |
513 | if (msg->complete) | 513 | if (msg->complete) |
514 | msg->complete(msg->context); | 514 | msg->complete(msg->context); |
515 | /* This message is completed, so let's turn off the clocks & power */ | ||
516 | pm_runtime_put(&pl022->adev->dev); | ||
517 | } | 515 | } |
518 | 516 | ||
519 | /** | 517 | /** |
@@ -1509,14 +1507,18 @@ static void pump_messages(struct work_struct *work) | |||
1509 | struct pl022 *pl022 = | 1507 | struct pl022 *pl022 = |
1510 | container_of(work, struct pl022, pump_messages); | 1508 | container_of(work, struct pl022, pump_messages); |
1511 | unsigned long flags; | 1509 | unsigned long flags; |
1510 | bool was_busy = false; | ||
1512 | 1511 | ||
1513 | /* Lock queue and check for queue work */ | 1512 | /* Lock queue and check for queue work */ |
1514 | spin_lock_irqsave(&pl022->queue_lock, flags); | 1513 | spin_lock_irqsave(&pl022->queue_lock, flags); |
1515 | if (list_empty(&pl022->queue) || !pl022->running) { | 1514 | if (list_empty(&pl022->queue) || !pl022->running) { |
1515 | if (pl022->busy) | ||
1516 | pm_runtime_put(&pl022->adev->dev); | ||
1516 | pl022->busy = false; | 1517 | pl022->busy = false; |
1517 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | 1518 | spin_unlock_irqrestore(&pl022->queue_lock, flags); |
1518 | return; | 1519 | return; |
1519 | } | 1520 | } |
1521 | |||
1520 | /* Make sure we are not already running a message */ | 1522 | /* Make sure we are not already running a message */ |
1521 | if (pl022->cur_msg) { | 1523 | if (pl022->cur_msg) { |
1522 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | 1524 | spin_unlock_irqrestore(&pl022->queue_lock, flags); |
@@ -1527,7 +1529,10 @@ static void pump_messages(struct work_struct *work) | |||
1527 | list_entry(pl022->queue.next, struct spi_message, queue); | 1529 | list_entry(pl022->queue.next, struct spi_message, queue); |
1528 | 1530 | ||
1529 | list_del_init(&pl022->cur_msg->queue); | 1531 | list_del_init(&pl022->cur_msg->queue); |
1530 | pl022->busy = true; | 1532 | if (pl022->busy) |
1533 | was_busy = true; | ||
1534 | else | ||
1535 | pl022->busy = true; | ||
1531 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | 1536 | spin_unlock_irqrestore(&pl022->queue_lock, flags); |
1532 | 1537 | ||
1533 | /* Initial message state */ | 1538 | /* Initial message state */ |
@@ -1537,12 +1542,14 @@ static void pump_messages(struct work_struct *work) | |||
1537 | 1542 | ||
1538 | /* Setup the SPI using the per chip configuration */ | 1543 | /* Setup the SPI using the per chip configuration */ |
1539 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); | 1544 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); |
1540 | /* | 1545 | if (!was_busy) |
1541 | * We enable the core voltage and clocks here, then the clocks | 1546 | /* |
1542 | * and core will be disabled when giveback() is called in each method | 1547 | * We enable the core voltage and clocks here, then the clocks |
1543 | * (poll/interrupt/DMA) | 1548 | * and core will be disabled when this workqueue is run again |
1544 | */ | 1549 | * and there is no more work to be done. |
1545 | pm_runtime_get_sync(&pl022->adev->dev); | 1550 | */ |
1551 | pm_runtime_get_sync(&pl022->adev->dev); | ||
1552 | |||
1546 | restore_state(pl022); | 1553 | restore_state(pl022); |
1547 | flush(pl022); | 1554 | flush(pl022); |
1548 | 1555 | ||