diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-07-06 22:25:06 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-07-06 22:25:06 -0700 |
commit | 94e0d43e51ff8577ad273032bb1cacfd68e9297b (patch) | |
tree | 088b57c63fa789187ff8333b0791069d4ced58a9 /drivers/acpi | |
parent | 7210de3a328c4df5cb8b25b2ef5703c72d8842e9 (diff) | |
parent | 2e178ee13b02d95c7380f6a21149de535ccdfc7f (diff) | |
download | linux-stable-94e0d43e51ff8577ad273032bb1cacfd68e9297b.tar.gz linux-stable-94e0d43e51ff8577ad273032bb1cacfd68e9297b.tar.bz2 linux-stable-94e0d43e51ff8577ad273032bb1cacfd68e9297b.zip |
Merge tag 'acpi-6.5-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more ACPI updates from Rafael Wysocki:
"These fix a couple of compiler warnings, refine an ACPI device
enumeration quirk to address a driver regression and clean up code.
Specifics:
- Make acpi_companion_match() return a const pointer and update its
callers accordingly (Andy Shevchenko)
- Move the extern declaration of the acpi_root variable to a header
file so as to address a compiler warning (Andy Shevchenko)
- Address compiler warnings in the ACPI device enumeration code by
adding a missing header file include to it (Ben Dooks)
- Refine the SMB0001 quirk in the ACPI device enumeration code so as
to address an i2c-scmi driver regression (Andy Shevchenko)
- Clean up two pieces of the ACPI device enumeration code (Andy
Shevchenko)"
* tag 'acpi-6.5-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
ACPI: scan: Use the acpi_match_acpi_device() helper
ACPI: platform: Move SMB0001 HID to the header and reuse
ACPI: platform: Ignore SMB0001 only when it has resources
ACPI: bus: Introduce acpi_match_acpi_device() helper
ACPI: scan: fix undeclared variable warnings by including sleep.h
ACPI: bus: Constify acpi_companion_match() returned value
ACPI: scan: Move acpi_root to internal header
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpi_platform.c | 31 | ||||
-rw-r--r-- | drivers/acpi/bus.c | 31 | ||||
-rw-r--r-- | drivers/acpi/device_sysfs.c | 2 | ||||
-rw-r--r-- | drivers/acpi/internal.h | 4 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 24 |
5 files changed, 69 insertions, 23 deletions
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index fe00a5783f53..48d15dd785f6 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -9,6 +9,7 @@ */ #include <linux/acpi.h> +#include <linux/bits.h> #include <linux/device.h> #include <linux/err.h> #include <linux/kernel.h> @@ -19,13 +20,16 @@ #include "internal.h" +/* Exclude devices that have no _CRS resources provided */ +#define ACPI_ALLOW_WO_RESOURCES BIT(0) + static const struct acpi_device_id forbidden_id_list[] = { {"ACPI0009", 0}, /* IOxAPIC */ {"ACPI000A", 0}, /* IOAPIC */ {"PNP0000", 0}, /* PIC */ {"PNP0100", 0}, /* Timer */ {"PNP0200", 0}, /* AT DMA Controller */ - {"SMB0001", 0}, /* ACPI SMBUS virtual device */ + {ACPI_SMBUS_MS_HID, ACPI_ALLOW_WO_RESOURCES}, /* ACPI SMBUS virtual device */ { } }; @@ -83,6 +87,15 @@ static void acpi_platform_fill_resource(struct acpi_device *adev, dest->parent = pci_find_resource(to_pci_dev(parent), dest); } +static unsigned int acpi_platform_resource_count(struct acpi_resource *ares, void *data) +{ + bool *has_resources = data; + + *has_resources = true; + + return AE_CTRL_TERMINATE; +} + /** * acpi_create_platform_device - Create platform device for ACPI device node * @adev: ACPI device node to create a platform device for. @@ -100,6 +113,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, struct acpi_device *parent = acpi_dev_parent(adev); struct platform_device *pdev = NULL; struct platform_device_info pdevinfo; + const struct acpi_device_id *match; struct resource_entry *rentry; struct list_head resource_list; struct resource *resources = NULL; @@ -109,8 +123,19 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, if (adev->physical_node_count) return NULL; - if (!acpi_match_device_ids(adev, forbidden_id_list)) - return ERR_PTR(-EINVAL); + match = acpi_match_acpi_device(forbidden_id_list, adev); + if (match) { + if (match->driver_data & ACPI_ALLOW_WO_RESOURCES) { + bool has_resources = false; + + acpi_walk_resources(adev->handle, METHOD_NAME__CRS, + acpi_platform_resource_count, &has_resources); + if (has_resources) + return ERR_PTR(-EINVAL); + } else { + return ERR_PTR(-EINVAL); + } + } INIT_LIST_HEAD(&resource_list); count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e3e0bd0c5a50..2fc2b43a4ed3 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -682,7 +682,7 @@ bool acpi_device_is_first_physical_node(struct acpi_device *adev, * resources available from it but they will be matched normally using functions * provided by their bus types (and analogously for their modalias). */ -struct acpi_device *acpi_companion_match(const struct device *dev) +const struct acpi_device *acpi_companion_match(const struct device *dev) { struct acpi_device *adev; @@ -706,7 +706,7 @@ struct acpi_device *acpi_companion_match(const struct device *dev) * identifiers and a _DSD object with the "compatible" property, use that * property to match against the given list of identifiers. */ -static bool acpi_of_match_device(struct acpi_device *adev, +static bool acpi_of_match_device(const struct acpi_device *adev, const struct of_device_id *of_match_table, const struct of_device_id **of_id) { @@ -808,7 +808,7 @@ static bool __acpi_match_device_cls(const struct acpi_device_id *id, return true; } -static bool __acpi_match_device(struct acpi_device *device, +static bool __acpi_match_device(const struct acpi_device *device, const struct acpi_device_id *acpi_ids, const struct of_device_id *of_ids, const struct acpi_device_id **acpi_id, @@ -851,6 +851,26 @@ out_acpi_match: } /** + * acpi_match_acpi_device - Match an ACPI device against a given list of ACPI IDs + * @ids: Array of struct acpi_device_id objects to match against. + * @adev: The ACPI device pointer to match. + * + * Match the ACPI device @adev against a given list of ACPI IDs @ids. + * + * Return: + * a pointer to the first matching ACPI ID on success or %NULL on failure. + */ +const struct acpi_device_id *acpi_match_acpi_device(const struct acpi_device_id *ids, + const struct acpi_device *adev) +{ + const struct acpi_device_id *id = NULL; + + __acpi_match_device(adev, ids, NULL, &id, NULL); + return id; +} +EXPORT_SYMBOL_GPL(acpi_match_acpi_device); + +/** * acpi_match_device - Match a struct device against a given list of ACPI IDs * @ids: Array of struct acpi_device_id object to match against. * @dev: The device structure to match. @@ -864,10 +884,7 @@ out_acpi_match: const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, const struct device *dev) { - const struct acpi_device_id *id = NULL; - - __acpi_match_device(acpi_companion_match(dev), ids, NULL, &id, NULL); - return id; + return acpi_match_acpi_device(ids, acpi_companion_match(dev)); } EXPORT_SYMBOL_GPL(acpi_match_device); diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index 0fbfbaa8d8e3..b9bbf0746199 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -283,7 +283,7 @@ int acpi_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env } EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); -static int __acpi_device_modalias(struct acpi_device *adev, char *buf, int size) +static int __acpi_device_modalias(const struct acpi_device *adev, char *buf, int size) { int len, count; diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 06ad497067ac..f4148dc50b9c 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -11,6 +11,8 @@ #include <linux/idr.h> +extern struct acpi_device *acpi_root; + int early_acpi_osi_init(void); int acpi_osi_init(void); acpi_status acpi_os_initialize1(void); @@ -119,7 +121,7 @@ int acpi_bus_register_early_device(int type); /* -------------------------------------------------------------------------- Device Matching and Notification -------------------------------------------------------------------------- */ -struct acpi_device *acpi_companion_match(const struct device *dev); +const struct acpi_device *acpi_companion_match(const struct device *dev); int __acpi_device_uevent_modalias(const struct acpi_device *adev, struct kobj_uevent_env *env); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 1c3e1e2bb0b5..5b145f1aaa1b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -23,8 +23,7 @@ #include <linux/dma-direct.h> #include "internal.h" - -extern struct acpi_device *acpi_root; +#include "sleep.h" #define ACPI_BUS_CLASS "system_bus" #define ACPI_BUS_HID "LNXSYBUS" @@ -930,26 +929,29 @@ static int acpi_bus_extract_wakeup_device_power_package(struct acpi_device *dev) return err; } +/* Do not use a button for S5 wakeup */ +#define ACPI_AVOID_WAKE_FROM_S5 BIT(0) + static bool acpi_wakeup_gpe_init(struct acpi_device *device) { static const struct acpi_device_id button_device_ids[] = { - {"PNP0C0C", 0}, /* Power button */ - {"PNP0C0D", 0}, /* Lid */ - {"PNP0C0E", 0}, /* Sleep button */ + {"PNP0C0C", 0}, /* Power button */ + {"PNP0C0D", ACPI_AVOID_WAKE_FROM_S5}, /* Lid */ + {"PNP0C0E", ACPI_AVOID_WAKE_FROM_S5}, /* Sleep button */ {"", 0}, }; struct acpi_device_wakeup *wakeup = &device->wakeup; + const struct acpi_device_id *match; acpi_status status; wakeup->flags.notifier_present = 0; /* Power button, Lid switch always enable wakeup */ - if (!acpi_match_device_ids(device, button_device_ids)) { - if (!acpi_match_device_ids(device, &button_device_ids[1])) { - /* Do not use Lid/sleep button for S5 wakeup */ - if (wakeup->sleep_state == ACPI_STATE_S5) - wakeup->sleep_state = ACPI_STATE_S4; - } + match = acpi_match_acpi_device(button_device_ids, device); + if (match) { + if ((match->driver_data & ACPI_AVOID_WAKE_FROM_S5) && + wakeup->sleep_state == ACPI_STATE_S5) + wakeup->sleep_state = ACPI_STATE_S4; acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number); device_set_wakeup_capable(&device->dev, true); return true; |