mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 07:03:03 +02:00
Merge branches 'acpi-scan', 'acpi-bus', 'acpi-pm' and 'acpi-resource'
Merge ACPI device enumeration and bus type changes, ACPI power management changes and ACPI IRQ override handling quirks for 6.9-rc1: - Rearrange Device Check and Bus Check notification handling in the ACPI device hotplug code to make it get the "enabled" _STA bit into account (Rafael Wysocki). - Modify acpi_processor_add() to skip processors with the "enabled" _STA bit clear, as per the specification (Rafael Wysocki). - Stop failing Device Check notification handling without a valid reason (Rafael Wysocki). - Defer enumeration of devices that depend on a device with an ACPI device ID equalt to INTC10CF to address probe ordering issues on some platforms (Wentong Wu). - Constify acpi_bus_type (Ricardo Marliere). - Make the ACPI-specific suspend-to-idle code take the Low-Power S0 Idle MSFT UUID into account on non-AMD systems (Rafael Wysocki). - Add ACPI IRQ override quirks for some new platforms (Sergey Kalinichev, Maxim Kudinov, Alexey Froloff, Sviatoslav Harasymchuk, Nicolas Haye). * acpi-scan: ACPI: scan: Consolidate Device Check and Bus Check notification handling ACPI: scan: Rework Device Check and Bus Check notification handling ACPI: scan: Make acpi_processor_add() check the device enabled bit ACPI: scan: Relocate acpi_bus_trim_one() ACPI: scan: Fix device check notification handling ACPI: scan: Defer enumeration of devices with a _DEP pointing to IVSC device * acpi-bus: ACPI: bus: make acpi_bus_type const * acpi-pm: ACPI: PM: s2idle: Enable Low-Power S0 Idle MSFT UUID for non-AMD systems * acpi-resource: ACPI: resource: Use IRQ override on Maibenben X565 ACPI: resource: Add MAIBENBEN X577 to irq1_edge_low_force_override ACPI: resource: Do IRQ override on Lunnen Ground laptops ACPI: resource: Add IRQ override quirk for ASUS ExpertBook B2502FBA ACPI: resource: Skip IRQ override on ASUS ExpertBook B1502CVA
This commit is contained in:
commit
8c34f112ff
|
|
@ -381,6 +381,9 @@ static int acpi_processor_add(struct acpi_device *device,
|
|||
struct device *dev;
|
||||
int result = 0;
|
||||
|
||||
if (!acpi_device_is_enabled(device))
|
||||
return -ENODEV;
|
||||
|
||||
pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
|
||||
if (!pr)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -1097,7 +1097,7 @@ static void acpi_device_remove(struct device *dev)
|
|||
put_device(dev);
|
||||
}
|
||||
|
||||
struct bus_type acpi_bus_type = {
|
||||
const struct bus_type acpi_bus_type = {
|
||||
.name = "acpi",
|
||||
.match = acpi_bus_match,
|
||||
.probe = acpi_device_probe,
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ int acpi_device_setup_files(struct acpi_device *dev);
|
|||
void acpi_device_remove_files(struct acpi_device *dev);
|
||||
void acpi_device_add_finalize(struct acpi_device *device);
|
||||
void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
|
||||
bool acpi_device_is_enabled(const struct acpi_device *adev);
|
||||
bool acpi_device_is_present(const struct acpi_device *adev);
|
||||
bool acpi_device_is_battery(struct acpi_device *adev);
|
||||
bool acpi_device_is_first_physical_node(struct acpi_device *adev,
|
||||
|
|
|
|||
|
|
@ -468,6 +468,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = {
|
|||
DMI_MATCH(DMI_BOARD_NAME, "B1502CGA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Asus ExpertBook B1502CVA */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "B1502CVA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Asus ExpertBook B2402CBA */
|
||||
.matches = {
|
||||
|
|
@ -489,6 +496,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = {
|
|||
DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Asus ExpertBook B2502FBA */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "B2502FBA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Asus Vivobook E1504GA */
|
||||
.matches = {
|
||||
|
|
@ -588,6 +602,34 @@ static const struct dmi_system_id irq1_edge_low_force_override[] = {
|
|||
DMI_MATCH(DMI_BOARD_NAME, "GM5RGEE0016COM"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Lunnen Ground 15 / AMD Ryzen 5 5500U */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Lunnen"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "LLL5DAW"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Lunnen Ground 16 / AMD Ryzen 7 5800U */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Lunnen"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "LL6FA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* MAIBENBEN X577 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "MAIBENBEN"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X577"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Maibenben X565 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "MAIBENBEN"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X565"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -244,6 +244,53 @@ static int acpi_scan_try_to_offline(struct acpi_device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_scan_check_and_detach(struct acpi_device *adev, void *check)
|
||||
{
|
||||
struct acpi_scan_handler *handler = adev->handler;
|
||||
|
||||
acpi_dev_for_each_child_reverse(adev, acpi_scan_check_and_detach, check);
|
||||
|
||||
if (check) {
|
||||
acpi_bus_get_status(adev);
|
||||
/*
|
||||
* Skip devices that are still there and take the enabled
|
||||
* flag into account.
|
||||
*/
|
||||
if (acpi_device_is_enabled(adev))
|
||||
return 0;
|
||||
|
||||
/* Skip device that have not been enumerated. */
|
||||
if (!acpi_device_enumerated(adev)) {
|
||||
dev_dbg(&adev->dev, "Still not enumerated\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
adev->flags.match_driver = false;
|
||||
if (handler) {
|
||||
if (handler->detach)
|
||||
handler->detach(adev);
|
||||
|
||||
adev->handler = NULL;
|
||||
} else {
|
||||
device_release_driver(&adev->dev);
|
||||
}
|
||||
/*
|
||||
* Most likely, the device is going away, so put it into D3cold before
|
||||
* that.
|
||||
*/
|
||||
acpi_device_set_power(adev, ACPI_STATE_D3_COLD);
|
||||
adev->flags.initialized = false;
|
||||
acpi_device_clear_enumerated(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_scan_check_subtree(struct acpi_device *adev)
|
||||
{
|
||||
acpi_scan_check_and_detach(adev, (void *)true);
|
||||
}
|
||||
|
||||
static int acpi_scan_hot_remove(struct acpi_device *device)
|
||||
{
|
||||
acpi_handle handle = device->handle;
|
||||
|
|
@ -289,75 +336,62 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_scan_device_not_enumerated(struct acpi_device *adev)
|
||||
static int acpi_scan_rescan_bus(struct acpi_device *adev)
|
||||
{
|
||||
if (!acpi_device_enumerated(adev)) {
|
||||
dev_warn(&adev->dev, "Still not enumerated\n");
|
||||
return -EALREADY;
|
||||
}
|
||||
acpi_bus_trim(adev);
|
||||
return 0;
|
||||
struct acpi_scan_handler *handler = adev->handler;
|
||||
int ret;
|
||||
|
||||
if (handler && handler->hotplug.scan_dependent)
|
||||
ret = handler->hotplug.scan_dependent(adev);
|
||||
else
|
||||
ret = acpi_bus_scan(adev->handle);
|
||||
|
||||
if (ret)
|
||||
dev_info(&adev->dev, "Namespace scan failure\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int acpi_scan_device_check(struct acpi_device *adev)
|
||||
{
|
||||
int error;
|
||||
struct acpi_device *parent;
|
||||
|
||||
acpi_bus_get_status(adev);
|
||||
if (acpi_device_is_present(adev)) {
|
||||
/*
|
||||
* This function is only called for device objects for which
|
||||
* matching scan handlers exist. The only situation in which
|
||||
* the scan handler is not attached to this device object yet
|
||||
* is when the device has just appeared (either it wasn't
|
||||
* present at all before or it was removed and then added
|
||||
* again).
|
||||
*/
|
||||
if (adev->handler) {
|
||||
dev_warn(&adev->dev, "Already enumerated\n");
|
||||
return -EALREADY;
|
||||
}
|
||||
error = acpi_bus_scan(adev->handle);
|
||||
if (error) {
|
||||
dev_warn(&adev->dev, "Namespace scan failure\n");
|
||||
return error;
|
||||
}
|
||||
if (!adev->handler) {
|
||||
dev_warn(&adev->dev, "Enumeration failure\n");
|
||||
error = -ENODEV;
|
||||
}
|
||||
} else {
|
||||
error = acpi_scan_device_not_enumerated(adev);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
acpi_scan_check_subtree(adev);
|
||||
|
||||
static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used)
|
||||
{
|
||||
struct acpi_scan_handler *handler = adev->handler;
|
||||
int error;
|
||||
if (!acpi_device_is_present(adev))
|
||||
return 0;
|
||||
|
||||
acpi_bus_get_status(adev);
|
||||
if (!acpi_device_is_present(adev)) {
|
||||
acpi_scan_device_not_enumerated(adev);
|
||||
/*
|
||||
* This function is only called for device objects for which matching
|
||||
* scan handlers exist. The only situation in which the scan handler
|
||||
* is not attached to this device object yet is when the device has
|
||||
* just appeared (either it wasn't present at all before or it was
|
||||
* removed and then added again).
|
||||
*/
|
||||
if (adev->handler) {
|
||||
dev_dbg(&adev->dev, "Already enumerated\n");
|
||||
return 0;
|
||||
}
|
||||
if (handler && handler->hotplug.scan_dependent)
|
||||
return handler->hotplug.scan_dependent(adev);
|
||||
|
||||
error = acpi_bus_scan(adev->handle);
|
||||
if (error) {
|
||||
dev_warn(&adev->dev, "Namespace scan failure\n");
|
||||
return error;
|
||||
}
|
||||
return acpi_dev_for_each_child(adev, acpi_scan_bus_check, NULL);
|
||||
parent = acpi_dev_parent(adev);
|
||||
if (!parent)
|
||||
parent = adev;
|
||||
|
||||
return acpi_scan_rescan_bus(parent);
|
||||
}
|
||||
|
||||
static int acpi_scan_bus_check(struct acpi_device *adev)
|
||||
{
|
||||
acpi_scan_check_subtree(adev);
|
||||
|
||||
return acpi_scan_rescan_bus(adev);
|
||||
}
|
||||
|
||||
static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type)
|
||||
{
|
||||
switch (type) {
|
||||
case ACPI_NOTIFY_BUS_CHECK:
|
||||
return acpi_scan_bus_check(adev, NULL);
|
||||
return acpi_scan_bus_check(adev);
|
||||
case ACPI_NOTIFY_DEVICE_CHECK:
|
||||
return acpi_scan_device_check(adev);
|
||||
case ACPI_NOTIFY_EJECT_REQUEST:
|
||||
|
|
@ -798,6 +832,7 @@ static const char * const acpi_honor_dep_ids[] = {
|
|||
"INTC1059", /* IVSC (TGL) driver must be loaded to allow i2c access to camera sensors */
|
||||
"INTC1095", /* IVSC (ADL) driver must be loaded to allow i2c access to camera sensors */
|
||||
"INTC100A", /* IVSC (RPL) driver must be loaded to allow i2c access to camera sensors */
|
||||
"INTC10CF", /* IVSC (MTL) driver must be loaded to allow i2c access to camera sensors */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -1922,6 +1957,11 @@ bool acpi_device_is_present(const struct acpi_device *adev)
|
|||
return adev->status.present || adev->status.functional;
|
||||
}
|
||||
|
||||
bool acpi_device_is_enabled(const struct acpi_device *adev)
|
||||
{
|
||||
return adev->status.present && adev->status.enabled;
|
||||
}
|
||||
|
||||
static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
|
||||
const char *idstr,
|
||||
const struct acpi_device_id **matchid)
|
||||
|
|
@ -2550,32 +2590,6 @@ int acpi_bus_scan(acpi_handle handle)
|
|||
}
|
||||
EXPORT_SYMBOL(acpi_bus_scan);
|
||||
|
||||
static int acpi_bus_trim_one(struct acpi_device *adev, void *not_used)
|
||||
{
|
||||
struct acpi_scan_handler *handler = adev->handler;
|
||||
|
||||
acpi_dev_for_each_child_reverse(adev, acpi_bus_trim_one, NULL);
|
||||
|
||||
adev->flags.match_driver = false;
|
||||
if (handler) {
|
||||
if (handler->detach)
|
||||
handler->detach(adev);
|
||||
|
||||
adev->handler = NULL;
|
||||
} else {
|
||||
device_release_driver(&adev->dev);
|
||||
}
|
||||
/*
|
||||
* Most likely, the device is going away, so put it into D3cold before
|
||||
* that.
|
||||
*/
|
||||
acpi_device_set_power(adev, ACPI_STATE_D3_COLD);
|
||||
adev->flags.initialized = false;
|
||||
acpi_device_clear_enumerated(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_bus_trim - Detach scan handlers and drivers from ACPI device objects.
|
||||
* @adev: Root of the ACPI namespace scope to walk.
|
||||
|
|
@ -2584,7 +2598,7 @@ static int acpi_bus_trim_one(struct acpi_device *adev, void *not_used)
|
|||
*/
|
||||
void acpi_bus_trim(struct acpi_device *adev)
|
||||
{
|
||||
acpi_bus_trim_one(adev, NULL);
|
||||
acpi_scan_check_and_detach(adev, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_bus_trim);
|
||||
|
||||
|
|
|
|||
|
|
@ -488,7 +488,21 @@ static int lps0_device_attach(struct acpi_device *adev,
|
|||
rev_id = 1;
|
||||
lps0_dsm_func_mask = validate_dsm(adev->handle,
|
||||
ACPI_LPS0_DSM_UUID, rev_id, &lps0_dsm_guid);
|
||||
lps0_dsm_func_mask_microsoft = -EINVAL;
|
||||
if (lps0_dsm_func_mask > 0 && lps0_dsm_func_mask_microsoft > 0) {
|
||||
unsigned int func_mask;
|
||||
|
||||
/*
|
||||
* Avoid evaluating the same _DSM function for two
|
||||
* different UUIDs and prioritize the MSFT one.
|
||||
*/
|
||||
func_mask = lps0_dsm_func_mask & lps0_dsm_func_mask_microsoft;
|
||||
if (func_mask) {
|
||||
acpi_handle_info(adev->handle,
|
||||
"Duplicate LPS0 _DSM functions (mask: 0x%x)\n",
|
||||
func_mask);
|
||||
lps0_dsm_func_mask &= ~func_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lps0_dsm_func_mask < 0 && lps0_dsm_func_mask_microsoft < 0)
|
||||
|
|
@ -549,19 +563,22 @@ int acpi_s2idle_prepare_late(void)
|
|||
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
|
||||
|
||||
/* LPS0 entry */
|
||||
if (lps0_dsm_func_mask > 0)
|
||||
acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
|
||||
ACPI_LPS0_ENTRY_AMD :
|
||||
ACPI_LPS0_ENTRY,
|
||||
if (lps0_dsm_func_mask > 0 && acpi_s2idle_vendor_amd())
|
||||
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD,
|
||||
lps0_dsm_func_mask, lps0_dsm_guid);
|
||||
|
||||
if (lps0_dsm_func_mask_microsoft > 0) {
|
||||
/* modern standby entry */
|
||||
/* Modern Standby entry */
|
||||
acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY,
|
||||
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
|
||||
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
|
||||
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
|
||||
}
|
||||
|
||||
if (lps0_dsm_func_mask > 0 && !acpi_s2idle_vendor_amd())
|
||||
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
|
||||
lps0_dsm_func_mask, lps0_dsm_guid);
|
||||
|
||||
list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) {
|
||||
if (handler->prepare)
|
||||
handler->prepare();
|
||||
|
|
@ -600,14 +617,14 @@ void acpi_s2idle_restore_early(void)
|
|||
ACPI_LPS0_EXIT_AMD :
|
||||
ACPI_LPS0_EXIT,
|
||||
lps0_dsm_func_mask, lps0_dsm_guid);
|
||||
if (lps0_dsm_func_mask_microsoft > 0)
|
||||
|
||||
if (lps0_dsm_func_mask_microsoft > 0) {
|
||||
acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
|
||||
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
|
||||
|
||||
/* Modern standby exit */
|
||||
if (lps0_dsm_func_mask_microsoft > 0)
|
||||
/* Modern Standby exit */
|
||||
acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT,
|
||||
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
|
||||
}
|
||||
|
||||
/* Screen on */
|
||||
if (lps0_dsm_func_mask_microsoft > 0)
|
||||
|
|
|
|||
|
|
@ -582,7 +582,7 @@ void acpi_initialize_hp_context(struct acpi_device *adev,
|
|||
void (*uevent)(struct acpi_device *, u32));
|
||||
|
||||
/* acpi_device.dev.bus == &acpi_bus_type */
|
||||
extern struct bus_type acpi_bus_type;
|
||||
extern const struct bus_type acpi_bus_type;
|
||||
|
||||
int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data);
|
||||
int acpi_dev_for_each_child(struct acpi_device *adev,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user