]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cpuidle: riscv-sbi: Use scoped device node handling to fix missing of_node_put
authorKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Tue, 20 Aug 2024 09:40:22 +0000 (11:40 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 20 Aug 2024 19:46:43 +0000 (21:46 +0200)
Two return statements in sbi_cpuidle_dt_init_states() did not drop the
OF node reference count.  Solve the issue and simplify entire error
handling with scoped/cleanup.h.

Fixes: 6abf32f1d9c5 ("cpuidle: Add RISC-V SBI CPU idle driver")
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://patch.msgid.link/20240820094023.61155-1-krzysztof.kozlowski@linaro.org
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpuidle/cpuidle-riscv-sbi.c

index a6e123dfe394d8a6b50063cee9bdf4fdf8ad1b48..5bb3401220d296e0ad341f77ec682e71516dde7a 100644 (file)
@@ -8,6 +8,7 @@
 
 #define pr_fmt(fmt) "cpuidle-riscv-sbi: " fmt
 
+#include <linux/cleanup.h>
 #include <linux/cpuhotplug.h>
 #include <linux/cpuidle.h>
 #include <linux/cpumask.h>
@@ -236,19 +237,16 @@ static int sbi_cpuidle_dt_init_states(struct device *dev,
 {
        struct sbi_cpuidle_data *data = per_cpu_ptr(&sbi_cpuidle_data, cpu);
        struct device_node *state_node;
-       struct device_node *cpu_node;
        u32 *states;
        int i, ret;
 
-       cpu_node = of_cpu_device_node_get(cpu);
+       struct device_node *cpu_node __free(device_node) = of_cpu_device_node_get(cpu);
        if (!cpu_node)
                return -ENODEV;
 
        states = devm_kcalloc(dev, state_count, sizeof(*states), GFP_KERNEL);
-       if (!states) {
-               ret = -ENOMEM;
-               goto fail;
-       }
+       if (!states)
+               return -ENOMEM;
 
        /* Parse SBI specific details from state DT nodes */
        for (i = 1; i < state_count; i++) {
@@ -264,10 +262,8 @@ static int sbi_cpuidle_dt_init_states(struct device *dev,
 
                pr_debug("sbi-state %#x index %d\n", states[i], i);
        }
-       if (i != state_count) {
-               ret = -ENODEV;
-               goto fail;
-       }
+       if (i != state_count)
+               return -ENODEV;
 
        /* Initialize optional data, used for the hierarchical topology. */
        ret = sbi_dt_cpu_init_topology(drv, data, state_count, cpu);
@@ -277,10 +273,7 @@ static int sbi_cpuidle_dt_init_states(struct device *dev,
        /* Store states in the per-cpu struct. */
        data->states = states;
 
-fail:
-       of_node_put(cpu_node);
-
-       return ret;
+       return 0;
 }
 
 static void sbi_cpuidle_deinit_cpu(int cpu)