From patchwork Tue Oct 15 09:16:17 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 21028 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f200.google.com (mail-qc0-f200.google.com [209.85.216.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2AA3A20D84 for ; Tue, 15 Oct 2013 09:17:18 +0000 (UTC) Received: by mail-qc0-f200.google.com with SMTP id x20sf16206743qcv.3 for ; Tue, 15 Oct 2013 02:17:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=mime-version:x-gm-message-state:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=gh0yAJDEJ8kDvWMxd1z6G/m+UWFZw3fT4WjwQFrUQYA=; b=Vmyg4RE0FvGenfg/1VqPt2YUuRU1TON43eQlkhnUemLNmUpQ94izKulZ5rI2vWSwo7 /X0y3qlzbl+H+Ic0Cr5GbisFEkJ0U2pn/cvW1pluK+ceBKl7fBT01v62PCUJ4OKfFATt zocchXwteprYFoyOhr4TSct4mamfd6pjhBr8qWXRYAg05iG3n9i0KRT2Ubic9lZhAG7n Kk/cEYVtLMwPKfZ5ksP2qr/J8iqo0GChyze3bXeV8ZNdRmzgSbZlSpS2ZFY0h5fzjBfA NTOot+Jf4OLQUXyAeJIJonnVsOyd3ope2EPHiYRG6kWPRffH+lniPuaQjSvGaj/qMDrv dTUw== X-Received: by 10.236.85.6 with SMTP id t6mr37373723yhe.37.1381828637797; Tue, 15 Oct 2013 02:17:17 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.27.199 with SMTP id v7ls37968qeg.85.gmail; Tue, 15 Oct 2013 02:17:17 -0700 (PDT) X-Received: by 10.220.69.212 with SMTP id a20mr39481801vcj.10.1381828637670; Tue, 15 Oct 2013 02:17:17 -0700 (PDT) Received: from mail-vc0-f174.google.com (mail-vc0-f174.google.com [209.85.220.174]) by mx.google.com with ESMTPS id bz3si22428320vcb.48.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 15 Oct 2013 02:17:17 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.174 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.174; Received: by mail-vc0-f174.google.com with SMTP id ie18so1006365vcb.5 for ; Tue, 15 Oct 2013 02:17:17 -0700 (PDT) X-Gm-Message-State: ALoCoQkiOyIx4Z7y9VISEGrKj9PKEc2lJA4idB4EjEE6ZDXGC3AiYBAur63DLlG8upViAXWqjLst X-Received: by 10.58.255.233 with SMTP id at9mr701589ved.20.1381828637562; Tue, 15 Oct 2013 02:17:17 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp284377vcz; Tue, 15 Oct 2013 02:17:16 -0700 (PDT) X-Received: by 10.68.194.230 with SMTP id hz6mr19164020pbc.55.1381828636562; Tue, 15 Oct 2013 02:17:16 -0700 (PDT) Received: from mail-pa0-f50.google.com (mail-pa0-f50.google.com [209.85.220.50]) by mx.google.com with ESMTPS id gj2si8347094pac.138.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 15 Oct 2013 02:17:16 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.50 is neither permitted nor denied by best guess record for domain of haojian.zhuang@linaro.org) client-ip=209.85.220.50; Received: by mail-pa0-f50.google.com with SMTP id fb1so8780891pad.9 for ; Tue, 15 Oct 2013 02:17:16 -0700 (PDT) X-Received: by 10.68.179.98 with SMTP id df2mr40202585pbc.38.1381828636077; Tue, 15 Oct 2013 02:17:16 -0700 (PDT) Received: from localhost.localdomain ([98.126.20.66]) by mx.google.com with ESMTPSA id ye1sm97457107pab.19.1969.12.31.16.00.00 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 15 Oct 2013 02:17:15 -0700 (PDT) From: Haojian Zhuang To: arnd@arndb.de, linux@arm.linux.org.uk, linus.walleij@linaro.org, olof@lixom.net, rob.herring@calxeda.com, linux-arm-kernel@lists.infradead.org, tglx@linutronix.de, john.stultz@linaro.org, mturquette@linaro.org, grant.likely@linaro.org, mark.rutland@arm.com, khilman@linaro.org, swarren@wwwdotorg.org, shaojie.sun@linaro.org, devicetree@vger.kernel.org Cc: patches@linaro.org, Zhangfei Gao , Haojian Zhuang Subject: [PATCH v10 7/7] ARM: hi3xxx: add hotplug support Date: Tue, 15 Oct 2013 17:16:17 +0800 Message-Id: <1381828577-27998-8-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1381828577-27998-1-git-send-email-haojian.zhuang@linaro.org> References: <1381828577-27998-1-git-send-email-haojian.zhuang@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: haojian.zhuang@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.174 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Zhangfei Gao Enable hotplug support on hi3xxx platform How to test: cat proc/interrupts echo 0 > /sys/devices/system/cpu/cpuX/online cat proc/interrupts echo 1 > /sys/devices/system/cpu/cpuX/online Signed-off-by: Zhangfei Gao Tested-by: Zhang Mingjun Signed-off-by: Haojian Zhuang --- arch/arm/mach-hi3xxx/Makefile | 1 + arch/arm/mach-hi3xxx/core.h | 4 + arch/arm/mach-hi3xxx/hotplug.c | 200 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-hi3xxx/platsmp.c | 5 ++ 4 files changed, 210 insertions(+) create mode 100644 arch/arm/mach-hi3xxx/hotplug.c diff --git a/arch/arm/mach-hi3xxx/Makefile b/arch/arm/mach-hi3xxx/Makefile index 7a869a7..c9919e8 100644 --- a/arch/arm/mach-hi3xxx/Makefile +++ b/arch/arm/mach-hi3xxx/Makefile @@ -4,3 +4,4 @@ obj-y += hi3xxx.o obj-$(CONFIG_SMP) += platsmp.o +obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-hi3xxx/core.h b/arch/arm/mach-hi3xxx/core.h index 226f020..af23ec2 100644 --- a/arch/arm/mach-hi3xxx/core.h +++ b/arch/arm/mach-hi3xxx/core.h @@ -8,4 +8,8 @@ extern int hi3xxx_get_cpu_jump(int cpu); extern void secondary_startup(void); extern struct smp_operations hi3xxx_smp_ops; +extern void hi3xxx_cpu_die(unsigned int cpu); +extern int hi3xxx_cpu_kill(unsigned int cpu); +extern void hi3xxx_set_cpu(int cpu, bool enable); + #endif diff --git a/arch/arm/mach-hi3xxx/hotplug.c b/arch/arm/mach-hi3xxx/hotplug.c new file mode 100644 index 0000000..5dc949e --- /dev/null +++ b/arch/arm/mach-hi3xxx/hotplug.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "core.h" + +/* Sysctrl registers in Hi3620 SoC */ +#define SCISOEN 0xc0 +#define SCISODIS 0xc4 +#define SCPERPWREN 0xd0 +#define SCPERPWRDIS 0xd4 +#define SCCPUCOREEN 0xf4 +#define SCCPUCOREDIS 0xf8 +#define SCPERCTRL0 0x200 +#define SCCPURSTEN 0x410 +#define SCCPURSTDIS 0x414 + +/* + * bit definition in SCISOEN/SCPERPWREN/... + * + * CPU2_ISO_CTRL (1 << 5) + * CPU3_ISO_CTRL (1 << 6) + * ... + */ +#define CPU2_ISO_CTRL (1 << 5) + +/* + * bit definition in SCPERCTRL0 + * + * CPU0_WFI_MASK_CFG (1 << 28) + * CPU1_WFI_MASK_CFG (1 << 29) + * ... + */ +#define CPU0_WFI_MASK_CFG (1 << 28) + +/* + * bit definition in SCCPURSTEN/... + * + * CPU0_SRST_REQ_EN (1 << 0) + * CPU1_SRST_REQ_EN (1 << 1) + * ... + */ +#define CPU0_HPM_SRST_REQ_EN (1 << 22) +#define CPU0_DBG_SRST_REQ_EN (1 << 12) +#define CPU0_NEON_SRST_REQ_EN (1 << 4) +#define CPU0_SRST_REQ_EN (1 << 0) + +enum { + HI3620_CTRL, + ERROR_CTRL, +}; + +static void __iomem *ctrl_base = NULL; +static int id; + +static void set_cpu_hi3620(int cpu, bool enable) +{ + u32 val = 0; + + if (enable) { + /* MTCMOS set */ + if ((cpu == 2) || (cpu == 3)) + writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), + ctrl_base + SCPERPWREN); + udelay(100); + + /* Enable core */ + writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREEN); + + /* unreset */ + val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN + | CPU0_SRST_REQ_EN; + writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS); + /* reset */ + val |= CPU0_HPM_SRST_REQ_EN; + writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN); + + /* ISO disable */ + if ((cpu == 2) || (cpu == 3)) + writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), + ctrl_base + SCISODIS); + udelay(1); + + /* WFI Mask */ + val = readl_relaxed(ctrl_base + SCPERCTRL0); + val &= ~(CPU0_WFI_MASK_CFG << cpu); + writel_relaxed(val, ctrl_base + SCPERCTRL0); + + /* Unreset */ + val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN + | CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN; + writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS); + } else { + /* wfi mask */ + val = readl_relaxed(ctrl_base + SCPERCTRL0); + val |= (CPU0_WFI_MASK_CFG << cpu); + writel_relaxed(val, ctrl_base + SCPERCTRL0); + + /* disable core*/ + writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREDIS); + + if ((cpu == 2) || (cpu == 3)) { + /* iso enable */ + writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), + ctrl_base + SCISOEN); + udelay(1); + } + + /* reset */ + val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN + | CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN; + writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN); + + if ((cpu == 2) || (cpu == 3)) { + /* MTCMOS unset */ + writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), + ctrl_base + SCPERPWRDIS); + udelay(100); + } + } +} + +static int hi3xxx_hotplug_init(void) +{ + struct device_node *node; + + node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); + if (node) { + ctrl_base = of_iomap(node, 0); + id = HI3620_CTRL; + return 0; + } + id = ERROR_CTRL; + return -ENOENT; +} + +void hi3xxx_set_cpu(int cpu, bool enable) +{ + if (!ctrl_base) { + if (hi3xxx_hotplug_init() < 0) + return; + } + + if (id == HI3620_CTRL) + set_cpu_hi3620(cpu, enable); +} + +static inline void cpu_enter_lowpower(void) +{ + unsigned int v; + + flush_cache_all(); + + /* + * Turn off coherency and L1 D-cache + */ + asm volatile( + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, #0x40\n" + " mcr p15, 0, %0, c1, c0, 1\n" + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, #0x04\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "r" (0) + : "cc"); +} + +void hi3xxx_cpu_die(unsigned int cpu) +{ + cpu_enter_lowpower(); + hi3xxx_set_cpu_jump(cpu, phys_to_virt(0)); + cpu_do_idle(); + + /* We should have never returned from idle */ + panic("cpu %d unexpectedly exit from shutdown\n", cpu); +} + +int hi3xxx_cpu_kill(unsigned int cpu) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(50); + + while (hi3xxx_get_cpu_jump(cpu)) + if (time_after(jiffies, timeout)) + return 0; + hi3xxx_set_cpu(cpu, false); + return 1; +} diff --git a/arch/arm/mach-hi3xxx/platsmp.c b/arch/arm/mach-hi3xxx/platsmp.c index a4d04c0..4357758 100644 --- a/arch/arm/mach-hi3xxx/platsmp.c +++ b/arch/arm/mach-hi3xxx/platsmp.c @@ -73,6 +73,7 @@ static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus) static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle) { + hi3xxx_set_cpu(cpu, true); hi3xxx_set_cpu_jump(cpu, secondary_startup); arch_send_wakeup_ipi_mask(cpumask_of(cpu)); return 0; @@ -81,4 +82,8 @@ static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle) struct smp_operations hi3xxx_smp_ops __initdata = { .smp_prepare_cpus = hi3xxx_smp_prepare_cpus, .smp_boot_secondary = hi3xxx_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = hi3xxx_cpu_die, + .cpu_kill = hi3xxx_cpu_kill, +#endif };