5e3b8c15ddbe6e1c87ac49adb88663e8f0808f92
[linux-2.6-microblaze.git] / drivers / power / supply / power_supply_sysfs.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  Sysfs interface for the universal power supply monitor class
4  *
5  *  Copyright © 2007  David Woodhouse <dwmw2@infradead.org>
6  *  Copyright © 2007  Anton Vorontsov <cbou@mail.ru>
7  *  Copyright © 2004  Szabolcs Gyurko
8  *  Copyright © 2003  Ian Molton <spyro@f2s.com>
9  *
10  *  Modified: 2004, Oct     Szabolcs Gyurko
11  */
12
13 #include <linux/ctype.h>
14 #include <linux/device.h>
15 #include <linux/power_supply.h>
16 #include <linux/slab.h>
17 #include <linux/stat.h>
18
19 #include "power_supply.h"
20
21 #define MAX_PROP_NAME_LEN 30
22
23 struct power_supply_attr {
24         const char *prop_name;
25         char attr_name[MAX_PROP_NAME_LEN + 1];
26         struct device_attribute dev_attr;
27         const char * const *text_values;
28         int text_values_len;
29 };
30
31 #define _POWER_SUPPLY_ATTR(_name, _text, _len)  \
32 [POWER_SUPPLY_PROP_ ## _name] =                 \
33 {                                               \
34         .prop_name = #_name,                    \
35         .attr_name = #_name "\0",               \
36         .text_values = _text,                   \
37         .text_values_len = _len,                \
38 }
39
40 #define POWER_SUPPLY_ATTR(_name) _POWER_SUPPLY_ATTR(_name, NULL, 0)
41 #define _POWER_SUPPLY_ENUM_ATTR(_name, _text)   \
42         _POWER_SUPPLY_ATTR(_name, _text, ARRAY_SIZE(_text))
43 #define POWER_SUPPLY_ENUM_ATTR(_name)   \
44         _POWER_SUPPLY_ENUM_ATTR(_name, POWER_SUPPLY_ ## _name ## _TEXT)
45
46 static const char * const POWER_SUPPLY_TYPE_TEXT[] = {
47         [POWER_SUPPLY_TYPE_UNKNOWN]             = "Unknown",
48         [POWER_SUPPLY_TYPE_BATTERY]             = "Battery",
49         [POWER_SUPPLY_TYPE_UPS]                 = "UPS",
50         [POWER_SUPPLY_TYPE_MAINS]               = "Mains",
51         [POWER_SUPPLY_TYPE_USB]                 = "USB",
52         [POWER_SUPPLY_TYPE_USB_DCP]             = "USB_DCP",
53         [POWER_SUPPLY_TYPE_USB_CDP]             = "USB_CDP",
54         [POWER_SUPPLY_TYPE_USB_ACA]             = "USB_ACA",
55         [POWER_SUPPLY_TYPE_USB_TYPE_C]          = "USB_C",
56         [POWER_SUPPLY_TYPE_USB_PD]              = "USB_PD",
57         [POWER_SUPPLY_TYPE_USB_PD_DRP]          = "USB_PD_DRP",
58         [POWER_SUPPLY_TYPE_APPLE_BRICK_ID]      = "BrickID",
59         [POWER_SUPPLY_TYPE_WIRELESS]            = "Wireless",
60 };
61
62 static const char * const POWER_SUPPLY_USB_TYPE_TEXT[] = {
63         [POWER_SUPPLY_USB_TYPE_UNKNOWN]         = "Unknown",
64         [POWER_SUPPLY_USB_TYPE_SDP]             = "SDP",
65         [POWER_SUPPLY_USB_TYPE_DCP]             = "DCP",
66         [POWER_SUPPLY_USB_TYPE_CDP]             = "CDP",
67         [POWER_SUPPLY_USB_TYPE_ACA]             = "ACA",
68         [POWER_SUPPLY_USB_TYPE_C]               = "C",
69         [POWER_SUPPLY_USB_TYPE_PD]              = "PD",
70         [POWER_SUPPLY_USB_TYPE_PD_DRP]          = "PD_DRP",
71         [POWER_SUPPLY_USB_TYPE_PD_PPS]          = "PD_PPS",
72         [POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID]  = "BrickID",
73 };
74
75 static const char * const POWER_SUPPLY_STATUS_TEXT[] = {
76         [POWER_SUPPLY_STATUS_UNKNOWN]           = "Unknown",
77         [POWER_SUPPLY_STATUS_CHARGING]          = "Charging",
78         [POWER_SUPPLY_STATUS_DISCHARGING]       = "Discharging",
79         [POWER_SUPPLY_STATUS_NOT_CHARGING]      = "Not charging",
80         [POWER_SUPPLY_STATUS_FULL]              = "Full",
81 };
82
83 static const char * const POWER_SUPPLY_CHARGE_TYPE_TEXT[] = {
84         [POWER_SUPPLY_CHARGE_TYPE_UNKNOWN]      = "Unknown",
85         [POWER_SUPPLY_CHARGE_TYPE_NONE]         = "N/A",
86         [POWER_SUPPLY_CHARGE_TYPE_TRICKLE]      = "Trickle",
87         [POWER_SUPPLY_CHARGE_TYPE_FAST]         = "Fast",
88         [POWER_SUPPLY_CHARGE_TYPE_STANDARD]     = "Standard",
89         [POWER_SUPPLY_CHARGE_TYPE_ADAPTIVE]     = "Adaptive",
90         [POWER_SUPPLY_CHARGE_TYPE_CUSTOM]       = "Custom",
91         [POWER_SUPPLY_CHARGE_TYPE_LONGLIFE]     = "Long Life",
92 };
93
94 static const char * const POWER_SUPPLY_HEALTH_TEXT[] = {
95         [POWER_SUPPLY_HEALTH_UNKNOWN]               = "Unknown",
96         [POWER_SUPPLY_HEALTH_GOOD]                  = "Good",
97         [POWER_SUPPLY_HEALTH_OVERHEAT]              = "Overheat",
98         [POWER_SUPPLY_HEALTH_DEAD]                  = "Dead",
99         [POWER_SUPPLY_HEALTH_OVERVOLTAGE]           = "Over voltage",
100         [POWER_SUPPLY_HEALTH_UNSPEC_FAILURE]        = "Unspecified failure",
101         [POWER_SUPPLY_HEALTH_COLD]                  = "Cold",
102         [POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE] = "Watchdog timer expire",
103         [POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE]   = "Safety timer expire",
104         [POWER_SUPPLY_HEALTH_OVERCURRENT]           = "Over current",
105         [POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED]  = "Calibration required",
106         [POWER_SUPPLY_HEALTH_WARM]                  = "Warm",
107         [POWER_SUPPLY_HEALTH_COOL]                  = "Cool",
108         [POWER_SUPPLY_HEALTH_HOT]                   = "Hot",
109 };
110
111 static const char * const POWER_SUPPLY_TECHNOLOGY_TEXT[] = {
112         [POWER_SUPPLY_TECHNOLOGY_UNKNOWN]       = "Unknown",
113         [POWER_SUPPLY_TECHNOLOGY_NiMH]          = "NiMH",
114         [POWER_SUPPLY_TECHNOLOGY_LION]          = "Li-ion",
115         [POWER_SUPPLY_TECHNOLOGY_LIPO]          = "Li-poly",
116         [POWER_SUPPLY_TECHNOLOGY_LiFe]          = "LiFe",
117         [POWER_SUPPLY_TECHNOLOGY_NiCd]          = "NiCd",
118         [POWER_SUPPLY_TECHNOLOGY_LiMn]          = "LiMn",
119 };
120
121 static const char * const POWER_SUPPLY_CAPACITY_LEVEL_TEXT[] = {
122         [POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN]   = "Unknown",
123         [POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL]  = "Critical",
124         [POWER_SUPPLY_CAPACITY_LEVEL_LOW]       = "Low",
125         [POWER_SUPPLY_CAPACITY_LEVEL_NORMAL]    = "Normal",
126         [POWER_SUPPLY_CAPACITY_LEVEL_HIGH]      = "High",
127         [POWER_SUPPLY_CAPACITY_LEVEL_FULL]      = "Full",
128 };
129
130 static const char * const POWER_SUPPLY_SCOPE_TEXT[] = {
131         [POWER_SUPPLY_SCOPE_UNKNOWN]    = "Unknown",
132         [POWER_SUPPLY_SCOPE_SYSTEM]     = "System",
133         [POWER_SUPPLY_SCOPE_DEVICE]     = "Device",
134 };
135
136 static const char * const POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[] = {
137         [POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO]            = "auto",
138         [POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE]  = "inhibit-charge",
139         [POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE] = "force-discharge",
140 };
141
142 static struct power_supply_attr power_supply_attrs[] = {
143         /* Properties of type `int' */
144         POWER_SUPPLY_ENUM_ATTR(STATUS),
145         POWER_SUPPLY_ENUM_ATTR(CHARGE_TYPE),
146         POWER_SUPPLY_ENUM_ATTR(HEALTH),
147         POWER_SUPPLY_ATTR(PRESENT),
148         POWER_SUPPLY_ATTR(ONLINE),
149         POWER_SUPPLY_ATTR(AUTHENTIC),
150         POWER_SUPPLY_ENUM_ATTR(TECHNOLOGY),
151         POWER_SUPPLY_ATTR(CYCLE_COUNT),
152         POWER_SUPPLY_ATTR(VOLTAGE_MAX),
153         POWER_SUPPLY_ATTR(VOLTAGE_MIN),
154         POWER_SUPPLY_ATTR(VOLTAGE_MAX_DESIGN),
155         POWER_SUPPLY_ATTR(VOLTAGE_MIN_DESIGN),
156         POWER_SUPPLY_ATTR(VOLTAGE_NOW),
157         POWER_SUPPLY_ATTR(VOLTAGE_AVG),
158         POWER_SUPPLY_ATTR(VOLTAGE_OCV),
159         POWER_SUPPLY_ATTR(VOLTAGE_BOOT),
160         POWER_SUPPLY_ATTR(CURRENT_MAX),
161         POWER_SUPPLY_ATTR(CURRENT_NOW),
162         POWER_SUPPLY_ATTR(CURRENT_AVG),
163         POWER_SUPPLY_ATTR(CURRENT_BOOT),
164         POWER_SUPPLY_ATTR(POWER_NOW),
165         POWER_SUPPLY_ATTR(POWER_AVG),
166         POWER_SUPPLY_ATTR(CHARGE_FULL_DESIGN),
167         POWER_SUPPLY_ATTR(CHARGE_EMPTY_DESIGN),
168         POWER_SUPPLY_ATTR(CHARGE_FULL),
169         POWER_SUPPLY_ATTR(CHARGE_EMPTY),
170         POWER_SUPPLY_ATTR(CHARGE_NOW),
171         POWER_SUPPLY_ATTR(CHARGE_AVG),
172         POWER_SUPPLY_ATTR(CHARGE_COUNTER),
173         POWER_SUPPLY_ATTR(CONSTANT_CHARGE_CURRENT),
174         POWER_SUPPLY_ATTR(CONSTANT_CHARGE_CURRENT_MAX),
175         POWER_SUPPLY_ATTR(CONSTANT_CHARGE_VOLTAGE),
176         POWER_SUPPLY_ATTR(CONSTANT_CHARGE_VOLTAGE_MAX),
177         POWER_SUPPLY_ATTR(CHARGE_CONTROL_LIMIT),
178         POWER_SUPPLY_ATTR(CHARGE_CONTROL_LIMIT_MAX),
179         POWER_SUPPLY_ATTR(CHARGE_CONTROL_START_THRESHOLD),
180         POWER_SUPPLY_ATTR(CHARGE_CONTROL_END_THRESHOLD),
181         POWER_SUPPLY_ATTR(INPUT_CURRENT_LIMIT),
182         POWER_SUPPLY_ATTR(INPUT_VOLTAGE_LIMIT),
183         POWER_SUPPLY_ATTR(INPUT_POWER_LIMIT),
184         POWER_SUPPLY_ATTR(ENERGY_FULL_DESIGN),
185         POWER_SUPPLY_ATTR(ENERGY_EMPTY_DESIGN),
186         POWER_SUPPLY_ATTR(ENERGY_FULL),
187         POWER_SUPPLY_ATTR(ENERGY_EMPTY),
188         POWER_SUPPLY_ATTR(ENERGY_NOW),
189         POWER_SUPPLY_ATTR(ENERGY_AVG),
190         POWER_SUPPLY_ATTR(CAPACITY),
191         POWER_SUPPLY_ATTR(CAPACITY_ALERT_MIN),
192         POWER_SUPPLY_ATTR(CAPACITY_ALERT_MAX),
193         POWER_SUPPLY_ATTR(CAPACITY_ERROR_MARGIN),
194         POWER_SUPPLY_ENUM_ATTR(CAPACITY_LEVEL),
195         POWER_SUPPLY_ATTR(TEMP),
196         POWER_SUPPLY_ATTR(TEMP_MAX),
197         POWER_SUPPLY_ATTR(TEMP_MIN),
198         POWER_SUPPLY_ATTR(TEMP_ALERT_MIN),
199         POWER_SUPPLY_ATTR(TEMP_ALERT_MAX),
200         POWER_SUPPLY_ATTR(TEMP_AMBIENT),
201         POWER_SUPPLY_ATTR(TEMP_AMBIENT_ALERT_MIN),
202         POWER_SUPPLY_ATTR(TEMP_AMBIENT_ALERT_MAX),
203         POWER_SUPPLY_ATTR(TIME_TO_EMPTY_NOW),
204         POWER_SUPPLY_ATTR(TIME_TO_EMPTY_AVG),
205         POWER_SUPPLY_ATTR(TIME_TO_FULL_NOW),
206         POWER_SUPPLY_ATTR(TIME_TO_FULL_AVG),
207         POWER_SUPPLY_ENUM_ATTR(TYPE),
208         POWER_SUPPLY_ATTR(USB_TYPE),
209         POWER_SUPPLY_ENUM_ATTR(SCOPE),
210         POWER_SUPPLY_ATTR(PRECHARGE_CURRENT),
211         POWER_SUPPLY_ATTR(CHARGE_TERM_CURRENT),
212         POWER_SUPPLY_ATTR(CALIBRATE),
213         POWER_SUPPLY_ATTR(MANUFACTURE_YEAR),
214         POWER_SUPPLY_ATTR(MANUFACTURE_MONTH),
215         POWER_SUPPLY_ATTR(MANUFACTURE_DAY),
216         /* Properties of type `const char *' */
217         POWER_SUPPLY_ATTR(MODEL_NAME),
218         POWER_SUPPLY_ATTR(MANUFACTURER),
219         POWER_SUPPLY_ATTR(SERIAL_NUMBER),
220 };
221
222 static struct attribute *
223 __power_supply_attrs[ARRAY_SIZE(power_supply_attrs) + 1];
224
225 static struct power_supply_attr *to_ps_attr(struct device_attribute *attr)
226 {
227         return container_of(attr, struct power_supply_attr, dev_attr);
228 }
229
230 static enum power_supply_property dev_attr_psp(struct device_attribute *attr)
231 {
232         return  to_ps_attr(attr) - power_supply_attrs;
233 }
234
235 static ssize_t power_supply_show_usb_type(struct device *dev,
236                                           const struct power_supply_desc *desc,
237                                           union power_supply_propval *value,
238                                           char *buf)
239 {
240         enum power_supply_usb_type usb_type;
241         ssize_t count = 0;
242         bool match = false;
243         int i;
244
245         for (i = 0; i < desc->num_usb_types; ++i) {
246                 usb_type = desc->usb_types[i];
247
248                 if (value->intval == usb_type) {
249                         count += sprintf(buf + count, "[%s] ",
250                                          POWER_SUPPLY_USB_TYPE_TEXT[usb_type]);
251                         match = true;
252                 } else {
253                         count += sprintf(buf + count, "%s ",
254                                          POWER_SUPPLY_USB_TYPE_TEXT[usb_type]);
255                 }
256         }
257
258         if (!match) {
259                 dev_warn(dev, "driver reporting unsupported connected type\n");
260                 return -EINVAL;
261         }
262
263         if (count)
264                 buf[count - 1] = '\n';
265
266         return count;
267 }
268
269 static ssize_t power_supply_show_property(struct device *dev,
270                                           struct device_attribute *attr,
271                                           char *buf) {
272         ssize_t ret;
273         struct power_supply *psy = dev_get_drvdata(dev);
274         struct power_supply_attr *ps_attr = to_ps_attr(attr);
275         enum power_supply_property psp = dev_attr_psp(attr);
276         union power_supply_propval value;
277
278         if (psp == POWER_SUPPLY_PROP_TYPE) {
279                 value.intval = psy->desc->type;
280         } else {
281                 ret = power_supply_get_property(psy, psp, &value);
282
283                 if (ret < 0) {
284                         if (ret == -ENODATA)
285                                 dev_dbg(dev, "driver has no data for `%s' property\n",
286                                         attr->attr.name);
287                         else if (ret != -ENODEV && ret != -EAGAIN)
288                                 dev_err_ratelimited(dev,
289                                         "driver failed to report `%s' property: %zd\n",
290                                         attr->attr.name, ret);
291                         return ret;
292                 }
293         }
294
295         if (ps_attr->text_values_len > 0 &&
296             value.intval < ps_attr->text_values_len && value.intval >= 0) {
297                 return sprintf(buf, "%s\n", ps_attr->text_values[value.intval]);
298         }
299
300         switch (psp) {
301         case POWER_SUPPLY_PROP_USB_TYPE:
302                 ret = power_supply_show_usb_type(dev, psy->desc,
303                                                 &value, buf);
304                 break;
305         case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER:
306                 ret = sprintf(buf, "%s\n", value.strval);
307                 break;
308         default:
309                 ret = sprintf(buf, "%d\n", value.intval);
310         }
311
312         return ret;
313 }
314
315 static ssize_t power_supply_store_property(struct device *dev,
316                                            struct device_attribute *attr,
317                                            const char *buf, size_t count) {
318         ssize_t ret;
319         struct power_supply *psy = dev_get_drvdata(dev);
320         struct power_supply_attr *ps_attr = to_ps_attr(attr);
321         enum power_supply_property psp = dev_attr_psp(attr);
322         union power_supply_propval value;
323
324         ret = -EINVAL;
325         if (ps_attr->text_values_len > 0) {
326                 ret = __sysfs_match_string(ps_attr->text_values,
327                                            ps_attr->text_values_len, buf);
328         }
329
330         /*
331          * If no match was found, then check to see if it is an integer.
332          * Integer values are valid for enums in addition to the text value.
333          */
334         if (ret < 0) {
335                 long long_val;
336
337                 ret = kstrtol(buf, 10, &long_val);
338                 if (ret < 0)
339                         return ret;
340
341                 ret = long_val;
342         }
343
344         value.intval = ret;
345
346         ret = power_supply_set_property(psy, psp, &value);
347         if (ret < 0)
348                 return ret;
349
350         return count;
351 }
352
353 static umode_t power_supply_attr_is_visible(struct kobject *kobj,
354                                            struct attribute *attr,
355                                            int attrno)
356 {
357         struct device *dev = kobj_to_dev(kobj);
358         struct power_supply *psy = dev_get_drvdata(dev);
359         umode_t mode = S_IRUSR | S_IRGRP | S_IROTH;
360         int i;
361
362         if (!power_supply_attrs[attrno].prop_name)
363                 return 0;
364
365         if (attrno == POWER_SUPPLY_PROP_TYPE)
366                 return mode;
367
368         for (i = 0; i < psy->desc->num_properties; i++) {
369                 int property = psy->desc->properties[i];
370
371                 if (property == attrno) {
372                         if (psy->desc->property_is_writeable &&
373                             psy->desc->property_is_writeable(psy, property) > 0)
374                                 mode |= S_IWUSR;
375
376                         return mode;
377                 }
378         }
379
380         return 0;
381 }
382
383 static const struct attribute_group power_supply_attr_group = {
384         .attrs = __power_supply_attrs,
385         .is_visible = power_supply_attr_is_visible,
386 };
387
388 static const struct attribute_group *power_supply_attr_groups[] = {
389         &power_supply_attr_group,
390         NULL,
391 };
392
393 static void str_to_lower(char *str)
394 {
395         while (*str) {
396                 *str = tolower(*str);
397                 str++;
398         }
399 }
400
401 void power_supply_init_attrs(struct device_type *dev_type)
402 {
403         int i;
404
405         dev_type->groups = power_supply_attr_groups;
406
407         for (i = 0; i < ARRAY_SIZE(power_supply_attrs); i++) {
408                 struct device_attribute *attr;
409
410                 if (!power_supply_attrs[i].prop_name) {
411                         pr_warn("%s: Property %d skipped because it is missing from power_supply_attrs\n",
412                                 __func__, i);
413                         sprintf(power_supply_attrs[i].attr_name, "_err_%d", i);
414                 } else {
415                         str_to_lower(power_supply_attrs[i].attr_name);
416                 }
417
418                 attr = &power_supply_attrs[i].dev_attr;
419
420                 attr->attr.name = power_supply_attrs[i].attr_name;
421                 attr->show = power_supply_show_property;
422                 attr->store = power_supply_store_property;
423                 __power_supply_attrs[i] = &attr->attr;
424         }
425 }
426
427 static int add_prop_uevent(struct device *dev, struct kobj_uevent_env *env,
428                            enum power_supply_property prop, char *prop_buf)
429 {
430         int ret = 0;
431         struct power_supply_attr *pwr_attr;
432         struct device_attribute *dev_attr;
433         char *line;
434
435         pwr_attr = &power_supply_attrs[prop];
436         dev_attr = &pwr_attr->dev_attr;
437
438         ret = power_supply_show_property(dev, dev_attr, prop_buf);
439         if (ret == -ENODEV || ret == -ENODATA) {
440                 /*
441                  * When a battery is absent, we expect -ENODEV. Don't abort;
442                  * send the uevent with at least the the PRESENT=0 property
443                  */
444                 return 0;
445         }
446
447         if (ret < 0)
448                 return ret;
449
450         line = strchr(prop_buf, '\n');
451         if (line)
452                 *line = 0;
453
454         return add_uevent_var(env, "POWER_SUPPLY_%s=%s",
455                               pwr_attr->prop_name, prop_buf);
456 }
457
458 int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
459 {
460         struct power_supply *psy = dev_get_drvdata(dev);
461         int ret = 0, j;
462         char *prop_buf;
463
464         if (!psy || !psy->desc) {
465                 dev_dbg(dev, "No power supply yet\n");
466                 return ret;
467         }
468
469         ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->desc->name);
470         if (ret)
471                 return ret;
472
473         prop_buf = (char *)get_zeroed_page(GFP_KERNEL);
474         if (!prop_buf)
475                 return -ENOMEM;
476
477         ret = add_prop_uevent(dev, env, POWER_SUPPLY_PROP_TYPE, prop_buf);
478         if (ret)
479                 goto out;
480
481         for (j = 0; j < psy->desc->num_properties; j++) {
482                 ret = add_prop_uevent(dev, env, psy->desc->properties[j],
483                                       prop_buf);
484                 if (ret)
485                         goto out;
486         }
487
488 out:
489         free_page((unsigned long)prop_buf);
490
491         return ret;
492 }
493
494 ssize_t power_supply_charge_behaviour_show(struct device *dev,
495                                            unsigned int available_behaviours,
496                                            enum power_supply_charge_behaviour current_behaviour,
497                                            char *buf)
498 {
499         bool match = false, available, active;
500         ssize_t count = 0;
501         int i;
502
503         for (i = 0; i < ARRAY_SIZE(POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT); i++) {
504                 available = available_behaviours & BIT(i);
505                 active = i == current_behaviour;
506
507                 if (available && active) {
508                         count += sysfs_emit_at(buf, count, "[%s] ",
509                                                POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[i]);
510                         match = true;
511                 } else if (available) {
512                         count += sysfs_emit_at(buf, count, "%s ",
513                                                POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[i]);
514                 }
515         }
516
517         if (!match) {
518                 dev_warn(dev, "driver reporting unsupported charge behaviour\n");
519                 return -EINVAL;
520         }
521
522         if (count)
523                 buf[count - 1] = '\n';
524
525         return count;
526 }
527 EXPORT_SYMBOL_GPL(power_supply_charge_behaviour_show);
528
529 int power_supply_charge_behaviour_parse(unsigned int available_behaviours, const char *buf)
530 {
531         int i = sysfs_match_string(POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT, buf);
532
533         if (i < 0)
534                 return i;
535
536         if (available_behaviours & BIT(i))
537                 return i;
538
539         return -EINVAL;
540 }
541 EXPORT_SYMBOL_GPL(power_supply_charge_behaviour_parse);