diff options
author | Graeme Gregory <graeme.gregory@linaro.org> | 2014-03-31 10:48:12 +0100 |
---|---|---|
committer | Graeme Gregory <graeme.gregory@linaro.org> | 2014-06-03 09:24:31 +0100 |
commit | 396ed11fb516f587671798c26977ed479dbbef74 (patch) | |
tree | fb71ca6354b59923e8fcd271af42d7a1eb38c95a | |
parent | 6aae5f0650e8ea11cd55174aadccca65e325236b (diff) | |
download | leg-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.c | 91 |
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 |