Backported fixes for non-updating battery when CONFIG_SYSFS_POWER is enabled. Changesets backported from HAL's git master to fix several bugs in HAL's battery handling when CONFIG_SYSFS_POWER is enabled in the 2.6.24 kernels. - Fixes the duplicated battery issue when both CONFIG_SYSFS_POWER and CONFIG_PROCFS_POWER are enabled. - Fixes non-updating battery charge level in HAL's battery device when it is reading it from sysfs. This is a flattened patch, log entries for included changesets from git follow. -------------- changeset: 1:288af73bdd5e tag: qbase tag: 000-fix-duplicate-battery-when-in-both-sysfs-and-procfs.patch user: Kyle McMartin files: hald/linux/acpi.c hald/linux/device.c hald/linux/device.h description: fix hal see same battery twice from sysfs and proc Date: Mon, 28 Jan 2008 14:19:39 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=4541abd23fd02118a1a7f8b825aed338d2a5d638 fix hal see same battery twice from sysfs and proc I've turned on both ACPI_PROCFS_POWER and ACPI_SYSFS_POWER in Fedora rawhide. With both options set, hal sees two battery devices, when it should really only check the second if the first doesn't exist. Fix this up by only checking procfs if we don't find anything in sysfs. --- changeset: 2:657b78f2d793 tag: 010-fix-config_power_supply-battery-reporting.patch user: Richard Hughes files: hald/linux/device.c description: fix the battery reporting when using CONFIG_POWER_SUPPLY Date: Wed, 2 Jan 2008 20:03:58 +0000 (+0000) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=f018f6480384e2607aa3cac6aad5f114b832ebc0 fix the battery reporting when using CONFIG_POWER_SUPPLY When using CONFIG_ACPI_BATTERY we set battery.is_rechargeable but do not set it when using CONFIG_POWER_SUPPLY. This causes gnome-power-manager to not report battery status correctly on fedora rawhide. Add this key if we are setting battery.rechargeable.* --- changeset: 3:8d5ae053114a tag: 015-call-refresh_battery_fast-instead-of-_slow.patch user: Danny Kukawka files: hald/linux/device.c description: fixed power_supply_refresh() for batteries Date: Tue, 29 Jan 2008 15:44:27 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=f1d2c7c0fb89f84db2649eca7dc554c7b6f80cdc fixed power_supply_refresh() for batteries Fixed power_supply_refresh() for the battery case. No need to call refresh_battery_slow() on refresh, refresh_battery_fast() should be enough since the info updated by refresh_battery_slow() never change if the device is present. --- changeset: 4:5e999bc0e603 tag: 020-fix-refresh_battery_slow-for-power_supply-batteries.patch user: Danny Kukawka files: hald/linux/device.c description: fixed refresh_battery_slow() for power_supply batteries Date: Tue, 29 Jan 2008 16:36:53 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=228d76b1d2f01d4801087e060697c25ab11ead79 fixed refresh_battery_slow() for power_supply batteries Fixed refresh_battery_slow() for power_supply batteries: removed not needed variable 'technology', set the model_name correctly to info.product and set also battery.model property. --- changeset: 5:ebfa623af971 tag: 030-fix-refresh_battery_fast-for-power_supply-batteries.patch user: Danny Kukawka files: hald/linux/device.c description: fixed refresh_battery_fast() for power_supply: battery.*.rate Date: Tue, 29 Jan 2008 17:18:41 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=950a003afe5f3072db8e9b26a05b8d3b24fbd09e fixed refresh_battery_fast() for power_supply: battery.*.rate Fixed refresh_battery_fast() for power_supply. Added missing key battery.voltage.unit and replace not existing key battery.current (this key was introduced with 356ccdfa3bbf64648c48da8b756eaccef13d0dd9, but the key was never part of the spec!) with battery.charge_level.rate. Added also battery.reporting.rate property. --- changeset: 6:fe1c570e6793 tag: 040-fix-compute-udi-for-power_supply.patch user: Danny Kukawka files: hald/linux/device.c description: fixed power_supply_compute_udi() to generate useful UDIs Date: Tue, 29 Jan 2008 17:00:01 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=3543df3ea534f9e197cc766ac106561f59f821d3 fixed power_supply_compute_udi() to generate useful UDIs Fixed power_supply_compute_udi() to generate useful UDIs, including (if available) power_supply-type and ID of the device. --- changeset: 7:e8f6fb0e2793 tag: 050-fix-refresh_battery_fast-for-power_supply.patch user: Danny Kukawka files: hald/linux/device.c description: fixed refresh_battery_fast() for power_supply devices Date: Tue, 29 Jan 2008 18:11:02 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=0de960db93ab36c862182bf6ed2536b9fe5afa41 fixed refresh_battery_fast() for power_supply devices Fixed refresh_battery_fast() for power_supply devices: - reworked logic to get the reporting unit for the device and prevent set battery.reporting.unit again, if not needed because it is already set - removed battery.charge_level.rate again, they get set somewhere else. --- changeset: 8:a149881b79ec tag: 060-get-static-info-only-in-refresh_battery_slow.patch user: Danny Kukawka files: hald/linux/device.c description: power_supply battery: moved static stuff to refresh_battery_slow() Date: Tue, 29 Jan 2008 19:38:42 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=7e221dfb85e7be5ed3eb447c5051823f0d5519a3 power_supply battery: moved static stuff to refresh_battery_slow() Moved static info (*_design) from refresh_battery_fast() to refresh_battery_slow() since they should never change after the first read of them. Try to set also battery.reporting.unit directly to prevent reread in refresh_battery_fast(). --- changeset: 9:708c56a2d2dc tag: 070-fix-power_supply-primary-batteries-to-update-correctly.patch user: Danny Kukawka files: hald/linux/device.c description: fixed power_supply primary batteries to update values Date: Tue, 29 Jan 2008 22:21:04 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=7430beeb6c6fd6c8e51c24df20fd53c526aed6e8 fixed power_supply primary batteries to update values Fixed power_supply primary batteries to update values, since there are no events about changes via ACPI or from udev/kernel. Added function to poll for changes similar to the ACPI battery poll. Limited the poll to power_supply primary batteries for now. If this is also needed for ups/ubs/mains batteries, we can add them later. The poll interval is 30 seconds. TODO: differ in refresh_battery_fast between ACPI and other batteries since there are several files which are currently not provided by the sysfs interface for ACPI batteries in the power_supply subsystem. --- changeset: 10:9b3571120aac tag: 080-get-battery-voltage-design-on-power_supply-batteries.patch user: Danny Kukawka files: hald/linux/device.c description: get battery.voltage.design on ACPI power_supply batteries Date: Tue, 29 Jan 2008 22:38:16 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=0c4ecf172cc80cc036b14873cdd94c9d9bce3c09 get battery.voltage.design on ACPI power_supply batteries Applied adopted version of a patch from Sjoerd Simons git repo. Get battery.voltage.design for ACPI power_supply batteries from voltage_min_design. > According to Alexey Starikovskiy: > On most new batteries design voltage is less than current voltage, > thus I've chosen VOLTAGE_MIN_DESIGN. On older batteries, current > voltage may become lower than design, so I think hal should not be > very strict about how they relate to each other. --- changeset: 11:3b19d14dc821 tag: 090-fix-typos-in-power_supply-code.patch user: Thadeu Lima de Souza Cascardo files: hald/linux/device.c description: fixed typo in power_supply code Date: Tue, 5 Feb 2008 21:37:18 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=e60d7a01d54b91764f5fe78a6e628593391a6a44 fixed typo in power_supply code Test for success in reading file, not failure. --- changeset: 12:51bc6d76760c tag: 091-fix-typo-in-reporting_unit.patch user: Thadeu Lima de Souza Cascardo files: hald/linux/device.c description: fixed a typo in variable name: is_mah -> is_mWh Date: Tue, 5 Feb 2008 21:35:29 +0000 (+0100) X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=f53fa72e79e31ce78c3aa6b64e3f56faafbf4b16 fixed a typo in variable name: is_mah -> is_mWh Fixed a typo in variable name: is_mah -> is_mWh. --- changeset: 13:72c11ed02474 tag: qtip tag: 100-get-battery-serial-number-from-sysfs.patch tag: tip user: Sjoerd Simons files: hald/linux/device.c description: get battery serial number from sysfs Date: Sat, 1 Mar 2008 12:42:23 +0100 X-Git-Url: http://gitweb.freedesktop.org/?p=hal.git;a=commitdiff;h=85390b2b5b45253f64867895204d95bf2e1dc357 Get the battery serial number from sysfs diff --git a/hald/linux/acpi.c b/hald/linux/acpi.c --- a/hald/linux/acpi.c +++ b/hald/linux/acpi.c @@ -944,10 +944,23 @@ acpi_synthesize_hotplug_events (void) return TRUE; } +static gboolean +is_power_supply(ACPIDevHandler *h) +{ + if (h && (h->acpi_type == ACPI_TYPE_BATTERY) || + (h->acpi_type == ACPI_TYPE_AC_ADAPTER)) + return TRUE; + return FALSE; +} + static HalDevice * acpi_generic_add (const gchar *acpi_path, HalDevice *parent, ACPIDevHandler *handler) { HalDevice *d; + + if (is_power_supply(handler) && _have_sysfs_power_supply) + return NULL; + d = hal_device_new (); hal_device_property_set_string (d, "linux.acpi_path", acpi_path); hal_device_property_set_int (d, "linux.acpi_type", handler->acpi_type); diff --git a/hald/linux/device.c b/hald/linux/device.c --- a/hald/linux/device.c +++ b/hald/linux/device.c @@ -67,6 +67,9 @@ gboolean _have_sysfs_lid_button = FALSE; gboolean _have_sysfs_lid_button = FALSE; gboolean _have_sysfs_power_button = FALSE; gboolean _have_sysfs_sleep_button = FALSE; +gboolean _have_sysfs_power_supply = FALSE; + +#define POWER_SUPPLY_BATTERY_POLL_INTERVAL 30000 /* we must use this kernel-compatible implementation */ #define BITS_PER_LONG (sizeof(long) * 8) @@ -3001,15 +3004,12 @@ refresh_battery_fast (HalDevice *d) { gint percentage = 0; gint voltage_now = 0; - gint voltage_design = 0; gint current = 0; gint time = 0; gint value_now = 0; gint value_last_full = 0; - gint value_full_design = 0; gboolean present = FALSE; - gboolean could_be_mah = TRUE; - gboolean could_be_mwh = TRUE; + gboolean unknown_unit = TRUE; gboolean is_mah = FALSE; gboolean is_mwh = FALSE; gboolean is_charging = FALSE; @@ -3047,15 +3047,12 @@ refresh_battery_fast (HalDevice *d) } else if (hal_util_get_int_from_file (path, "voltage_now", &voltage_now, 10)) { hal_device_property_set_int (d, "battery.voltage.current", voltage_now / 1000); } - if (hal_util_get_int_from_file (path, "voltage_max_design", &voltage_design, 10)) { - hal_device_property_set_int (d, "battery.voltage.design", voltage_design / 1000); - } /* CURRENT: we prefer the average if it exists, although present is still pretty good */ if (hal_util_get_int_from_file (path, "current_avg", ¤t, 10)) { - hal_device_property_set_int (d, "battery.current", current / 1000); + hal_device_property_set_int (d, "battery.reporting.rate", current / 1000); } else if (hal_util_get_int_from_file (path, "current_now", ¤t, 10)) { - hal_device_property_set_int (d, "battery.current", current / 1000); + hal_device_property_set_int (d, "battery.reporting.rate", current / 1000); } /* STATUS: Convert to charging/discharging state */ @@ -3066,6 +3063,7 @@ refresh_battery_fast (HalDevice *d) } else if (strcasecmp (status, "discharging") == 0) { is_discharging = TRUE; } + hal_device_property_set_bool (d, "battery.is_rechargeable", TRUE); hal_device_property_set_bool (d, "battery.rechargeable.is_charging", is_charging); hal_device_property_set_bool (d, "battery.rechargeable.is_discharging", is_discharging); } @@ -3088,14 +3086,16 @@ refresh_battery_fast (HalDevice *d) reporting_unit = hal_device_property_get_string (d, "battery.reporting.unit"); if (reporting_unit != NULL) { if (strcasecmp (reporting_unit, "mah") == 0) { - could_be_mwh = FALSE; + is_mah = TRUE; + unknown_unit = FALSE; } else if (strcasecmp (reporting_unit, "mwh") == 0) { - could_be_mah = FALSE; + is_mwh = TRUE; + unknown_unit = FALSE; } } /* ENERGY (reported in uWh, so need to convert to mWh) */ - if (could_be_mwh) { + if (unknown_unit || is_mwh) { if (hal_util_get_int_from_file (path, "energy_avg", &value_now, 10)) { hal_device_property_set_int (d, "battery.reporting.current", value_now / 1000); is_mwh = TRUE; @@ -3107,14 +3107,10 @@ refresh_battery_fast (HalDevice *d) hal_device_property_set_int (d, "battery.reporting.last_full", value_last_full / 1000); is_mwh = TRUE; } - if (hal_util_get_int_from_file (path, "energy_full_design", &value_full_design, 10)) { - hal_device_property_set_int (d, "battery.reporting.design", value_full_design / 1000); - is_mwh = TRUE; - } } /* CHARGE (reported in uAh, so need to convert to mAh) */ - if (could_be_mah) { + if ((unknown_unit && !is_mwh) || is_mah) { if (hal_util_get_int_from_file (path, "charge_avg", &value_now, 10)) { hal_device_property_set_int (d, "battery.reporting.current", value_now / 1000); is_mah = TRUE; @@ -3126,17 +3122,15 @@ refresh_battery_fast (HalDevice *d) hal_device_property_set_int (d, "battery.reporting.last_full", value_last_full / 1000); is_mah = TRUE; } - if (hal_util_get_int_from_file (path, "charge_full_design", &value_full_design, 10)) { - hal_device_property_set_int (d, "battery.reporting.design", value_full_design / 1000); - is_mah = TRUE; - } } /* record these for future savings */ - if (is_mwh == TRUE) { - hal_device_property_set_string (d, "battery.reporting.unit", "mWh"); - } else if (is_mah == TRUE) { - hal_device_property_set_string (d, "battery.reporting.unit", "mAh"); + if (unknown_unit) { + if (is_mwh == TRUE) { + hal_device_property_set_string (d, "battery.reporting.unit", "mWh"); + } else if (is_mah == TRUE) { + hal_device_property_set_string (d, "battery.reporting.unit", "mAh"); + } } /* we've now got the 'reporting' keys, now we need to populate the @@ -3166,10 +3160,12 @@ static void static void refresh_battery_slow (HalDevice *d) { - const char *technology; + gint voltage_design = 0; + gint value_full_design = 0; char *technology_raw; char *model_name; char *manufacturer; + char *serial; const gchar *path; path = hal_device_property_get_string (d, "linux.sysfs_path"); @@ -3181,13 +3177,12 @@ refresh_battery_slow (HalDevice *d) if (technology_raw != NULL) { hal_device_property_set_string (d, "battery.reporting.technology", technology_raw); } - /* we set this, even if it's unknown */ - technology = util_get_battery_technology (technology_raw); - hal_device_property_set_string (d, "battery.technology", technology); + hal_device_property_set_string (d, "battery.technology", util_get_battery_technology (technology_raw)); /* get product name */ - model_name = hal_util_get_string_from_file (path, "technology"); + model_name = hal_util_get_string_from_file (path, "model_name"); if (model_name != NULL) { + hal_device_property_set_string (d, "battery.model", model_name); hal_device_property_set_string (d, "info.product", model_name); } else { hal_device_property_set_string (d, "info.product", "Generic Battery Device"); @@ -3197,6 +3192,30 @@ refresh_battery_slow (HalDevice *d) manufacturer = hal_util_get_string_from_file (path, "manufacturer"); if (manufacturer != NULL) { hal_device_property_set_string (d, "battery.vendor", manufacturer); + } + + /* get stuff that never changes */ + if (hal_util_get_int_from_file (path, "voltage_max_design", &voltage_design, 10)) { + hal_device_property_set_int (d, "battery.voltage.design", voltage_design / 1000); + hal_device_property_set_string (d, "battery.voltage.unit", "mV"); + } else if (hal_util_get_int_from_file (path, "voltage_min_design", &voltage_design, 10)) { + hal_device_property_set_int (d, "battery.voltage.design", voltage_design / 1000); + hal_device_property_set_string (d, "battery.voltage.unit", "mV"); + } + + /* try to get the design info and set the units */ + if (hal_util_get_int_from_file (path, "energy_full_design", &value_full_design, 10)) { + hal_device_property_set_int (d, "battery.reporting.design", value_full_design / 1000); + hal_device_property_set_string (d, "battery.reporting.unit", "mWh"); + } else if (hal_util_get_int_from_file (path, "charge_full_design", &value_full_design, 10)) { + hal_device_property_set_int (d, "battery.reporting.design", value_full_design / 1000); + hal_device_property_set_string (d, "battery.reporting.unit", "mAh"); + } + + /* get serial */ + serial = hal_util_get_string_from_file (path, "serial_number"); + if (serial != NULL) { + hal_device_property_set_string (d, "battery.serial", serial); } /* now do stuff that happens quickly */ @@ -3217,12 +3236,43 @@ power_supply_refresh (HalDevice *d) device_property_atomic_update_end (); } else if (strcmp (type, "battery") == 0) { device_property_atomic_update_begin (); - refresh_battery_slow (d); + refresh_battery_fast (d); device_property_atomic_update_end (); } else { HAL_WARNING (("Could not recognise power_supply type!")); return FALSE; } + return TRUE; +} + + +static gboolean +power_supply_battery_poll (gpointer data) { + + GSList *i; + GSList *battery_devices; + HalDevice *d; + + /* for now do it only for primary batteries and extend if neede for the other types */ + battery_devices = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), + "battery.type", + "primary"); + + if (battery_devices) { + for (i = battery_devices; i != NULL; i = g_slist_next (i)) { + const char *subsys; + + d = HAL_DEVICE (i->data); + subsys = hal_device_property_get_string (d, "linux.subsystem"); + if (subsys && (strcmp(subsys, "power_supply") == 0)) { + hal_util_grep_discard_existing_data(); + device_property_atomic_update_begin (); + refresh_battery_fast(d); + device_property_atomic_update_end (); + } + } + } + g_slist_free (battery_devices); return TRUE; } @@ -3268,6 +3318,11 @@ power_supply_add (const gchar *sysfs_pat hal_device_property_set_string (d, "battery.type", battery_type); refresh_battery_slow (d); hal_device_add_capability (d, "battery"); + + /* setup timer for things that we need to poll */ + g_timeout_add ( POWER_SUPPLY_BATTERY_POLL_INTERVAL, + power_supply_battery_poll, + NULL); } if (is_ac_adapter == TRUE) { @@ -3276,6 +3331,8 @@ power_supply_add (const gchar *sysfs_pat refresh_ac_adapter (d); hal_device_add_capability (d, "ac_adapter"); } + + _have_sysfs_power_supply = TRUE; finish: return d; } @@ -3290,9 +3347,18 @@ power_supply_compute_udi (HalDevice *d) dir = hal_device_property_get_string (d, "linux.sysfs_path"); name = hal_util_get_last_element(dir); - hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi), - "%s_power_supply", - hal_device_property_get_string (d, "info.parent")); + if (name) + hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi), + "%s_power_supply_%s_%s", + hal_device_property_get_string (d, "info.parent"), + hal_device_property_get_string (d, "info.category"), + name); + else + hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi), + "%s_power_supply_%s", + hal_device_property_get_string (d, "info.parent"), + hal_device_property_get_string (d, "info.category")); + hal_device_set_udi (d, udi); hal_device_property_set_string (d, "info.udi", udi); return TRUE; diff --git a/hald/linux/device.h b/hald/linux/device.h --- a/hald/linux/device.h +++ b/hald/linux/device.h @@ -52,5 +52,6 @@ extern gboolean _have_sysfs_lid_button; extern gboolean _have_sysfs_lid_button; extern gboolean _have_sysfs_power_button; extern gboolean _have_sysfs_sleep_button; +extern gboolean _have_sysfs_power_supply; #endif