History

thermal/drivers/cpuidle_cooling: Change the registration function

Today, there is no user for the cpuidle cooling device. The targetted platform is ARM and ARM64. The cpuidle and the cpufreq cooling device are based on the device tree. As the cpuidle cooling device can have its own configuration depending on the platform and the available idle states. The DT node description will give the optional properties to set the cooling device up. Do no longer rely on the CPU node which is prone to error and will lead to a confusion in the DT because the cpufreq cooling device is also using it. Let initialize the cpuidle cooling device with the DT binding. This was tested on: - hikey960 - hikey6220 - rock960 - db845c

Daniel Lezcano committed 6 years ago

Commit dfd0bda1 parent 3b258462 files · +53 −22Browse files

Unified · Split

2 files
  1. drivers/thermal/cpuidle_cooling.c +51 −12
  2. include/linux/cpu_cooling.h +2 −10
drivers/thermal/cpuidle_cooling.c+51−12
@@ -5,11 +5,14 @@ · 4 unmodified lines
5 * Author: Daniel Lezcano <daniel.lezcano@linaro.org>5 * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
6 *6 *
7 */7 */
8#define pr_fmt(fmt) "cpuidle cooling: " fmt
9
8#include <linux/cpu_cooling.h>10#include <linux/cpu_cooling.h>
9#include <linux/cpuidle.h>11#include <linux/cpuidle.h>
10#include <linux/err.h>12#include <linux/err.h>
11#include <linux/idle_inject.h>13#include <linux/idle_inject.h>
12#include <linux/idr.h>14#include <linux/idr.h>
15#include <linux/of_device.h>
13#include <linux/slab.h>16#include <linux/slab.h>
14#include <linux/thermal.h>17#include <linux/thermal.h>
15 18
@@ -154,22 +157,25 @@ static struct thermal_cooling_device_ops cpuidle_cooling_ops = { · 138 unmodified lines
154};157};
155 158
156/**159/**
157 * cpuidle_of_cooling_register - Idle cooling device initialization function160 * __cpuidle_cooling_register: register the cooling device
158 * @drv: a cpuidle driver structure pointer161 * @drv: a cpuidle driver structure pointer
159 * @np: a node pointer to a device tree cooling device node162 * @np: a device node structure pointer used for the thermal binding
160 *163 *
161 * This function is in charge of creating a cooling device per cpuidle164 * This function is in charge of allocating the cpuidle cooling device
162 * driver and register it to thermal framework.165 * structure, the idle injection, initialize them and register the
166 * cooling device to the thermal framework.
163 *167 *
164 * Return: zero on success, or negative value corresponding to the168 * Return: zero on success, a negative value returned by one of the
165 * error detected in the underlying subsystems.169 * underlying subsystem in case of error
166 */170 */
167int cpuidle_of_cooling_register(struct device_node *np,171static int __cpuidle_cooling_register(struct device_node *np,
168 struct cpuidle_driver *drv)172 struct cpuidle_driver *drv)
169{173{
170 struct idle_inject_device *ii_dev;174 struct idle_inject_device *ii_dev;
171 struct cpuidle_cooling_device *idle_cdev;175 struct cpuidle_cooling_device *idle_cdev;
172 struct thermal_cooling_device *cdev;176 struct thermal_cooling_device *cdev;
177 unsigned int idle_duration_us = TICK_USEC;
178 unsigned int latency_us = UINT_MAX;
173 char dev_name[THERMAL_NAME_LENGTH];179 char dev_name[THERMAL_NAME_LENGTH];
174 int id, ret;180 int id, ret;
175 181
@@ -191,7 +197,11 @@ int cpuidle_of_cooling_register(struct device_node *np, · 15 unmodified lines
191 goto out_id;197 goto out_id;
192 }198 }
193 199
194 idle_inject_set_duration(ii_dev, TICK_USEC, TICK_USEC);200 of_property_read_u32(np, "duration-us", &idle_duration_us);
201 of_property_read_u32(np, "exit-latency-us", &latency_us);
202
203 idle_inject_set_duration(ii_dev, TICK_USEC, idle_duration_us);
204 idle_inject_set_latency(ii_dev, latency_us);
195 205
196 idle_cdev->ii_dev = ii_dev;206 idle_cdev->ii_dev = ii_dev;
197 207
@@ -204,6 +214,9 @@ int cpuidle_of_cooling_register(struct device_node *np, · 6 unmodified lines
204 goto out_unregister;214 goto out_unregister;
205 }215 }
206 216
217 pr_debug("%s: Idle injection set with idle duration=%u, latency=%u\n",
218 dev_name, idle_duration_us, latency_us);
219
207 return 0;220 return 0;
208 221
209out_unregister:222out_unregister:
@@ -221,12 +234,38 @@ out: · 11 unmodified lines
221 * @drv: a cpuidle driver structure pointer234 * @drv: a cpuidle driver structure pointer
222 *235 *
223 * This function is in charge of creating a cooling device per cpuidle236 * This function is in charge of creating a cooling device per cpuidle
224 * driver and register it to thermal framework.237 * driver and register it to the thermal framework.
225 *238 *
226 * Return: zero on success, or negative value corresponding to the239 * Return: zero on success, or negative value corresponding to the
227 * error detected in the underlying subsystems.240 * error detected in the underlying subsystems.
228 */241 */
229int cpuidle_cooling_register(struct cpuidle_driver *drv)242void cpuidle_cooling_register(struct cpuidle_driver *drv)
230{243{
231 return cpuidle_of_cooling_register(NULL, drv);244 struct device_node *cooling_node;
245 struct device_node *cpu_node;
246 int cpu, ret;
247
248 for_each_cpu(cpu, drv->cpumask) {
249
250 cpu_node = of_cpu_device_node_get(cpu);
251
252 cooling_node = of_get_child_by_name(cpu_node, "thermal-idle");
253
254 of_node_put(cpu_node);
255
256 if (!cooling_node) {
257 pr_debug("'thermal-idle' node not found for cpu%d\n", cpu);
258 continue;
259 }
260
261 ret = __cpuidle_cooling_register(cooling_node, drv);
262
263 of_node_put(cooling_node);
264
265 if (ret) {
266 pr_err("Failed to register the cpuidle cooling device" \
267 "for cpu%d: %d\n", cpu, ret);
268 break;
269 }
270 }
232}271}
include/linux/cpu_cooling.h+2−10
@@ -63,18 +63,10 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy) · 62 unmodified lines
63struct cpuidle_driver;63struct cpuidle_driver;
64 64
65#ifdef CONFIG_CPU_IDLE_THERMAL65#ifdef CONFIG_CPU_IDLE_THERMAL
66int cpuidle_cooling_register(struct cpuidle_driver *drv);66void cpuidle_cooling_register(struct cpuidle_driver *drv);
67int cpuidle_of_cooling_register(struct device_node *np,
68 struct cpuidle_driver *drv);
69#else /* CONFIG_CPU_IDLE_THERMAL */67#else /* CONFIG_CPU_IDLE_THERMAL */
70static inline int cpuidle_cooling_register(struct cpuidle_driver *drv)68static inline void cpuidle_cooling_register(struct cpuidle_driver *drv)
71{69{
72 return 0;
73}
74static inline int cpuidle_of_cooling_register(struct device_node *np,
75 struct cpuidle_driver *drv)
76{
77 return 0;
78}70}
79#endif /* CONFIG_CPU_IDLE_THERMAL */71#endif /* CONFIG_CPU_IDLE_THERMAL */
80 72