aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGraeme Gregory <graeme.gregory@linaro.org>2014-03-31 10:48:12 +0100
committerGraeme Gregory <graeme.gregory@linaro.org>2014-06-03 09:24:31 +0100
commit396ed11fb516f587671798c26977ed479dbbef74 (patch)
treefb71ca6354b59923e8fcd271af42d7a1eb38c95a
parent6aae5f0650e8ea11cd55174aadccca65e325236b (diff)
downloadleg-kernel-396ed11fb516f587671798c26977ed479dbbef74.tar.gz
arm64/psci: add handling for ACPI
hardcode the conduit to smc until such time as a table update is available. set the psci 2.0 functions in the ACPI case. Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
-rw-r--r--arch/arm64/kernel/psci.c91
1 files changed, 68 insertions, 23 deletions
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 6b6590de9eb0..7996c3daf449 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -15,6 +15,7 @@
#define pr_fmt(fmt) "psci: " fmt
+#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/smp.h>
@@ -231,6 +232,46 @@ static int get_set_conduit_method(struct device_node *np)
return 0;
}
+#ifdef CONFIG_ACPI
+static int get_set_conduit_method_acpi(void)
+{
+ /*
+ * Hardcoded for ACPI until we get the correct flags in tables approved
+ * so this information can be read from the appropriate table.
+ */
+ invoke_psci_fn = __invoke_psci_fn_smc;
+
+ return 0;
+}
+#else
+static int get_set_conduit_method_acpi(struct device *dev)
+{
+ return 0;
+}
+#endif
+
+static void psci_0_2_set_functions(void)
+{
+ pr_info("Using standard PSCI v0.2 function IDs\n");
+ psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_ID_CPU_SUSPEND_64;
+ psci_ops.cpu_suspend = psci_cpu_suspend;
+
+ psci_function_id[PSCI_FN_CPU_OFF] = PSCI_ID_CPU_OFF;
+ psci_ops.cpu_off = psci_cpu_off;
+
+ psci_function_id[PSCI_FN_CPU_ON] = PSCI_ID_CPU_ON_64;
+ psci_ops.cpu_on = psci_cpu_on;
+
+ psci_function_id[PSCI_FN_MIGRATE] = PSCI_ID_CPU_MIGRATE_64;
+ psci_ops.migrate = psci_migrate;
+
+ psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_ID_AFFINITY_INFO_64;
+ psci_ops.affinity_info = psci_affinity_info;
+
+ psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] = PSCI_ID_MIGRATE_INFO_TYPE;
+ psci_ops.migrate_info_type = psci_migrate_info_type;
+}
+
/*
* PSCI Function IDs for v0.2+ are well defined so use
* standard values.
@@ -255,24 +296,7 @@ static int psci_0_2_init(struct device_node *np)
goto out_put_node;
}
- pr_info("Using standard PSCI v0.2 function IDs\n");
- psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_ID_CPU_SUSPEND_64;
- psci_ops.cpu_suspend = psci_cpu_suspend;
-
- psci_function_id[PSCI_FN_CPU_OFF] = PSCI_ID_CPU_OFF;
- psci_ops.cpu_off = psci_cpu_off;
-
- psci_function_id[PSCI_FN_CPU_ON] = PSCI_ID_CPU_ON_64;
- psci_ops.cpu_on = psci_cpu_on;
-
- psci_function_id[PSCI_FN_MIGRATE] = PSCI_ID_CPU_MIGRATE_64;
- psci_ops.migrate = psci_migrate;
-
- psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_ID_AFFINITY_INFO_64;
- psci_ops.affinity_info = psci_affinity_info;
-
- psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] = PSCI_ID_MIGRATE_INFO_TYPE;
- psci_ops.migrate_info_type = psci_migrate_info_type;
+ psci_0_2_set_functions();
out_put_node:
of_node_put(np);
@@ -319,6 +343,21 @@ out_put_node:
return err;
}
+#ifdef CONFIG_ACPI
+static int psci_0_2_init_acpi(void)
+{
+ get_set_conduit_method_acpi();
+
+ psci_0_2_set_functions();
+
+ return 0;
+}
+#else
+static int psci_0_2_init_acpi(void)
+{
+ return 0;
+}
+#endif
static const struct of_device_id psci_of_match[] __initconst = {
{ .compatible = "arm,psci", .data = psci_0_1_init},
{ .compatible = "arm,psci-0.2", .data = psci_0_2_init},
@@ -331,13 +370,19 @@ int __init psci_init(void)
const struct of_device_id *matched_np;
psci_initcall_t init_fn;
- np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
+ if (acpi_disabled) {
+ np = of_find_matching_node_and_match(NULL,
+ psci_of_match, &matched_np);
- if (!np)
- return -ENODEV;
+ if (!np)
+ return -ENODEV;
+
+ init_fn = (psci_initcall_t)matched_np->data;
+
+ return init_fn(np);
+ }
- init_fn = (psci_initcall_t)matched_np->data;
- return init_fn(np);
+ return psci_0_2_init_acpi();
}
#ifdef CONFIG_SMP