From patchwork Fri Nov 20 09:14:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chenhui zhao X-Patchwork-Id: 546863 X-Patchwork-Delegate: scottwood@freescale.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 9C01E140DA3 for ; Fri, 20 Nov 2015 20:47:01 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 825731A003D for ; Fri, 20 Nov 2015 20:47:01 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from na01-by2-obe.outbound.protection.outlook.com (mail-by2on0128.outbound.protection.outlook.com [207.46.100.128]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 6D7F81A0018 for ; Fri, 20 Nov 2015 20:46:01 +1100 (AEDT) Received: from BN3PR0301CA0001.namprd03.prod.outlook.com (10.160.180.139) by BN3PR03MB1480.namprd03.prod.outlook.com (10.163.35.143) with Microsoft SMTP Server (TLS) id 15.1.331.20; Fri, 20 Nov 2015 09:13:41 +0000 Received: from BL2FFO11FD031.protection.gbl (2a01:111:f400:7c09::144) by BN3PR0301CA0001.outlook.office365.com (2a01:111:e400:4000::11) with Microsoft SMTP Server (TLS) id 15.1.331.20 via Frontend Transport; Fri, 20 Nov 2015 09:13:41 +0000 Authentication-Results: spf=permerror (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none; freescale.mail.onmicrosoft.com; dmarc=none action=none header.from=freescale.com; Received-SPF: PermError (protection.outlook.com: domain of freescale.com used an invalid SPF mechanism) Received: from az84smr01.freescale.net (192.88.158.2) by BL2FFO11FD031.mail.protection.outlook.com (10.173.160.71) with Microsoft SMTP Server (TLS) id 15.1.331.11 via Frontend Transport; Fri, 20 Nov 2015 09:13:41 +0000 Received: from localhost.localdomain ([10.193.20.174]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id tAK9DUPd015178; Fri, 20 Nov 2015 02:13:39 -0700 From: Chenhui Zhao To: Subject: [PATCH v3 5/6] powerpc/mpc85xx: Add hotplug support on E5500 and E500MC cores Date: Fri, 20 Nov 2015 17:14:01 +0800 Message-ID: <1448010842-22345-5-git-send-email-chenhui.zhao@freescale.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1448010842-22345-1-git-send-email-chenhui.zhao@freescale.com> References: <1448010842-22345-1-git-send-email-chenhui.zhao@freescale.com> X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD031; 1:dC8dhRj+2jF65Jd8maOzHQAYnZVDea2MH9CiBDyd0QCGxQVoiTuV82P1/x3HZpBc49/pSRypxGh7+rv2jO52JuH2JmEwKePS2uTL1B8Ii6nLZH/T0XImaMnatKg3gyj+tiNDl5dRYP22DAYmvzha1QTvVhhVxOAxT49ON9l1O7tJcyipQedWB0ScenNqTke+Jm6jdczrziKIvu+UQ7YGuLlCgttmDeeI0JNgWm/MAJdNZIyxM5AFN9nR+/oDAGQ5oFRjfCMT059Kgb9QyT+gPn0Ycq8mti94gPe6eK/Lociom3xzV04wi4DP9I9Q4EPB35CQc6aJVwg/qp7basm1aTFlWMHDJdCmZxRgFZtw+K9zlmjs8Ezkr5ZFxZUaRr17qQhEQmUgFc0TnYhvY0UaBqDZnFmdSUUqCFFg5HLgcpY= X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(979002)(6009001)(2980300002)(448002)(189002)(199003)(575784001)(86362001)(110136002)(50466002)(5001960100002)(5008740100001)(107886002)(11100500001)(189998001)(6806005)(36756003)(4001430100002)(69596002)(5007970100001)(19580395003)(19580405001)(97736004)(81156007)(92566002)(106466001)(50226001)(2351001)(104016004)(450100001)(229853001)(33646002)(586003)(50986999)(2950100001)(76176999)(47776003)(5003940100001)(87936001)(77096005)(48376002)(49486002)(85326001)(969003)(989001)(999001)(1009001)(1019001); DIR:OUT; SFP:1102; SCL:1; SRVR:BN3PR03MB1480; H:az84smr01.freescale.net; FPR:; SPF:PermError; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB1480; 2:XQ4lY84mZ0uGVLBp9SdoR3zH/2+HQ/VNn+O7J/l9gGfWFsX+7O9u3/hNg8pDk3lbk3cKpGg9jTzfljJ734tYMDuDO3lKmxbVdTDTJfB/l6naLcFkl8DvukWWEuRT9XG432IrVrxxSKX3vNxgJ8Zrhg==; 3:7MNAiJlts04k2kD0c53iJ1cFkqHTtgzoIgaEGyhfyzj1q/XFvmDuvQRoCqlLUfJpgvM5/XJht1edv7khwEE3vVhNjm52ddA6dsTqs2gZe63kbaRVbpEiwSkxfOXqAE+Cab9bSMk60duMwQNns+L2G5pRbhUcDRXuxRxWjOEBwXCBQIfK9yptYY/rTNwZRxCbGuAmGV1s7aIlcyFj32SdSGAJ/H6aPVv5W1+oxrioDf4=; 25:wdMgxbSq+VoybdyfnviUpQotL4pfViMvtp368XLHvaa3wrKF++Zew8Ds4UFtUo3uNqbe+yNtDGJlX2/HtyUk2xjxZAvRT9OxB/t9Bb6Vvy0weSdVWUIlyLKC6K5jQJe6xbUeLHdGrFVCEhP+Pte+S+VrPpCtvyYB7g9Go/cdKO4JtdXW4IL4UmoQeAFA1sFXtIgU0d0H/+mhiKIZRbUbGfOOISLCa70wxbNRQRVj6uvAHuMu4IWQIOPlTI9qlJ/hUBcHK5damfZNxTLIYHMGuw== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN3PR03MB1480; X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB1480; 20:nOKLt07ypuJrTfsi5/ozAYQSAq9w4DFiFtRWPpQISso0/yyAAwfJJ9g9+hAQfVK2lp+RxDucg2MvT3KRbFY7kX+F5ahAXXWBWzx6wruWKyMEIpSGf9juoKYzMRv996cIPFtr1/83NDohX7Y/2Btr0h8Jd6If10KYEwJIRaPFu1YqhxQKxfItHnmsLYlS0xiL03/ukRZyfGLv1yxPaZy/4q+Z/EqAF+J68cHhsC0MymOMZQkLjiZCydqwHqgvbcPmHDEZZynbc3OZcrzscsl7cj2TNTataZrG5vbxfUNvoeuQxLtmFVFd+J+qkx35tchih0Cws0Svf2CIs8hFl/INL5fsOkgA1f68iqhWLeS3dMw=; 4:/pIVgPrNp+Q1g5AtHYi/4xLImBcSzHAclo/HgUlq9BhwMd3l16/VHkNr/6PqWDJzG98+M82EsNZgZEgKiVIM6ZsjWj9rv0vDWMO62J+cPXge3EUTrWvECc4Oj5QIvgHgT+KxMjWhYVvN4y2GkTyvsy5CGyTxcCvAU3LOnkjFN0CYdYCbck5fLrdoZIAnMRvKwMC77U4/3u2pbwPaBn/4febCge3VP1FeMgsmmTTpxbainqKZGHxifgNs6B9CyqxROsoBvXQHLTFv6GBLihVEY/mcFaC5qPeInJjxtj7j1kVQ2FDmOW9qcxZWOdnX+z7qxPTEcSVTe62dm6To9d7YcwqqQv5dTRHroyI1mIjk3hWuECCyFSD3aPlQsneR8Yl7GTUONuOAEQSAatxXj4Ag0Sp9SlnKhBM7Vi3DrIBZZyvu4KWWwC81UnzbkbMAXFKH X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(101931422205132); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(520078)(5005006)(8121501046)(10201501046)(3002001); SRVR:BN3PR03MB1480; BCL:0; PCL:0; RULEID:; SRVR:BN3PR03MB1480; X-Forefront-PRVS: 07665BE9D1 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN3PR03MB1480; 23:v+vxlh2/SQoO66dA+p+msg7Osu+ZUiCeupdiTWYZm?= =?us-ascii?Q?Fz/8O7ZeKx9K8gmrdEIpva8IyVIcrAAvAhagTxTSDBOEnDQaomQ2rsghcn/X?= =?us-ascii?Q?XeMH24HL3TvmNLbvQVfWcav/L+l2r1j1MGcvev4x263zL4XYfsG8YIFvD9C8?= =?us-ascii?Q?DEpd3KsBhL1TZ44C+bp9Y1WDtVl88OFA7Gh/QOVCxijiyNa37QXcYYQCLAcx?= =?us-ascii?Q?998ij/4fCWH8MuyaOnAyzZcSw7DL5SiYhewRL6HLW7IPcOKvktor9wrML+cQ?= =?us-ascii?Q?Tf+wXxOJ+O1PjXiSmgvL3WVJFw5tyg1uNwt8OiOUxvU2u5tiKZWCIcMGjiAN?= =?us-ascii?Q?XQ6NlOf4l9m5mG1zWdpXHvjEHpUheRTkp3cW2L4A/nAPKxSKT0ay7RXacOPE?= =?us-ascii?Q?tG0BBGPV2sLYNIlRAacAnZmNxD3eFzfUaUM/g+usnq3F8q14ACx9w6vtPrsp?= =?us-ascii?Q?VM3bdKlqB33AKX5ycTQoI+sXbK+EStCE4wxFxXyxpeZRDzopTwQCB+h5mWx0?= =?us-ascii?Q?TQTc7CJD1pURSa1bax4433fsUjSuJFq5JGL3U+Ij1mTAoS5QQ+275NwO3XdR?= =?us-ascii?Q?op+9HmBCE+dWAomUnUviEgZwAkTlLMdK5Bitp/G9ZuTQeVtYi+fKM3cnQTph?= =?us-ascii?Q?La38QcXrObET7RjBejsm3LMcC+sC7Qo6Xg2mEV42I8Ky7YEkqsIyDXYJbn7V?= =?us-ascii?Q?jLwMRSa4X6T4ixemXJrsp8uGmtAu4cmgsMIOztFkTQJZUk8iZuno99KK7VNY?= =?us-ascii?Q?I/VO1cwbyZb77Jl80JP3ZQ6ao7Ou4oJErNIv5LJBoUZfoNhSEoChPncB8qWB?= =?us-ascii?Q?y94lGXDigmOFY6UkIwvQr+SNI0Xl7dNToQuzX3rEjJqoWb7UkL8AJuFlcTnj?= =?us-ascii?Q?smr+wLJn/B/W76D6Wcq8/qC/ODGQX0NG3/9yIrLTkgHnwKg5pNXytQW1UV+2?= =?us-ascii?Q?qweVNTQKv0BuCRyd22+L6q6hqKO5ptJYo/TE1mDAEundWqvr9Uw0VD+O8JbT?= =?us-ascii?Q?cBYaN1KnH/JSy8zjY3hBwoggnp1F/oTZymNDrRMSmOqRIP/67M3pQ6c0ePqM?= =?us-ascii?Q?i+Gh6quvOR6r6+fB1tdL4nq7PCEpdQ+gfkKq+b13O0xNNKywwveib4fYRTUd?= =?us-ascii?Q?o0nTl5NUAIfsfeJ6njU0wDUmo63Cyd50UeYRe1Q7yxLcf2IJm/ySEKddMlhF?= =?us-ascii?Q?+53hARPsfdJBWO4Iz0p40rqCHtJfpE2ZbU13a3rvtPmNUy4DonZmEaw1A=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB1480; 5:jolAlOWu/n14nadTdSbnoHYcG6mXjN+iav51TK7xBjRiY8rwmR9Drfr0kjOz+jkqptUvRaHn36iUT94yc1eV+y+JN9BBDZn2ixSNBmBjvtKZzTeWEHOv5w8YEFSLO+UfecdRutPiXVFkTiePF4TXew==; 24:7PpWhYy98hrR+SPG4fKEEpyk+ebiy1nNtEi0lPD+Ac28W5LEbDx3CQSyJ/gR/IH/vnIE6d/Z79FM3fIrK8hh2oK1l8r7Qn8YFJ+klOQAQDw= X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Nov 2015 09:13:41.4587 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR03MB1480 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: scottwood@freescale.com Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Freescale E500MC and E5500 core-based platforms, like P4080, T1040, support disabling/enabling CPU dynamically. This patch adds this feature on those platforms. Signed-off-by: Chenhui Zhao Signed-off-by: Tang Yuantian --- changes for v3 * move changes in arch/powerpc/platforms/85xx/smp.h to patch 2 * get rid of unused primary_hw * check_cpu_dead() renamed to is_cpu_dead() * move the declaration of fsl_rcpm_init() to patch 2/5 major changes for v2: * factor out smp_85xx_start_cpu() * move fsl_rcpm_init() into mpc85xx_smp_init() due to the init sequence * add hard_irq_disable() after local_irq_save(). for platforms that implement lazy enabling/disabling of interrupts, call hard_irq_disable() to ensure interrupts are disabled physically. arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/smp.h | 3 + arch/powerpc/kernel/smp.c | 7 +- arch/powerpc/platforms/85xx/smp.c | 198 +++++++++++++++++++++----------------- 4 files changed, 120 insertions(+), 90 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index db49e0d..1093143 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -391,7 +391,7 @@ config SWIOTLB config HOTPLUG_CPU bool "Support for enabling/disabling CPUs" depends on SMP && (PPC_PSERIES || \ - PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC)) + PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 825663c..bdb8111 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -67,6 +67,9 @@ void generic_cpu_die(unsigned int cpu); void generic_set_cpu_dead(unsigned int cpu); void generic_set_cpu_up(unsigned int cpu); int generic_check_cpu_restart(unsigned int cpu); +int is_cpu_dead(unsigned int cpu); +#else +#define generic_set_cpu_up(i) do { } while (0) #endif #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index ec9ec20..8575d04 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -427,7 +427,7 @@ void generic_cpu_die(unsigned int cpu) for (i = 0; i < 100; i++) { smp_rmb(); - if (per_cpu(cpu_state, cpu) == CPU_DEAD) + if (is_cpu_dead(cpu)) return; msleep(100); } @@ -454,6 +454,11 @@ int generic_check_cpu_restart(unsigned int cpu) return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; } +int is_cpu_dead(unsigned int cpu) +{ + return per_cpu(cpu_state, cpu) == CPU_DEAD; +} + static bool secondaries_inhibited(void) { return kvm_hv_mode_active(); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index ab0459d..0f56dd5 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -10,6 +10,8 @@ * option) any later version. */ +#define pr_fmt(fmt) "smp: %s: " fmt, __func__ + #include #include #include @@ -53,6 +55,7 @@ static void mpc85xx_give_timebase(void) unsigned long flags; local_irq_save(flags); + hard_irq_disable(); while (!tb_req) barrier(); @@ -101,6 +104,7 @@ static void mpc85xx_take_timebase(void) unsigned long flags; local_irq_save(flags); + hard_irq_disable(); tb_req = 1; while (!tb_valid) @@ -136,8 +140,31 @@ static void smp_85xx_mach_cpu_die(void) while (1) ; } + +static void qoriq_cpu_kill(unsigned int cpu) +{ + int i; + + for (i = 0; i < 500; i++) { + if (is_cpu_dead(cpu)) { +#ifdef CONFIG_PPC64 + paca[cpu].cpu_start = 0; +#endif + return; + } + msleep(20); + } + pr_err("CPU%d didn't die...\n", cpu); +} #endif +/* + * To keep it compatible with old boot program which uses + * cache-inhibit spin table, we need to flush the cache + * before accessing spin table to invalidate any staled data. + * We also need to flush the cache after writing to spin + * table to push data out. + */ static inline void flush_spin_table(void *spin_table) { flush_dcache_range((ulong)spin_table, @@ -176,57 +203,20 @@ static void wake_hw_thread(void *info) } #endif -static int smp_85xx_kick_cpu(int nr) +static int smp_85xx_start_cpu(int cpu) { - unsigned long flags; - const u64 *cpu_rel_addr; - __iomem struct epapr_spin_table *spin_table; + int ret = 0; struct device_node *np; - int hw_cpu = get_hard_smp_processor_id(nr); + const u64 *cpu_rel_addr; + unsigned long flags; int ioremappable; - int ret = 0; - - WARN_ON(nr < 0 || nr >= NR_CPUS); - WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS); - - pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); - -#ifdef CONFIG_PPC64 - /* Threads don't use the spin table */ - if (cpu_thread_in_core(nr) != 0) { - int primary = cpu_first_thread_sibling(nr); - - if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) - return -ENOENT; + int hw_cpu = get_hard_smp_processor_id(cpu); + struct epapr_spin_table __iomem *spin_table; - if (cpu_thread_in_core(nr) != 1) { - pr_err("%s: cpu %d: invalid hw thread %d\n", - __func__, nr, cpu_thread_in_core(nr)); - return -ENOENT; - } - - if (!cpu_online(primary)) { - pr_err("%s: cpu %d: primary %d not online\n", - __func__, nr, primary); - return -ENOENT; - } - - smp_call_function_single(primary, wake_hw_thread, &nr, 0); - return 0; - } else if (cpu_thread_in_core(boot_cpuid) != 0 && - cpu_first_thread_sibling(boot_cpuid) == nr) { - if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) - return -ENOENT; - - smp_call_function_single(boot_cpuid, wake_hw_thread, &nr, 0); - } -#endif - - np = of_get_cpu_node(nr, NULL); + np = of_get_cpu_node(cpu, NULL); cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL); - - if (cpu_rel_addr == NULL) { - printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr); + if (!cpu_rel_addr) { + pr_err("No cpu-release-addr for cpu %d\n", cpu); return -ENOENT; } @@ -246,28 +236,18 @@ static int smp_85xx_kick_cpu(int nr) spin_table = phys_to_virt(*cpu_rel_addr); local_irq_save(flags); -#ifdef CONFIG_PPC32 -#ifdef CONFIG_HOTPLUG_CPU - /* Corresponding to generic_set_cpu_dead() */ - generic_set_cpu_up(nr); + hard_irq_disable(); - if (system_state == SYSTEM_RUNNING) { - /* - * To keep it compatible with old boot program which uses - * cache-inhibit spin table, we need to flush the cache - * before accessing spin table to invalidate any staled data. - * We also need to flush the cache after writing to spin - * table to push data out. - */ - flush_spin_table(spin_table); - out_be32(&spin_table->addr_l, 0); - flush_spin_table(spin_table); + if (qoriq_pm_ops) + qoriq_pm_ops->cpu_up_prepare(cpu); + /* if cpu is not spinning, reset it */ + if (read_spin_table_addr_l(spin_table) != 1) { /* * We don't set the BPTR register here since it already points * to the boot page properly. */ - mpic_reset_core(nr); + mpic_reset_core(cpu); /* * wait until core is ready... @@ -277,40 +257,23 @@ static int smp_85xx_kick_cpu(int nr) if (!spin_event_timeout( read_spin_table_addr_l(spin_table) == 1, 10000, 100)) { - pr_err("%s: timeout waiting for core %d to reset\n", - __func__, hw_cpu); - ret = -ENOENT; - goto out; + pr_err("timeout waiting for cpu %d to reset\n", + hw_cpu); + ret = -EAGAIN; + goto err; } - - /* clear the acknowledge status */ - __secondary_hold_acknowledge = -1; } -#endif - flush_spin_table(spin_table); - out_be32(&spin_table->pir, hw_cpu); - out_be32(&spin_table->addr_l, __pa(__early_start)); - flush_spin_table(spin_table); - - /* Wait a bit for the CPU to ack. */ - if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu, - 10000, 100)) { - pr_err("%s: timeout waiting for core %d to ack\n", - __func__, hw_cpu); - ret = -ENOENT; - goto out; - } -out: -#else - smp_generic_kick_cpu(nr); flush_spin_table(spin_table); out_be32(&spin_table->pir, hw_cpu); +#ifdef CONFIG_PPC64 out_be64((u64 *)(&spin_table->addr_h), __pa(ppc_function_entry(generic_secondary_smp_init))); - flush_spin_table(spin_table); +#else + out_be32(&spin_table->addr_l, __pa(__early_start)); #endif - + flush_spin_table(spin_table); +err: local_irq_restore(flags); if (ioremappable) @@ -319,6 +282,60 @@ out: return ret; } +static int smp_85xx_kick_cpu(int nr) +{ + int ret = 0; +#ifdef CONFIG_PPC64 + int primary = nr; +#endif + + WARN_ON(nr < 0 || nr >= num_possible_cpus()); + + pr_debug("kick CPU #%d\n", nr); + +#ifdef CONFIG_PPC64 + /* Threads don't use the spin table */ + if (cpu_thread_in_core(nr) != 0) { + int primary = cpu_first_thread_sibling(nr); + + if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) + return -ENOENT; + + if (cpu_thread_in_core(nr) != 1) { + pr_err("%s: cpu %d: invalid hw thread %d\n", + __func__, nr, cpu_thread_in_core(nr)); + return -ENOENT; + } + + if (!cpu_online(primary)) { + pr_err("%s: cpu %d: primary %d not online\n", + __func__, nr, primary); + return -ENOENT; + } + + smp_call_function_single(primary, wake_hw_thread, &nr, 0); + return 0; + } + + ret = smp_85xx_start_cpu(primary); + if (ret) + return ret; + + paca[nr].cpu_start = 1; + generic_set_cpu_up(nr); + + return ret; +#else + ret = smp_85xx_start_cpu(nr); + if (ret) + return ret; + + generic_set_cpu_up(nr); + + return ret; +#endif +} + struct smp_ops_t smp_85xx_ops = { .kick_cpu = smp_85xx_kick_cpu, .cpu_bootable = smp_generic_cpu_bootable, @@ -473,6 +490,10 @@ void __init mpc85xx_smp_init(void) } #ifdef CONFIG_HOTPLUG_CPU +#ifdef CONFIG_FSL_CORENET_RCPM + fsl_rcpm_init(); +#endif + #ifdef CONFIG_FSL_PMC mpc85xx_setup_pmc(); #endif @@ -480,6 +501,7 @@ void __init mpc85xx_smp_init(void) smp_85xx_ops.give_timebase = mpc85xx_give_timebase; smp_85xx_ops.take_timebase = mpc85xx_take_timebase; ppc_md.cpu_die = smp_85xx_mach_cpu_die; + smp_85xx_ops.cpu_die = qoriq_cpu_kill; } #endif smp_ops = &smp_85xx_ops;