Loading drivers/thermal/cpu_cooling.c +49 −7 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ struct cpufreq_cooling_device { int dyn_power_table_entries; struct device *cpu_dev; get_static_t plat_get_static_power; struct cpu_cooling_ops *plat_ops; }; static DEFINE_IDR(cpufreq_idr); static DEFINE_MUTEX(cooling_cpufreq_lock); Loading Loading @@ -504,7 +505,12 @@ static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state) { struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; unsigned int cpu = cpumask_any(&cpufreq_device->allowed_cpus); if (cpufreq_device->plat_ops && cpufreq_device->plat_ops->get_cur_state) cpufreq_device->plat_ops->get_cur_state(cpu, state); else *state = cpufreq_device->cpufreq_state; return 0; Loading Loading @@ -539,7 +545,17 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, cpufreq_device->cpufreq_state = state; cpufreq_device->clipped_freq = clip_freq; /* Check if the device has a platform mitigation function that * can handle the CPU freq mitigation, if not, notify cpufreq * framework. */ if (cpufreq_device->plat_ops) { if (cpufreq_device->plat_ops->ceil_limit) cpufreq_device->plat_ops->ceil_limit(cpu, clip_freq); } else { cpufreq_update_policy(cpu); } return 0; } Loading Loading @@ -773,6 +789,9 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table, * @capacitance: dynamic power coefficient for these cpus * @plat_static_func: function to calculate the static power consumed by these * cpus (optional) * @plat_mitig_func: function that does the mitigation by changing the * frequencies (Optional). By default, cpufreq framweork will * be notified of the new limits. * * This interface function registers the cpufreq cooling device with the name * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq Loading @@ -785,7 +804,8 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table, static struct thermal_cooling_device * __cpufreq_cooling_register(struct device_node *np, const struct cpumask *clip_cpus, u32 capacitance, get_static_t plat_static_func) get_static_t plat_static_func, struct cpu_cooling_ops *plat_ops) { struct thermal_cooling_device *cool_dev; struct cpufreq_cooling_device *cpufreq_dev; Loading Loading @@ -851,6 +871,8 @@ __cpufreq_cooling_register(struct device_node *np, } } cpufreq_dev->plat_ops = plat_ops; ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); if (ret) { cool_dev = ERR_PTR(ret); Loading Loading @@ -924,7 +946,7 @@ free_cdev: struct thermal_cooling_device * cpufreq_cooling_register(const struct cpumask *clip_cpus) { return __cpufreq_cooling_register(NULL, clip_cpus, 0, NULL); return __cpufreq_cooling_register(NULL, clip_cpus, 0, NULL, NULL); } EXPORT_SYMBOL_GPL(cpufreq_cooling_register); Loading @@ -948,7 +970,7 @@ of_cpufreq_cooling_register(struct device_node *np, if (!np) return ERR_PTR(-EINVAL); return __cpufreq_cooling_register(np, clip_cpus, 0, NULL); return __cpufreq_cooling_register(np, clip_cpus, 0, NULL, NULL); } EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register); Loading Loading @@ -978,10 +1000,30 @@ cpufreq_power_cooling_register(const struct cpumask *clip_cpus, u32 capacitance, get_static_t plat_static_func) { return __cpufreq_cooling_register(NULL, clip_cpus, capacitance, plat_static_func); plat_static_func, NULL); } EXPORT_SYMBOL(cpufreq_power_cooling_register); /** * cpufreq_platform_cooling_register() - create cpufreq cooling device with * additional platform specific mitigation function. * * @clip_cpus: cpumask of cpus where the frequency constraints will happen * @plat_ops: the platform mitigation functions that will be called insted of * cpufreq, if provided. * * Return: a valid struct thermal_cooling_device pointer on success, * on failure, it returns a corresponding ERR_PTR(). */ struct thermal_cooling_device * cpufreq_platform_cooling_register(const struct cpumask *clip_cpus, struct cpu_cooling_ops *plat_ops) { return __cpufreq_cooling_register(NULL, clip_cpus, 0, NULL, plat_ops); } EXPORT_SYMBOL(cpufreq_platform_cooling_register); /** * of_cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions * @np: a valid struct device_node to the cooling device device tree node Loading Loading @@ -1015,7 +1057,7 @@ of_cpufreq_power_cooling_register(struct device_node *np, return ERR_PTR(-EINVAL); return __cpufreq_cooling_register(np, clip_cpus, capacitance, plat_static_func); plat_static_func, NULL); } EXPORT_SYMBOL(of_cpufreq_power_cooling_register); Loading drivers/thermal/msm_lmh_dcvs.c +57 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <linux/interrupt.h> #include <linux/timer.h> #include <linux/pm_opp.h> #include <linux/cpu_cooling.h> #include <asm/smp_plat.h> #include <asm/cacheflush.h> Loading @@ -40,6 +41,7 @@ #define MSM_LIMITS_NODE_DCVS 0x44435653 #define MSM_LIMITS_SUB_FN_THERMAL 0x54484D4C #define MSM_LIMITS_SUB_FN_GENERAL 0x47454E00 #define MSM_LIMITS_ALGO_MODE_ENABLE 0x454E424C Loading @@ -49,6 +51,8 @@ #define MSM_LIMITS_CLUSTER_0 0x6370302D #define MSM_LIMITS_CLUSTER_1 0x6370312D #define MSM_LIMITS_DOMAIN_MAX 0x444D4158 #define MSM_LIMITS_HIGH_THRESHOLD_VAL 95000 #define MSM_LIMITS_ARM_THRESHOLD_VAL 65000 #define MSM_LIMITS_POLLING_DELAY_MS 10 Loading Loading @@ -77,8 +81,12 @@ struct msm_lmh_dcvs_hw { cpumask_t core_map; struct timer_list poll_timer; uint32_t max_freq; uint32_t hw_freq_limit; struct list_head list; }; LIST_HEAD(lmh_dcvs_hw_list); static void msm_lmh_dcvs_get_max_freq(uint32_t cpu, uint32_t *max_freq) { unsigned long freq_ceil = UINT_MAX; Loading @@ -104,6 +112,7 @@ static uint32_t msm_lmh_mitigation_notify(struct msm_lmh_dcvs_hw *hw) dcvsh_get_frequency(val, max_limit); sched_update_cpu_freq_min_max(&hw->core_map, 0, max_limit); trace_lmh_dcvs_freq(cpumask_first(&hw->core_map), max_limit); hw->hw_freq_limit = max_limit; return max_limit; } Loading Loading @@ -250,6 +259,45 @@ static int trip_notify(enum thermal_trip_type type, int temp, void *data) return 0; } static struct msm_lmh_dcvs_hw *get_dcvsh_hw_from_cpu(int cpu) { struct msm_lmh_dcvs_hw *hw; list_for_each_entry(hw, &lmh_dcvs_hw_list, list) { if (cpumask_test_cpu(cpu, &hw->core_map)) return hw; } return NULL; } static int lmh_set_max_limit(int cpu, u32 freq) { struct msm_lmh_dcvs_hw *hw = get_dcvsh_hw_from_cpu(cpu); if (!hw) return -EINVAL; return msm_lmh_dcvs_write(hw->affinity, MSM_LIMITS_SUB_FN_GENERAL, MSM_LIMITS_DOMAIN_MAX, freq); } static int lmh_get_cur_limit(int cpu, unsigned long *freq) { struct msm_lmh_dcvs_hw *hw = get_dcvsh_hw_from_cpu(cpu); if (!hw) return -EINVAL; *freq = hw->hw_freq_limit; return 0; } static struct cpu_cooling_ops cd_ops = { .get_cur_state = lmh_get_cur_limit, .ceil_limit = lmh_set_max_limit, }; static int msm_lmh_dcvs_probe(struct platform_device *pdev) { int ret; Loading @@ -257,6 +305,7 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev) struct msm_lmh_dcvs_hw *hw; char sensor_name[] = "limits_sensor-00"; struct thermal_zone_device *tzdev; struct thermal_cooling_device *cdev; struct device_node *dn = pdev->dev.of_node; struct device_node *cpu_node, *lmh_node; uint32_t id, max_freq, request_reg, clear_reg; Loading Loading @@ -331,6 +380,10 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev) if (IS_ERR_OR_NULL(tzdev)) return PTR_ERR(tzdev); /* Setup cooling devices to request mitigation states */ cdev = cpufreq_platform_cooling_register(&hw->core_map, &cd_ops); if (IS_ERR_OR_NULL(cdev)) return PTR_ERR(cdev); /* * Driver defaults to for low and hi thresholds. * Since we make a check for hi > lo value, set the hi threshold Loading @@ -356,7 +409,7 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev) return ret; } hw->max_freq = max_freq; hw->hw_freq_limit = hw->max_freq = max_freq; switch (affinity) { case 0: Loading Loading @@ -399,6 +452,9 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev) return ret; } INIT_LIST_HEAD(&hw->list); list_add(&hw->list, &lmh_dcvs_hw_list); return ret; } Loading include/linux/cpu_cooling.h +16 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,11 @@ typedef int (*get_static_t)(cpumask_t *cpumask, int interval, unsigned long voltage, u32 *power); struct cpu_cooling_ops { int (*ceil_limit)(int, u32); int (*get_cur_state)(int, unsigned long *); }; #ifdef CONFIG_CPU_THERMAL /** * cpufreq_cooling_register - function to create cpufreq cooling device. Loading @@ -43,6 +48,10 @@ struct thermal_cooling_device * cpufreq_power_cooling_register(const struct cpumask *clip_cpus, u32 capacitance, get_static_t plat_static_func); struct thermal_cooling_device * cpufreq_platform_cooling_register(const struct cpumask *clip_cpus, struct cpu_cooling_ops *ops); /** * of_cpufreq_cooling_register - create cpufreq cooling device based on DT. * @np: a valid struct device_node to the cooling device device tree node. Loading Loading @@ -112,6 +121,13 @@ of_cpufreq_power_cooling_register(struct device_node *np, return NULL; } static inline struct thermal_cooling_device * cpufreq_platform_cooling_register(const struct cpumask *clip_cpus, struct cpu_cooling_ops *ops) { return NULL; } static inline void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) { Loading Loading
drivers/thermal/cpu_cooling.c +49 −7 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ struct cpufreq_cooling_device { int dyn_power_table_entries; struct device *cpu_dev; get_static_t plat_get_static_power; struct cpu_cooling_ops *plat_ops; }; static DEFINE_IDR(cpufreq_idr); static DEFINE_MUTEX(cooling_cpufreq_lock); Loading Loading @@ -504,7 +505,12 @@ static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state) { struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; unsigned int cpu = cpumask_any(&cpufreq_device->allowed_cpus); if (cpufreq_device->plat_ops && cpufreq_device->plat_ops->get_cur_state) cpufreq_device->plat_ops->get_cur_state(cpu, state); else *state = cpufreq_device->cpufreq_state; return 0; Loading Loading @@ -539,7 +545,17 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, cpufreq_device->cpufreq_state = state; cpufreq_device->clipped_freq = clip_freq; /* Check if the device has a platform mitigation function that * can handle the CPU freq mitigation, if not, notify cpufreq * framework. */ if (cpufreq_device->plat_ops) { if (cpufreq_device->plat_ops->ceil_limit) cpufreq_device->plat_ops->ceil_limit(cpu, clip_freq); } else { cpufreq_update_policy(cpu); } return 0; } Loading Loading @@ -773,6 +789,9 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table, * @capacitance: dynamic power coefficient for these cpus * @plat_static_func: function to calculate the static power consumed by these * cpus (optional) * @plat_mitig_func: function that does the mitigation by changing the * frequencies (Optional). By default, cpufreq framweork will * be notified of the new limits. * * This interface function registers the cpufreq cooling device with the name * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq Loading @@ -785,7 +804,8 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table, static struct thermal_cooling_device * __cpufreq_cooling_register(struct device_node *np, const struct cpumask *clip_cpus, u32 capacitance, get_static_t plat_static_func) get_static_t plat_static_func, struct cpu_cooling_ops *plat_ops) { struct thermal_cooling_device *cool_dev; struct cpufreq_cooling_device *cpufreq_dev; Loading Loading @@ -851,6 +871,8 @@ __cpufreq_cooling_register(struct device_node *np, } } cpufreq_dev->plat_ops = plat_ops; ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); if (ret) { cool_dev = ERR_PTR(ret); Loading Loading @@ -924,7 +946,7 @@ free_cdev: struct thermal_cooling_device * cpufreq_cooling_register(const struct cpumask *clip_cpus) { return __cpufreq_cooling_register(NULL, clip_cpus, 0, NULL); return __cpufreq_cooling_register(NULL, clip_cpus, 0, NULL, NULL); } EXPORT_SYMBOL_GPL(cpufreq_cooling_register); Loading @@ -948,7 +970,7 @@ of_cpufreq_cooling_register(struct device_node *np, if (!np) return ERR_PTR(-EINVAL); return __cpufreq_cooling_register(np, clip_cpus, 0, NULL); return __cpufreq_cooling_register(np, clip_cpus, 0, NULL, NULL); } EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register); Loading Loading @@ -978,10 +1000,30 @@ cpufreq_power_cooling_register(const struct cpumask *clip_cpus, u32 capacitance, get_static_t plat_static_func) { return __cpufreq_cooling_register(NULL, clip_cpus, capacitance, plat_static_func); plat_static_func, NULL); } EXPORT_SYMBOL(cpufreq_power_cooling_register); /** * cpufreq_platform_cooling_register() - create cpufreq cooling device with * additional platform specific mitigation function. * * @clip_cpus: cpumask of cpus where the frequency constraints will happen * @plat_ops: the platform mitigation functions that will be called insted of * cpufreq, if provided. * * Return: a valid struct thermal_cooling_device pointer on success, * on failure, it returns a corresponding ERR_PTR(). */ struct thermal_cooling_device * cpufreq_platform_cooling_register(const struct cpumask *clip_cpus, struct cpu_cooling_ops *plat_ops) { return __cpufreq_cooling_register(NULL, clip_cpus, 0, NULL, plat_ops); } EXPORT_SYMBOL(cpufreq_platform_cooling_register); /** * of_cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions * @np: a valid struct device_node to the cooling device device tree node Loading Loading @@ -1015,7 +1057,7 @@ of_cpufreq_power_cooling_register(struct device_node *np, return ERR_PTR(-EINVAL); return __cpufreq_cooling_register(np, clip_cpus, capacitance, plat_static_func); plat_static_func, NULL); } EXPORT_SYMBOL(of_cpufreq_power_cooling_register); Loading
drivers/thermal/msm_lmh_dcvs.c +57 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <linux/interrupt.h> #include <linux/timer.h> #include <linux/pm_opp.h> #include <linux/cpu_cooling.h> #include <asm/smp_plat.h> #include <asm/cacheflush.h> Loading @@ -40,6 +41,7 @@ #define MSM_LIMITS_NODE_DCVS 0x44435653 #define MSM_LIMITS_SUB_FN_THERMAL 0x54484D4C #define MSM_LIMITS_SUB_FN_GENERAL 0x47454E00 #define MSM_LIMITS_ALGO_MODE_ENABLE 0x454E424C Loading @@ -49,6 +51,8 @@ #define MSM_LIMITS_CLUSTER_0 0x6370302D #define MSM_LIMITS_CLUSTER_1 0x6370312D #define MSM_LIMITS_DOMAIN_MAX 0x444D4158 #define MSM_LIMITS_HIGH_THRESHOLD_VAL 95000 #define MSM_LIMITS_ARM_THRESHOLD_VAL 65000 #define MSM_LIMITS_POLLING_DELAY_MS 10 Loading Loading @@ -77,8 +81,12 @@ struct msm_lmh_dcvs_hw { cpumask_t core_map; struct timer_list poll_timer; uint32_t max_freq; uint32_t hw_freq_limit; struct list_head list; }; LIST_HEAD(lmh_dcvs_hw_list); static void msm_lmh_dcvs_get_max_freq(uint32_t cpu, uint32_t *max_freq) { unsigned long freq_ceil = UINT_MAX; Loading @@ -104,6 +112,7 @@ static uint32_t msm_lmh_mitigation_notify(struct msm_lmh_dcvs_hw *hw) dcvsh_get_frequency(val, max_limit); sched_update_cpu_freq_min_max(&hw->core_map, 0, max_limit); trace_lmh_dcvs_freq(cpumask_first(&hw->core_map), max_limit); hw->hw_freq_limit = max_limit; return max_limit; } Loading Loading @@ -250,6 +259,45 @@ static int trip_notify(enum thermal_trip_type type, int temp, void *data) return 0; } static struct msm_lmh_dcvs_hw *get_dcvsh_hw_from_cpu(int cpu) { struct msm_lmh_dcvs_hw *hw; list_for_each_entry(hw, &lmh_dcvs_hw_list, list) { if (cpumask_test_cpu(cpu, &hw->core_map)) return hw; } return NULL; } static int lmh_set_max_limit(int cpu, u32 freq) { struct msm_lmh_dcvs_hw *hw = get_dcvsh_hw_from_cpu(cpu); if (!hw) return -EINVAL; return msm_lmh_dcvs_write(hw->affinity, MSM_LIMITS_SUB_FN_GENERAL, MSM_LIMITS_DOMAIN_MAX, freq); } static int lmh_get_cur_limit(int cpu, unsigned long *freq) { struct msm_lmh_dcvs_hw *hw = get_dcvsh_hw_from_cpu(cpu); if (!hw) return -EINVAL; *freq = hw->hw_freq_limit; return 0; } static struct cpu_cooling_ops cd_ops = { .get_cur_state = lmh_get_cur_limit, .ceil_limit = lmh_set_max_limit, }; static int msm_lmh_dcvs_probe(struct platform_device *pdev) { int ret; Loading @@ -257,6 +305,7 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev) struct msm_lmh_dcvs_hw *hw; char sensor_name[] = "limits_sensor-00"; struct thermal_zone_device *tzdev; struct thermal_cooling_device *cdev; struct device_node *dn = pdev->dev.of_node; struct device_node *cpu_node, *lmh_node; uint32_t id, max_freq, request_reg, clear_reg; Loading Loading @@ -331,6 +380,10 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev) if (IS_ERR_OR_NULL(tzdev)) return PTR_ERR(tzdev); /* Setup cooling devices to request mitigation states */ cdev = cpufreq_platform_cooling_register(&hw->core_map, &cd_ops); if (IS_ERR_OR_NULL(cdev)) return PTR_ERR(cdev); /* * Driver defaults to for low and hi thresholds. * Since we make a check for hi > lo value, set the hi threshold Loading @@ -356,7 +409,7 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev) return ret; } hw->max_freq = max_freq; hw->hw_freq_limit = hw->max_freq = max_freq; switch (affinity) { case 0: Loading Loading @@ -399,6 +452,9 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev) return ret; } INIT_LIST_HEAD(&hw->list); list_add(&hw->list, &lmh_dcvs_hw_list); return ret; } Loading
include/linux/cpu_cooling.h +16 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,11 @@ typedef int (*get_static_t)(cpumask_t *cpumask, int interval, unsigned long voltage, u32 *power); struct cpu_cooling_ops { int (*ceil_limit)(int, u32); int (*get_cur_state)(int, unsigned long *); }; #ifdef CONFIG_CPU_THERMAL /** * cpufreq_cooling_register - function to create cpufreq cooling device. Loading @@ -43,6 +48,10 @@ struct thermal_cooling_device * cpufreq_power_cooling_register(const struct cpumask *clip_cpus, u32 capacitance, get_static_t plat_static_func); struct thermal_cooling_device * cpufreq_platform_cooling_register(const struct cpumask *clip_cpus, struct cpu_cooling_ops *ops); /** * of_cpufreq_cooling_register - create cpufreq cooling device based on DT. * @np: a valid struct device_node to the cooling device device tree node. Loading Loading @@ -112,6 +121,13 @@ of_cpufreq_power_cooling_register(struct device_node *np, return NULL; } static inline struct thermal_cooling_device * cpufreq_platform_cooling_register(const struct cpumask *clip_cpus, struct cpu_cooling_ops *ops) { return NULL; } static inline void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) { Loading