From patchwork Thu Jul 24 13:00:16 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanjun Guo X-Patchwork-Id: 34211 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f199.google.com (mail-lb0-f199.google.com [209.85.217.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 863F820C7F for ; Thu, 24 Jul 2014 13:03:12 +0000 (UTC) Received: by mail-lb0-f199.google.com with SMTP id 10sf2139070lbg.10 for ; Thu, 24 Jul 2014 06:03:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=LBrB/C3oV6CDnRr3Pm8G/ychMm/D83t4/hPVRQezV5A=; b=ADRaKrHA+3UtlZSdNj7I/pT1tEvej+oxvOO8YWyEVjgHz8ktXHg3mHttgY1LcTfSoE Q/jlf7vmwm9VuOmnxsnSnWAot7sJ6vXlLCfskGZ4PSR1TbmcpiA7ZTu/FuaRqqRWy2ai kKA/NLcRupwru9LuGrcWubpBF9J/X8FmudzerhXy1q/EMbuvyB+sqT9NGAMnfrofFxff BsLjt6F6LEOqctsTTjnR5B7FTY4iG57z5m3CayHVfI8s0CkBdm9gq2xZt+g79Y6Vl9il wYtUvGWX5koN/PRsPqkjwDLFP5taujvWjv3IMff37yEIlria70X98Uh8sq+GSHlpyUnH dgdw== X-Gm-Message-State: ALoCoQkyQ5srJLA6KVaoodKg21teNVe0Auf4LCobE+Hec22WPZmcLVDmkIbxr1/646G1RhsDO8OC X-Received: by 10.180.20.175 with SMTP id o15mr974979wie.7.1406206990287; Thu, 24 Jul 2014 06:03:10 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.36.37 with SMTP id o34ls752370qgo.67.gmail; Thu, 24 Jul 2014 06:03:10 -0700 (PDT) X-Received: by 10.220.17.199 with SMTP id t7mr11944619vca.1.1406206990163; Thu, 24 Jul 2014 06:03:10 -0700 (PDT) Received: from mail-vc0-f181.google.com (mail-vc0-f181.google.com [209.85.220.181]) by mx.google.com with ESMTPS id qx9si4851592vcb.93.2014.07.24.06.03.09 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 24 Jul 2014 06:03:09 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.181 as permitted sender) client-ip=209.85.220.181; Received: by mail-vc0-f181.google.com with SMTP id lf12so4699532vcb.40 for ; Thu, 24 Jul 2014 06:03:09 -0700 (PDT) X-Received: by 10.220.50.8 with SMTP id x8mr11657936vcf.18.1406206989462; Thu, 24 Jul 2014 06:03:09 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp362988vcb; Thu, 24 Jul 2014 06:03:09 -0700 (PDT) X-Received: by 10.70.102.169 with SMTP id fp9mr10105534pdb.118.1406206988416; Thu, 24 Jul 2014 06:03:08 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id wt2si5940461pbc.82.2014.07.24.06.03.05 for ; Thu, 24 Jul 2014 06:03:05 -0700 (PDT) Received-SPF: none (google.com: linux-acpi-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759263AbaGXNCr (ORCPT + 8 others); Thu, 24 Jul 2014 09:02:47 -0400 Received: from mail-pa0-f50.google.com ([209.85.220.50]:62860 "EHLO mail-pa0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758834AbaGXNCo (ORCPT ); Thu, 24 Jul 2014 09:02:44 -0400 Received: by mail-pa0-f50.google.com with SMTP id et14so3851888pad.23 for ; Thu, 24 Jul 2014 06:02:44 -0700 (PDT) X-Received: by 10.66.229.98 with SMTP id sp2mr10062104pac.95.1406206964228; Thu, 24 Jul 2014 06:02:44 -0700 (PDT) Received: from localhost ([183.247.163.231]) by mx.google.com with ESMTPSA id pl10sm5568575pbb.56.2014.07.24.06.02.37 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 24 Jul 2014 06:02:43 -0700 (PDT) From: Hanjun Guo To: Catalin Marinas , "Rafael J. Wysocki" , Mark Rutland Cc: Graeme Gregory , Arnd Bergmann , Grant Likely , Sudeep Holla , Will Deacon , Jason Cooper , Marc Zyngier , Bjorn Helgaas , Daniel Lezcano , Mark Brown , Robert Richter , Lv Zheng , Robert Moore , Lorenzo Pieralisi , Liviu Dudau , Randy Dunlap , Charles.Garcia-Tobin@arm.com, linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linaro-acpi-private@linaro.org, Hanjun Guo , Tomasz Nowicki Subject: [PATCH 10/19] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way Date: Thu, 24 Jul 2014 21:00:16 +0800 Message-Id: <1406206825-15590-11-git-send-email-hanjun.guo@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1406206825-15590-1-git-send-email-hanjun.guo@linaro.org> References: <1406206825-15590-1-git-send-email-hanjun.guo@linaro.org> Sender: linux-acpi-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: hanjun.guo@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.181 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , ACPI 5.1 only has two explicit methods to boot up SMP, PSCI and Parking protocol, but the Parking protocol is only suitable for ARMv7 now, so make PSCI as the only way for the SMP boot protocol before some updates for the ACPI spec or the Parking protocol spec. Signed-off-by: Hanjun Guo Signed-off-by: Tomasz Nowicki --- arch/arm64/include/asm/acpi.h | 21 +++++++++++++++ arch/arm64/include/asm/cpu_ops.h | 9 ++++++- arch/arm64/include/asm/smp.h | 2 +- arch/arm64/kernel/acpi.c | 9 +++++++ arch/arm64/kernel/cpu_ops.c | 52 ++++++++++++++++++++++++++++++++++---- arch/arm64/kernel/smp.c | 29 +++++++++++++++++++-- 6 files changed, 113 insertions(+), 9 deletions(-) diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index 5ce85f8..6240327 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -14,6 +14,27 @@ /* Basic configuration for ACPI */ #ifdef CONFIG_ACPI +/* + * ACPI 5.1 only has two explicit methods to + * boot up SMP, PSCI and Parking protocol, + * but the Parking protocol is only defined + * for ARMv7 now, so make PSCI as the only + * way for the SMP boot protocol before some + * updates for the ACPI spec or the Parking + * protocol spec. + * + * This enum is intend to make the boot method + * scalable when above updates are happended, + * which NOT means to support all of them. + */ +enum acpi_smp_boot_protocol { + ACPI_SMP_BOOT_PSCI, + ACPI_SMP_BOOT_PARKING_PROTOCOL, + ACPI_SMP_BOOT_PROTOCOL_MAX +}; + +enum acpi_smp_boot_protocol smp_boot_protocol(void); + extern int acpi_disabled; extern int acpi_noirq; extern int acpi_pci_disabled; diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h index d7b4b38..2a7c6fd 100644 --- a/arch/arm64/include/asm/cpu_ops.h +++ b/arch/arm64/include/asm/cpu_ops.h @@ -61,7 +61,14 @@ struct cpu_operations { }; extern const struct cpu_operations *cpu_ops[NR_CPUS]; -extern int __init cpu_read_ops(struct device_node *dn, int cpu); +extern int __init cpu_of_read_ops(struct device_node *dn, int cpu); + +#ifdef CONFIG_ACPI +extern int __init cpu_acpi_read_ops(int cpu); +#else +static inline int __init cpu_acpi_read_ops(int cpu) { return -ENODEV; } +#endif + extern void __init cpu_read_bootcpu_ops(void); #endif /* ifndef __ASM_CPU_OPS_H */ diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index a498f2c..a5cea56 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -39,7 +39,7 @@ extern void show_ipi_list(struct seq_file *p, int prec); extern void handle_IPI(int ipinr, struct pt_regs *regs); /* - * Setup the set of possible CPUs (via set_cpu_possible) + * Platform specific SMP operations */ extern void smp_init_cpus(void); diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index ff0f6a0..2af6662 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -184,6 +184,15 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void) return 0; } +/* Protocol to bring up secondary CPUs */ +enum acpi_smp_boot_protocol smp_boot_protocol(void) +{ + if (acpi_psci_present) + return ACPI_SMP_BOOT_PSCI; + else + return ACPI_SMP_BOOT_PARKING_PROTOCOL; +} + static int __init acpi_parse_fadt(struct acpi_table_header *table) { struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c index d62d12f..4d9b3cf 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 . */ -#include -#include #include #include #include +#include + +#include +#include extern const struct cpu_operations smp_spin_table_ops; extern const struct cpu_operations cpu_psci_ops; @@ -52,7 +54,7 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name) /* * Read a cpu's enable method from the device tree and record it in cpu_ops. */ -int __init cpu_read_ops(struct device_node *dn, int cpu) +int __init cpu_of_read_ops(struct device_node *dn, int cpu) { const char *enable_method = of_get_property(dn, "enable-method", NULL); if (!enable_method) { @@ -76,12 +78,52 @@ int __init cpu_read_ops(struct device_node *dn, int cpu) return 0; } +#ifdef CONFIG_ACPI +/* + * Read a cpu's enable method in the ACPI way and record it in cpu_ops. + */ +int __init cpu_acpi_read_ops(int cpu) +{ + /* + * For ACPI 5.1, only two kind of methods are provided, + * Parking protocol and PSCI, but Parking protocol is + * used on ARMv7 only, so make PSCI as the only method + * for SMP initialization before the ACPI spec or Parking + * protocol spec is updated. + */ + switch (smp_boot_protocol()) { + case ACPI_SMP_BOOT_PSCI: + cpu_ops[cpu] = cpu_get_ops("psci"); + break; + case ACPI_SMP_BOOT_PARKING_PROTOCOL: + default: + cpu_ops[cpu] = NULL; + break; + } + + if (!cpu_ops[cpu]) { + pr_warn("CPU %d: unsupported enable-method, only PSCI is supported\n", + cpu); + return -EOPNOTSUPP; + } + + return 0; +} +#endif + void __init cpu_read_bootcpu_ops(void) { - struct device_node *dn = of_get_cpu_node(0, NULL); + struct device_node *dn; + + if (!acpi_disabled) { + cpu_acpi_read_ops(0); + return; + } + + 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); + cpu_of_read_ops(dn, 0); } diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 8f1d37c..cb71662 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -315,7 +315,7 @@ static void (*smp_cross_call)(const struct cpumask *, unsigned int); * cpu logical map array containing MPIDR values related to logical * cpus. Assumes that cpu_logical_map(0) has already been initialized. */ -void __init smp_init_cpus(void) +static void __init of_smp_init_cpus(void) { struct device_node *dn = NULL; unsigned int i, cpu = 1; @@ -387,7 +387,7 @@ void __init smp_init_cpus(void) if (cpu >= NR_CPUS) goto next; - if (cpu_read_ops(dn, cpu) != 0) + if (cpu_of_read_ops(dn, cpu) != 0) goto next; if (cpu_ops[cpu]->cpu_init(dn, cpu)) @@ -418,6 +418,31 @@ next: set_cpu_possible(i, true); } +/* + * In ACPI mode, the cpu possible map was enumerated before SMP + * initialization when MADT table was parsed, so we can get the + * possible map here to initialize CPUs. + */ +static void __init acpi_smp_init_cpus(void) +{ + int cpu; + + for_each_possible_cpu(cpu) { + if (cpu_acpi_read_ops(cpu) != 0) + continue; + + cpu_ops[cpu]->cpu_init(NULL, cpu); + } +} + +void __init smp_init_cpus(void) +{ + if (acpi_disabled) + of_smp_init_cpus(); + else + acpi_smp_init_cpus(); +} + void __init smp_prepare_cpus(unsigned int max_cpus) { int err;