spi: lpspi: enable runtime pm for lpspi
Subsystems (2)
PATCH 1/1 spi: lpspi: enable runtime pm for lpspi
From: Han Xu <[email protected]>
Enable the runtime power management for lpspi module.
--- drivers/spi/spi-fsl-lpspi.c | 117 ++++++++++++++++++++++++++++-------- 1 file changed, 92 insertions(+), 25 deletions(-)
drivers/spi/spi-fsl-lpspi.c +92 -25
@@ -16,7 +16,9 @@#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> +#include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/spi/spi.h> #include <linux/spi/spi_bitbang.h>
@@ -24,6 +26,8 @@#define DRIVER_NAME "fsl_lpspi" +#define FSL_LPSPI_RPM_TIMEOUT 50/* 50ms */ +/* i.MX7ULP LPSPI registers */ #define IMX7ULP_VERID 0x0#define IMX7ULP_PARAM 0x4
@@ -150,13 +154,9 @@ static int lpspi_prepare_xfer_hardware(struct spi_controller *controller)spi_controller_get_devdata (controller);int ret; - ret =clk_prepare_enable (fsl_lpspi->clk_ipg); -if (ret) -return ret; - - ret =clk_prepare_enable (fsl_lpspi->clk_per); -if (ret) { -clk_disable_unprepare (fsl_lpspi->clk_ipg); + ret =pm_runtime_get_sync (fsl_lpspi->dev); +if (ret <0 ) { +dev_err (fsl_lpspi->dev,"failed to enable clock\n" );return ret; }
@@ -168,8 +168,8 @@ static int lpspi_unprepare_xfer_hardware(struct spi_controller *controller)struct fsl_lpspi_data *fsl_lpspi =spi_controller_get_devdata (controller); -clk_disable_unprepare (fsl_lpspi->clk_ipg); -clk_disable_unprepare (fsl_lpspi->clk_per); +pm_runtime_mark_last_busy (fsl_lpspi->dev); +pm_runtime_put_autosuspend (fsl_lpspi->dev);return 0 ; }
@@ -476,6 +476,45 @@ static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id)return IRQ_NONE ; } +int fsl_lpspi_runtime_resume (struct device *dev) +{ +struct fsl_lpspi_data *fsl_lpspi =dev_get_drvdata (dev); +int ret; + + ret =clk_prepare_enable (fsl_lpspi->clk_per); +if (ret) +return ret; + + ret =clk_prepare_enable (fsl_lpspi->clk_ipg); +if (ret) { +clk_disable_unprepare (fsl_lpspi->clk_per); +return ret; + } + +return 0 ; +} + +int fsl_lpspi_runtime_suspend (struct device *dev) +{ +struct fsl_lpspi_data *fsl_lpspi =dev_get_drvdata (dev); + +clk_disable_unprepare (fsl_lpspi->clk_per); +clk_disable_unprepare (fsl_lpspi->clk_ipg); + +return 0 ; +} + +static int fsl_lpspi_init_rpm (struct fsl_lpspi_data *fsl_lpspi) +{ +struct device *dev = fsl_lpspi->dev; + +pm_runtime_enable (dev); +pm_runtime_set_autosuspend_delay (dev,FSL_LPSPI_RPM_TIMEOUT ); +pm_runtime_use_autosuspend (dev); + +return 0 ; +} +static int fsl_lpspi_probe (struct platform_device *pdev) {struct fsl_lpspi_data *fsl_lpspi;
@@ -501,6 +540,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev) fsl_lpspi =spi_controller_get_devdata (controller); fsl_lpspi->dev = &pdev->dev; +dev_set_drvdata (&pdev->dev, fsl_lpspi); fsl_lpspi->is_slave =of_property_read_bool ((&pdev->dev)->of_node,"spi-slave" );
@@ -547,28 +587,21 @@ static int fsl_lpspi_probe(struct platform_device *pdev) goto out_controller_put; } - ret =clk_prepare_enable (fsl_lpspi->clk_ipg); -if (ret) { -dev_err (&pdev->dev, -"can't enable lpspi ipg clock, ret=%d\n" , ret); +/* enable the clock */ + ret =fsl_lpspi_init_rpm (fsl_lpspi); +if (ret) goto out_controller_put; - } - ret =clk_prepare_enable (fsl_lpspi->clk_per); -if (ret) { -dev_err (&pdev->dev, -"can't enable lpspi per clock, ret=%d\n" , ret); -clk_disable_unprepare (fsl_lpspi->clk_ipg); - goto out_controller_put; + ret =pm_runtime_get_sync (fsl_lpspi->dev); +if (ret <0 ) { +dev_err (fsl_lpspi->dev,"failed to enable clock\n" ); +return ret; } temp =readl (fsl_lpspi->base +IMX7ULP_PARAM ); fsl_lpspi->txfifosize =1 << (temp &0x0f ); fsl_lpspi->rxfifosize =1 << ((temp >>8 ) &0x0f ); -clk_disable_unprepare (fsl_lpspi->clk_per); -clk_disable_unprepare (fsl_lpspi->clk_ipg); - ret =devm_spi_register_controller (&pdev->dev, controller);if (ret <0 ) {dev_err (&pdev->dev,"spi_register_controller error.\n" );
@@ -589,16 +622,50 @@ static int fsl_lpspi_remove(struct platform_device *pdev)struct fsl_lpspi_data *fsl_lpspi =spi_controller_get_devdata (controller); -clk_disable_unprepare (fsl_lpspi->clk_per); -clk_disable_unprepare (fsl_lpspi->clk_ipg); +pm_runtime_disable (fsl_lpspi->dev); + +spi_master_put (controller); + +return 0 ; +} + +#ifdef CONFIG_PM_SLEEP +static int fsl_lpspi_suspend (struct device *dev) +{ +int ret; + +pinctrl_pm_select_sleep_state (dev); + ret =pm_runtime_force_suspend (dev); +return ret; +} + +static int fsl_lpspi_resume (struct device *dev) +{ +int ret; + + ret =pm_runtime_force_resume (dev); +if (ret) { +dev_err (dev,"Error in resume: %d\n" , ret); +return ret; + } + +pinctrl_pm_select_default_state (dev);return 0 ; } +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops fsl_lpspi_pm_ops = { + SET_RUNTIME_PM_OPS(fsl_lpspi_runtime_suspend, + fsl_lpspi_runtime_resume, NULL) +SET_SYSTEM_SLEEP_PM_OPS (fsl_lpspi_suspend, fsl_lpspi_resume) +};static struct platform_driver fsl_lpspi_driver = { .driver = { .name =DRIVER_NAME , .of_match_table = fsl_lpspi_dt_ids, + .pm = &fsl_lpspi_pm_ops, }, .probe = fsl_lpspi_probe, .remove = fsl_lpspi_remove,
Signature · 1 line
2.17.1
Mark Brown
maintainerQuoted 7 lines · Clark Wang
From: Han Xu <[email protected]>
Enable the runtime power management for lpspi module.
Signed-off-by Han Xu <[email protected]>Reviewed-by Frank Li <[email protected]>---
There's no signed-off-by from you here? These are required, please see submitting-patches.rst.
Quoted 11 lines
-----Original Message-----
From: Mark Brown <[email protected]>
Sent: Tuesday, December 11, 2018 22:28
To: Clark Wang <[email protected]>
Cc: [email protected]; [email protected]
Subject: Re: [PATCH] spi: lpspi: enable runtime pm for lpspiQuoted 2 lines · Clark Wang
From: Han Xu <[email protected]>
Quoted 8 lines
Quoted 5 lines
Enable the runtime power management for lpspi module.
Signed-off-by Han Xu <[email protected]>Reviewed-by Frank Li <[email protected]>---
There's no signed-off-by from you here? These are required, please see
submitting-patches.rst.
Oh, there should have my signed-off-by here. For the big changes with 4.9 in our git branch, I did some adaptation work.
Regards,
Clark Wang