aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/apm_power.c
diff options
context:
space:
mode:
authorAnton Vorontsov <cbou@mail.ru>2007-10-04 17:05:00 -0400
committerAnton Vorontsov <cbou@mail.ru>2007-10-04 17:05:00 -0400
commitd385376f0d75fdbeed8041ed6baf5cb4a1578ffb (patch)
tree123182e8e7c8468565d3f1718c7ac1fe4dd65b80 /drivers/power/apm_power.c
parentcd1ebcc0ef620e8e7c5e399bf9e123135e4f24a4 (diff)
apm_power: improve battery finding algorithm
Prior to this patch, if use_for_apm unspecified, apm_power able to choice batteries according to their charge only. This patch adds ability to choice batteries according to their charge, energy, use_for_apm flag, and fallback to any battery if it failed to decide. Patch is mandatory to report Apple PMU batteries through legacy /proc/apm interface using power supply class. Signed-off-by: Anton Vorontsov <cbou@mail.ru>
Diffstat (limited to 'drivers/power/apm_power.c')
-rw-r--r--drivers/power/apm_power.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c
index 32ebfd76722a..3928e7cdddc1 100644
--- a/drivers/power/apm_power.c
+++ b/drivers/power/apm_power.c
@@ -26,28 +26,65 @@ static struct power_supply *main_battery;
26static void find_main_battery(void) 26static void find_main_battery(void)
27{ 27{
28 struct device *dev; 28 struct device *dev;
29 struct power_supply *bat, *batm; 29 struct power_supply *bat = NULL;
30 struct power_supply *max_charge_bat = NULL;
31 struct power_supply *max_energy_bat = NULL;
30 union power_supply_propval full; 32 union power_supply_propval full;
31 int max_charge = 0; 33 int max_charge = 0;
34 int max_energy = 0;
32 35
33 main_battery = NULL; 36 main_battery = NULL;
34 batm = NULL; 37
35 list_for_each_entry(dev, &power_supply_class->devices, node) { 38 list_for_each_entry(dev, &power_supply_class->devices, node) {
36 bat = dev_get_drvdata(dev); 39 bat = dev_get_drvdata(dev);
37 /* If none of battery devices cantains 'use_for_apm' flag, 40
38 choice one with maximum design charge */ 41 if (bat->use_for_apm) {
39 if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full)) { 42 /* nice, we explicitly asked to report this battery. */
43 main_battery = bat;
44 return;
45 }
46
47 if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full) ||
48 !PSY_PROP(bat, CHARGE_FULL, &full)) {
40 if (full.intval > max_charge) { 49 if (full.intval > max_charge) {
41 batm = bat; 50 max_charge_bat = bat;
42 max_charge = full.intval; 51 max_charge = full.intval;
43 } 52 }
53 } else if (!PSY_PROP(bat, ENERGY_FULL_DESIGN, &full) ||
54 !PSY_PROP(bat, ENERGY_FULL, &full)) {
55 if (full.intval > max_energy) {
56 max_energy_bat = bat;
57 max_energy = full.intval;
58 }
44 } 59 }
60 }
45 61
46 if (bat->use_for_apm) 62 if ((max_energy_bat && max_charge_bat) &&
47 main_battery = bat; 63 (max_energy_bat != max_charge_bat)) {
64 /* try guess battery with more capacity */
65 if (!PSY_PROP(max_charge_bat, VOLTAGE_MAX_DESIGN, &full)) {
66 if (max_energy > max_charge * full.intval)
67 main_battery = max_energy_bat;
68 else
69 main_battery = max_charge_bat;
70 } else if (!PSY_PROP(max_energy_bat, VOLTAGE_MAX_DESIGN,
71 &full)) {
72 if (max_charge > max_energy / full.intval)
73 main_battery = max_charge_bat;
74 else
75 main_battery = max_energy_bat;
76 } else {
77 /* give up, choice any */
78 main_battery = max_energy_bat;
79 }
80 } else if (max_charge_bat) {
81 main_battery = max_charge_bat;
82 } else if (max_energy_bat) {
83 main_battery = max_energy_bat;
84 } else {
85 /* give up, try the last if any */
86 main_battery = bat;
48 } 87 }
49 if (!main_battery)
50 main_battery = batm;
51} 88}
52 89
53static int calculate_time(int status) 90static int calculate_time(int status)