diff options
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/apm_power.c | 57 |
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; | |||
26 | static void find_main_battery(void) | 26 | static 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 | ||
53 | static int calculate_time(int status) | 90 | static int calculate_time(int status) |