diff options
| author | Ulf Hansson <ulf.hansson@linaro.org> | 2025-02-05 14:15:52 +0800 |
|---|---|---|
| committer | Ulf Hansson <ulf.hansson@linaro.org> | 2025-02-13 14:47:48 +0100 |
| commit | cd3fa304ba5c93ce57b9b55b3cd893af2be96527 (patch) | |
| tree | fdb6dc1df0ad5a263387c98de43e260118e0ebb4 /drivers/pmdomain/core.c | |
| parent | 184055a9ae2b7b19f6fd6e9c0b7e1edce6930b2f (diff) | |
| download | linux-cd3fa304ba5c93ce57b9b55b3cd893af2be96527.tar.gz linux-cd3fa304ba5c93ce57b9b55b3cd893af2be96527.tar.bz2 linux-cd3fa304ba5c93ce57b9b55b3cd893af2be96527.zip | |
pmdomain: core: Introduce dev_pm_genpd_rpm_always_on()
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@linaro.org>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/1738736156-119203-4-git-send-email-shawn.lin@rock-chips.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/pmdomain/core.c')
| -rw-r--r-- | drivers/pmdomain/core.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c index 6c94137865c9..9b2f28b34bb5 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)) |
