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

Merge branches 'acpi-pm', 'acpi-pci', 'acpi-sysfs' and 'acpi-tables'

Merge power management, PCI and sysfs-related material and changes
related to handling ACPI tables for 5.19-rc1:

 - Improve debug messages in the ACPI device PM code (Rafael Wysocki).

 - Block ASUS B1400CEAE from suspend to idle by default (Mario
   Limonciello).

 - Improve handling of PCI devices that are in D3cold during system
   initialization (Rafael Wysocki).

 - Fix BERT error region memory mapping (Lorenzo Pieralisi).

 - Add support for NVIDIA 16550-compatible port subtype to the SPCR
   parsing code (Jeff Brasen).

 - Use static for BGRT_SHOW kobj_attribute defines (Tom Rix).

 - Fix missing prototype warning for acpi_agdi_init() (Ilkka Koskinen).

* acpi-pm:
  ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default
  ACPI: PM: Always print final debug message in acpi_device_set_power()
  ACPI: PM: Unify debug messages in acpi_device_set_power()
  ACPI: PM: Change pr_fmt() in device_pm.c
  ACPI: PM: Convert debug message in acpi_device_get_power()

* acpi-pci:
  ACPI: bus: Avoid non-ACPI device objects in walks over children
  PCI: ACPI: PM: Power up devices in D3cold before scanning them
  ACPI: PM: Introduce acpi_dev_power_up_children_with_adr()
  ACPI: bus: Introduce acpi_dev_for_each_child()

* acpi-sysfs:
  ACPI: sysfs: Fix BERT error region memory mapping

* acpi-tables:
  ACPI: AGDI: Fix missing prototype warning for acpi_agdi_init()
  ACPI: BGRT: use static for BGRT_SHOW kobj_attribute defines
  ACPI: SPCR: Add support for NVIDIA 16550-compatible port subtype
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#define pr_fmt(fmt) "ACPI: AGDI: " fmt

#include <linux/acpi.h>
#include <linux/acpi_agdi.h>
#include <linux/arm_sdei.h>
#include <linux/io.h>
#include <linux/kernel.h>
+1 −1
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ static struct kobject *bgrt_kobj;
	{									\
		return sysfs_emit(buf, "%d\n", bgrt_tab._member);		\
	}									\
	struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name)
	static struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name)

BGRT_SHOW(version, version);
BGRT_SHOW(status, status);
+26 −0
Original line number Diff line number Diff line
@@ -1070,6 +1070,32 @@ int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data)
}
EXPORT_SYMBOL_GPL(acpi_bus_for_each_dev);

struct acpi_dev_walk_context {
	int (*fn)(struct acpi_device *, void *);
	void *data;
};

static int acpi_dev_for_one_check(struct device *dev, void *context)
{
	struct acpi_dev_walk_context *adwc = context;

	if (dev->bus != &acpi_bus_type)
		return 0;

	return adwc->fn(to_acpi_device(dev), adwc->data);
}

int acpi_dev_for_each_child(struct acpi_device *adev,
			    int (*fn)(struct acpi_device *, void *), void *data)
{
	struct acpi_dev_walk_context adwc = {
		.fn = fn,
		.data = data,
	};

	return device_for_each_child(&adev->dev, &adwc, acpi_dev_for_one_check);
}

/* --------------------------------------------------------------------------
                             Initialization/Cleanup
   -------------------------------------------------------------------------- */
+57 −26
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#define pr_fmt(fmt) "ACPI: PM: " fmt
#define pr_fmt(fmt) "PM: " fmt

#include <linux/acpi.h>
#include <linux/export.h>
@@ -130,7 +130,7 @@ int acpi_device_get_power(struct acpi_device *device, int *state)
	*state = result;

 out:
	dev_dbg(&device->dev, "Device power state is %s\n",
	acpi_handle_debug(device->handle, "Power state: %s\n",
			  acpi_power_state_string(*state));

	return 0;
@@ -173,11 +173,8 @@ int acpi_device_set_power(struct acpi_device *device, int state)
	/* Make sure this is a valid target state */

	/* There is a special case for D0 addressed below. */
	if (state > ACPI_STATE_D0 && state == device->power.state) {
		dev_dbg(&device->dev, "Device already in %s\n",
			acpi_power_state_string(state));
		return 0;
	}
	if (state > ACPI_STATE_D0 && state == device->power.state)
		goto no_change;

	if (state == ACPI_STATE_D3_COLD) {
		/*
@@ -189,15 +186,15 @@ int acpi_device_set_power(struct acpi_device *device, int state)
		if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid)
			target_state = state;
	} else if (!device->power.states[state].flags.valid) {
		dev_warn(&device->dev, "Power state %s not supported\n",
		acpi_handle_debug(device->handle, "Power state %s not supported\n",
				  acpi_power_state_string(state));
		return -ENODEV;
	}

	if (!device->power.flags.ignore_parent &&
	    device->parent && (state < device->parent->power.state)) {
		dev_warn(&device->dev,
			 "Cannot transition to power state %s for parent in %s\n",
	if (!device->power.flags.ignore_parent && device->parent &&
	    state < device->parent->power.state) {
		acpi_handle_debug(device->handle,
				  "Cannot transition to %s for parent in %s\n",
				  acpi_power_state_string(state),
				  acpi_power_state_string(device->parent->power.state));
		return -ENODEV;
@@ -216,7 +213,8 @@ int acpi_device_set_power(struct acpi_device *device, int state)
		 * (deeper) states to higher-power (shallower) states.
		 */
		if (state < device->power.state) {
			dev_warn(&device->dev, "Cannot transition from %s to %s\n",
			acpi_handle_debug(device->handle,
					  "Cannot transition from %s to %s\n",
					  acpi_power_state_string(device->power.state),
					  acpi_power_state_string(state));
			return -ENODEV;
@@ -248,7 +246,7 @@ int acpi_device_set_power(struct acpi_device *device, int state)

			/* Nothing to do here if _PSC is not present. */
			if (!device->power.flags.explicit_get)
				return 0;
				goto no_change;

			/*
			 * The power state of the device was set to D0 last
@@ -263,7 +261,7 @@ int acpi_device_set_power(struct acpi_device *device, int state)
			 */
			result = acpi_dev_pm_explicit_get(device, &psc);
			if (result || psc == ACPI_STATE_D0)
				return 0;
				goto no_change;
		}

		result = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0);
@@ -271,15 +269,21 @@ int acpi_device_set_power(struct acpi_device *device, int state)

end:
	if (result) {
		dev_warn(&device->dev, "Failed to change power state to %s\n",
		acpi_handle_debug(device->handle,
				  "Failed to change power state to %s\n",
				  acpi_power_state_string(target_state));
	} else {
		device->power.state = target_state;
		dev_dbg(&device->dev, "Power state changed to %s\n",
		acpi_handle_debug(device->handle, "Power state changed to %s\n",
				  acpi_power_state_string(target_state));
	}

	return result;

no_change:
	acpi_handle_debug(device->handle, "Already in %s\n",
			  acpi_power_state_string(state));
	return 0;
}
EXPORT_SYMBOL(acpi_device_set_power);

@@ -425,6 +429,33 @@ bool acpi_bus_power_manageable(acpi_handle handle)
}
EXPORT_SYMBOL(acpi_bus_power_manageable);

static int acpi_power_up_if_adr_present(struct acpi_device *adev, void *not_used)
{
	if (!(adev->flags.power_manageable && adev->pnp.type.bus_address))
		return 0;

	acpi_handle_debug(adev->handle, "Power state: %s\n",
			  acpi_power_state_string(adev->power.state));

	if (adev->power.state == ACPI_STATE_D3_COLD)
		return acpi_device_set_power(adev, ACPI_STATE_D0);

	return 0;
}

/**
 * acpi_dev_power_up_children_with_adr - Power up childres with valid _ADR
 * @adev: Parent ACPI device object.
 *
 * Change the power states of the direct children of @adev that are in D3cold
 * and hold valid _ADR objects to D0 in order to allow bus (e.g. PCI)
 * enumeration code to access them.
 */
void acpi_dev_power_up_children_with_adr(struct acpi_device *adev)
{
	acpi_dev_for_each_child(adev, acpi_power_up_if_adr_present, NULL);
}

#ifdef CONFIG_PM
static DEFINE_MUTEX(acpi_pm_notifier_lock);
static DEFINE_MUTEX(acpi_pm_notifier_install_lock);
+2 −0
Original line number Diff line number Diff line
@@ -927,6 +927,8 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
		host_bridge->preserve_config = 1;
	ACPI_FREE(obj);

	acpi_dev_power_up_children_with_adr(device);

	pci_scan_child_bus(bus);
	pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info,
				    info);
Loading