summaryrefslogtreecommitdiff
path: root/drivers/firmware/psci_checker.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-23 13:52:46 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-23 13:52:46 -0700
commitf3ea496213819c80ce9c49a9b65f9261da713d11 (patch)
tree1c8fad9c5c609504c2916ad3844494093f89f8f1 /drivers/firmware/psci_checker.c
parent9e259f9352d52053058a234f7c062c4e4f56dc85 (diff)
parent29ed45fff05899f6f39d05fe1c32b1bc51f8926b (diff)
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Olof Johansson: "Some of the larger changes this merge window: - Removal of drivers for Exynos5440, a Samsung SoC that never saw widespread use. - Uniphier support for USB3 and SPI reset handling - Syste control and SRAM drivers and bindings for Allwinner platforms - Qualcomm AOSS (Always-on subsystem) reset controller drivers - Raspberry Pi hwmon driver for voltage - Mediatek pwrap (pmic) support for MT6797 SoC" * tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (52 commits) drivers/firmware: psci_checker: stash and use topology_core_cpumask for hotplug tests soc: fsl: cleanup Kconfig menu soc: fsl: dpio: Convert DPIO documentation to .rst staging: fsl-mc: Remove remaining files staging: fsl-mc: Move DPIO from staging to drivers/soc/fsl staging: fsl-dpaa2: eth: move generic FD defines to DPIO soc: fsl: qe: gpio: Add qe_gpio_set_multiple usb: host: exynos: Remove support for Exynos5440 clk: samsung: Remove support for Exynos5440 soc: sunxi: Add the A13, A23 and H3 system control compatibles reset: uniphier: add reset control support for SPI cpufreq: exynos: Remove support for Exynos5440 ata: ahci-platform: Remove support for Exynos5440 soc: imx6qp: Use GENPD_FLAG_ALWAYS_ON for PU errata soc: mediatek: pwrap: add mt6351 driver for mt6797 SoCs soc: mediatek: pwrap: add pwrap driver for mt6797 SoCs soc: mediatek: pwrap: fix cipher init setting error dt-bindings: pwrap: mediatek: add pwrap support for MT6797 reset: uniphier: add USB3 core reset control dt-bindings: reset: uniphier: add USB3 core reset support ...
Diffstat (limited to 'drivers/firmware/psci_checker.c')
-rw-r--r--drivers/firmware/psci_checker.c83
1 files changed, 49 insertions, 34 deletions
diff --git a/drivers/firmware/psci_checker.c b/drivers/firmware/psci_checker.c
index bb1c068bff19..346943657962 100644
--- a/drivers/firmware/psci_checker.c
+++ b/drivers/firmware/psci_checker.c
@@ -77,28 +77,6 @@ static int psci_ops_check(void)
return 0;
}
-static int find_cpu_groups(const struct cpumask *cpus,
- const struct cpumask **cpu_groups)
-{
- unsigned int nb = 0;
- cpumask_var_t tmp;
-
- if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
- return -ENOMEM;
- cpumask_copy(tmp, cpus);
-
- while (!cpumask_empty(tmp)) {
- const struct cpumask *cpu_group =
- topology_core_cpumask(cpumask_any(tmp));
-
- cpu_groups[nb++] = cpu_group;
- cpumask_andnot(tmp, tmp, cpu_group);
- }
-
- free_cpumask_var(tmp);
- return nb;
-}
-
/*
* offlined_cpus is a temporary array but passing it as an argument avoids
* multiple allocations.
@@ -166,29 +144,66 @@ static unsigned int down_and_up_cpus(const struct cpumask *cpus,
return err;
}
+static void free_cpu_groups(int num, cpumask_var_t **pcpu_groups)
+{
+ int i;
+ cpumask_var_t *cpu_groups = *pcpu_groups;
+
+ for (i = 0; i < num; ++i)
+ free_cpumask_var(cpu_groups[i]);
+ kfree(cpu_groups);
+}
+
+static int alloc_init_cpu_groups(cpumask_var_t **pcpu_groups)
+{
+ int num_groups = 0;
+ cpumask_var_t tmp, *cpu_groups;
+
+ if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
+ return -ENOMEM;
+
+ cpu_groups = kcalloc(nb_available_cpus, sizeof(cpu_groups),
+ GFP_KERNEL);
+ if (!cpu_groups)
+ return -ENOMEM;
+
+ cpumask_copy(tmp, cpu_online_mask);
+
+ while (!cpumask_empty(tmp)) {
+ const struct cpumask *cpu_group =
+ topology_core_cpumask(cpumask_any(tmp));
+
+ if (!alloc_cpumask_var(&cpu_groups[num_groups], GFP_KERNEL)) {
+ free_cpu_groups(num_groups, &cpu_groups);
+ return -ENOMEM;
+ }
+ cpumask_copy(cpu_groups[num_groups++], cpu_group);
+ cpumask_andnot(tmp, tmp, cpu_group);
+ }
+
+ free_cpumask_var(tmp);
+ *pcpu_groups = cpu_groups;
+
+ return num_groups;
+}
+
static int hotplug_tests(void)
{
- int err;
- cpumask_var_t offlined_cpus;
- int i, nb_cpu_group;
- const struct cpumask **cpu_groups;
+ int i, nb_cpu_group, err = -ENOMEM;
+ cpumask_var_t offlined_cpus, *cpu_groups;
char *page_buf;
- err = -ENOMEM;
if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL))
return err;
- /* We may have up to nb_available_cpus cpu_groups. */
- cpu_groups = kmalloc_array(nb_available_cpus, sizeof(*cpu_groups),
- GFP_KERNEL);
- if (!cpu_groups)
+
+ nb_cpu_group = alloc_init_cpu_groups(&cpu_groups);
+ if (nb_cpu_group < 0)
goto out_free_cpus;
page_buf = (char *)__get_free_page(GFP_KERNEL);
if (!page_buf)
goto out_free_cpu_groups;
err = 0;
- nb_cpu_group = find_cpu_groups(cpu_online_mask, cpu_groups);
-
/*
* Of course the last CPU cannot be powered down and cpu_down() should
* refuse doing that.
@@ -212,7 +227,7 @@ static int hotplug_tests(void)
free_page((unsigned long)page_buf);
out_free_cpu_groups:
- kfree(cpu_groups);
+ free_cpu_groups(nb_cpu_group, &cpu_groups);
out_free_cpus:
free_cpumask_var(offlined_cpus);
return err;