Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Power Supply driver for a Greybus module.
0004  *
0005  * Copyright 2014-2015 Google Inc.
0006  * Copyright 2014-2015 Linaro Ltd.
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/power_supply.h>
0012 #include <linux/slab.h>
0013 #include <linux/greybus.h>
0014 
0015 #define PROP_MAX 32
0016 
0017 struct gb_power_supply_prop {
0018     enum power_supply_property  prop;
0019     u8              gb_prop;
0020     int             val;
0021     int             previous_val;
0022     bool                is_writeable;
0023 };
0024 
0025 struct gb_power_supply {
0026     u8              id;
0027     bool                registered;
0028     struct power_supply     *psy;
0029     struct power_supply_desc    desc;
0030     char                name[64];
0031     struct gb_power_supplies    *supplies;
0032     struct delayed_work     work;
0033     char                *manufacturer;
0034     char                *model_name;
0035     char                *serial_number;
0036     u8              type;
0037     u8              properties_count;
0038     u8              properties_count_str;
0039     unsigned long           last_update;
0040     u8              cache_invalid;
0041     unsigned int            update_interval;
0042     bool                changed;
0043     struct gb_power_supply_prop *props;
0044     enum power_supply_property  *props_raw;
0045     bool                pm_acquired;
0046     struct mutex            supply_lock;
0047 };
0048 
0049 struct gb_power_supplies {
0050     struct gb_connection    *connection;
0051     u8          supplies_count;
0052     struct gb_power_supply  *supply;
0053     struct mutex        supplies_lock;
0054 };
0055 
0056 #define to_gb_power_supply(x) power_supply_get_drvdata(x)
0057 
0058 /*
0059  * General power supply properties that could be absent from various reasons,
0060  * like kernel versions or vendor specific versions
0061  */
0062 #ifndef POWER_SUPPLY_PROP_VOLTAGE_BOOT
0063     #define POWER_SUPPLY_PROP_VOLTAGE_BOOT  -1
0064 #endif
0065 #ifndef POWER_SUPPLY_PROP_CURRENT_BOOT
0066     #define POWER_SUPPLY_PROP_CURRENT_BOOT  -1
0067 #endif
0068 #ifndef POWER_SUPPLY_PROP_CALIBRATE
0069     #define POWER_SUPPLY_PROP_CALIBRATE -1
0070 #endif
0071 
0072 /* cache time in milliseconds, if cache_time is set to 0 cache is disable */
0073 static unsigned int cache_time = 1000;
0074 /*
0075  * update interval initial and maximum value, between the two will
0076  * back-off exponential
0077  */
0078 static unsigned int update_interval_init = 1 * HZ;
0079 static unsigned int update_interval_max = 30 * HZ;
0080 
0081 struct gb_power_supply_changes {
0082     enum power_supply_property  prop;
0083     u32             tolerance_change;
0084     void (*prop_changed)(struct gb_power_supply *gbpsy,
0085                  struct gb_power_supply_prop *prop);
0086 };
0087 
0088 static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
0089                      struct gb_power_supply_prop *prop);
0090 
0091 static const struct gb_power_supply_changes psy_props_changes[] = {
0092     {   .prop           = GB_POWER_SUPPLY_PROP_STATUS,
0093         .tolerance_change   = 0,
0094         .prop_changed       = gb_power_supply_state_change,
0095     },
0096     {   .prop           = GB_POWER_SUPPLY_PROP_TEMP,
0097         .tolerance_change   = 500,
0098         .prop_changed       = NULL,
0099     },
0100     {   .prop           = GB_POWER_SUPPLY_PROP_ONLINE,
0101         .tolerance_change   = 0,
0102         .prop_changed       = NULL,
0103     },
0104 };
0105 
0106 static int get_psp_from_gb_prop(int gb_prop, enum power_supply_property *psp)
0107 {
0108     int prop;
0109 
0110     switch (gb_prop) {
0111     case GB_POWER_SUPPLY_PROP_STATUS:
0112         prop = POWER_SUPPLY_PROP_STATUS;
0113         break;
0114     case GB_POWER_SUPPLY_PROP_CHARGE_TYPE:
0115         prop = POWER_SUPPLY_PROP_CHARGE_TYPE;
0116         break;
0117     case GB_POWER_SUPPLY_PROP_HEALTH:
0118         prop = POWER_SUPPLY_PROP_HEALTH;
0119         break;
0120     case GB_POWER_SUPPLY_PROP_PRESENT:
0121         prop = POWER_SUPPLY_PROP_PRESENT;
0122         break;
0123     case GB_POWER_SUPPLY_PROP_ONLINE:
0124         prop = POWER_SUPPLY_PROP_ONLINE;
0125         break;
0126     case GB_POWER_SUPPLY_PROP_AUTHENTIC:
0127         prop = POWER_SUPPLY_PROP_AUTHENTIC;
0128         break;
0129     case GB_POWER_SUPPLY_PROP_TECHNOLOGY:
0130         prop = POWER_SUPPLY_PROP_TECHNOLOGY;
0131         break;
0132     case GB_POWER_SUPPLY_PROP_CYCLE_COUNT:
0133         prop = POWER_SUPPLY_PROP_CYCLE_COUNT;
0134         break;
0135     case GB_POWER_SUPPLY_PROP_VOLTAGE_MAX:
0136         prop = POWER_SUPPLY_PROP_VOLTAGE_MAX;
0137         break;
0138     case GB_POWER_SUPPLY_PROP_VOLTAGE_MIN:
0139         prop = POWER_SUPPLY_PROP_VOLTAGE_MIN;
0140         break;
0141     case GB_POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
0142         prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN;
0143         break;
0144     case GB_POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
0145         prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN;
0146         break;
0147     case GB_POWER_SUPPLY_PROP_VOLTAGE_NOW:
0148         prop = POWER_SUPPLY_PROP_VOLTAGE_NOW;
0149         break;
0150     case GB_POWER_SUPPLY_PROP_VOLTAGE_AVG:
0151         prop = POWER_SUPPLY_PROP_VOLTAGE_AVG;
0152         break;
0153     case GB_POWER_SUPPLY_PROP_VOLTAGE_OCV:
0154         prop = POWER_SUPPLY_PROP_VOLTAGE_OCV;
0155         break;
0156     case GB_POWER_SUPPLY_PROP_VOLTAGE_BOOT:
0157         prop = POWER_SUPPLY_PROP_VOLTAGE_BOOT;
0158         break;
0159     case GB_POWER_SUPPLY_PROP_CURRENT_MAX:
0160         prop = POWER_SUPPLY_PROP_CURRENT_MAX;
0161         break;
0162     case GB_POWER_SUPPLY_PROP_CURRENT_NOW:
0163         prop = POWER_SUPPLY_PROP_CURRENT_NOW;
0164         break;
0165     case GB_POWER_SUPPLY_PROP_CURRENT_AVG:
0166         prop = POWER_SUPPLY_PROP_CURRENT_AVG;
0167         break;
0168     case GB_POWER_SUPPLY_PROP_CURRENT_BOOT:
0169         prop = POWER_SUPPLY_PROP_CURRENT_BOOT;
0170         break;
0171     case GB_POWER_SUPPLY_PROP_POWER_NOW:
0172         prop = POWER_SUPPLY_PROP_POWER_NOW;
0173         break;
0174     case GB_POWER_SUPPLY_PROP_POWER_AVG:
0175         prop = POWER_SUPPLY_PROP_POWER_AVG;
0176         break;
0177     case GB_POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
0178         prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
0179         break;
0180     case GB_POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
0181         prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN;
0182         break;
0183     case GB_POWER_SUPPLY_PROP_CHARGE_FULL:
0184         prop = POWER_SUPPLY_PROP_CHARGE_FULL;
0185         break;
0186     case GB_POWER_SUPPLY_PROP_CHARGE_EMPTY:
0187         prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
0188         break;
0189     case GB_POWER_SUPPLY_PROP_CHARGE_NOW:
0190         prop = POWER_SUPPLY_PROP_CHARGE_NOW;
0191         break;
0192     case GB_POWER_SUPPLY_PROP_CHARGE_AVG:
0193         prop = POWER_SUPPLY_PROP_CHARGE_AVG;
0194         break;
0195     case GB_POWER_SUPPLY_PROP_CHARGE_COUNTER:
0196         prop = POWER_SUPPLY_PROP_CHARGE_COUNTER;
0197         break;
0198     case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
0199         prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT;
0200         break;
0201     case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
0202         prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
0203         break;
0204     case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
0205         prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE;
0206         break;
0207     case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
0208         prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX;
0209         break;
0210     case GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
0211         prop = POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT;
0212         break;
0213     case GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX:
0214         prop = POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX;
0215         break;
0216     case GB_POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
0217         prop = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
0218         break;
0219     case GB_POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
0220         prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
0221         break;
0222     case GB_POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN:
0223         prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN;
0224         break;
0225     case GB_POWER_SUPPLY_PROP_ENERGY_FULL:
0226         prop = POWER_SUPPLY_PROP_ENERGY_FULL;
0227         break;
0228     case GB_POWER_SUPPLY_PROP_ENERGY_EMPTY:
0229         prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
0230         break;
0231     case GB_POWER_SUPPLY_PROP_ENERGY_NOW:
0232         prop = POWER_SUPPLY_PROP_ENERGY_NOW;
0233         break;
0234     case GB_POWER_SUPPLY_PROP_ENERGY_AVG:
0235         prop = POWER_SUPPLY_PROP_ENERGY_AVG;
0236         break;
0237     case GB_POWER_SUPPLY_PROP_CAPACITY:
0238         prop = POWER_SUPPLY_PROP_CAPACITY;
0239         break;
0240     case GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
0241         prop = POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN;
0242         break;
0243     case GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX:
0244         prop = POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX;
0245         break;
0246     case GB_POWER_SUPPLY_PROP_CAPACITY_LEVEL:
0247         prop = POWER_SUPPLY_PROP_CAPACITY_LEVEL;
0248         break;
0249     case GB_POWER_SUPPLY_PROP_TEMP:
0250         prop = POWER_SUPPLY_PROP_TEMP;
0251         break;
0252     case GB_POWER_SUPPLY_PROP_TEMP_MAX:
0253         prop = POWER_SUPPLY_PROP_TEMP_MAX;
0254         break;
0255     case GB_POWER_SUPPLY_PROP_TEMP_MIN:
0256         prop = POWER_SUPPLY_PROP_TEMP_MIN;
0257         break;
0258     case GB_POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
0259         prop = POWER_SUPPLY_PROP_TEMP_ALERT_MIN;
0260         break;
0261     case GB_POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
0262         prop = POWER_SUPPLY_PROP_TEMP_ALERT_MAX;
0263         break;
0264     case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT:
0265         prop = POWER_SUPPLY_PROP_TEMP_AMBIENT;
0266         break;
0267     case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
0268         prop = POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN;
0269         break;
0270     case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
0271         prop = POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX;
0272         break;
0273     case GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
0274         prop = POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW;
0275         break;
0276     case GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
0277         prop = POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG;
0278         break;
0279     case GB_POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
0280         prop = POWER_SUPPLY_PROP_TIME_TO_FULL_NOW;
0281         break;
0282     case GB_POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
0283         prop = POWER_SUPPLY_PROP_TIME_TO_FULL_AVG;
0284         break;
0285     case GB_POWER_SUPPLY_PROP_TYPE:
0286         prop = POWER_SUPPLY_PROP_TYPE;
0287         break;
0288     case GB_POWER_SUPPLY_PROP_SCOPE:
0289         prop = POWER_SUPPLY_PROP_SCOPE;
0290         break;
0291     case GB_POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
0292         prop = POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT;
0293         break;
0294     case GB_POWER_SUPPLY_PROP_CALIBRATE:
0295         prop = POWER_SUPPLY_PROP_CALIBRATE;
0296         break;
0297     default:
0298         prop = -1;
0299         break;
0300     }
0301 
0302     if (prop < 0)
0303         return prop;
0304 
0305     *psp = (enum power_supply_property)prop;
0306 
0307     return 0;
0308 }
0309 
0310 static struct gb_connection *get_conn_from_psy(struct gb_power_supply *gbpsy)
0311 {
0312     return gbpsy->supplies->connection;
0313 }
0314 
0315 static struct gb_power_supply_prop *get_psy_prop(struct gb_power_supply *gbpsy,
0316                          enum power_supply_property psp)
0317 {
0318     int i;
0319 
0320     for (i = 0; i < gbpsy->properties_count; i++)
0321         if (gbpsy->props[i].prop == psp)
0322             return &gbpsy->props[i];
0323     return NULL;
0324 }
0325 
0326 static int is_psy_prop_writeable(struct gb_power_supply *gbpsy,
0327                      enum power_supply_property psp)
0328 {
0329     struct gb_power_supply_prop *prop;
0330 
0331     prop = get_psy_prop(gbpsy, psp);
0332     if (!prop)
0333         return -ENOENT;
0334     return prop->is_writeable ? 1 : 0;
0335 }
0336 
0337 static int is_prop_valint(enum power_supply_property psp)
0338 {
0339     return ((psp < POWER_SUPPLY_PROP_MODEL_NAME) ? 1 : 0);
0340 }
0341 
0342 static void next_interval(struct gb_power_supply *gbpsy)
0343 {
0344     if (gbpsy->update_interval == update_interval_max)
0345         return;
0346 
0347     /* do some exponential back-off in the update interval */
0348     gbpsy->update_interval *= 2;
0349     if (gbpsy->update_interval > update_interval_max)
0350         gbpsy->update_interval = update_interval_max;
0351 }
0352 
0353 static void __gb_power_supply_changed(struct gb_power_supply *gbpsy)
0354 {
0355     power_supply_changed(gbpsy->psy);
0356 }
0357 
0358 static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
0359                      struct gb_power_supply_prop *prop)
0360 {
0361     struct gb_connection *connection = get_conn_from_psy(gbpsy);
0362     int ret;
0363 
0364     /*
0365      * Check gbpsy->pm_acquired to make sure only one pair of 'get_sync'
0366      * and 'put_autosuspend' runtime pm call for state property change.
0367      */
0368     mutex_lock(&gbpsy->supply_lock);
0369 
0370     if ((prop->val == GB_POWER_SUPPLY_STATUS_CHARGING) &&
0371         !gbpsy->pm_acquired) {
0372         ret = gb_pm_runtime_get_sync(connection->bundle);
0373         if (ret)
0374             dev_err(&connection->bundle->dev,
0375                 "Fail to set wake lock for charging state\n");
0376         else
0377             gbpsy->pm_acquired = true;
0378     } else {
0379         if (gbpsy->pm_acquired) {
0380             ret = gb_pm_runtime_put_autosuspend(connection->bundle);
0381             if (ret)
0382                 dev_err(&connection->bundle->dev,
0383                     "Fail to set wake unlock for none charging\n");
0384             else
0385                 gbpsy->pm_acquired = false;
0386         }
0387     }
0388 
0389     mutex_unlock(&gbpsy->supply_lock);
0390 }
0391 
0392 static void check_changed(struct gb_power_supply *gbpsy,
0393               struct gb_power_supply_prop *prop)
0394 {
0395     const struct gb_power_supply_changes *psyc;
0396     int val = prop->val;
0397     int prev_val = prop->previous_val;
0398     bool changed = false;
0399     int i;
0400 
0401     for (i = 0; i < ARRAY_SIZE(psy_props_changes); i++) {
0402         psyc = &psy_props_changes[i];
0403         if (prop->prop == psyc->prop) {
0404             if (!psyc->tolerance_change)
0405                 changed = true;
0406             else if (val < prev_val &&
0407                  prev_val - val > psyc->tolerance_change)
0408                 changed = true;
0409             else if (val > prev_val &&
0410                  val - prev_val > psyc->tolerance_change)
0411                 changed = true;
0412 
0413             if (changed && psyc->prop_changed)
0414                 psyc->prop_changed(gbpsy, prop);
0415 
0416             if (changed)
0417                 gbpsy->changed = true;
0418             break;
0419         }
0420     }
0421 }
0422 
0423 static int total_props(struct gb_power_supply *gbpsy)
0424 {
0425     /* this return the intval plus the strval properties */
0426     return (gbpsy->properties_count + gbpsy->properties_count_str);
0427 }
0428 
0429 static void prop_append(struct gb_power_supply *gbpsy,
0430             enum power_supply_property prop)
0431 {
0432     enum power_supply_property *new_props_raw;
0433 
0434     gbpsy->properties_count_str++;
0435     new_props_raw = krealloc(gbpsy->props_raw, total_props(gbpsy) *
0436                  sizeof(enum power_supply_property),
0437                  GFP_KERNEL);
0438     if (!new_props_raw)
0439         return;
0440     gbpsy->props_raw = new_props_raw;
0441     gbpsy->props_raw[total_props(gbpsy) - 1] = prop;
0442 }
0443 
0444 static int __gb_power_supply_set_name(char *init_name, char *name, size_t len)
0445 {
0446     unsigned int i = 0;
0447     int ret = 0;
0448     struct power_supply *psy;
0449 
0450     if (!strlen(init_name))
0451         init_name = "gb_power_supply";
0452     strscpy(name, init_name, len);
0453 
0454     while ((ret < len) && (psy = power_supply_get_by_name(name))) {
0455         power_supply_put(psy);
0456 
0457         ret = snprintf(name, len, "%s_%u", init_name, ++i);
0458     }
0459     if (ret >= len)
0460         return -ENOMEM;
0461     return i;
0462 }
0463 
0464 static void _gb_power_supply_append_props(struct gb_power_supply *gbpsy)
0465 {
0466     if (strlen(gbpsy->manufacturer))
0467         prop_append(gbpsy, POWER_SUPPLY_PROP_MANUFACTURER);
0468     if (strlen(gbpsy->model_name))
0469         prop_append(gbpsy, POWER_SUPPLY_PROP_MODEL_NAME);
0470     if (strlen(gbpsy->serial_number))
0471         prop_append(gbpsy, POWER_SUPPLY_PROP_SERIAL_NUMBER);
0472 }
0473 
0474 static int gb_power_supply_description_get(struct gb_power_supply *gbpsy)
0475 {
0476     struct gb_connection *connection = get_conn_from_psy(gbpsy);
0477     struct gb_power_supply_get_description_request req;
0478     struct gb_power_supply_get_description_response resp;
0479     int ret;
0480 
0481     req.psy_id = gbpsy->id;
0482 
0483     ret = gb_operation_sync(connection,
0484                 GB_POWER_SUPPLY_TYPE_GET_DESCRIPTION,
0485                 &req, sizeof(req), &resp, sizeof(resp));
0486     if (ret < 0)
0487         return ret;
0488 
0489     gbpsy->manufacturer = kstrndup(resp.manufacturer, PROP_MAX, GFP_KERNEL);
0490     if (!gbpsy->manufacturer)
0491         return -ENOMEM;
0492     gbpsy->model_name = kstrndup(resp.model, PROP_MAX, GFP_KERNEL);
0493     if (!gbpsy->model_name)
0494         return -ENOMEM;
0495     gbpsy->serial_number = kstrndup(resp.serial_number, PROP_MAX,
0496                        GFP_KERNEL);
0497     if (!gbpsy->serial_number)
0498         return -ENOMEM;
0499 
0500     gbpsy->type = le16_to_cpu(resp.type);
0501     gbpsy->properties_count = resp.properties_count;
0502 
0503     return 0;
0504 }
0505 
0506 static int gb_power_supply_prop_descriptors_get(struct gb_power_supply *gbpsy)
0507 {
0508     struct gb_connection *connection = get_conn_from_psy(gbpsy);
0509     struct gb_power_supply_get_property_descriptors_request *req;
0510     struct gb_power_supply_get_property_descriptors_response *resp;
0511     struct gb_operation *op;
0512     u8 props_count = gbpsy->properties_count;
0513     enum power_supply_property psp;
0514     int ret;
0515     int i, r = 0;
0516 
0517     if (props_count == 0)
0518         return 0;
0519 
0520     op = gb_operation_create(connection,
0521                  GB_POWER_SUPPLY_TYPE_GET_PROP_DESCRIPTORS,
0522                  sizeof(*req),
0523                  struct_size(resp, props, props_count),
0524                  GFP_KERNEL);
0525     if (!op)
0526         return -ENOMEM;
0527 
0528     req = op->request->payload;
0529     req->psy_id = gbpsy->id;
0530 
0531     ret = gb_operation_request_send_sync(op);
0532     if (ret < 0)
0533         goto out_put_operation;
0534 
0535     resp = op->response->payload;
0536 
0537     /* validate received properties */
0538     for (i = 0; i < props_count; i++) {
0539         ret = get_psp_from_gb_prop(resp->props[i].property, &psp);
0540         if (ret < 0) {
0541             dev_warn(&connection->bundle->dev,
0542                  "greybus property %u it is not supported by this kernel, dropped\n",
0543                  resp->props[i].property);
0544             gbpsy->properties_count--;
0545         }
0546     }
0547 
0548     gbpsy->props = kcalloc(gbpsy->properties_count, sizeof(*gbpsy->props),
0549                   GFP_KERNEL);
0550     if (!gbpsy->props) {
0551         ret = -ENOMEM;
0552         goto out_put_operation;
0553     }
0554 
0555     gbpsy->props_raw = kcalloc(gbpsy->properties_count,
0556                    sizeof(*gbpsy->props_raw), GFP_KERNEL);
0557     if (!gbpsy->props_raw) {
0558         ret = -ENOMEM;
0559         goto out_put_operation;
0560     }
0561 
0562     /* Store available properties, skip the ones we do not support */
0563     for (i = 0; i < props_count; i++) {
0564         ret = get_psp_from_gb_prop(resp->props[i].property, &psp);
0565         if (ret < 0) {
0566             r++;
0567             continue;
0568         }
0569         gbpsy->props[i - r].prop = psp;
0570         gbpsy->props[i - r].gb_prop = resp->props[i].property;
0571         gbpsy->props_raw[i - r] = psp;
0572         if (resp->props[i].is_writeable)
0573             gbpsy->props[i - r].is_writeable = true;
0574     }
0575 
0576     /*
0577      * now append the properties that we already got information in the
0578      * get_description operation. (char * ones)
0579      */
0580     _gb_power_supply_append_props(gbpsy);
0581 
0582     ret = 0;
0583 out_put_operation:
0584     gb_operation_put(op);
0585 
0586     return ret;
0587 }
0588 
0589 static int __gb_power_supply_property_update(struct gb_power_supply *gbpsy,
0590                          enum power_supply_property psp)
0591 {
0592     struct gb_connection *connection = get_conn_from_psy(gbpsy);
0593     struct gb_power_supply_prop *prop;
0594     struct gb_power_supply_get_property_request req;
0595     struct gb_power_supply_get_property_response resp;
0596     int val;
0597     int ret;
0598 
0599     prop = get_psy_prop(gbpsy, psp);
0600     if (!prop)
0601         return -EINVAL;
0602     req.psy_id = gbpsy->id;
0603     req.property = prop->gb_prop;
0604 
0605     ret = gb_operation_sync(connection, GB_POWER_SUPPLY_TYPE_GET_PROPERTY,
0606                 &req, sizeof(req), &resp, sizeof(resp));
0607     if (ret < 0)
0608         return ret;
0609 
0610     val = le32_to_cpu(resp.prop_val);
0611     if (val == prop->val)
0612         return 0;
0613 
0614     prop->previous_val = prop->val;
0615     prop->val = val;
0616 
0617     check_changed(gbpsy, prop);
0618 
0619     return 0;
0620 }
0621 
0622 static int __gb_power_supply_property_get(struct gb_power_supply *gbpsy,
0623                       enum power_supply_property psp,
0624                       union power_supply_propval *val)
0625 {
0626     struct gb_power_supply_prop *prop;
0627 
0628     prop = get_psy_prop(gbpsy, psp);
0629     if (!prop)
0630         return -EINVAL;
0631 
0632     val->intval = prop->val;
0633     return 0;
0634 }
0635 
0636 static int __gb_power_supply_property_strval_get(struct gb_power_supply *gbpsy,
0637                         enum power_supply_property psp,
0638                         union power_supply_propval *val)
0639 {
0640     switch (psp) {
0641     case POWER_SUPPLY_PROP_MODEL_NAME:
0642         val->strval = gbpsy->model_name;
0643         break;
0644     case POWER_SUPPLY_PROP_MANUFACTURER:
0645         val->strval = gbpsy->manufacturer;
0646         break;
0647     case POWER_SUPPLY_PROP_SERIAL_NUMBER:
0648         val->strval = gbpsy->serial_number;
0649         break;
0650     default:
0651         break;
0652     }
0653 
0654     return 0;
0655 }
0656 
0657 static int _gb_power_supply_property_get(struct gb_power_supply *gbpsy,
0658                      enum power_supply_property psp,
0659                      union power_supply_propval *val)
0660 {
0661     struct gb_connection *connection = get_conn_from_psy(gbpsy);
0662     int ret;
0663 
0664     /*
0665      * Properties of type const char *, were already fetched on
0666      * get_description operation and should be cached in gb
0667      */
0668     if (is_prop_valint(psp))
0669         ret = __gb_power_supply_property_get(gbpsy, psp, val);
0670     else
0671         ret = __gb_power_supply_property_strval_get(gbpsy, psp, val);
0672 
0673     if (ret < 0)
0674         dev_err(&connection->bundle->dev, "get property %u\n", psp);
0675 
0676     return 0;
0677 }
0678 
0679 static int is_cache_valid(struct gb_power_supply *gbpsy)
0680 {
0681     /* check if cache is good enough or it has expired */
0682     if (gbpsy->cache_invalid) {
0683         gbpsy->cache_invalid = 0;
0684         return 0;
0685     }
0686 
0687     if (gbpsy->last_update &&
0688         time_is_after_jiffies(gbpsy->last_update +
0689                   msecs_to_jiffies(cache_time)))
0690         return 1;
0691 
0692     return 0;
0693 }
0694 
0695 static int gb_power_supply_status_get(struct gb_power_supply *gbpsy)
0696 {
0697     struct gb_connection *connection = get_conn_from_psy(gbpsy);
0698     int ret = 0;
0699     int i;
0700 
0701     if (is_cache_valid(gbpsy))
0702         return 0;
0703 
0704     ret = gb_pm_runtime_get_sync(connection->bundle);
0705     if (ret)
0706         return ret;
0707 
0708     for (i = 0; i < gbpsy->properties_count; i++) {
0709         ret = __gb_power_supply_property_update(gbpsy,
0710                             gbpsy->props[i].prop);
0711         if (ret < 0)
0712             break;
0713     }
0714 
0715     if (ret == 0)
0716         gbpsy->last_update = jiffies;
0717 
0718     gb_pm_runtime_put_autosuspend(connection->bundle);
0719     return ret;
0720 }
0721 
0722 static void gb_power_supply_status_update(struct gb_power_supply *gbpsy)
0723 {
0724     /* check if there a change that need to be reported */
0725     gb_power_supply_status_get(gbpsy);
0726 
0727     if (!gbpsy->changed)
0728         return;
0729 
0730     gbpsy->update_interval = update_interval_init;
0731     __gb_power_supply_changed(gbpsy);
0732     gbpsy->changed = false;
0733 }
0734 
0735 static void gb_power_supply_work(struct work_struct *work)
0736 {
0737     struct gb_power_supply *gbpsy = container_of(work,
0738                              struct gb_power_supply,
0739                              work.work);
0740 
0741     /*
0742      * if the poll interval is not set, disable polling, this is helpful
0743      * specially at unregister time.
0744      */
0745     if (!gbpsy->update_interval)
0746         return;
0747 
0748     gb_power_supply_status_update(gbpsy);
0749     next_interval(gbpsy);
0750     schedule_delayed_work(&gbpsy->work, gbpsy->update_interval);
0751 }
0752 
0753 static int get_property(struct power_supply *b,
0754             enum power_supply_property psp,
0755             union power_supply_propval *val)
0756 {
0757     struct gb_power_supply *gbpsy = to_gb_power_supply(b);
0758 
0759     gb_power_supply_status_get(gbpsy);
0760 
0761     return _gb_power_supply_property_get(gbpsy, psp, val);
0762 }
0763 
0764 static int gb_power_supply_property_set(struct gb_power_supply *gbpsy,
0765                     enum power_supply_property psp,
0766                     int val)
0767 {
0768     struct gb_connection *connection = get_conn_from_psy(gbpsy);
0769     struct gb_power_supply_prop *prop;
0770     struct gb_power_supply_set_property_request req;
0771     int ret;
0772 
0773     ret = gb_pm_runtime_get_sync(connection->bundle);
0774     if (ret)
0775         return ret;
0776 
0777     prop = get_psy_prop(gbpsy, psp);
0778     if (!prop) {
0779         ret = -EINVAL;
0780         goto out;
0781     }
0782 
0783     req.psy_id = gbpsy->id;
0784     req.property = prop->gb_prop;
0785     req.prop_val = cpu_to_le32((s32)val);
0786 
0787     ret = gb_operation_sync(connection, GB_POWER_SUPPLY_TYPE_SET_PROPERTY,
0788                 &req, sizeof(req), NULL, 0);
0789     if (ret < 0)
0790         goto out;
0791 
0792     /* cache immediately the new value */
0793     prop->val = val;
0794 
0795 out:
0796     gb_pm_runtime_put_autosuspend(connection->bundle);
0797     return ret;
0798 }
0799 
0800 static int set_property(struct power_supply *b,
0801             enum power_supply_property psp,
0802             const union power_supply_propval *val)
0803 {
0804     struct gb_power_supply *gbpsy = to_gb_power_supply(b);
0805 
0806     return gb_power_supply_property_set(gbpsy, psp, val->intval);
0807 }
0808 
0809 static int property_is_writeable(struct power_supply *b,
0810                  enum power_supply_property psp)
0811 {
0812     struct gb_power_supply *gbpsy = to_gb_power_supply(b);
0813 
0814     return is_psy_prop_writeable(gbpsy, psp);
0815 }
0816 
0817 static int gb_power_supply_register(struct gb_power_supply *gbpsy)
0818 {
0819     struct gb_connection *connection = get_conn_from_psy(gbpsy);
0820     struct power_supply_config cfg = {};
0821 
0822     cfg.drv_data = gbpsy;
0823 
0824     gbpsy->desc.name        = gbpsy->name;
0825     gbpsy->desc.type        = gbpsy->type;
0826     gbpsy->desc.properties      = gbpsy->props_raw;
0827     gbpsy->desc.num_properties  = total_props(gbpsy);
0828     gbpsy->desc.get_property    = get_property;
0829     gbpsy->desc.set_property    = set_property;
0830     gbpsy->desc.property_is_writeable = property_is_writeable;
0831 
0832     gbpsy->psy = power_supply_register(&connection->bundle->dev,
0833                        &gbpsy->desc, &cfg);
0834     return PTR_ERR_OR_ZERO(gbpsy->psy);
0835 }
0836 
0837 static void _gb_power_supply_free(struct gb_power_supply *gbpsy)
0838 {
0839     kfree(gbpsy->serial_number);
0840     kfree(gbpsy->model_name);
0841     kfree(gbpsy->manufacturer);
0842     kfree(gbpsy->props_raw);
0843     kfree(gbpsy->props);
0844 }
0845 
0846 static void _gb_power_supply_release(struct gb_power_supply *gbpsy)
0847 {
0848     gbpsy->update_interval = 0;
0849 
0850     cancel_delayed_work_sync(&gbpsy->work);
0851 
0852     if (gbpsy->registered)
0853         power_supply_unregister(gbpsy->psy);
0854 
0855     _gb_power_supply_free(gbpsy);
0856 }
0857 
0858 static void _gb_power_supplies_release(struct gb_power_supplies *supplies)
0859 {
0860     int i;
0861 
0862     if (!supplies->supply)
0863         return;
0864 
0865     mutex_lock(&supplies->supplies_lock);
0866     for (i = 0; i < supplies->supplies_count; i++)
0867         _gb_power_supply_release(&supplies->supply[i]);
0868     kfree(supplies->supply);
0869     mutex_unlock(&supplies->supplies_lock);
0870     kfree(supplies);
0871 }
0872 
0873 static int gb_power_supplies_get_count(struct gb_power_supplies *supplies)
0874 {
0875     struct gb_power_supply_get_supplies_response resp;
0876     int ret;
0877 
0878     ret = gb_operation_sync(supplies->connection,
0879                 GB_POWER_SUPPLY_TYPE_GET_SUPPLIES,
0880                 NULL, 0, &resp, sizeof(resp));
0881     if (ret < 0)
0882         return ret;
0883 
0884     if  (!resp.supplies_count)
0885         return -EINVAL;
0886 
0887     supplies->supplies_count = resp.supplies_count;
0888 
0889     return ret;
0890 }
0891 
0892 static int gb_power_supply_config(struct gb_power_supplies *supplies, int id)
0893 {
0894     struct gb_power_supply *gbpsy = &supplies->supply[id];
0895     int ret;
0896 
0897     gbpsy->supplies = supplies;
0898     gbpsy->id = id;
0899 
0900     ret = gb_power_supply_description_get(gbpsy);
0901     if (ret < 0)
0902         return ret;
0903 
0904     return gb_power_supply_prop_descriptors_get(gbpsy);
0905 }
0906 
0907 static int gb_power_supply_enable(struct gb_power_supply *gbpsy)
0908 {
0909     int ret;
0910 
0911     /* guarantee that we have an unique name, before register */
0912     ret =  __gb_power_supply_set_name(gbpsy->model_name, gbpsy->name,
0913                       sizeof(gbpsy->name));
0914     if (ret < 0)
0915         return ret;
0916 
0917     mutex_init(&gbpsy->supply_lock);
0918 
0919     ret = gb_power_supply_register(gbpsy);
0920     if (ret < 0)
0921         return ret;
0922 
0923     gbpsy->update_interval = update_interval_init;
0924     INIT_DELAYED_WORK(&gbpsy->work, gb_power_supply_work);
0925     schedule_delayed_work(&gbpsy->work, 0);
0926 
0927     /* everything went fine, mark it for release code to know */
0928     gbpsy->registered = true;
0929 
0930     return 0;
0931 }
0932 
0933 static int gb_power_supplies_setup(struct gb_power_supplies *supplies)
0934 {
0935     struct gb_connection *connection = supplies->connection;
0936     int ret;
0937     int i;
0938 
0939     mutex_lock(&supplies->supplies_lock);
0940 
0941     ret = gb_power_supplies_get_count(supplies);
0942     if (ret < 0)
0943         goto out;
0944 
0945     supplies->supply = kcalloc(supplies->supplies_count,
0946                      sizeof(struct gb_power_supply),
0947                      GFP_KERNEL);
0948 
0949     if (!supplies->supply) {
0950         ret = -ENOMEM;
0951         goto out;
0952     }
0953 
0954     for (i = 0; i < supplies->supplies_count; i++) {
0955         ret = gb_power_supply_config(supplies, i);
0956         if (ret < 0) {
0957             dev_err(&connection->bundle->dev,
0958                 "Fail to configure supplies devices\n");
0959             goto out;
0960         }
0961     }
0962 out:
0963     mutex_unlock(&supplies->supplies_lock);
0964     return ret;
0965 }
0966 
0967 static int gb_power_supplies_register(struct gb_power_supplies *supplies)
0968 {
0969     struct gb_connection *connection = supplies->connection;
0970     int ret = 0;
0971     int i;
0972 
0973     mutex_lock(&supplies->supplies_lock);
0974 
0975     for (i = 0; i < supplies->supplies_count; i++) {
0976         ret = gb_power_supply_enable(&supplies->supply[i]);
0977         if (ret < 0) {
0978             dev_err(&connection->bundle->dev,
0979                 "Fail to enable supplies devices\n");
0980             break;
0981         }
0982     }
0983 
0984     mutex_unlock(&supplies->supplies_lock);
0985     return ret;
0986 }
0987 
0988 static int gb_supplies_request_handler(struct gb_operation *op)
0989 {
0990     struct gb_connection *connection = op->connection;
0991     struct gb_power_supplies *supplies = gb_connection_get_data(connection);
0992     struct gb_power_supply *gbpsy;
0993     struct gb_message *request;
0994     struct gb_power_supply_event_request *payload;
0995     u8 psy_id;
0996     u8 event;
0997     int ret = 0;
0998 
0999     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");