cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

power_supply.c (29134B)


      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
     17struct 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
     25struct 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
     49struct 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 */
     73static unsigned int cache_time = 1000;
     74/*
     75 * update interval initial and maximum value, between the two will
     76 * back-off exponential
     77 */
     78static unsigned int update_interval_init = 1 * HZ;
     79static unsigned int update_interval_max = 30 * HZ;
     80
     81struct 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
     88static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
     89					 struct gb_power_supply_prop *prop);
     90
     91static 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
    106static 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
    310static struct gb_connection *get_conn_from_psy(struct gb_power_supply *gbpsy)
    311{
    312	return gbpsy->supplies->connection;
    313}
    314
    315static 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
    326static 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
    337static int is_prop_valint(enum power_supply_property psp)
    338{
    339	return ((psp < POWER_SUPPLY_PROP_MODEL_NAME) ? 1 : 0);
    340}
    341
    342static 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
    353static void __gb_power_supply_changed(struct gb_power_supply *gbpsy)
    354{
    355	power_supply_changed(gbpsy->psy);
    356}
    357
    358static 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
    392static 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
    423static 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
    429static 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
    444static 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	strscpy(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
    464static 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
    474static 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
    506static 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;
    583out_put_operation:
    584	gb_operation_put(op);
    585
    586	return ret;
    587}
    588
    589static 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
    622static 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
    636static 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
    657static 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
    679static 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
    695static 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
    722static 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
    735static 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
    753static 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
    764static 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
    795out:
    796	gb_pm_runtime_put_autosuspend(connection->bundle);
    797	return ret;
    798}
    799
    800static 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
    809static 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
    817static 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
    837static 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
    846static 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
    858static 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
    873static 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
    892static 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
    907static 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
    933static 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	}
    962out:
    963	mutex_unlock(&supplies->supplies_lock);
    964	return ret;
    965}
    966
    967static 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
    988static 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
   1047out_unlock:
   1048	mutex_unlock(&supplies->supplies_lock);
   1049	return ret;
   1050}
   1051
   1052static 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
   1106error_connection_disable:
   1107	gb_connection_disable(connection);
   1108error_connection_destroy:
   1109	gb_connection_destroy(connection);
   1110out:
   1111	_gb_power_supplies_release(supplies);
   1112	return ret;
   1113}
   1114
   1115static 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
   1125static const struct greybus_bundle_id gb_power_supply_id_table[] = {
   1126	{ GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_POWER_SUPPLY) },
   1127	{ }
   1128};
   1129MODULE_DEVICE_TABLE(greybus, gb_power_supply_id_table);
   1130
   1131static 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};
   1137module_greybus_driver(gb_power_supply_driver);
   1138
   1139MODULE_LICENSE("GPL v2");