root/drivers/staging/greybus/power_supply.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_psp_from_gb_prop
  2. get_conn_from_psy
  3. get_psy_prop
  4. is_psy_prop_writeable
  5. is_prop_valint
  6. next_interval
  7. __gb_power_supply_changed
  8. gb_power_supply_state_change
  9. check_changed
  10. total_props
  11. prop_append
  12. __gb_power_supply_set_name
  13. _gb_power_supply_append_props
  14. gb_power_supply_description_get
  15. gb_power_supply_prop_descriptors_get
  16. __gb_power_supply_property_update
  17. __gb_power_supply_property_get
  18. __gb_power_supply_property_strval_get
  19. _gb_power_supply_property_get
  20. is_cache_valid
  21. gb_power_supply_status_get
  22. gb_power_supply_status_update
  23. gb_power_supply_work
  24. get_property
  25. gb_power_supply_property_set
  26. set_property
  27. property_is_writeable
  28. gb_power_supply_register
  29. _gb_power_supply_free
  30. _gb_power_supply_release
  31. _gb_power_supplies_release
  32. gb_power_supplies_get_count
  33. gb_power_supply_config
  34. gb_power_supply_enable
  35. gb_power_supplies_setup
  36. gb_power_supplies_register
  37. gb_supplies_request_handler
  38. gb_power_supply_probe
  39. gb_power_supply_disconnect

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

/* [<][>][^][v][top][bottom][index][help] */