Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64a2f30a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ACPI fixes from Rafael Wysocki:

 - Fix for a regression causing a failure to turn on some devices on
   some systems during initialization introduced by a recent revert of
   an ACPI PM change that broke something else.  Fortunately, we know
   exactly what devices are affected, so we can add a fix just for them
   leaving everyone else alone.

 - ACPI power resources initialization fix preventing a NULL pointer
   from being dereferenced in the acpi_add_power_resource() error code
   path.

 - ACPI dock station driver fix that adds missing locking to
   write_undock().

 - ACPI resources allocation fix changing the scope of an old workaround
   so that it doesn't affect systems that aren't actually buggy.  This
   was reported a couple of days ago to fix DMA problems on some new
   platforms so we need it in -stable.  From Mika Westerberg.

* tag 'acpi-3.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI / LPSS: Power up LPSS devices during enumeration
  ACPI / PM: Fix error code path for power resources initialization
  ACPI / dock: Take ACPI scan lock in write_undock()
  ACPI / resources: call acpi_get_override_irq() only for legacy IRQ resources
parents 9d0be540 b9e95fc6
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -164,13 +164,22 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
	if (dev_desc->clk_required) {
		ret = register_device_clock(adev, pdata);
		if (ret) {
			/* Skip the device, but continue the namespace scan. */
			ret = 0;
			goto err_out;
		}
	}

	/*
			 * Skip the device, but don't terminate the namespace
			 * scan.
	 * This works around a known issue in ACPI tables where LPSS devices
	 * have _PS0 and _PS3 without _PSC (and no power resources), so
	 * acpi_bus_init_power() will assume that the BIOS has put them into D0.
	 */
			kfree(pdata);
			return 0;
		}
	ret = acpi_device_fix_up_power(adev);
	if (ret) {
		/* Skip the device, but continue the namespace scan. */
		ret = 0;
		goto err_out;
	}

	adev->driver_data = pdata;
+20 −0
Original line number Diff line number Diff line
@@ -290,6 +290,26 @@ int acpi_bus_init_power(struct acpi_device *device)
	return 0;
}

/**
 * acpi_device_fix_up_power - Force device with missing _PSC into D0.
 * @device: Device object whose power state is to be fixed up.
 *
 * Devices without power resources and _PSC, but having _PS0 and _PS3 defined,
 * are assumed to be put into D0 by the BIOS.  However, in some cases that may
 * not be the case and this function should be used then.
 */
int acpi_device_fix_up_power(struct acpi_device *device)
{
	int ret = 0;

	if (!device->power.flags.power_resources
	    && !device->power.flags.explicit_get
	    && device->power.state == ACPI_STATE_D0)
		ret = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0);

	return ret;
}

int acpi_bus_update_power(acpi_handle handle, int *state_p)
{
	struct acpi_device *device;
+2 −0
Original line number Diff line number Diff line
@@ -868,8 +868,10 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
	if (!count)
		return -EINVAL;

	acpi_scan_lock_acquire();
	begin_undock(dock_station);
	ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST);
	acpi_scan_lock_release();
	return ret ? ret: count;
}
static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock);
+1 −0
Original line number Diff line number Diff line
@@ -885,6 +885,7 @@ int acpi_add_power_resource(acpi_handle handle)
				ACPI_STA_DEFAULT);
	mutex_init(&resource->resource_lock);
	INIT_LIST_HEAD(&resource->dependent);
	INIT_LIST_HEAD(&resource->list_node);
	resource->name = device->pnp.bus_id;
	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
+11 −5
Original line number Diff line number Diff line
@@ -304,7 +304,8 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
}

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

@@ -317,14 +318,19 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
	 * In IO-APIC mode, use overrided attribute. Two reasons:
	 * 1. BIOS bug in DSDT
	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
	 *
	 * We do this only if we are dealing with IRQ() or IRQNoFlags()
	 * resource (the legacy ISA resources). With modern ACPI 5 devices
	 * using extended IRQ descriptors we take the IRQ configuration
	 * from _CRS directly.
	 */
	if (!acpi_get_override_irq(gsi, &t, &p)) {
	if (legacy && !acpi_get_override_irq(gsi, &t, &p)) {
		u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
		u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;

		if (triggering != trig || polarity != pol) {
			pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
				   t ? "edge" : "level", p ? "low" : "high");
				   t ? "level" : "edge", p ? "low" : "high");
			triggering = trig;
			polarity = pol;
		}
@@ -373,7 +379,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
		}
		acpi_dev_get_irqresource(res, irq->interrupts[index],
					 irq->triggering, irq->polarity,
					 irq->sharable);
					 irq->sharable, true);
		break;
	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
		ext_irq = &ares->data.extended_irq;
@@ -383,7 +389,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
		}
		acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
					 ext_irq->triggering, ext_irq->polarity,
					 ext_irq->sharable);
					 ext_irq->sharable, false);
		break;
	default:
		return false;
Loading