File Index
Files and directories
Sign in
FILE

power_supply.c

File preview with syntax highlighting.

linux-6.19.14/drivers/staging/greybus/power_supply.c C
   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_DESCRIPTION("Power Supply driver for a Greybus module");
1140MODULE_LICENSE("GPL v2");
~/ Read-only file preview.