diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 81aff651a0d4..db487ff9dd1b 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -48,19 +48,12 @@ static const struct acpi_device_id ac_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, ac_device_ids); -/* Lists of PMIC ACPI HIDs with an (often better) native charger driver */ -static const struct acpi_ac_bl acpi_ac_blacklist[] = { - { "INT33F4", -1 }, /* X-Powers AXP288 PMIC */ - { "INT34D3", 3 }, /* Intel Cherrytrail Whiskey Cove PMIC */ -}; - #ifdef CONFIG_PM_SLEEP static int acpi_ac_resume(struct device *dev); #endif static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); static int ac_sleep_before_get_state_ms; -static int ac_check_pmic = 1; static int ac_only; static struct acpi_driver acpi_ac_driver = { @@ -200,12 +193,6 @@ static int __init thinkpad_e530_quirk(const struct dmi_system_id *d) return 0; } -static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d) -{ - ac_check_pmic = 0; - return 0; -} - static int __init ac_only_quirk(const struct dmi_system_id *d) { ac_only = 1; @@ -214,13 +201,6 @@ static int __init ac_only_quirk(const struct dmi_system_id *d) /* Please keep this list alphabetically sorted */ static const struct dmi_system_id ac_dmi_table[] __initconst = { - { - /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */ - .callback = ac_do_not_check_pmic_quirk, - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), - }, - }, { /* Kodlix GK45 returning incorrect state */ .callback = ac_only_quirk, @@ -228,15 +208,6 @@ static const struct dmi_system_id ac_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "GK45"), }, }, - { - /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */ - .callback = ac_do_not_check_pmic_quirk, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "80XF"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), - }, - }, { /* Lenovo Thinkpad e530, see comment in acpi_ac_notify() */ .callback = thinkpad_e530_quirk, @@ -341,23 +312,15 @@ static int acpi_ac_remove(struct acpi_device *device) static int __init acpi_ac_init(void) { - unsigned int i; int result; if (acpi_disabled) return -ENODEV; - dmi_check_system(ac_dmi_table); + if (acpi_quirk_skip_acpi_ac_and_battery()) + return -ENODEV; - if (ac_check_pmic) { - for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++) - if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1", - acpi_ac_blacklist[i].hrv)) { - pr_info("found native %s PMIC, not loading\n", - acpi_ac_blacklist[i].hid); - return -ENODEV; - } - } + dmi_check_system(ac_dmi_table); result = acpi_bus_register_driver(&acpi_ac_driver); if (result < 0) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 8afa85d6eb6a..bf4b7f0b627a 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -52,7 +52,6 @@ static bool battery_driver_registered; static int battery_bix_broken_package; static int battery_notification_delay_ms; static int battery_ac_is_broken; -static int battery_check_pmic = 1; static unsigned int cache_time = 1000; module_param(cache_time, uint, 0644); MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); @@ -64,11 +63,6 @@ static const struct acpi_device_id battery_device_ids[] = { MODULE_DEVICE_TABLE(acpi, battery_device_ids); -/* Lists of PMIC ACPI HIDs with an (often better) native battery driver */ -static const char * const acpi_battery_blacklist[] = { - "INT33F4", /* X-Powers AXP288 PMIC */ -}; - enum { ACPI_BATTERY_ALARM_PRESENT, ACPI_BATTERY_XINFO_PRESENT, @@ -1104,13 +1098,6 @@ battery_ac_is_broken_quirk(const struct dmi_system_id *d) return 0; } -static int __init -battery_do_not_check_pmic_quirk(const struct dmi_system_id *d) -{ - battery_check_pmic = 0; - return 0; -} - static const struct dmi_system_id bat_dmi_table[] __initconst = { { /* NEC LZ750/LS */ @@ -1139,22 +1126,6 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = { DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"), }, }, - { - /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */ - .callback = battery_do_not_check_pmic_quirk, - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), - }, - }, - { - /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */ - .callback = battery_do_not_check_pmic_quirk, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "80XF"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), - }, - }, {}, }; @@ -1279,19 +1250,12 @@ static struct acpi_driver acpi_battery_driver = { static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) { - unsigned int i; int result; - dmi_check_system(bat_dmi_table); + if (acpi_quirk_skip_acpi_ac_and_battery()) + return; - if (battery_check_pmic) { - for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++) - if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) { - pr_info("found native %s PMIC, not loading\n", - acpi_battery_blacklist[i]); - return; - } - } + dmi_check_system(bat_dmi_table); result = acpi_bus_register_driver(&acpi_battery_driver); battery_driver_registered = (result == 0); diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index 375a0911f06d..5411f2f1254e 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -8,6 +8,8 @@ * Copyright (C) 2013-2015 Intel Corporation. All rights reserved. */ +#define pr_fmt(fmt) "ACPI: " fmt + #include #include #include @@ -210,7 +212,6 @@ bool force_storage_d3(void) return x86_match_cpu(storage_d3_cpu_ids); } -#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS) /* * x86 ACPI boards which ship with only Android as their factory image usually * declare a whole bunch of bogus I2C devices in their ACPI tables and sometimes @@ -236,8 +237,36 @@ bool force_storage_d3(void) */ #define ACPI_QUIRK_SKIP_I2C_CLIENTS BIT(0) #define ACPI_QUIRK_UART1_TTY_UART2_SKIP BIT(1) +#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY BIT(2) +#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY BIT(3) -static const struct dmi_system_id acpi_skip_serial_bus_enumeration_ids[] = { +static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { + /* + * 1. Devices with only the skip / don't-skip AC and battery quirks, + * sorted alphabetically. + */ + { + /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), + }, + .driver_data = (void *)ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY + }, + { + /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "80XF"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), + }, + .driver_data = (void *)ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY + }, + + /* + * 2. Devices which also have the skip i2c/serdev quirks and which + * need the x86-android-tablets module to properly work. + */ +#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS) { .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), @@ -263,9 +292,11 @@ static const struct dmi_system_id acpi_skip_serial_bus_enumeration_ids[] = { }, .driver_data = (void *)ACPI_QUIRK_SKIP_I2C_CLIENTS, }, +#endif {} }; +#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS) static const struct acpi_device_id i2c_acpi_known_good_ids[] = { { "10EC5640", 0 }, /* RealTek ALC5640 audio codec */ { "INT33F4", 0 }, /* X-Powers AXP288 PMIC */ @@ -279,7 +310,7 @@ bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev) const struct dmi_system_id *dmi_id; long quirks; - dmi_id = dmi_first_match(acpi_skip_serial_bus_enumeration_ids); + dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids); if (!dmi_id) return false; @@ -303,7 +334,7 @@ int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *s if (!adev || !adev->pnp.unique_id || !dev_is_platform(controller_parent)) return 0; - dmi_id = dmi_first_match(acpi_skip_serial_bus_enumeration_ids); + dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids); if (dmi_id) quirks = (unsigned long)dmi_id->driver_data; @@ -319,3 +350,41 @@ int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *s } EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration); #endif + +/* Lists of PMIC ACPI HIDs with an (often better) native charger driver */ +static const struct { + const char *hid; + int hrv; +} acpi_skip_ac_and_battery_pmic_ids[] = { + { "INT33F4", -1 }, /* X-Powers AXP288 PMIC */ + { "INT34D3", 3 }, /* Intel Cherrytrail Whiskey Cove PMIC */ +}; + +bool acpi_quirk_skip_acpi_ac_and_battery(void) +{ + const struct dmi_system_id *dmi_id; + long quirks = 0; + int i; + + dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids); + if (dmi_id) + quirks = (unsigned long)dmi_id->driver_data; + + if (quirks & ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY) + return true; + + if (quirks & ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY) + return false; + + for (i = 0; i < ARRAY_SIZE(acpi_skip_ac_and_battery_pmic_ids); i++) { + if (acpi_dev_present(acpi_skip_ac_and_battery_pmic_ids[i].hid, "1", + acpi_skip_ac_and_battery_pmic_ids[i].hrv)) { + pr_info_once("found native %s PMIC, skipping ACPI AC and battery devices\n", + acpi_skip_ac_and_battery_pmic_ids[i].hid); + return true; + } + } + + return false; +} +EXPORT_SYMBOL_GPL(acpi_quirk_skip_acpi_ac_and_battery); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 80c425bc98a7..04b9ace9689b 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -615,12 +615,17 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev); #ifdef CONFIG_X86 bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status); +bool acpi_quirk_skip_acpi_ac_and_battery(void); #else static inline bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status) { return false; } +static inline bool acpi_quirk_skip_acpi_ac_and_battery(void) +{ + return false; +} #endif #if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS)