diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/Kconfig | 10 | ||||
-rw-r--r-- | drivers/acpi/Makefile | 3 | ||||
-rw-r--r-- | drivers/acpi/acpi_pnp.c | 2 | ||||
-rw-r--r-- | drivers/acpi/acpi_processor.c | 7 | ||||
-rw-r--r-- | drivers/acpi/acpica/utglobal.c | 13 | ||||
-rw-r--r-- | drivers/acpi/bus.c | 3 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 2 | ||||
-rw-r--r-- | drivers/acpi/gsi.c | 105 | ||||
-rw-r--r-- | drivers/acpi/internal.h | 4 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 12 | ||||
-rw-r--r-- | drivers/acpi/processor_core.c | 60 | ||||
-rw-r--r-- | drivers/acpi/resource.c | 2 | ||||
-rw-r--r-- | drivers/acpi/sbs.c | 2 | ||||
-rw-r--r-- | drivers/acpi/sbshc.c | 22 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 39 | ||||
-rw-r--r-- | drivers/acpi/tables.c | 52 |
16 files changed, 278 insertions, 60 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index e6c3ddd92665..ab2cbb51c6aa 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -5,7 +5,7 @@ menuconfig ACPI bool "ACPI (Advanced Configuration and Power Interface) Support" depends on !IA64_HP_SIM - depends on IA64 || X86 + depends on IA64 || X86 || (ARM64 && EXPERT) depends on PCI select PNP default y @@ -48,9 +48,16 @@ config ACPI_LEGACY_TABLES_LOOKUP config ARCH_MIGHT_HAVE_ACPI_PDC bool +config ACPI_GENERIC_GSI + bool + +config ACPI_SYSTEM_POWER_STATES_SUPPORT + bool + config ACPI_SLEEP bool depends on SUSPEND || HIBERNATION + depends on ACPI_SYSTEM_POWER_STATES_SUPPORT default y config ACPI_PROCFS_POWER @@ -163,6 +170,7 @@ config ACPI_PROCESSOR tristate "Processor" select THERMAL select CPU_IDLE + depends on X86 || IA64 default y help This driver installs ACPI as the idle handler for Linux and uses diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 623b117ad1a2..8a063e276530 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -23,7 +23,7 @@ acpi-y += nvs.o # Power management related files acpi-y += wakeup.o -acpi-y += sleep.o +acpi-$(CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT) += sleep.o acpi-y += device_pm.o acpi-$(CONFIG_ACPI_SLEEP) += proc.o @@ -56,6 +56,7 @@ ifdef CONFIG_ACPI_VIDEO acpi-y += video_detect.o endif acpi-y += acpi_lpat.o +acpi-$(CONFIG_ACPI_GENERIC_GSI) += gsi.o # These are (potentially) separate modules diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c index b193f8425999..ff6d8adc9cda 100644 --- a/drivers/acpi/acpi_pnp.c +++ b/drivers/acpi/acpi_pnp.c @@ -304,6 +304,8 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = { {"PNPb006"}, /* cs423x-pnpbios */ {"CSC0100"}, + {"CSC0103"}, + {"CSC0110"}, {"CSC0000"}, {"GIM0100"}, /* Guillemot Turtlebeach something appears to be cs4232 compatible */ /* es18xx-pnpbios */ diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 1020b1b53a17..58f335ca2e75 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -170,7 +170,7 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) acpi_status status; int ret; - if (pr->phys_id == -1) + if (pr->phys_id == PHYS_CPUID_INVALID) return -ENODEV; status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta); @@ -215,7 +215,8 @@ static int acpi_processor_get_info(struct acpi_device *device) union acpi_object object = { 0 }; struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; struct acpi_processor *pr = acpi_driver_data(device); - int phys_id, cpu_index, device_declaration = 0; + phys_cpuid_t phys_id; + int cpu_index, device_declaration = 0; acpi_status status = AE_OK; static int cpu0_initialized; unsigned long long value; @@ -263,7 +264,7 @@ static int acpi_processor_get_info(struct acpi_device *device) } phys_id = acpi_get_phys_id(pr->handle, device_declaration, pr->acpi_id); - if (phys_id < 0) + if (phys_id == PHYS_CPUID_INVALID) acpi_handle_debug(pr->handle, "failed to get CPU physical ID.\n"); pr->phys_id = phys_id; diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index a72685c1e819..5e8df9177da4 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -102,19 +102,12 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { {"_SB_", ACPI_TYPE_DEVICE, NULL}, {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, {"_TZ_", ACPI_TYPE_DEVICE, NULL}, - /* - * March, 2015: - * The _REV object is in the process of being deprecated, because - * other ACPI implementations permanently return 2. Thus, it - * has little or no value. Return 2 for compatibility with - * other ACPI implementations. - */ - {"_REV", ACPI_TYPE_INTEGER, ACPI_CAST_PTR(char, 2)}, + {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, - {"_GL_", ACPI_TYPE_MUTEX, ACPI_CAST_PTR(char, 1)}, + {"_GL_", ACPI_TYPE_MUTEX, (char *)1}, #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) - {"_OSI", ACPI_TYPE_METHOD, ACPI_CAST_PTR(char, 1)}, + {"_OSI", ACPI_TYPE_METHOD, (char *)1}, #endif /* Table terminator */ 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) case ACPI_IRQ_MODEL_IOSAPIC: message = "IOSAPIC"; break; + case ACPI_IRQ_MODEL_GIC: + message = "GIC"; + break; case ACPI_IRQ_MODEL_PLATFORM: message = "platform specific model"; break; diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 220d6406c9e9..5e8fed448850 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -861,7 +861,7 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) } } mutex_unlock(&ec->mutex); - list_for_each_entry(handler, &free_list, node) + list_for_each_entry_safe(handler, tmp, &free_list, node) acpi_ec_put_query_handler(handler); } EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c new file mode 100644 index 000000000000..38208f2d0e69 --- /dev/null +++ b/drivers/acpi/gsi.c @@ -0,0 +1,105 @@ +/* + * ACPI GSI IRQ layer + * + * Copyright (C) 2015 ARM Ltd. + * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/acpi.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> + +enum acpi_irq_model_id acpi_irq_model; + +static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity) +{ + switch (polarity) { + case ACPI_ACTIVE_LOW: + return trigger == ACPI_EDGE_SENSITIVE ? + IRQ_TYPE_EDGE_FALLING : + IRQ_TYPE_LEVEL_LOW; + case ACPI_ACTIVE_HIGH: + return trigger == ACPI_EDGE_SENSITIVE ? + IRQ_TYPE_EDGE_RISING : + IRQ_TYPE_LEVEL_HIGH; + case ACPI_ACTIVE_BOTH: + if (trigger == ACPI_EDGE_SENSITIVE) + return IRQ_TYPE_EDGE_BOTH; + default: + return IRQ_TYPE_NONE; + } +} + +/** + * acpi_gsi_to_irq() - Retrieve the linux irq number for a given GSI + * @gsi: GSI IRQ number to map + * @irq: pointer where linux IRQ number is stored + * + * irq location updated with irq value [>0 on success, 0 on failure] + * + * Returns: linux IRQ number on success (>0) + * -EINVAL on failure + */ +int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) +{ + /* + * Only default domain is supported at present, always find + * the mapping corresponding to default domain by passing NULL + * as irq_domain parameter + */ + *irq = irq_find_mapping(NULL, gsi); + /* + * *irq == 0 means no mapping, that should + * be reported as a failure + */ + return (*irq > 0) ? *irq : -EINVAL; +} +EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); + +/** + * acpi_register_gsi() - Map a GSI to a linux IRQ number + * @dev: device for which IRQ has to be mapped + * @gsi: GSI IRQ number + * @trigger: trigger type of the GSI number to be mapped + * @polarity: polarity of the GSI to be mapped + * + * Returns: a valid linux IRQ number on success + * -EINVAL on failure + */ +int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, + int polarity) +{ + unsigned int irq; + unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity); + + /* + * There is no way at present to look-up the IRQ domain on ACPI, + * hence always create mapping referring to the default domain + * by passing NULL as irq_domain parameter + */ + irq = irq_create_mapping(NULL, gsi); + if (!irq) + return -EINVAL; + + /* Set irq type if specified and different than the current one */ + if (irq_type != IRQ_TYPE_NONE && + irq_type != irq_get_trigger_type(irq)) + irq_set_irq_type(irq, irq_type); + return irq; +} +EXPORT_SYMBOL_GPL(acpi_register_gsi); + +/** + * acpi_unregister_gsi() - Free a GSI<->linux IRQ number mapping + * @gsi: GSI IRQ number + */ +void acpi_unregister_gsi(u32 gsi) +{ + int irq = irq_find_mapping(NULL, gsi); + + irq_dispose_mapping(irq); +} +EXPORT_SYMBOL_GPL(acpi_unregister_gsi); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 56b321aa2b1c..ba4a61e964be 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -161,7 +161,11 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); /*-------------------------------------------------------------------------- Suspend/Resume -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT extern int acpi_sleep_init(void); +#else +static inline int acpi_sleep_init(void) { return -ENXIO; } +#endif #ifdef CONFIG_ACPI_SLEEP int acpi_sleep_proc_init(void); diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index f9eeae871593..7ccba395c9dd 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -182,7 +182,7 @@ static void __init acpi_request_region (struct acpi_generic_address *gas, request_mem_region(addr, length, desc); } -static int __init acpi_reserve_resources(void) +static void __init acpi_reserve_resources(void) { acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length, "ACPI PM1a_EVT_BLK"); @@ -211,10 +211,7 @@ static int __init acpi_reserve_resources(void) if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) acpi_request_region(&acpi_gbl_FADT.xgpe1_block, acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK"); - - return 0; } -device_initcall(acpi_reserve_resources); void acpi_os_printf(const char *fmt, ...) { @@ -336,11 +333,11 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size) return NULL; } -#ifndef CONFIG_IA64 -#define should_use_kmap(pfn) page_is_ram(pfn) -#else +#if defined(CONFIG_IA64) || defined(CONFIG_ARM64) /* ioremap will take care of cache attributes */ #define should_use_kmap(pfn) 0 +#else +#define should_use_kmap(pfn) page_is_ram(pfn) #endif static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz) @@ -1845,6 +1842,7 @@ acpi_status __init acpi_os_initialize(void) acpi_status __init acpi_os_initialize1(void) { + acpi_reserve_resources(); kacpid_wq = alloc_workqueue("kacpid", 0, 1); kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0); diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 7962651cdbd4..b1ec78b8a645 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -32,7 +32,7 @@ static struct acpi_table_madt *get_madt_table(void) } static int map_lapic_id(struct acpi_subtable_header *entry, - u32 acpi_id, int *apic_id) + u32 acpi_id, phys_cpuid_t *apic_id) { struct acpi_madt_local_apic *lapic = container_of(entry, struct acpi_madt_local_apic, header); @@ -48,7 +48,7 @@ static int map_lapic_id(struct acpi_subtable_header *entry, } static int map_x2apic_id(struct acpi_subtable_header *entry, - int device_declaration, u32 acpi_id, int *apic_id) + int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id) { struct acpi_madt_local_x2apic *apic = container_of(entry, struct acpi_madt_local_x2apic, header); @@ -65,7 +65,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, } static int map_lsapic_id(struct acpi_subtable_header *entry, - int device_declaration, u32 acpi_id, int *apic_id) + int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id) { struct acpi_madt_local_sapic *lsapic = container_of(entry, struct acpi_madt_local_sapic, header); @@ -83,10 +83,35 @@ static int map_lsapic_id(struct acpi_subtable_header *entry, return 0; } -static int map_madt_entry(int type, u32 acpi_id) +/* + * Retrieve the ARM CPU physical identifier (MPIDR) + */ +static int map_gicc_mpidr(struct acpi_subtable_header *entry, + int device_declaration, u32 acpi_id, phys_cpuid_t *mpidr) +{ + struct acpi_madt_generic_interrupt *gicc = + container_of(entry, struct acpi_madt_generic_interrupt, header); + + if (!(gicc->flags & ACPI_MADT_ENABLED)) + return -ENODEV; + + /* device_declaration means Device object in DSDT, in the + * GIC interrupt model, logical processors are required to + * have a Processor Device object in the DSDT, so we should + * check device_declaration here + */ + if (device_declaration && (gicc->uid == acpi_id)) { + *mpidr = gicc->arm_mpidr; + return 0; + } + + return -EINVAL; +} + +static phys_cpuid_t map_madt_entry(int type, u32 acpi_id) { unsigned long madt_end, entry; - int phys_id = -1; /* CPU hardware ID */ + phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */ struct acpi_table_madt *madt; madt = get_madt_table(); @@ -111,18 +136,21 @@ static int map_madt_entry(int type, u32 acpi_id) } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { if (!map_lsapic_id(header, type, acpi_id, &phys_id)) break; + } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) { + if (!map_gicc_mpidr(header, type, acpi_id, &phys_id)) + break; } entry += header->length; } return phys_id; } -static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) +static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; struct acpi_subtable_header *header; - int phys_id = -1; + phys_cpuid_t phys_id = PHYS_CPUID_INVALID; if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) goto exit; @@ -143,33 +171,35 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) map_lsapic_id(header, type, acpi_id, &phys_id); else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) map_x2apic_id(header, type, acpi_id, &phys_id); + else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) + map_gicc_mpidr(header, type, acpi_id, &phys_id); exit: kfree(buffer.pointer); return phys_id; } -int acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) +phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) { - int phys_id; + phys_cpuid_t phys_id; phys_id = map_mat_entry(handle, type, acpi_id); - if (phys_id == -1) + if (phys_id == PHYS_CPUID_INVALID) phys_id = map_madt_entry(type, acpi_id); return phys_id; } -int acpi_map_cpuid(int phys_id, u32 acpi_id) +int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id) { #ifdef CONFIG_SMP int i; #endif - if (phys_id == -1) { + if (phys_id == PHYS_CPUID_INVALID) { /* * On UP processor, there is no _MAT or MADT table. - * So above phys_id is always set to -1. + * So above phys_id is always set to PHYS_CPUID_INVALID. * * BIOS may define multiple CPU handles even for UP processor. * For example, @@ -190,7 +220,7 @@ int acpi_map_cpuid(int phys_id, u32 acpi_id) if (nr_cpu_ids <= 1 && acpi_id == 0) return acpi_id; else - return phys_id; + return -1; } #ifdef CONFIG_SMP @@ -208,7 +238,7 @@ int acpi_map_cpuid(int phys_id, u32 acpi_id) int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) { - int phys_id; + phys_cpuid_t phys_id; phys_id = acpi_get_phys_id(handle, type, acpi_id); diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 5589a6e2a023..8244f013f210 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_resources); * @ares: Input ACPI resource object. * @types: Valid resource types of IORESOURCE_XXX * - * This is a hepler function to support acpi_dev_get_resources(), which filters + * This is a helper function to support acpi_dev_get_resources(), which filters * ACPI resource objects according to resource types. */ int acpi_dev_filter_resource_type(struct acpi_resource *ares, diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index cd827625cf07..01504c819e8f 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -684,7 +684,7 @@ static int acpi_sbs_add(struct acpi_device *device) if (!sbs_manager_broken) { result = acpi_manager_get_info(sbs); if (!result) { - sbs->manager_present = 0; + sbs->manager_present = 1; for (id = 0; id < MAX_SBS_BAT; ++id) if ((sbs->batteries_supported & (1 << id))) acpi_battery_add(sbs, id); diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index 26e5b5060523..bf034f8b7c1a 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -14,6 +14,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/interrupt.h> +#include <linux/dmi.h> #include "sbshc.h" #define PREFIX "ACPI: " @@ -87,6 +88,8 @@ enum acpi_smb_offset { ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */ }; +static bool macbook; + static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data) { return ec_read(hc->offset + address, data); @@ -132,6 +135,8 @@ static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, } mutex_lock(&hc->lock); + if (macbook) + udelay(5); if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp)) goto end; if (temp) { @@ -257,12 +262,29 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, acpi_handle handle, acpi_ec_query_func func, void *data); +static int macbook_dmi_match(const struct dmi_system_id *d) +{ + pr_debug("Detected MacBook, enabling workaround\n"); + macbook = true; + return 0; +} + +static struct dmi_system_id acpi_smbus_dmi_table[] = { + { macbook_dmi_match, "Apple MacBook", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") }, + }, + { }, +}; + static int acpi_smbus_hc_add(struct acpi_device *device) { int status; unsigned long long val; struct acpi_smb_hc *hc; + dmi_check_system(acpi_smbus_dmi_table); + if (!device) return -EINVAL; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 69bc0d888c01..03141aa4ea95 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -375,7 +375,11 @@ bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent) struct acpi_device_physical_node *pn; bool offline = true; - mutex_lock(&adev->physical_node_lock); + /* + * acpi_container_offline() calls this for all of the container's + * children under the container's physical_node_lock lock. + */ + mutex_lock_nested(&adev->physical_node_lock, SINGLE_DEPTH_NESTING); list_for_each_entry(pn, &adev->physical_node_list, node) if (device_supports_offline(pn->dev) && !pn->dev->offline) { @@ -2388,9 +2392,6 @@ static void acpi_default_enumeration(struct acpi_device *device) struct list_head resource_list; bool is_spi_i2c_slave = false; - if (!device->pnp.type.platform_id || device->handler) - return; - /* * Do not enemerate SPI/I2C slaves as they will be enuerated by their * respective parents. @@ -2403,6 +2404,29 @@ static void acpi_default_enumeration(struct acpi_device *device) acpi_create_platform_device(device); } +static const struct acpi_device_id generic_device_ids[] = { + {"PRP0001", }, + {"", }, +}; + +static int acpi_generic_device_attach(struct acpi_device *adev, + const struct acpi_device_id *not_used) +{ + /* + * Since PRP0001 is the only ID handled here, the test below can be + * unconditional. + */ + if (adev->data.of_compatible) + acpi_default_enumeration(adev); + + return 1; +} + +static struct acpi_scan_handler generic_device_handler = { + .ids = generic_device_ids, + .attach = acpi_generic_device_attach, +}; + static int acpi_scan_attach_handler(struct acpi_device *device) { struct acpi_hardware_id *hwid; @@ -2428,8 +2452,6 @@ static int acpi_scan_attach_handler(struct acpi_device *device) break; } } - if (!ret) - acpi_default_enumeration(device); return ret; } @@ -2471,6 +2493,9 @@ static void acpi_bus_attach(struct acpi_device *device) ret = device_attach(&device->dev); if (ret < 0) return; + + if (!ret && device->pnp.type.platform_id) + acpi_default_enumeration(device); } device->flags.visited = true; @@ -2629,6 +2654,8 @@ int __init acpi_scan_init(void) acpi_pnp_init(); acpi_int340x_thermal_init(); + acpi_scan_add_handler(&generic_device_handler); + mutex_lock(&acpi_scan_lock); /* * Enumerate devices in the ACPI namespace. diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 93b81523a2fe..2e19189da0ee 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -23,6 +23,8 @@ * */ +/* Uncomment next line to get verbose printout */ +/* #define DEBUG */ #define pr_fmt(fmt) "ACPI: " fmt #include <linux/init.h> @@ -61,9 +63,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_local_apic *p = (struct acpi_madt_local_apic *)header; - pr_info("LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", - p->processor_id, p->id, - (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + pr_debug("LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", + p->processor_id, p->id, + (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); } break; @@ -71,9 +73,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_local_x2apic *p = (struct acpi_madt_local_x2apic *)header; - pr_info("X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n", - p->local_apic_id, p->uid, - (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + pr_debug("X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n", + p->local_apic_id, p->uid, + (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); } break; @@ -81,8 +83,8 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_io_apic *p = (struct acpi_madt_io_apic *)header; - pr_info("IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", - p->id, p->address, p->global_irq_base); + pr_debug("IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", + p->id, p->address, p->global_irq_base); } break; @@ -155,9 +157,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_io_sapic *p = (struct acpi_madt_io_sapic *)header; - pr_info("IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", - p->id, (void *)(unsigned long)p->address, - p->global_irq_base); + pr_debug("IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", + p->id, (void *)(unsigned long)p->address, + p->global_irq_base); } break; @@ -165,9 +167,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_local_sapic *p = (struct acpi_madt_local_sapic *)header; - pr_info("LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", - p->processor_id, p->id, p->eid, - (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + pr_debug("LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", + p->processor_id, p->id, p->eid, + (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); } break; @@ -183,6 +185,28 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) } break; + case ACPI_MADT_TYPE_GENERIC_INTERRUPT: + { + struct acpi_madt_generic_interrupt *p = + (struct acpi_madt_generic_interrupt *)header; + pr_debug("GICC (acpi_id[0x%04x] address[%llx] MPIDR[0x%llx] %s)\n", + p->uid, p->base_address, + p->arm_mpidr, + (p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + + } + break; + + case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: + { + struct acpi_madt_generic_distributor *p = + (struct acpi_madt_generic_distributor *)header; + pr_debug("GIC Distributor (gic_id[0x%04x] address[%llx] gsi_base[%d])\n", + p->gic_id, p->base_address, + p->global_irq_base); + } + break; + default: pr_warn("Found unsupported MADT entry (type = 0x%x)\n", header->type); |