On Wed, Feb 05, 2025 at 02:15:52PM +0800, Shawn Lin wrote: > From: Ulf Hansson <ulf.hansson@xxxxxxxxxx> > > For some usecases a consumer driver requires its device to remain power-on > from the PM domain perspective during runtime. Using dev PM qos along with > the genpd governors, doesn't work for this case as would potentially > prevent the device from being runtime suspended too. > > To support these usecases, let's introduce dev_pm_genpd_rpm_always_on() to > allow consumers drivers to dynamically control the behaviour in genpd for a > device that is attached to it. > > Signed-off-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx> > Signed-off-by: Shawn Lin <shawn.lin@xxxxxxxxxxxxxx> Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> - Mani > --- > > Changes in v7: None > Changes in v6: > - export dev_pm_genpd_rpm_always_on() > > Changes in v5: None > Changes in v4: None > Changes in v3: None > Changes in v2: None > > drivers/pmdomain/core.c | 35 +++++++++++++++++++++++++++++++++++ > include/linux/pm_domain.h | 7 +++++++ > 2 files changed, 42 insertions(+) > > diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c > index 6c94137..9b2f28b 100644 > --- a/drivers/pmdomain/core.c > +++ b/drivers/pmdomain/core.c > @@ -697,6 +697,37 @@ bool dev_pm_genpd_get_hwmode(struct device *dev) > } > EXPORT_SYMBOL_GPL(dev_pm_genpd_get_hwmode); > > +/** > + * dev_pm_genpd_rpm_always_on() - Control if the PM domain can be powered off. > + * > + * @dev: Device for which the PM domain may need to stay on for. > + * @on: Value to set or unset for the condition. > + * > + * For some usecases a consumer driver requires its device to remain power-on > + * from the PM domain perspective during runtime. This function allows the > + * behaviour to be dynamically controlled for a device attached to a genpd. > + * > + * It is assumed that the users guarantee that the genpd wouldn't be detached > + * while this routine is getting called. > + * > + * Return: Returns 0 on success and negative error values on failures. > + */ > +int dev_pm_genpd_rpm_always_on(struct device *dev, bool on) > +{ > + struct generic_pm_domain *genpd; > + > + genpd = dev_to_genpd_safe(dev); > + if (!genpd) > + return -ENODEV; > + > + genpd_lock(genpd); > + dev_gpd_data(dev)->rpm_always_on = on; > + genpd_unlock(genpd); > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(dev_pm_genpd_rpm_always_on); > + > static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) > { > unsigned int state_idx = genpd->state_idx; > @@ -868,6 +899,10 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, > if (!pm_runtime_suspended(pdd->dev) || > irq_safe_dev_in_sleep_domain(pdd->dev, genpd)) > not_suspended++; > + > + /* The device may need its PM domain to stay powered on. */ > + if (to_gpd_data(pdd)->rpm_always_on) > + return -EBUSY; > } > > if (not_suspended > 1 || (not_suspended == 1 && !one_dev_on)) > diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h > index 1aab313..d56a78a 100644 > --- a/include/linux/pm_domain.h > +++ b/include/linux/pm_domain.h > @@ -261,6 +261,7 @@ struct generic_pm_domain_data { > unsigned int rpm_pstate; > unsigned int opp_token; > bool hw_mode; > + bool rpm_always_on; > void *data; > }; > > @@ -293,6 +294,7 @@ ktime_t dev_pm_genpd_get_next_hrtimer(struct device *dev); > void dev_pm_genpd_synced_poweroff(struct device *dev); > int dev_pm_genpd_set_hwmode(struct device *dev, bool enable); > bool dev_pm_genpd_get_hwmode(struct device *dev); > +int dev_pm_genpd_rpm_always_on(struct device *dev, bool on); > > extern struct dev_power_governor simple_qos_governor; > extern struct dev_power_governor pm_domain_always_on_gov; > @@ -376,6 +378,11 @@ static inline bool dev_pm_genpd_get_hwmode(struct device *dev) > return false; > } > > +static inline int dev_pm_genpd_rpm_always_on(struct device *dev, bool on) > +{ > + return -EOPNOTSUPP; > +} > + > #define simple_qos_governor (*(struct dev_power_governor *)(NULL)) > #define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL)) > #endif > -- > 2.7.4 > -- மணிவண்ணன் சதாசிவம்