• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * USB Power Delivery sysfs entries
4  *
5  * Copyright (C) 2022, Intel Corporation
6  * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
7  */
8 
9 #include <linux/slab.h>
10 #include <linux/usb/pd.h>
11 
12 #include "pd.h"
13 
14 static DEFINE_IDA(pd_ida);
15 
16 static struct class pd_class = {
17 	.name = "usb_power_delivery",
18 };
19 
20 #define to_pdo(o) container_of(o, struct pdo, dev)
21 
22 struct pdo {
23 	struct device dev;
24 	int object_position;
25 	u32 pdo;
26 };
27 
pdo_release(struct device * dev)28 static void pdo_release(struct device *dev)
29 {
30 	kfree(to_pdo(dev));
31 }
32 
33 /* -------------------------------------------------------------------------- */
34 /* Fixed Supply */
35 
36 static ssize_t
dual_role_power_show(struct device * dev,struct device_attribute * attr,char * buf)37 dual_role_power_show(struct device *dev, struct device_attribute *attr, char *buf)
38 {
39 	return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_DUAL_ROLE));
40 }
41 static DEVICE_ATTR_RO(dual_role_power);
42 
43 static ssize_t
usb_suspend_supported_show(struct device * dev,struct device_attribute * attr,char * buf)44 usb_suspend_supported_show(struct device *dev, struct device_attribute *attr, char *buf)
45 {
46 	return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_SUSPEND));
47 }
48 static DEVICE_ATTR_RO(usb_suspend_supported);
49 
50 static ssize_t
higher_capability_show(struct device * dev,struct device_attribute * attr,char * buf)51 higher_capability_show(struct device *dev, struct device_attribute *attr, char *buf)
52 {
53 	return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_HIGHER_CAP));
54 }
55 static DEVICE_ATTR_RO(higher_capability);
56 
57 static ssize_t
unconstrained_power_show(struct device * dev,struct device_attribute * attr,char * buf)58 unconstrained_power_show(struct device *dev, struct device_attribute *attr, char *buf)
59 {
60 	return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_EXTPOWER));
61 }
62 static DEVICE_ATTR_RO(unconstrained_power);
63 
64 static ssize_t
usb_communication_capable_show(struct device * dev,struct device_attribute * attr,char * buf)65 usb_communication_capable_show(struct device *dev, struct device_attribute *attr, char *buf)
66 {
67 	return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_USB_COMM));
68 }
69 static DEVICE_ATTR_RO(usb_communication_capable);
70 
71 static ssize_t
dual_role_data_show(struct device * dev,struct device_attribute * attr,char * buf)72 dual_role_data_show(struct device *dev, struct device_attribute *attr, char *buf)
73 {
74 	return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_DATA_SWAP));
75 }
76 static DEVICE_ATTR_RO(dual_role_data);
77 
78 static ssize_t
unchunked_extended_messages_supported_show(struct device * dev,struct device_attribute * attr,char * buf)79 unchunked_extended_messages_supported_show(struct device *dev,
80 					   struct device_attribute *attr, char *buf)
81 {
82 	return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_UNCHUNK_EXT));
83 }
84 static DEVICE_ATTR_RO(unchunked_extended_messages_supported);
85 
86 /*
87  * REVISIT: Peak Current requires access also to the RDO.
88 static ssize_t
89 peak_current_show(struct device *dev, struct device_attribute *attr, char *buf)
90 {
91 	...
92 }
93 */
94 
95 static ssize_t
fast_role_swap_current_show(struct device * dev,struct device_attribute * attr,char * buf)96 fast_role_swap_current_show(struct device *dev, struct device_attribute *attr, char *buf)
97 {
98 	return sysfs_emit(buf, "%u\n", (to_pdo(dev)->pdo >> PDO_FIXED_FRS_CURR_SHIFT) & 3);
99 }
100 static DEVICE_ATTR_RO(fast_role_swap_current);
101 
voltage_show(struct device * dev,struct device_attribute * attr,char * buf)102 static ssize_t voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
103 {
104 	return sysfs_emit(buf, "%umV\n", pdo_fixed_voltage(to_pdo(dev)->pdo));
105 }
106 static DEVICE_ATTR_RO(voltage);
107 
108 /* Shared with Variable supplies, both source and sink */
current_show(struct device * dev,struct device_attribute * attr,char * buf)109 static ssize_t current_show(struct device *dev, struct device_attribute *attr, char *buf)
110 {
111 	return sysfs_emit(buf, "%umA\n", pdo_max_current(to_pdo(dev)->pdo));
112 }
113 
114 /* Shared with Variable type supplies */
115 static struct device_attribute maximum_current_attr = {
116 	.attr = {
117 		.name = "maximum_current",
118 		.mode = 0444,
119 	},
120 	.show = current_show,
121 };
122 
123 static struct device_attribute operational_current_attr = {
124 	.attr = {
125 		.name = "operational_current",
126 		.mode = 0444,
127 	},
128 	.show = current_show,
129 };
130 
131 static struct attribute *source_fixed_supply_attrs[] = {
132 	&dev_attr_dual_role_power.attr,
133 	&dev_attr_usb_suspend_supported.attr,
134 	&dev_attr_unconstrained_power.attr,
135 	&dev_attr_usb_communication_capable.attr,
136 	&dev_attr_dual_role_data.attr,
137 	&dev_attr_unchunked_extended_messages_supported.attr,
138 	/*&dev_attr_peak_current.attr,*/
139 	&dev_attr_voltage.attr,
140 	&maximum_current_attr.attr,
141 	NULL
142 };
143 
fixed_attr_is_visible(struct kobject * kobj,struct attribute * attr,int n)144 static umode_t fixed_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
145 {
146 	if (to_pdo(kobj_to_dev(kobj))->object_position &&
147 	    /*attr != &dev_attr_peak_current.attr &&*/
148 	    attr != &dev_attr_voltage.attr &&
149 	    attr != &maximum_current_attr.attr &&
150 	    attr != &operational_current_attr.attr)
151 		return 0;
152 
153 	return attr->mode;
154 }
155 
156 static const struct attribute_group source_fixed_supply_group = {
157 	.is_visible = fixed_attr_is_visible,
158 	.attrs = source_fixed_supply_attrs,
159 };
160 __ATTRIBUTE_GROUPS(source_fixed_supply);
161 
162 static struct device_type source_fixed_supply_type = {
163 	.name = "pdo",
164 	.release = pdo_release,
165 	.groups = source_fixed_supply_groups,
166 };
167 
168 static struct attribute *sink_fixed_supply_attrs[] = {
169 	&dev_attr_dual_role_power.attr,
170 	&dev_attr_higher_capability.attr,
171 	&dev_attr_unconstrained_power.attr,
172 	&dev_attr_usb_communication_capable.attr,
173 	&dev_attr_dual_role_data.attr,
174 	&dev_attr_unchunked_extended_messages_supported.attr,
175 	&dev_attr_fast_role_swap_current.attr,
176 	&dev_attr_voltage.attr,
177 	&operational_current_attr.attr,
178 	NULL
179 };
180 
181 static const struct attribute_group sink_fixed_supply_group = {
182 	.is_visible = fixed_attr_is_visible,
183 	.attrs = sink_fixed_supply_attrs,
184 };
185 __ATTRIBUTE_GROUPS(sink_fixed_supply);
186 
187 static struct device_type sink_fixed_supply_type = {
188 	.name = "pdo",
189 	.release = pdo_release,
190 	.groups = sink_fixed_supply_groups,
191 };
192 
193 /* -------------------------------------------------------------------------- */
194 /* Variable Supply */
195 
196 static ssize_t
maximum_voltage_show(struct device * dev,struct device_attribute * attr,char * buf)197 maximum_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
198 {
199 	return sysfs_emit(buf, "%umV\n", pdo_max_voltage(to_pdo(dev)->pdo));
200 }
201 static DEVICE_ATTR_RO(maximum_voltage);
202 
203 static ssize_t
minimum_voltage_show(struct device * dev,struct device_attribute * attr,char * buf)204 minimum_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
205 {
206 	return sysfs_emit(buf, "%umV\n", pdo_min_voltage(to_pdo(dev)->pdo));
207 }
208 static DEVICE_ATTR_RO(minimum_voltage);
209 
210 static struct attribute *source_variable_supply_attrs[] = {
211 	&dev_attr_maximum_voltage.attr,
212 	&dev_attr_minimum_voltage.attr,
213 	&maximum_current_attr.attr,
214 	NULL
215 };
216 ATTRIBUTE_GROUPS(source_variable_supply);
217 
218 static struct device_type source_variable_supply_type = {
219 	.name = "pdo",
220 	.release = pdo_release,
221 	.groups = source_variable_supply_groups,
222 };
223 
224 static struct attribute *sink_variable_supply_attrs[] = {
225 	&dev_attr_maximum_voltage.attr,
226 	&dev_attr_minimum_voltage.attr,
227 	&operational_current_attr.attr,
228 	NULL
229 };
230 ATTRIBUTE_GROUPS(sink_variable_supply);
231 
232 static struct device_type sink_variable_supply_type = {
233 	.name = "pdo",
234 	.release = pdo_release,
235 	.groups = sink_variable_supply_groups,
236 };
237 
238 /* -------------------------------------------------------------------------- */
239 /* Battery */
240 
241 static ssize_t
maximum_power_show(struct device * dev,struct device_attribute * attr,char * buf)242 maximum_power_show(struct device *dev, struct device_attribute *attr, char *buf)
243 {
244 	return sysfs_emit(buf, "%umW\n", pdo_max_power(to_pdo(dev)->pdo));
245 }
246 static DEVICE_ATTR_RO(maximum_power);
247 
248 static ssize_t
operational_power_show(struct device * dev,struct device_attribute * attr,char * buf)249 operational_power_show(struct device *dev, struct device_attribute *attr, char *buf)
250 {
251 	return sysfs_emit(buf, "%umW\n", pdo_max_power(to_pdo(dev)->pdo));
252 }
253 static DEVICE_ATTR_RO(operational_power);
254 
255 static struct attribute *source_battery_attrs[] = {
256 	&dev_attr_maximum_voltage.attr,
257 	&dev_attr_minimum_voltage.attr,
258 	&dev_attr_maximum_power.attr,
259 	NULL
260 };
261 ATTRIBUTE_GROUPS(source_battery);
262 
263 static struct device_type source_battery_type = {
264 	.name = "pdo",
265 	.release = pdo_release,
266 	.groups = source_battery_groups,
267 };
268 
269 static struct attribute *sink_battery_attrs[] = {
270 	&dev_attr_maximum_voltage.attr,
271 	&dev_attr_minimum_voltage.attr,
272 	&dev_attr_operational_power.attr,
273 	NULL
274 };
275 ATTRIBUTE_GROUPS(sink_battery);
276 
277 static struct device_type sink_battery_type = {
278 	.name = "pdo",
279 	.release = pdo_release,
280 	.groups = sink_battery_groups,
281 };
282 
283 /* -------------------------------------------------------------------------- */
284 /* Standard Power Range (SPR) Programmable Power Supply (PPS) */
285 
286 static ssize_t
pps_power_limited_show(struct device * dev,struct device_attribute * attr,char * buf)287 pps_power_limited_show(struct device *dev, struct device_attribute *attr, char *buf)
288 {
289 	return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & BIT(27)));
290 }
291 static DEVICE_ATTR_RO(pps_power_limited);
292 
293 static ssize_t
pps_max_voltage_show(struct device * dev,struct device_attribute * attr,char * buf)294 pps_max_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
295 {
296 	return sysfs_emit(buf, "%umV\n", pdo_pps_apdo_max_voltage(to_pdo(dev)->pdo));
297 }
298 
299 static ssize_t
pps_min_voltage_show(struct device * dev,struct device_attribute * attr,char * buf)300 pps_min_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
301 {
302 	return sysfs_emit(buf, "%umV\n", pdo_pps_apdo_min_voltage(to_pdo(dev)->pdo));
303 }
304 
305 static ssize_t
pps_max_current_show(struct device * dev,struct device_attribute * attr,char * buf)306 pps_max_current_show(struct device *dev, struct device_attribute *attr, char *buf)
307 {
308 	return sysfs_emit(buf, "%umA\n", pdo_pps_apdo_max_current(to_pdo(dev)->pdo));
309 }
310 
311 static struct device_attribute pps_max_voltage_attr = {
312 	.attr = {
313 		.name = "maximum_voltage",
314 		.mode = 0444,
315 	},
316 	.show = pps_max_voltage_show,
317 };
318 
319 static struct device_attribute pps_min_voltage_attr = {
320 	.attr = {
321 		.name = "minimum_voltage",
322 		.mode = 0444,
323 	},
324 	.show = pps_min_voltage_show,
325 };
326 
327 static struct device_attribute pps_max_current_attr = {
328 	.attr = {
329 		.name = "maximum_current",
330 		.mode = 0444,
331 	},
332 	.show = pps_max_current_show,
333 };
334 
335 static struct attribute *source_pps_attrs[] = {
336 	&dev_attr_pps_power_limited.attr,
337 	&pps_max_voltage_attr.attr,
338 	&pps_min_voltage_attr.attr,
339 	&pps_max_current_attr.attr,
340 	NULL
341 };
342 ATTRIBUTE_GROUPS(source_pps);
343 
344 static struct device_type source_pps_type = {
345 	.name = "pdo",
346 	.release = pdo_release,
347 	.groups = source_pps_groups,
348 };
349 
350 static struct attribute *sink_pps_attrs[] = {
351 	&pps_max_voltage_attr.attr,
352 	&pps_min_voltage_attr.attr,
353 	&pps_max_current_attr.attr,
354 	NULL
355 };
356 ATTRIBUTE_GROUPS(sink_pps);
357 
358 static struct device_type sink_pps_type = {
359 	.name = "pdo",
360 	.release = pdo_release,
361 	.groups = sink_pps_groups,
362 };
363 
364 /* -------------------------------------------------------------------------- */
365 
366 static const char * const supply_name[] = {
367 	[PDO_TYPE_FIXED] = "fixed_supply",
368 	[PDO_TYPE_BATT]  = "battery",
369 	[PDO_TYPE_VAR]	 = "variable_supply",
370 };
371 
372 static const char * const apdo_supply_name[] = {
373 	[APDO_TYPE_PPS]  = "programmable_supply",
374 };
375 
376 static struct device_type *source_type[] = {
377 	[PDO_TYPE_FIXED] = &source_fixed_supply_type,
378 	[PDO_TYPE_BATT]  = &source_battery_type,
379 	[PDO_TYPE_VAR]   = &source_variable_supply_type,
380 };
381 
382 static struct device_type *source_apdo_type[] = {
383 	[APDO_TYPE_PPS]  = &source_pps_type,
384 };
385 
386 static struct device_type *sink_type[] = {
387 	[PDO_TYPE_FIXED] = &sink_fixed_supply_type,
388 	[PDO_TYPE_BATT]  = &sink_battery_type,
389 	[PDO_TYPE_VAR]   = &sink_variable_supply_type,
390 };
391 
392 static struct device_type *sink_apdo_type[] = {
393 	[APDO_TYPE_PPS]  = &sink_pps_type,
394 };
395 
396 /* REVISIT: Export when EPR_*_Capabilities need to be supported. */
add_pdo(struct usb_power_delivery_capabilities * cap,u32 pdo,int position)397 static int add_pdo(struct usb_power_delivery_capabilities *cap, u32 pdo, int position)
398 {
399 	struct device_type *type;
400 	const char *name;
401 	struct pdo *p;
402 	int ret;
403 
404 	p = kzalloc(sizeof(*p), GFP_KERNEL);
405 	if (!p)
406 		return -ENOMEM;
407 
408 	p->pdo = pdo;
409 	p->object_position = position;
410 
411 	if (pdo_type(pdo) == PDO_TYPE_APDO) {
412 		/* FIXME: Only PPS supported for now! Skipping others. */
413 		if (pdo_apdo_type(pdo) > APDO_TYPE_PPS) {
414 			dev_warn(&cap->dev, "Unknown APDO type. PDO 0x%08x\n", pdo);
415 			kfree(p);
416 			return 0;
417 		}
418 
419 		if (is_source(cap->role))
420 			type = source_apdo_type[pdo_apdo_type(pdo)];
421 		else
422 			type = sink_apdo_type[pdo_apdo_type(pdo)];
423 
424 		name = apdo_supply_name[pdo_apdo_type(pdo)];
425 	} else {
426 		if (is_source(cap->role))
427 			type = source_type[pdo_type(pdo)];
428 		else
429 			type = sink_type[pdo_type(pdo)];
430 
431 		name = supply_name[pdo_type(pdo)];
432 	}
433 
434 	p->dev.parent = &cap->dev;
435 	p->dev.type = type;
436 	dev_set_name(&p->dev, "%u:%s", position + 1, name);
437 
438 	ret = device_register(&p->dev);
439 	if (ret) {
440 		put_device(&p->dev);
441 		return ret;
442 	}
443 
444 	return 0;
445 }
446 
remove_pdo(struct device * dev,void * data)447 static int remove_pdo(struct device *dev, void *data)
448 {
449 	device_unregister(dev);
450 	return 0;
451 }
452 
453 /* -------------------------------------------------------------------------- */
454 
455 static const char * const cap_name[] = {
456 	[TYPEC_SINK]    = "sink-capabilities",
457 	[TYPEC_SOURCE]  = "source-capabilities",
458 };
459 
pd_capabilities_release(struct device * dev)460 static void pd_capabilities_release(struct device *dev)
461 {
462 	kfree(to_usb_power_delivery_capabilities(dev));
463 }
464 
465 static struct device_type pd_capabilities_type = {
466 	.name = "capabilities",
467 	.release = pd_capabilities_release,
468 };
469 
470 /**
471  * usb_power_delivery_register_capabilities - Register a set of capabilities.
472  * @pd: The USB PD instance that the capabilities belong to.
473  * @desc: Description of the Capablities Message.
474  *
475  * This function registers a Capabilities Message described in @desc. The
476  * capabilities will have their own sub-directory under @pd in sysfs.
477  *
478  * The function returns pointer to struct usb_power_delivery_capabilities, or
479  * ERR_PRT(errno).
480  */
481 struct usb_power_delivery_capabilities *
usb_power_delivery_register_capabilities(struct usb_power_delivery * pd,struct usb_power_delivery_capabilities_desc * desc)482 usb_power_delivery_register_capabilities(struct usb_power_delivery *pd,
483 					 struct usb_power_delivery_capabilities_desc *desc)
484 {
485 	struct usb_power_delivery_capabilities *cap;
486 	int ret;
487 	int i;
488 
489 	cap = kzalloc(sizeof(*cap), GFP_KERNEL);
490 	if (!cap)
491 		return ERR_PTR(-ENOMEM);
492 
493 	cap->pd = pd;
494 	cap->role = desc->role;
495 
496 	cap->dev.parent = &pd->dev;
497 	cap->dev.type = &pd_capabilities_type;
498 	dev_set_name(&cap->dev, "%s", cap_name[cap->role]);
499 
500 	ret = device_register(&cap->dev);
501 	if (ret) {
502 		put_device(&cap->dev);
503 		return ERR_PTR(ret);
504 	}
505 
506 	for (i = 0; i < PDO_MAX_OBJECTS && desc->pdo[i]; i++) {
507 		ret = add_pdo(cap, desc->pdo[i], i);
508 		if (ret) {
509 			usb_power_delivery_unregister_capabilities(cap);
510 			return ERR_PTR(ret);
511 		}
512 	}
513 
514 	return cap;
515 }
516 EXPORT_SYMBOL_GPL(usb_power_delivery_register_capabilities);
517 
518 /**
519  * usb_power_delivery_unregister_capabilities - Unregister a set of capabilities
520  * @cap: The capabilities
521  */
usb_power_delivery_unregister_capabilities(struct usb_power_delivery_capabilities * cap)522 void usb_power_delivery_unregister_capabilities(struct usb_power_delivery_capabilities *cap)
523 {
524 	if (!cap)
525 		return;
526 
527 	device_for_each_child(&cap->dev, NULL, remove_pdo);
528 	device_unregister(&cap->dev);
529 }
530 EXPORT_SYMBOL_GPL(usb_power_delivery_unregister_capabilities);
531 
532 /* -------------------------------------------------------------------------- */
533 
revision_show(struct device * dev,struct device_attribute * attr,char * buf)534 static ssize_t revision_show(struct device *dev, struct device_attribute *attr, char *buf)
535 {
536 	struct usb_power_delivery *pd = to_usb_power_delivery(dev);
537 
538 	return sysfs_emit(buf, "%u.%u\n", (pd->revision >> 8) & 0xff, (pd->revision >> 4) & 0xf);
539 }
540 static DEVICE_ATTR_RO(revision);
541 
version_show(struct device * dev,struct device_attribute * attr,char * buf)542 static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf)
543 {
544 	struct usb_power_delivery *pd = to_usb_power_delivery(dev);
545 
546 	return sysfs_emit(buf, "%u.%u\n", (pd->version >> 8) & 0xff, (pd->version >> 4) & 0xf);
547 }
548 static DEVICE_ATTR_RO(version);
549 
550 static struct attribute *pd_attrs[] = {
551 	&dev_attr_revision.attr,
552 	&dev_attr_version.attr,
553 	NULL
554 };
555 
pd_attr_is_visible(struct kobject * kobj,struct attribute * attr,int n)556 static umode_t pd_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
557 {
558 	struct usb_power_delivery *pd = to_usb_power_delivery(kobj_to_dev(kobj));
559 
560 	if (attr == &dev_attr_version.attr && !pd->version)
561 		return 0;
562 
563 	return attr->mode;
564 }
565 
566 static const struct attribute_group pd_group = {
567 	.is_visible = pd_attr_is_visible,
568 	.attrs = pd_attrs,
569 };
570 __ATTRIBUTE_GROUPS(pd);
571 
pd_release(struct device * dev)572 static void pd_release(struct device *dev)
573 {
574 	struct usb_power_delivery *pd = to_usb_power_delivery(dev);
575 
576 	ida_simple_remove(&pd_ida, pd->id);
577 	kfree(pd);
578 }
579 
580 static struct device_type pd_type = {
581 	.name = "usb_power_delivery",
582 	.release = pd_release,
583 	.groups = pd_groups,
584 };
585 
usb_power_delivery_find(const char * name)586 struct usb_power_delivery *usb_power_delivery_find(const char *name)
587 {
588 	struct device *dev;
589 
590 	dev = class_find_device_by_name(&pd_class, name);
591 
592 	return dev ? to_usb_power_delivery(dev) : NULL;
593 }
594 
595 /**
596  * usb_power_delivery_register - Register USB Power Delivery Support.
597  * @parent: Parent device.
598  * @desc: Description of the USB PD contract.
599  *
600  * This routine can be used to register USB Power Delivery capabilities that a
601  * device or devices can support. These capabilities represent all the
602  * capabilities that can be negotiated with a partner, so not only the Power
603  * Capabilities that are negotiated using the USB PD Capabilities Message.
604  *
605  * The USB Power Delivery Support object that this routine generates can be used
606  * as the parent object for all the actual USB Power Delivery Messages and
607  * objects that can be negotiated with the partner.
608  *
609  * Returns handle to struct usb_power_delivery or ERR_PTR.
610  */
611 struct usb_power_delivery *
usb_power_delivery_register(struct device * parent,struct usb_power_delivery_desc * desc)612 usb_power_delivery_register(struct device *parent, struct usb_power_delivery_desc *desc)
613 {
614 	struct usb_power_delivery *pd;
615 	int ret;
616 
617 	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
618 	if (!pd)
619 		return ERR_PTR(-ENOMEM);
620 
621 	ret = ida_simple_get(&pd_ida, 0, 0, GFP_KERNEL);
622 	if (ret < 0) {
623 		kfree(pd);
624 		return ERR_PTR(ret);
625 	}
626 
627 	pd->id = ret;
628 	pd->revision = desc->revision;
629 	pd->version = desc->version;
630 
631 	pd->dev.parent = parent;
632 	pd->dev.type = &pd_type;
633 	pd->dev.class = &pd_class;
634 	dev_set_name(&pd->dev, "pd%d", pd->id);
635 
636 	ret = device_register(&pd->dev);
637 	if (ret) {
638 		put_device(&pd->dev);
639 		return ERR_PTR(ret);
640 	}
641 
642 	return pd;
643 }
644 EXPORT_SYMBOL_GPL(usb_power_delivery_register);
645 
646 /**
647  * usb_power_delivery_unregister - Unregister USB Power Delivery Support.
648  * @pd: The USB PD contract.
649  */
usb_power_delivery_unregister(struct usb_power_delivery * pd)650 void usb_power_delivery_unregister(struct usb_power_delivery *pd)
651 {
652 	if (IS_ERR_OR_NULL(pd))
653 		return;
654 
655 	device_unregister(&pd->dev);
656 }
657 EXPORT_SYMBOL_GPL(usb_power_delivery_unregister);
658 
659 /**
660  * usb_power_delivery_link_device - Link device to its USB PD object.
661  * @pd: The USB PD instance.
662  * @dev: The device.
663  *
664  * This function can be used to create a symlink named "usb_power_delivery" for
665  * @dev that points to @pd.
666  */
usb_power_delivery_link_device(struct usb_power_delivery * pd,struct device * dev)667 int usb_power_delivery_link_device(struct usb_power_delivery *pd, struct device *dev)
668 {
669 	int ret;
670 
671 	if (IS_ERR_OR_NULL(pd) || !dev)
672 		return 0;
673 
674 	ret = sysfs_create_link(&dev->kobj, &pd->dev.kobj, "usb_power_delivery");
675 	if (ret)
676 		return ret;
677 
678 	get_device(&pd->dev);
679 	get_device(dev);
680 
681 	return 0;
682 }
683 EXPORT_SYMBOL_GPL(usb_power_delivery_link_device);
684 
685 /**
686  * usb_power_delivery_unlink_device - Unlink device from its USB PD object.
687  * @pd: The USB PD instance.
688  * @dev: The device.
689  *
690  * Remove the symlink that was previously created with pd_link_device().
691  */
usb_power_delivery_unlink_device(struct usb_power_delivery * pd,struct device * dev)692 void usb_power_delivery_unlink_device(struct usb_power_delivery *pd, struct device *dev)
693 {
694 	if (IS_ERR_OR_NULL(pd) || !dev)
695 		return;
696 
697 	sysfs_remove_link(&dev->kobj, "usb_power_delivery");
698 	put_device(&pd->dev);
699 	put_device(dev);
700 }
701 EXPORT_SYMBOL_GPL(usb_power_delivery_unlink_device);
702 
703 /* -------------------------------------------------------------------------- */
704 
usb_power_delivery_init(void)705 int __init usb_power_delivery_init(void)
706 {
707 	return class_register(&pd_class);
708 }
709 
usb_power_delivery_exit(void)710 void __exit usb_power_delivery_exit(void)
711 {
712 	ida_destroy(&pd_ida);
713 	class_unregister(&pd_class);
714 }
715