static int sun8i_smp_boot_secondary(unsigned int cpu, struct task_struct *idle) { u32 reg; if (!(prcm_membase && cpucfg_membase)) return -EFAULT; spin_lock(&cpu_lock); /* Set CPU boot address */ writel(virt_to_phys(secondary_startup), cpucfg_membase + CPUCFG_PRIVATE0_REG); /* Assert the CPU core in reset */ writel(0, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu)); /* Assert the L1 cache in reset */ reg = readl(cpucfg_membase + CPUCFG_GEN_CTRL_REG); writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_GEN_CTRL_REG); /* Clear CPU power-off gating */ reg = readl(prcm_membase + PRCM_CPU_PWROFF_REG); writel(reg & ~BIT(cpu), prcm_membase + PRCM_CPU_PWROFF_REG); mdelay(1); /* Deassert the CPU core reset */ writel(3, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu)); spin_unlock(&cpu_lock); return 0; }
static int sun6i_smp_boot_secondary(unsigned int cpu, struct task_struct *idle) { u32 reg; int i; if (!(prcm_membase && cpucfg_membase)) return -EFAULT; spin_lock(&cpu_lock); /* Set CPU boot address */ writel(virt_to_phys(secondary_startup), cpucfg_membase + CPUCFG_PRIVATE0_REG); /* Assert the CPU core in reset */ writel(0, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu)); /* Assert the L1 cache in reset */ reg = readl(cpucfg_membase + CPUCFG_GEN_CTRL_REG); writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_GEN_CTRL_REG); /* Disable external debug access */ reg = readl(cpucfg_membase + CPUCFG_DBG_CTL1_REG); writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_DBG_CTL1_REG); /* Power up the CPU */ for (i = 0; i <= 8; i++) writel(0xff >> i, prcm_membase + PRCM_CPU_PWR_CLAMP_REG(cpu)); mdelay(10); /* Clear CPU power-off gating */ reg = readl(prcm_membase + PRCM_CPU_PWROFF_REG); writel(reg & ~BIT(cpu), prcm_membase + PRCM_CPU_PWROFF_REG); mdelay(1); /* Deassert the CPU core reset */ writel(3, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu)); /* Enable back the external debug accesses */ reg = readl(cpucfg_membase + CPUCFG_DBG_CTL1_REG); writel(reg | BIT(cpu), cpucfg_membase + CPUCFG_DBG_CTL1_REG); spin_unlock(&cpu_lock); return 0; }