diff options
-rw-r--r-- | arch/arm64/kernel/acpi.c | 73 | ||||
-rw-r--r-- | drivers/acpi/bus.c | 3 | ||||
-rw-r--r-- | include/linux/acpi.h | 1 |
3 files changed, 77 insertions, 0 deletions
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index c9203c0a1179..dec6f8aed3dc 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c | |||
@@ -76,6 +76,12 @@ static int __init dt_scan_depth1_nodes(unsigned long node, | |||
76 | } | 76 | } |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * Since we're on ARM, the default interrupt routing model | ||
80 | * clearly has to be GIC. | ||
81 | */ | ||
82 | enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_GIC; | ||
83 | |||
84 | /* | ||
79 | * __acpi_map_table() will be called before page_init(), so early_ioremap() | 85 | * __acpi_map_table() will be called before page_init(), so early_ioremap() |
80 | * or early_memremap() should be called here to for ACPI table mapping. | 86 | * or early_memremap() should be called here to for ACPI table mapping. |
81 | */ | 87 | */ |
@@ -218,6 +224,73 @@ void __init acpi_init_cpus(void) | |||
218 | pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus); | 224 | pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus); |
219 | } | 225 | } |
220 | 226 | ||
227 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | ||
228 | { | ||
229 | *irq = irq_find_mapping(NULL, gsi); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); | ||
234 | |||
235 | /* | ||
236 | * success: return IRQ number (>0) | ||
237 | * failure: return =< 0 | ||
238 | */ | ||
239 | int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) | ||
240 | { | ||
241 | unsigned int irq; | ||
242 | unsigned int irq_type; | ||
243 | |||
244 | /* | ||
245 | * ACPI have no bindings to indicate SPI or PPI, so we | ||
246 | * use different mappings from DT in ACPI. | ||
247 | * | ||
248 | * For FDT | ||
249 | * PPI interrupt: in the range [0, 15]; | ||
250 | * SPI interrupt: in the range [0, 987]; | ||
251 | * | ||
252 | * For ACPI, GSI should be unique so using | ||
253 | * the hwirq directly for the mapping: | ||
254 | * PPI interrupt: in the range [16, 31]; | ||
255 | * SPI interrupt: in the range [32, 1019]; | ||
256 | */ | ||
257 | |||
258 | if (trigger == ACPI_EDGE_SENSITIVE && | ||
259 | polarity == ACPI_ACTIVE_LOW) | ||
260 | irq_type = IRQ_TYPE_EDGE_FALLING; | ||
261 | else if (trigger == ACPI_EDGE_SENSITIVE && | ||
262 | polarity == ACPI_ACTIVE_HIGH) | ||
263 | irq_type = IRQ_TYPE_EDGE_RISING; | ||
264 | else if (trigger == ACPI_LEVEL_SENSITIVE && | ||
265 | polarity == ACPI_ACTIVE_LOW) | ||
266 | irq_type = IRQ_TYPE_LEVEL_LOW; | ||
267 | else if (trigger == ACPI_LEVEL_SENSITIVE && | ||
268 | polarity == ACPI_ACTIVE_HIGH) | ||
269 | irq_type = IRQ_TYPE_LEVEL_HIGH; | ||
270 | else | ||
271 | irq_type = IRQ_TYPE_NONE; | ||
272 | |||
273 | /* | ||
274 | * Since only one GIC is supported in ACPI 5.0, we can | ||
275 | * create mapping refer to the default domain | ||
276 | */ | ||
277 | irq = irq_create_mapping(NULL, gsi); | ||
278 | if (!irq) | ||
279 | return irq; | ||
280 | |||
281 | /* Set irq type if specified and different than the current one */ | ||
282 | if (irq_type != IRQ_TYPE_NONE && | ||
283 | irq_type != irq_get_trigger_type(irq)) | ||
284 | irq_set_irq_type(irq, irq_type); | ||
285 | return irq; | ||
286 | } | ||
287 | EXPORT_SYMBOL_GPL(acpi_register_gsi); | ||
288 | |||
289 | void acpi_unregister_gsi(u32 gsi) | ||
290 | { | ||
291 | } | ||
292 | EXPORT_SYMBOL_GPL(acpi_unregister_gsi); | ||
293 | |||
221 | static int __init acpi_parse_fadt(struct acpi_table_header *table) | 294 | static int __init acpi_parse_fadt(struct acpi_table_header *table) |
222 | { | 295 | { |
223 | struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; | 296 | struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 8b67bd0f6bb5..c412fdb28d34 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -448,6 +448,9 @@ static int __init acpi_bus_init_irq(void) | |||
448 | case ACPI_IRQ_MODEL_IOSAPIC: | 448 | case ACPI_IRQ_MODEL_IOSAPIC: |
449 | message = "IOSAPIC"; | 449 | message = "IOSAPIC"; |
450 | break; | 450 | break; |
451 | case ACPI_IRQ_MODEL_GIC: | ||
452 | message = "GIC"; | ||
453 | break; | ||
451 | case ACPI_IRQ_MODEL_PLATFORM: | 454 | case ACPI_IRQ_MODEL_PLATFORM: |
452 | message = "platform specific model"; | 455 | message = "platform specific model"; |
453 | break; | 456 | break; |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 6ec33c595aea..de4e86f89c83 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -73,6 +73,7 @@ enum acpi_irq_model_id { | |||
73 | ACPI_IRQ_MODEL_IOAPIC, | 73 | ACPI_IRQ_MODEL_IOAPIC, |
74 | ACPI_IRQ_MODEL_IOSAPIC, | 74 | ACPI_IRQ_MODEL_IOSAPIC, |
75 | ACPI_IRQ_MODEL_PLATFORM, | 75 | ACPI_IRQ_MODEL_PLATFORM, |
76 | ACPI_IRQ_MODEL_GIC, | ||
76 | ACPI_IRQ_MODEL_COUNT | 77 | ACPI_IRQ_MODEL_COUNT |
77 | }; | 78 | }; |
78 | 79 | ||