Commit 3a1e24fa authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more ACPI updates from Rafael Wysocki:
 "These fix two issues, in APEI and in the int3472 driver, clean up the
  ACPI thermal driver, add ACPI support for non-GPE system wakeup events
  and make the system reboot code use the S5 (system off) state by
  default.

  Specifics:

   - Fix ACPI device object reference counting in (recently updated)
     skl_int3472_fill_clk_pdata() (Andy Shevchenko).

   - Fix a memory leak in APEI by avoiding to add a task_work to kernel
     threads running when an asynchronous error is detected (Shuai Xue).

   - Add ACPI support for handling system wakeups via GPIO wake capable
     IRQs in addition to GPEs (Raul E Rangel).

   - Make the system reboot code put ACPI-enabled systems into the S5
     (system off) state which is necessary for some platforms to work as
     expected (Kai-Heng Feng).

   - Make the white space usage in the ACPI thermal driver more
     consistent and drop redundant code from it (Rafael Wysocki)"

* tag 'acpi-6.1-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI: thermal: Drop some redundant code
  ACPI: thermal: Drop redundant parens from expressions
  ACPI: thermal: Use white space more consistently
  platform/x86: int3472: Don't leak reference on error
  ACPI: APEI: do not add task_work to kernel thread to avoid memory leak
  PM: ACPI: reboot: Reinstate S5 for reboot
  kernel/reboot: Add SYS_OFF_MODE_RESTART_PREPARE mode
  ACPI: PM: Take wake IRQ into consideration when entering suspend-to-idle
  i2c: acpi: Use ACPI wake capability bit to set wake_irq
  ACPI: resources: Add wake_capable parameter to acpi_dev_irq_flags
  gpiolib: acpi: Add wake_capable variants of acpi_dev_gpio_irq_get
parents 10b22b53 056a8154
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -985,7 +985,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
				ghes_estatus_cache_add(generic, estatus);
		}

		if (task_work_pending && current->mm != &init_mm) {
		if (task_work_pending && current->mm) {
			estatus_node->task_work.func = ghes_kick_task_work;
			estatus_node->task_work_cpu = smp_processor_id();
			ret = task_work_add(current, &estatus_node->task_work,
+15 −0
Original line number Diff line number Diff line
@@ -687,7 +687,22 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev,
		d_min = ret;
		wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid
			&& adev->wakeup.sleep_state >= target_state;
	} else if (device_may_wakeup(dev) && dev->power.wakeirq) {
		/*
		 * The ACPI subsystem doesn't manage the wake bit for IRQs
		 * defined with ExclusiveAndWake and SharedAndWake. Instead we
		 * expect them to be managed via the PM subsystem. Drivers
		 * should call dev_pm_set_wake_irq to register an IRQ as a wake
		 * source.
		 *
		 * If a device has a wake IRQ attached we need to check the
		 * _S0W method to get the correct wake D-state. Otherwise we
		 * end up putting the device into D3Cold which will more than
		 * likely disable wake functionality.
		 */
		wakeup = true;
	} else {
		/* ACPI GPE is specified in _PRW. */
		wakeup = adev->wakeup.flags.valid;
	}

+5 −3
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ struct acpi_irq_parse_one_ctx {
 * @polarity: polarity attributes of hwirq
 * @polarity: polarity attributes of hwirq
 * @shareable: shareable attributes of hwirq
 * @wake_capable: wake capable attribute of hwirq
 * @ctx: acpi_irq_parse_one_ctx updated by this function
 *
 * Description:
@@ -156,12 +157,13 @@ struct acpi_irq_parse_one_ctx {
static inline void acpi_irq_parse_one_match(struct fwnode_handle *fwnode,
					    u32 hwirq, u8 triggering,
					    u8 polarity, u8 shareable,
					    u8 wake_capable,
					    struct acpi_irq_parse_one_ctx *ctx)
{
	if (!fwnode)
		return;
	ctx->rc = 0;
	*ctx->res_flags = acpi_dev_irq_flags(triggering, polarity, shareable);
	*ctx->res_flags = acpi_dev_irq_flags(triggering, polarity, shareable, wake_capable);
	ctx->fwspec->fwnode = fwnode;
	ctx->fwspec->param[0] = hwirq;
	ctx->fwspec->param[1] = acpi_dev_get_irq_type(triggering, polarity);
@@ -204,7 +206,7 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
		fwnode = acpi_get_gsi_domain_id(irq->interrupts[ctx->index]);
		acpi_irq_parse_one_match(fwnode, irq->interrupts[ctx->index],
					 irq->triggering, irq->polarity,
					 irq->shareable, ctx);
					 irq->shareable, irq->wake_capable, ctx);
		return AE_CTRL_TERMINATE;
	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
		eirq = &ares->data.extended_irq;
@@ -218,7 +220,7 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
						      eirq->interrupts[ctx->index]);
		acpi_irq_parse_one_match(fwnode, eirq->interrupts[ctx->index],
					 eirq->triggering, eirq->polarity,
					 eirq->shareable, ctx);
					 eirq->shareable, eirq->wake_capable, ctx);
		return AE_CTRL_TERMINATE;
	}

+11 −5
Original line number Diff line number Diff line
@@ -336,8 +336,9 @@ EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space);
 * @triggering: Triggering type as provided by ACPI.
 * @polarity: Interrupt polarity as provided by ACPI.
 * @shareable: Whether or not the interrupt is shareable.
 * @wake_capable: Wake capability as provided by ACPI.
 */
unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable, u8 wake_capable)
{
	unsigned long flags;

@@ -351,6 +352,9 @@ unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
	if (shareable == ACPI_SHARED)
		flags |= IORESOURCE_IRQ_SHAREABLE;

	if (wake_capable == ACPI_WAKE_CAPABLE)
		flags |= IORESOURCE_IRQ_WAKECAPABLE;

	return flags | IORESOURCE_IRQ;
}
EXPORT_SYMBOL_GPL(acpi_dev_irq_flags);
@@ -468,7 +472,7 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,

static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
				     u8 triggering, u8 polarity, u8 shareable,
				     bool check_override)
				     u8 wake_capable, bool check_override)
{
	int irq, p, t;

@@ -501,7 +505,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
		}
	}

	res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
	res->flags = acpi_dev_irq_flags(triggering, polarity, shareable, wake_capable);
	irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
	if (irq >= 0) {
		res->start = irq;
@@ -549,7 +553,8 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
		}
		acpi_dev_get_irqresource(res, irq->interrupts[index],
					 irq->triggering, irq->polarity,
					 irq->shareable, true);
					 irq->shareable, irq->wake_capable,
					 true);
		break;
	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
		ext_irq = &ares->data.extended_irq;
@@ -560,7 +565,8 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
		if (is_gsi(ext_irq))
			acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
					 ext_irq->triggering, ext_irq->polarity,
					 ext_irq->shareable, false);
					 ext_irq->shareable, ext_irq->wake_capable,
					 false);
		else
			irqresource_disabled(res, 0);
		break;
+8 −0
Original line number Diff line number Diff line
@@ -1088,6 +1088,14 @@ int __init acpi_sleep_init(void)
		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
					 SYS_OFF_PRIO_FIRMWARE,
					 acpi_power_off, NULL);

		/*
		 * Windows uses S5 for reboot, so some BIOSes depend on it to
		 * perform proper reboot.
		 */
		register_sys_off_handler(SYS_OFF_MODE_RESTART_PREPARE,
					 SYS_OFF_PRIO_FIRMWARE,
					 acpi_power_off_prepare, NULL);
	} else {
		acpi_no_s5 = true;
	}
Loading