summaryrefslogtreecommitdiff
path: root/arch/arm/mach-shmobile/platsmp-apmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-shmobile/platsmp-apmu.c')
-rw-r--r--arch/arm/mach-shmobile/platsmp-apmu.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c
index 0c6bb458b7a4..3ca2c13346f0 100644
--- a/arch/arm/mach-shmobile/platsmp-apmu.c
+++ b/arch/arm/mach-shmobile/platsmp-apmu.c
@@ -31,9 +31,21 @@ static struct {
int bit;
} apmu_cpus[NR_CPUS];
-#define WUPCR_OFFS 0x10
-#define PSTR_OFFS 0x40
-#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n)))
+#define WUPCR_OFFS 0x10 /* Wake Up Control Register */
+#define PSTR_OFFS 0x40 /* Power Status Register */
+#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n)))
+ /* CPUn Power Status Control Register */
+#define DBGRCR_OFFS 0x180 /* Debug Resource Reset Control Reg. */
+
+/* Power Status Register */
+#define CPUNST(r, n) (((r) >> (n * 4)) & 3) /* CPUn Status Bit */
+#define CPUST_RUN 0 /* Run Mode */
+#define CPUST_STANDBY 3 /* CoreStandby Mode */
+
+/* Debug Resource Reset Control Register */
+#define DBGCPUREN BIT(24) /* CPU Other Reset Request Enable */
+#define DBGCPUNREN(n) BIT((n) + 20) /* CPUn Reset Request Enable */
+#define DBGCPUPREN BIT(19) /* CPU Peripheral Reset Req. Enable */
static int __maybe_unused apmu_power_on(void __iomem *p, int bit)
{
@@ -59,7 +71,7 @@ static int __maybe_unused apmu_power_off_poll(void __iomem *p, int bit)
int k;
for (k = 0; k < 1000; k++) {
- if (((readl_relaxed(p + PSTR_OFFS) >> (bit * 4)) & 0x03) == 3)
+ if (CPUNST(readl_relaxed(p + PSTR_OFFS), bit) == CPUST_STANDBY)
return 1;
mdelay(1);
@@ -78,6 +90,8 @@ static int __maybe_unused apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)
#ifdef CONFIG_SMP
static void apmu_init_cpu(struct resource *res, int cpu, int bit)
{
+ u32 x;
+
if ((cpu >= ARRAY_SIZE(apmu_cpus)) || apmu_cpus[cpu].iomem)
return;
@@ -85,6 +99,11 @@ static void apmu_init_cpu(struct resource *res, int cpu, int bit)
apmu_cpus[cpu].bit = bit;
pr_debug("apmu ioremap %d %d %pr\n", cpu, bit, res);
+
+ /* Setup for debug mode */
+ x = readl(apmu_cpus[cpu].iomem + DBGRCR_OFFS);
+ x |= DBGCPUREN | DBGCPUNREN(bit) | DBGCPUPREN;
+ writel(x, apmu_cpus[cpu].iomem + DBGRCR_OFFS);
}
static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit),
@@ -171,7 +190,7 @@ static void apmu_parse_dt(void (*fn)(struct resource *res, int cpu, int bit))
static void __init shmobile_smp_apmu_setup_boot(void)
{
/* install boot code shared by all CPUs */
- shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
+ shmobile_boot_fn = __pa_symbol(shmobile_smp_boot);
}
void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
@@ -185,7 +204,7 @@ void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
/* For this particular CPU register boot vector */
- shmobile_smp_hook(cpu, virt_to_phys(secondary_startup), 0);
+ shmobile_smp_hook(cpu, __pa_symbol(secondary_startup), 0);
return apmu_wrap(cpu, apmu_power_on);
}
@@ -197,21 +216,9 @@ static void __init shmobile_smp_apmu_prepare_cpus_dt(unsigned int max_cpus)
rcar_gen2_pm_init();
}
-static int shmobile_smp_apmu_boot_secondary_md21(unsigned int cpu,
- struct task_struct *idle)
-{
- /* Error out when hardware debug mode is enabled */
- if (rcar_gen2_read_mode_pins() & BIT(21)) {
- pr_warn("Unable to boot CPU%u when MD21 is set\n", cpu);
- return -ENOTSUPP;
- }
-
- return shmobile_smp_apmu_boot_secondary(cpu, idle);
-}
-
static struct smp_operations apmu_smp_ops __initdata = {
.smp_prepare_cpus = shmobile_smp_apmu_prepare_cpus_dt,
- .smp_boot_secondary = shmobile_smp_apmu_boot_secondary_md21,
+ .smp_boot_secondary = shmobile_smp_apmu_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_can_disable = shmobile_smp_cpu_can_disable,
.cpu_die = shmobile_smp_apmu_cpu_die,
@@ -301,7 +308,7 @@ int shmobile_smp_apmu_cpu_kill(unsigned int cpu)
#if defined(CONFIG_SUSPEND)
static int shmobile_smp_apmu_do_suspend(unsigned long cpu)
{
- shmobile_smp_hook(cpu, virt_to_phys(cpu_resume), 0);
+ shmobile_smp_hook(cpu, __pa_symbol(cpu_resume), 0);
shmobile_smp_apmu_cpu_shutdown(cpu);
cpu_do_idle(); /* WFI selects Core Standby */
return 1;