ACPI fixes for 3.10-rc7
- 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. - 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. / -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJRw3LNAAoJEKhOf7ml8uNskwcP/308WmvIElGA6Ty6dY/nN2il S9r6zC+EWeW9nsDczKL8CYBQYnBqoJ52gjk3eJRLUV7EZhqUVaYJ2tak2dbEfSQq 6Sq1YuBNaeAQxIeWsV/xIAwWW6rPH7Mh28E5DddNGm35h8NCrudFlO5CJmA9qssq CbxCVSKul/jJEG3CTgDYMaqjeckXqgx9dobII/e+PAVdKoO6GM0eXcgqTiDJ6+xT RVZE7QaiS5rAvVzUuqveeSDJDthukoIftrC9GoREPkSeCrDTM8we1OwlhpMuHJyr bPb0oRgNmI328ZDnv3/uUqyGInYzp1OgOPx/beG4FmpNEw7J9ucHGyPhC/Mu9aoa CcRuAg1oweDtT2vzfDq0sgO8KfZLcAOkS+mhq9DyLQVgsyxLeLEIfQA1mHmfsZYr Y2aETzXEunGpvEOXMXBFDuK0VfdJhAfgtDHBcxg1oOnxFGDXdjNcLY9UuFAbRpE1 GD6zIIZrU2ZJp9jX146QBddws8Ac6drH1jpByROl8RNYG5PzWoPV2KEwfx/s9NG0 wfCtFOSBHThIStiJHkNK9ZTMI83xLgGOkx/JraRy/Vtz5bXRs2h/5WuFYt3BIiOh rNTqgjX7z17rYR6llBlXb296u7uJlEiUVYoVm1E5UzXUeQyvxZ9Ixi1tZ9Vz50C4 6dTYeIvtyCxIVHyOGxn/ =V0L1 -----END PGP SIGNATURE----- Merge tag 'acpi-3.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm 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
This commit is contained in:
Коммит
64a2f30a89
|
@ -164,15 +164,24 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
|
||||||
if (dev_desc->clk_required) {
|
if (dev_desc->clk_required) {
|
||||||
ret = register_device_clock(adev, pdata);
|
ret = register_device_clock(adev, pdata);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/*
|
/* Skip the device, but continue the namespace scan. */
|
||||||
* Skip the device, but don't terminate the namespace
|
ret = 0;
|
||||||
* scan.
|
goto err_out;
|
||||||
*/
|
|
||||||
kfree(pdata);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
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;
|
adev->driver_data = pdata;
|
||||||
ret = acpi_create_platform_device(adev, id);
|
ret = acpi_create_platform_device(adev, id);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
|
|
|
@ -290,6 +290,26 @@ int acpi_bus_init_power(struct acpi_device *device)
|
||||||
return 0;
|
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)
|
int acpi_bus_update_power(acpi_handle handle, int *state_p)
|
||||||
{
|
{
|
||||||
struct acpi_device *device;
|
struct acpi_device *device;
|
||||||
|
|
|
@ -868,8 +868,10 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
|
||||||
if (!count)
|
if (!count)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
acpi_scan_lock_acquire();
|
||||||
begin_undock(dock_station);
|
begin_undock(dock_station);
|
||||||
ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST);
|
ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST);
|
||||||
|
acpi_scan_lock_release();
|
||||||
return ret ? ret: count;
|
return ret ? ret: count;
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock);
|
static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock);
|
||||||
|
|
|
@ -885,6 +885,7 @@ int acpi_add_power_resource(acpi_handle handle)
|
||||||
ACPI_STA_DEFAULT);
|
ACPI_STA_DEFAULT);
|
||||||
mutex_init(&resource->resource_lock);
|
mutex_init(&resource->resource_lock);
|
||||||
INIT_LIST_HEAD(&resource->dependent);
|
INIT_LIST_HEAD(&resource->dependent);
|
||||||
|
INIT_LIST_HEAD(&resource->list_node);
|
||||||
resource->name = device->pnp.bus_id;
|
resource->name = device->pnp.bus_id;
|
||||||
strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
|
strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
|
||||||
strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
|
strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
|
||||||
|
|
|
@ -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,
|
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;
|
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:
|
* In IO-APIC mode, use overrided attribute. Two reasons:
|
||||||
* 1. BIOS bug in DSDT
|
* 1. BIOS bug in DSDT
|
||||||
* 2. BIOS uses IO-APIC mode Interrupt Source Override
|
* 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 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
|
||||||
u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
|
u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
|
||||||
|
|
||||||
if (triggering != trig || polarity != pol) {
|
if (triggering != trig || polarity != pol) {
|
||||||
pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
|
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;
|
triggering = trig;
|
||||||
polarity = pol;
|
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],
|
acpi_dev_get_irqresource(res, irq->interrupts[index],
|
||||||
irq->triggering, irq->polarity,
|
irq->triggering, irq->polarity,
|
||||||
irq->sharable);
|
irq->sharable, true);
|
||||||
break;
|
break;
|
||||||
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
|
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
|
||||||
ext_irq = &ares->data.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],
|
acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
|
||||||
ext_irq->triggering, ext_irq->polarity,
|
ext_irq->triggering, ext_irq->polarity,
|
||||||
ext_irq->sharable);
|
ext_irq->sharable, false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -382,6 +382,7 @@ const char *acpi_power_state_string(int state);
|
||||||
int acpi_device_get_power(struct acpi_device *device, int *state);
|
int acpi_device_get_power(struct acpi_device *device, int *state);
|
||||||
int acpi_device_set_power(struct acpi_device *device, int state);
|
int acpi_device_set_power(struct acpi_device *device, int state);
|
||||||
int acpi_bus_init_power(struct acpi_device *device);
|
int acpi_bus_init_power(struct acpi_device *device);
|
||||||
|
int acpi_device_fix_up_power(struct acpi_device *device);
|
||||||
int acpi_bus_update_power(acpi_handle handle, int *state_p);
|
int acpi_bus_update_power(acpi_handle handle, int *state_p);
|
||||||
bool acpi_bus_power_manageable(acpi_handle handle);
|
bool acpi_bus_power_manageable(acpi_handle handle);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче