Commit f5b4df96 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-pci', 'acpi-battery', 'acpi-ec' and 'acpi-apei'

Merge an ACPI PCI root driver update, ACPI battery driver updates, an
ACPI EC driver update and APEI updates for 6.16-rc1:

 - Turn the acpi_pci_root_remap_iospace() fwnode_handle parameter into a
   const pointer (Pei Xiao).

 - Round battery capacity percengate in the ACPI battery driver to the
   closest integer to avoid user confusion (shitao).

 - Make the ACPI battery driver report the current as a negative number
   to the power supply framework when the battery is discharging as
   documented (Peter Marheine).

 - Add TUXEDO InfinityBook Pro AMD Gen9 to the acpi_ec_no_wakeup[] list
   to prevent spurious wakeups from suspend-to-idle (Werner Sembach).

 - Convert the APEI EINJ driver to a faux device one (Sudeep Holla, Jon
   Hunter).

 - Remove redundant calls to einj_get_available_error_type() from the
   APEI EINJ driver (Zaid Alali).

* acpi-pci:
  ACPI: PCI: Constify fwnode_handle in acpi_pci_root_remap_iospace()

* acpi-battery:
  ACPI: battery: negate current when discharging
  ACPI: battery: Round capacity percengate to closest integer

* acpi-ec:
  ACPI: EC: Add device to acpi_ec_no_wakeup[] qurik list

* acpi-apei:
  ACPI: APEI: EINJ: Remove redundant calls to einj_get_available_error_type()
  ACPI: APEI: EINJ: Fix probe error message
  ACPI: APEI: EINJ: Transition to the faux device interface
Loading
Loading
Loading
Loading
+24 −38
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@
#include <linux/nmi.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/platform_device.h>
#include <linux/device/faux.h>
#include <linux/unaligned.h>

#include "apei-internal.h"
@@ -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;
}
@@ -749,17 +741,12 @@ 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;
	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) {
@@ -777,6 +764,10 @@ static int __init einj_probe(struct platform_device *pdev)
		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());

@@ -851,7 +842,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 +863,30 @@ 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;
	if (acpi_disabled) {
		pr_debug("ACPI disabled.\n");
		return -ENODEV;
	}

	einj_dev = platform_device_register_full(&einj_dev_info);
	if (IS_ERR(einj_dev))
		return PTR_ERR(einj_dev);
	einj_dev = faux_device_create("acpi-einj", NULL, &einj_device_ops);
	if (!einj_dev)
		return -ENODEV;

	rc = platform_driver_probe(&einj_driver, einj_probe);
	einj_initialized = rc == 0;
	einj_initialized = true;

	return 0;
}
@@ -907,9 +894,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);
+18 −5
Original line number Diff line number Diff line
@@ -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
			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:
@@ -279,8 +292,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)
+6 −0
Original line number Diff line number Diff line
@@ -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"),
		},
	},
	{ },
};

+1 −1
Original line number Diff line number Diff line
@@ -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