Merge tag 'powerpc-5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[linux-2.6-microblaze.git] / drivers / cpufreq / powernv-cpufreq.c
index 23a06cb..5a2cf5f 100644 (file)
@@ -36,6 +36,7 @@
 #define MAX_PSTATE_SHIFT       32
 #define LPSTATE_SHIFT          48
 #define GPSTATE_SHIFT          56
+#define MAX_NR_CHIPS           32
 
 #define MAX_RAMP_DOWN_TIME                             5120
 /*
@@ -1046,12 +1047,20 @@ static int init_chip_info(void)
        unsigned int *chip;
        unsigned int cpu, i;
        unsigned int prev_chip_id = UINT_MAX;
+       cpumask_t *chip_cpu_mask;
        int ret = 0;
 
        chip = kcalloc(num_possible_cpus(), sizeof(*chip), GFP_KERNEL);
        if (!chip)
                return -ENOMEM;
 
+       /* Allocate a chip cpu mask large enough to fit mask for all chips */
+       chip_cpu_mask = kcalloc(MAX_NR_CHIPS, sizeof(cpumask_t), GFP_KERNEL);
+       if (!chip_cpu_mask) {
+               ret = -ENOMEM;
+               goto free_and_return;
+       }
+
        for_each_possible_cpu(cpu) {
                unsigned int id = cpu_to_chip_id(cpu);
 
@@ -1059,22 +1068,25 @@ static int init_chip_info(void)
                        prev_chip_id = id;
                        chip[nr_chips++] = id;
                }
+               cpumask_set_cpu(cpu, &chip_cpu_mask[nr_chips-1]);
        }
 
        chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL);
        if (!chips) {
                ret = -ENOMEM;
-               goto free_and_return;
+               goto out_free_chip_cpu_mask;
        }
 
        for (i = 0; i < nr_chips; i++) {
                chips[i].id = chip[i];
-               cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i]));
+               cpumask_copy(&chips[i].mask, &chip_cpu_mask[i]);
                INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn);
                for_each_cpu(cpu, &chips[i].mask)
                        per_cpu(chip_info, cpu) =  &chips[i];
        }
 
+out_free_chip_cpu_mask:
+       kfree(chip_cpu_mask);
 free_and_return:
        kfree(chip);
        return ret;