Skip to content

Commit

Permalink
Merge branches 'acpi-scan', 'acpi-bus', 'acpi-pm' and 'acpi-resource'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Rafael J. Wysocki committed Mar 11, 2024
5 parents 2f4a4d6 + 4f4a335 + 592190b + 0732372 + 00efe7f commit 8c34f11
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 91 deletions.
3 changes: 3 additions & 0 deletions drivers/acpi/acpi_processor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/acpi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
42 changes: 42 additions & 0 deletions drivers/acpi/resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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 = {
Expand Down Expand Up @@ -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"),
},
},
{ }
};

Expand Down
172 changes: 93 additions & 79 deletions drivers/acpi/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
};

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand All @@ -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);

Expand Down
37 changes: 27 additions & 10 deletions drivers/acpi/x86/s2idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion include/acpi/acpi_bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 8c34f11

Please sign in to comment.