diff options
Diffstat (limited to 'arch/arm64/kernel/cpu_ops.c')
| -rw-r--r-- | arch/arm64/kernel/cpu_ops.c | 72 | 
1 files changed, 44 insertions, 28 deletions
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c index fb8ff9ba467a..5ea337dd2f15 100644 --- a/arch/arm64/kernel/cpu_ops.c +++ b/arch/arm64/kernel/cpu_ops.c @@ -16,11 +16,13 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ -#include <asm/cpu_ops.h> -#include <asm/smp_plat.h> +#include <linux/acpi.h>  #include <linux/errno.h>  #include <linux/of.h>  #include <linux/string.h> +#include <asm/acpi.h> +#include <asm/cpu_ops.h> +#include <asm/smp_plat.h>  extern const struct cpu_operations smp_spin_table_ops;  extern const struct cpu_operations cpu_psci_ops; @@ -35,7 +37,7 @@ static const struct cpu_operations *supported_cpu_ops[] __initconst = {  	NULL,  }; -const struct cpu_operations * __init cpu_get_ops(const char *name) +static const struct cpu_operations * __init cpu_get_ops(const char *name)  {  	const struct cpu_operations **ops = supported_cpu_ops; @@ -49,39 +51,53 @@ const struct cpu_operations * __init cpu_get_ops(const char *name)  	return NULL;  } +static const char *__init cpu_read_enable_method(int cpu) +{ +	const char *enable_method; + +	if (acpi_disabled) { +		struct device_node *dn = of_get_cpu_node(cpu, NULL); + +		if (!dn) { +			if (!cpu) +				pr_err("Failed to find device node for boot cpu\n"); +			return NULL; +		} + +		enable_method = of_get_property(dn, "enable-method", NULL); +		if (!enable_method) { +			/* +			 * The boot CPU may not have an enable method (e.g. +			 * when spin-table is used for secondaries). +			 * Don't warn spuriously. +			 */ +			if (cpu != 0) +				pr_err("%s: missing enable-method property\n", +					dn->full_name); +		} +	} else { +		enable_method = acpi_get_enable_method(cpu); +		if (!enable_method) +			pr_err("Unsupported ACPI enable-method\n"); +	} + +	return enable_method; +}  /* - * Read a cpu's enable method from the device tree and record it in cpu_ops. + * Read a cpu's enable method and record it in cpu_ops.   */ -int __init cpu_read_ops(struct device_node *dn, int cpu) +int __init cpu_read_ops(int cpu)  { -	const char *enable_method = of_get_property(dn, "enable-method", NULL); -	if (!enable_method) { -		/* -		 * The boot CPU may not have an enable method (e.g. when -		 * spin-table is used for secondaries). Don't warn spuriously. -		 */ -		if (cpu != 0) -			pr_err("%s: missing enable-method property\n", -				dn->full_name); -		return -ENOENT; -	} +	const char *enable_method = cpu_read_enable_method(cpu); + +	if (!enable_method) +		return -ENODEV;  	cpu_ops[cpu] = cpu_get_ops(enable_method);  	if (!cpu_ops[cpu]) { -		pr_warn("%s: unsupported enable-method property: %s\n", -			dn->full_name, enable_method); +		pr_warn("Unsupported enable-method: %s\n", enable_method);  		return -EOPNOTSUPP;  	}  	return 0;  } - -void __init cpu_read_bootcpu_ops(void) -{ -	struct device_node *dn = of_get_cpu_node(0, NULL); -	if (!dn) { -		pr_err("Failed to find device node for boot cpu\n"); -		return; -	} -	cpu_read_ops(dn, 0); -}  |