2 * Universal power supply monitor class
4 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
5 * Copyright © 2004 Szabolcs Gyurko
6 * Copyright © 2003 Ian Molton <spyro@f2s.com>
8 * Modified: 2004, Oct Szabolcs Gyurko
10 * You may use this code as per GPL version 2
13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/init.h>
16 #include <linux/slab.h>
17 #include <linux/device.h>
18 #include <linux/err.h>
19 #include <linux/power_supply.h>
20 #include <linux/thermal.h>
21 #include "power_supply.h"
23 /* exported for the APM Power driver, APM emulation */
24 struct class *power_supply_class
;
25 EXPORT_SYMBOL_GPL(power_supply_class
);
27 static struct device_type power_supply_dev_type
;
29 static bool __power_supply_is_supplied_by(struct power_supply
*supplier
,
30 struct power_supply
*supply
)
34 if (!supply
->supplied_from
&& !supplier
->supplied_to
)
37 /* Support both supplied_to and supplied_from modes */
38 if (supply
->supplied_from
) {
41 for (i
= 0; i
< supply
->num_supplies
; i
++)
42 if (!strcmp(supplier
->name
, supply
->supplied_from
[i
]))
47 for (i
= 0; i
< supplier
->num_supplicants
; i
++)
48 if (!strcmp(supplier
->supplied_to
[i
], supply
->name
))
55 static int __power_supply_changed_work(struct device
*dev
, void *data
)
57 struct power_supply
*psy
= (struct power_supply
*)data
;
58 struct power_supply
*pst
= dev_get_drvdata(dev
);
60 if (__power_supply_is_supplied_by(psy
, pst
)) {
61 if (pst
->external_power_changed
)
62 pst
->external_power_changed(pst
);
68 static void power_supply_changed_work(struct work_struct
*work
)
71 struct power_supply
*psy
= container_of(work
, struct power_supply
,
74 dev_dbg(psy
->dev
, "%s\n", __func__
);
76 spin_lock_irqsave(&psy
->changed_lock
, flags
);
79 spin_unlock_irqrestore(&psy
->changed_lock
, flags
);
81 class_for_each_device(power_supply_class
, NULL
, psy
,
82 __power_supply_changed_work
);
84 power_supply_update_leds(psy
);
86 kobject_uevent(&psy
->dev
->kobj
, KOBJ_CHANGE
);
87 spin_lock_irqsave(&psy
->changed_lock
, flags
);
91 spin_unlock_irqrestore(&psy
->changed_lock
, flags
);
94 void power_supply_changed(struct power_supply
*psy
)
98 dev_dbg(psy
->dev
, "%s\n", __func__
);
100 spin_lock_irqsave(&psy
->changed_lock
, flags
);
102 pm_stay_awake(psy
->dev
);
103 spin_unlock_irqrestore(&psy
->changed_lock
, flags
);
104 schedule_work(&psy
->changed_work
);
106 EXPORT_SYMBOL_GPL(power_supply_changed
);
109 #include <linux/of.h>
111 static int __power_supply_populate_supplied_from(struct device
*dev
,
114 struct power_supply
*psy
= (struct power_supply
*)data
;
115 struct power_supply
*epsy
= dev_get_drvdata(dev
);
116 struct device_node
*np
;
120 np
= of_parse_phandle(psy
->of_node
, "power-supplies", i
++);
124 if (np
== epsy
->of_node
) {
125 dev_info(psy
->dev
, "%s: Found supply : %s\n",
126 psy
->name
, epsy
->name
);
127 psy
->supplied_from
[i
-1] = (char *)epsy
->name
;
136 static int power_supply_populate_supplied_from(struct power_supply
*psy
)
140 error
= class_for_each_device(power_supply_class
, NULL
, psy
,
141 __power_supply_populate_supplied_from
);
143 dev_dbg(psy
->dev
, "%s %d\n", __func__
, error
);
148 static int __power_supply_find_supply_from_node(struct device
*dev
,
151 struct device_node
*np
= (struct device_node
*)data
;
152 struct power_supply
*epsy
= dev_get_drvdata(dev
);
154 /* return error breaks out of class_for_each_device loop */
155 if (epsy
->of_node
== np
)
161 static int power_supply_find_supply_from_node(struct device_node
*supply_node
)
165 struct class_dev_iter iter
;
168 * Use iterator to see if any other device is registered.
169 * This is required since class_for_each_device returns 0
170 * if there are no devices registered.
172 class_dev_iter_init(&iter
, power_supply_class
, NULL
, NULL
);
173 dev
= class_dev_iter_next(&iter
);
176 return -EPROBE_DEFER
;
179 * We have to treat the return value as inverted, because if
180 * we return error on not found, then it won't continue looking.
181 * So we trick it by returning error on success to stop looking
182 * once the matching device is found.
184 error
= class_for_each_device(power_supply_class
, NULL
, supply_node
,
185 __power_supply_find_supply_from_node
);
187 return error
? 0 : -EPROBE_DEFER
;
190 static int power_supply_check_supplies(struct power_supply
*psy
)
192 struct device_node
*np
;
195 /* If there is already a list honor it */
196 if (psy
->supplied_from
&& psy
->num_supplies
> 0)
199 /* No device node found, nothing to do */
206 np
= of_parse_phandle(psy
->of_node
, "power-supplies", cnt
++);
210 ret
= power_supply_find_supply_from_node(np
);
212 dev_dbg(psy
->dev
, "Failed to find supply, defer!\n");
213 return -EPROBE_DEFER
;
217 /* All supplies found, allocate char ** array for filling */
218 psy
->supplied_from
= devm_kzalloc(psy
->dev
, sizeof(psy
->supplied_from
),
220 if (!psy
->supplied_from
) {
221 dev_err(psy
->dev
, "Couldn't allocate memory for supply list\n");
225 *psy
->supplied_from
= devm_kzalloc(psy
->dev
, sizeof(char *) * cnt
,
227 if (!*psy
->supplied_from
) {
228 dev_err(psy
->dev
, "Couldn't allocate memory for supply list\n");
232 return power_supply_populate_supplied_from(psy
);
235 static inline int power_supply_check_supplies(struct power_supply
*psy
)
241 static int __power_supply_am_i_supplied(struct device
*dev
, void *data
)
243 union power_supply_propval ret
= {0,};
244 struct power_supply
*psy
= (struct power_supply
*)data
;
245 struct power_supply
*epsy
= dev_get_drvdata(dev
);
247 if (__power_supply_is_supplied_by(epsy
, psy
))
248 if (!epsy
->get_property(epsy
, POWER_SUPPLY_PROP_ONLINE
, &ret
)) {
256 int power_supply_am_i_supplied(struct power_supply
*psy
)
260 error
= class_for_each_device(power_supply_class
, NULL
, psy
,
261 __power_supply_am_i_supplied
);
263 dev_dbg(psy
->dev
, "%s %d\n", __func__
, error
);
267 EXPORT_SYMBOL_GPL(power_supply_am_i_supplied
);
269 static int __power_supply_is_system_supplied(struct device
*dev
, void *data
)
271 union power_supply_propval ret
= {0,};
272 struct power_supply
*psy
= dev_get_drvdata(dev
);
273 unsigned int *count
= data
;
276 if (psy
->type
!= POWER_SUPPLY_TYPE_BATTERY
) {
277 if (psy
->get_property(psy
, POWER_SUPPLY_PROP_ONLINE
, &ret
))
285 int power_supply_is_system_supplied(void)
288 unsigned int count
= 0;
290 error
= class_for_each_device(power_supply_class
, NULL
, &count
,
291 __power_supply_is_system_supplied
);
294 * If no power class device was found at all, most probably we are
295 * running on a desktop system, so assume we are on mains power.
302 EXPORT_SYMBOL_GPL(power_supply_is_system_supplied
);
304 int power_supply_set_battery_charged(struct power_supply
*psy
)
306 if (psy
->type
== POWER_SUPPLY_TYPE_BATTERY
&& psy
->set_charged
) {
307 psy
->set_charged(psy
);
313 EXPORT_SYMBOL_GPL(power_supply_set_battery_charged
);
315 static int power_supply_match_device_by_name(struct device
*dev
, const void *data
)
317 const char *name
= data
;
318 struct power_supply
*psy
= dev_get_drvdata(dev
);
320 return strcmp(psy
->name
, name
) == 0;
323 struct power_supply
*power_supply_get_by_name(const char *name
)
325 struct device
*dev
= class_find_device(power_supply_class
, NULL
, name
,
326 power_supply_match_device_by_name
);
328 return dev
? dev_get_drvdata(dev
) : NULL
;
330 EXPORT_SYMBOL_GPL(power_supply_get_by_name
);
332 int power_supply_powers(struct power_supply
*psy
, struct device
*dev
)
334 return sysfs_create_link(&psy
->dev
->kobj
, &dev
->kobj
, "powers");
336 EXPORT_SYMBOL_GPL(power_supply_powers
);
338 static void power_supply_dev_release(struct device
*dev
)
340 pr_debug("device: '%s': %s\n", dev_name(dev
), __func__
);
344 #ifdef CONFIG_THERMAL
345 static int power_supply_read_temp(struct thermal_zone_device
*tzd
,
348 struct power_supply
*psy
;
349 union power_supply_propval val
;
352 WARN_ON(tzd
== NULL
);
354 ret
= psy
->get_property(psy
, POWER_SUPPLY_PROP_TEMP
, &val
);
356 /* Convert tenths of degree Celsius to milli degree Celsius. */
358 *temp
= val
.intval
* 100;
363 static struct thermal_zone_device_ops psy_tzd_ops
= {
364 .get_temp
= power_supply_read_temp
,
367 static int psy_register_thermal(struct power_supply
*psy
)
371 /* Register battery zone device psy reports temperature */
372 for (i
= 0; i
< psy
->num_properties
; i
++) {
373 if (psy
->properties
[i
] == POWER_SUPPLY_PROP_TEMP
) {
374 psy
->tzd
= thermal_zone_device_register(psy
->name
, 0, 0,
375 psy
, &psy_tzd_ops
, NULL
, 0, 0);
376 if (IS_ERR(psy
->tzd
))
377 return PTR_ERR(psy
->tzd
);
384 static void psy_unregister_thermal(struct power_supply
*psy
)
386 if (IS_ERR_OR_NULL(psy
->tzd
))
388 thermal_zone_device_unregister(psy
->tzd
);
391 /* thermal cooling device callbacks */
392 static int ps_get_max_charge_cntl_limit(struct thermal_cooling_device
*tcd
,
393 unsigned long *state
)
395 struct power_supply
*psy
;
396 union power_supply_propval val
;
400 ret
= psy
->get_property(psy
,
401 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX
, &val
);
408 static int ps_get_cur_chrage_cntl_limit(struct thermal_cooling_device
*tcd
,
409 unsigned long *state
)
411 struct power_supply
*psy
;
412 union power_supply_propval val
;
416 ret
= psy
->get_property(psy
,
417 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT
, &val
);
424 static int ps_set_cur_charge_cntl_limit(struct thermal_cooling_device
*tcd
,
427 struct power_supply
*psy
;
428 union power_supply_propval val
;
433 ret
= psy
->set_property(psy
,
434 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT
, &val
);
439 static struct thermal_cooling_device_ops psy_tcd_ops
= {
440 .get_max_state
= ps_get_max_charge_cntl_limit
,
441 .get_cur_state
= ps_get_cur_chrage_cntl_limit
,
442 .set_cur_state
= ps_set_cur_charge_cntl_limit
,
445 static int psy_register_cooler(struct power_supply
*psy
)
449 /* Register for cooling device if psy can control charging */
450 for (i
= 0; i
< psy
->num_properties
; i
++) {
451 if (psy
->properties
[i
] ==
452 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT
) {
453 psy
->tcd
= thermal_cooling_device_register(
456 if (IS_ERR(psy
->tcd
))
457 return PTR_ERR(psy
->tcd
);
464 static void psy_unregister_cooler(struct power_supply
*psy
)
466 if (IS_ERR_OR_NULL(psy
->tcd
))
468 thermal_cooling_device_unregister(psy
->tcd
);
471 static int psy_register_thermal(struct power_supply
*psy
)
476 static void psy_unregister_thermal(struct power_supply
*psy
)
480 static int psy_register_cooler(struct power_supply
*psy
)
485 static void psy_unregister_cooler(struct power_supply
*psy
)
490 int power_supply_register(struct device
*parent
, struct power_supply
*psy
)
495 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
499 device_initialize(dev
);
501 dev
->class = power_supply_class
;
502 dev
->type
= &power_supply_dev_type
;
503 dev
->parent
= parent
;
504 dev
->release
= power_supply_dev_release
;
505 dev_set_drvdata(dev
, psy
);
508 INIT_WORK(&psy
->changed_work
, power_supply_changed_work
);
510 rc
= power_supply_check_supplies(psy
);
512 dev_info(dev
, "Not all required supplies found, defer probe\n");
513 goto check_supplies_failed
;
516 rc
= kobject_set_name(&dev
->kobj
, "%s", psy
->name
);
518 goto kobject_set_name_failed
;
520 rc
= device_add(dev
);
522 goto device_add_failed
;
524 spin_lock_init(&psy
->changed_lock
);
525 rc
= device_init_wakeup(dev
, true);
527 goto wakeup_init_failed
;
529 rc
= psy_register_thermal(psy
);
531 goto register_thermal_failed
;
533 rc
= psy_register_cooler(psy
);
535 goto register_cooler_failed
;
537 rc
= power_supply_create_triggers(psy
);
539 goto create_triggers_failed
;
541 power_supply_changed(psy
);
545 create_triggers_failed
:
546 psy_unregister_cooler(psy
);
547 register_cooler_failed
:
548 psy_unregister_thermal(psy
);
549 register_thermal_failed
:
552 kobject_set_name_failed
:
554 check_supplies_failed
:
559 EXPORT_SYMBOL_GPL(power_supply_register
);
561 void power_supply_unregister(struct power_supply
*psy
)
563 cancel_work_sync(&psy
->changed_work
);
564 sysfs_remove_link(&psy
->dev
->kobj
, "powers");
565 power_supply_remove_triggers(psy
);
566 psy_unregister_cooler(psy
);
567 psy_unregister_thermal(psy
);
568 device_unregister(psy
->dev
);
570 EXPORT_SYMBOL_GPL(power_supply_unregister
);
572 static int __init
power_supply_class_init(void)
574 power_supply_class
= class_create(THIS_MODULE
, "power_supply");
576 if (IS_ERR(power_supply_class
))
577 return PTR_ERR(power_supply_class
);
579 power_supply_class
->dev_uevent
= power_supply_uevent
;
580 power_supply_init_attrs(&power_supply_dev_type
);
585 static void __exit
power_supply_class_exit(void)
587 class_destroy(power_supply_class
);
590 subsys_initcall(power_supply_class_init
);
591 module_exit(power_supply_class_exit
);
593 MODULE_DESCRIPTION("Universal power supply monitor class");
594 MODULE_AUTHOR("Ian Molton <spyro@f2s.com>, "
596 "Anton Vorontsov <cbou@mail.ru>");
597 MODULE_LICENSE("GPL");