Merge git://git.infradead.org/battery-2.6

* git://git.infradead.org/battery-2.6:
apm_power: check I.intval for zero value, we use it as the divisor
MAINTAINERS: remove kernel-discuss@handhelds.org list
pda_power: implement polling
pda_power: various cleanups
apm_power: support using VOLTAGE_* properties for apm calculations
pda_power: add suspend/resume support
power_supply: add few more values and props
pda_power: only register available psu
power: fix incorrect unregistration in power_supply_create_attrs error path
power: remove POWER_SUPPLY_PROP_CAPACITY_LEVEL
[BATTERY] power_supply_leds: use kasprintf
[BATTERY] Every file should include the headers containing the prototypes for its global functions.

+301 -153
+4 -2
Documentation/power_supply_class.txt
··· 87 87 Battery driver also can use this attribute just to inform userspace 88 88 about maximal and minimal voltage thresholds of a given battery. 89 89 90 + VOLTAGE_MAX, VOLTAGE_MIN - same as _DESIGN voltage values except that 91 + these ones should be used if hardware could only guess (measure and 92 + retain) the thresholds of a given power supply. 93 + 90 94 CHARGE_FULL_DESIGN, CHARGE_EMPTY_DESIGN - design charge values, when 91 95 battery considered full/empty. 92 96 ··· 104 100 ENERGY_FULL, ENERGY_EMPTY - same as above but for energy. 105 101 106 102 CAPACITY - capacity in percents. 107 - CAPACITY_LEVEL - capacity level. This corresponds to 108 - POWER_SUPPLY_CAPACITY_LEVEL_*. 109 103 110 104 TEMP - temperature of the power supply. 111 105 TEMP_AMBIENT - ambient temperature.
-1
MAINTAINERS
··· 3053 3053 P: David Woodhouse 3054 3054 M: dwmw2@infradead.org 3055 3055 L: linux-kernel@vger.kernel.org 3056 - L: kernel-discuss@handhelds.org 3057 3056 T: git git.infradead.org/battery-2.6.git 3058 3057 S: Maintained 3059 3058
+73 -21
drivers/power/apm_power.c
··· 13 13 #include <linux/power_supply.h> 14 14 #include <linux/apm-emulation.h> 15 15 16 - static DEFINE_MUTEX(apm_mutex); 16 + 17 17 #define PSY_PROP(psy, prop, val) psy->get_property(psy, \ 18 18 POWER_SUPPLY_PROP_##prop, val) 19 19 ··· 22 22 23 23 #define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val) 24 24 25 + static DEFINE_MUTEX(apm_mutex); 25 26 static struct power_supply *main_battery; 27 + 28 + enum apm_source { 29 + SOURCE_ENERGY, 30 + SOURCE_CHARGE, 31 + SOURCE_VOLTAGE, 32 + }; 26 33 27 34 struct find_bat_param { 28 35 struct power_supply *main; ··· 114 107 } 115 108 } 116 109 117 - static int calculate_time(int status, int using_charge) 110 + static int do_calculate_time(int status, enum apm_source source) 118 111 { 119 112 union power_supply_propval full; 120 113 union power_supply_propval empty; ··· 133 126 return -1; 134 127 } 135 128 136 - if (using_charge) { 129 + if (!I.intval) 130 + return 0; 131 + 132 + switch (source) { 133 + case SOURCE_CHARGE: 137 134 full_prop = POWER_SUPPLY_PROP_CHARGE_FULL; 138 135 full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; 139 136 empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; 140 137 empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; 141 138 cur_avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG; 142 139 cur_now_prop = POWER_SUPPLY_PROP_CHARGE_NOW; 143 - } else { 140 + break; 141 + case SOURCE_ENERGY: 144 142 full_prop = POWER_SUPPLY_PROP_ENERGY_FULL; 145 143 full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN; 146 144 empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY; 147 145 empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; 148 146 cur_avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; 149 147 cur_now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; 148 + break; 149 + case SOURCE_VOLTAGE: 150 + full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX; 151 + full_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN; 152 + empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN; 153 + empty_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN; 154 + cur_avg_prop = POWER_SUPPLY_PROP_VOLTAGE_AVG; 155 + cur_now_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW; 156 + break; 157 + default: 158 + printk(KERN_ERR "Unsupported source: %d\n", source); 159 + return -1; 150 160 } 151 161 152 162 if (_MPSY_PROP(full_prop, &full)) { ··· 190 166 return -((cur.intval - empty.intval) * 60L) / I.intval; 191 167 } 192 168 193 - static int calculate_capacity(int using_charge) 169 + static int calculate_time(int status) 170 + { 171 + int time; 172 + 173 + time = do_calculate_time(status, SOURCE_ENERGY); 174 + if (time != -1) 175 + return time; 176 + 177 + time = do_calculate_time(status, SOURCE_CHARGE); 178 + if (time != -1) 179 + return time; 180 + 181 + time = do_calculate_time(status, SOURCE_VOLTAGE); 182 + if (time != -1) 183 + return time; 184 + 185 + return -1; 186 + } 187 + 188 + static int calculate_capacity(enum apm_source source) 194 189 { 195 190 enum power_supply_property full_prop, empty_prop; 196 191 enum power_supply_property full_design_prop, empty_design_prop; ··· 217 174 union power_supply_propval empty, full, cur; 218 175 int ret; 219 176 220 - if (using_charge) { 177 + switch (source) { 178 + case SOURCE_CHARGE: 221 179 full_prop = POWER_SUPPLY_PROP_CHARGE_FULL; 222 180 empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; 223 181 full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; 224 182 empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN; 225 183 now_prop = POWER_SUPPLY_PROP_CHARGE_NOW; 226 184 avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG; 227 - } else { 185 + break; 186 + case SOURCE_ENERGY: 228 187 full_prop = POWER_SUPPLY_PROP_ENERGY_FULL; 229 188 empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY; 230 189 full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN; 231 190 empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN; 232 191 now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; 233 192 avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; 193 + case SOURCE_VOLTAGE: 194 + full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX; 195 + empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN; 196 + full_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN; 197 + empty_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN; 198 + now_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW; 199 + avg_prop = POWER_SUPPLY_PROP_VOLTAGE_AVG; 200 + break; 201 + default: 202 + printk(KERN_ERR "Unsupported source: %d\n", source); 203 + return -1; 234 204 } 235 205 236 206 if (_MPSY_PROP(full_prop, &full)) { ··· 310 254 info->battery_life = capacity.intval; 311 255 } else { 312 256 /* try calculate using energy */ 313 - info->battery_life = calculate_capacity(0); 257 + info->battery_life = calculate_capacity(SOURCE_ENERGY); 314 258 /* if failed try calculate using charge instead */ 315 259 if (info->battery_life == -1) 316 - info->battery_life = calculate_capacity(1); 260 + info->battery_life = calculate_capacity(SOURCE_CHARGE); 261 + if (info->battery_life == -1) 262 + info->battery_life = calculate_capacity(SOURCE_VOLTAGE); 317 263 } 318 264 319 265 /* charging status */ ··· 338 280 339 281 if (status.intval == POWER_SUPPLY_STATUS_CHARGING) { 340 282 if (!MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full) || 341 - !MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) { 283 + !MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) 342 284 info->time = time_to_full.intval / 60; 343 - } else { 344 - info->time = calculate_time(status.intval, 0); 345 - if (info->time == -1) 346 - info->time = calculate_time(status.intval, 1); 347 - } 285 + else 286 + info->time = calculate_time(status.intval); 348 287 } else { 349 288 if (!MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty) || 350 - !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) { 289 + !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) 351 290 info->time = time_to_empty.intval / 60; 352 - } else { 353 - info->time = calculate_time(status.intval, 0); 354 - if (info->time == -1) 355 - info->time = calculate_time(status.intval, 1); 356 - } 291 + else 292 + info->time = calculate_time(status.intval); 357 293 } 358 294 359 295 mutex_unlock(&apm_mutex);
-9
drivers/power/olpc_battery.c
··· 226 226 return ret; 227 227 val->intval = ec_byte; 228 228 break; 229 - case POWER_SUPPLY_PROP_CAPACITY_LEVEL: 230 - if (ec_byte & BAT_STAT_FULL) 231 - val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL; 232 - else if (ec_byte & BAT_STAT_LOW) 233 - val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW; 234 - else 235 - val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; 236 - break; 237 229 case POWER_SUPPLY_PROP_TEMP: 238 230 ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2); 239 231 if (ret) ··· 257 265 POWER_SUPPLY_PROP_VOLTAGE_AVG, 258 266 POWER_SUPPLY_PROP_CURRENT_AVG, 259 267 POWER_SUPPLY_PROP_CAPACITY, 260 - POWER_SUPPLY_PROP_CAPACITY_LEVEL, 261 268 POWER_SUPPLY_PROP_TEMP, 262 269 POWER_SUPPLY_PROP_TEMP_AMBIENT, 263 270 POWER_SUPPLY_PROP_MANUFACTURER,
+203 -81
drivers/power/pda_power.c
··· 32 32 static struct resource *ac_irq, *usb_irq; 33 33 static struct timer_list charger_timer; 34 34 static struct timer_list supply_timer; 35 + static struct timer_list polling_timer; 36 + static int polling; 37 + 38 + enum { 39 + PDA_PSY_OFFLINE = 0, 40 + PDA_PSY_ONLINE = 1, 41 + PDA_PSY_TO_CHANGE, 42 + }; 43 + static int new_ac_status = -1; 44 + static int new_usb_status = -1; 45 + static int ac_status = -1; 46 + static int usb_status = -1; 35 47 36 48 static int pda_power_get_property(struct power_supply *psy, 37 49 enum power_supply_property psp, ··· 73 61 "backup-battery", 74 62 }; 75 63 76 - static struct power_supply pda_power_supplies[] = { 77 - { 78 - .name = "ac", 79 - .type = POWER_SUPPLY_TYPE_MAINS, 80 - .supplied_to = pda_power_supplied_to, 81 - .num_supplicants = ARRAY_SIZE(pda_power_supplied_to), 82 - .properties = pda_power_props, 83 - .num_properties = ARRAY_SIZE(pda_power_props), 84 - .get_property = pda_power_get_property, 85 - }, 86 - { 87 - .name = "usb", 88 - .type = POWER_SUPPLY_TYPE_USB, 89 - .supplied_to = pda_power_supplied_to, 90 - .num_supplicants = ARRAY_SIZE(pda_power_supplied_to), 91 - .properties = pda_power_props, 92 - .num_properties = ARRAY_SIZE(pda_power_props), 93 - .get_property = pda_power_get_property, 94 - }, 64 + static struct power_supply pda_psy_ac = { 65 + .name = "ac", 66 + .type = POWER_SUPPLY_TYPE_MAINS, 67 + .supplied_to = pda_power_supplied_to, 68 + .num_supplicants = ARRAY_SIZE(pda_power_supplied_to), 69 + .properties = pda_power_props, 70 + .num_properties = ARRAY_SIZE(pda_power_props), 71 + .get_property = pda_power_get_property, 95 72 }; 73 + 74 + static struct power_supply pda_psy_usb = { 75 + .name = "usb", 76 + .type = POWER_SUPPLY_TYPE_USB, 77 + .supplied_to = pda_power_supplied_to, 78 + .num_supplicants = ARRAY_SIZE(pda_power_supplied_to), 79 + .properties = pda_power_props, 80 + .num_properties = ARRAY_SIZE(pda_power_props), 81 + .get_property = pda_power_get_property, 82 + }; 83 + 84 + static void update_status(void) 85 + { 86 + if (pdata->is_ac_online) 87 + new_ac_status = !!pdata->is_ac_online(); 88 + 89 + if (pdata->is_usb_online) 90 + new_usb_status = !!pdata->is_usb_online(); 91 + } 96 92 97 93 static void update_charger(void) 98 94 { 99 95 if (!pdata->set_charge) 100 96 return; 101 97 102 - if (pdata->is_ac_online && pdata->is_ac_online()) { 98 + if (new_ac_status > 0) { 103 99 dev_dbg(dev, "charger on (AC)\n"); 104 100 pdata->set_charge(PDA_POWER_CHARGE_AC); 105 - } else if (pdata->is_usb_online && pdata->is_usb_online()) { 101 + } else if (new_usb_status > 0) { 106 102 dev_dbg(dev, "charger on (USB)\n"); 107 103 pdata->set_charge(PDA_POWER_CHARGE_USB); 108 104 } else { ··· 119 99 } 120 100 } 121 101 122 - static void supply_timer_func(unsigned long power_supply_ptr) 102 + static void supply_timer_func(unsigned long unused) 123 103 { 124 - void *power_supply = (void *)power_supply_ptr; 104 + if (ac_status == PDA_PSY_TO_CHANGE) { 105 + ac_status = new_ac_status; 106 + power_supply_changed(&pda_psy_ac); 107 + } 125 108 126 - power_supply_changed(power_supply); 109 + if (usb_status == PDA_PSY_TO_CHANGE) { 110 + usb_status = new_usb_status; 111 + power_supply_changed(&pda_psy_usb); 112 + } 127 113 } 128 114 129 - static void charger_timer_func(unsigned long power_supply_ptr) 115 + static void psy_changed(void) 130 116 { 131 117 update_charger(); 132 118 133 - /* Okay, charger set. Now wait a bit before notifying supplicants, 134 - * charge power should stabilize. */ 135 - supply_timer.data = power_supply_ptr; 119 + /* 120 + * Okay, charger set. Now wait a bit before notifying supplicants, 121 + * charge power should stabilize. 122 + */ 136 123 mod_timer(&supply_timer, 137 124 jiffies + msecs_to_jiffies(pdata->wait_for_charger)); 138 125 } 139 126 127 + static void charger_timer_func(unsigned long unused) 128 + { 129 + update_status(); 130 + psy_changed(); 131 + } 132 + 140 133 static irqreturn_t power_changed_isr(int irq, void *power_supply) 141 134 { 142 - /* Wait a bit before reading ac/usb line status and setting charger, 143 - * because ac/usb status readings may lag from irq. */ 144 - charger_timer.data = (unsigned long)power_supply; 135 + if (power_supply == &pda_psy_ac) 136 + ac_status = PDA_PSY_TO_CHANGE; 137 + else if (power_supply == &pda_psy_usb) 138 + usb_status = PDA_PSY_TO_CHANGE; 139 + else 140 + return IRQ_NONE; 141 + 142 + /* 143 + * Wait a bit before reading ac/usb line status and setting charger, 144 + * because ac/usb status readings may lag from irq. 145 + */ 145 146 mod_timer(&charger_timer, 146 147 jiffies + msecs_to_jiffies(pdata->wait_for_status)); 148 + 147 149 return IRQ_HANDLED; 150 + } 151 + 152 + static void polling_timer_func(unsigned long unused) 153 + { 154 + int changed = 0; 155 + 156 + dev_dbg(dev, "polling...\n"); 157 + 158 + update_status(); 159 + 160 + if (!ac_irq && new_ac_status != ac_status) { 161 + ac_status = PDA_PSY_TO_CHANGE; 162 + changed = 1; 163 + } 164 + 165 + if (!usb_irq && new_usb_status != usb_status) { 166 + usb_status = PDA_PSY_TO_CHANGE; 167 + changed = 1; 168 + } 169 + 170 + if (changed) 171 + psy_changed(); 172 + 173 + mod_timer(&polling_timer, 174 + jiffies + msecs_to_jiffies(pdata->polling_interval)); 148 175 } 149 176 150 177 static int pda_power_probe(struct platform_device *pdev) ··· 209 142 210 143 pdata = pdev->dev.platform_data; 211 144 145 + update_status(); 212 146 update_charger(); 213 147 214 148 if (!pdata->wait_for_status) ··· 218 150 if (!pdata->wait_for_charger) 219 151 pdata->wait_for_charger = 500; 220 152 153 + if (!pdata->polling_interval) 154 + pdata->polling_interval = 2000; 155 + 221 156 setup_timer(&charger_timer, charger_timer_func, 0); 222 157 setup_timer(&supply_timer, supply_timer_func, 0); 223 158 224 159 ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac"); 225 160 usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); 226 - if (!ac_irq && !usb_irq) { 227 - dev_err(dev, "no ac/usb irq specified\n"); 228 - ret = -ENODEV; 229 - goto noirqs; 230 - } 231 161 232 162 if (pdata->supplied_to) { 233 - pda_power_supplies[0].supplied_to = pdata->supplied_to; 234 - pda_power_supplies[1].supplied_to = pdata->supplied_to; 235 - pda_power_supplies[0].num_supplicants = pdata->num_supplicants; 236 - pda_power_supplies[1].num_supplicants = pdata->num_supplicants; 163 + pda_psy_ac.supplied_to = pdata->supplied_to; 164 + pda_psy_ac.num_supplicants = pdata->num_supplicants; 165 + pda_psy_usb.supplied_to = pdata->supplied_to; 166 + pda_psy_usb.num_supplicants = pdata->num_supplicants; 237 167 } 238 168 239 - ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]); 240 - if (ret) { 241 - dev_err(dev, "failed to register %s power supply\n", 242 - pda_power_supplies[0].name); 243 - goto supply0_failed; 244 - } 245 - 246 - ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]); 247 - if (ret) { 248 - dev_err(dev, "failed to register %s power supply\n", 249 - pda_power_supplies[1].name); 250 - goto supply1_failed; 251 - } 252 - 253 - if (ac_irq) { 254 - ret = request_irq(ac_irq->start, power_changed_isr, 255 - get_irq_flags(ac_irq), ac_irq->name, 256 - &pda_power_supplies[0]); 169 + if (pdata->is_ac_online) { 170 + ret = power_supply_register(&pdev->dev, &pda_psy_ac); 257 171 if (ret) { 258 - dev_err(dev, "request ac irq failed\n"); 259 - goto ac_irq_failed; 172 + dev_err(dev, "failed to register %s power supply\n", 173 + pda_psy_ac.name); 174 + goto ac_supply_failed; 175 + } 176 + 177 + if (ac_irq) { 178 + ret = request_irq(ac_irq->start, power_changed_isr, 179 + get_irq_flags(ac_irq), ac_irq->name, 180 + &pda_psy_ac); 181 + if (ret) { 182 + dev_err(dev, "request ac irq failed\n"); 183 + goto ac_irq_failed; 184 + } 185 + } else { 186 + polling = 1; 260 187 } 261 188 } 262 189 263 - if (usb_irq) { 264 - ret = request_irq(usb_irq->start, power_changed_isr, 265 - get_irq_flags(usb_irq), usb_irq->name, 266 - &pda_power_supplies[1]); 190 + if (pdata->is_usb_online) { 191 + ret = power_supply_register(&pdev->dev, &pda_psy_usb); 267 192 if (ret) { 268 - dev_err(dev, "request usb irq failed\n"); 269 - goto usb_irq_failed; 193 + dev_err(dev, "failed to register %s power supply\n", 194 + pda_psy_usb.name); 195 + goto usb_supply_failed; 196 + } 197 + 198 + if (usb_irq) { 199 + ret = request_irq(usb_irq->start, power_changed_isr, 200 + get_irq_flags(usb_irq), 201 + usb_irq->name, &pda_psy_usb); 202 + if (ret) { 203 + dev_err(dev, "request usb irq failed\n"); 204 + goto usb_irq_failed; 205 + } 206 + } else { 207 + polling = 1; 270 208 } 271 209 } 272 210 273 - goto success; 211 + if (polling) { 212 + dev_dbg(dev, "will poll for status\n"); 213 + setup_timer(&polling_timer, polling_timer_func, 0); 214 + mod_timer(&polling_timer, 215 + jiffies + msecs_to_jiffies(pdata->polling_interval)); 216 + } 217 + 218 + if (ac_irq || usb_irq) 219 + device_init_wakeup(&pdev->dev, 1); 220 + 221 + return 0; 274 222 275 223 usb_irq_failed: 276 - if (ac_irq) 277 - free_irq(ac_irq->start, &pda_power_supplies[0]); 224 + if (pdata->is_usb_online) 225 + power_supply_unregister(&pda_psy_usb); 226 + usb_supply_failed: 227 + if (pdata->is_ac_online && ac_irq) 228 + free_irq(ac_irq->start, &pda_psy_ac); 278 229 ac_irq_failed: 279 - power_supply_unregister(&pda_power_supplies[1]); 280 - supply1_failed: 281 - power_supply_unregister(&pda_power_supplies[0]); 282 - supply0_failed: 283 - noirqs: 230 + if (pdata->is_ac_online) 231 + power_supply_unregister(&pda_psy_ac); 232 + ac_supply_failed: 284 233 wrongid: 285 - success: 286 234 return ret; 287 235 } 288 236 289 237 static int pda_power_remove(struct platform_device *pdev) 290 238 { 291 - if (usb_irq) 292 - free_irq(usb_irq->start, &pda_power_supplies[1]); 293 - if (ac_irq) 294 - free_irq(ac_irq->start, &pda_power_supplies[0]); 239 + if (pdata->is_usb_online && usb_irq) 240 + free_irq(usb_irq->start, &pda_psy_usb); 241 + if (pdata->is_ac_online && ac_irq) 242 + free_irq(ac_irq->start, &pda_psy_ac); 243 + 244 + if (polling) 245 + del_timer_sync(&polling_timer); 295 246 del_timer_sync(&charger_timer); 296 247 del_timer_sync(&supply_timer); 297 - power_supply_unregister(&pda_power_supplies[1]); 298 - power_supply_unregister(&pda_power_supplies[0]); 248 + 249 + if (pdata->is_usb_online) 250 + power_supply_unregister(&pda_psy_usb); 251 + if (pdata->is_ac_online) 252 + power_supply_unregister(&pda_psy_ac); 253 + 299 254 return 0; 300 255 } 256 + 257 + #ifdef CONFIG_PM 258 + static int pda_power_suspend(struct platform_device *pdev, pm_message_t state) 259 + { 260 + if (device_may_wakeup(&pdev->dev)) { 261 + if (ac_irq) 262 + enable_irq_wake(ac_irq->start); 263 + if (usb_irq) 264 + enable_irq_wake(usb_irq->start); 265 + } 266 + 267 + return 0; 268 + } 269 + 270 + static int pda_power_resume(struct platform_device *pdev) 271 + { 272 + if (device_may_wakeup(&pdev->dev)) { 273 + if (usb_irq) 274 + disable_irq_wake(usb_irq->start); 275 + if (ac_irq) 276 + disable_irq_wake(ac_irq->start); 277 + } 278 + 279 + return 0; 280 + } 281 + #else 282 + #define pda_power_suspend NULL 283 + #define pda_power_resume NULL 284 + #endif /* CONFIG_PM */ 301 285 302 286 static struct platform_driver pda_power_pdrv = { 303 287 .driver = { ··· 357 237 }, 358 238 .probe = pda_power_probe, 359 239 .remove = pda_power_remove, 240 + .suspend = pda_power_suspend, 241 + .resume = pda_power_resume, 360 242 }; 361 243 362 244 static int __init pda_power_init(void)
+9 -18
drivers/power/power_supply_leds.c
··· 10 10 * You may use this code as per GPL version 2 11 11 */ 12 12 13 + #include <linux/kernel.h> 13 14 #include <linux/power_supply.h> 15 + 16 + #include "power_supply.h" 14 17 15 18 /* Battery specific LEDs triggers. */ 16 19 ··· 49 46 { 50 47 int rc = 0; 51 48 52 - psy->charging_full_trig_name = kmalloc(strlen(psy->name) + 53 - sizeof("-charging-or-full"), GFP_KERNEL); 49 + psy->charging_full_trig_name = kasprintf(GFP_KERNEL, 50 + "%s-charging-or-full", psy->name); 54 51 if (!psy->charging_full_trig_name) 55 52 goto charging_full_failed; 56 53 57 - psy->charging_trig_name = kmalloc(strlen(psy->name) + 58 - sizeof("-charging"), GFP_KERNEL); 54 + psy->charging_trig_name = kasprintf(GFP_KERNEL, 55 + "%s-charging", psy->name); 59 56 if (!psy->charging_trig_name) 60 57 goto charging_failed; 61 58 62 - psy->full_trig_name = kmalloc(strlen(psy->name) + 63 - sizeof("-full"), GFP_KERNEL); 59 + psy->full_trig_name = kasprintf(GFP_KERNEL, "%s-full", psy->name); 64 60 if (!psy->full_trig_name) 65 61 goto full_failed; 66 - 67 - strcpy(psy->charging_full_trig_name, psy->name); 68 - strcat(psy->charging_full_trig_name, "-charging-or-full"); 69 - strcpy(psy->charging_trig_name, psy->name); 70 - strcat(psy->charging_trig_name, "-charging"); 71 - strcpy(psy->full_trig_name, psy->name); 72 - strcat(psy->full_trig_name, "-full"); 73 62 74 63 led_trigger_register_simple(psy->charging_full_trig_name, 75 64 &psy->charging_full_trig); ··· 113 118 { 114 119 int rc = 0; 115 120 116 - psy->online_trig_name = kmalloc(strlen(psy->name) + sizeof("-online"), 117 - GFP_KERNEL); 121 + psy->online_trig_name = kasprintf(GFP_KERNEL, "%s-online", psy->name); 118 122 if (!psy->online_trig_name) 119 123 goto online_failed; 120 - 121 - strcpy(psy->online_trig_name, psy->name); 122 - strcat(psy->online_trig_name, "-online"); 123 124 124 125 led_trigger_register_simple(psy->online_trig_name, &psy->online_trig); 125 126
+8 -11
drivers/power/power_supply_sysfs.c
··· 14 14 #include <linux/ctype.h> 15 15 #include <linux/power_supply.h> 16 16 17 + #include "power_supply.h" 18 + 17 19 /* 18 20 * This is because the name "current" breaks the device attr macro. 19 21 * The "current" word resolves to "(get_current())" so instead of ··· 48 46 "Unspecified failure" 49 47 }; 50 48 static char *technology_text[] = { 51 - "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd" 52 - }; 53 - static char *capacity_level_text[] = { 54 - "Unknown", "Critical", "Low", "Normal", "High", "Full" 49 + "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd", 50 + "LiMn" 55 51 }; 56 52 ssize_t ret; 57 53 struct power_supply *psy = dev_get_drvdata(dev); ··· 71 71 return sprintf(buf, "%s\n", health_text[value.intval]); 72 72 else if (off == POWER_SUPPLY_PROP_TECHNOLOGY) 73 73 return sprintf(buf, "%s\n", technology_text[value.intval]); 74 - else if (off == POWER_SUPPLY_PROP_CAPACITY_LEVEL) 75 - return sprintf(buf, "%s\n", 76 - capacity_level_text[value.intval]); 77 74 else if (off >= POWER_SUPPLY_PROP_MODEL_NAME) 78 75 return sprintf(buf, "%s\n", value.strval); 79 76 ··· 85 88 POWER_SUPPLY_ATTR(present), 86 89 POWER_SUPPLY_ATTR(online), 87 90 POWER_SUPPLY_ATTR(technology), 91 + POWER_SUPPLY_ATTR(voltage_max), 92 + POWER_SUPPLY_ATTR(voltage_min), 88 93 POWER_SUPPLY_ATTR(voltage_max_design), 89 94 POWER_SUPPLY_ATTR(voltage_min_design), 90 95 POWER_SUPPLY_ATTR(voltage_now), ··· 158 159 &power_supply_attrs[psy->properties[j]]); 159 160 statics_failed: 160 161 while (i--) 161 - device_remove_file(psy->dev, 162 - &power_supply_static_attrs[psy->properties[i]]); 162 + device_remove_file(psy->dev, &power_supply_static_attrs[i]); 163 163 succeed: 164 164 return rc; 165 165 } ··· 168 170 int i; 169 171 170 172 for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++) 171 - device_remove_file(psy->dev, 172 - &power_supply_static_attrs[i]); 173 + device_remove_file(psy->dev, &power_supply_static_attrs[i]); 173 174 174 175 for (i = 0; i < psy->num_properties; i++) 175 176 device_remove_file(psy->dev,
+1
include/linux/pda_power.h
··· 26 26 27 27 unsigned int wait_for_status; /* msecs, default is 500 */ 28 28 unsigned int wait_for_charger; /* msecs, default is 500 */ 29 + unsigned int polling_interval; /* msecs, default is 2000 */ 29 30 }; 30 31 31 32 #endif /* __PDA_POWER_H__ */
+3 -10
include/linux/power_supply.h
··· 54 54 POWER_SUPPLY_TECHNOLOGY_LIPO, 55 55 POWER_SUPPLY_TECHNOLOGY_LiFe, 56 56 POWER_SUPPLY_TECHNOLOGY_NiCd, 57 - }; 58 - 59 - enum { 60 - POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN = 0, 61 - POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL, 62 - POWER_SUPPLY_CAPACITY_LEVEL_LOW, 63 - POWER_SUPPLY_CAPACITY_LEVEL_NORMAL, 64 - POWER_SUPPLY_CAPACITY_LEVEL_HIGH, 65 - POWER_SUPPLY_CAPACITY_LEVEL_FULL, 57 + POWER_SUPPLY_TECHNOLOGY_LiMn, 66 58 }; 67 59 68 60 enum power_supply_property { ··· 64 72 POWER_SUPPLY_PROP_PRESENT, 65 73 POWER_SUPPLY_PROP_ONLINE, 66 74 POWER_SUPPLY_PROP_TECHNOLOGY, 75 + POWER_SUPPLY_PROP_VOLTAGE_MAX, 76 + POWER_SUPPLY_PROP_VOLTAGE_MIN, 67 77 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 68 78 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 69 79 POWER_SUPPLY_PROP_VOLTAGE_NOW, ··· 85 91 POWER_SUPPLY_PROP_ENERGY_NOW, 86 92 POWER_SUPPLY_PROP_ENERGY_AVG, 87 93 POWER_SUPPLY_PROP_CAPACITY, /* in percents! */ 88 - POWER_SUPPLY_PROP_CAPACITY_LEVEL, 89 94 POWER_SUPPLY_PROP_TEMP, 90 95 POWER_SUPPLY_PROP_TEMP_AMBIENT, 91 96 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,