ARM: hisi: rename hi3xxx to hisi
authorHaojian Zhuang <haojian.zhuang@linaro.org>
Fri, 20 Dec 2013 02:52:56 +0000 (10:52 +0800)
committerKevin Hilman <khilman@linaro.org>
Fri, 20 Dec 2013 16:23:01 +0000 (08:23 -0800)
Since some new Hisilicon SoCs are not named as hi3xxx, rename mach-hi3xxx
to mach-hisi instead. And the pronounciation of "hisi" is similar to the
chinese pronounciation of Hisilicon. So Hisilicon guys like this name.

ARCH_HI3xxx will be renamed later since other drivers are using it and
they are still in linux-next git tree. So rename ARCH_HI3xxx later.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Kevin Hilman <khilman@linaro.org>
14 files changed:
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/mach-hi3xxx/Kconfig [deleted file]
arch/arm/mach-hi3xxx/Makefile [deleted file]
arch/arm/mach-hi3xxx/core.h [deleted file]
arch/arm/mach-hi3xxx/hi3xxx.c [deleted file]
arch/arm/mach-hi3xxx/hotplug.c [deleted file]
arch/arm/mach-hi3xxx/platsmp.c [deleted file]
arch/arm/mach-hisi/Kconfig [new file with mode: 0644]
arch/arm/mach-hisi/Makefile [new file with mode: 0644]
arch/arm/mach-hisi/core.h [new file with mode: 0644]
arch/arm/mach-hisi/hisilicon.c [new file with mode: 0644]
arch/arm/mach-hisi/hotplug.c [new file with mode: 0644]
arch/arm/mach-hisi/platsmp.c [new file with mode: 0644]

index 75eb532..b7662df 100644 (file)
@@ -925,10 +925,10 @@ source "arch/arm/mach-footbridge/Kconfig"
 
 source "arch/arm/mach-gemini/Kconfig"
 
-source "arch/arm/mach-hi3xxx/Kconfig"
-
 source "arch/arm/mach-highbank/Kconfig"
 
+source "arch/arm/mach-hisi/Kconfig"
+
 source "arch/arm/mach-integrator/Kconfig"
 
 source "arch/arm/mach-iop32x/Kconfig"
index dfbafa3..173ea7b 100644 (file)
@@ -156,8 +156,8 @@ machine-$(CONFIG_ARCH_EBSA110)              += ebsa110
 machine-$(CONFIG_ARCH_EP93XX)          += ep93xx
 machine-$(CONFIG_ARCH_EXYNOS)          += exynos
 machine-$(CONFIG_ARCH_GEMINI)          += gemini
-machine-$(CONFIG_ARCH_HI3xxx)          += hi3xxx
 machine-$(CONFIG_ARCH_HIGHBANK)                += highbank
+machine-$(CONFIG_ARCH_HI3xxx)          += hisi
 machine-$(CONFIG_ARCH_INTEGRATOR)      += integrator
 machine-$(CONFIG_ARCH_IOP13XX)         += iop13xx
 machine-$(CONFIG_ARCH_IOP32X)          += iop32x
diff --git a/arch/arm/mach-hi3xxx/Kconfig b/arch/arm/mach-hi3xxx/Kconfig
deleted file mode 100644 (file)
index 018ad67..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-config ARCH_HI3xxx
-       bool "Hisilicon Hi36xx/Hi37xx family" if ARCH_MULTI_V7
-       select ARM_AMBA
-       select ARM_GIC
-       select ARM_TIMER_SP804
-       select ARCH_WANT_OPTIONAL_GPIOLIB
-       select CACHE_L2X0
-       select CLKSRC_OF
-       select GENERIC_CLOCKEVENTS
-       select HAVE_ARM_SCU
-       select HAVE_ARM_TWD
-       select HAVE_SMP
-       select PINCTRL
-       select PINCTRL_SINGLE
-       select SMP
-       help
-         Support for Hisilicon Hi36xx/Hi37xx processor family
diff --git a/arch/arm/mach-hi3xxx/Makefile b/arch/arm/mach-hi3xxx/Makefile
deleted file mode 100644 (file)
index c9919e8..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for Hisilicon Hi36xx/Hi37xx processors line
-#
-
-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
deleted file mode 100644 (file)
index af23ec2..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __HISILICON_CORE_H
-#define __HISILICON_CORE_H
-
-#include <linux/reboot.h>
-
-extern void hi3xxx_set_cpu_jump(int cpu, void *jump_addr);
-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/hi3xxx.c b/arch/arm/mach-hi3xxx/hi3xxx.c
deleted file mode 100644 (file)
index 661a912..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * (Hisilicon's Hi36xx/Hi37xx SoC based) flattened device tree enabled machine
- *
- * Copyright (c) 2012-2013 Hisilicon Ltd.
- * Copyright (c) 2012-2013 Linaro Ltd.
- *
- * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
- *
- * 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.
-*/
-
-#include <linux/clk-provider.h>
-#include <linux/clocksource.h>
-#include <linux/irqchip.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-
-#include <asm/proc-fns.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "core.h"
-
-#define HI3620_SYSCTRL_PHYS_BASE               0xfc802000
-#define HI3620_SYSCTRL_VIRT_BASE               0xfe802000
-
-/*
- * This table is only for optimization. Since ioremap() could always share
- * the same mapping if it's defined as static IO mapping.
- *
- * Without this table, system could also work. The cost is some virtual address
- * spaces wasted since ioremap() may be called multi times for the same
- * IO space.
- */
-static struct map_desc hi3620_io_desc[] __initdata = {
-       {
-               /* sysctrl */
-               .pfn            = __phys_to_pfn(HI3620_SYSCTRL_PHYS_BASE),
-               .virtual        = HI3620_SYSCTRL_VIRT_BASE,
-               .length         = 0x1000,
-               .type           = MT_DEVICE,
-       },
-};
-
-static void __init hi3620_map_io(void)
-{
-       debug_ll_io_init();
-       iotable_init(hi3620_io_desc, ARRAY_SIZE(hi3620_io_desc));
-}
-
-static void __init hi3xxx_timer_init(void)
-{
-       of_clk_init(NULL);
-       clocksource_of_init();
-}
-
-static void hi3xxx_restart(enum reboot_mode mode, const char *cmd)
-{
-       struct device_node *np;
-       void __iomem *base;
-       int offset;
-
-       np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
-       if (!np) {
-               pr_err("failed to find hisilicon,sysctrl node\n");
-               return;
-       }
-       base = of_iomap(np, 0);
-       if (!base) {
-               pr_err("failed to map address in hisilicon,sysctrl node\n");
-               return;
-       }
-       if (of_property_read_u32(np, "reboot-offset", &offset) < 0) {
-               pr_err("failed to find reboot-offset property\n");
-               return;
-       }
-       writel_relaxed(0xdeadbeef, base + offset);
-
-       while (1)
-               cpu_do_idle();
-}
-
-static const char *hi3xxx_compat[] __initconst = {
-       "hisilicon,hi3620-hi4511",
-       NULL,
-};
-
-DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)")
-       .map_io         = hi3620_map_io,
-       .init_time      = hi3xxx_timer_init,
-       .dt_compat      = hi3xxx_compat,
-       .smp            = smp_ops(hi3xxx_smp_ops),
-       .restart        = hi3xxx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-hi3xxx/hotplug.c b/arch/arm/mach-hi3xxx/hotplug.c
deleted file mode 100644 (file)
index b909854..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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 <linux/cpu.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <asm/cacheflush.h>
-#include <asm/smp_plat.h>
-#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;
-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
deleted file mode 100644 (file)
index 471f1ee..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2013 Linaro Ltd.
- * Copyright (c) 2013 Hisilicon Limited.
- * Based on arch/arm/mach-vexpress/platsmp.c, Copyright (C) 2002 ARM Ltd.
- *
- * 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 <linux/smp.h>
-#include <linux/io.h>
-#include <linux/of_address.h>
-
-#include <asm/cacheflush.h>
-#include <asm/smp_plat.h>
-#include <asm/smp_scu.h>
-
-#include "core.h"
-
-static void __iomem *ctrl_base;
-
-void hi3xxx_set_cpu_jump(int cpu, void *jump_addr)
-{
-       cpu = cpu_logical_map(cpu);
-       if (!cpu || !ctrl_base)
-               return;
-       writel_relaxed(virt_to_phys(jump_addr), ctrl_base + ((cpu - 1) << 2));
-}
-
-int hi3xxx_get_cpu_jump(int cpu)
-{
-       cpu = cpu_logical_map(cpu);
-       if (!cpu || !ctrl_base)
-               return 0;
-       return readl_relaxed(ctrl_base + ((cpu - 1) << 2));
-}
-
-static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus)
-{
-       struct device_node *np = NULL;
-       unsigned long base = 0;
-       u32 offset = 0;
-       void __iomem *scu_base = NULL;
-
-       if (scu_a9_has_base()) {
-               base = scu_a9_get_base();
-               scu_base = ioremap(base, SZ_4K);
-               if (!scu_base) {
-                       pr_err("ioremap(scu_base) failed\n");
-                       return;
-               }
-               scu_enable(scu_base);
-               iounmap(scu_base);
-       }
-       if (!ctrl_base) {
-               np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
-               if (!np) {
-                       pr_err("failed to find hisilicon,sysctrl node\n");
-                       return;
-               }
-               ctrl_base = of_iomap(np, 0);
-               if (!ctrl_base) {
-                       pr_err("failed to map address\n");
-                       return;
-               }
-               if (of_property_read_u32(np, "smp-offset", &offset) < 0) {
-                       pr_err("failed to find smp-offset property\n");
-                       return;
-               }
-               ctrl_base += offset;
-       }
-}
-
-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;
-}
-
-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
-};
diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig
new file mode 100644 (file)
index 0000000..018ad67
--- /dev/null
@@ -0,0 +1,17 @@
+config ARCH_HI3xxx
+       bool "Hisilicon Hi36xx/Hi37xx family" if ARCH_MULTI_V7
+       select ARM_AMBA
+       select ARM_GIC
+       select ARM_TIMER_SP804
+       select ARCH_WANT_OPTIONAL_GPIOLIB
+       select CACHE_L2X0
+       select CLKSRC_OF
+       select GENERIC_CLOCKEVENTS
+       select HAVE_ARM_SCU
+       select HAVE_ARM_TWD
+       select HAVE_SMP
+       select PINCTRL
+       select PINCTRL_SINGLE
+       select SMP
+       help
+         Support for Hisilicon Hi36xx/Hi37xx processor family
diff --git a/arch/arm/mach-hisi/Makefile b/arch/arm/mach-hisi/Makefile
new file mode 100644 (file)
index 0000000..6870058
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for Hisilicon processors family
+#
+
+obj-y  += hisilicon.o
+obj-$(CONFIG_SMP)              += platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
diff --git a/arch/arm/mach-hisi/core.h b/arch/arm/mach-hisi/core.h
new file mode 100644 (file)
index 0000000..af23ec2
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __HISILICON_CORE_H
+#define __HISILICON_CORE_H
+
+#include <linux/reboot.h>
+
+extern void hi3xxx_set_cpu_jump(int cpu, void *jump_addr);
+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-hisi/hisilicon.c b/arch/arm/mach-hisi/hisilicon.c
new file mode 100644 (file)
index 0000000..685d9eb
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * (Hisilicon's SoC based) flattened device tree enabled machine
+ *
+ * Copyright (c) 2012-2013 Hisilicon Ltd.
+ * Copyright (c) 2012-2013 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * 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.
+*/
+
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#include <asm/proc-fns.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "core.h"
+
+#define HI3620_SYSCTRL_PHYS_BASE               0xfc802000
+#define HI3620_SYSCTRL_VIRT_BASE               0xfe802000
+
+/*
+ * This table is only for optimization. Since ioremap() could always share
+ * the same mapping if it's defined as static IO mapping.
+ *
+ * Without this table, system could also work. The cost is some virtual address
+ * spaces wasted since ioremap() may be called multi times for the same
+ * IO space.
+ */
+static struct map_desc hi3620_io_desc[] __initdata = {
+       {
+               /* sysctrl */
+               .pfn            = __phys_to_pfn(HI3620_SYSCTRL_PHYS_BASE),
+               .virtual        = HI3620_SYSCTRL_VIRT_BASE,
+               .length         = 0x1000,
+               .type           = MT_DEVICE,
+       },
+};
+
+static void __init hi3620_map_io(void)
+{
+       debug_ll_io_init();
+       iotable_init(hi3620_io_desc, ARRAY_SIZE(hi3620_io_desc));
+}
+
+static void __init hi3xxx_timer_init(void)
+{
+       of_clk_init(NULL);
+       clocksource_of_init();
+}
+
+static void hi3xxx_restart(enum reboot_mode mode, const char *cmd)
+{
+       struct device_node *np;
+       void __iomem *base;
+       int offset;
+
+       np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+       if (!np) {
+               pr_err("failed to find hisilicon,sysctrl node\n");
+               return;
+       }
+       base = of_iomap(np, 0);
+       if (!base) {
+               pr_err("failed to map address in hisilicon,sysctrl node\n");
+               return;
+       }
+       if (of_property_read_u32(np, "reboot-offset", &offset) < 0) {
+               pr_err("failed to find reboot-offset property\n");
+               return;
+       }
+       writel_relaxed(0xdeadbeef, base + offset);
+
+       while (1)
+               cpu_do_idle();
+}
+
+static const char *hi3xxx_compat[] __initconst = {
+       "hisilicon,hi3620-hi4511",
+       NULL,
+};
+
+DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)")
+       .map_io         = hi3620_map_io,
+       .init_time      = hi3xxx_timer_init,
+       .dt_compat      = hi3xxx_compat,
+       .smp            = smp_ops(hi3xxx_smp_ops),
+       .restart        = hi3xxx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-hisi/hotplug.c b/arch/arm/mach-hisi/hotplug.c
new file mode 100644 (file)
index 0000000..b909854
--- /dev/null
@@ -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 <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#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;
+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-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c
new file mode 100644 (file)
index 0000000..471f1ee
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013 Linaro Ltd.
+ * Copyright (c) 2013 Hisilicon Limited.
+ * Based on arch/arm/mach-vexpress/platsmp.c, Copyright (C) 2002 ARM Ltd.
+ *
+ * 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 <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include "core.h"
+
+static void __iomem *ctrl_base;
+
+void hi3xxx_set_cpu_jump(int cpu, void *jump_addr)
+{
+       cpu = cpu_logical_map(cpu);
+       if (!cpu || !ctrl_base)
+               return;
+       writel_relaxed(virt_to_phys(jump_addr), ctrl_base + ((cpu - 1) << 2));
+}
+
+int hi3xxx_get_cpu_jump(int cpu)
+{
+       cpu = cpu_logical_map(cpu);
+       if (!cpu || !ctrl_base)
+               return 0;
+       return readl_relaxed(ctrl_base + ((cpu - 1) << 2));
+}
+
+static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus)
+{
+       struct device_node *np = NULL;
+       unsigned long base = 0;
+       u32 offset = 0;
+       void __iomem *scu_base = NULL;
+
+       if (scu_a9_has_base()) {
+               base = scu_a9_get_base();
+               scu_base = ioremap(base, SZ_4K);
+               if (!scu_base) {
+                       pr_err("ioremap(scu_base) failed\n");
+                       return;
+               }
+               scu_enable(scu_base);
+               iounmap(scu_base);
+       }
+       if (!ctrl_base) {
+               np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+               if (!np) {
+                       pr_err("failed to find hisilicon,sysctrl node\n");
+                       return;
+               }
+               ctrl_base = of_iomap(np, 0);
+               if (!ctrl_base) {
+                       pr_err("failed to map address\n");
+                       return;
+               }
+               if (of_property_read_u32(np, "smp-offset", &offset) < 0) {
+                       pr_err("failed to find smp-offset property\n");
+                       return;
+               }
+               ctrl_base += offset;
+       }
+}
+
+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;
+}
+
+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
+};