aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-07-28 09:47:02 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:05:53 -0400
commit5a42f567433f9b870f98049b73f5a76d77c97aa0 (patch)
tree5f97baa0d2ecadc512558ebb0e477127c636aaad
parentf09cb87e6cab90b9345eb7eb4a91277f6b903969 (diff)
spi: Provide core support for runtime PM during transfers
Most SPI drivers that implement runtime PM support use identical code to do so: they acquire a runtime PM lock in prepare_transfer_hardware() and then they release it in unprepare_transfer_hardware(). The variations in this are mostly missing error checking and the choice to use autosuspend. Since these runtime PM calls are normally the only thing in the prepare and unprepare callbacks and the autosuspend API transparently does the right thing on devices with autosuspend disabled factor all of this out into the core with a flag to enable the behaviour. Signed-off-by: Mark Brown <broonie@linaro.org> Reviewed-by: Stephen Warren <swarren@nvidia.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Huang Shijie <b32955@freescale.com>
-rw-r--r--drivers/spi/spi.c16
-rw-r--r--include/linux/spi/spi.h5
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index e380e79e57cc..7b8f59e6ccab 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -553,6 +553,10 @@ static void spi_pump_messages(struct kthread_work *work)
553 master->unprepare_transfer_hardware(master)) 553 master->unprepare_transfer_hardware(master))
554 dev_err(&master->dev, 554 dev_err(&master->dev,
555 "failed to unprepare transfer hardware\n"); 555 "failed to unprepare transfer hardware\n");
556 if (master->auto_runtime_pm) {
557 pm_runtime_mark_last_busy(master->dev.parent);
558 pm_runtime_put_autosuspend(master->dev.parent);
559 }
556 return; 560 return;
557 } 561 }
558 562
@@ -572,11 +576,23 @@ static void spi_pump_messages(struct kthread_work *work)
572 master->busy = true; 576 master->busy = true;
573 spin_unlock_irqrestore(&master->queue_lock, flags); 577 spin_unlock_irqrestore(&master->queue_lock, flags);
574 578
579 if (!was_busy && master->auto_runtime_pm) {
580 ret = pm_runtime_get_sync(master->dev.parent);
581 if (ret < 0) {
582 dev_err(&master->dev, "Failed to power device: %d\n",
583 ret);
584 return;
585 }
586 }
587
575 if (!was_busy && master->prepare_transfer_hardware) { 588 if (!was_busy && master->prepare_transfer_hardware) {
576 ret = master->prepare_transfer_hardware(master); 589 ret = master->prepare_transfer_hardware(master);
577 if (ret) { 590 if (ret) {
578 dev_err(&master->dev, 591 dev_err(&master->dev,
579 "failed to prepare transfer hardware\n"); 592 "failed to prepare transfer hardware\n");
593
594 if (master->auto_runtime_pm)
595 pm_runtime_put(master->dev.parent);
580 return; 596 return;
581 } 597 }
582 } 598 }
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index be40c977df07..c28ac127ef3d 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -256,6 +256,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
256 * @busy: message pump is busy 256 * @busy: message pump is busy
257 * @running: message pump is running 257 * @running: message pump is running
258 * @rt: whether this queue is set to run as a realtime task 258 * @rt: whether this queue is set to run as a realtime task
259 * @auto_runtime_pm: the core should ensure a runtime PM reference is held
260 * while the hardware is prepared, using the parent
261 * device for the spidev
259 * @prepare_transfer_hardware: a message will soon arrive from the queue 262 * @prepare_transfer_hardware: a message will soon arrive from the queue
260 * so the subsystem requests the driver to prepare the transfer hardware 263 * so the subsystem requests the driver to prepare the transfer hardware
261 * by issuing this call 264 * by issuing this call
@@ -380,11 +383,13 @@ struct spi_master {
380 bool busy; 383 bool busy;
381 bool running; 384 bool running;
382 bool rt; 385 bool rt;
386 bool auto_runtime_pm;
383 387
384 int (*prepare_transfer_hardware)(struct spi_master *master); 388 int (*prepare_transfer_hardware)(struct spi_master *master);
385 int (*transfer_one_message)(struct spi_master *master, 389 int (*transfer_one_message)(struct spi_master *master,
386 struct spi_message *mesg); 390 struct spi_message *mesg);
387 int (*unprepare_transfer_hardware)(struct spi_master *master); 391 int (*unprepare_transfer_hardware)(struct spi_master *master);
392
388 /* gpio chip select */ 393 /* gpio chip select */
389 int *cs_gpios; 394 int *cs_gpios;
390}; 395};