From 621dc2fdcea1496ddd472c297d42e8d6642b05bc Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 28 May 2019 15:36:44 +0200 Subject: acpi/irq: Implement helper to create hierachical domains ACPI permits arbitrary producer->consumer interrupt links to be described in AML, which means a topology such as the following is perfectly legal: Device (EXIU) { Name (_HID, "SCX0008") Name (_UID, Zero) Name (_CRS, ResourceTemplate () { ... }) } Device (GPIO) { Name (_HID, "SCX0007") Name (_UID, Zero) Name (_CRS, ResourceTemplate () { Memory32Fixed (ReadWrite, SYNQUACER_GPIO_BASE, SYNQUACER_GPIO_SIZE) Interrupt (ResourceConsumer, Edge, ActiveHigh, ExclusiveAndWake, 0, "\\_SB.EXIU") { 7, } }) ... } The EXIU in this example is the external interrupt unit as can be found on Socionext SynQuacer based platforms, which converts a block of 32 SPIs from arbitrary polarity/trigger into level-high, with a separate set of config/mask/unmask/clear controls. The existing DT based driver in drivers/irqchip/irq-sni-exiu.c models this as a hierarchical domain stacked on top of the GIC's irqdomain. Since the GIC is modeled as a DT node as well, obtaining a reference to this irqdomain is easily done by going through the parent link. On ACPI systems, however, the GIC is not modeled as an object in the namespace, and so device objects cannot refer to it directly. So in order to obtain the irqdomain reference when driving the EXIU in ACPI mode, we need a helper that implicitly grabs the default domain as the parent of the hierarchy for interrupts allocated out of the global GSI pool. Reviewed-by: Mika Westerberg Reviewed-by: Lorenzo Pieralisi Signed-off-by: Ard Biesheuvel Signed-off-by: Marc Zyngier --- include/linux/acpi.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 98440df7fe42..70de4bc30cea 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -23,6 +23,7 @@ #include #include /* for struct resource */ +#include #include #include #include @@ -327,6 +328,12 @@ int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi); void acpi_set_irq_model(enum acpi_irq_model_id model, struct fwnode_handle *fwnode); +struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags, + unsigned int size, + struct fwnode_handle *fwnode, + const struct irq_domain_ops *ops, + void *host_data); + #ifdef CONFIG_X86_IO_APIC extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity); #else -- cgit v1.2.3 From e7488e58c7cfe4be0c52db68622a0397bb75258e Mon Sep 17 00:00:00 2001 From: Yurii Pavlovskyi Date: Tue, 14 May 2019 20:59:01 +0200 Subject: platform/x86: wmi: Add function to get _UID of WMI device Add a new function to acpi.h / wmi.c that returns _UID of the ACPI WMI device. For example, it returns "ATK" for the following declaration in DSDT: Device (ATKD) { Name (_HID, "PNP0C14" /* Windows Management Instrumentation Device */) // _HID: Hardware ID Name (_UID, "ATK") // _UID: Unique ID .. Generally, it is possible that multiple PNP0C14 ACPI devices are present in the system as mentioned in the commit message of commit bff431e49ff5 ("ACPI: WMI: Add ACPI-WMI mapping driver"). Therefore the _UID is returned for a specific ACPI device that declares the given GUID, to which it is also mapped by other methods of wmi module. Signed-off-by: Yurii Pavlovskyi Signed-off-by: Andy Shevchenko --- include/linux/acpi.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 98440df7fe42..d867a9a904f9 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -380,6 +380,7 @@ extern acpi_status wmi_install_notify_handler(const char *guid, extern acpi_status wmi_remove_notify_handler(const char *guid); extern acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out); extern bool wmi_has_guid(const char *guid); +extern char *wmi_get_acpi_device_uid(const char *guid); #endif /* CONFIG_ACPI_WMI */ -- cgit v1.2.3 From 56855a99f3d0d1e9f1f4e24f5851f9bf14c83296 Mon Sep 17 00:00:00 2001 From: Jeremy Linton Date: Wed, 26 Jun 2019 16:37:16 -0500 Subject: ACPI/PPTT: Add function to return ACPI 6.3 Identical tokens ACPI 6.3 adds a flag to indicate that child nodes are all identical cores. This is useful to authoritatively determine if a set of (possibly offline) cores are identical or not. Since the flag doesn't give us a unique id we can generate one and use it to create bitmaps of sibling nodes, or simply in a loop to determine if a subset of cores are identical. Acked-by: Rafael J. Wysocki Tested-by: Hanjun Guo Reviewed-by: Sudeep Holla Signed-off-by: Jeremy Linton Signed-off-by: Will Deacon --- include/linux/acpi.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d315d86844e4..5bcd23e5ccd6 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1303,6 +1303,7 @@ static inline int lpit_read_residency_count_address(u64 *address) #ifdef CONFIG_ACPI_PPTT int find_acpi_cpu_topology(unsigned int cpu, int level); int find_acpi_cpu_topology_package(unsigned int cpu); +int find_acpi_cpu_topology_hetero_id(unsigned int cpu); int find_acpi_cpu_cache_topology(unsigned int cpu, int level); #else static inline int find_acpi_cpu_topology(unsigned int cpu, int level) @@ -1313,6 +1314,10 @@ static inline int find_acpi_cpu_topology_package(unsigned int cpu) { return -EINVAL; } +static inline int find_acpi_cpu_topology_hetero_id(unsigned int cpu) +{ + return -EINVAL; +} static inline int find_acpi_cpu_cache_topology(unsigned int cpu, int level) { return -EINVAL; -- cgit v1.2.3 From 3cd7957e85e67120bb9f6bfb75d81dcc19af282b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 1 Jul 2019 12:54:10 +0200 Subject: ACPI: PM: Simplify and fix PM domain hibernation callbacks First, after a previous change causing all runtime-suspended devices in the ACPI PM domain (and ACPI LPSS devices) to be resumed before creating a snapshot image of memory during hibernation, it is not necessary to worry about the case in which them might be left in runtime-suspend any more, so get rid of the code related to that from ACPI PM domain and ACPI LPSS hibernation callbacks. Second, it is not correct to use pm_generic_resume_early() and acpi_subsys_resume_noirq() in hibernation "restore" callbacks (which currently happens in the ACPI PM domain and ACPI LPSS), so introduce proper _restore_late and _restore_noirq callbacks for the ACPI PM domain and ACPI LPSS. Fixes: 05087360fd7a (ACPI / PM: Take SMART_SUSPEND driver flag into account) Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Reviewed-by: Hans de Goede --- include/linux/acpi.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d315d86844e4..ea7415440901 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -918,26 +918,16 @@ int acpi_subsys_prepare(struct device *dev); void acpi_subsys_complete(struct device *dev); int acpi_subsys_suspend_late(struct device *dev); int acpi_subsys_suspend_noirq(struct device *dev); -int acpi_subsys_resume_noirq(struct device *dev); -int acpi_subsys_resume_early(struct device *dev); int acpi_subsys_suspend(struct device *dev); int acpi_subsys_freeze(struct device *dev); -int acpi_subsys_freeze_late(struct device *dev); -int acpi_subsys_freeze_noirq(struct device *dev); -int acpi_subsys_thaw_noirq(struct device *dev); #else static inline int acpi_dev_resume_early(struct device *dev) { return 0; } static inline int acpi_subsys_prepare(struct device *dev) { return 0; } static inline void acpi_subsys_complete(struct device *dev) {} static inline int acpi_subsys_suspend_late(struct device *dev) { return 0; } static inline int acpi_subsys_suspend_noirq(struct device *dev) { return 0; } -static inline int acpi_subsys_resume_noirq(struct device *dev) { return 0; } -static inline int acpi_subsys_resume_early(struct device *dev) { return 0; } static inline int acpi_subsys_suspend(struct device *dev) { return 0; } static inline int acpi_subsys_freeze(struct device *dev) { return 0; } -static inline int acpi_subsys_freeze_late(struct device *dev) { return 0; } -static inline int acpi_subsys_freeze_noirq(struct device *dev) { return 0; } -static inline int acpi_subsys_thaw_noirq(struct device *dev) { return 0; } #endif #ifdef CONFIG_ACPI -- cgit v1.2.3 From c95b7595f85c688d5c569ddbbd6ab6a4bdae2f36 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 1 Jul 2019 12:54:29 +0200 Subject: ACPI: PM: Introduce "poweroff" callbacks for ACPI PM domain and LPSS In general, it is not correct to call pm_generic_suspend(), pm_generic_suspend_late() and pm_generic_suspend_noirq() during the hibernation's "poweroff" transition, because device drivers may provide special callbacks to be invoked then and the wrappers in question cause system suspend callbacks to be run. Unfortunately, that happens in the ACPI PM domain and ACPI LPSS. To address this potential issue, introduce "poweroff" callbacks for the ACPI PM and LPSS that will use pm_generic_poweroff(), pm_generic_poweroff_late() and pm_generic_poweroff_noirq() as appropriate. Fixes: 05087360fd7a (ACPI / PM: Take SMART_SUSPEND driver flag into account) Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Reviewed-by: Hans de Goede --- include/linux/acpi.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index ea7415440901..22840633c28c 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -920,6 +920,7 @@ int acpi_subsys_suspend_late(struct device *dev); int acpi_subsys_suspend_noirq(struct device *dev); int acpi_subsys_suspend(struct device *dev); int acpi_subsys_freeze(struct device *dev); +int acpi_subsys_poweroff(struct device *dev); #else static inline int acpi_dev_resume_early(struct device *dev) { return 0; } static inline int acpi_subsys_prepare(struct device *dev) { return 0; } @@ -928,6 +929,7 @@ static inline int acpi_subsys_suspend_late(struct device *dev) { return 0; } static inline int acpi_subsys_suspend_noirq(struct device *dev) { return 0; } static inline int acpi_subsys_suspend(struct device *dev) { return 0; } static inline int acpi_subsys_freeze(struct device *dev) { return 0; } +static inline int acpi_subsys_poweroff(struct device *dev) { return 0; } #endif #ifdef CONFIG_ACPI -- cgit v1.2.3 From 99465f12babd4f3d5659b6c147bb5b9976dfe033 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 1 Jul 2019 12:55:43 +0200 Subject: ACPI: PM: Drop unused function and function header Remove a leftover function header and a static inline stub with no users from the ACPI header file. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Reviewed-by: Hans de Goede --- include/linux/acpi.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 22840633c28c..cbbe45e408d9 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -913,7 +913,6 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on) #endif #if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP) -int acpi_dev_suspend_late(struct device *dev); int acpi_subsys_prepare(struct device *dev); void acpi_subsys_complete(struct device *dev); int acpi_subsys_suspend_late(struct device *dev); @@ -922,7 +921,6 @@ int acpi_subsys_suspend(struct device *dev); int acpi_subsys_freeze(struct device *dev); int acpi_subsys_poweroff(struct device *dev); #else -static inline int acpi_dev_resume_early(struct device *dev) { return 0; } static inline int acpi_subsys_prepare(struct device *dev) { return 0; } static inline void acpi_subsys_complete(struct device *dev) {} static inline int acpi_subsys_suspend_late(struct device *dev) { return 0; } -- cgit v1.2.3 From dfd6f9ad36368b8dbd5f5a2b2f0a4705ae69a323 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 12 Jul 2019 11:01:21 +0200 Subject: ACPI: fix false-positive -Wuninitialized warning clang gets confused by an uninitialized variable in what looks to it like a never executed code path: arch/x86/kernel/acpi/boot.c:618:13: error: variable 'polarity' is uninitialized when used here [-Werror,-Wuninitialized] polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; ^~~~~~~~ arch/x86/kernel/acpi/boot.c:606:32: note: initialize the variable 'polarity' to silence this warning int rc, irq, trigger, polarity; ^ = 0 arch/x86/kernel/acpi/boot.c:617:12: error: variable 'trigger' is uninitialized when used here [-Werror,-Wuninitialized] trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; ^~~~~~~ arch/x86/kernel/acpi/boot.c:606:22: note: initialize the variable 'trigger' to silence this warning int rc, irq, trigger, polarity; ^ = 0 This is unfortunately a design decision in clang and won't be fixed. Changing the acpi_get_override_irq() macro to an inline function reliably avoids the issue. Signed-off-by: Arnd Bergmann Reviewed-by: Andy Shevchenko Reviewed-by: Nathan Chancellor Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 451e7b544342..8309923eafe1 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -324,7 +324,10 @@ struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags, #ifdef CONFIG_X86_IO_APIC extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity); #else -#define acpi_get_override_irq(gsi, trigger, polarity) (-1) +static inline int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity) +{ + return -1; +} #endif /* * This function undoes the effect of one call to acpi_register_gsi(). -- cgit v1.2.3