Skip to content

Commit 3031cdd

Browse files
Matthew Garrettrafaeljw
authored andcommitted
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 <[email protected]> Signed-off-by: Andreas Noever <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 0f33be0 commit 3031cdd

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

drivers/acpi/sbs.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct acpi_sbs {
109109
u8 batteries_supported:4;
110110
u8 manager_present:1;
111111
u8 charger_present:1;
112+
u8 charger_exists:1;
112113
};
113114

114115
#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)
429430

430431
result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER,
431432
0x13, (u8 *) & status);
432-
if (!result)
433-
sbs->charger_present = (status >> 15) & 0x1;
434-
return result;
433+
434+
if (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;
435446
}
436447

437448
static ssize_t acpi_battery_alarm_show(struct device *dev,
@@ -554,6 +565,7 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
554565
if (result)
555566
goto end;
556567

568+
sbs->charger_exists = 1;
557569
sbs->charger.name = "sbs-charger";
558570
sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
559571
sbs->charger.properties = sbs_ac_props;
@@ -580,9 +592,12 @@ static void acpi_sbs_callback(void *context)
580592
struct acpi_battery *bat;
581593
u8 saved_charger_state = sbs->charger_present;
582594
u8 saved_battery_state;
583-
acpi_ac_get_present(sbs);
584-
if (sbs->charger_present != saved_charger_state)
585-
kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
595+
596+
if (sbs->charger_exists) {
597+
acpi_ac_get_present(sbs);
598+
if (sbs->charger_present != saved_charger_state)
599+
kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
600+
}
586601

587602
if (sbs->manager_present) {
588603
for (id = 0; id < MAX_SBS_BAT; ++id) {
@@ -619,7 +634,7 @@ static int acpi_sbs_add(struct acpi_device *device)
619634
device->driver_data = sbs;
620635

621636
result = acpi_charger_add(sbs);
622-
if (result)
637+
if (result && result != -ENODEV)
623638
goto end;
624639

625640
result = acpi_manager_get_info(sbs);

0 commit comments

Comments
 (0)