18
18
19
19
#include "power_supply.h"
20
20
21
- /*
22
- * This is because the name "current" breaks the device attr macro.
23
- * The "current" word resolves to "(get_current())" so instead of
24
- * "current" "(get_current())" appears in the sysfs.
25
- *
26
- * The source of this definition is the device.h which calls __ATTR
27
- * macro in sysfs.h which calls the __stringify macro.
28
- *
29
- * Only modification that the name is not tried to be resolved
30
- * (as a macro let's say).
31
- */
21
+ #define MAX_PROP_NAME_LEN 30
32
22
33
- #define POWER_SUPPLY_ATTR (_name ) \
34
- { \
35
- .attr = { .name = #_name }, \
36
- .show = power_supply_show_property, \
37
- .store = power_supply_store_property, \
38
- }
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
+ };
39
28
40
- static struct device_attribute power_supply_attrs [];
29
+ #define POWER_SUPPLY_ATTR (_name ) \
30
+ [POWER_SUPPLY_PROP_ ## _name] = \
31
+ { \
32
+ .prop_name = #_name, \
33
+ .attr_name = #_name "\0", \
34
+ }
41
35
42
36
static const char * const power_supply_type_text [] = {
43
37
"Unknown" , "Battery" , "UPS" , "Mains" , "USB" ,
@@ -77,6 +71,91 @@ static const char * const power_supply_scope_text[] = {
77
71
"Unknown" , "System" , "Device"
78
72
};
79
73
74
+ static struct power_supply_attr power_supply_attrs [] = {
75
+ /* Properties of type `int' */
76
+ POWER_SUPPLY_ATTR (STATUS ),
77
+ POWER_SUPPLY_ATTR (CHARGE_TYPE ),
78
+ POWER_SUPPLY_ATTR (HEALTH ),
79
+ POWER_SUPPLY_ATTR (PRESENT ),
80
+ POWER_SUPPLY_ATTR (ONLINE ),
81
+ POWER_SUPPLY_ATTR (AUTHENTIC ),
82
+ POWER_SUPPLY_ATTR (TECHNOLOGY ),
83
+ POWER_SUPPLY_ATTR (CYCLE_COUNT ),
84
+ POWER_SUPPLY_ATTR (VOLTAGE_MAX ),
85
+ POWER_SUPPLY_ATTR (VOLTAGE_MIN ),
86
+ POWER_SUPPLY_ATTR (VOLTAGE_MAX_DESIGN ),
87
+ POWER_SUPPLY_ATTR (VOLTAGE_MIN_DESIGN ),
88
+ POWER_SUPPLY_ATTR (VOLTAGE_NOW ),
89
+ POWER_SUPPLY_ATTR (VOLTAGE_AVG ),
90
+ POWER_SUPPLY_ATTR (VOLTAGE_OCV ),
91
+ POWER_SUPPLY_ATTR (VOLTAGE_BOOT ),
92
+ POWER_SUPPLY_ATTR (CURRENT_MAX ),
93
+ POWER_SUPPLY_ATTR (CURRENT_NOW ),
94
+ POWER_SUPPLY_ATTR (CURRENT_AVG ),
95
+ POWER_SUPPLY_ATTR (CURRENT_BOOT ),
96
+ POWER_SUPPLY_ATTR (POWER_NOW ),
97
+ POWER_SUPPLY_ATTR (POWER_AVG ),
98
+ POWER_SUPPLY_ATTR (CHARGE_FULL_DESIGN ),
99
+ POWER_SUPPLY_ATTR (CHARGE_EMPTY_DESIGN ),
100
+ POWER_SUPPLY_ATTR (CHARGE_FULL ),
101
+ POWER_SUPPLY_ATTR (CHARGE_EMPTY ),
102
+ POWER_SUPPLY_ATTR (CHARGE_NOW ),
103
+ POWER_SUPPLY_ATTR (CHARGE_AVG ),
104
+ POWER_SUPPLY_ATTR (CHARGE_COUNTER ),
105
+ POWER_SUPPLY_ATTR (CONSTANT_CHARGE_CURRENT ),
106
+ POWER_SUPPLY_ATTR (CONSTANT_CHARGE_CURRENT_MAX ),
107
+ POWER_SUPPLY_ATTR (CONSTANT_CHARGE_VOLTAGE ),
108
+ POWER_SUPPLY_ATTR (CONSTANT_CHARGE_VOLTAGE_MAX ),
109
+ POWER_SUPPLY_ATTR (CHARGE_CONTROL_LIMIT ),
110
+ POWER_SUPPLY_ATTR (CHARGE_CONTROL_LIMIT_MAX ),
111
+ POWER_SUPPLY_ATTR (CHARGE_CONTROL_START_THRESHOLD ),
112
+ POWER_SUPPLY_ATTR (CHARGE_CONTROL_END_THRESHOLD ),
113
+ POWER_SUPPLY_ATTR (INPUT_CURRENT_LIMIT ),
114
+ POWER_SUPPLY_ATTR (INPUT_VOLTAGE_LIMIT ),
115
+ POWER_SUPPLY_ATTR (INPUT_POWER_LIMIT ),
116
+ POWER_SUPPLY_ATTR (ENERGY_FULL_DESIGN ),
117
+ POWER_SUPPLY_ATTR (ENERGY_EMPTY_DESIGN ),
118
+ POWER_SUPPLY_ATTR (ENERGY_FULL ),
119
+ POWER_SUPPLY_ATTR (ENERGY_EMPTY ),
120
+ POWER_SUPPLY_ATTR (ENERGY_NOW ),
121
+ POWER_SUPPLY_ATTR (ENERGY_AVG ),
122
+ POWER_SUPPLY_ATTR (CAPACITY ),
123
+ POWER_SUPPLY_ATTR (CAPACITY_ALERT_MIN ),
124
+ POWER_SUPPLY_ATTR (CAPACITY_ALERT_MAX ),
125
+ POWER_SUPPLY_ATTR (CAPACITY_LEVEL ),
126
+ POWER_SUPPLY_ATTR (TEMP ),
127
+ POWER_SUPPLY_ATTR (TEMP_MAX ),
128
+ POWER_SUPPLY_ATTR (TEMP_MIN ),
129
+ POWER_SUPPLY_ATTR (TEMP_ALERT_MIN ),
130
+ POWER_SUPPLY_ATTR (TEMP_ALERT_MAX ),
131
+ POWER_SUPPLY_ATTR (TEMP_AMBIENT ),
132
+ POWER_SUPPLY_ATTR (TEMP_AMBIENT_ALERT_MIN ),
133
+ POWER_SUPPLY_ATTR (TEMP_AMBIENT_ALERT_MAX ),
134
+ POWER_SUPPLY_ATTR (TIME_TO_EMPTY_NOW ),
135
+ POWER_SUPPLY_ATTR (TIME_TO_EMPTY_AVG ),
136
+ POWER_SUPPLY_ATTR (TIME_TO_FULL_NOW ),
137
+ POWER_SUPPLY_ATTR (TIME_TO_FULL_AVG ),
138
+ POWER_SUPPLY_ATTR (TYPE ),
139
+ POWER_SUPPLY_ATTR (USB_TYPE ),
140
+ POWER_SUPPLY_ATTR (SCOPE ),
141
+ POWER_SUPPLY_ATTR (PRECHARGE_CURRENT ),
142
+ POWER_SUPPLY_ATTR (CHARGE_TERM_CURRENT ),
143
+ POWER_SUPPLY_ATTR (CALIBRATE ),
144
+ /* Properties of type `const char *' */
145
+ POWER_SUPPLY_ATTR (MODEL_NAME ),
146
+ POWER_SUPPLY_ATTR (MANUFACTURER ),
147
+ POWER_SUPPLY_ATTR (SERIAL_NUMBER ),
148
+ };
149
+
150
+ static struct attribute *
151
+ __power_supply_attrs [ARRAY_SIZE (power_supply_attrs ) + 1 ];
152
+
153
+ static enum power_supply_property dev_attr_psp (struct device_attribute * attr )
154
+ {
155
+ return container_of (attr , struct power_supply_attr , dev_attr ) -
156
+ power_supply_attrs ;
157
+ }
158
+
80
159
static ssize_t power_supply_show_usb_type (struct device * dev ,
81
160
const struct power_supply_desc * desc ,
82
161
union power_supply_propval * value ,
@@ -116,7 +195,7 @@ static ssize_t power_supply_show_property(struct device *dev,
116
195
char * buf ) {
117
196
ssize_t ret ;
118
197
struct power_supply * psy = dev_get_drvdata (dev );
119
- enum power_supply_property psp = attr - power_supply_attrs ;
198
+ enum power_supply_property psp = dev_attr_psp ( attr ) ;
120
199
union power_supply_propval value ;
121
200
122
201
if (psp == POWER_SUPPLY_PROP_TYPE ) {
@@ -184,7 +263,7 @@ static ssize_t power_supply_store_property(struct device *dev,
184
263
const char * buf , size_t count ) {
185
264
ssize_t ret ;
186
265
struct power_supply * psy = dev_get_drvdata (dev );
187
- enum power_supply_property psp = attr - power_supply_attrs ;
266
+ enum power_supply_property psp = dev_attr_psp ( attr ) ;
188
267
union power_supply_propval value ;
189
268
190
269
switch (psp ) {
@@ -233,86 +312,6 @@ static ssize_t power_supply_store_property(struct device *dev,
233
312
return count ;
234
313
}
235
314
236
- /* Must be in the same order as POWER_SUPPLY_PROP_* */
237
- static struct device_attribute power_supply_attrs [] = {
238
- /* Properties of type `int' */
239
- POWER_SUPPLY_ATTR (status ),
240
- POWER_SUPPLY_ATTR (charge_type ),
241
- POWER_SUPPLY_ATTR (health ),
242
- POWER_SUPPLY_ATTR (present ),
243
- POWER_SUPPLY_ATTR (online ),
244
- POWER_SUPPLY_ATTR (authentic ),
245
- POWER_SUPPLY_ATTR (technology ),
246
- POWER_SUPPLY_ATTR (cycle_count ),
247
- POWER_SUPPLY_ATTR (voltage_max ),
248
- POWER_SUPPLY_ATTR (voltage_min ),
249
- POWER_SUPPLY_ATTR (voltage_max_design ),
250
- POWER_SUPPLY_ATTR (voltage_min_design ),
251
- POWER_SUPPLY_ATTR (voltage_now ),
252
- POWER_SUPPLY_ATTR (voltage_avg ),
253
- POWER_SUPPLY_ATTR (voltage_ocv ),
254
- POWER_SUPPLY_ATTR (voltage_boot ),
255
- POWER_SUPPLY_ATTR (current_max ),
256
- POWER_SUPPLY_ATTR (current_now ),
257
- POWER_SUPPLY_ATTR (current_avg ),
258
- POWER_SUPPLY_ATTR (current_boot ),
259
- POWER_SUPPLY_ATTR (power_now ),
260
- POWER_SUPPLY_ATTR (power_avg ),
261
- POWER_SUPPLY_ATTR (charge_full_design ),
262
- POWER_SUPPLY_ATTR (charge_empty_design ),
263
- POWER_SUPPLY_ATTR (charge_full ),
264
- POWER_SUPPLY_ATTR (charge_empty ),
265
- POWER_SUPPLY_ATTR (charge_now ),
266
- POWER_SUPPLY_ATTR (charge_avg ),
267
- POWER_SUPPLY_ATTR (charge_counter ),
268
- POWER_SUPPLY_ATTR (constant_charge_current ),
269
- POWER_SUPPLY_ATTR (constant_charge_current_max ),
270
- POWER_SUPPLY_ATTR (constant_charge_voltage ),
271
- POWER_SUPPLY_ATTR (constant_charge_voltage_max ),
272
- POWER_SUPPLY_ATTR (charge_control_limit ),
273
- POWER_SUPPLY_ATTR (charge_control_limit_max ),
274
- POWER_SUPPLY_ATTR (charge_control_start_threshold ),
275
- POWER_SUPPLY_ATTR (charge_control_end_threshold ),
276
- POWER_SUPPLY_ATTR (input_current_limit ),
277
- POWER_SUPPLY_ATTR (input_voltage_limit ),
278
- POWER_SUPPLY_ATTR (input_power_limit ),
279
- POWER_SUPPLY_ATTR (energy_full_design ),
280
- POWER_SUPPLY_ATTR (energy_empty_design ),
281
- POWER_SUPPLY_ATTR (energy_full ),
282
- POWER_SUPPLY_ATTR (energy_empty ),
283
- POWER_SUPPLY_ATTR (energy_now ),
284
- POWER_SUPPLY_ATTR (energy_avg ),
285
- POWER_SUPPLY_ATTR (capacity ),
286
- POWER_SUPPLY_ATTR (capacity_alert_min ),
287
- POWER_SUPPLY_ATTR (capacity_alert_max ),
288
- POWER_SUPPLY_ATTR (capacity_level ),
289
- POWER_SUPPLY_ATTR (temp ),
290
- POWER_SUPPLY_ATTR (temp_max ),
291
- POWER_SUPPLY_ATTR (temp_min ),
292
- POWER_SUPPLY_ATTR (temp_alert_min ),
293
- POWER_SUPPLY_ATTR (temp_alert_max ),
294
- POWER_SUPPLY_ATTR (temp_ambient ),
295
- POWER_SUPPLY_ATTR (temp_ambient_alert_min ),
296
- POWER_SUPPLY_ATTR (temp_ambient_alert_max ),
297
- POWER_SUPPLY_ATTR (time_to_empty_now ),
298
- POWER_SUPPLY_ATTR (time_to_empty_avg ),
299
- POWER_SUPPLY_ATTR (time_to_full_now ),
300
- POWER_SUPPLY_ATTR (time_to_full_avg ),
301
- POWER_SUPPLY_ATTR (type ),
302
- POWER_SUPPLY_ATTR (usb_type ),
303
- POWER_SUPPLY_ATTR (scope ),
304
- POWER_SUPPLY_ATTR (precharge_current ),
305
- POWER_SUPPLY_ATTR (charge_term_current ),
306
- POWER_SUPPLY_ATTR (calibrate ),
307
- /* Properties of type `const char *' */
308
- POWER_SUPPLY_ATTR (model_name ),
309
- POWER_SUPPLY_ATTR (manufacturer ),
310
- POWER_SUPPLY_ATTR (serial_number ),
311
- };
312
-
313
- static struct attribute *
314
- __power_supply_attrs [ARRAY_SIZE (power_supply_attrs ) + 1 ];
315
-
316
315
static umode_t power_supply_attr_is_visible (struct kobject * kobj ,
317
316
struct attribute * attr ,
318
317
int attrno )
@@ -322,6 +321,9 @@ static umode_t power_supply_attr_is_visible(struct kobject *kobj,
322
321
umode_t mode = S_IRUSR | S_IRGRP | S_IROTH ;
323
322
int i ;
324
323
324
+ if (!power_supply_attrs [attrno ].prop_name )
325
+ return 0 ;
326
+
325
327
if (attrno == POWER_SUPPLY_PROP_TYPE )
326
328
return mode ;
327
329
@@ -350,39 +352,45 @@ static const struct attribute_group *power_supply_attr_groups[] = {
350
352
NULL ,
351
353
};
352
354
353
- void power_supply_init_attrs ( struct device_type * dev_type )
355
+ static void str_to_lower ( char * str )
354
356
{
355
- int i ;
356
-
357
- dev_type -> groups = power_supply_attr_groups ;
358
-
359
- for (i = 0 ; i < ARRAY_SIZE (power_supply_attrs ); i ++ )
360
- __power_supply_attrs [i ] = & power_supply_attrs [i ].attr ;
357
+ while (* str ) {
358
+ * str = tolower (* str );
359
+ str ++ ;
360
+ }
361
361
}
362
362
363
- static char * kstruprdup ( const char * str , gfp_t gfp )
363
+ void power_supply_init_attrs ( struct device_type * dev_type )
364
364
{
365
- char * ret , * ustr ;
365
+ int i ;
366
366
367
- ustr = ret = kmalloc ( strlen ( str ) + 1 , gfp ) ;
367
+ dev_type -> groups = power_supply_attr_groups ;
368
368
369
- if (! ret )
370
- return NULL ;
369
+ for ( i = 0 ; i < ARRAY_SIZE ( power_supply_attrs ); i ++ ) {
370
+ struct device_attribute * attr ;
371
371
372
- while (* str )
373
- * ustr ++ = toupper (* str ++ );
372
+ if (!power_supply_attrs [i ].prop_name ) {
373
+ pr_warn ("%s: Property %d skipped because is is missing from power_supply_attrs\n" ,
374
+ __func__ , i );
375
+ sprintf (power_supply_attrs [i ].attr_name , "_err_%d" , i );
376
+ } else {
377
+ str_to_lower (power_supply_attrs [i ].attr_name );
378
+ }
374
379
375
- * ustr = 0 ;
380
+ attr = & power_supply_attrs [ i ]. dev_attr ;
376
381
377
- return ret ;
382
+ attr -> attr .name = power_supply_attrs [i ].attr_name ;
383
+ attr -> show = power_supply_show_property ;
384
+ attr -> store = power_supply_store_property ;
385
+ __power_supply_attrs [i ] = & attr -> attr ;
386
+ }
378
387
}
379
388
380
389
int power_supply_uevent (struct device * dev , struct kobj_uevent_env * env )
381
390
{
382
391
struct power_supply * psy = dev_get_drvdata (dev );
383
392
int ret = 0 , j ;
384
393
char * prop_buf ;
385
- char * attrname ;
386
394
387
395
if (!psy || !psy -> desc ) {
388
396
dev_dbg (dev , "No power supply yet\n" );
@@ -398,12 +406,14 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
398
406
return - ENOMEM ;
399
407
400
408
for (j = 0 ; j < psy -> desc -> num_properties ; j ++ ) {
401
- struct device_attribute * attr ;
409
+ struct power_supply_attr * pwr_attr ;
410
+ struct device_attribute * dev_attr ;
402
411
char * line ;
403
412
404
- attr = & power_supply_attrs [psy -> desc -> properties [j ]];
413
+ pwr_attr = & power_supply_attrs [psy -> desc -> properties [j ]];
414
+ dev_attr = & pwr_attr -> dev_attr ;
405
415
406
- ret = power_supply_show_property (dev , attr , prop_buf );
416
+ ret = power_supply_show_property (dev , dev_attr , prop_buf );
407
417
if (ret == - ENODEV || ret == - ENODATA ) {
408
418
/* When a battery is absent, we expect -ENODEV. Don't abort;
409
419
send the uevent with at least the the PRESENT=0 property */
@@ -418,14 +428,8 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
418
428
if (line )
419
429
* line = 0 ;
420
430
421
- attrname = kstruprdup (attr -> attr .name , GFP_KERNEL );
422
- if (!attrname ) {
423
- ret = - ENOMEM ;
424
- goto out ;
425
- }
426
-
427
- ret = add_uevent_var (env , "POWER_SUPPLY_%s=%s" , attrname , prop_buf );
428
- kfree (attrname );
431
+ ret = add_uevent_var (env , "POWER_SUPPLY_%s=%s" ,
432
+ pwr_attr -> prop_name , prop_buf );
429
433
if (ret )
430
434
goto out ;
431
435
}
0 commit comments