diff options
author | Zhuoyu Zhang <Zhuoyu.Zhang@freescale.com> | 2014-12-11 03:14:08 (GMT) |
---|---|---|
committer | Zhengxiong Jin <Jason.Jin@freescale.com> | 2015-02-05 08:16:24 (GMT) |
commit | 2b1ea53af2c59f718f91ece8192f3b1b435a0f29 (patch) | |
tree | 1acc7ebb528a2d16f72a7be6739dda6ae5a9900b /arch/arm/mach-imx/platsmp.c | |
parent | 885df91947e29649eb4836001e7f7779ffdcb2a9 (diff) | |
download | linux-fsl-qoriq-2b1ea53af2c59f718f91ece8192f3b1b435a0f29.tar.xz |
arm: ls1: add error handling case
* Add iomap() error handling case and initialize rcpm_base when system
booting up.
* Only fill secondary_pre_boot_entry with value of SCRATCHRW1 register
when system boot up, do not need to fill it each time doing cpu-hotplug.
Signed-off-by: Zhuoyu Zhang <Zhuoyu.Zhang@freescale.com>
Change-Id: If672bd18074eea6db75c9273a7656aff983ffd9a
Reviewed-on: http://git.am.freescale.net:8181/28866
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Chenhui Zhao <chenhui.zhao@freescale.com>
Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Diffstat (limited to 'arch/arm/mach-imx/platsmp.c')
-rw-r--r-- | arch/arm/mach-imx/platsmp.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 22f9814..140c98c 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -19,6 +19,7 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/delay.h> +#include <asm/smp_plat.h> #include "common.h" #include "hardware.h" @@ -36,6 +37,8 @@ #define DCSR_RCPM2_DEBUG1 0x400 #define DCSR_RCPM2_DEBUG2 0x414 +#define CCSR_TWAITSR0 0x04C + #define STRIDE_4B 4 u32 g_diag_reg; @@ -43,6 +46,7 @@ static void __iomem *scu_base; static void __iomem *dcfg_base; static void __iomem *scfg_base; static void __iomem *dcsr_rcpm2_base; +static void __iomem *rcpm_base; static u32 secondary_pre_boot_entry; static struct map_desc scu_io_desc __initdata = { @@ -134,7 +138,7 @@ static int ls1021a_secondary_iomap(void) np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg"); if (!np) { pr_err("%s: failed to find dcfg node.\n", __func__); - ret = -EINVAL; + ret = -ENODEV; goto dcfg_err; } @@ -149,7 +153,7 @@ static int ls1021a_secondary_iomap(void) np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-scfg"); if (!np) { pr_err("%s: failed to find scfg node.\n", __func__); - ret = -EINVAL; + ret = -ENODEV; goto scfg_err; } @@ -164,7 +168,7 @@ static int ls1021a_secondary_iomap(void) np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcsr-rcpm"); if (!np) { pr_err("%s: failed to find dcsr node.\n", __func__); - ret = -EINVAL; + ret = -ENODEV; goto dcsr_err; } @@ -176,8 +180,25 @@ static int ls1021a_secondary_iomap(void) goto dcsr_err; } + np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-rcpm-2.1"); + if (!np) { + pr_err("%s(): failed to find the RCPM node.\n", __func__); + ret = -ENODEV; + goto rcpm_err; + } + + rcpm_base = of_iomap(np, 0); + of_node_put(np); + if (!rcpm_base) { + pr_err("%s: failed to map rcpm.\n", __func__); + ret = -ENOMEM; + goto rcpm_err; + } + return 0; +rcpm_err: + iounmap(dcsr_rcpm2_base); dcsr_err: iounmap(scfg_base); scfg_err: @@ -186,13 +207,18 @@ dcfg_err: return ret; } +u32 ls1_get_cpu_arg(int cpu) +{ + BUG_ON(!rcpm_base); + + cpu = cpu_logical_map(cpu); + return ioread32be(rcpm_base + CCSR_TWAITSR0) & (1 << cpu); +} + void ls1021a_set_secondary_entry(void) { unsigned long paddr; - secondary_pre_boot_entry = readl_relaxed(dcfg_base + - DCFG_CCSR_SCRATCHRW1); - if (dcfg_base) { paddr = virt_to_phys(secondary_startup); writel_relaxed(cpu_to_be32(paddr), @@ -259,6 +285,10 @@ static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus) { ls1021a_secondary_iomap(); + + secondary_pre_boot_entry = readl_relaxed(dcfg_base + + DCFG_CCSR_SCRATCHRW1); + ls1021a_set_secondary_entry(); } |