mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									0f33be009b
								
							
						
					
					
						commit
						3031cddea6
					
				
					 1 changed files with 22 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -109,6 +109,7 @@ struct acpi_sbs {
 | 
			
		|||
	u8 batteries_supported:4;
 | 
			
		||||
	u8 manager_present:1;
 | 
			
		||||
	u8 charger_present:1;
 | 
			
		||||
	u8 charger_exists:1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		|||
 | 
			
		||||
	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER,
 | 
			
		||||
				 0x13, (u8 *) & status);
 | 
			
		||||
	if (!result)
 | 
			
		||||
		sbs->charger_present = (status >> 15) & 0x1;
 | 
			
		||||
	return result;
 | 
			
		||||
 | 
			
		||||
	if (result)
 | 
			
		||||
		return result;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The spec requires that bit 4 always be 1. If it's not set, assume
 | 
			
		||||
	 * that the implementation doesn't support an SBS charger
 | 
			
		||||
	 */
 | 
			
		||||
	if (!(status >> 4) & 0x1)
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
 | 
			
		||||
	sbs->charger_present = (status >> 15) & 0x1;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t acpi_battery_alarm_show(struct device *dev,
 | 
			
		||||
| 
						 | 
				
			
			@ -554,6 +565,7 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
 | 
			
		|||
	if (result)
 | 
			
		||||
		goto end;
 | 
			
		||||
 | 
			
		||||
	sbs->charger_exists = 1;
 | 
			
		||||
	sbs->charger.name = "sbs-charger";
 | 
			
		||||
	sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
 | 
			
		||||
	sbs->charger.properties = sbs_ac_props;
 | 
			
		||||
| 
						 | 
				
			
			@ -580,9 +592,12 @@ static void acpi_sbs_callback(void *context)
 | 
			
		|||
	struct acpi_battery *bat;
 | 
			
		||||
	u8 saved_charger_state = sbs->charger_present;
 | 
			
		||||
	u8 saved_battery_state;
 | 
			
		||||
	acpi_ac_get_present(sbs);
 | 
			
		||||
	if (sbs->charger_present != saved_charger_state)
 | 
			
		||||
		kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
 | 
			
		||||
 | 
			
		||||
	if (sbs->charger_exists) {
 | 
			
		||||
		acpi_ac_get_present(sbs);
 | 
			
		||||
		if (sbs->charger_present != saved_charger_state)
 | 
			
		||||
			kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (sbs->manager_present) {
 | 
			
		||||
		for (id = 0; id < MAX_SBS_BAT; ++id) {
 | 
			
		||||
| 
						 | 
				
			
			@ -619,7 +634,7 @@ static int acpi_sbs_add(struct acpi_device *device)
 | 
			
		|||
	device->driver_data = sbs;
 | 
			
		||||
 | 
			
		||||
	result = acpi_charger_add(sbs);
 | 
			
		||||
	if (result)
 | 
			
		||||
	if (result && result != -ENODEV)
 | 
			
		||||
		goto end;
 | 
			
		||||
 | 
			
		||||
	result = acpi_manager_get_info(sbs);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue