Add runtime and system sleep power management operations to the RZ DMAC driver. This enables proper handling of suspend and resume sequences, including device reset and channel re-initialization, preparing the driver for power state transitions. Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@xxxxxxxxxxxxxx> --- drivers/dma/sh/rz-dmac.c | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index 4ab6076f5499e..d849e313a7f79 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -437,6 +437,24 @@ static int rz_dmac_xfer_desc(struct rz_dmac_chan *chan) * DMA engine operations */ +static int rz_dmac_chan_init_all(struct rz_dmac *dmac) +{ + unsigned int i; + int ret; + + ret = pm_runtime_resume_and_get(dmac->dev); + if (ret < 0) + return ret; + + rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_0_7_COMMON_BASE + DCTRL); + rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_8_15_COMMON_BASE + DCTRL); + + for (i = 0; i < dmac->n_channels; i++) + rz_dmac_ch_writel(&dmac->channels[i], CHCTRL_DEFAULT, CHCTRL, 1); + + return pm_runtime_put_sync(dmac->dev); +} + static int rz_dmac_alloc_chan_resources(struct dma_chan *chan) { struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); @@ -1070,6 +1088,34 @@ static void rz_dmac_remove(struct platform_device *pdev) platform_device_put(dmac->icu.pdev); } +static int rz_dmac_suspend(struct device *dev) +{ + struct rz_dmac *dmac = dev_get_drvdata(dev); + + return reset_control_assert(dmac->rstc); +} + +static int rz_dmac_resume(struct device *dev) +{ + struct rz_dmac *dmac = dev_get_drvdata(dev); + int ret; + + ret = reset_control_deassert(dmac->rstc); + if (ret) + return ret; + + return rz_dmac_chan_init_all(dmac); +} + +static const struct dev_pm_ops rz_dmac_pm_ops = { + /* + * TODO for system sleep/resume: + * - Wait for the current transfer to complete and stop the device, + * - Resume transfers, if any. + */ + SYSTEM_SLEEP_PM_OPS(rz_dmac_suspend, rz_dmac_resume) +}; + static const struct of_device_id of_rz_dmac_match[] = { { .compatible = "renesas,r9a09g057-dmac", }, { .compatible = "renesas,rz-dmac", }, @@ -1079,6 +1125,7 @@ MODULE_DEVICE_TABLE(of, of_rz_dmac_match); static struct platform_driver rz_dmac_driver = { .driver = { + .pm = pm_sleep_ptr(&rz_dmac_pm_ops), .name = "rz-dmac", .of_match_table = of_rz_dmac_match, }, -- 2.43.0