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