Hi, > From: linux-acpi-owner@xxxxxxxxxxxxxxx [mailto:linux-acpi-owner@xxxxxxxxxxxxxxx] On Behalf Of Dave > Lambley > Subject: [PATCH] Avoid _BIX ACPI method on Lenovo Yoga 300. > > On the (current?) Yoga 300 firmware, the _BIX method fails with an error. > This prevents the kernel from correctly detecting the presence of a > battery. > > [ 28.641906] ACPI Exception: AE_AML_PACKAGE_LIMIT, Index (0x000000010) is beyond end of object > (length 0xD) (20160422/exoparg2-427) > [ 28.641924] ACPI Error: Method parse/execution failed [\_SB.PCI0.LPCB.H_EC.BAT1._BIX] (Node > ffff9145fb0b2230), AE_AML_PACKAGE_LIMIT (20160422/psparse-542) > > Fortunately, the _BIF method can be used to get battery information. This > change causes the kernel to use the _BIF method to preference on the > Yogo 300, allowing the battery to be detected correctly. Wasn't it better to try _BIX first, and then _BIF next when _BIX failed. What's the merit of increasing the number of the platform quirks? Thanks Lv > > Signed-off-by: Dave Lambley <linux@xxxxxxxxxxx> > Cc: "Rafael J. Wysocki" <rjw@xxxxxxxxxxxxx> > CC: Len Brown <lenb@xxxxxxxxxx> > --- > drivers/acpi/battery.c | 29 +++++++++++++++++++++++++---- > 1 file changed, 25 insertions(+), 4 deletions(-) > > diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c > index ab23479..2b165a8 100644 > --- a/drivers/acpi/battery.c > +++ b/drivers/acpi/battery.c > @@ -69,6 +69,7 @@ MODULE_LICENSE("GPL"); > static async_cookie_t async_cookie; > static int battery_bix_broken_package; > static int battery_notification_delay_ms; > +static int battery_avoid_bix; > static unsigned int cache_time = 1000; > module_param(cache_time, uint, 0644); > MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); > @@ -434,11 +435,16 @@ static int acpi_battery_get_info(struct acpi_battery *battery) > { > int result = -EFAULT; > acpi_status status = 0; > - char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags) ? > - "_BIX" : "_BIF"; > + bool use_bix = !battery_avoid_bix && > + test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); > + > + char *name = use_bix ? "_BIX" : "_BIF"; > > struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; > > + if (battery_avoid_bix) > + dev_dbg(&battery->device->dev, "ACPI _BIX method blacklisted on this hardware, avoiding."); > + > if (!acpi_battery_present(battery)) > return 0; > mutex_lock(&battery->lock); > @@ -451,11 +457,11 @@ static int acpi_battery_get_info(struct acpi_battery *battery) > return -ENODEV; > } > > - if (battery_bix_broken_package) > + if (use_bix && battery_bix_broken_package) > result = extract_package(battery, buffer.pointer, > extended_info_offsets + 1, > ARRAY_SIZE(extended_info_offsets) - 1); > - else if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)) > + else if (use_bix) > result = extract_package(battery, buffer.pointer, > extended_info_offsets, > ARRAY_SIZE(extended_info_offsets)); > @@ -1134,6 +1140,12 @@ battery_notification_delay_quirk(const struct dmi_system_id *d) > return 0; > } > > +static int __init > +battery_avoid_bix_quirk(const struct dmi_system_id *d) > +{ > + battery_avoid_bix = 1; > + return 0; > +} > static const struct dmi_system_id bat_dmi_table[] __initconst = { > { > .callback = battery_bix_broken_package_quirk, > @@ -1151,6 +1163,15 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = { > DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"), > }, > }, > + { > + .callback = battery_avoid_bix_quirk, > + .ident = "Lenovo Yogo 3000", > + .matches = { > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), > + DMI_MATCH(DMI_PRODUCT_NAME, "80M1"), > + }, > + }, > + > {}, > }; > > -- > 2.7.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html