aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 978dda2c5239..361cced68069 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 28e440be1c07..bf0204c00053 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -254,6 +254,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
254 * @busy: message pump is busy 254 * @busy: message pump is busy
255 * @running: message pump is running 255 * @running: message pump is running
256 * @rt: whether this queue is set to run as a realtime task 256 * @rt: whether this queue is set to run as a realtime task
257 * @auto_runtime_pm: the core should ensure a runtime PM reference is held
258 * while the hardware is prepared, using the parent
259 * device for the spidev
257 * @prepare_transfer_hardware: a message will soon arrive from the queue 260 * @prepare_transfer_hardware: a message will soon arrive from the queue
258 * so the subsystem requests the driver to prepare the transfer hardware 261 * so the subsystem requests the driver to prepare the transfer hardware
259 * by issuing this call 262 * by issuing this call
@@ -374,11 +377,13 @@ struct spi_master {
374 bool busy; 377 bool busy;
375 bool running; 378 bool running;
376 bool rt; 379 bool rt;
380 bool auto_runtime_pm;
377 381
378 int (*prepare_transfer_hardware)(struct spi_master *master); 382 int (*prepare_transfer_hardware)(struct spi_master *master);
379 int (*transfer_one_message)(struct spi_master *master, 383 int (*transfer_one_message)(struct spi_master *master,
380 struct spi_message *mesg); 384 struct spi_message *mesg);
381 int (*unprepare_transfer_hardware)(struct spi_master *master); 385 int (*unprepare_transfer_hardware)(struct spi_master *master);
386
382 /* gpio chip select */ 387 /* gpio chip select */
383 int *cs_gpios; 388 int *cs_gpios;
384}; 389};