diff options
author | 2025-02-13 14:51:28 +0100 | |
---|---|---|
committer | 2025-02-13 14:51:28 +0100 | |
commit | 7ad91e9c4aff40b5d8ab5bab67b9de9e9f8e6c4f (patch) | |
tree | 2579da49ec0ab830f0b8be1e30a994c8685d2ba0 | |
parent | pmdomain: bcm2835-power: set flag GENPD_FLAG_ACTIVE_WAKEUP (diff) | |
parent | pmdomain: rockchip: Add smc call to inform firmware (diff) | |
download | wireguard-linux-7ad91e9c4aff40b5d8ab5bab67b9de9e9f8e6c4f.tar.xz wireguard-linux-7ad91e9c4aff40b5d8ab5bab67b9de9e9f8e6c4f.zip |
mdomain: Merge branch rockchip into next
Merge the immutable branch rockchip into next, to allow it to be tested
together with the changes that are targeted for v6.15.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r-- | drivers/pmdomain/core.c | 35 | ||||
-rw-r--r-- | drivers/pmdomain/rockchip/pm-domains.c | 8 | ||||
-rw-r--r-- | include/linux/pm_domain.h | 7 | ||||
-rw-r--r-- | include/soc/rockchip/rockchip_sip.h | 3 |
4 files changed, 53 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)) diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c index cb0f93800138..49842f16f33d 100644 --- a/drivers/pmdomain/rockchip/pm-domains.c +++ b/drivers/pmdomain/rockchip/pm-domains.c @@ -5,6 +5,7 @@ * Copyright (c) 2015 ROCKCHIP, Co. Ltd. */ +#include <linux/arm-smccc.h> #include <linux/io.h> #include <linux/iopoll.h> #include <linux/err.h> @@ -20,6 +21,7 @@ #include <linux/regmap.h> #include <linux/mfd/syscon.h> #include <soc/rockchip/pm_domains.h> +#include <soc/rockchip/rockchip_sip.h> #include <dt-bindings/power/px30-power.h> #include <dt-bindings/power/rockchip,rv1126-power.h> #include <dt-bindings/power/rk3036-power.h> @@ -540,6 +542,7 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, struct generic_pm_domain *genpd = &pd->genpd; u32 pd_pwr_offset = pd->info->pwr_offset; bool is_on, is_mem_on = false; + struct arm_smccc_res res; if (pd->info->pwr_mask == 0) return; @@ -567,6 +570,11 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, genpd->name, is_on); return; } + + /* Inform firmware to keep this pd on or off */ + arm_smccc_smc(ROCKCHIP_SIP_SUSPEND_MODE, ROCKCHIP_SLEEP_PD_CONFIG, + pmu->info->pwr_offset + pd_pwr_offset, + pd->info->pwr_mask, on, 0, 0, 0, &res); } static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on) diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 1aab31370065..d56a78af4af1 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 diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h index c46a9ae2a2ab..501ad1fedb20 100644 --- a/include/soc/rockchip/rockchip_sip.h +++ b/include/soc/rockchip/rockchip_sip.h @@ -6,6 +6,9 @@ #ifndef __SOC_ROCKCHIP_SIP_H #define __SOC_ROCKCHIP_SIP_H +#define ROCKCHIP_SIP_SUSPEND_MODE 0x82000003 +#define ROCKCHIP_SLEEP_PD_CONFIG 0xff + #define ROCKCHIP_SIP_DRAM_FREQ 0x82000008 #define ROCKCHIP_SIP_CONFIG_DRAM_INIT 0x00 #define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE 0x01 |