acpi.c (b10d79f76085b577673395daf92d6208ae09196f) | acpi.c (fccb9a81fd08b61bed91ddef88341694f8ecbfd1) |
---|---|
1/* 2 * ARM64 Specific Low-Level ACPI Boot Support 3 * 4 * Copyright (C) 2013-2014, Linaro Ltd. 5 * Author: Al Stone <al.stone@linaro.org> 6 * Author: Graeme Gregory <graeme.gregory@linaro.org> 7 * Author: Hanjun Guo <hanjun.guo@linaro.org> 8 * Author: Tomasz Nowicki <tomasz.nowicki@linaro.org> --- 11 unchanged lines hidden (view full) --- 20#include <linux/cpumask.h> 21#include <linux/init.h> 22#include <linux/irq.h> 23#include <linux/irqdomain.h> 24#include <linux/memblock.h> 25#include <linux/of_fdt.h> 26#include <linux/smp.h> 27 | 1/* 2 * ARM64 Specific Low-Level ACPI Boot Support 3 * 4 * Copyright (C) 2013-2014, Linaro Ltd. 5 * Author: Al Stone <al.stone@linaro.org> 6 * Author: Graeme Gregory <graeme.gregory@linaro.org> 7 * Author: Hanjun Guo <hanjun.guo@linaro.org> 8 * Author: Tomasz Nowicki <tomasz.nowicki@linaro.org> --- 11 unchanged lines hidden (view full) --- 20#include <linux/cpumask.h> 21#include <linux/init.h> 22#include <linux/irq.h> 23#include <linux/irqdomain.h> 24#include <linux/memblock.h> 25#include <linux/of_fdt.h> 26#include <linux/smp.h> 27 |
28#include <asm/cputype.h> 29#include <asm/cpu_ops.h> 30#include <asm/smp_plat.h> 31 |
|
28int acpi_noirq = 1; /* skip ACPI IRQ initialization */ 29int acpi_disabled = 1; 30EXPORT_SYMBOL(acpi_disabled); 31 32int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */ 33EXPORT_SYMBOL(acpi_pci_disabled); 34 | 32int acpi_noirq = 1; /* skip ACPI IRQ initialization */ 33int acpi_disabled = 1; 34EXPORT_SYMBOL(acpi_disabled); 35 36int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */ 37EXPORT_SYMBOL(acpi_pci_disabled); 38 |
39/* Processors with enabled flag and sane MPIDR */ 40static int enabled_cpus; 41 42/* Boot CPU is valid or not in MADT */ 43static bool bootcpu_valid __initdata; 44 |
|
35static bool param_acpi_off __initdata; 36static bool param_acpi_force __initdata; 37 38static int __init parse_acpi(char *arg) 39{ 40 if (!arg) 41 return -EINVAL; 42 --- 37 unchanged lines hidden (view full) --- 80void __init __acpi_unmap_table(char *map, unsigned long size) 81{ 82 if (!map || !size) 83 return; 84 85 early_memunmap(map, size); 86} 87 | 45static bool param_acpi_off __initdata; 46static bool param_acpi_force __initdata; 47 48static int __init parse_acpi(char *arg) 49{ 50 if (!arg) 51 return -EINVAL; 52 --- 37 unchanged lines hidden (view full) --- 90void __init __acpi_unmap_table(char *map, unsigned long size) 91{ 92 if (!map || !size) 93 return; 94 95 early_memunmap(map, size); 96} 97 |
98/** 99 * acpi_map_gic_cpu_interface - generates a logical cpu number 100 * and map to MPIDR represented by GICC structure 101 * @mpidr: CPU's hardware id to register, MPIDR represented in MADT 102 * @enabled: this cpu is enabled or not 103 * 104 * Returns the logical cpu number which maps to MPIDR 105 */ 106static int __init acpi_map_gic_cpu_interface(u64 mpidr, u8 enabled) 107{ 108 int i; 109 110 if (mpidr == INVALID_HWID) { 111 pr_info("Skip MADT cpu entry with invalid MPIDR\n"); 112 return -EINVAL; 113 } 114 115 total_cpus++; 116 if (!enabled) 117 return -EINVAL; 118 119 if (enabled_cpus >= NR_CPUS) { 120 pr_warn("NR_CPUS limit of %d reached, Processor %d/0x%llx ignored.\n", 121 NR_CPUS, total_cpus, mpidr); 122 return -EINVAL; 123 } 124 125 /* Check if GICC structure of boot CPU is available in the MADT */ 126 if (cpu_logical_map(0) == mpidr) { 127 if (bootcpu_valid) { 128 pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n", 129 mpidr); 130 return -EINVAL; 131 } 132 133 bootcpu_valid = true; 134 } 135 136 /* 137 * Duplicate MPIDRs are a recipe for disaster. Scan 138 * all initialized entries and check for 139 * duplicates. If any is found just ignore the CPU. 140 */ 141 for (i = 1; i < enabled_cpus; i++) { 142 if (cpu_logical_map(i) == mpidr) { 143 pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n", 144 mpidr); 145 return -EINVAL; 146 } 147 } 148 149 if (!acpi_psci_present()) 150 return -EOPNOTSUPP; 151 152 cpu_ops[enabled_cpus] = cpu_get_ops("psci"); 153 /* CPU 0 was already initialized */ 154 if (enabled_cpus) { 155 if (!cpu_ops[enabled_cpus]) 156 return -EINVAL; 157 158 if (cpu_ops[enabled_cpus]->cpu_init(NULL, enabled_cpus)) 159 return -EOPNOTSUPP; 160 161 /* map the logical cpu id to cpu MPIDR */ 162 cpu_logical_map(enabled_cpus) = mpidr; 163 } 164 165 enabled_cpus++; 166 return enabled_cpus; 167} 168 169static int __init 170acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header, 171 const unsigned long end) 172{ 173 struct acpi_madt_generic_interrupt *processor; 174 175 processor = (struct acpi_madt_generic_interrupt *)header; 176 177 if (BAD_MADT_ENTRY(processor, end)) 178 return -EINVAL; 179 180 acpi_table_print_madt_entry(header); 181 182 acpi_map_gic_cpu_interface(processor->arm_mpidr & MPIDR_HWID_BITMASK, 183 processor->flags & ACPI_MADT_ENABLED); 184 185 return 0; 186} 187 188/* Parse GIC cpu interface entries in MADT for SMP init */ 189void __init acpi_init_cpus(void) 190{ 191 int count, i; 192 193 /* 194 * do a partial walk of MADT to determine how many CPUs 195 * we have including disabled CPUs, and get information 196 * we need for SMP init 197 */ 198 count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, 199 acpi_parse_gic_cpu_interface, 0); 200 201 if (!count) { 202 pr_err("No GIC CPU interface entries present\n"); 203 return; 204 } else if (count < 0) { 205 pr_err("Error parsing GIC CPU interface entry\n"); 206 return; 207 } 208 209 if (!bootcpu_valid) { 210 pr_err("MADT missing boot CPU MPIDR, not enabling secondaries\n"); 211 return; 212 } 213 214 for (i = 0; i < enabled_cpus; i++) 215 set_cpu_possible(i, true); 216 217 /* Make boot-up look pretty */ 218 pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus); 219} 220 |
|
88static int __init acpi_parse_fadt(struct acpi_table_header *table) 89{ 90 struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; 91 92 /* 93 * Revision in table header is the FADT Major revision, and there 94 * is a minor revision of FADT which was introduced by ACPI 5.1, 95 * we only deal with ACPI 5.1 or newer revision to get GIC and SMP 96 * boot protocol configuration data, or we will disable ACPI. 97 */ 98 if (table->revision > 5 || | 221static int __init acpi_parse_fadt(struct acpi_table_header *table) 222{ 223 struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; 224 225 /* 226 * Revision in table header is the FADT Major revision, and there 227 * is a minor revision of FADT which was introduced by ACPI 5.1, 228 * we only deal with ACPI 5.1 or newer revision to get GIC and SMP 229 * boot protocol configuration data, or we will disable ACPI. 230 */ 231 if (table->revision > 5 || |
99 (table->revision == 5 && fadt->minor_revision >= 1)) 100 return 0; | 232 (table->revision == 5 && fadt->minor_revision >= 1)) { 233 /* 234 * ACPI 5.1 only has two explicit methods to boot up SMP, 235 * PSCI and Parking protocol, but the Parking protocol is 236 * only specified for ARMv7 now, so make PSCI as the only 237 * way for the SMP boot protocol before some updates for 238 * the Parking protocol spec. 239 */ 240 if (acpi_psci_present()) 241 return 0; |
101 | 242 |
243 pr_warn("No PSCI support, will not bring up secondary CPUs\n"); 244 return -EOPNOTSUPP; 245 } 246 |
|
102 pr_warn("Unsupported FADT revision %d.%d, should be 5.1+, will disable ACPI\n", 103 table->revision, fadt->minor_revision); 104 disable_acpi(); 105 106 return -EINVAL; 107} 108 109/* --- 34 unchanged lines hidden --- | 247 pr_warn("Unsupported FADT revision %d.%d, should be 5.1+, will disable ACPI\n", 248 table->revision, fadt->minor_revision); 249 disable_acpi(); 250 251 return -EINVAL; 252} 253 254/* --- 34 unchanged lines hidden --- |