]> Git Repo - linux.git/blob - drivers/usb/typec/class.c
Merge tag 'timers-urgent-2021-02-22' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / drivers / usb / typec / class.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * USB Type-C Connector Class
4  *
5  * Copyright (C) 2017, Intel Corporation
6  * Author: Heikki Krogerus <[email protected]>
7  */
8
9 #include <linux/device.h>
10 #include <linux/module.h>
11 #include <linux/mutex.h>
12 #include <linux/property.h>
13 #include <linux/slab.h>
14 #include <linux/usb/pd_vdo.h>
15
16 #include "bus.h"
17
18 struct typec_plug {
19         struct device                   dev;
20         enum typec_plug_index           index;
21         struct ida                      mode_ids;
22         int                             num_altmodes;
23 };
24
25 struct typec_cable {
26         struct device                   dev;
27         enum typec_plug_type            type;
28         struct usb_pd_identity          *identity;
29         unsigned int                    active:1;
30         u16                             pd_revision; /* 0300H = "3.0" */
31 };
32
33 struct typec_partner {
34         struct device                   dev;
35         unsigned int                    usb_pd:1;
36         struct usb_pd_identity          *identity;
37         enum typec_accessory            accessory;
38         struct ida                      mode_ids;
39         int                             num_altmodes;
40         u16                             pd_revision; /* 0300H = "3.0" */
41         enum usb_pd_svdm_ver            svdm_version;
42 };
43
44 struct typec_port {
45         unsigned int                    id;
46         struct device                   dev;
47         struct ida                      mode_ids;
48
49         int                             prefer_role;
50         enum typec_data_role            data_role;
51         enum typec_role                 pwr_role;
52         enum typec_role                 vconn_role;
53         enum typec_pwr_opmode           pwr_opmode;
54         enum typec_port_type            port_type;
55         struct mutex                    port_type_lock;
56
57         enum typec_orientation          orientation;
58         struct typec_switch             *sw;
59         struct typec_mux                *mux;
60
61         const struct typec_capability   *cap;
62         const struct typec_operations   *ops;
63 };
64
65 #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev)
66 #define to_typec_plug(_dev_) container_of(_dev_, struct typec_plug, dev)
67 #define to_typec_cable(_dev_) container_of(_dev_, struct typec_cable, dev)
68 #define to_typec_partner(_dev_) container_of(_dev_, struct typec_partner, dev)
69
70 static const struct device_type typec_partner_dev_type;
71 static const struct device_type typec_cable_dev_type;
72 static const struct device_type typec_plug_dev_type;
73
74 #define is_typec_partner(_dev_) (_dev_->type == &typec_partner_dev_type)
75 #define is_typec_cable(_dev_) (_dev_->type == &typec_cable_dev_type)
76 #define is_typec_plug(_dev_) (_dev_->type == &typec_plug_dev_type)
77
78 static DEFINE_IDA(typec_index_ida);
79 static struct class *typec_class;
80
81 /* ------------------------------------------------------------------------- */
82 /* Common attributes */
83
84 static const char * const typec_accessory_modes[] = {
85         [TYPEC_ACCESSORY_NONE]          = "none",
86         [TYPEC_ACCESSORY_AUDIO]         = "analog_audio",
87         [TYPEC_ACCESSORY_DEBUG]         = "debug",
88 };
89
90 /* Product types defined in USB PD Specification R3.0 V2.0 */
91 static const char * const product_type_ufp[8] = {
92         [IDH_PTYPE_NOT_UFP]             = "not_ufp",
93         [IDH_PTYPE_HUB]                 = "hub",
94         [IDH_PTYPE_PERIPH]              = "peripheral",
95         [IDH_PTYPE_PSD]                 = "psd",
96         [IDH_PTYPE_AMA]                 = "ama",
97 };
98
99 static const char * const product_type_dfp[8] = {
100         [IDH_PTYPE_NOT_DFP]             = "not_dfp",
101         [IDH_PTYPE_DFP_HUB]             = "hub",
102         [IDH_PTYPE_DFP_HOST]            = "host",
103         [IDH_PTYPE_DFP_PB]              = "power_brick",
104 };
105
106 static const char * const product_type_cable[8] = {
107         [IDH_PTYPE_NOT_CABLE]           = "not_cable",
108         [IDH_PTYPE_PCABLE]              = "passive",
109         [IDH_PTYPE_ACABLE]              = "active",
110         [IDH_PTYPE_VPD]                 = "vpd",
111 };
112
113 static struct usb_pd_identity *get_pd_identity(struct device *dev)
114 {
115         if (is_typec_partner(dev)) {
116                 struct typec_partner *partner = to_typec_partner(dev);
117
118                 return partner->identity;
119         } else if (is_typec_cable(dev)) {
120                 struct typec_cable *cable = to_typec_cable(dev);
121
122                 return cable->identity;
123         }
124         return NULL;
125 }
126
127 static const char *get_pd_product_type(struct device *dev)
128 {
129         struct typec_port *port = to_typec_port(dev->parent);
130         struct usb_pd_identity *id = get_pd_identity(dev);
131         const char *ptype = NULL;
132
133         if (is_typec_partner(dev)) {
134                 if (!id)
135                         return NULL;
136
137                 if (port->data_role == TYPEC_HOST)
138                         ptype = product_type_ufp[PD_IDH_PTYPE(id->id_header)];
139                 else
140                         ptype = product_type_dfp[PD_IDH_DFP_PTYPE(id->id_header)];
141         } else if (is_typec_cable(dev)) {
142                 if (id)
143                         ptype = product_type_cable[PD_IDH_PTYPE(id->id_header)];
144                 else
145                         ptype = to_typec_cable(dev)->active ?
146                                 product_type_cable[IDH_PTYPE_ACABLE] :
147                                 product_type_cable[IDH_PTYPE_PCABLE];
148         }
149
150         return ptype;
151 }
152
153 static ssize_t id_header_show(struct device *dev, struct device_attribute *attr,
154                               char *buf)
155 {
156         struct usb_pd_identity *id = get_pd_identity(dev);
157
158         return sprintf(buf, "0x%08x\n", id->id_header);
159 }
160 static DEVICE_ATTR_RO(id_header);
161
162 static ssize_t cert_stat_show(struct device *dev, struct device_attribute *attr,
163                               char *buf)
164 {
165         struct usb_pd_identity *id = get_pd_identity(dev);
166
167         return sprintf(buf, "0x%08x\n", id->cert_stat);
168 }
169 static DEVICE_ATTR_RO(cert_stat);
170
171 static ssize_t product_show(struct device *dev, struct device_attribute *attr,
172                             char *buf)
173 {
174         struct usb_pd_identity *id = get_pd_identity(dev);
175
176         return sprintf(buf, "0x%08x\n", id->product);
177 }
178 static DEVICE_ATTR_RO(product);
179
180 static ssize_t product_type_vdo1_show(struct device *dev, struct device_attribute *attr,
181                                       char *buf)
182 {
183         struct usb_pd_identity *id = get_pd_identity(dev);
184
185         return sysfs_emit(buf, "0x%08x\n", id->vdo[0]);
186 }
187 static DEVICE_ATTR_RO(product_type_vdo1);
188
189 static ssize_t product_type_vdo2_show(struct device *dev, struct device_attribute *attr,
190                                       char *buf)
191 {
192         struct usb_pd_identity *id = get_pd_identity(dev);
193
194         return sysfs_emit(buf, "0x%08x\n", id->vdo[1]);
195 }
196 static DEVICE_ATTR_RO(product_type_vdo2);
197
198 static ssize_t product_type_vdo3_show(struct device *dev, struct device_attribute *attr,
199                                       char *buf)
200 {
201         struct usb_pd_identity *id = get_pd_identity(dev);
202
203         return sysfs_emit(buf, "0x%08x\n", id->vdo[2]);
204 }
205 static DEVICE_ATTR_RO(product_type_vdo3);
206
207 static struct attribute *usb_pd_id_attrs[] = {
208         &dev_attr_id_header.attr,
209         &dev_attr_cert_stat.attr,
210         &dev_attr_product.attr,
211         &dev_attr_product_type_vdo1.attr,
212         &dev_attr_product_type_vdo2.attr,
213         &dev_attr_product_type_vdo3.attr,
214         NULL
215 };
216
217 static const struct attribute_group usb_pd_id_group = {
218         .name = "identity",
219         .attrs = usb_pd_id_attrs,
220 };
221
222 static const struct attribute_group *usb_pd_id_groups[] = {
223         &usb_pd_id_group,
224         NULL,
225 };
226
227 static void typec_product_type_notify(struct device *dev)
228 {
229         char *envp[2] = { };
230         const char *ptype;
231
232         ptype = get_pd_product_type(dev);
233         if (!ptype)
234                 return;
235
236         sysfs_notify(&dev->kobj, NULL, "type");
237
238         envp[0] = kasprintf(GFP_KERNEL, "PRODUCT_TYPE=%s", ptype);
239         if (!envp[0])
240                 return;
241
242         kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
243         kfree(envp[0]);
244 }
245
246 static void typec_report_identity(struct device *dev)
247 {
248         sysfs_notify(&dev->kobj, "identity", "id_header");
249         sysfs_notify(&dev->kobj, "identity", "cert_stat");
250         sysfs_notify(&dev->kobj, "identity", "product");
251         sysfs_notify(&dev->kobj, "identity", "product_type_vdo1");
252         sysfs_notify(&dev->kobj, "identity", "product_type_vdo2");
253         sysfs_notify(&dev->kobj, "identity", "product_type_vdo3");
254         typec_product_type_notify(dev);
255 }
256
257 static ssize_t
258 type_show(struct device *dev, struct device_attribute *attr, char *buf)
259 {
260         const char *ptype;
261
262         ptype = get_pd_product_type(dev);
263         if (!ptype)
264                 return 0;
265
266         return sysfs_emit(buf, "%s\n", ptype);
267 }
268 static DEVICE_ATTR_RO(type);
269
270 static ssize_t usb_power_delivery_revision_show(struct device *dev,
271                                                 struct device_attribute *attr,
272                                                 char *buf);
273 static DEVICE_ATTR_RO(usb_power_delivery_revision);
274
275 /* ------------------------------------------------------------------------- */
276 /* Alternate Modes */
277
278 static int altmode_match(struct device *dev, void *data)
279 {
280         struct typec_altmode *adev = to_typec_altmode(dev);
281         struct typec_device_id *id = data;
282
283         if (!is_typec_altmode(dev))
284                 return 0;
285
286         return ((adev->svid == id->svid) && (adev->mode == id->mode));
287 }
288
289 static void typec_altmode_set_partner(struct altmode *altmode)
290 {
291         struct typec_altmode *adev = &altmode->adev;
292         struct typec_device_id id = { adev->svid, adev->mode, };
293         struct typec_port *port = typec_altmode2port(adev);
294         struct altmode *partner;
295         struct device *dev;
296
297         dev = device_find_child(&port->dev, &id, altmode_match);
298         if (!dev)
299                 return;
300
301         /* Bind the port alt mode to the partner/plug alt mode. */
302         partner = to_altmode(to_typec_altmode(dev));
303         altmode->partner = partner;
304
305         /* Bind the partner/plug alt mode to the port alt mode. */
306         if (is_typec_plug(adev->dev.parent)) {
307                 struct typec_plug *plug = to_typec_plug(adev->dev.parent);
308
309                 partner->plug[plug->index] = altmode;
310         } else {
311                 partner->partner = altmode;
312         }
313 }
314
315 static void typec_altmode_put_partner(struct altmode *altmode)
316 {
317         struct altmode *partner = altmode->partner;
318         struct typec_altmode *adev;
319
320         if (!partner)
321                 return;
322
323         adev = &partner->adev;
324
325         if (is_typec_plug(adev->dev.parent)) {
326                 struct typec_plug *plug = to_typec_plug(adev->dev.parent);
327
328                 partner->plug[plug->index] = NULL;
329         } else {
330                 partner->partner = NULL;
331         }
332         put_device(&adev->dev);
333 }
334
335 /**
336  * typec_altmode_update_active - Report Enter/Exit mode
337  * @adev: Handle to the alternate mode
338  * @active: True when the mode has been entered
339  *
340  * If a partner or cable plug executes Enter/Exit Mode command successfully, the
341  * drivers use this routine to report the updated state of the mode.
342  */
343 void typec_altmode_update_active(struct typec_altmode *adev, bool active)
344 {
345         char dir[6];
346
347         if (adev->active == active)
348                 return;
349
350         if (!is_typec_port(adev->dev.parent) && adev->dev.driver) {
351                 if (!active)
352                         module_put(adev->dev.driver->owner);
353                 else
354                         WARN_ON(!try_module_get(adev->dev.driver->owner));
355         }
356
357         adev->active = active;
358         snprintf(dir, sizeof(dir), "mode%d", adev->mode);
359         sysfs_notify(&adev->dev.kobj, dir, "active");
360         sysfs_notify(&adev->dev.kobj, NULL, "active");
361         kobject_uevent(&adev->dev.kobj, KOBJ_CHANGE);
362 }
363 EXPORT_SYMBOL_GPL(typec_altmode_update_active);
364
365 /**
366  * typec_altmode2port - Alternate Mode to USB Type-C port
367  * @alt: The Alternate Mode
368  *
369  * Returns handle to the port that a cable plug or partner with @alt is
370  * connected to.
371  */
372 struct typec_port *typec_altmode2port(struct typec_altmode *alt)
373 {
374         if (is_typec_plug(alt->dev.parent))
375                 return to_typec_port(alt->dev.parent->parent->parent);
376         if (is_typec_partner(alt->dev.parent))
377                 return to_typec_port(alt->dev.parent->parent);
378         if (is_typec_port(alt->dev.parent))
379                 return to_typec_port(alt->dev.parent);
380
381         return NULL;
382 }
383 EXPORT_SYMBOL_GPL(typec_altmode2port);
384
385 static ssize_t
386 vdo_show(struct device *dev, struct device_attribute *attr, char *buf)
387 {
388         struct typec_altmode *alt = to_typec_altmode(dev);
389
390         return sprintf(buf, "0x%08x\n", alt->vdo);
391 }
392 static DEVICE_ATTR_RO(vdo);
393
394 static ssize_t
395 description_show(struct device *dev, struct device_attribute *attr, char *buf)
396 {
397         struct typec_altmode *alt = to_typec_altmode(dev);
398
399         return sprintf(buf, "%s\n", alt->desc ? alt->desc : "");
400 }
401 static DEVICE_ATTR_RO(description);
402
403 static ssize_t
404 active_show(struct device *dev, struct device_attribute *attr, char *buf)
405 {
406         struct typec_altmode *alt = to_typec_altmode(dev);
407
408         return sprintf(buf, "%s\n", alt->active ? "yes" : "no");
409 }
410
411 static ssize_t active_store(struct device *dev, struct device_attribute *attr,
412                             const char *buf, size_t size)
413 {
414         struct typec_altmode *adev = to_typec_altmode(dev);
415         struct altmode *altmode = to_altmode(adev);
416         bool enter;
417         int ret;
418
419         ret = kstrtobool(buf, &enter);
420         if (ret)
421                 return ret;
422
423         if (adev->active == enter)
424                 return size;
425
426         if (is_typec_port(adev->dev.parent)) {
427                 typec_altmode_update_active(adev, enter);
428
429                 /* Make sure that the partner exits the mode before disabling */
430                 if (altmode->partner && !enter && altmode->partner->adev.active)
431                         typec_altmode_exit(&altmode->partner->adev);
432         } else if (altmode->partner) {
433                 if (enter && !altmode->partner->adev.active) {
434                         dev_warn(dev, "port has the mode disabled\n");
435                         return -EPERM;
436                 }
437         }
438
439         /* Note: If there is no driver, the mode will not be entered */
440         if (adev->ops && adev->ops->activate) {
441                 ret = adev->ops->activate(adev, enter);
442                 if (ret)
443                         return ret;
444         }
445
446         return size;
447 }
448 static DEVICE_ATTR_RW(active);
449
450 static ssize_t
451 supported_roles_show(struct device *dev, struct device_attribute *attr,
452                      char *buf)
453 {
454         struct altmode *alt = to_altmode(to_typec_altmode(dev));
455         ssize_t ret;
456
457         switch (alt->roles) {
458         case TYPEC_PORT_SRC:
459                 ret = sprintf(buf, "source\n");
460                 break;
461         case TYPEC_PORT_SNK:
462                 ret = sprintf(buf, "sink\n");
463                 break;
464         case TYPEC_PORT_DRP:
465         default:
466                 ret = sprintf(buf, "source sink\n");
467                 break;
468         }
469         return ret;
470 }
471 static DEVICE_ATTR_RO(supported_roles);
472
473 static ssize_t
474 mode_show(struct device *dev, struct device_attribute *attr, char *buf)
475 {
476         struct typec_altmode *adev = to_typec_altmode(dev);
477
478         return sprintf(buf, "%u\n", adev->mode);
479 }
480 static DEVICE_ATTR_RO(mode);
481
482 static ssize_t
483 svid_show(struct device *dev, struct device_attribute *attr, char *buf)
484 {
485         struct typec_altmode *adev = to_typec_altmode(dev);
486
487         return sprintf(buf, "%04x\n", adev->svid);
488 }
489 static DEVICE_ATTR_RO(svid);
490
491 static struct attribute *typec_altmode_attrs[] = {
492         &dev_attr_active.attr,
493         &dev_attr_mode.attr,
494         &dev_attr_svid.attr,
495         &dev_attr_vdo.attr,
496         NULL
497 };
498
499 static umode_t typec_altmode_attr_is_visible(struct kobject *kobj,
500                                              struct attribute *attr, int n)
501 {
502         struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj));
503
504         if (attr == &dev_attr_active.attr)
505                 if (!adev->ops || !adev->ops->activate)
506                         return 0444;
507
508         return attr->mode;
509 }
510
511 static const struct attribute_group typec_altmode_group = {
512         .is_visible = typec_altmode_attr_is_visible,
513         .attrs = typec_altmode_attrs,
514 };
515
516 static const struct attribute_group *typec_altmode_groups[] = {
517         &typec_altmode_group,
518         NULL
519 };
520
521 static int altmode_id_get(struct device *dev)
522 {
523         struct ida *ids;
524
525         if (is_typec_partner(dev))
526                 ids = &to_typec_partner(dev)->mode_ids;
527         else if (is_typec_plug(dev))
528                 ids = &to_typec_plug(dev)->mode_ids;
529         else
530                 ids = &to_typec_port(dev)->mode_ids;
531
532         return ida_simple_get(ids, 0, 0, GFP_KERNEL);
533 }
534
535 static void altmode_id_remove(struct device *dev, int id)
536 {
537         struct ida *ids;
538
539         if (is_typec_partner(dev))
540                 ids = &to_typec_partner(dev)->mode_ids;
541         else if (is_typec_plug(dev))
542                 ids = &to_typec_plug(dev)->mode_ids;
543         else
544                 ids = &to_typec_port(dev)->mode_ids;
545
546         ida_simple_remove(ids, id);
547 }
548
549 static void typec_altmode_release(struct device *dev)
550 {
551         struct altmode *alt = to_altmode(to_typec_altmode(dev));
552
553         typec_altmode_put_partner(alt);
554
555         altmode_id_remove(alt->adev.dev.parent, alt->id);
556         kfree(alt);
557 }
558
559 const struct device_type typec_altmode_dev_type = {
560         .name = "typec_alternate_mode",
561         .groups = typec_altmode_groups,
562         .release = typec_altmode_release,
563 };
564
565 static struct typec_altmode *
566 typec_register_altmode(struct device *parent,
567                        const struct typec_altmode_desc *desc)
568 {
569         unsigned int id = altmode_id_get(parent);
570         bool is_port = is_typec_port(parent);
571         struct altmode *alt;
572         int ret;
573
574         alt = kzalloc(sizeof(*alt), GFP_KERNEL);
575         if (!alt)
576                 return ERR_PTR(-ENOMEM);
577
578         alt->adev.svid = desc->svid;
579         alt->adev.mode = desc->mode;
580         alt->adev.vdo = desc->vdo;
581         alt->roles = desc->roles;
582         alt->id = id;
583
584         alt->attrs[0] = &dev_attr_vdo.attr;
585         alt->attrs[1] = &dev_attr_description.attr;
586         alt->attrs[2] = &dev_attr_active.attr;
587
588         if (is_port) {
589                 alt->attrs[3] = &dev_attr_supported_roles.attr;
590                 alt->adev.active = true; /* Enabled by default */
591         }
592
593         sprintf(alt->group_name, "mode%d", desc->mode);
594         alt->group.name = alt->group_name;
595         alt->group.attrs = alt->attrs;
596         alt->groups[0] = &alt->group;
597
598         alt->adev.dev.parent = parent;
599         alt->adev.dev.groups = alt->groups;
600         alt->adev.dev.type = &typec_altmode_dev_type;
601         dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id);
602
603         /* Link partners and plugs with the ports */
604         if (!is_port)
605                 typec_altmode_set_partner(alt);
606
607         /* The partners are bind to drivers */
608         if (is_typec_partner(parent))
609                 alt->adev.dev.bus = &typec_bus;
610
611         /* Plug alt modes need a class to generate udev events. */
612         if (is_typec_plug(parent))
613                 alt->adev.dev.class = typec_class;
614
615         ret = device_register(&alt->adev.dev);
616         if (ret) {
617                 dev_err(parent, "failed to register alternate mode (%d)\n",
618                         ret);
619                 put_device(&alt->adev.dev);
620                 return ERR_PTR(ret);
621         }
622
623         return &alt->adev;
624 }
625
626 /**
627  * typec_unregister_altmode - Unregister Alternate Mode
628  * @adev: The alternate mode to be unregistered
629  *
630  * Unregister device created with typec_partner_register_altmode(),
631  * typec_plug_register_altmode() or typec_port_register_altmode().
632  */
633 void typec_unregister_altmode(struct typec_altmode *adev)
634 {
635         if (IS_ERR_OR_NULL(adev))
636                 return;
637         typec_mux_put(to_altmode(adev)->mux);
638         device_unregister(&adev->dev);
639 }
640 EXPORT_SYMBOL_GPL(typec_unregister_altmode);
641
642 /* ------------------------------------------------------------------------- */
643 /* Type-C Partners */
644
645 static ssize_t accessory_mode_show(struct device *dev,
646                                    struct device_attribute *attr,
647                                    char *buf)
648 {
649         struct typec_partner *p = to_typec_partner(dev);
650
651         return sprintf(buf, "%s\n", typec_accessory_modes[p->accessory]);
652 }
653 static DEVICE_ATTR_RO(accessory_mode);
654
655 static ssize_t supports_usb_power_delivery_show(struct device *dev,
656                                                 struct device_attribute *attr,
657                                                 char *buf)
658 {
659         struct typec_partner *p = to_typec_partner(dev);
660
661         return sprintf(buf, "%s\n", p->usb_pd ? "yes" : "no");
662 }
663 static DEVICE_ATTR_RO(supports_usb_power_delivery);
664
665 static ssize_t number_of_alternate_modes_show(struct device *dev, struct device_attribute *attr,
666                                               char *buf)
667 {
668         struct typec_partner *partner;
669         struct typec_plug *plug;
670         int num_altmodes;
671
672         if (is_typec_partner(dev)) {
673                 partner = to_typec_partner(dev);
674                 num_altmodes = partner->num_altmodes;
675         } else if (is_typec_plug(dev)) {
676                 plug = to_typec_plug(dev);
677                 num_altmodes = plug->num_altmodes;
678         } else {
679                 return 0;
680         }
681
682         return sysfs_emit(buf, "%d\n", num_altmodes);
683 }
684 static DEVICE_ATTR_RO(number_of_alternate_modes);
685
686 static struct attribute *typec_partner_attrs[] = {
687         &dev_attr_accessory_mode.attr,
688         &dev_attr_supports_usb_power_delivery.attr,
689         &dev_attr_number_of_alternate_modes.attr,
690         &dev_attr_type.attr,
691         &dev_attr_usb_power_delivery_revision.attr,
692         NULL
693 };
694
695 static umode_t typec_partner_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
696 {
697         struct typec_partner *partner = to_typec_partner(kobj_to_dev(kobj));
698
699         if (attr == &dev_attr_number_of_alternate_modes.attr) {
700                 if (partner->num_altmodes < 0)
701                         return 0;
702         }
703
704         if (attr == &dev_attr_type.attr)
705                 if (!get_pd_product_type(kobj_to_dev(kobj)))
706                         return 0;
707
708         return attr->mode;
709 }
710
711 static const struct attribute_group typec_partner_group = {
712         .is_visible = typec_partner_attr_is_visible,
713         .attrs = typec_partner_attrs
714 };
715
716 static const struct attribute_group *typec_partner_groups[] = {
717         &typec_partner_group,
718         NULL
719 };
720
721 static void typec_partner_release(struct device *dev)
722 {
723         struct typec_partner *partner = to_typec_partner(dev);
724
725         ida_destroy(&partner->mode_ids);
726         kfree(partner);
727 }
728
729 static const struct device_type typec_partner_dev_type = {
730         .name = "typec_partner",
731         .groups = typec_partner_groups,
732         .release = typec_partner_release,
733 };
734
735 /**
736  * typec_partner_set_identity - Report result from Discover Identity command
737  * @partner: The partner updated identity values
738  *
739  * This routine is used to report that the result of Discover Identity USB power
740  * delivery command has become available.
741  */
742 int typec_partner_set_identity(struct typec_partner *partner)
743 {
744         if (!partner->identity)
745                 return -EINVAL;
746
747         typec_report_identity(&partner->dev);
748         return 0;
749 }
750 EXPORT_SYMBOL_GPL(typec_partner_set_identity);
751
752 /**
753  * typec_partner_set_pd_revision - Set the PD revision supported by the partner
754  * @partner: The partner to be updated.
755  * @pd_revision:  USB Power Delivery Specification Revision supported by partner
756  *
757  * This routine is used to report that the PD revision of the port partner has
758  * become available.
759  */
760 void typec_partner_set_pd_revision(struct typec_partner *partner, u16 pd_revision)
761 {
762         if (partner->pd_revision == pd_revision)
763                 return;
764
765         partner->pd_revision = pd_revision;
766         sysfs_notify(&partner->dev.kobj, NULL, "usb_power_delivery_revision");
767         if (pd_revision != 0 && !partner->usb_pd) {
768                 partner->usb_pd = 1;
769                 sysfs_notify(&partner->dev.kobj, NULL,
770                              "supports_usb_power_delivery");
771         }
772         kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE);
773 }
774 EXPORT_SYMBOL_GPL(typec_partner_set_pd_revision);
775
776 /**
777  * typec_partner_set_num_altmodes - Set the number of available partner altmodes
778  * @partner: The partner to be updated.
779  * @num_altmodes: The number of altmodes we want to specify as available.
780  *
781  * This routine is used to report the number of alternate modes supported by the
782  * partner. This value is *not* enforced in alternate mode registration routines.
783  *
784  * @partner.num_altmodes is set to -1 on partner registration, denoting that
785  * a valid value has not been set for it yet.
786  *
787  * Returns 0 on success or negative error number on failure.
788  */
789 int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmodes)
790 {
791         int ret;
792
793         if (num_altmodes < 0)
794                 return -EINVAL;
795
796         partner->num_altmodes = num_altmodes;
797         ret = sysfs_update_group(&partner->dev.kobj, &typec_partner_group);
798         if (ret < 0)
799                 return ret;
800
801         sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes");
802         kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE);
803
804         return 0;
805 }
806 EXPORT_SYMBOL_GPL(typec_partner_set_num_altmodes);
807
808 /**
809  * typec_partner_register_altmode - Register USB Type-C Partner Alternate Mode
810  * @partner: USB Type-C Partner that supports the alternate mode
811  * @desc: Description of the alternate mode
812  *
813  * This routine is used to register each alternate mode individually that
814  * @partner has listed in response to Discover SVIDs command. The modes for a
815  * SVID listed in response to Discover Modes command need to be listed in an
816  * array in @desc.
817  *
818  * Returns handle to the alternate mode on success or ERR_PTR on failure.
819  */
820 struct typec_altmode *
821 typec_partner_register_altmode(struct typec_partner *partner,
822                                const struct typec_altmode_desc *desc)
823 {
824         return typec_register_altmode(&partner->dev, desc);
825 }
826 EXPORT_SYMBOL_GPL(typec_partner_register_altmode);
827
828 /**
829  * typec_partner_set_svdm_version - Set negotiated Structured VDM (SVDM) Version
830  * @partner: USB Type-C Partner that supports SVDM
831  * @svdm_version: Negotiated SVDM Version
832  *
833  * This routine is used to save the negotiated SVDM Version.
834  */
835 void typec_partner_set_svdm_version(struct typec_partner *partner,
836                                    enum usb_pd_svdm_ver svdm_version)
837 {
838         partner->svdm_version = svdm_version;
839 }
840 EXPORT_SYMBOL_GPL(typec_partner_set_svdm_version);
841
842 /**
843  * typec_register_partner - Register a USB Type-C Partner
844  * @port: The USB Type-C Port the partner is connected to
845  * @desc: Description of the partner
846  *
847  * Registers a device for USB Type-C Partner described in @desc.
848  *
849  * Returns handle to the partner on success or ERR_PTR on failure.
850  */
851 struct typec_partner *typec_register_partner(struct typec_port *port,
852                                              struct typec_partner_desc *desc)
853 {
854         struct typec_partner *partner;
855         int ret;
856
857         partner = kzalloc(sizeof(*partner), GFP_KERNEL);
858         if (!partner)
859                 return ERR_PTR(-ENOMEM);
860
861         ida_init(&partner->mode_ids);
862         partner->usb_pd = desc->usb_pd;
863         partner->accessory = desc->accessory;
864         partner->num_altmodes = -1;
865         partner->pd_revision = desc->pd_revision;
866         partner->svdm_version = port->cap->svdm_version;
867
868         if (desc->identity) {
869                 /*
870                  * Creating directory for the identity only if the driver is
871                  * able to provide data to it.
872                  */
873                 partner->dev.groups = usb_pd_id_groups;
874                 partner->identity = desc->identity;
875         }
876
877         partner->dev.class = typec_class;
878         partner->dev.parent = &port->dev;
879         partner->dev.type = &typec_partner_dev_type;
880         dev_set_name(&partner->dev, "%s-partner", dev_name(&port->dev));
881
882         ret = device_register(&partner->dev);
883         if (ret) {
884                 dev_err(&port->dev, "failed to register partner (%d)\n", ret);
885                 put_device(&partner->dev);
886                 return ERR_PTR(ret);
887         }
888
889         return partner;
890 }
891 EXPORT_SYMBOL_GPL(typec_register_partner);
892
893 /**
894  * typec_unregister_partner - Unregister a USB Type-C Partner
895  * @partner: The partner to be unregistered
896  *
897  * Unregister device created with typec_register_partner().
898  */
899 void typec_unregister_partner(struct typec_partner *partner)
900 {
901         if (!IS_ERR_OR_NULL(partner))
902                 device_unregister(&partner->dev);
903 }
904 EXPORT_SYMBOL_GPL(typec_unregister_partner);
905
906 /* ------------------------------------------------------------------------- */
907 /* Type-C Cable Plugs */
908
909 static void typec_plug_release(struct device *dev)
910 {
911         struct typec_plug *plug = to_typec_plug(dev);
912
913         ida_destroy(&plug->mode_ids);
914         kfree(plug);
915 }
916
917 static struct attribute *typec_plug_attrs[] = {
918         &dev_attr_number_of_alternate_modes.attr,
919         NULL
920 };
921
922 static umode_t typec_plug_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
923 {
924         struct typec_plug *plug = to_typec_plug(kobj_to_dev(kobj));
925
926         if (attr == &dev_attr_number_of_alternate_modes.attr) {
927                 if (plug->num_altmodes < 0)
928                         return 0;
929         }
930
931         return attr->mode;
932 }
933
934 static const struct attribute_group typec_plug_group = {
935         .is_visible = typec_plug_attr_is_visible,
936         .attrs = typec_plug_attrs
937 };
938
939 static const struct attribute_group *typec_plug_groups[] = {
940         &typec_plug_group,
941         NULL
942 };
943
944 static const struct device_type typec_plug_dev_type = {
945         .name = "typec_plug",
946         .groups = typec_plug_groups,
947         .release = typec_plug_release,
948 };
949
950 /**
951  * typec_plug_set_num_altmodes - Set the number of available plug altmodes
952  * @plug: The plug to be updated.
953  * @num_altmodes: The number of altmodes we want to specify as available.
954  *
955  * This routine is used to report the number of alternate modes supported by the
956  * plug. This value is *not* enforced in alternate mode registration routines.
957  *
958  * @plug.num_altmodes is set to -1 on plug registration, denoting that
959  * a valid value has not been set for it yet.
960  *
961  * Returns 0 on success or negative error number on failure.
962  */
963 int typec_plug_set_num_altmodes(struct typec_plug *plug, int num_altmodes)
964 {
965         int ret;
966
967         if (num_altmodes < 0)
968                 return -EINVAL;
969
970         plug->num_altmodes = num_altmodes;
971         ret = sysfs_update_group(&plug->dev.kobj, &typec_plug_group);
972         if (ret < 0)
973                 return ret;
974
975         sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes");
976         kobject_uevent(&plug->dev.kobj, KOBJ_CHANGE);
977
978         return 0;
979 }
980 EXPORT_SYMBOL_GPL(typec_plug_set_num_altmodes);
981
982 /**
983  * typec_plug_register_altmode - Register USB Type-C Cable Plug Alternate Mode
984  * @plug: USB Type-C Cable Plug that supports the alternate mode
985  * @desc: Description of the alternate mode
986  *
987  * This routine is used to register each alternate mode individually that @plug
988  * has listed in response to Discover SVIDs command. The modes for a SVID that
989  * the plug lists in response to Discover Modes command need to be listed in an
990  * array in @desc.
991  *
992  * Returns handle to the alternate mode on success or ERR_PTR on failure.
993  */
994 struct typec_altmode *
995 typec_plug_register_altmode(struct typec_plug *plug,
996                             const struct typec_altmode_desc *desc)
997 {
998         return typec_register_altmode(&plug->dev, desc);
999 }
1000 EXPORT_SYMBOL_GPL(typec_plug_register_altmode);
1001
1002 /**
1003  * typec_register_plug - Register a USB Type-C Cable Plug
1004  * @cable: USB Type-C Cable with the plug
1005  * @desc: Description of the cable plug
1006  *
1007  * Registers a device for USB Type-C Cable Plug described in @desc. A USB Type-C
1008  * Cable Plug represents a plug with electronics in it that can response to USB
1009  * Power Delivery SOP Prime or SOP Double Prime packages.
1010  *
1011  * Returns handle to the cable plug on success or ERR_PTR on failure.
1012  */
1013 struct typec_plug *typec_register_plug(struct typec_cable *cable,
1014                                        struct typec_plug_desc *desc)
1015 {
1016         struct typec_plug *plug;
1017         char name[8];
1018         int ret;
1019
1020         plug = kzalloc(sizeof(*plug), GFP_KERNEL);
1021         if (!plug)
1022                 return ERR_PTR(-ENOMEM);
1023
1024         sprintf(name, "plug%d", desc->index);
1025
1026         ida_init(&plug->mode_ids);
1027         plug->num_altmodes = -1;
1028         plug->index = desc->index;
1029         plug->dev.class = typec_class;
1030         plug->dev.parent = &cable->dev;
1031         plug->dev.type = &typec_plug_dev_type;
1032         dev_set_name(&plug->dev, "%s-%s", dev_name(cable->dev.parent), name);
1033
1034         ret = device_register(&plug->dev);
1035         if (ret) {
1036                 dev_err(&cable->dev, "failed to register plug (%d)\n", ret);
1037                 put_device(&plug->dev);
1038                 return ERR_PTR(ret);
1039         }
1040
1041         return plug;
1042 }
1043 EXPORT_SYMBOL_GPL(typec_register_plug);
1044
1045 /**
1046  * typec_unregister_plug - Unregister a USB Type-C Cable Plug
1047  * @plug: The cable plug to be unregistered
1048  *
1049  * Unregister device created with typec_register_plug().
1050  */
1051 void typec_unregister_plug(struct typec_plug *plug)
1052 {
1053         if (!IS_ERR_OR_NULL(plug))
1054                 device_unregister(&plug->dev);
1055 }
1056 EXPORT_SYMBOL_GPL(typec_unregister_plug);
1057
1058 /* Type-C Cables */
1059
1060 static const char * const typec_plug_types[] = {
1061         [USB_PLUG_NONE]         = "unknown",
1062         [USB_PLUG_TYPE_A]       = "type-a",
1063         [USB_PLUG_TYPE_B]       = "type-b",
1064         [USB_PLUG_TYPE_C]       = "type-c",
1065         [USB_PLUG_CAPTIVE]      = "captive",
1066 };
1067
1068 static ssize_t plug_type_show(struct device *dev,
1069                               struct device_attribute *attr, char *buf)
1070 {
1071         struct typec_cable *cable = to_typec_cable(dev);
1072
1073         return sprintf(buf, "%s\n", typec_plug_types[cable->type]);
1074 }
1075 static DEVICE_ATTR_RO(plug_type);
1076
1077 static struct attribute *typec_cable_attrs[] = {
1078         &dev_attr_type.attr,
1079         &dev_attr_plug_type.attr,
1080         &dev_attr_usb_power_delivery_revision.attr,
1081         NULL
1082 };
1083 ATTRIBUTE_GROUPS(typec_cable);
1084
1085 static void typec_cable_release(struct device *dev)
1086 {
1087         struct typec_cable *cable = to_typec_cable(dev);
1088
1089         kfree(cable);
1090 }
1091
1092 static const struct device_type typec_cable_dev_type = {
1093         .name = "typec_cable",
1094         .groups = typec_cable_groups,
1095         .release = typec_cable_release,
1096 };
1097
1098 static int cable_match(struct device *dev, void *data)
1099 {
1100         return is_typec_cable(dev);
1101 }
1102
1103 /**
1104  * typec_cable_get - Get a reference to the USB Type-C cable
1105  * @port: The USB Type-C Port the cable is connected to
1106  *
1107  * The caller must decrement the reference count with typec_cable_put() after
1108  * use.
1109  */
1110 struct typec_cable *typec_cable_get(struct typec_port *port)
1111 {
1112         struct device *dev;
1113
1114         dev = device_find_child(&port->dev, NULL, cable_match);
1115         if (!dev)
1116                 return NULL;
1117
1118         return to_typec_cable(dev);
1119 }
1120 EXPORT_SYMBOL_GPL(typec_cable_get);
1121
1122 /**
1123  * typec_cable_put - Decrement the reference count on USB Type-C cable
1124  * @cable: The USB Type-C cable
1125  */
1126 void typec_cable_put(struct typec_cable *cable)
1127 {
1128         put_device(&cable->dev);
1129 }
1130 EXPORT_SYMBOL_GPL(typec_cable_put);
1131
1132 /**
1133  * typec_cable_is_active - Check is the USB Type-C cable active or passive
1134  * @cable: The USB Type-C Cable
1135  *
1136  * Return 1 if the cable is active or 0 if it's passive.
1137  */
1138 int typec_cable_is_active(struct typec_cable *cable)
1139 {
1140         return cable->active;
1141 }
1142 EXPORT_SYMBOL_GPL(typec_cable_is_active);
1143
1144 /**
1145  * typec_cable_set_identity - Report result from Discover Identity command
1146  * @cable: The cable updated identity values
1147  *
1148  * This routine is used to report that the result of Discover Identity USB power
1149  * delivery command has become available.
1150  */
1151 int typec_cable_set_identity(struct typec_cable *cable)
1152 {
1153         if (!cable->identity)
1154                 return -EINVAL;
1155
1156         typec_report_identity(&cable->dev);
1157         return 0;
1158 }
1159 EXPORT_SYMBOL_GPL(typec_cable_set_identity);
1160
1161 /**
1162  * typec_register_cable - Register a USB Type-C Cable
1163  * @port: The USB Type-C Port the cable is connected to
1164  * @desc: Description of the cable
1165  *
1166  * Registers a device for USB Type-C Cable described in @desc. The cable will be
1167  * parent for the optional cable plug devises.
1168  *
1169  * Returns handle to the cable on success or ERR_PTR on failure.
1170  */
1171 struct typec_cable *typec_register_cable(struct typec_port *port,
1172                                          struct typec_cable_desc *desc)
1173 {
1174         struct typec_cable *cable;
1175         int ret;
1176
1177         cable = kzalloc(sizeof(*cable), GFP_KERNEL);
1178         if (!cable)
1179                 return ERR_PTR(-ENOMEM);
1180
1181         cable->type = desc->type;
1182         cable->active = desc->active;
1183         cable->pd_revision = desc->pd_revision;
1184
1185         if (desc->identity) {
1186                 /*
1187                  * Creating directory for the identity only if the driver is
1188                  * able to provide data to it.
1189                  */
1190                 cable->dev.groups = usb_pd_id_groups;
1191                 cable->identity = desc->identity;
1192         }
1193
1194         cable->dev.class = typec_class;
1195         cable->dev.parent = &port->dev;
1196         cable->dev.type = &typec_cable_dev_type;
1197         dev_set_name(&cable->dev, "%s-cable", dev_name(&port->dev));
1198
1199         ret = device_register(&cable->dev);
1200         if (ret) {
1201                 dev_err(&port->dev, "failed to register cable (%d)\n", ret);
1202                 put_device(&cable->dev);
1203                 return ERR_PTR(ret);
1204         }
1205
1206         return cable;
1207 }
1208 EXPORT_SYMBOL_GPL(typec_register_cable);
1209
1210 /**
1211  * typec_unregister_cable - Unregister a USB Type-C Cable
1212  * @cable: The cable to be unregistered
1213  *
1214  * Unregister device created with typec_register_cable().
1215  */
1216 void typec_unregister_cable(struct typec_cable *cable)
1217 {
1218         if (!IS_ERR_OR_NULL(cable))
1219                 device_unregister(&cable->dev);
1220 }
1221 EXPORT_SYMBOL_GPL(typec_unregister_cable);
1222
1223 /* ------------------------------------------------------------------------- */
1224 /* USB Type-C ports */
1225
1226 static const char * const typec_orientations[] = {
1227         [TYPEC_ORIENTATION_NONE]        = "unknown",
1228         [TYPEC_ORIENTATION_NORMAL]      = "normal",
1229         [TYPEC_ORIENTATION_REVERSE]     = "reverse",
1230 };
1231
1232 static const char * const typec_roles[] = {
1233         [TYPEC_SINK]    = "sink",
1234         [TYPEC_SOURCE]  = "source",
1235 };
1236
1237 static const char * const typec_data_roles[] = {
1238         [TYPEC_DEVICE]  = "device",
1239         [TYPEC_HOST]    = "host",
1240 };
1241
1242 static const char * const typec_port_power_roles[] = {
1243         [TYPEC_PORT_SRC] = "source",
1244         [TYPEC_PORT_SNK] = "sink",
1245         [TYPEC_PORT_DRP] = "dual",
1246 };
1247
1248 static const char * const typec_port_data_roles[] = {
1249         [TYPEC_PORT_DFP] = "host",
1250         [TYPEC_PORT_UFP] = "device",
1251         [TYPEC_PORT_DRD] = "dual",
1252 };
1253
1254 static const char * const typec_port_types_drp[] = {
1255         [TYPEC_PORT_SRC] = "dual [source] sink",
1256         [TYPEC_PORT_SNK] = "dual source [sink]",
1257         [TYPEC_PORT_DRP] = "[dual] source sink",
1258 };
1259
1260 static ssize_t
1261 preferred_role_store(struct device *dev, struct device_attribute *attr,
1262                      const char *buf, size_t size)
1263 {
1264         struct typec_port *port = to_typec_port(dev);
1265         int role;
1266         int ret;
1267
1268         if (port->cap->type != TYPEC_PORT_DRP) {
1269                 dev_dbg(dev, "Preferred role only supported with DRP ports\n");
1270                 return -EOPNOTSUPP;
1271         }
1272
1273         if (!port->ops || !port->ops->try_role) {
1274                 dev_dbg(dev, "Setting preferred role not supported\n");
1275                 return -EOPNOTSUPP;
1276         }
1277
1278         role = sysfs_match_string(typec_roles, buf);
1279         if (role < 0) {
1280                 if (sysfs_streq(buf, "none"))
1281                         role = TYPEC_NO_PREFERRED_ROLE;
1282                 else
1283                         return -EINVAL;
1284         }
1285
1286         ret = port->ops->try_role(port, role);
1287         if (ret)
1288                 return ret;
1289
1290         port->prefer_role = role;
1291         return size;
1292 }
1293
1294 static ssize_t
1295 preferred_role_show(struct device *dev, struct device_attribute *attr,
1296                     char *buf)
1297 {
1298         struct typec_port *port = to_typec_port(dev);
1299
1300         if (port->cap->type != TYPEC_PORT_DRP)
1301                 return 0;
1302
1303         if (port->prefer_role < 0)
1304                 return 0;
1305
1306         return sprintf(buf, "%s\n", typec_roles[port->prefer_role]);
1307 }
1308 static DEVICE_ATTR_RW(preferred_role);
1309
1310 static ssize_t data_role_store(struct device *dev,
1311                                struct device_attribute *attr,
1312                                const char *buf, size_t size)
1313 {
1314         struct typec_port *port = to_typec_port(dev);
1315         int ret;
1316
1317         if (!port->ops || !port->ops->dr_set) {
1318                 dev_dbg(dev, "data role swapping not supported\n");
1319                 return -EOPNOTSUPP;
1320         }
1321
1322         ret = sysfs_match_string(typec_data_roles, buf);
1323         if (ret < 0)
1324                 return ret;
1325
1326         mutex_lock(&port->port_type_lock);
1327         if (port->cap->data != TYPEC_PORT_DRD) {
1328                 ret = -EOPNOTSUPP;
1329                 goto unlock_and_ret;
1330         }
1331
1332         ret = port->ops->dr_set(port, ret);
1333         if (ret)
1334                 goto unlock_and_ret;
1335
1336         ret = size;
1337 unlock_and_ret:
1338         mutex_unlock(&port->port_type_lock);
1339         return ret;
1340 }
1341
1342 static ssize_t data_role_show(struct device *dev,
1343                               struct device_attribute *attr, char *buf)
1344 {
1345         struct typec_port *port = to_typec_port(dev);
1346
1347         if (port->cap->data == TYPEC_PORT_DRD)
1348                 return sprintf(buf, "%s\n", port->data_role == TYPEC_HOST ?
1349                                "[host] device" : "host [device]");
1350
1351         return sprintf(buf, "[%s]\n", typec_data_roles[port->data_role]);
1352 }
1353 static DEVICE_ATTR_RW(data_role);
1354
1355 static ssize_t power_role_store(struct device *dev,
1356                                 struct device_attribute *attr,
1357                                 const char *buf, size_t size)
1358 {
1359         struct typec_port *port = to_typec_port(dev);
1360         int ret;
1361
1362         if (!port->ops || !port->ops->pr_set) {
1363                 dev_dbg(dev, "power role swapping not supported\n");
1364                 return -EOPNOTSUPP;
1365         }
1366
1367         if (port->pwr_opmode != TYPEC_PWR_MODE_PD) {
1368                 dev_dbg(dev, "partner unable to swap power role\n");
1369                 return -EIO;
1370         }
1371
1372         ret = sysfs_match_string(typec_roles, buf);
1373         if (ret < 0)
1374                 return ret;
1375
1376         mutex_lock(&port->port_type_lock);
1377         if (port->port_type != TYPEC_PORT_DRP) {
1378                 dev_dbg(dev, "port type fixed at \"%s\"",
1379                              typec_port_power_roles[port->port_type]);
1380                 ret = -EOPNOTSUPP;
1381                 goto unlock_and_ret;
1382         }
1383
1384         ret = port->ops->pr_set(port, ret);
1385         if (ret)
1386                 goto unlock_and_ret;
1387
1388         ret = size;
1389 unlock_and_ret:
1390         mutex_unlock(&port->port_type_lock);
1391         return ret;
1392 }
1393
1394 static ssize_t power_role_show(struct device *dev,
1395                                struct device_attribute *attr, char *buf)
1396 {
1397         struct typec_port *port = to_typec_port(dev);
1398
1399         if (port->cap->type == TYPEC_PORT_DRP)
1400                 return sprintf(buf, "%s\n", port->pwr_role == TYPEC_SOURCE ?
1401                                "[source] sink" : "source [sink]");
1402
1403         return sprintf(buf, "[%s]\n", typec_roles[port->pwr_role]);
1404 }
1405 static DEVICE_ATTR_RW(power_role);
1406
1407 static ssize_t
1408 port_type_store(struct device *dev, struct device_attribute *attr,
1409                         const char *buf, size_t size)
1410 {
1411         struct typec_port *port = to_typec_port(dev);
1412         int ret;
1413         enum typec_port_type type;
1414
1415         if (port->cap->type != TYPEC_PORT_DRP ||
1416             !port->ops || !port->ops->port_type_set) {
1417                 dev_dbg(dev, "changing port type not supported\n");
1418                 return -EOPNOTSUPP;
1419         }
1420
1421         ret = sysfs_match_string(typec_port_power_roles, buf);
1422         if (ret < 0)
1423                 return ret;
1424
1425         type = ret;
1426         mutex_lock(&port->port_type_lock);
1427
1428         if (port->port_type == type) {
1429                 ret = size;
1430                 goto unlock_and_ret;
1431         }
1432
1433         ret = port->ops->port_type_set(port, type);
1434         if (ret)
1435                 goto unlock_and_ret;
1436
1437         port->port_type = type;
1438         ret = size;
1439
1440 unlock_and_ret:
1441         mutex_unlock(&port->port_type_lock);
1442         return ret;
1443 }
1444
1445 static ssize_t
1446 port_type_show(struct device *dev, struct device_attribute *attr,
1447                 char *buf)
1448 {
1449         struct typec_port *port = to_typec_port(dev);
1450
1451         if (port->cap->type == TYPEC_PORT_DRP)
1452                 return sprintf(buf, "%s\n",
1453                                typec_port_types_drp[port->port_type]);
1454
1455         return sprintf(buf, "[%s]\n", typec_port_power_roles[port->cap->type]);
1456 }
1457 static DEVICE_ATTR_RW(port_type);
1458
1459 static const char * const typec_pwr_opmodes[] = {
1460         [TYPEC_PWR_MODE_USB]    = "default",
1461         [TYPEC_PWR_MODE_1_5A]   = "1.5A",
1462         [TYPEC_PWR_MODE_3_0A]   = "3.0A",
1463         [TYPEC_PWR_MODE_PD]     = "usb_power_delivery",
1464 };
1465
1466 static ssize_t power_operation_mode_show(struct device *dev,
1467                                          struct device_attribute *attr,
1468                                          char *buf)
1469 {
1470         struct typec_port *port = to_typec_port(dev);
1471
1472         return sprintf(buf, "%s\n", typec_pwr_opmodes[port->pwr_opmode]);
1473 }
1474 static DEVICE_ATTR_RO(power_operation_mode);
1475
1476 static ssize_t vconn_source_store(struct device *dev,
1477                                   struct device_attribute *attr,
1478                                   const char *buf, size_t size)
1479 {
1480         struct typec_port *port = to_typec_port(dev);
1481         bool source;
1482         int ret;
1483
1484         if (!port->cap->pd_revision) {
1485                 dev_dbg(dev, "VCONN swap depends on USB Power Delivery\n");
1486                 return -EOPNOTSUPP;
1487         }
1488
1489         if (!port->ops || !port->ops->vconn_set) {
1490                 dev_dbg(dev, "VCONN swapping not supported\n");
1491                 return -EOPNOTSUPP;
1492         }
1493
1494         ret = kstrtobool(buf, &source);
1495         if (ret)
1496                 return ret;
1497
1498         ret = port->ops->vconn_set(port, (enum typec_role)source);
1499         if (ret)
1500                 return ret;
1501
1502         return size;
1503 }
1504
1505 static ssize_t vconn_source_show(struct device *dev,
1506                                  struct device_attribute *attr, char *buf)
1507 {
1508         struct typec_port *port = to_typec_port(dev);
1509
1510         return sprintf(buf, "%s\n",
1511                        port->vconn_role == TYPEC_SOURCE ? "yes" : "no");
1512 }
1513 static DEVICE_ATTR_RW(vconn_source);
1514
1515 static ssize_t supported_accessory_modes_show(struct device *dev,
1516                                               struct device_attribute *attr,
1517                                               char *buf)
1518 {
1519         struct typec_port *port = to_typec_port(dev);
1520         ssize_t ret = 0;
1521         int i;
1522
1523         for (i = 0; i < ARRAY_SIZE(port->cap->accessory); i++) {
1524                 if (port->cap->accessory[i])
1525                         ret += sprintf(buf + ret, "%s ",
1526                                typec_accessory_modes[port->cap->accessory[i]]);
1527         }
1528
1529         if (!ret)
1530                 return sprintf(buf, "none\n");
1531
1532         buf[ret - 1] = '\n';
1533
1534         return ret;
1535 }
1536 static DEVICE_ATTR_RO(supported_accessory_modes);
1537
1538 static ssize_t usb_typec_revision_show(struct device *dev,
1539                                        struct device_attribute *attr,
1540                                        char *buf)
1541 {
1542         struct typec_port *port = to_typec_port(dev);
1543         u16 rev = port->cap->revision;
1544
1545         return sprintf(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf);
1546 }
1547 static DEVICE_ATTR_RO(usb_typec_revision);
1548
1549 static ssize_t usb_power_delivery_revision_show(struct device *dev,
1550                                                 struct device_attribute *attr,
1551                                                 char *buf)
1552 {
1553         u16 rev = 0;
1554
1555         if (is_typec_partner(dev)) {
1556                 struct typec_partner *partner = to_typec_partner(dev);
1557
1558                 rev = partner->pd_revision;
1559         } else if (is_typec_cable(dev)) {
1560                 struct typec_cable *cable = to_typec_cable(dev);
1561
1562                 rev = cable->pd_revision;
1563         } else if (is_typec_port(dev)) {
1564                 struct typec_port *p = to_typec_port(dev);
1565
1566                 rev = p->cap->pd_revision;
1567         }
1568         return sysfs_emit(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf);
1569 }
1570
1571 static ssize_t orientation_show(struct device *dev,
1572                                    struct device_attribute *attr,
1573                                    char *buf)
1574 {
1575         struct typec_port *port = to_typec_port(dev);
1576
1577         return sprintf(buf, "%s\n", typec_orientations[port->orientation]);
1578 }
1579 static DEVICE_ATTR_RO(orientation);
1580
1581 static struct attribute *typec_attrs[] = {
1582         &dev_attr_data_role.attr,
1583         &dev_attr_power_operation_mode.attr,
1584         &dev_attr_power_role.attr,
1585         &dev_attr_preferred_role.attr,
1586         &dev_attr_supported_accessory_modes.attr,
1587         &dev_attr_usb_power_delivery_revision.attr,
1588         &dev_attr_usb_typec_revision.attr,
1589         &dev_attr_vconn_source.attr,
1590         &dev_attr_port_type.attr,
1591         &dev_attr_orientation.attr,
1592         NULL,
1593 };
1594
1595 static umode_t typec_attr_is_visible(struct kobject *kobj,
1596                                      struct attribute *attr, int n)
1597 {
1598         struct typec_port *port = to_typec_port(kobj_to_dev(kobj));
1599
1600         if (attr == &dev_attr_data_role.attr) {
1601                 if (port->cap->data != TYPEC_PORT_DRD ||
1602                     !port->ops || !port->ops->dr_set)
1603                         return 0444;
1604         } else if (attr == &dev_attr_power_role.attr) {
1605                 if (port->cap->type != TYPEC_PORT_DRP ||
1606                     !port->ops || !port->ops->pr_set)
1607                         return 0444;
1608         } else if (attr == &dev_attr_vconn_source.attr) {
1609                 if (!port->cap->pd_revision ||
1610                     !port->ops || !port->ops->vconn_set)
1611                         return 0444;
1612         } else if (attr == &dev_attr_preferred_role.attr) {
1613                 if (port->cap->type != TYPEC_PORT_DRP ||
1614                     !port->ops || !port->ops->try_role)
1615                         return 0444;
1616         } else if (attr == &dev_attr_port_type.attr) {
1617                 if (!port->ops || !port->ops->port_type_set)
1618                         return 0;
1619                 if (port->cap->type != TYPEC_PORT_DRP)
1620                         return 0444;
1621         } else if (attr == &dev_attr_orientation.attr) {
1622                 if (port->cap->orientation_aware)
1623                         return 0444;
1624                 return 0;
1625         }
1626
1627         return attr->mode;
1628 }
1629
1630 static const struct attribute_group typec_group = {
1631         .is_visible = typec_attr_is_visible,
1632         .attrs = typec_attrs,
1633 };
1634
1635 static const struct attribute_group *typec_groups[] = {
1636         &typec_group,
1637         NULL
1638 };
1639
1640 static int typec_uevent(struct device *dev, struct kobj_uevent_env *env)
1641 {
1642         int ret;
1643
1644         ret = add_uevent_var(env, "TYPEC_PORT=%s", dev_name(dev));
1645         if (ret)
1646                 dev_err(dev, "failed to add uevent TYPEC_PORT\n");
1647
1648         return ret;
1649 }
1650
1651 static void typec_release(struct device *dev)
1652 {
1653         struct typec_port *port = to_typec_port(dev);
1654
1655         ida_simple_remove(&typec_index_ida, port->id);
1656         ida_destroy(&port->mode_ids);
1657         typec_switch_put(port->sw);
1658         typec_mux_put(port->mux);
1659         kfree(port->cap);
1660         kfree(port);
1661 }
1662
1663 const struct device_type typec_port_dev_type = {
1664         .name = "typec_port",
1665         .groups = typec_groups,
1666         .uevent = typec_uevent,
1667         .release = typec_release,
1668 };
1669
1670 /* --------------------------------------- */
1671 /* Driver callbacks to report role updates */
1672
1673 static int partner_match(struct device *dev, void *data)
1674 {
1675         return is_typec_partner(dev);
1676 }
1677
1678 /**
1679  * typec_set_data_role - Report data role change
1680  * @port: The USB Type-C Port where the role was changed
1681  * @role: The new data role
1682  *
1683  * This routine is used by the port drivers to report data role changes.
1684  */
1685 void typec_set_data_role(struct typec_port *port, enum typec_data_role role)
1686 {
1687         struct device *partner_dev;
1688
1689         if (port->data_role == role)
1690                 return;
1691
1692         port->data_role = role;
1693         sysfs_notify(&port->dev.kobj, NULL, "data_role");
1694         kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
1695
1696         partner_dev = device_find_child(&port->dev, NULL, partner_match);
1697         if (!partner_dev)
1698                 return;
1699
1700         if (to_typec_partner(partner_dev)->identity)
1701                 typec_product_type_notify(partner_dev);
1702
1703         put_device(partner_dev);
1704 }
1705 EXPORT_SYMBOL_GPL(typec_set_data_role);
1706
1707 /**
1708  * typec_set_pwr_role - Report power role change
1709  * @port: The USB Type-C Port where the role was changed
1710  * @role: The new data role
1711  *
1712  * This routine is used by the port drivers to report power role changes.
1713  */
1714 void typec_set_pwr_role(struct typec_port *port, enum typec_role role)
1715 {
1716         if (port->pwr_role == role)
1717                 return;
1718
1719         port->pwr_role = role;
1720         sysfs_notify(&port->dev.kobj, NULL, "power_role");
1721         kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
1722 }
1723 EXPORT_SYMBOL_GPL(typec_set_pwr_role);
1724
1725 /**
1726  * typec_set_vconn_role - Report VCONN source change
1727  * @port: The USB Type-C Port which VCONN role changed
1728  * @role: Source when @port is sourcing VCONN, or Sink when it's not
1729  *
1730  * This routine is used by the port drivers to report if the VCONN source is
1731  * changes.
1732  */
1733 void typec_set_vconn_role(struct typec_port *port, enum typec_role role)
1734 {
1735         if (port->vconn_role == role)
1736                 return;
1737
1738         port->vconn_role = role;
1739         sysfs_notify(&port->dev.kobj, NULL, "vconn_source");
1740         kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
1741 }
1742 EXPORT_SYMBOL_GPL(typec_set_vconn_role);
1743
1744 /**
1745  * typec_set_pwr_opmode - Report changed power operation mode
1746  * @port: The USB Type-C Port where the mode was changed
1747  * @opmode: New power operation mode
1748  *
1749  * This routine is used by the port drivers to report changed power operation
1750  * mode in @port. The modes are USB (default), 1.5A, 3.0A as defined in USB
1751  * Type-C specification, and "USB Power Delivery" when the power levels are
1752  * negotiated with methods defined in USB Power Delivery specification.
1753  */
1754 void typec_set_pwr_opmode(struct typec_port *port,
1755                           enum typec_pwr_opmode opmode)
1756 {
1757         struct device *partner_dev;
1758
1759         if (port->pwr_opmode == opmode)
1760                 return;
1761
1762         port->pwr_opmode = opmode;
1763         sysfs_notify(&port->dev.kobj, NULL, "power_operation_mode");
1764         kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
1765
1766         partner_dev = device_find_child(&port->dev, NULL, partner_match);
1767         if (partner_dev) {
1768                 struct typec_partner *partner = to_typec_partner(partner_dev);
1769
1770                 if (opmode == TYPEC_PWR_MODE_PD && !partner->usb_pd) {
1771                         partner->usb_pd = 1;
1772                         sysfs_notify(&partner_dev->kobj, NULL,
1773                                      "supports_usb_power_delivery");
1774                 }
1775                 put_device(partner_dev);
1776         }
1777 }
1778 EXPORT_SYMBOL_GPL(typec_set_pwr_opmode);
1779
1780 /**
1781  * typec_find_pwr_opmode - Get the typec power operation mode capability
1782  * @name: power operation mode string
1783  *
1784  * This routine is used to find the typec_pwr_opmode by its string @name.
1785  *
1786  * Returns typec_pwr_opmode if success, otherwise negative error code.
1787  */
1788 int typec_find_pwr_opmode(const char *name)
1789 {
1790         return match_string(typec_pwr_opmodes,
1791                             ARRAY_SIZE(typec_pwr_opmodes), name);
1792 }
1793 EXPORT_SYMBOL_GPL(typec_find_pwr_opmode);
1794
1795 /**
1796  * typec_find_orientation - Convert orientation string to enum typec_orientation
1797  * @name: Orientation string
1798  *
1799  * This routine is used to find the typec_orientation by its string name @name.
1800  *
1801  * Returns the orientation value on success, otherwise negative error code.
1802  */
1803 int typec_find_orientation(const char *name)
1804 {
1805         return match_string(typec_orientations, ARRAY_SIZE(typec_orientations),
1806                             name);
1807 }
1808 EXPORT_SYMBOL_GPL(typec_find_orientation);
1809
1810 /**
1811  * typec_find_port_power_role - Get the typec port power capability
1812  * @name: port power capability string
1813  *
1814  * This routine is used to find the typec_port_type by its string name.
1815  *
1816  * Returns typec_port_type if success, otherwise negative error code.
1817  */
1818 int typec_find_port_power_role(const char *name)
1819 {
1820         return match_string(typec_port_power_roles,
1821                             ARRAY_SIZE(typec_port_power_roles), name);
1822 }
1823 EXPORT_SYMBOL_GPL(typec_find_port_power_role);
1824
1825 /**
1826  * typec_find_power_role - Find the typec one specific power role
1827  * @name: power role string
1828  *
1829  * This routine is used to find the typec_role by its string name.
1830  *
1831  * Returns typec_role if success, otherwise negative error code.
1832  */
1833 int typec_find_power_role(const char *name)
1834 {
1835         return match_string(typec_roles, ARRAY_SIZE(typec_roles), name);
1836 }
1837 EXPORT_SYMBOL_GPL(typec_find_power_role);
1838
1839 /**
1840  * typec_find_port_data_role - Get the typec port data capability
1841  * @name: port data capability string
1842  *
1843  * This routine is used to find the typec_port_data by its string name.
1844  *
1845  * Returns typec_port_data if success, otherwise negative error code.
1846  */
1847 int typec_find_port_data_role(const char *name)
1848 {
1849         return match_string(typec_port_data_roles,
1850                             ARRAY_SIZE(typec_port_data_roles), name);
1851 }
1852 EXPORT_SYMBOL_GPL(typec_find_port_data_role);
1853
1854 /* ------------------------------------------ */
1855 /* API for Multiplexer/DeMultiplexer Switches */
1856
1857 /**
1858  * typec_set_orientation - Set USB Type-C cable plug orientation
1859  * @port: USB Type-C Port
1860  * @orientation: USB Type-C cable plug orientation
1861  *
1862  * Set cable plug orientation for @port.
1863  */
1864 int typec_set_orientation(struct typec_port *port,
1865                           enum typec_orientation orientation)
1866 {
1867         int ret;
1868
1869         ret = typec_switch_set(port->sw, orientation);
1870         if (ret)
1871                 return ret;
1872
1873         port->orientation = orientation;
1874         sysfs_notify(&port->dev.kobj, NULL, "orientation");
1875         kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
1876
1877         return 0;
1878 }
1879 EXPORT_SYMBOL_GPL(typec_set_orientation);
1880
1881 /**
1882  * typec_get_orientation - Get USB Type-C cable plug orientation
1883  * @port: USB Type-C Port
1884  *
1885  * Get current cable plug orientation for @port.
1886  */
1887 enum typec_orientation typec_get_orientation(struct typec_port *port)
1888 {
1889         return port->orientation;
1890 }
1891 EXPORT_SYMBOL_GPL(typec_get_orientation);
1892
1893 /**
1894  * typec_set_mode - Set mode of operation for USB Type-C connector
1895  * @port: USB Type-C connector
1896  * @mode: Accessory Mode, USB Operation or Safe State
1897  *
1898  * Configure @port for Accessory Mode @mode. This function will configure the
1899  * muxes needed for @mode.
1900  */
1901 int typec_set_mode(struct typec_port *port, int mode)
1902 {
1903         struct typec_mux_state state = { };
1904
1905         state.mode = mode;
1906
1907         return typec_mux_set(port->mux, &state);
1908 }
1909 EXPORT_SYMBOL_GPL(typec_set_mode);
1910
1911 /* --------------------------------------- */
1912
1913 /**
1914  * typec_get_negotiated_svdm_version - Get negotiated SVDM Version
1915  * @port: USB Type-C Port.
1916  *
1917  * Get the negotiated SVDM Version. The Version is set to the port default
1918  * value stored in typec_capability on partner registration, and updated after
1919  * a successful Discover Identity if the negotiated value is less than the
1920  * default value.
1921  *
1922  * Returns usb_pd_svdm_ver if the partner has been registered otherwise -ENODEV.
1923  */
1924 int typec_get_negotiated_svdm_version(struct typec_port *port)
1925 {
1926         enum usb_pd_svdm_ver svdm_version;
1927         struct device *partner_dev;
1928
1929         partner_dev = device_find_child(&port->dev, NULL, partner_match);
1930         if (!partner_dev)
1931                 return -ENODEV;
1932
1933         svdm_version = to_typec_partner(partner_dev)->svdm_version;
1934         put_device(partner_dev);
1935
1936         return svdm_version;
1937 }
1938 EXPORT_SYMBOL_GPL(typec_get_negotiated_svdm_version);
1939
1940 /**
1941  * typec_get_drvdata - Return private driver data pointer
1942  * @port: USB Type-C port
1943  */
1944 void *typec_get_drvdata(struct typec_port *port)
1945 {
1946         return dev_get_drvdata(&port->dev);
1947 }
1948 EXPORT_SYMBOL_GPL(typec_get_drvdata);
1949
1950 /**
1951  * typec_port_register_altmode - Register USB Type-C Port Alternate Mode
1952  * @port: USB Type-C Port that supports the alternate mode
1953  * @desc: Description of the alternate mode
1954  *
1955  * This routine is used to register an alternate mode that @port is capable of
1956  * supporting.
1957  *
1958  * Returns handle to the alternate mode on success or ERR_PTR on failure.
1959  */
1960 struct typec_altmode *
1961 typec_port_register_altmode(struct typec_port *port,
1962                             const struct typec_altmode_desc *desc)
1963 {
1964         struct typec_altmode *adev;
1965         struct typec_mux *mux;
1966
1967         mux = typec_mux_get(&port->dev, desc);
1968         if (IS_ERR(mux))
1969                 return ERR_CAST(mux);
1970
1971         adev = typec_register_altmode(&port->dev, desc);
1972         if (IS_ERR(adev))
1973                 typec_mux_put(mux);
1974         else
1975                 to_altmode(adev)->mux = mux;
1976
1977         return adev;
1978 }
1979 EXPORT_SYMBOL_GPL(typec_port_register_altmode);
1980
1981 /**
1982  * typec_register_port - Register a USB Type-C Port
1983  * @parent: Parent device
1984  * @cap: Description of the port
1985  *
1986  * Registers a device for USB Type-C Port described in @cap.
1987  *
1988  * Returns handle to the port on success or ERR_PTR on failure.
1989  */
1990 struct typec_port *typec_register_port(struct device *parent,
1991                                        const struct typec_capability *cap)
1992 {
1993         struct typec_port *port;
1994         int ret;
1995         int id;
1996
1997         port = kzalloc(sizeof(*port), GFP_KERNEL);
1998         if (!port)
1999                 return ERR_PTR(-ENOMEM);
2000
2001         id = ida_simple_get(&typec_index_ida, 0, 0, GFP_KERNEL);
2002         if (id < 0) {
2003                 kfree(port);
2004                 return ERR_PTR(id);
2005         }
2006
2007         switch (cap->type) {
2008         case TYPEC_PORT_SRC:
2009                 port->pwr_role = TYPEC_SOURCE;
2010                 port->vconn_role = TYPEC_SOURCE;
2011                 break;
2012         case TYPEC_PORT_SNK:
2013                 port->pwr_role = TYPEC_SINK;
2014                 port->vconn_role = TYPEC_SINK;
2015                 break;
2016         case TYPEC_PORT_DRP:
2017                 if (cap->prefer_role != TYPEC_NO_PREFERRED_ROLE)
2018                         port->pwr_role = cap->prefer_role;
2019                 else
2020                         port->pwr_role = TYPEC_SINK;
2021                 break;
2022         }
2023
2024         switch (cap->data) {
2025         case TYPEC_PORT_DFP:
2026                 port->data_role = TYPEC_HOST;
2027                 break;
2028         case TYPEC_PORT_UFP:
2029                 port->data_role = TYPEC_DEVICE;
2030                 break;
2031         case TYPEC_PORT_DRD:
2032                 if (cap->prefer_role == TYPEC_SOURCE)
2033                         port->data_role = TYPEC_HOST;
2034                 else
2035                         port->data_role = TYPEC_DEVICE;
2036                 break;
2037         }
2038
2039         ida_init(&port->mode_ids);
2040         mutex_init(&port->port_type_lock);
2041
2042         port->id = id;
2043         port->ops = cap->ops;
2044         port->port_type = cap->type;
2045         port->prefer_role = cap->prefer_role;
2046
2047         device_initialize(&port->dev);
2048         port->dev.class = typec_class;
2049         port->dev.parent = parent;
2050         port->dev.fwnode = cap->fwnode;
2051         port->dev.type = &typec_port_dev_type;
2052         dev_set_name(&port->dev, "port%d", id);
2053         dev_set_drvdata(&port->dev, cap->driver_data);
2054
2055         port->cap = kmemdup(cap, sizeof(*cap), GFP_KERNEL);
2056         if (!port->cap) {
2057                 put_device(&port->dev);
2058                 return ERR_PTR(-ENOMEM);
2059         }
2060
2061         port->sw = typec_switch_get(&port->dev);
2062         if (IS_ERR(port->sw)) {
2063                 ret = PTR_ERR(port->sw);
2064                 put_device(&port->dev);
2065                 return ERR_PTR(ret);
2066         }
2067
2068         port->mux = typec_mux_get(&port->dev, NULL);
2069         if (IS_ERR(port->mux)) {
2070                 ret = PTR_ERR(port->mux);
2071                 put_device(&port->dev);
2072                 return ERR_PTR(ret);
2073         }
2074
2075         ret = device_add(&port->dev);
2076         if (ret) {
2077                 dev_err(parent, "failed to register port (%d)\n", ret);
2078                 put_device(&port->dev);
2079                 return ERR_PTR(ret);
2080         }
2081
2082         return port;
2083 }
2084 EXPORT_SYMBOL_GPL(typec_register_port);
2085
2086 /**
2087  * typec_unregister_port - Unregister a USB Type-C Port
2088  * @port: The port to be unregistered
2089  *
2090  * Unregister device created with typec_register_port().
2091  */
2092 void typec_unregister_port(struct typec_port *port)
2093 {
2094         if (!IS_ERR_OR_NULL(port))
2095                 device_unregister(&port->dev);
2096 }
2097 EXPORT_SYMBOL_GPL(typec_unregister_port);
2098
2099 static int __init typec_init(void)
2100 {
2101         int ret;
2102
2103         ret = bus_register(&typec_bus);
2104         if (ret)
2105                 return ret;
2106
2107         ret = class_register(&typec_mux_class);
2108         if (ret)
2109                 goto err_unregister_bus;
2110
2111         typec_class = class_create(THIS_MODULE, "typec");
2112         if (IS_ERR(typec_class)) {
2113                 ret = PTR_ERR(typec_class);
2114                 goto err_unregister_mux_class;
2115         }
2116
2117         return 0;
2118
2119 err_unregister_mux_class:
2120         class_unregister(&typec_mux_class);
2121
2122 err_unregister_bus:
2123         bus_unregister(&typec_bus);
2124
2125         return ret;
2126 }
2127 subsys_initcall(typec_init);
2128
2129 static void __exit typec_exit(void)
2130 {
2131         class_destroy(typec_class);
2132         ida_destroy(&typec_index_ida);
2133         bus_unregister(&typec_bus);
2134         class_unregister(&typec_mux_class);
2135 }
2136 module_exit(typec_exit);
2137
2138 MODULE_AUTHOR("Heikki Krogerus <[email protected]>");
2139 MODULE_LICENSE("GPL v2");
2140 MODULE_DESCRIPTION("USB Type-C Connector Class");
This page took 0.162243 seconds and 4 git commands to generate.