min/max: remove sparse warnings when they're nested
[cascardo/linux.git] / drivers / staging / greybus / power_supply.c
1 /*
2  * Power Supply driver for a Greybus module.
3  *
4  * Copyright 2014-2015 Google Inc.
5  * Copyright 2014-2015 Linaro Ltd.
6  *
7  * Released under the GPLv2 only.
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/power_supply.h>
13 #include <linux/slab.h>
14
15 #include "greybus.h"
16
17 #define PROP_MAX 32
18
19 struct gb_power_supply_prop {
20         enum power_supply_property      prop;
21         u8                              gb_prop;
22         int                             val;
23         int                             previous_val;
24         bool                            is_writeable;
25 };
26
27 struct gb_power_supply {
28         u8                              id;
29         bool                            registered;
30         struct power_supply             *psy;
31         struct power_supply_desc        desc;
32         char                            name[64];
33         struct gb_power_supplies        *supplies;
34         struct delayed_work             work;
35         char                            *manufacturer;
36         char                            *model_name;
37         char                            *serial_number;
38         u8                              type;
39         u8                              properties_count;
40         u8                              properties_count_str;
41         unsigned long                   last_update;
42         u8                              cache_invalid;
43         unsigned int                    update_interval;
44         bool                            changed;
45         struct gb_power_supply_prop     *props;
46         enum power_supply_property      *props_raw;
47         bool                            pm_acquired;
48         struct mutex                    supply_lock;
49 };
50
51 struct gb_power_supplies {
52         struct gb_connection    *connection;
53         u8                      supplies_count;
54         struct gb_power_supply  *supply;
55         struct mutex            supplies_lock;
56 };
57
58 #define to_gb_power_supply(x) power_supply_get_drvdata(x)
59
60 /*
61  * General power supply properties that could be absent from various reasons,
62  * like kernel versions or vendor specific versions
63  */
64 #ifndef POWER_SUPPLY_PROP_VOLTAGE_BOOT
65         #define POWER_SUPPLY_PROP_VOLTAGE_BOOT  -1
66 #endif
67 #ifndef POWER_SUPPLY_PROP_CURRENT_BOOT
68         #define POWER_SUPPLY_PROP_CURRENT_BOOT  -1
69 #endif
70 #ifndef POWER_SUPPLY_PROP_CALIBRATE
71         #define POWER_SUPPLY_PROP_CALIBRATE     -1
72 #endif
73
74 /* cache time in milliseconds, if cache_time is set to 0 cache is disable */
75 static unsigned int cache_time = 1000;
76 /*
77  * update interval initial and maximum value, between the two will
78  * back-off exponential
79  */
80 static unsigned int update_interval_init = 1 * HZ;
81 static unsigned int update_interval_max = 30 * HZ;
82
83 struct gb_power_supply_changes {
84         enum power_supply_property      prop;
85         u32                             tolerance_change;
86         void (*prop_changed)(struct gb_power_supply *gbpsy,
87                              struct gb_power_supply_prop *prop);
88 };
89
90 static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
91                                          struct gb_power_supply_prop *prop);
92
93 static const struct gb_power_supply_changes psy_props_changes[] = {
94         {       .prop                   = GB_POWER_SUPPLY_PROP_STATUS,
95                 .tolerance_change       = 0,
96                 .prop_changed           = gb_power_supply_state_change,
97         },
98         {       .prop                   = GB_POWER_SUPPLY_PROP_TEMP,
99                 .tolerance_change       = 500,
100                 .prop_changed           = NULL,
101         },
102         {       .prop                   = GB_POWER_SUPPLY_PROP_ONLINE,
103                 .tolerance_change       = 0,
104                 .prop_changed           = NULL,
105         },
106 };
107
108 static int get_psp_from_gb_prop(int gb_prop, enum power_supply_property *psp)
109 {
110         int prop;
111
112         switch (gb_prop) {
113         case GB_POWER_SUPPLY_PROP_STATUS:
114                 prop = POWER_SUPPLY_PROP_STATUS;
115                 break;
116         case GB_POWER_SUPPLY_PROP_CHARGE_TYPE:
117                 prop = POWER_SUPPLY_PROP_CHARGE_TYPE;
118                 break;
119         case GB_POWER_SUPPLY_PROP_HEALTH:
120                 prop = POWER_SUPPLY_PROP_HEALTH;
121                 break;
122         case GB_POWER_SUPPLY_PROP_PRESENT:
123                 prop = POWER_SUPPLY_PROP_PRESENT;
124                 break;
125         case GB_POWER_SUPPLY_PROP_ONLINE:
126                 prop = POWER_SUPPLY_PROP_ONLINE;
127                 break;
128         case GB_POWER_SUPPLY_PROP_AUTHENTIC:
129                 prop = POWER_SUPPLY_PROP_AUTHENTIC;
130                 break;
131         case GB_POWER_SUPPLY_PROP_TECHNOLOGY:
132                 prop = POWER_SUPPLY_PROP_TECHNOLOGY;
133                 break;
134         case GB_POWER_SUPPLY_PROP_CYCLE_COUNT:
135                 prop = POWER_SUPPLY_PROP_CYCLE_COUNT;
136                 break;
137         case GB_POWER_SUPPLY_PROP_VOLTAGE_MAX:
138                 prop = POWER_SUPPLY_PROP_VOLTAGE_MAX;
139                 break;
140         case GB_POWER_SUPPLY_PROP_VOLTAGE_MIN:
141                 prop = POWER_SUPPLY_PROP_VOLTAGE_MIN;
142                 break;
143         case GB_POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
144                 prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN;
145                 break;
146         case GB_POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
147                 prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN;
148                 break;
149         case GB_POWER_SUPPLY_PROP_VOLTAGE_NOW:
150                 prop = POWER_SUPPLY_PROP_VOLTAGE_NOW;
151                 break;
152         case GB_POWER_SUPPLY_PROP_VOLTAGE_AVG:
153                 prop = POWER_SUPPLY_PROP_VOLTAGE_AVG;
154                 break;
155         case GB_POWER_SUPPLY_PROP_VOLTAGE_OCV:
156                 prop = POWER_SUPPLY_PROP_VOLTAGE_OCV;
157                 break;
158         case GB_POWER_SUPPLY_PROP_VOLTAGE_BOOT:
159                 prop = POWER_SUPPLY_PROP_VOLTAGE_BOOT;
160                 break;
161         case GB_POWER_SUPPLY_PROP_CURRENT_MAX:
162                 prop = POWER_SUPPLY_PROP_CURRENT_MAX;
163                 break;
164         case GB_POWER_SUPPLY_PROP_CURRENT_NOW:
165                 prop = POWER_SUPPLY_PROP_CURRENT_NOW;
166                 break;
167         case GB_POWER_SUPPLY_PROP_CURRENT_AVG:
168                 prop = POWER_SUPPLY_PROP_CURRENT_AVG;
169                 break;
170         case GB_POWER_SUPPLY_PROP_CURRENT_BOOT:
171                 prop = POWER_SUPPLY_PROP_CURRENT_BOOT;
172                 break;
173         case GB_POWER_SUPPLY_PROP_POWER_NOW:
174                 prop = POWER_SUPPLY_PROP_POWER_NOW;
175                 break;
176         case GB_POWER_SUPPLY_PROP_POWER_AVG:
177                 prop = POWER_SUPPLY_PROP_POWER_AVG;
178                 break;
179         case GB_POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
180                 prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
181                 break;
182         case GB_POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
183                 prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN;
184                 break;
185         case GB_POWER_SUPPLY_PROP_CHARGE_FULL:
186                 prop = POWER_SUPPLY_PROP_CHARGE_FULL;
187                 break;
188         case GB_POWER_SUPPLY_PROP_CHARGE_EMPTY:
189                 prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
190                 break;
191         case GB_POWER_SUPPLY_PROP_CHARGE_NOW:
192                 prop = POWER_SUPPLY_PROP_CHARGE_NOW;
193                 break;
194         case GB_POWER_SUPPLY_PROP_CHARGE_AVG:
195                 prop = POWER_SUPPLY_PROP_CHARGE_AVG;
196                 break;
197         case GB_POWER_SUPPLY_PROP_CHARGE_COUNTER:
198                 prop = POWER_SUPPLY_PROP_CHARGE_COUNTER;
199                 break;
200         case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
201                 prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT;
202                 break;
203         case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
204                 prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
205                 break;
206         case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
207                 prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE;
208                 break;
209         case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
210                 prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX;
211                 break;
212         case GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
213                 prop = POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT;
214                 break;
215         case GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX:
216                 prop = POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX;
217                 break;
218         case GB_POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
219                 prop = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
220                 break;
221         case GB_POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
222                 prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
223                 break;
224         case GB_POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN:
225                 prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN;
226                 break;
227         case GB_POWER_SUPPLY_PROP_ENERGY_FULL:
228                 prop = POWER_SUPPLY_PROP_ENERGY_FULL;
229                 break;
230         case GB_POWER_SUPPLY_PROP_ENERGY_EMPTY:
231                 prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
232                 break;
233         case GB_POWER_SUPPLY_PROP_ENERGY_NOW:
234                 prop = POWER_SUPPLY_PROP_ENERGY_NOW;
235                 break;
236         case GB_POWER_SUPPLY_PROP_ENERGY_AVG:
237                 prop = POWER_SUPPLY_PROP_ENERGY_AVG;
238                 break;
239         case GB_POWER_SUPPLY_PROP_CAPACITY:
240                 prop = POWER_SUPPLY_PROP_CAPACITY;
241                 break;
242         case GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
243                 prop = POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN;
244                 break;
245         case GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX:
246                 prop = POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX;
247                 break;
248         case GB_POWER_SUPPLY_PROP_CAPACITY_LEVEL:
249                 prop = POWER_SUPPLY_PROP_CAPACITY_LEVEL;
250                 break;
251         case GB_POWER_SUPPLY_PROP_TEMP:
252                 prop = POWER_SUPPLY_PROP_TEMP;
253                 break;
254         case GB_POWER_SUPPLY_PROP_TEMP_MAX:
255                 prop = POWER_SUPPLY_PROP_TEMP_MAX;
256                 break;
257         case GB_POWER_SUPPLY_PROP_TEMP_MIN:
258                 prop = POWER_SUPPLY_PROP_TEMP_MIN;
259                 break;
260         case GB_POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
261                 prop = POWER_SUPPLY_PROP_TEMP_ALERT_MIN;
262                 break;
263         case GB_POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
264                 prop = POWER_SUPPLY_PROP_TEMP_ALERT_MAX;
265                 break;
266         case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT:
267                 prop = POWER_SUPPLY_PROP_TEMP_AMBIENT;
268                 break;
269         case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
270                 prop = POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN;
271                 break;
272         case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
273                 prop = POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX;
274                 break;
275         case GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
276                 prop = POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW;
277                 break;
278         case GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
279                 prop = POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG;
280                 break;
281         case GB_POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
282                 prop = POWER_SUPPLY_PROP_TIME_TO_FULL_NOW;
283                 break;
284         case GB_POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
285                 prop = POWER_SUPPLY_PROP_TIME_TO_FULL_AVG;
286                 break;
287         case GB_POWER_SUPPLY_PROP_TYPE:
288                 prop = POWER_SUPPLY_PROP_TYPE;
289                 break;
290         case GB_POWER_SUPPLY_PROP_SCOPE:
291                 prop = POWER_SUPPLY_PROP_SCOPE;
292                 break;
293         case GB_POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
294                 prop = POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT;
295                 break;
296         case GB_POWER_SUPPLY_PROP_CALIBRATE:
297                 prop = POWER_SUPPLY_PROP_CALIBRATE;
298                 break;
299         default:
300                 prop = -1;
301                 break;
302         }
303
304         if (prop < 0)
305                 return prop;
306
307         *psp = (enum power_supply_property)prop;
308
309         return 0;
310 }
311
312 static struct gb_connection *get_conn_from_psy(struct gb_power_supply *gbpsy)
313 {
314         return gbpsy->supplies->connection;
315 }
316
317 static struct gb_power_supply_prop *get_psy_prop(struct gb_power_supply *gbpsy,
318                                                  enum power_supply_property psp)
319 {
320         int i;
321
322         for (i = 0; i < gbpsy->properties_count; i++)
323                 if (gbpsy->props[i].prop == psp)
324                         return &gbpsy->props[i];
325         return NULL;
326 }
327
328 static int is_psy_prop_writeable(struct gb_power_supply *gbpsy,
329                                      enum power_supply_property psp)
330 {
331         struct gb_power_supply_prop *prop;
332
333         prop = get_psy_prop(gbpsy, psp);
334         if (!prop)
335                 return -ENOENT;
336         return prop->is_writeable ? 1 : 0;
337 }
338
339 static int is_prop_valint(enum power_supply_property psp)
340 {
341         return ((psp < POWER_SUPPLY_PROP_MODEL_NAME) ? 1 : 0);
342 }
343
344 static void next_interval(struct gb_power_supply *gbpsy)
345 {
346         if (gbpsy->update_interval == update_interval_max)
347                 return;
348
349         /* do some exponential back-off in the update interval */
350         gbpsy->update_interval *= 2;
351         if (gbpsy->update_interval > update_interval_max)
352                 gbpsy->update_interval = update_interval_max;
353 }
354
355 static void __gb_power_supply_changed(struct gb_power_supply *gbpsy)
356 {
357         power_supply_changed(gbpsy->psy);
358 }
359
360 static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
361                                          struct gb_power_supply_prop *prop)
362 {
363         struct gb_connection *connection = get_conn_from_psy(gbpsy);
364         int ret;
365
366         /*
367          * Check gbpsy->pm_acquired to make sure only one pair of 'get_sync'
368          * and 'put_autosuspend' runtime pm call for state property change.
369          */
370         mutex_lock(&gbpsy->supply_lock);
371
372         if ((prop->val == GB_POWER_SUPPLY_STATUS_CHARGING) &&
373             !gbpsy->pm_acquired) {
374                 ret = gb_pm_runtime_get_sync(connection->bundle);
375                 if (ret)
376                         dev_err(&connection->bundle->dev,
377                                 "Fail to set wake lock for charging state\n");
378                 else
379                         gbpsy->pm_acquired = true;
380         } else {
381                 if (gbpsy->pm_acquired) {
382                         ret = gb_pm_runtime_put_autosuspend(connection->bundle);
383                         if (ret)
384                                 dev_err(&connection->bundle->dev,
385                                         "Fail to set wake unlock for none charging\n");
386                         else
387                                 gbpsy->pm_acquired = false;
388                 }
389         }
390
391         mutex_unlock(&gbpsy->supply_lock);
392 }
393
394 static void check_changed(struct gb_power_supply *gbpsy,
395                           struct gb_power_supply_prop *prop)
396 {
397         const struct gb_power_supply_changes *psyc;
398         int val = prop->val;
399         int prev_val = prop->previous_val;
400         bool changed = false;
401         int i;
402
403         for (i = 0; i < ARRAY_SIZE(psy_props_changes); i++) {
404                 psyc = &psy_props_changes[i];
405                 if (prop->prop == psyc->prop) {
406                         if (!psyc->tolerance_change)
407                                 changed = true;
408                         else if (val < prev_val &&
409                                  prev_val - val > psyc->tolerance_change)
410                                 changed = true;
411                         else if (val > prev_val &&
412                                  val - prev_val > psyc->tolerance_change)
413                                 changed = true;
414
415                         if (changed && psyc->prop_changed)
416                                 psyc->prop_changed(gbpsy, prop);
417
418                         if (changed)
419                                 gbpsy->changed = true;
420                         break;
421                 }
422         }
423 }
424
425 static int total_props(struct gb_power_supply *gbpsy)
426 {
427         /* this return the intval plus the strval properties */
428         return (gbpsy->properties_count + gbpsy->properties_count_str);
429 }
430
431 static void prop_append(struct gb_power_supply *gbpsy,
432                         enum power_supply_property prop)
433 {
434         enum power_supply_property *new_props_raw;
435
436         gbpsy->properties_count_str++;
437         new_props_raw = krealloc(gbpsy->props_raw, total_props(gbpsy) *
438                                  sizeof(enum power_supply_property),
439                                  GFP_KERNEL);
440         if (!new_props_raw)
441                 return;
442         gbpsy->props_raw = new_props_raw;
443         gbpsy->props_raw[total_props(gbpsy) - 1] = prop;
444 }
445
446 static int __gb_power_supply_set_name(char *init_name, char *name, size_t len)
447 {
448         unsigned int i = 0;
449         int ret = 0;
450         struct power_supply *psy;
451
452         if (!strlen(init_name))
453                 init_name = "gb_power_supply";
454         strlcpy(name, init_name, len);
455
456         while ((ret < len) && (psy = power_supply_get_by_name(name))) {
457                 power_supply_put(psy);
458
459                 ret = snprintf(name, len, "%s_%u", init_name, ++i);
460         }
461         if (ret >= len)
462                 return -ENOMEM;
463         return i;
464 }
465
466 static void _gb_power_supply_append_props(struct gb_power_supply *gbpsy)
467 {
468         if (strlen(gbpsy->manufacturer))
469                 prop_append(gbpsy, POWER_SUPPLY_PROP_MANUFACTURER);
470         if (strlen(gbpsy->model_name))
471                 prop_append(gbpsy, POWER_SUPPLY_PROP_MODEL_NAME);
472         if (strlen(gbpsy->serial_number))
473                 prop_append(gbpsy, POWER_SUPPLY_PROP_SERIAL_NUMBER);
474 }
475
476 static int gb_power_supply_description_get(struct gb_power_supply *gbpsy)
477 {
478         struct gb_connection *connection = get_conn_from_psy(gbpsy);
479         struct gb_power_supply_get_description_request req;
480         struct gb_power_supply_get_description_response resp;
481         int ret;
482
483         req.psy_id = gbpsy->id;
484
485         ret = gb_operation_sync(connection,
486                                 GB_POWER_SUPPLY_TYPE_GET_DESCRIPTION,
487                                 &req, sizeof(req), &resp, sizeof(resp));
488         if (ret < 0)
489                 return ret;
490
491         gbpsy->manufacturer = kstrndup(resp.manufacturer, PROP_MAX, GFP_KERNEL);
492         if (!gbpsy->manufacturer)
493                 return -ENOMEM;
494         gbpsy->model_name = kstrndup(resp.model, PROP_MAX, GFP_KERNEL);
495         if (!gbpsy->model_name)
496                 return -ENOMEM;
497         gbpsy->serial_number = kstrndup(resp.serial_number, PROP_MAX,
498                                        GFP_KERNEL);
499         if (!gbpsy->serial_number)
500                 return -ENOMEM;
501
502         gbpsy->type = le16_to_cpu(resp.type);
503         gbpsy->properties_count = resp.properties_count;
504
505         return 0;
506 }
507
508 static int gb_power_supply_prop_descriptors_get(struct gb_power_supply *gbpsy)
509 {
510         struct gb_connection *connection = get_conn_from_psy(gbpsy);
511         struct gb_power_supply_get_property_descriptors_request *req;
512         struct gb_power_supply_get_property_descriptors_response *resp;
513         struct gb_operation *op;
514         u8 props_count = gbpsy->properties_count;
515         enum power_supply_property psp;
516         int ret;
517         int i, r = 0;
518
519         if (props_count == 0)
520                 return 0;
521
522         op = gb_operation_create(connection,
523                                  GB_POWER_SUPPLY_TYPE_GET_PROP_DESCRIPTORS,
524                                  sizeof(req), sizeof(*resp) + props_count *
525                                  sizeof(struct gb_power_supply_props_desc),
526                                  GFP_KERNEL);
527         if (!op)
528                 return -ENOMEM;
529
530         req = op->request->payload;
531         req->psy_id = gbpsy->id;
532
533         ret = gb_operation_request_send_sync(op);
534         if (ret < 0)
535                 goto out_put_operation;
536
537         resp = op->response->payload;
538
539         /* validate received properties */
540         for (i = 0; i < props_count; i++) {
541                 ret = get_psp_from_gb_prop(resp->props[i].property, &psp);
542                 if (ret < 0) {
543                         dev_warn(&connection->bundle->dev,
544                                  "greybus property %u it is not supported by this kernel, dropped\n",
545                                  resp->props[i].property);
546                         gbpsy->properties_count--;
547                 }
548         }
549
550         gbpsy->props = kcalloc(gbpsy->properties_count, sizeof(*gbpsy->props),
551                               GFP_KERNEL);
552         if (!gbpsy->props) {
553                 ret = -ENOMEM;
554                 goto out_put_operation;
555         }
556
557         gbpsy->props_raw = kcalloc(gbpsy->properties_count,
558                                    sizeof(*gbpsy->props_raw), GFP_KERNEL);
559         if (!gbpsy->props_raw) {
560                 ret = -ENOMEM;
561                 goto out_put_operation;
562         }
563
564         /* Store available properties, skip the ones we do not support */
565         for (i = 0; i < props_count; i++) {
566                 ret = get_psp_from_gb_prop(resp->props[i].property, &psp);
567                 if (ret < 0) {
568                         r++;
569                         continue;
570                 }
571                 gbpsy->props[i - r].prop = psp;
572                 gbpsy->props[i - r].gb_prop = resp->props[i].property;
573                 gbpsy->props_raw[i - r] = psp;
574                 if (resp->props[i].is_writeable)
575                         gbpsy->props[i - r].is_writeable = true;
576         }
577
578         /*
579          * now append the properties that we already got information in the
580          * get_description operation. (char * ones)
581          */
582         _gb_power_supply_append_props(gbpsy);
583
584         ret = 0;
585 out_put_operation:
586         gb_operation_put(op);
587
588         return ret;
589 }
590
591 static int __gb_power_supply_property_update(struct gb_power_supply *gbpsy,
592                                              enum power_supply_property psp)
593 {
594         struct gb_connection *connection = get_conn_from_psy(gbpsy);
595         struct gb_power_supply_prop *prop;
596         struct gb_power_supply_get_property_request req;
597         struct gb_power_supply_get_property_response resp;
598         int val;
599         int ret;
600
601         prop = get_psy_prop(gbpsy, psp);
602         if (!prop)
603                 return -EINVAL;
604         req.psy_id = gbpsy->id;
605         req.property = prop->gb_prop;
606
607         ret = gb_operation_sync(connection, GB_POWER_SUPPLY_TYPE_GET_PROPERTY,
608                                 &req, sizeof(req), &resp, sizeof(resp));
609         if (ret < 0)
610                 return ret;
611
612         val = le32_to_cpu(resp.prop_val);
613         if (val == prop->val)
614                 return 0;
615
616         prop->previous_val = prop->val;
617         prop->val = val;
618
619         check_changed(gbpsy, prop);
620
621         return 0;
622 }
623
624 static int __gb_power_supply_property_get(struct gb_power_supply *gbpsy,
625                                           enum power_supply_property psp,
626                                           union power_supply_propval *val)
627 {
628         struct gb_power_supply_prop *prop;
629
630         prop = get_psy_prop(gbpsy, psp);
631         if (!prop)
632                 return -EINVAL;
633
634         val->intval = prop->val;
635         return 0;
636 }
637
638 static int __gb_power_supply_property_strval_get(struct gb_power_supply *gbpsy,
639                                                 enum power_supply_property psp,
640                                                 union power_supply_propval *val)
641 {
642         switch (psp) {
643         case POWER_SUPPLY_PROP_MODEL_NAME:
644                 val->strval = gbpsy->model_name;
645                 break;
646         case POWER_SUPPLY_PROP_MANUFACTURER:
647                 val->strval = gbpsy->manufacturer;
648                 break;
649         case POWER_SUPPLY_PROP_SERIAL_NUMBER:
650                 val->strval = gbpsy->serial_number;
651                 break;
652         default:
653                 break;
654         }
655
656         return 0;
657 }
658
659 static int _gb_power_supply_property_get(struct gb_power_supply *gbpsy,
660                                          enum power_supply_property psp,
661                                          union power_supply_propval *val)
662 {
663         struct gb_connection *connection = get_conn_from_psy(gbpsy);
664         int ret;
665
666         /*
667          * Properties of type const char *, were already fetched on
668          * get_description operation and should be cached in gb
669          */
670         if (is_prop_valint(psp))
671                 ret = __gb_power_supply_property_get(gbpsy, psp, val);
672         else
673                 ret = __gb_power_supply_property_strval_get(gbpsy, psp, val);
674
675         if (ret < 0)
676                 dev_err(&connection->bundle->dev, "get property %u\n", psp);
677
678         return 0;
679 }
680
681 static int is_cache_valid(struct gb_power_supply *gbpsy)
682 {
683         /* check if cache is good enough or it has expired */
684         if (gbpsy->cache_invalid) {
685                 gbpsy->cache_invalid = 0;
686                 return 0;
687         }
688
689         if (gbpsy->last_update &&
690             time_is_after_jiffies(gbpsy->last_update +
691                                   msecs_to_jiffies(cache_time)))
692                 return 1;
693
694         return 0;
695 }
696
697 static int gb_power_supply_status_get(struct gb_power_supply *gbpsy)
698 {
699         struct gb_connection *connection = get_conn_from_psy(gbpsy);
700         int ret = 0;
701         int i;
702
703         if (is_cache_valid(gbpsy))
704                 return 0;
705
706         ret = gb_pm_runtime_get_sync(connection->bundle);
707         if (ret)
708                 return ret;
709
710         for (i = 0; i < gbpsy->properties_count; i++) {
711                 ret = __gb_power_supply_property_update(gbpsy,
712                                                         gbpsy->props[i].prop);
713                 if (ret < 0)
714                         break;
715         }
716
717         if (ret == 0)
718                 gbpsy->last_update = jiffies;
719
720         gb_pm_runtime_put_autosuspend(connection->bundle);
721         return ret;
722 }
723
724 static void gb_power_supply_status_update(struct gb_power_supply *gbpsy)
725 {
726         /* check if there a change that need to be reported */
727         gb_power_supply_status_get(gbpsy);
728
729         if (!gbpsy->changed)
730                 return;
731
732         gbpsy->update_interval = update_interval_init;
733         __gb_power_supply_changed(gbpsy);
734         gbpsy->changed = false;
735 }
736
737 static void gb_power_supply_work(struct work_struct *work)
738 {
739         struct gb_power_supply *gbpsy = container_of(work,
740                                                      struct gb_power_supply,
741                                                      work.work);
742
743         /*
744          * if the poll interval is not set, disable polling, this is helpful
745          * specially at unregister time.
746          */
747         if (!gbpsy->update_interval)
748                 return;
749
750         gb_power_supply_status_update(gbpsy);
751         next_interval(gbpsy);
752         schedule_delayed_work(&gbpsy->work, gbpsy->update_interval);
753 }
754
755 static int get_property(struct power_supply *b,
756                         enum power_supply_property psp,
757                         union power_supply_propval *val)
758 {
759         struct gb_power_supply *gbpsy = to_gb_power_supply(b);
760
761         gb_power_supply_status_get(gbpsy);
762
763         return _gb_power_supply_property_get(gbpsy, psp, val);
764 }
765
766 static int gb_power_supply_property_set(struct gb_power_supply *gbpsy,
767                                         enum power_supply_property psp,
768                                         int val)
769 {
770         struct gb_connection *connection = get_conn_from_psy(gbpsy);
771         struct gb_power_supply_prop *prop;
772         struct gb_power_supply_set_property_request req;
773         int ret;
774
775         ret = gb_pm_runtime_get_sync(connection->bundle);
776         if (ret)
777                 return ret;
778
779         prop = get_psy_prop(gbpsy, psp);
780         if (!prop) {
781                 ret = -EINVAL;
782                 goto out;
783         }
784
785         req.psy_id = gbpsy->id;
786         req.property = prop->gb_prop;
787         req.prop_val = cpu_to_le32((s32)val);
788
789         ret = gb_operation_sync(connection, GB_POWER_SUPPLY_TYPE_SET_PROPERTY,
790                                 &req, sizeof(req), NULL, 0);
791         if (ret < 0)
792                 goto out;
793
794         /* cache immediately the new value */
795         prop->val = val;
796
797 out:
798         gb_pm_runtime_put_autosuspend(connection->bundle);
799         return ret;
800 }
801
802 static int set_property(struct power_supply *b,
803                         enum power_supply_property psp,
804                         const union power_supply_propval *val)
805 {
806         struct gb_power_supply *gbpsy = to_gb_power_supply(b);
807
808         return gb_power_supply_property_set(gbpsy, psp, val->intval);
809 }
810
811 static int property_is_writeable(struct power_supply *b,
812                                  enum power_supply_property psp)
813 {
814         struct gb_power_supply *gbpsy = to_gb_power_supply(b);
815
816         return is_psy_prop_writeable(gbpsy, psp);
817 }
818
819 static int gb_power_supply_register(struct gb_power_supply *gbpsy)
820 {
821         struct gb_connection *connection = get_conn_from_psy(gbpsy);
822         struct power_supply_config cfg = {};
823
824         cfg.drv_data = gbpsy;
825
826         gbpsy->desc.name                = gbpsy->name;
827         gbpsy->desc.type                = gbpsy->type;
828         gbpsy->desc.properties          = gbpsy->props_raw;
829         gbpsy->desc.num_properties      = total_props(gbpsy);
830         gbpsy->desc.get_property        = get_property;
831         gbpsy->desc.set_property        = set_property;
832         gbpsy->desc.property_is_writeable = property_is_writeable;
833
834         gbpsy->psy = power_supply_register(&connection->bundle->dev,
835                                            &gbpsy->desc, &cfg);
836         return PTR_ERR_OR_ZERO(gbpsy->psy);
837 }
838
839 static void _gb_power_supply_free(struct gb_power_supply *gbpsy)
840 {
841         kfree(gbpsy->serial_number);
842         kfree(gbpsy->model_name);
843         kfree(gbpsy->manufacturer);
844         kfree(gbpsy->props_raw);
845         kfree(gbpsy->props);
846 }
847
848 static void _gb_power_supply_release(struct gb_power_supply *gbpsy)
849 {
850         gbpsy->update_interval = 0;
851
852         cancel_delayed_work_sync(&gbpsy->work);
853
854         if (gbpsy->registered)
855                 power_supply_unregister(gbpsy->psy);
856
857         _gb_power_supply_free(gbpsy);
858 }
859
860 static void _gb_power_supplies_release(struct gb_power_supplies *supplies)
861 {
862         int i;
863
864         if (!supplies->supply)
865                 return;
866
867         mutex_lock(&supplies->supplies_lock);
868         for (i = 0; i < supplies->supplies_count; i++)
869                 _gb_power_supply_release(&supplies->supply[i]);
870         kfree(supplies->supply);
871         mutex_unlock(&supplies->supplies_lock);
872         kfree(supplies);
873 }
874
875 static int gb_power_supplies_get_count(struct gb_power_supplies *supplies)
876 {
877         struct gb_power_supply_get_supplies_response resp;
878         int ret;
879
880         ret = gb_operation_sync(supplies->connection,
881                                 GB_POWER_SUPPLY_TYPE_GET_SUPPLIES,
882                                 NULL, 0, &resp, sizeof(resp));
883         if (ret < 0)
884                 return ret;
885
886         if  (!resp.supplies_count)
887                 return -EINVAL;
888
889         supplies->supplies_count = resp.supplies_count;
890
891         return ret;
892 }
893
894 static int gb_power_supply_config(struct gb_power_supplies *supplies, int id)
895 {
896         struct gb_power_supply *gbpsy = &supplies->supply[id];
897         int ret;
898
899         gbpsy->supplies = supplies;
900         gbpsy->id = id;
901
902         ret = gb_power_supply_description_get(gbpsy);
903         if (ret < 0)
904                 return ret;
905
906         return gb_power_supply_prop_descriptors_get(gbpsy);
907 }
908
909 static int gb_power_supply_enable(struct gb_power_supply *gbpsy)
910 {
911         int ret;
912
913         /* guarantee that we have an unique name, before register */
914         ret =  __gb_power_supply_set_name(gbpsy->model_name, gbpsy->name,
915                                           sizeof(gbpsy->name));
916         if (ret < 0)
917                 return ret;
918
919         mutex_init(&gbpsy->supply_lock);
920
921         ret = gb_power_supply_register(gbpsy);
922         if (ret < 0)
923                 return ret;
924
925         gbpsy->update_interval = update_interval_init;
926         INIT_DELAYED_WORK(&gbpsy->work, gb_power_supply_work);
927         schedule_delayed_work(&gbpsy->work, 0);
928
929         /* everything went fine, mark it for release code to know */
930         gbpsy->registered = true;
931
932         return 0;
933 }
934
935 static int gb_power_supplies_setup(struct gb_power_supplies *supplies)
936 {
937         struct gb_connection *connection = supplies->connection;
938         int ret;
939         int i;
940
941         mutex_lock(&supplies->supplies_lock);
942
943         ret = gb_power_supplies_get_count(supplies);
944         if (ret < 0)
945                 goto out;
946
947         supplies->supply = kzalloc(supplies->supplies_count *
948                                      sizeof(struct gb_power_supply),
949                                      GFP_KERNEL);
950
951         if (!supplies->supply) {
952                 ret = -ENOMEM;
953                 goto out;
954         }
955
956         for (i = 0; i < supplies->supplies_count; i++) {
957                 ret = gb_power_supply_config(supplies, i);
958                 if (ret < 0) {
959                         dev_err(&connection->bundle->dev,
960                                 "Fail to configure supplies devices\n");
961                         goto out;
962                 }
963         }
964 out:
965         mutex_unlock(&supplies->supplies_lock);
966         return ret;
967 }
968
969 static int gb_power_supplies_register(struct gb_power_supplies *supplies)
970 {
971         struct gb_connection *connection = supplies->connection;
972         int ret = 0;
973         int i;
974
975         mutex_lock(&supplies->supplies_lock);
976
977         for (i = 0; i < supplies->supplies_count; i++) {
978                 ret = gb_power_supply_enable(&supplies->supply[i]);
979                 if (ret < 0) {
980                         dev_err(&connection->bundle->dev,
981                                 "Fail to enable supplies devices\n");
982                         break;
983                 }
984         }
985
986         mutex_unlock(&supplies->supplies_lock);
987         return ret;
988 }
989
990 static int gb_supplies_request_handler(struct gb_operation *op)
991 {
992         struct gb_connection *connection = op->connection;
993         struct gb_power_supplies *supplies = gb_connection_get_data(connection);
994         struct gb_power_supply *gbpsy;
995         struct gb_message *request;
996         struct gb_power_supply_event_request *payload;
997         u8 psy_id;
998         u8 event;
999         int ret = 0;
1000
1001         if (op->type != GB_POWER_SUPPLY_TYPE_EVENT) {
1002                 dev_err(&connection->bundle->dev,
1003                         "Unsupported unsolicited event: %u\n", op->type);
1004                 return -EINVAL;
1005         }
1006
1007         request = op->request;
1008
1009         if (request->payload_size < sizeof(*payload)) {
1010                 dev_err(&connection->bundle->dev,
1011                         "Wrong event size received (%zu < %zu)\n",
1012                         request->payload_size, sizeof(*payload));
1013                 return -EINVAL;
1014         }
1015
1016         payload = request->payload;
1017         psy_id = payload->psy_id;
1018         mutex_lock(&supplies->supplies_lock);
1019         if (psy_id >= supplies->supplies_count ||
1020             !supplies->supply[psy_id].registered) {
1021                 dev_err(&connection->bundle->dev,
1022                         "Event received for unconfigured power_supply id: %d\n",
1023                         psy_id);
1024                 ret = -EINVAL;
1025                 goto out_unlock;
1026         }
1027
1028         event = payload->event;
1029         /*
1030          * we will only handle events after setup is done and before release is
1031          * running. For that just check update_interval.
1032          */
1033         gbpsy = &supplies->supply[psy_id];
1034         if (!gbpsy->update_interval) {
1035                 ret = -ESHUTDOWN;
1036                 goto out_unlock;
1037         }
1038
1039         if (event & GB_POWER_SUPPLY_UPDATE) {
1040                 /*
1041                  * we need to make sure we invalidate cache, if not no new
1042                  * values for the properties will be fetch and the all propose
1043                  * of this event is missed
1044                  */
1045                 gbpsy->cache_invalid = 1;
1046                 gb_power_supply_status_update(gbpsy);
1047         }
1048
1049 out_unlock:
1050         mutex_unlock(&supplies->supplies_lock);
1051         return ret;
1052 }
1053
1054 static int gb_power_supply_probe(struct gb_bundle *bundle,
1055                                  const struct greybus_bundle_id *id)
1056 {
1057         struct greybus_descriptor_cport *cport_desc;
1058         struct gb_connection *connection;
1059         struct gb_power_supplies *supplies;
1060         int ret;
1061
1062         if (bundle->num_cports != 1)
1063                 return -ENODEV;
1064
1065         cport_desc = &bundle->cport_desc[0];
1066         if (cport_desc->protocol_id != GREYBUS_PROTOCOL_POWER_SUPPLY)
1067                 return -ENODEV;
1068
1069         supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
1070         if (!supplies)
1071                 return -ENOMEM;
1072
1073         connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
1074                                           gb_supplies_request_handler);
1075         if (IS_ERR(connection)) {
1076                 ret = PTR_ERR(connection);
1077                 goto out;
1078         }
1079
1080         supplies->connection = connection;
1081         gb_connection_set_data(connection, supplies);
1082
1083         mutex_init(&supplies->supplies_lock);
1084
1085         greybus_set_drvdata(bundle, supplies);
1086
1087         /* We aren't ready to receive an incoming request yet */
1088         ret = gb_connection_enable_tx(connection);
1089         if (ret)
1090                 goto error_connection_destroy;
1091
1092         ret = gb_power_supplies_setup(supplies);
1093         if (ret < 0)
1094                 goto error_connection_disable;
1095
1096         /* We are ready to receive an incoming request now, enable RX as well */
1097         ret = gb_connection_enable(connection);
1098         if (ret)
1099                 goto error_connection_disable;
1100
1101         ret = gb_power_supplies_register(supplies);
1102         if (ret < 0)
1103                 goto error_connection_disable;
1104
1105         gb_pm_runtime_put_autosuspend(bundle);
1106         return 0;
1107
1108 error_connection_disable:
1109         gb_connection_disable(connection);
1110 error_connection_destroy:
1111         gb_connection_destroy(connection);
1112 out:
1113         _gb_power_supplies_release(supplies);
1114         return ret;
1115 }
1116
1117 static void gb_power_supply_disconnect(struct gb_bundle *bundle)
1118 {
1119         struct gb_power_supplies *supplies = greybus_get_drvdata(bundle);
1120
1121         gb_connection_disable(supplies->connection);
1122         gb_connection_destroy(supplies->connection);
1123
1124         _gb_power_supplies_release(supplies);
1125 }
1126
1127 static const struct greybus_bundle_id gb_power_supply_id_table[] = {
1128         { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_POWER_SUPPLY) },
1129         { }
1130 };
1131 MODULE_DEVICE_TABLE(greybus, gb_power_supply_id_table);
1132
1133 static struct greybus_driver gb_power_supply_driver = {
1134         .name           = "power_supply",
1135         .probe          = gb_power_supply_probe,
1136         .disconnect     = gb_power_supply_disconnect,
1137         .id_table       = gb_power_supply_id_table,
1138 };
1139 module_greybus_driver(gb_power_supply_driver);
1140
1141 MODULE_LICENSE("GPL v2");