Loading drivers/pmdomain/core.c +35 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)) Loading drivers/pmdomain/rockchip/pm-domains.c +8 −0 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading Loading @@ -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; Loading Loading @@ -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) Loading include/linux/pm_domain.h +7 −0 Original line number Diff line number Diff line Loading @@ -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; }; Loading Loading @@ -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; Loading Loading @@ -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 Loading include/soc/rockchip/rockchip_sip.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
drivers/pmdomain/core.c +35 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)) Loading
drivers/pmdomain/rockchip/pm-domains.c +8 −0 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading Loading @@ -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; Loading Loading @@ -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) Loading
include/linux/pm_domain.h +7 −0 Original line number Diff line number Diff line Loading @@ -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; }; Loading Loading @@ -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; Loading Loading @@ -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 Loading
include/soc/rockchip/rockchip_sip.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading