aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/battery.c
diff options
context:
space:
mode:
authorAndrey Borzenkov <arvidjaar@mail.ru>2007-10-28 05:50:09 -0400
committerLen Brown <len.brown@intel.com>2007-10-29 16:30:23 -0400
commit508df92d1f8d1921013cb4f45bb547d0eaff912a (patch)
tree5cd6bffd9a8888e085e3e90d378eeac11d98f0f4 /drivers/acpi/battery.c
parentb19073a0be5e317d626b3b404e0039b59383891c (diff)
ACPI: battery: register power_supply subdevice only when battery is present
Make sure no power_supply object is present unless we actualy detect presence of battery. This fixes ghost batteries detected by HAL Signed-off-by: Andrey Borzenkov <arvidjaar@mail.ru> Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r--drivers/acpi/battery.c130
1 files changed, 75 insertions, 55 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 9da8cec80fd1..489d3385efe4 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -388,29 +388,81 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
388 return acpi_battery_set_alarm(battery); 388 return acpi_battery_set_alarm(battery);
389} 389}
390 390
391static ssize_t acpi_battery_alarm_show(struct device *dev,
392 struct device_attribute *attr,
393 char *buf)
394{
395 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
396 return sprintf(buf, "%d\n", battery->alarm * 1000);
397}
398
399static ssize_t acpi_battery_alarm_store(struct device *dev,
400 struct device_attribute *attr,
401 const char *buf, size_t count)
402{
403 unsigned long x;
404 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
405 if (sscanf(buf, "%ld\n", &x) == 1)
406 battery->alarm = x/1000;
407 if (acpi_battery_present(battery))
408 acpi_battery_set_alarm(battery);
409 return count;
410}
411
412static struct device_attribute alarm_attr = {
413 .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
414 .show = acpi_battery_alarm_show,
415 .store = acpi_battery_alarm_store,
416};
417
418static int sysfs_add_battery(struct acpi_battery *battery)
419{
420 int result;
421
422 battery->update_time = 0;
423 result = acpi_battery_get_info(battery);
424 acpi_battery_init_alarm(battery);
425 if (result)
426 return result;
427 if (battery->power_unit) {
428 battery->bat.properties = charge_battery_props;
429 battery->bat.num_properties =
430 ARRAY_SIZE(charge_battery_props);
431 } else {
432 battery->bat.properties = energy_battery_props;
433 battery->bat.num_properties =
434 ARRAY_SIZE(energy_battery_props);
435 }
436
437 battery->bat.name = acpi_device_bid(battery->device);
438 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
439 battery->bat.get_property = acpi_battery_get_property;
440
441 result = power_supply_register(&battery->device->dev, &battery->bat);
442 if (result)
443 return result;
444 return device_create_file(battery->bat.dev, &alarm_attr);
445}
446
447static void sysfs_remove_battery(struct acpi_battery *battery)
448{
449 if (!battery->bat.dev)
450 return;
451 device_remove_file(battery->bat.dev, &alarm_attr);
452 power_supply_unregister(&battery->bat);
453}
454
391static int acpi_battery_update(struct acpi_battery *battery) 455static int acpi_battery_update(struct acpi_battery *battery)
392{ 456{
393 int saved_present = acpi_battery_present(battery);
394 int result = acpi_battery_get_status(battery); 457 int result = acpi_battery_get_status(battery);
395 if (result || !acpi_battery_present(battery)) 458 if (result)
396 return result; 459 return result;
397 if (saved_present != acpi_battery_present(battery) || 460 if (!acpi_battery_present(battery)) {
398 !battery->update_time) { 461 sysfs_remove_battery(battery);
399 battery->update_time = 0; 462 return 0;
400 result = acpi_battery_get_info(battery);
401 if (result)
402 return result;
403 if (battery->power_unit) {
404 battery->bat.properties = charge_battery_props;
405 battery->bat.num_properties =
406 ARRAY_SIZE(charge_battery_props);
407 } else {
408 battery->bat.properties = energy_battery_props;
409 battery->bat.num_properties =
410 ARRAY_SIZE(energy_battery_props);
411 }
412 acpi_battery_init_alarm(battery);
413 } 463 }
464 if (!battery->bat.dev)
465 sysfs_add_battery(battery);
414 return acpi_battery_get_state(battery); 466 return acpi_battery_get_state(battery);
415} 467}
416 468
@@ -687,33 +739,6 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
687 739
688#endif 740#endif
689 741
690static ssize_t acpi_battery_alarm_show(struct device *dev,
691 struct device_attribute *attr,
692 char *buf)
693{
694 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
695 return sprintf(buf, "%d\n", battery->alarm * 1000);
696}
697
698static ssize_t acpi_battery_alarm_store(struct device *dev,
699 struct device_attribute *attr,
700 const char *buf, size_t count)
701{
702 unsigned long x;
703 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
704 if (sscanf(buf, "%ld\n", &x) == 1)
705 battery->alarm = x/1000;
706 if (acpi_battery_present(battery))
707 acpi_battery_set_alarm(battery);
708 return count;
709}
710
711static struct device_attribute alarm_attr = {
712 .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
713 .show = acpi_battery_alarm_show,
714 .store = acpi_battery_alarm_store,
715};
716
717/* -------------------------------------------------------------------------- 742/* --------------------------------------------------------------------------
718 Driver Interface 743 Driver Interface
719 -------------------------------------------------------------------------- */ 744 -------------------------------------------------------------------------- */
@@ -731,7 +756,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
731 acpi_bus_generate_netlink_event(device->pnp.device_class, 756 acpi_bus_generate_netlink_event(device->pnp.device_class,
732 device->dev.bus_id, event, 757 device->dev.bus_id, event,
733 acpi_battery_present(battery)); 758 acpi_battery_present(battery));
734 kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE); 759 /* acpi_batter_update could remove power_supply object */
760 if (battery->bat.dev)
761 kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
735} 762}
736 763
737static int acpi_battery_add(struct acpi_device *device) 764static int acpi_battery_add(struct acpi_device *device)
@@ -755,11 +782,6 @@ static int acpi_battery_add(struct acpi_device *device)
755 if (result) 782 if (result)
756 goto end; 783 goto end;
757#endif 784#endif
758 battery->bat.name = acpi_device_bid(device);
759 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
760 battery->bat.get_property = acpi_battery_get_property;
761 result = power_supply_register(&battery->device->dev, &battery->bat);
762 result = device_create_file(battery->bat.dev, &alarm_attr);
763 status = acpi_install_notify_handler(device->handle, 785 status = acpi_install_notify_handler(device->handle,
764 ACPI_ALL_NOTIFY, 786 ACPI_ALL_NOTIFY,
765 acpi_battery_notify, battery); 787 acpi_battery_notify, battery);
@@ -795,10 +817,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
795#ifdef CONFIG_ACPI_PROCFS 817#ifdef CONFIG_ACPI_PROCFS
796 acpi_battery_remove_fs(device); 818 acpi_battery_remove_fs(device);
797#endif 819#endif
798 if (battery->bat.dev) { 820 sysfs_remove_battery(battery);
799 device_remove_file(battery->bat.dev, &alarm_attr);
800 power_supply_unregister(&battery->bat);
801 }
802 mutex_destroy(&battery->lock); 821 mutex_destroy(&battery->lock);
803 kfree(battery); 822 kfree(battery);
804 return 0; 823 return 0;
@@ -812,6 +831,7 @@ static int acpi_battery_resume(struct acpi_device *device)
812 return -EINVAL; 831 return -EINVAL;
813 battery = acpi_driver_data(device); 832 battery = acpi_driver_data(device);
814 battery->update_time = 0; 833 battery->update_time = 0;
834 acpi_battery_update(battery);
815 return 0; 835 return 0;
816} 836}
817 837