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
55 * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
66 *
77 */
8+#define pr_fmt(fmt) "cpuidle cooling: " fmt
9+
810 #include <linux/cpu_cooling.h>
911 #include <linux/cpuidle.h>
1012 #include <linux/err.h>
1113 #include <linux/idle_inject.h>
1214 #include <linux/idr.h>
15+#include <linux/of_device.h>
1316 #include <linux/slab.h>
1417 #include <linux/thermal.h>
1518
@@ -154,22 +157,25 @@ static struct thermal_cooling_device_ops cpuidle_cooling_ops = { · 138 unmodified lines
154157 };
155158
156159 /**
157− * cpuidle_of_cooling_register - Idle cooling device initialization function
160+ * __cpuidle_cooling_register: register the cooling device
158161 * @drv: a cpuidle driver structure pointer
159− * @np: a node pointer to a device tree cooling device node
162+ * @np: a device node structure pointer used for the thermal binding
160163 *
161− * This function is in charge of creating a cooling device per cpuidle
162− * driver and register it to thermal framework.
164+ * This function is in charge of allocating the cpuidle cooling device
165+ * structure, the idle injection, initialize them and register the
166+ * cooling device to the thermal framework.
163167 *
164− * Return: zero on success, or negative value corresponding to the
165− * error detected in the underlying subsystems.
168+ * Return: zero on success, a negative value returned by one of the
169+ * underlying subsystem in case of error
166170 */
167−int cpuidle_of_cooling_register(struct device_node *np,
168− struct cpuidle_driver *drv)
171+static int __cpuidle_cooling_register(struct device_node *np,
172+ struct cpuidle_driver *drv)
169173 {
170174 struct idle_inject_device *ii_dev;
171175 struct cpuidle_cooling_device *idle_cdev;
172176 struct thermal_cooling_device *cdev;
177+ unsigned int idle_duration_us = TICK_USEC;
178+ unsigned int latency_us = UINT_MAX;
173179 char dev_name[THERMAL_NAME_LENGTH];
174180 int id, ret;
175181
@@ -191,7 +197,11 @@ int cpuidle_of_cooling_register(struct device_node *np, · 15 unmodified lines
191197 goto out_id;
192198 }
193199
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);
195205
196206 idle_cdev->ii_dev = ii_dev;
197207
@@ -204,6 +214,9 @@ int cpuidle_of_cooling_register(struct device_node *np, · 6 unmodified lines
204214 goto out_unregister;
205215 }
206216
217+ pr_debug("%s: Idle injection set with idle duration=%u, latency=%u\n",
218+ dev_name, idle_duration_us, latency_us);
219+
207220 return 0;
208221
209222 out_unregister:
@@ -221,12 +234,38 @@ out: · 11 unmodified lines
221234 * @drv: a cpuidle driver structure pointer
222235 *
223236 * 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.
225238 *
226239 * Return: zero on success, or negative value corresponding to the
227240 * error detected in the underlying subsystems.
228241 */
229−int cpuidle_cooling_register(struct cpuidle_driver *drv)
242+void cpuidle_cooling_register(struct cpuidle_driver *drv)
230243 {
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+ }
232271 }
include/linux/cpu_cooling.h+2−10
@@ -63,18 +63,10 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy) · 62 unmodified lines
6363 struct cpuidle_driver;
6464
6565 #ifdef CONFIG_CPU_IDLE_THERMAL
66−int cpuidle_cooling_register(struct cpuidle_driver *drv);
67−int cpuidle_of_cooling_register(struct device_node *np,
68− struct cpuidle_driver *drv);
66+void cpuidle_cooling_register(struct cpuidle_driver *drv);
6967 #else /* CONFIG_CPU_IDLE_THERMAL */
70−static inline int cpuidle_cooling_register(struct cpuidle_driver *drv)
68+static inline void cpuidle_cooling_register(struct cpuidle_driver *drv)
7169 {
72− return 0;
73−}
74−static inline int cpuidle_of_cooling_register(struct device_node *np,
75− struct cpuidle_driver *drv)
76−{
77− return 0;
7870 }
7971 #endif /* CONFIG_CPU_IDLE_THERMAL */
8072