Message ID | 1375022606-7576-1-git-send-email-broonie@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Sun, Jul 28, 2013 at 4:43 PM, Mark Brown <broonie@kernel.org> wrote: > 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> Acked-by: Linus Walleij <linus.walleij@linaro.org> > + * @auto_runtime_pm: the core should ensure a runtime PM reference is held > + * while the hardware is prepared I'd mention here that the reference is taken on the parent device of the SPI master, i.e. the very platform or AMBA device, so that it will hit upwards to the bus. Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sun, Jul 28, 2013 at 10:51:31PM +0200, Linus Walleij wrote: > On Sun, Jul 28, 2013 at 4:43 PM, Mark Brown <broonie@kernel.org> wrote: > > + * @auto_runtime_pm: the core should ensure a runtime PM reference is held > > + * while the hardware is prepared > I'd mention here that the reference is taken on the parent > device of the SPI master, i.e. the very platform or AMBA > device, so that it will hit upwards to the bus. Yeah, I was actually contemplating changing that to use the spidev though I think I'm going to stich with what's there. On the one hand runtime PM does do the right thing with children but really the way it's set up at the minute is more obvious for users.
On 07/28/2013 08:43 AM, Mark Brown wrote: > From: Mark Brown <broonie@linaro.org> > > 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. Patch 1, 9, 10, 11, Reviewed-by: Stephen Warren <swarren@nvidia.com> -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 46c3f56..61f71b9 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -553,6 +553,10 @@ static void spi_pump_messages(struct kthread_work *work) master->unprepare_transfer_hardware(master)) dev_err(&master->dev, "failed to unprepare transfer hardware\n"); + if (master->auto_runtime_pm) { + pm_runtime_mark_last_busy(master->dev.parent); + pm_runtime_put_autosuspend(master->dev.parent); + } return; } @@ -572,11 +576,23 @@ static void spi_pump_messages(struct kthread_work *work) master->busy = true; spin_unlock_irqrestore(&master->queue_lock, flags); + if (!was_busy && master->auto_runtime_pm) { + ret = pm_runtime_get_sync(master->dev.parent); + if (ret < 0) { + dev_err(&master->dev, "Failed to power device: %d\n", + ret); + return; + } + } + if (!was_busy && master->prepare_transfer_hardware) { ret = master->prepare_transfer_hardware(master); if (ret) { dev_err(&master->dev, "failed to prepare transfer hardware\n"); + + if (master->auto_runtime_pm) + pm_runtime_put(master->dev.parent); return; } } diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index be40c97..d73059a 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -256,6 +256,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @busy: message pump is busy * @running: message pump is running * @rt: whether this queue is set to run as a realtime task + * @auto_runtime_pm: the core should ensure a runtime PM reference is held + * while the hardware is prepared * @prepare_transfer_hardware: a message will soon arrive from the queue * so the subsystem requests the driver to prepare the transfer hardware * by issuing this call @@ -380,11 +382,13 @@ struct spi_master { bool busy; bool running; bool rt; + bool auto_runtime_pm; int (*prepare_transfer_hardware)(struct spi_master *master); int (*transfer_one_message)(struct spi_master *master, struct spi_message *mesg); int (*unprepare_transfer_hardware)(struct spi_master *master); + /* gpio chip select */ int *cs_gpios; };