From 7c058c7c74b3dbeb7d157c273959f87faf710350 Mon Sep 17 00:00:00 2001 From: Ravi Chandra Sadineni Date: Wed, 27 Jun 2018 10:55:02 -0700 Subject: ACPI / button: increment wakeup count only when notified Because acpi_lid_initialize_state() is called on every system resume and it triggers acpi_lid_notify_state() which invokes acpi_pm_wakeup_event() for the lid device, the lid's wakeup count is incremented even if the lid was not the source of the event that woke up the system. That behavior confuses user space deamons using wakeup_count to identify the potential system wakeup source. To avoid the confusion, only trigger acpi_pm_wakeup_event() in the acpi_button_notify() path and don't do that in the acpi_lid_initialize_state() path. Signed-off-by: Ravi Chandra Sadineni Signed-off-by: Rafael J. Wysocki --- drivers/acpi/button.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 2345a5ee2dbb..40ed3ec9fc94 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -235,9 +235,6 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) button->last_time = ktime_get(); } - if (state) - acpi_pm_wakeup_event(&device->dev); - ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); if (ret == NOTIFY_DONE) ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, @@ -366,7 +363,8 @@ int acpi_lid_open(void) } EXPORT_SYMBOL(acpi_lid_open); -static int acpi_lid_update_state(struct acpi_device *device) +static int acpi_lid_update_state(struct acpi_device *device, + bool signal_wakeup) { int state; @@ -374,6 +372,9 @@ static int acpi_lid_update_state(struct acpi_device *device) if (state < 0) return state; + if (state && signal_wakeup) + acpi_pm_wakeup_event(&device->dev); + return acpi_lid_notify_state(device, state); } @@ -384,7 +385,7 @@ static void acpi_lid_initialize_state(struct acpi_device *device) (void)acpi_lid_notify_state(device, 1); break; case ACPI_BUTTON_LID_INIT_METHOD: - (void)acpi_lid_update_state(device); + (void)acpi_lid_update_state(device, false); break; case ACPI_BUTTON_LID_INIT_IGNORE: default: @@ -409,7 +410,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) users = button->input->users; mutex_unlock(&button->input->mutex); if (users) - acpi_lid_update_state(device); + acpi_lid_update_state(device, true); } else { int keycode; -- cgit v1.2.3-59-g8ed1b From 2c4c2a71bd6f75c3982ac09407889b110673ac83 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 7 Jul 2018 08:25:01 -0700 Subject: ACPI / button: fix defined but not used warning Fix a build warning in the ACPI button driver when CONFIG_PROC_FS is not enabled by marking the unused function as __maybe_unused. ../drivers/acpi/button.c:252:12: warning: 'acpi_button_state_seq_show' defined but not used [-Wunused-function] Signed-off-by: Randy Dunlap Signed-off-by: Rafael J. Wysocki --- drivers/acpi/button.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 40ed3ec9fc94..a19ff3977ac4 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -21,6 +21,7 @@ #define pr_fmt(fmt) "ACPI: button: " fmt +#include #include #include #include @@ -249,7 +250,8 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) return ret; } -static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) +static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq, + void *offset) { struct acpi_device *device = seq->private; int state; -- cgit v1.2.3-59-g8ed1b From 887532ca7ca59fcf0547a79211756791128030a3 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 18 Jul 2018 11:46:55 -0700 Subject: ACPI / OSI: Add OEM _OSI string to enable NVidia HDMI audio Some ThinkPad systems have a power-saving feature that turns off HDMI audio device in Windows, but NVidia Linux driver does not support this feature. As a result, HDMI audio will not work on Linux. A BIOS workaround is added with an OEM_OSI string "Linux-Lenovo-NV-HDMI-Audio" to power on NVidia HDMI audio when booting. The form of the OEM _OSI strings is defined by each OEMs and is discussed in Documentation/acpi/osi.txt. Signed-off-by: Alex Hung Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c index 8a8f43568510..b2a16ed7e81a 100644 --- a/drivers/acpi/osi.c +++ b/drivers/acpi/osi.c @@ -66,6 +66,14 @@ osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { * be removed if both new and old graphics cards are supported. */ {"Linux-Dell-Video", true}, + /* + * Linux-Lenovo-NV-HDMI-Audio is used by BIOS to power on NVidia's HDMI + * audio device which is turned off for power-saving in Windows OS. + * This power management feature observed on some Lenovo Thinkpad + * systems which will not be able to output audio via HDMI without + * a BIOS workaround. + */ + {"Linux-Lenovo-NV-HDMI-Audio", true}, }; static u32 acpi_osi_handler(acpi_string interface, u32 supported) -- cgit v1.2.3-59-g8ed1b From 82f2d30570b7ecdf1ce7e6376805f063ae86a7e5 Mon Sep 17 00:00:00 2001 From: Lucas Rangit Magasweran Date: Sat, 14 Jul 2018 15:40:18 -0700 Subject: ACPI: battery: remove redundant old_present check on insertion On removal battery_present changes from 1 to 0 after calling acpi_battery_get_status() and battery->update_time is set to 0 before returning. On insertion battery_present changes from 0 to 1 after calling acpi_battery_get_status() and acpi_battery_get_info() is called because battery->update_time is 0. The old_present condition is therefore redundant. This was added in the commit below when there was a path without sysfs that would skip getting the newly inserted battery info. commit 50b178512b7d ("Newly inserted battery might differ from one just removed, so update of battery info fields is required.") Signed-off-by: Lucas Rangit Magasweran Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index d79ad844c78f..78e40a9f5e18 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -918,10 +918,11 @@ static void acpi_battery_quirks(struct acpi_battery *battery) static int acpi_battery_update(struct acpi_battery *battery, bool resume) { - int result, old_present = acpi_battery_present(battery); - result = acpi_battery_get_status(battery); + int result = acpi_battery_get_status(battery); + if (result) return result; + if (!acpi_battery_present(battery)) { sysfs_remove_battery(battery); battery->update_time = 0; @@ -931,8 +932,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume) if (resume) return 0; - if (!battery->update_time || - old_present != acpi_battery_present(battery)) { + if (!battery->update_time) { result = acpi_battery_get_info(battery); if (result) return result; -- cgit v1.2.3-59-g8ed1b From 3461dfbabcc40d48c7b4b3ebb26a4ec927303e16 Mon Sep 17 00:00:00 2001 From: Dmitry Rozhkov Date: Tue, 24 Jul 2018 14:27:31 +0300 Subject: ACPI / battery: drop inclusion of init.h The driver can be built as a module thus inclusion of init.h is redundant in battery.c since it's always included by module.h. Suggested-by: Andy Shevchenko Signed-off-by: Dmitry Rozhkov Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 78e40a9f5e18..642e51f8f412 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 53dd200a2eed1413f2ef980dd5a193a3d45cc9a9 Mon Sep 17 00:00:00 2001 From: Dmitry Rozhkov Date: Tue, 24 Jul 2018 14:27:32 +0300 Subject: ACPI / battery: reorder headers alphabetically Headers ordered alphabetically as easier to maintain. Suggested-by: Andy Shevchenko Signed-off-by: Dmitry Rozhkov Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 642e51f8f412..321b5f98b63c 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -23,17 +23,18 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include #include #include +#include + #include #ifdef CONFIG_ACPI_PROCFS_POWER -- cgit v1.2.3-59-g8ed1b From dd1fca9e6cd4c5c179f4e854ceddbc22890109ce Mon Sep 17 00:00:00 2001 From: Dmitry Rozhkov Date: Tue, 24 Jul 2018 14:27:33 +0300 Subject: ACPI / battery: use specialized print macros The kernel provides specialized macros for printing info and warning messages which make the code shorter. Use the specialized macros instead of bare printk()'s. Also format one user visible string literal into a searchable one line string. Suggested-by: Andy Shevchenko Signed-off-by: Dmitry Rozhkov Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 321b5f98b63c..6d302bb2f51b 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -577,8 +577,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN && (s16)(battery->rate_now) < 0) { battery->rate_now = abs((s16)battery->rate_now); - printk_once(KERN_WARNING FW_BUG - "battery: (dis)charge rate invalid.\n"); + pr_warn_once(FW_BUG "battery: (dis)charge rate invalid.\n"); } if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) @@ -1170,8 +1169,7 @@ static const struct file_operations acpi_battery_alarm_fops = { static int acpi_battery_add_fs(struct acpi_device *device) { - printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded," - " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); + pr_warning(PREFIX "Deprecated procfs I/F for battery is loaded, please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_battery_dir); @@ -1398,7 +1396,7 @@ static int acpi_battery_add(struct acpi_device *device) } #endif - printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", + pr_info(PREFIX "%s Slot [%s] (battery %s)\n", ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), device->status.battery_present ? "present" : "absent"); -- cgit v1.2.3-59-g8ed1b From 2754435d4c820875412785da9bfa017a74fe51a7 Mon Sep 17 00:00:00 2001 From: Dmitry Rozhkov Date: Tue, 24 Jul 2018 14:27:34 +0300 Subject: ACPI / battery: get rid of negations in conditions Simple conditions without negations inflict less cognitive load on readers. Rework conditional branches not to use negations. Also add braces around single statement branches where their counterpart else-branches consist of more than one statement as suggested in the paragraph 3 of the coding style. Suggested-by: Andy Shevchenko Signed-off-by: Dmitry Rozhkov Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 6d302bb2f51b..cb664e87cde8 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1020,7 +1020,7 @@ static int acpi_battery_info_proc_show(struct seq_file *seq, void *offset) acpi_battery_units(battery)); seq_printf(seq, "battery technology: %srechargeable\n", - (!battery->technology)?"non-":""); + battery->technology ? "" : "non-"); if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "design voltage: unknown\n"); @@ -1111,11 +1111,12 @@ static int acpi_battery_alarm_proc_show(struct seq_file *seq, void *offset) goto end; } seq_printf(seq, "alarm: "); - if (!battery->alarm) - seq_printf(seq, "unsupported\n"); - else + if (battery->alarm) { seq_printf(seq, "%u %sh\n", battery->alarm, acpi_battery_units(battery)); + } else { + seq_printf(seq, "unsupported\n"); + } end: if (result) seq_printf(seq, "ERROR: Unable to read battery alarm\n"); @@ -1148,9 +1149,9 @@ static ssize_t acpi_battery_write_alarm(struct file *file, } result = acpi_battery_set_alarm(battery); end: - if (!result) - return count; - return result; + if (result) + return result; + return count; } static int acpi_battery_alarm_proc_open(struct inode *inode, struct file *file) @@ -1245,7 +1246,9 @@ static int battery_notify(struct notifier_block *nb, if (!acpi_battery_present(battery)) return 0; - if (!battery->bat) { + if (battery->bat) { + acpi_battery_refresh(battery); + } else { result = acpi_battery_get_info(battery); if (result) return result; @@ -1253,8 +1256,7 @@ static int battery_notify(struct notifier_block *nb, result = sysfs_add_battery(battery); if (result) return result; - } else - acpi_battery_refresh(battery); + } acpi_battery_init_alarm(battery); acpi_battery_get_state(battery); -- cgit v1.2.3-59-g8ed1b From b41901a2cf06f33c030be96c075872201089d47a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 7 Aug 2018 09:36:30 +0200 Subject: ACPI / battery: Do not export energy_full[_design] on devices without full_charge_capacity On some devices (with a buggy _BIX implementation) full_charge_capacity always reports as 0. This means that our energy_full sysfs attribute will also always be 0, which is not useful to export. Worse we calculate our reported capacity on full_charge_capacity and if it is 0 we always report 0. This causes userspace to immediately shutdown or hibernate the laptop since it assumes that the battery is critically low. This commit makes us not report energy_full[_design] or capacity on such broken devices, avoiding the immediate shutdown / hibernate from userspace. Link: https://bugzilla.kernel.org/show_bug.cgi?id=83941 Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index cb664e87cde8..cb97b6105f52 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -364,6 +364,20 @@ static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_SERIAL_NUMBER, }; +static enum power_supply_property energy_battery_full_cap_broken_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CYCLE_COUNT, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_POWER_NOW, + POWER_SUPPLY_PROP_ENERGY_NOW, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, +}; + /* -------------------------------------------------------------------------- Battery Management -------------------------------------------------------------------------- */ @@ -798,6 +812,11 @@ static int sysfs_add_battery(struct acpi_battery *battery) battery->bat_desc.properties = charge_battery_props; battery->bat_desc.num_properties = ARRAY_SIZE(charge_battery_props); + } else if (battery->full_charge_capacity == 0) { + battery->bat_desc.properties = + energy_battery_full_cap_broken_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(energy_battery_full_cap_broken_props); } else { battery->bat_desc.properties = energy_battery_props; battery->bat_desc.num_properties = -- cgit v1.2.3-59-g8ed1b