diff options
author | Alexander Mezin <mezin.alexander@gmail.com> | 2014-03-11 13:58:48 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-03-18 20:57:47 -0400 |
commit | 4eee4f03ce7aea1ef212bb5c27a8b54d73315996 (patch) | |
tree | 5a62923fa3d55cf0a91dd5d797cb957678d7f47b /drivers/acpi | |
parent | 411e0f77bdf79cdb80b61ab78acc6513c9ff8f97 (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.c | 25 |
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 | ||
157 | static 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 | |||
155 | static int thinkpad_e530_quirk(const struct dmi_system_id *d) | 177 | static 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); | ||
218 | end: | 242 | end: |
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 | ||