From patchwork Tue Mar 26 14:41:15 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 2337731 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 8138B3FC54 for ; Tue, 26 Mar 2013 14:46:37 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UKV6N-00059t-IE; Tue, 26 Mar 2013 14:43:51 +0000 Received: from smtp.citrix.com ([66.165.176.89]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UKV4o-0004XP-HM for linux-arm-kernel@lists.infradead.org; Tue, 26 Mar 2013 14:42:16 +0000 X-IronPort-AV: E=Sophos;i="4.84,911,1355097600"; d="scan'208";a="15626930" Received: from accessns.citrite.net (HELO FTLPEX01CL02.citrite.net) ([10.9.154.239]) by FTLPIPO01.CITRIX.COM with ESMTP/TLS/AES128-SHA; 26 Mar 2013 14:41:24 +0000 Received: from ukmail1.uk.xensource.com (10.80.16.128) by smtprelay.citrix.com (10.13.107.79) with Microsoft SMTP Server id 14.2.342.3; Tue, 26 Mar 2013 10:41:24 -0400 Received: from kaball.uk.xensource.com ([10.80.2.59]) by ukmail1.uk.xensource.com with esmtp (Exim 4.69) (envelope-from ) id 1UKV3u-0002d2-KH; Tue, 26 Mar 2013 14:41:18 +0000 From: Stefano Stabellini To: Subject: [PATCH v2 6/6] [RFC] arm: use PSCI if available Date: Tue, 26 Mar 2013 14:41:15 +0000 Message-ID: <1364308875-26484-6-git-send-email-stefano.stabellini@eu.citrix.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130326_104214_904485_832D6C28 X-CRM114-Status: GOOD ( 22.93 ) X-Spam-Score: -8.2 (--------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-8.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [66.165.176.89 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -1.3 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: linux@arm.linux.org.uk, Ian.Campbell@citrix.com, arnd@arndb.de, konrad.wilk@oracle.com, marc.zyngier@arm.com, Stefano Stabellini , will.deacon@arm.com, linux-kernel@vger.kernel.org, nico@linaro.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Check for the presence of PSCI before setting smp_ops, use PSCI if it is available. This is useful because at least when running on Xen it's possible to have a PSCI node for example on a Versatile Express or an Exynos5 machine. In these cases the PSCI SMP calls should be the ones to be called. Remove virt_smp_ops and platsmp.c from mach-virt because they aren't needed anymore. Signed-off-by: Stefano Stabellini CC: will.deacon@arm.com CC: arnd@arndb.de CC: marc.zyngier@arm.com CC: linux@arm.linux.org.uk CC: nico@linaro.org --- arch/arm/include/asm/psci.h | 1 + arch/arm/kernel/psci.c | 42 +++++++++++++++++++++++++++--- arch/arm/kernel/smp.c | 7 ++++- arch/arm/mach-virt/Makefile | 1 - arch/arm/mach-virt/platsmp.c | 58 ------------------------------------------ arch/arm/mach-virt/virt.c | 3 -- 6 files changed, 45 insertions(+), 67 deletions(-) delete mode 100644 arch/arm/mach-virt/platsmp.c diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index ce0dbe7..e64ea84 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -32,5 +32,6 @@ struct psci_operations { }; extern struct psci_operations psci_ops; +int psci_init(struct smp_operations *ops); #endif /* __ASM_ARM_PSCI_H */ diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c index 3653164..6f66d93 100644 --- a/arch/arm/kernel/psci.c +++ b/arch/arm/kernel/psci.c @@ -16,6 +16,7 @@ #define pr_fmt(fmt) "psci: " fmt #include +#include #include #include @@ -23,7 +24,9 @@ #include #include #include +#include +extern void secondary_startup(void); struct psci_operations psci_ops; static int (*invoke_psci_fn)(u32, u32, u32, u32); @@ -153,20 +156,50 @@ static int psci_migrate(unsigned long cpuid) return psci_to_linux_errno(err); } +static void __init psci_smp_init_cpus(void) +{ +} + +static void __init psci_smp_prepare_cpus(unsigned int max_cpus) +{ +} + +static int __cpuinit psci_boot_secondary(unsigned int cpu, + struct task_struct *idle) +{ + if (psci_ops.cpu_on) + return psci_ops.cpu_on(cpu_logical_map(cpu), + __pa(secondary_startup)); + return -ENODEV; +} + +static void __cpuinit psci_secondary_init(unsigned int cpu) +{ + gic_secondary_init(0); +} + +struct smp_operations __initdata psci_smp_ops = { + .smp_init_cpus = psci_smp_init_cpus, + .smp_prepare_cpus = psci_smp_prepare_cpus, + .smp_secondary_init = psci_secondary_init, + .smp_boot_secondary = psci_boot_secondary, +}; + static const struct of_device_id psci_of_match[] __initconst = { { .compatible = "arm,psci", }, {}, }; -static int __init psci_init(void) +int __init psci_init(struct smp_operations *ops) { struct device_node *np; const char *method; u32 id; + int rc = -EINVAL; np = of_find_matching_node(NULL, psci_of_match); if (!np) - return 0; + return -ENODEV; pr_info("probing function IDs from device-tree\n"); @@ -203,9 +236,10 @@ static int __init psci_init(void) psci_function_id[PSCI_FN_MIGRATE] = id; psci_ops.migrate = psci_migrate; } + *ops = psci_smp_ops; + rc = 0; out_put_node: of_node_put(np); - return 0; + return rc; } -early_initcall(psci_init); diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 31644f1..09eda3c 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -74,7 +75,11 @@ static struct smp_operations smp_ops; void __init smp_set_ops(struct smp_operations *ops) { - if (ops) + int rc = -ENODEV; +#ifdef CONFIG_ARM_PSCI + rc = psci_init(&smp_ops); +#endif + if (rc && ops) smp_ops = *ops; }; diff --git a/arch/arm/mach-virt/Makefile b/arch/arm/mach-virt/Makefile index 042afc1..7ddbfa6 100644 --- a/arch/arm/mach-virt/Makefile +++ b/arch/arm/mach-virt/Makefile @@ -3,4 +3,3 @@ # obj-y := virt.o -obj-$(CONFIG_SMP) += platsmp.o diff --git a/arch/arm/mach-virt/platsmp.c b/arch/arm/mach-virt/platsmp.c deleted file mode 100644 index 8badaab..0000000 --- a/arch/arm/mach-virt/platsmp.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Dummy Virtual Machine - does what it says on the tin. - * - * Copyright (C) 2012 ARM Ltd - * Author: Will Deacon - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#include - -#include -#include - -extern void secondary_startup(void); - -static void __init virt_smp_init_cpus(void) -{ -} - -static void __init virt_smp_prepare_cpus(unsigned int max_cpus) -{ -} - -static int __cpuinit virt_boot_secondary(unsigned int cpu, - struct task_struct *idle) -{ - if (psci_ops.cpu_on) - return psci_ops.cpu_on(cpu_logical_map(cpu), - __pa(secondary_startup)); - return -ENODEV; -} - -static void __cpuinit virt_secondary_init(unsigned int cpu) -{ - gic_secondary_init(0); -} - -struct smp_operations __initdata virt_smp_ops = { - .smp_init_cpus = virt_smp_init_cpus, - .smp_prepare_cpus = virt_smp_prepare_cpus, - .smp_secondary_init = virt_secondary_init, - .smp_boot_secondary = virt_boot_secondary, -}; diff --git a/arch/arm/mach-virt/virt.c b/arch/arm/mach-virt/virt.c index 528c05e..c417752 100644 --- a/arch/arm/mach-virt/virt.c +++ b/arch/arm/mach-virt/virt.c @@ -44,12 +44,9 @@ static const char *virt_dt_match[] = { NULL }; -extern struct smp_operations virt_smp_ops; - DT_MACHINE_START(VIRT, "Dummy Virtual Machine") .init_irq = irqchip_init, .init_time = virt_timer_init, .init_machine = virt_init, - .smp = smp_ops(virt_smp_ops), .dt_compat = virt_dt_match, MACHINE_END