static int exynos5_cpu_up(int cpu) { u64 power_base_addr; u64 size; void __iomem *power; int rc; rc = exynos5_get_pmu_baseandsize(&power_base_addr, &size); if ( rc ) return rc; power = ioremap_nocache(power_base_addr, size); if ( !power ) { dprintk(XENLOG_ERR, "Unable to map power MMIO\n"); return -EFAULT; } rc = exynos5_cpu_power_up(power, cpu); if ( rc ) { iounmap(power); return -ETIMEDOUT; } iounmap(power); if ( secure_firmware ) call_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0); return cpu_up_send_sgi(cpu); }
int __init psci_init_0_2(void) { static const struct dt_device_match psci_ids[] __initconst = { DT_MATCH_COMPATIBLE("arm,psci-0.2"), DT_MATCH_COMPATIBLE("arm,psci-1.0"), { /* sentinel */ }, }; int ret; const struct dt_device_node *psci; psci = dt_find_matching_node(NULL, psci_ids); if ( !psci ) return -EOPNOTSUPP; ret = psci_is_smc_method(psci); if ( ret ) return -EINVAL; psci_ver = call_smc(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0); /* For the moment, we only support PSCI 0.2 and PSCI 1.x */ if ( psci_ver != PSCI_VERSION(0, 2) && PSCI_VERSION_MAJOR(psci_ver != 1) ) { printk("Error: Unrecognized PSCI version %u.%u\n", PSCI_VERSION_MAJOR(psci_ver), PSCI_VERSION_MINOR(psci_ver)); return -EOPNOTSUPP; } psci_cpu_on_nr = PSCI_0_2_FN_NATIVE(CPU_ON); printk(XENLOG_INFO "Using PSCI-%u.%u for SMP bringup\n", PSCI_VERSION_MAJOR(psci_ver), PSCI_VERSION_MINOR(psci_ver)); return 0; }
void call_psci_system_reset(void) { if ( psci_ver > PSCI_VERSION(0, 1) ) call_smc(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0); }
void call_psci_system_off(void) { if ( psci_ver > PSCI_VERSION(0, 1) ) call_smc(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0); }
int call_psci_cpu_on(int cpu) { return call_smc(psci_cpu_on_nr, cpu_logical_map(cpu), __pa(init_secondary), 0); }