From 46d839adcc93ccc445f90866c31b2ed2785f0319 Mon Sep 17 00:00:00 2001 From: shitao Date: Mon, 7 Apr 2025 16:54:19 +0800 Subject: [PATCH 1/7] ACPI: battery: Round capacity percengate to closest integer If the difference between capacity_now and full_capacity is within 0.5%, 100% is arguably a better number to expose than 99% and exposing the latter may confuse the user to think that there's something wrong with the battery. Round the capacity percentage to the closest integer value to avoid the confusion. Signed-off-by: shitao Link: https://patch.msgid.link/20250407085419.494234-1-shitao@kylinos.cn [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 6760330a8af5..6905b56bf3e4 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -279,8 +279,8 @@ static int acpi_battery_get_property(struct power_supply *psy, full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else - val->intval = battery->capacity_now * 100/ - full_capacity; + val->intval = DIV_ROUND_CLOSEST_ULL(battery->capacity_now * 100ULL, + full_capacity); break; case POWER_SUPPLY_PROP_CAPACITY_LEVEL: if (battery->state & ACPI_BATTERY_STATE_CRITICAL) From 6cb9441bfe8dd7fb91134de3c40c33fbbf0ed4c5 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Mon, 17 Mar 2025 10:13:20 +0000 Subject: [PATCH 2/7] ACPI: APEI: EINJ: Transition to the faux device interface The APEI error injection driver does not require the creation of a platform device. Originally, this approach was chosen for simplicity when the driver was first implemented. With the introduction of the lightweight faux device interface, we now have a more appropriate alternative. Migrate the driver to utilize the faux bus, given that the platform device it previously created was not a real one anyway. This will simplify the code, reducing its footprint while maintaining functionality. Signed-off-by: Sudeep Holla Link: https://patch.msgid.link/20250317-plat2faux_dev-v1-8-5fe67c085ad5@arm.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/einj-core.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c index 04731a5b01fa..7ff334422899 100644 --- a/drivers/acpi/apei/einj-core.c +++ b/drivers/acpi/apei/einj-core.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include "apei-internal.h" @@ -749,7 +749,7 @@ static int einj_check_table(struct acpi_table_einj *einj_tab) return 0; } -static int __init einj_probe(struct platform_device *pdev) +static int __init einj_probe(struct faux_device *fdev) { int rc; acpi_status status; @@ -851,7 +851,7 @@ static int __init einj_probe(struct platform_device *pdev) return rc; } -static void __exit einj_remove(struct platform_device *pdev) +static void __exit einj_remove(struct faux_device *fdev) { struct apei_exec_context ctx; @@ -872,34 +872,25 @@ static void __exit einj_remove(struct platform_device *pdev) acpi_put_table((struct acpi_table_header *)einj_tab); } -static struct platform_device *einj_dev; +static struct faux_device *einj_dev; /* * einj_remove() lives in .exit.text. For drivers registered via * platform_driver_probe() this is ok because they cannot get unbound at * runtime. So mark the driver struct with __refdata to prevent modpost * triggering a section mismatch warning. */ -static struct platform_driver einj_driver __refdata = { +static struct faux_device_ops einj_device_ops __refdata = { + .probe = einj_probe, .remove = __exit_p(einj_remove), - .driver = { - .name = "acpi-einj", - }, }; static int __init einj_init(void) { - struct platform_device_info einj_dev_info = { - .name = "acpi-einj", - .id = -1, - }; - int rc; + einj_dev = faux_device_create("acpi-einj", NULL, &einj_device_ops); + if (!einj_dev) + return -ENODEV; - einj_dev = platform_device_register_full(&einj_dev_info); - if (IS_ERR(einj_dev)) - return PTR_ERR(einj_dev); - - rc = platform_driver_probe(&einj_driver, einj_probe); - einj_initialized = rc == 0; + einj_initialized = true; return 0; } @@ -907,9 +898,8 @@ static int __init einj_init(void) static void __exit einj_exit(void) { if (einj_initialized) - platform_driver_unregister(&einj_driver); + faux_device_destroy(einj_dev); - platform_device_unregister(einj_dev); } module_init(einj_init); From 368604c739cf25802f71edac16a0fcac97e4e671 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 1 May 2025 13:46:21 +0100 Subject: [PATCH 3/7] ACPI: APEI: EINJ: Fix probe error message Commit 6cb9441bfe8d ("ACPI: APEI: EINJ: Transition to the faux device interface") updated the APEI error injection driver to use the faux device interface and now for devices that don't support ACPI, the following error message is seen on boot: ERR KERN faux acpi-einj: probe did not succeed, tearing down the device The APEI error injection driver returns -ENODEV in the probe function if ACPI is not supported and so after transitioning the driver to the faux device interface, the error returned from the probe now causes the above error message to be displayed. Fix this by moving the code that detects if ACPI is supported to the einj_init() function to fix the false error message displayed for devices that don't support ACPI. Fixes: 6cb9441bfe8d ("ACPI: APEI: EINJ: Transition to the faux device interface") Signed-off-by: Jon Hunter Reviewed-by: Sudeep Holla Link: https://patch.msgid.link/20250501124621.1251450-1-jonathanh@nvidia.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/einj-core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c index 7ff334422899..ea4fef3a9bb5 100644 --- a/drivers/acpi/apei/einj-core.c +++ b/drivers/acpi/apei/einj-core.c @@ -755,11 +755,6 @@ static int __init einj_probe(struct faux_device *fdev) acpi_status status; struct apei_exec_context ctx; - if (acpi_disabled) { - pr_debug("ACPI disabled.\n"); - return -ENODEV; - } - status = acpi_get_table(ACPI_SIG_EINJ, 0, (struct acpi_table_header **)&einj_tab); if (status == AE_NOT_FOUND) { @@ -886,6 +881,11 @@ static struct faux_device_ops einj_device_ops __refdata = { static int __init einj_init(void) { + if (acpi_disabled) { + pr_debug("ACPI disabled.\n"); + return -ENODEV; + } + einj_dev = faux_device_create("acpi-einj", NULL, &einj_device_ops); if (!einj_dev) return -ENODEV; From eba614b8280a971d5b39a75349bec2329d897b5d Mon Sep 17 00:00:00 2001 From: Pei Xiao Date: Fri, 25 Apr 2025 11:48:08 +0800 Subject: [PATCH 4/7] ACPI: PCI: Constify fwnode_handle in acpi_pci_root_remap_iospace() The fwnode_handle pointer passed into pci_register_io_range() is not modified, so annotate it as const. Signed-off-by: Pei Xiao Link: https://patch.msgid.link/7ae7866ab8b897253703ecee44c688b6832d49a3.1745552799.git.xiaopei01@kylinos.cn [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index d0b6a024daae..74ade4160314 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -858,7 +858,7 @@ static void acpi_pci_root_validate_resources(struct device *dev, } } -static void acpi_pci_root_remap_iospace(struct fwnode_handle *fwnode, +static void acpi_pci_root_remap_iospace(const struct fwnode_handle *fwnode, struct resource_entry *entry) { #ifdef PCI_IOBASE From 234f71555019d308c6bc6f98c78c5551cb8cd56a Mon Sep 17 00:00:00 2001 From: Peter Marheine Date: Thu, 8 May 2025 12:41:45 +1000 Subject: [PATCH 5/7] ACPI: battery: negate current when discharging The ACPI specification requires that battery rate is always positive, but the kernel ABI for POWER_SUPPLY_PROP_CURRENT_NOW (Documentation/ABI/testing/sysfs-class-power) specifies that it should be negative when a battery is discharging. When reporting CURRENT_NOW, massage the value to match the documented ABI. This only changes the sign of `current_now` and not `power_now` because documentation doesn't describe any particular meaning for `power_now` so leaving `power_now` unchanged is less likely to confuse userspace unnecessarily, whereas becoming consistent with the documented ABI is worth potentially confusing clients that read `current_now`. Signed-off-by: Peter Marheine Link: https://patch.msgid.link/20250508024146.1436129-1-pmarheine@chromium.org Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 6905b56bf3e4..45593612a4db 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -243,10 +243,23 @@ static int acpi_battery_get_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_CURRENT_NOW: case POWER_SUPPLY_PROP_POWER_NOW: - if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) + if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) { ret = -ENODEV; - else - val->intval = battery->rate_now * 1000; + break; + } + + val->intval = battery->rate_now * 1000; + /* + * When discharging, the current should be reported as a + * negative number as per the power supply class interface + * definition. + */ + if (psp == POWER_SUPPLY_PROP_CURRENT_NOW && + (battery->state & ACPI_BATTERY_STATE_DISCHARGING) && + acpi_battery_handle_discharging(battery) + == POWER_SUPPLY_STATUS_DISCHARGING) + val->intval = -val->intval; + break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: From 9cd51eefae3c871440b93c03716c5398f41bdf78 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Thu, 8 May 2025 13:16:18 +0200 Subject: [PATCH 6/7] ACPI: EC: Add device to acpi_ec_no_wakeup[] qurik list Add the TUXEDO InfinityBook Pro AMD Gen9 to the acpi_ec_no_wakeup[] quirk list to prevent spurious wakeups. Signed-off-by: Werner Sembach Link: https://patch.msgid.link/20250508111625.12149-1-wse@tuxedocomputers.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 3c5f34892734..6f4203716b53 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -2329,6 +2329,12 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = { DMI_MATCH(DMI_PRODUCT_NAME, "83Q3"), } }, + { + // TUXEDO InfinityBook Pro AMD Gen9 + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GXxHRXx"), + }, + }, { }, }; From e54b1dc1c4f083cb66a70d8ccc866de47fc36d7a Mon Sep 17 00:00:00 2001 From: Zaid Alali Date: Tue, 6 May 2025 14:38:08 -0700 Subject: [PATCH 7/7] ACPI: APEI: EINJ: Remove redundant calls to einj_get_available_error_type() A single call to einj_get_available_error_type() in init function is sufficient to save the return value in a global variable to be used later in various places in the code. This change has no functional impact, but only removes unnecessary redundant function calls. Reviewed-by: Jonathan Cameron Reviewed-by: Ira Weiny Signed-off-by: Zaid Alali Link: https://patch.msgid.link/20250506213814.2365788-5-zaidal@os.amperecomputing.com [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/einj-core.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c index ea4fef3a9bb5..ca3484dac5c4 100644 --- a/drivers/acpi/apei/einj-core.c +++ b/drivers/acpi/apei/einj-core.c @@ -83,6 +83,8 @@ static struct debugfs_blob_wrapper vendor_blob; static struct debugfs_blob_wrapper vendor_errors; static char vendor_dev[64]; +static u32 available_error_type; + /* * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the * EINJ table through an unpublished extension. Use with caution as @@ -648,14 +650,9 @@ static struct { u32 mask; const char *str; } const einj_error_type_string[] = { static int available_error_type_show(struct seq_file *m, void *v) { - int rc; - u32 error_type = 0; - rc = einj_get_available_error_type(&error_type); - if (rc) - return rc; for (int pos = 0; pos < ARRAY_SIZE(einj_error_type_string); pos++) - if (error_type & einj_error_type_string[pos].mask) + if (available_error_type & einj_error_type_string[pos].mask) seq_printf(m, "0x%08x\t%s\n", einj_error_type_string[pos].mask, einj_error_type_string[pos].str); @@ -678,8 +675,7 @@ bool einj_is_cxl_error_type(u64 type) int einj_validate_error_type(u64 type) { - u32 tval, vendor, available_error_type = 0; - int rc; + u32 tval, vendor; /* Only low 32 bits for error type are valid */ if (type & GENMASK_ULL(63, 32)) @@ -695,13 +691,9 @@ int einj_validate_error_type(u64 type) /* Only one error type can be specified */ if (tval & (tval - 1)) return -EINVAL; - if (!vendor) { - rc = einj_get_available_error_type(&available_error_type); - if (rc) - return rc; + if (!vendor) if (!(type & available_error_type)) return -EINVAL; - } return 0; } @@ -772,6 +764,10 @@ static int __init einj_probe(struct faux_device *fdev) goto err_put_table; } + rc = einj_get_available_error_type(&available_error_type); + if (rc) + return rc; + rc = -ENOMEM; einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir());