Beispiel #1
0
/*
 * We use PSCI 0.2+ when ACPI is deployed on ARM64 and it's
 * explicitly clarified in SBBR
 */
int __init psci_acpi_init(void)
{
	if (!acpi_psci_present()) {
		pr_info("is not implemented in ACPI.\n");
		return -EOPNOTSUPP;
	}

	pr_info("probing for conduit method from ACPI.\n");

	if (acpi_psci_use_hvc())
		invoke_psci_fn = __invoke_psci_fn_hvc;
	else
		invoke_psci_fn = __invoke_psci_fn_smc;

	return psci_probe();
}
Beispiel #2
0
/**
 * acpi_map_gic_cpu_interface - generates a logical cpu number
 * and map to MPIDR represented by GICC structure
 */
static void __init
acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
{
	int i;
	u64 mpidr = processor->arm_mpidr & MPIDR_HWID_BITMASK;
	bool enabled = !!(processor->flags & ACPI_MADT_ENABLED);

	if (mpidr == INVALID_HWID) {
		pr_info("Skip MADT cpu entry with invalid MPIDR\n");
		return;
	}

	total_cpus++;
	if (!enabled)
		return;

	if (enabled_cpus >=  NR_CPUS) {
		pr_warn("NR_CPUS limit of %d reached, Processor %d/0x%llx ignored.\n",
			NR_CPUS, total_cpus, mpidr);
		return;
	}

	/* Check if GICC structure of boot CPU is available in the MADT */
	if (cpu_logical_map(0) == mpidr) {
		if (bootcpu_valid) {
			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
			       mpidr);
			return;
		}

		bootcpu_valid = true;
	}

	/*
	 * Duplicate MPIDRs are a recipe for disaster. Scan
	 * all initialized entries and check for
	 * duplicates. If any is found just ignore the CPU.
	 */
	for (i = 1; i < enabled_cpus; i++) {
		if (cpu_logical_map(i) == mpidr) {
			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
			       mpidr);
			return;
		}
	}

	if (!acpi_psci_present())
		return;

	cpu_ops[enabled_cpus] = cpu_get_ops("psci");
	/* CPU 0 was already initialized */
	if (enabled_cpus) {
		if (!cpu_ops[enabled_cpus])
			return;

		if (cpu_ops[enabled_cpus]->cpu_init(NULL, enabled_cpus))
			return;

		/* map the logical cpu id to cpu MPIDR */
		cpu_logical_map(enabled_cpus) = mpidr;
	}

	enabled_cpus++;
}