aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorAlexander Mezin <mezin.alexander@gmail.com>2014-03-11 13:58:48 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-18 20:57:47 -0400
commit4eee4f03ce7aea1ef212bb5c27a8b54d73315996 (patch)
tree5a62923fa3d55cf0a91dd5d797cb957678d7f47b /drivers/acpi
parent411e0f77bdf79cdb80b61ab78acc6513c9ff8f97 (diff)
ACPI / AC: recheck adapter status upon battery status changes
On HP Pavilion dv6-6179er there are no notifications when AC adapter is plugged/unplugged. However, when AC status is read (acpi_ac_get_state), and if AC status has changed, AML code triggers the notification. This patch solves the problem by re-reading AC adapter status upon ACPI_BATTERY_NOTIFY_STATUS notification. Signed-off-by: Alexander Mezin <mezin.alexander@gmail.com> Acked-by: Lan Tianyu <tianyu.lan@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/ac.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 6f190bc2b8b7..2c01c1da29ce 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -33,6 +33,7 @@
33#include <linux/platform_device.h> 33#include <linux/platform_device.h>
34#include <linux/power_supply.h> 34#include <linux/power_supply.h>
35#include <linux/acpi.h> 35#include <linux/acpi.h>
36#include "battery.h"
36 37
37#define PREFIX "ACPI: " 38#define PREFIX "ACPI: "
38 39
@@ -57,6 +58,7 @@ struct acpi_ac {
57 struct power_supply charger; 58 struct power_supply charger;
58 struct platform_device *pdev; 59 struct platform_device *pdev;
59 unsigned long long state; 60 unsigned long long state;
61 struct notifier_block battery_nb;
60}; 62};
61 63
62#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger) 64#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger)
@@ -152,6 +154,26 @@ static void acpi_ac_notify_handler(acpi_handle handle, u32 event, void *data)
152 return; 154 return;
153} 155}
154 156
157static int acpi_ac_battery_notify(struct notifier_block *nb,
158 unsigned long action, void *data)
159{
160 struct acpi_ac *ac = container_of(nb, struct acpi_ac, battery_nb);
161 struct acpi_bus_event *event = (struct acpi_bus_event *)data;
162
163 /*
164 * On HP Pavilion dv6-6179er AC status notifications aren't triggered
165 * when adapter is plugged/unplugged. However, battery status
166 * notifcations are triggered when battery starts charging or
167 * discharging. Re-reading AC status triggers lost AC notifications,
168 * if AC status has changed.
169 */
170 if (strcmp(event->device_class, ACPI_BATTERY_CLASS) == 0 &&
171 event->type == ACPI_BATTERY_NOTIFY_STATUS)
172 acpi_ac_get_state(ac);
173
174 return NOTIFY_OK;
175}
176
155static int thinkpad_e530_quirk(const struct dmi_system_id *d) 177static int thinkpad_e530_quirk(const struct dmi_system_id *d)
156{ 178{
157 ac_sleep_before_get_state_ms = 1000; 179 ac_sleep_before_get_state_ms = 1000;
@@ -215,6 +237,8 @@ static int acpi_ac_probe(struct platform_device *pdev)
215 acpi_device_name(adev), acpi_device_bid(adev), 237 acpi_device_name(adev), acpi_device_bid(adev),
216 ac->state ? "on-line" : "off-line"); 238 ac->state ? "on-line" : "off-line");
217 239
240 ac->battery_nb.notifier_call = acpi_ac_battery_notify;
241 register_acpi_notifier(&ac->battery_nb);
218end: 242end:
219 if (result) 243 if (result)
220 kfree(ac); 244 kfree(ac);
@@ -261,6 +285,7 @@ static int acpi_ac_remove(struct platform_device *pdev)
261 ac = platform_get_drvdata(pdev); 285 ac = platform_get_drvdata(pdev);
262 if (ac->charger.dev) 286 if (ac->charger.dev)
263 power_supply_unregister(&ac->charger); 287 power_supply_unregister(&ac->charger);
288 unregister_acpi_notifier(&ac->battery_nb);
264 289
265 kfree(ac); 290 kfree(ac);
266 291