aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatthew Garrett <matthew.garrett@nebula.com>2014-09-20 07:19:45 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-09-24 17:31:11 -0400
commit3031cddea633ea5328162d3d712a582e4205dbed (patch)
treefdd49651c754cd6fd2f2c7d9810720eb21a6c230 /drivers
parent0f33be009b89d2268e94194dc4fd01a7851b6d51 (diff)
ACPI / SBS: Don't assume the existence of an SBS charger
Apple hardware continues to expose an ACPI AC charger even when using SBS to report battery state. The charger status byte returns all 0s in this case. Since the spec requires that bit 4 be 1 at all times, assume that there's not really a charger if it's set to zero. Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> Signed-off-by: Andreas Noever <andreas.noever@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/sbs.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 366ca40a6f70..b1df4eee8657 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -109,6 +109,7 @@ struct acpi_sbs {
109 u8 batteries_supported:4; 109 u8 batteries_supported:4;
110 u8 manager_present:1; 110 u8 manager_present:1;
111 u8 charger_present:1; 111 u8 charger_present:1;
112 u8 charger_exists:1;
112}; 113};
113 114
114#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) 115#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
@@ -429,9 +430,19 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
429 430
430 result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER, 431 result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER,
431 0x13, (u8 *) & status); 432 0x13, (u8 *) & status);
432 if (!result) 433
433 sbs->charger_present = (status >> 15) & 0x1; 434 if (result)
434 return result; 435 return result;
436
437 /*
438 * The spec requires that bit 4 always be 1. If it's not set, assume
439 * that the implementation doesn't support an SBS charger
440 */
441 if (!(status >> 4) & 0x1)
442 return -ENODEV;
443
444 sbs->charger_present = (status >> 15) & 0x1;
445 return 0;
435} 446}
436 447
437static ssize_t acpi_battery_alarm_show(struct device *dev, 448static ssize_t acpi_battery_alarm_show(struct device *dev,
@@ -554,6 +565,7 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
554 if (result) 565 if (result)
555 goto end; 566 goto end;
556 567
568 sbs->charger_exists = 1;
557 sbs->charger.name = "sbs-charger"; 569 sbs->charger.name = "sbs-charger";
558 sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; 570 sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
559 sbs->charger.properties = sbs_ac_props; 571 sbs->charger.properties = sbs_ac_props;
@@ -580,9 +592,12 @@ static void acpi_sbs_callback(void *context)
580 struct acpi_battery *bat; 592 struct acpi_battery *bat;
581 u8 saved_charger_state = sbs->charger_present; 593 u8 saved_charger_state = sbs->charger_present;
582 u8 saved_battery_state; 594 u8 saved_battery_state;
583 acpi_ac_get_present(sbs); 595
584 if (sbs->charger_present != saved_charger_state) 596 if (sbs->charger_exists) {
585 kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); 597 acpi_ac_get_present(sbs);
598 if (sbs->charger_present != saved_charger_state)
599 kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
600 }
586 601
587 if (sbs->manager_present) { 602 if (sbs->manager_present) {
588 for (id = 0; id < MAX_SBS_BAT; ++id) { 603 for (id = 0; id < MAX_SBS_BAT; ++id) {
@@ -619,7 +634,7 @@ static int acpi_sbs_add(struct acpi_device *device)
619 device->driver_data = sbs; 634 device->driver_data = sbs;
620 635
621 result = acpi_charger_add(sbs); 636 result = acpi_charger_add(sbs);
622 if (result) 637 if (result && result != -ENODEV)
623 goto end; 638 goto end;
624 639
625 result = acpi_manager_get_info(sbs); 640 result = acpi_manager_get_info(sbs);