From dc171114926ec390ab90f46534545420ec03e458 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 4 Jul 2024 18:26:54 +0200 Subject: [PATCH 1/8] ACPI: EC: Do not release locks during operation region accesses It is not particularly useful to release locks (the EC mutex and the ACPI global lock, if present) and re-acquire them immediately thereafter during EC address space accesses in acpi_ec_space_handler(). First, releasing them for a while before grabbing them again does not really help anyone because there may not be enough time for another thread to acquire them. Second, if another thread successfully acquires them and carries out a new EC write or read in the middle if an operation region access in progress, it may confuse the EC firmware, especially after the burst mode has been enabled. Finally, manipulating the locks after writing or reading every single byte of data is overhead that it is better to avoid. Accordingly, modify the code to carry out EC address space accesses entirely without releasing the locks. Signed-off-by: Rafael J. Wysocki Reviewed-by: Hans de Goede Link: https://patch.msgid.link/12473338.O9o76ZdvQC@rjwysocki.net --- drivers/acpi/ec.c | 55 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 299ec653388c..a7b59a19f8d9 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -783,6 +783,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, unsigned long tmp; int ret = 0; + if (t->rdata) + memset(t->rdata, 0, t->rlen); + /* start transaction */ spin_lock_irqsave(&ec->lock, tmp); /* Enable GPE for command processing (IBF=0/OBF=1) */ @@ -819,8 +822,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata)) return -EINVAL; - if (t->rdata) - memset(t->rdata, 0, t->rlen); mutex_lock(&ec->mutex); if (ec->global_lock) { @@ -847,7 +848,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec) .wdata = NULL, .rdata = &d, .wlen = 0, .rlen = 1}; - return acpi_ec_transaction(ec, &t); + return acpi_ec_transaction_unlocked(ec, &t); } static int acpi_ec_burst_disable(struct acpi_ec *ec) @@ -857,7 +858,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec) .wlen = 0, .rlen = 0}; return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? - acpi_ec_transaction(ec, &t) : 0; + acpi_ec_transaction_unlocked(ec, &t) : 0; } static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) @@ -873,6 +874,19 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) return result; } +static int acpi_ec_read_unlocked(struct acpi_ec *ec, u8 address, u8 *data) +{ + int result; + u8 d; + struct transaction t = {.command = ACPI_EC_COMMAND_READ, + .wdata = &address, .rdata = &d, + .wlen = 1, .rlen = 1}; + + result = acpi_ec_transaction_unlocked(ec, &t); + *data = d; + return result; +} + static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) { u8 wdata[2] = { address, data }; @@ -883,6 +897,16 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) return acpi_ec_transaction(ec, &t); } +static int acpi_ec_write_unlocked(struct acpi_ec *ec, u8 address, u8 data) +{ + u8 wdata[2] = { address, data }; + struct transaction t = {.command = ACPI_EC_COMMAND_WRITE, + .wdata = wdata, .rdata = NULL, + .wlen = 2, .rlen = 0}; + + return acpi_ec_transaction_unlocked(ec, &t); +} + int ec_read(u8 addr, u8 *val) { int err; @@ -1323,6 +1347,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, struct acpi_ec *ec = handler_context; int result = 0, i, bytes = bits / 8; u8 *value = (u8 *)value64; + u32 glk; if ((address > 0xFF) || !value || !handler_context) return AE_BAD_PARAMETER; @@ -1330,13 +1355,25 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, if (function != ACPI_READ && function != ACPI_WRITE) return AE_BAD_PARAMETER; + mutex_lock(&ec->mutex); + + if (ec->global_lock) { + acpi_status status; + + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) { + result = -ENODEV; + goto unlock; + } + } + if (ec->busy_polling || bits > 8) acpi_ec_burst_enable(ec); for (i = 0; i < bytes; ++i, ++address, ++value) { result = (function == ACPI_READ) ? - acpi_ec_read(ec, address, value) : - acpi_ec_write(ec, address, *value); + acpi_ec_read_unlocked(ec, address, value) : + acpi_ec_write_unlocked(ec, address, *value); if (result < 0) break; } @@ -1344,6 +1381,12 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, if (ec->busy_polling || bits > 8) acpi_ec_burst_disable(ec); + if (ec->global_lock) + acpi_release_global_lock(glk); + +unlock: + mutex_unlock(&ec->mutex); + switch (result) { case -EINVAL: return AE_BAD_PARAMETER; From 4bb1e7d027413835b086aed35bc3f0713bc0f72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Tue, 9 Jul 2024 22:37:24 +0200 Subject: [PATCH 2/8] ACPI: sysfs: validate return type of _STR method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only buffer objects are valid return values of _STR. If something else is returned description_show() will access invalid memory. Fixes: d1efe3c324ea ("ACPI: Add new sysfs interface to export device description") Cc: All applicable Signed-off-by: Thomas Weißschuh Link: https://patch.msgid.link/20240709-acpi-sysfs-groups-v2-1-058ab0667fa8@weissschuh.net Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_sysfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index 23373faa35ec..95a19e3569c8 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -540,8 +540,9 @@ int acpi_device_setup_files(struct acpi_device *dev) * If device has _STR, 'description' file is created */ if (acpi_has_method(dev->handle, "_STR")) { - status = acpi_evaluate_object(dev->handle, "_STR", - NULL, &buffer); + status = acpi_evaluate_object_typed(dev->handle, "_STR", + NULL, &buffer, + ACPI_TYPE_BUFFER); if (ACPI_FAILURE(status)) buffer.pointer = NULL; dev->pnp.str_obj = buffer.pointer; From 52831d9bbc9aa029aed525dfbe61cb78c1db991c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Tue, 9 Jul 2024 22:37:25 +0200 Subject: [PATCH 3/8] ACPI: sysfs: evaluate _STR on each sysfs access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The handling of the _STR method is inconsistent with the other method evaluations. It is the only method which is cached. The cached value stored in 'struct acpi_device_pnp' has a different lifetime than the other struct members. Commit d1efe3c324ea ("ACPI: Add new sysfs interface to export device description") does not explain this difference. Evaluating the method every time also removes the necessity to manage the lifetime of the cached value, which would be a problem when managing the sysfs attributes through the device core. Signed-off-by: Thomas Weißschuh Link: https://patch.msgid.link/20240709-acpi-sysfs-groups-v2-2-058ab0667fa8@weissschuh.net Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_sysfs.c | 30 +++++++++++++++--------------- include/acpi/acpi_bus.h | 1 - 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index 95a19e3569c8..6e4858ea035f 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -439,23 +439,33 @@ static ssize_t description_show(struct device *dev, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *str_obj; + acpi_status status; int result; - if (acpi_dev->pnp.str_obj == NULL) - return 0; + status = acpi_evaluate_object_typed(acpi_dev->handle, "_STR", + NULL, &buffer, + ACPI_TYPE_BUFFER); + if (ACPI_FAILURE(status)) + return -EIO; + + str_obj = buffer.pointer; /* * The _STR object contains a Unicode identifier for a device. * We need to convert to utf-8 so it can be displayed. */ result = utf16s_to_utf8s( - (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, - acpi_dev->pnp.str_obj->buffer.length, + (wchar_t *)str_obj->buffer.pointer, + str_obj->buffer.length, UTF16_LITTLE_ENDIAN, buf, PAGE_SIZE - 1); buf[result++] = '\n'; + kfree(str_obj); + return result; } static DEVICE_ATTR_RO(description); @@ -513,8 +523,6 @@ static DEVICE_ATTR_RO(status); */ int acpi_device_setup_files(struct acpi_device *dev) { - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_status status; int result = 0; /* @@ -540,12 +548,6 @@ int acpi_device_setup_files(struct acpi_device *dev) * If device has _STR, 'description' file is created */ if (acpi_has_method(dev->handle, "_STR")) { - status = acpi_evaluate_object_typed(dev->handle, "_STR", - NULL, &buffer, - ACPI_TYPE_BUFFER); - if (ACPI_FAILURE(status)) - buffer.pointer = NULL; - dev->pnp.str_obj = buffer.pointer; result = device_create_file(&dev->dev, &dev_attr_description); if (result) goto end; @@ -618,10 +620,8 @@ void acpi_device_remove_files(struct acpi_device *dev) /* * If device has _STR, remove 'description' file */ - if (acpi_has_method(dev->handle, "_STR")) { - kfree(dev->pnp.str_obj); + if (acpi_has_method(dev->handle, "_STR")) device_remove_file(&dev->dev, &dev_attr_description); - } /* * If device has _EJ0, remove 'eject' file. */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 8db5bd382915..d0ec808e2c42 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -255,7 +255,6 @@ struct acpi_device_pnp { struct list_head ids; /* _HID and _CIDs */ acpi_device_name device_name; /* Driver-determined */ acpi_device_class device_class; /* " */ - union acpi_object *str_obj; /* unicode string for _STR method */ }; #define acpi_device_bid(d) ((d)->pnp.bus_id) From f6bae04a40f4441c62f4f8cd3bbe0ecf8b54033e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Tue, 9 Jul 2024 22:37:26 +0200 Subject: [PATCH 4/8] ACPI: sysfs: manage attributes as attribute_group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current manual attribute management is inconsistent and brittle. Not all return values of device_create_file() are checked and the cleanup logic needs to be kept up to date manually. Moving all attributes into an attribute_group and using the is_visible() callback allows the management of all attributes as a single unit. Signed-off-by: Thomas Weißschuh Link: https://patch.msgid.link/20240709-acpi-sysfs-groups-v2-3-058ab0667fa8@weissschuh.net Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_sysfs.c | 187 ++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 106 deletions(-) diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index 6e4858ea035f..4afc773383ad 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -517,6 +517,85 @@ static ssize_t status_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(status); +static struct attribute *acpi_attrs[] = { + &dev_attr_path.attr, + &dev_attr_hid.attr, + &dev_attr_modalias.attr, + &dev_attr_description.attr, + &dev_attr_adr.attr, + &dev_attr_uid.attr, + &dev_attr_sun.attr, + &dev_attr_hrv.attr, + &dev_attr_status.attr, + &dev_attr_eject.attr, + &dev_attr_power_state.attr, + &dev_attr_real_power_state.attr, + NULL +}; + +static bool acpi_show_attr(struct acpi_device *dev, const struct device_attribute *attr) +{ + /* + * Devices gotten from FADT don't have a "path" attribute + */ + if (attr == &dev_attr_path) + return dev->handle; + + if (attr == &dev_attr_hid || attr == &dev_attr_modalias) + return !list_empty(&dev->pnp.ids); + + if (attr == &dev_attr_description) + return acpi_has_method(dev->handle, "_STR"); + + if (attr == &dev_attr_adr) + return dev->pnp.type.bus_address; + + if (attr == &dev_attr_uid) + return acpi_device_uid(dev); + + if (attr == &dev_attr_sun) + return acpi_has_method(dev->handle, "_SUN"); + + if (attr == &dev_attr_hrv) + return acpi_has_method(dev->handle, "_HRV"); + + if (attr == &dev_attr_status) + return acpi_has_method(dev->handle, "_STA"); + + /* + * If device has _EJ0, 'eject' file is created that is used to trigger + * hot-removal function from userland. + */ + if (attr == &dev_attr_eject) + return acpi_has_method(dev->handle, "_EJ0"); + + if (attr == &dev_attr_power_state) + return dev->flags.power_manageable; + + if (attr == &dev_attr_real_power_state) + return dev->flags.power_manageable && dev->power.flags.power_resources; + + dev_warn_once(&dev->dev, "Unexpected attribute: %s\n", attr->attr.name); + return false; +} + +static umode_t acpi_attr_is_visible(struct kobject *kobj, + struct attribute *attr, + int attrno) +{ + struct acpi_device *dev = to_acpi_device(kobj_to_dev(kobj)); + + if (acpi_show_attr(dev, container_of(attr, struct device_attribute, attr))) + return attr->mode; + else + return 0; +} + +static const struct attribute_group acpi_group = { + .attrs = acpi_attrs, + .is_visible = acpi_attr_is_visible, +}; + /** * acpi_device_setup_files - Create sysfs attributes of an ACPI device. * @dev: ACPI device object. @@ -525,80 +604,10 @@ int acpi_device_setup_files(struct acpi_device *dev) { int result = 0; - /* - * Devices gotten from FADT don't have a "path" attribute - */ - if (dev->handle) { - result = device_create_file(&dev->dev, &dev_attr_path); - if (result) - goto end; - } - - if (!list_empty(&dev->pnp.ids)) { - result = device_create_file(&dev->dev, &dev_attr_hid); - if (result) - goto end; - - result = device_create_file(&dev->dev, &dev_attr_modalias); - if (result) - goto end; - } - - /* - * If device has _STR, 'description' file is created - */ - if (acpi_has_method(dev->handle, "_STR")) { - result = device_create_file(&dev->dev, &dev_attr_description); - if (result) - goto end; - } - - if (dev->pnp.type.bus_address) - result = device_create_file(&dev->dev, &dev_attr_adr); - if (acpi_device_uid(dev)) - result = device_create_file(&dev->dev, &dev_attr_uid); - - if (acpi_has_method(dev->handle, "_SUN")) { - result = device_create_file(&dev->dev, &dev_attr_sun); - if (result) - goto end; - } - - if (acpi_has_method(dev->handle, "_HRV")) { - result = device_create_file(&dev->dev, &dev_attr_hrv); - if (result) - goto end; - } - - if (acpi_has_method(dev->handle, "_STA")) { - result = device_create_file(&dev->dev, &dev_attr_status); - if (result) - goto end; - } - - /* - * If device has _EJ0, 'eject' file is created that is used to trigger - * hot-removal function from userland. - */ - if (acpi_has_method(dev->handle, "_EJ0")) { - result = device_create_file(&dev->dev, &dev_attr_eject); - if (result) - return result; - } - - if (dev->flags.power_manageable) { - result = device_create_file(&dev->dev, &dev_attr_power_state); - if (result) - return result; - - if (dev->power.flags.power_resources) - result = device_create_file(&dev->dev, - &dev_attr_real_power_state); - } + result = device_add_group(&dev->dev, &acpi_group); acpi_expose_nondev_subnodes(&dev->dev.kobj, &dev->data); -end: return result; } @@ -609,39 +618,5 @@ end: void acpi_device_remove_files(struct acpi_device *dev) { acpi_hide_nondev_subnodes(&dev->data); - - if (dev->flags.power_manageable) { - device_remove_file(&dev->dev, &dev_attr_power_state); - if (dev->power.flags.power_resources) - device_remove_file(&dev->dev, - &dev_attr_real_power_state); - } - - /* - * If device has _STR, remove 'description' file - */ - if (acpi_has_method(dev->handle, "_STR")) - device_remove_file(&dev->dev, &dev_attr_description); - /* - * If device has _EJ0, remove 'eject' file. - */ - if (acpi_has_method(dev->handle, "_EJ0")) - device_remove_file(&dev->dev, &dev_attr_eject); - - if (acpi_has_method(dev->handle, "_SUN")) - device_remove_file(&dev->dev, &dev_attr_sun); - - if (acpi_has_method(dev->handle, "_HRV")) - device_remove_file(&dev->dev, &dev_attr_hrv); - - if (acpi_device_uid(dev)) - device_remove_file(&dev->dev, &dev_attr_uid); - if (dev->pnp.type.bus_address) - device_remove_file(&dev->dev, &dev_attr_adr); - device_remove_file(&dev->dev, &dev_attr_modalias); - device_remove_file(&dev->dev, &dev_attr_hid); - if (acpi_has_method(dev->handle, "_STA")) - device_remove_file(&dev->dev, &dev_attr_status); - if (dev->handle) - device_remove_file(&dev->dev, &dev_attr_path); + device_remove_group(&dev->dev, &acpi_group); } From cd4884724500232480cf79d8762f3cd716ba4c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Tue, 9 Jul 2024 22:37:27 +0200 Subject: [PATCH 5/8] ACPI: sysfs: manage sysfs attributes through device core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the ACPI sysfs attributes are organized around an attribute_group, the device core can manage them. Signed-off-by: Thomas Weißschuh Link: https://patch.msgid.link/20240709-acpi-sysfs-groups-v2-4-058ab0667fa8@weissschuh.net [ rjw: Changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_sysfs.c | 8 +++++--- drivers/acpi/internal.h | 1 + drivers/acpi/scan.c | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index 4afc773383ad..0bff4a1654ed 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -596,6 +596,11 @@ static const struct attribute_group acpi_group = { .is_visible = acpi_attr_is_visible, }; +const struct attribute_group *acpi_groups[] = { + &acpi_group, + NULL +}; + /** * acpi_device_setup_files - Create sysfs attributes of an ACPI device. * @dev: ACPI device object. @@ -604,8 +609,6 @@ int acpi_device_setup_files(struct acpi_device *dev) { int result = 0; - result = device_add_group(&dev->dev, &acpi_group); - acpi_expose_nondev_subnodes(&dev->dev.kobj, &dev->data); return result; @@ -618,5 +621,4 @@ int acpi_device_setup_files(struct acpi_device *dev) void acpi_device_remove_files(struct acpi_device *dev) { acpi_hide_nondev_subnodes(&dev->data); - device_remove_group(&dev->dev, &acpi_group); } diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 601b670356e5..8e1c21e45d0e 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -120,6 +120,7 @@ int acpi_tie_acpi_dev(struct acpi_device *adev); int acpi_device_add(struct acpi_device *device); int acpi_device_setup_files(struct acpi_device *dev); void acpi_device_remove_files(struct acpi_device *dev); +extern const struct attribute_group *acpi_groups[]; 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); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 59771412686b..14dba8f6faff 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1822,6 +1822,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, device->dev.parent = parent ? &parent->dev : NULL; device->dev.release = release; device->dev.bus = &acpi_bus_type; + device->dev.groups = acpi_groups; fwnode_init(&device->fwnode, &acpi_device_fwnode_ops); acpi_set_device_status(device, ACPI_STA_DEFAULT); acpi_device_get_busid(device); From bb664e50a9e0471fcaf0b2d84ee46a764cd2258d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Tue, 9 Jul 2024 22:37:28 +0200 Subject: [PATCH 6/8] ACPI: sysfs: remove return value of acpi_device_setup_files() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function can not fail anymore, so drop its return value. Signed-off-by: Thomas Weißschuh Link: https://patch.msgid.link/20240709-acpi-sysfs-groups-v2-5-058ab0667fa8@weissschuh.net Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_sysfs.c | 6 +----- drivers/acpi/internal.h | 2 +- drivers/acpi/scan.c | 5 +---- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index 0bff4a1654ed..3961fc47152c 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -605,13 +605,9 @@ const struct attribute_group *acpi_groups[] = { * acpi_device_setup_files - Create sysfs attributes of an ACPI device. * @dev: ACPI device object. */ -int acpi_device_setup_files(struct acpi_device *dev) +void acpi_device_setup_files(struct acpi_device *dev) { - int result = 0; - acpi_expose_nondev_subnodes(&dev->dev.kobj, &dev->data); - - return result; } /** diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 8e1c21e45d0e..ca712a7fde21 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -118,7 +118,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, int type, void (*release)(struct device *)); int acpi_tie_acpi_dev(struct acpi_device *adev); int acpi_device_add(struct acpi_device *device); -int acpi_device_setup_files(struct acpi_device *dev); +void acpi_device_setup_files(struct acpi_device *dev); void acpi_device_remove_files(struct acpi_device *dev); extern const struct attribute_group *acpi_groups[]; void acpi_device_add_finalize(struct acpi_device *device); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 14dba8f6faff..494f4f503e5b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -795,10 +795,7 @@ int acpi_device_add(struct acpi_device *device) goto err; } - result = acpi_device_setup_files(device); - if (result) - pr_err("Error creating sysfs interface for device %s\n", - dev_name(&device->dev)); + acpi_device_setup_files(device); return 0; From 8eea417b5748025d50fd537b224eb7be08e09dfb Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Mon, 12 Aug 2024 20:10:18 +0530 Subject: [PATCH 7/8] ACPI: APD: Add AMDI0015 as platform device Add AMDI0015 to the ACPI APD support list to ensure correct clock settings for the I3C device on the latest AMD platforms. Co-developed-by: Sanket Goswami Signed-off-by: Sanket Goswami Signed-off-by: Shyam Sundar S K Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20240812144018.360847-1-Shyam-sundar.S-k@amd.com [ rjw: Added missing tag ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_apd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index 80f945cbec8a..800f97868448 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -118,6 +118,11 @@ static const struct apd_device_desc wt_i2c_desc = { .fixed_clk_rate = 150000000, }; +static const struct apd_device_desc wt_i3c_desc = { + .setup = acpi_apd_setup, + .fixed_clk_rate = 125000000, +}; + static struct property_entry uart_properties[] = { PROPERTY_ENTRY_U32("reg-io-width", 4), PROPERTY_ENTRY_U32("reg-shift", 2), @@ -231,6 +236,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = { { "AMD0030", }, { "AMD0040", APD_ADDR(fch_misc_desc)}, { "AMDI0010", APD_ADDR(wt_i2c_desc) }, + { "AMDI0015", APD_ADDR(wt_i3c_desc) }, { "AMDI0019", APD_ADDR(wt_i2c_desc) }, { "AMDI0020", APD_ADDR(cz_uart_desc) }, { "AMDI0022", APD_ADDR(cz_uart_desc) }, From eeef9150a174a030894fa159f675ba804ad90c06 Mon Sep 17 00:00:00 2001 From: David Wang <00107082@163.com> Date: Tue, 27 Aug 2024 07:34:37 +0800 Subject: [PATCH 8/8] ACPI: utils: Add rev/func to message when acpi_evaluate_dsm() fails When acpi_evaluate_dsm() fails, the warning message lacks the rev and func information which is available and helpful. For example, iwlwifi would make _DSM queries for lari config, and when it fails, all warning messages are all the same: ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade (0x1001) With this change, the warnings would be more informative: ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade rev:0 func:1 (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade rev:0 func:6 (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade rev:0 func:7 (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade rev:0 func:8 (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade rev:0 func:3 (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade rev:0 func:9 (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade rev:0 func:10 (0x1001) ACPI: \: failed to evaluate _DSM bf0212f2-788f-c64d-a5b3-1f738e285ade rev:0 func:12 (0x1001) Signed-off-by: David Wang <00107082@163.com> Link: https://patch.msgid.link/20240826233437.19632-1-00107082@163.com [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index ae9384282273..6de542d99518 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -801,7 +801,8 @@ acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 func, if (ret != AE_NOT_FOUND) acpi_handle_warn(handle, - "failed to evaluate _DSM %pUb (0x%x)\n", guid, ret); + "failed to evaluate _DSM %pUb rev:%lld func:%lld (0x%x)\n", + guid, rev, func, ret); return NULL; }