Messages in this thread | | | Subject | Re: [PATCH v5 RESEND] drivers: bus: simple-pm-bus: Use clocks | From | Liu Ying <> | Date | Tue, 10 Jan 2023 11:50:47 +0800 |
| |
On Mon, 2022-12-26 at 11:14 +0800, Liu Ying wrote: > Simple Power-Managed bus controller may need functional clock(s) > to be enabled before child devices connected to the bus can be > accessed. Get the clock(s) as a bulk and enable/disable the > clock(s) when the bus is being power managed. > > One example is that Freescale i.MX8qxp pixel link MSI bus controller > needs MSI clock and AHB clock to be enabled before accessing child > devices. > > Signed-off-by: Liu Ying <victor.liu@nxp.com> > --- > v4->v5: > * Fix build warnings when CONFIG_PM=n by using RUNTIME_PM_OPS, > NOIRQ_SYSTEM_SLEEP_PM_OPS and pm_ptr macros. > * Drop Geert's R-b tag due to the fix. > * Resend based on v6.2-rc1. > > v3->v4: > * Drop unnecessary 'bus == NULL' check from > simple_pm_bus_runtime_{suspend,resume}. > (Geert) > * Add Geert's R-b tag. > > v1->v3: > * No change. > > drivers/bus/simple-pm-bus.c | 46 > +++++++++++++++++++++++++++++++++++++ > 1 file changed, 46 insertions(+)
Gentle ping.
Regards, Liu Ying
> > diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm- > bus.c > index 6b8d6257ed8a..7afe1947e1c0 100644 > --- a/drivers/bus/simple-pm-bus.c > +++ b/drivers/bus/simple-pm-bus.c > @@ -8,17 +8,24 @@ > * for more details. > */ > > +#include <linux/clk.h> > #include <linux/module.h> > #include <linux/of_platform.h> > #include <linux/platform_device.h> > #include <linux/pm_runtime.h> > > +struct simple_pm_bus { > + struct clk_bulk_data *clks; > + int num_clks; > +}; > + > static int simple_pm_bus_probe(struct platform_device *pdev) > { > const struct device *dev = &pdev->dev; > const struct of_dev_auxdata *lookup = dev_get_platdata(dev); > struct device_node *np = dev->of_node; > const struct of_device_id *match; > + struct simple_pm_bus *bus; > > /* > * Allow user to use driver_override to bind this driver to a > @@ -44,6 +51,16 @@ static int simple_pm_bus_probe(struct > platform_device *pdev) > return -ENODEV; > } > > + bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); > + if (!bus) > + return -ENOMEM; > + > + bus->num_clks = devm_clk_bulk_get_all(&pdev->dev, &bus->clks); > + if (bus->num_clks < 0) > + return dev_err_probe(&pdev->dev, bus->num_clks, "failed > to get clocks\n"); > + > + dev_set_drvdata(&pdev->dev, bus); > + > dev_dbg(&pdev->dev, "%s\n", __func__); > > pm_runtime_enable(&pdev->dev); > @@ -67,6 +84,34 @@ static int simple_pm_bus_remove(struct > platform_device *pdev) > return 0; > } > > +static int simple_pm_bus_runtime_suspend(struct device *dev) > +{ > + struct simple_pm_bus *bus = dev_get_drvdata(dev); > + > + clk_bulk_disable_unprepare(bus->num_clks, bus->clks); > + > + return 0; > +} > + > +static int simple_pm_bus_runtime_resume(struct device *dev) > +{ > + struct simple_pm_bus *bus = dev_get_drvdata(dev); > + int ret; > + > + ret = clk_bulk_prepare_enable(bus->num_clks, bus->clks); > + if (ret) { > + dev_err(dev, "failed to enable clocks: %d\n", ret); > + return ret; > + } > + > + return 0; > +} > + > +static const struct dev_pm_ops simple_pm_bus_pm_ops = { > + RUNTIME_PM_OPS(simple_pm_bus_runtime_suspend, > simple_pm_bus_runtime_resume, NULL) > + NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, > pm_runtime_force_resume) > +}; > + > #define ONLY_BUS ((void *) 1) /* Match if the device is only a > bus. */ > > static const struct of_device_id simple_pm_bus_of_match[] = { > @@ -85,6 +130,7 @@ static struct platform_driver simple_pm_bus_driver > = { > .driver = { > .name = "simple-pm-bus", > .of_match_table = simple_pm_bus_of_match, > + .pm = pm_ptr(&simple_pm_bus_pm_ops), > }, > }; >
| |