File Index
Files and directories
Sign in
FILE

class.c

File preview with syntax highlighting.

linux-6.19.14/drivers/usb/typec/class.c 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 <heikki.krogerus@linux.intel.com>
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/mutex.h>
  11#include <linux/property.h>
  12#include <linux/slab.h>
  13#include <linux/string_choices.h>
  14#include <linux/usb/pd_vdo.h>
  15#include <linux/usb/typec_mux.h>
  16#include <linux/usb/typec_retimer.h>
  17#include <linux/usb.h>
  18
  19#include "bus.h"
  20#include "class.h"
  21#include "pd.h"
  22
  23static DEFINE_IDA(typec_index_ida);
  24
  25const struct class typec_class = {
  26	.name = "typec",
  27};
  28
  29/* ------------------------------------------------------------------------- */
  30/* Common attributes */
  31
  32static const char * const typec_accessory_modes[] = {
  33	[TYPEC_ACCESSORY_NONE]		= "none",
  34	[TYPEC_ACCESSORY_AUDIO]		= "analog_audio",
  35	[TYPEC_ACCESSORY_DEBUG]		= "debug",
  36};
  37
  38/* Product types defined in USB PD Specification R3.0 V2.0 */
  39static const char * const product_type_ufp[8] = {
  40	[IDH_PTYPE_NOT_UFP]		= "not_ufp",
  41	[IDH_PTYPE_HUB]			= "hub",
  42	[IDH_PTYPE_PERIPH]		= "peripheral",
  43	[IDH_PTYPE_PSD]			= "psd",
  44	[IDH_PTYPE_AMA]			= "ama",
  45};
  46
  47static const char * const product_type_dfp[8] = {
  48	[IDH_PTYPE_NOT_DFP]		= "not_dfp",
  49	[IDH_PTYPE_DFP_HUB]		= "hub",
  50	[IDH_PTYPE_DFP_HOST]		= "host",
  51	[IDH_PTYPE_DFP_PB]		= "power_brick",
  52};
  53
  54static const char * const product_type_cable[8] = {
  55	[IDH_PTYPE_NOT_CABLE]		= "not_cable",
  56	[IDH_PTYPE_PCABLE]		= "passive",
  57	[IDH_PTYPE_ACABLE]		= "active",
  58	[IDH_PTYPE_VPD]			= "vpd",
  59};
  60
  61static struct usb_pd_identity *get_pd_identity(struct device *dev)
  62{
  63	if (is_typec_partner(dev)) {
  64		struct typec_partner *partner = to_typec_partner(dev);
  65
  66		return partner->identity;
  67	} else if (is_typec_cable(dev)) {
  68		struct typec_cable *cable = to_typec_cable(dev);
  69
  70		return cable->identity;
  71	}
  72	return NULL;
  73}
  74
  75static const char *get_pd_product_type(struct device *dev)
  76{
  77	struct typec_port *port = to_typec_port(dev->parent);
  78	struct usb_pd_identity *id = get_pd_identity(dev);
  79	const char *ptype = NULL;
  80
  81	if (is_typec_partner(dev)) {
  82		if (!id)
  83			return NULL;
  84
  85		if (port->data_role == TYPEC_HOST)
  86			ptype = product_type_ufp[PD_IDH_PTYPE(id->id_header)];
  87		else
  88			ptype = product_type_dfp[PD_IDH_DFP_PTYPE(id->id_header)];
  89	} else if (is_typec_cable(dev)) {
  90		if (id)
  91			ptype = product_type_cable[PD_IDH_PTYPE(id->id_header)];
  92		else
  93			ptype = to_typec_cable(dev)->active ?
  94				product_type_cable[IDH_PTYPE_ACABLE] :
  95				product_type_cable[IDH_PTYPE_PCABLE];
  96	}
  97
  98	return ptype;
  99}
 100
 101static ssize_t id_header_show(struct device *dev, struct device_attribute *attr,
 102			      char *buf)
 103{
 104	struct usb_pd_identity *id = get_pd_identity(dev);
 105
 106	return sprintf(buf, "0x%08x\n", id->id_header);
 107}
 108static DEVICE_ATTR_RO(id_header);
 109
 110static ssize_t cert_stat_show(struct device *dev, struct device_attribute *attr,
 111			      char *buf)
 112{
 113	struct usb_pd_identity *id = get_pd_identity(dev);
 114
 115	return sprintf(buf, "0x%08x\n", id->cert_stat);
 116}
 117static DEVICE_ATTR_RO(cert_stat);
 118
 119static ssize_t product_show(struct device *dev, struct device_attribute *attr,
 120			    char *buf)
 121{
 122	struct usb_pd_identity *id = get_pd_identity(dev);
 123
 124	return sprintf(buf, "0x%08x\n", id->product);
 125}
 126static DEVICE_ATTR_RO(product);
 127
 128static ssize_t product_type_vdo1_show(struct device *dev, struct device_attribute *attr,
 129				      char *buf)
 130{
 131	struct usb_pd_identity *id = get_pd_identity(dev);
 132
 133	return sysfs_emit(buf, "0x%08x\n", id->vdo[0]);
 134}
 135static DEVICE_ATTR_RO(product_type_vdo1);
 136
 137static ssize_t product_type_vdo2_show(struct device *dev, struct device_attribute *attr,
 138				      char *buf)
 139{
 140	struct usb_pd_identity *id = get_pd_identity(dev);
 141
 142	return sysfs_emit(buf, "0x%08x\n", id->vdo[1]);
 143}
 144static DEVICE_ATTR_RO(product_type_vdo2);
 145
 146static ssize_t product_type_vdo3_show(struct device *dev, struct device_attribute *attr,
 147				      char *buf)
 148{
 149	struct usb_pd_identity *id = get_pd_identity(dev);
 150
 151	return sysfs_emit(buf, "0x%08x\n", id->vdo[2]);
 152}
 153static DEVICE_ATTR_RO(product_type_vdo3);
 154
 155static struct attribute *usb_pd_id_attrs[] = {
 156	&dev_attr_id_header.attr,
 157	&dev_attr_cert_stat.attr,
 158	&dev_attr_product.attr,
 159	&dev_attr_product_type_vdo1.attr,
 160	&dev_attr_product_type_vdo2.attr,
 161	&dev_attr_product_type_vdo3.attr,
 162	NULL
 163};
 164
 165static const struct attribute_group usb_pd_id_group = {
 166	.name = "identity",
 167	.attrs = usb_pd_id_attrs,
 168};
 169
 170static const struct attribute_group *usb_pd_id_groups[] = {
 171	&usb_pd_id_group,
 172	NULL,
 173};
 174
 175static void typec_product_type_notify(struct device *dev)
 176{
 177	char *envp[2] = { };
 178	const char *ptype;
 179
 180	ptype = get_pd_product_type(dev);
 181	if (!ptype)
 182		return;
 183
 184	sysfs_notify(&dev->kobj, NULL, "type");
 185
 186	envp[0] = kasprintf(GFP_KERNEL, "PRODUCT_TYPE=%s", ptype);
 187	if (!envp[0])
 188		return;
 189
 190	kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
 191	kfree(envp[0]);
 192}
 193
 194static void typec_report_identity(struct device *dev)
 195{
 196	sysfs_notify(&dev->kobj, "identity", "id_header");
 197	sysfs_notify(&dev->kobj, "identity", "cert_stat");
 198	sysfs_notify(&dev->kobj, "identity", "product");
 199	sysfs_notify(&dev->kobj, "identity", "product_type_vdo1");
 200	sysfs_notify(&dev->kobj, "identity", "product_type_vdo2");
 201	sysfs_notify(&dev->kobj, "identity", "product_type_vdo3");
 202	typec_product_type_notify(dev);
 203}
 204
 205static ssize_t
 206type_show(struct device *dev, struct device_attribute *attr, char *buf)
 207{
 208	const char *ptype;
 209
 210	ptype = get_pd_product_type(dev);
 211	if (!ptype)
 212		return 0;
 213
 214	return sysfs_emit(buf, "%s\n", ptype);
 215}
 216static DEVICE_ATTR_RO(type);
 217
 218static ssize_t usb_power_delivery_revision_show(struct device *dev,
 219						struct device_attribute *attr,
 220						char *buf);
 221static DEVICE_ATTR_RO(usb_power_delivery_revision);
 222
 223static const char * const usb_modes[] = {
 224	[USB_MODE_NONE] = "none",
 225	[USB_MODE_USB2] = "usb2",
 226	[USB_MODE_USB3] = "usb3",
 227	[USB_MODE_USB4] = "usb4"
 228};
 229
 230/* ------------------------------------------------------------------------- */
 231/* Alternate Modes */
 232
 233static int altmode_match(struct device *dev, const void *data)
 234{
 235	struct typec_altmode *adev = to_typec_altmode(dev);
 236	const struct typec_device_id *id = data;
 237
 238	if (!is_typec_altmode(dev))
 239		return 0;
 240
 241	return (adev->svid == id->svid);
 242}
 243
 244static void typec_altmode_set_partner(struct altmode *altmode)
 245{
 246	struct typec_altmode *adev = &altmode->adev;
 247	struct typec_device_id id = { adev->svid };
 248	struct typec_port *port = typec_altmode2port(adev);
 249	struct altmode *partner;
 250	struct device *dev;
 251
 252	dev = device_find_child(&port->dev, &id, altmode_match);
 253	if (!dev)
 254		return;
 255
 256	/* Bind the port alt mode to the partner/plug alt mode. */
 257	partner = to_altmode(to_typec_altmode(dev));
 258	altmode->partner = partner;
 259
 260	/* Bind the partner/plug alt mode to the port alt mode. */
 261	if (is_typec_plug(adev->dev.parent)) {
 262		struct typec_plug *plug = to_typec_plug(adev->dev.parent);
 263
 264		partner->plug[plug->index] = altmode;
 265	} else {
 266		partner->partner = altmode;
 267	}
 268}
 269
 270static void typec_altmode_put_partner(struct altmode *altmode)
 271{
 272	struct altmode *partner = altmode->partner;
 273	struct typec_altmode *adev;
 274	struct typec_altmode *partner_adev;
 275
 276	if (!partner)
 277		return;
 278
 279	adev = &altmode->adev;
 280	partner_adev = &partner->adev;
 281
 282	if (is_typec_plug(adev->dev.parent)) {
 283		struct typec_plug *plug = to_typec_plug(adev->dev.parent);
 284
 285		partner->plug[plug->index] = NULL;
 286	} else {
 287		partner->partner = NULL;
 288	}
 289	put_device(&partner_adev->dev);
 290}
 291
 292/**
 293 * typec_altmode_update_active - Report Enter/Exit mode
 294 * @adev: Handle to the alternate mode
 295 * @active: True when the mode has been entered
 296 *
 297 * If a partner or cable plug executes Enter/Exit Mode command successfully, the
 298 * drivers use this routine to report the updated state of the mode.
 299 */
 300void typec_altmode_update_active(struct typec_altmode *adev, bool active)
 301{
 302	char dir[6];
 303
 304	if (adev->active == active)
 305		return;
 306
 307	if (!is_typec_port(adev->dev.parent) && adev->dev.driver) {
 308		if (!active)
 309			module_put(adev->dev.driver->owner);
 310		else
 311			WARN_ON(!try_module_get(adev->dev.driver->owner));
 312	}
 313
 314	adev->active = active;
 315	snprintf(dir, sizeof(dir), "mode%d", adev->mode);
 316	sysfs_notify(&adev->dev.kobj, dir, "active");
 317	sysfs_notify(&adev->dev.kobj, NULL, "active");
 318	kobject_uevent(&adev->dev.kobj, KOBJ_CHANGE);
 319}
 320EXPORT_SYMBOL_GPL(typec_altmode_update_active);
 321
 322/**
 323 * typec_altmode2port - Alternate Mode to USB Type-C port
 324 * @alt: The Alternate Mode
 325 *
 326 * Returns handle to the port that a cable plug or partner with @alt is
 327 * connected to.
 328 */
 329struct typec_port *typec_altmode2port(struct typec_altmode *alt)
 330{
 331	if (is_typec_plug(alt->dev.parent))
 332		return to_typec_port(alt->dev.parent->parent->parent);
 333	if (is_typec_partner(alt->dev.parent))
 334		return to_typec_port(alt->dev.parent->parent);
 335	if (is_typec_port(alt->dev.parent))
 336		return to_typec_port(alt->dev.parent);
 337
 338	return NULL;
 339}
 340EXPORT_SYMBOL_GPL(typec_altmode2port);
 341
 342static ssize_t
 343vdo_show(struct device *dev, struct device_attribute *attr, char *buf)
 344{
 345	struct typec_altmode *alt = to_typec_altmode(dev);
 346
 347	return sprintf(buf, "0x%08x\n", alt->vdo);
 348}
 349static DEVICE_ATTR_RO(vdo);
 350
 351static ssize_t
 352description_show(struct device *dev, struct device_attribute *attr, char *buf)
 353{
 354	struct typec_altmode *alt = to_typec_altmode(dev);
 355
 356	return sprintf(buf, "%s\n", alt->desc ? alt->desc : "");
 357}
 358static DEVICE_ATTR_RO(description);
 359
 360static ssize_t
 361active_show(struct device *dev, struct device_attribute *attr, char *buf)
 362{
 363	struct typec_altmode *alt = to_typec_altmode(dev);
 364
 365	return sprintf(buf, "%s\n", str_yes_no(alt->active));
 366}
 367
 368static ssize_t active_store(struct device *dev, struct device_attribute *attr,
 369			    const char *buf, size_t size)
 370{
 371	struct typec_altmode *adev = to_typec_altmode(dev);
 372	struct altmode *altmode = to_altmode(adev);
 373	bool enter;
 374	int ret;
 375
 376	ret = kstrtobool(buf, &enter);
 377	if (ret)
 378		return ret;
 379
 380	if (adev->active == enter)
 381		return size;
 382
 383	if (is_typec_port(adev->dev.parent)) {
 384		typec_altmode_update_active(adev, enter);
 385
 386		/* Make sure that the partner exits the mode before disabling */
 387		if (altmode->partner && !enter && altmode->partner->adev.active)
 388			typec_altmode_exit(&altmode->partner->adev);
 389	} else if (altmode->partner) {
 390		if (enter && !altmode->partner->adev.active) {
 391			dev_warn(dev, "port has the mode disabled\n");
 392			return -EPERM;
 393		}
 394	}
 395
 396	/* Note: If there is no driver, the mode will not be entered */
 397	if (adev->ops && adev->ops->activate) {
 398		ret = adev->ops->activate(adev, enter);
 399		if (ret)
 400			return ret;
 401	}
 402
 403	return size;
 404}
 405static DEVICE_ATTR_RW(active);
 406
 407static ssize_t
 408supported_roles_show(struct device *dev, struct device_attribute *attr,
 409		     char *buf)
 410{
 411	struct altmode *alt = to_altmode(to_typec_altmode(dev));
 412	ssize_t ret;
 413
 414	switch (alt->roles) {
 415	case TYPEC_PORT_SRC:
 416		ret = sprintf(buf, "source\n");
 417		break;
 418	case TYPEC_PORT_SNK:
 419		ret = sprintf(buf, "sink\n");
 420		break;
 421	case TYPEC_PORT_DRP:
 422	default:
 423		ret = sprintf(buf, "source sink\n");
 424		break;
 425	}
 426	return ret;
 427}
 428static DEVICE_ATTR_RO(supported_roles);
 429
 430static ssize_t
 431mode_show(struct device *dev, struct device_attribute *attr, char *buf)
 432{
 433	struct typec_altmode *adev = to_typec_altmode(dev);
 434
 435	return sprintf(buf, "%u\n", adev->mode);
 436}
 437static DEVICE_ATTR_RO(mode);
 438
 439static ssize_t
 440svid_show(struct device *dev, struct device_attribute *attr, char *buf)
 441{
 442	struct typec_altmode *adev = to_typec_altmode(dev);
 443
 444	return sprintf(buf, "%04x\n", adev->svid);
 445}
 446static DEVICE_ATTR_RO(svid);
 447
 448static struct attribute *typec_altmode_attrs[] = {
 449	&dev_attr_active.attr,
 450	&dev_attr_mode.attr,
 451	&dev_attr_svid.attr,
 452	&dev_attr_vdo.attr,
 453	NULL
 454};
 455
 456static umode_t typec_altmode_attr_is_visible(struct kobject *kobj,
 457					     struct attribute *attr, int n)
 458{
 459	struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj));
 460
 461	if (attr == &dev_attr_active.attr)
 462		if (!is_typec_port(adev->dev.parent) &&
 463		    (!adev->ops || !adev->ops->activate))
 464			return 0444;
 465
 466	return attr->mode;
 467}
 468
 469static const struct attribute_group typec_altmode_group = {
 470	.is_visible = typec_altmode_attr_is_visible,
 471	.attrs = typec_altmode_attrs,
 472};
 473
 474static const struct attribute_group *typec_altmode_groups[] = {
 475	&typec_altmode_group,
 476	NULL
 477};
 478
 479/**
 480 * typec_altmode_set_ops - Set ops for altmode
 481 * @adev: Handle to the alternate mode
 482 * @ops: Ops for the alternate mode
 483 *
 484 * After setting ops, attribute visiblity needs to be refreshed if the alternate
 485 * mode can be activated.
 486 */
 487void typec_altmode_set_ops(struct typec_altmode *adev,
 488			   const struct typec_altmode_ops *ops)
 489{
 490	adev->ops = ops;
 491	sysfs_update_group(&adev->dev.kobj, &typec_altmode_group);
 492}
 493EXPORT_SYMBOL_GPL(typec_altmode_set_ops);
 494
 495static int altmode_id_get(struct device *dev)
 496{
 497	struct ida *ids;
 498
 499	if (is_typec_partner(dev))
 500		ids = &to_typec_partner(dev)->mode_ids;
 501	else if (is_typec_plug(dev))
 502		ids = &to_typec_plug(dev)->mode_ids;
 503	else
 504		ids = &to_typec_port(dev)->mode_ids;
 505
 506	return ida_alloc(ids, GFP_KERNEL);
 507}
 508
 509static void altmode_id_remove(struct device *dev, int id)
 510{
 511	struct ida *ids;
 512
 513	if (is_typec_partner(dev))
 514		ids = &to_typec_partner(dev)->mode_ids;
 515	else if (is_typec_plug(dev))
 516		ids = &to_typec_plug(dev)->mode_ids;
 517	else
 518		ids = &to_typec_port(dev)->mode_ids;
 519
 520	ida_free(ids, id);
 521}
 522
 523static void typec_altmode_release(struct device *dev)
 524{
 525	struct altmode *alt = to_altmode(to_typec_altmode(dev));
 526
 527	if (!is_typec_port(dev->parent))
 528		typec_altmode_put_partner(alt);
 529
 530	altmode_id_remove(alt->adev.dev.parent, alt->id);
 531	put_device(alt->adev.dev.parent);
 532	kfree(alt);
 533}
 534
 535const struct device_type typec_altmode_dev_type = {
 536	.name = "typec_alternate_mode",
 537	.groups = typec_altmode_groups,
 538	.release = typec_altmode_release,
 539};
 540
 541static struct typec_altmode *
 542typec_register_altmode(struct device *parent,
 543		       const struct typec_altmode_desc *desc)
 544{
 545	unsigned int id = altmode_id_get(parent);
 546	bool is_port = is_typec_port(parent);
 547	struct altmode *alt;
 548	int ret;
 549
 550	alt = kzalloc(sizeof(*alt), GFP_KERNEL);
 551	if (!alt) {
 552		altmode_id_remove(parent, id);
 553		return ERR_PTR(-ENOMEM);
 554	}
 555
 556	alt->adev.svid = desc->svid;
 557	alt->adev.mode = desc->mode;
 558	alt->adev.vdo = desc->vdo;
 559	alt->roles = desc->roles;
 560	alt->id = id;
 561
 562	alt->attrs[0] = &dev_attr_vdo.attr;
 563	alt->attrs[1] = &dev_attr_description.attr;
 564	alt->attrs[2] = &dev_attr_active.attr;
 565
 566	if (is_port) {
 567		alt->attrs[3] = &dev_attr_supported_roles.attr;
 568		alt->adev.active = !desc->inactive; /* Enabled by default */
 569	}
 570
 571	sprintf(alt->group_name, "mode%d", desc->mode);
 572	alt->group.name = alt->group_name;
 573	alt->group.attrs = alt->attrs;
 574	alt->groups[0] = &alt->group;
 575
 576	alt->adev.dev.parent = parent;
 577	alt->adev.dev.groups = alt->groups;
 578	alt->adev.dev.type = &typec_altmode_dev_type;
 579	dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id);
 580
 581	get_device(alt->adev.dev.parent);
 582
 583	/* Link partners and plugs with the ports */
 584	if (!is_port)
 585		typec_altmode_set_partner(alt);
 586
 587	/* The partners are bind to drivers */
 588	if (is_typec_partner(parent))
 589		alt->adev.dev.bus = &typec_bus;
 590
 591	/* Plug alt modes need a class to generate udev events. */
 592	if (is_typec_plug(parent))
 593		alt->adev.dev.class = &typec_class;
 594
 595	ret = device_register(&alt->adev.dev);
 596	if (ret) {
 597		dev_err(parent, "failed to register alternate mode (%d)\n",
 598			ret);
 599		put_device(&alt->adev.dev);
 600		return ERR_PTR(ret);
 601	}
 602
 603	return &alt->adev;
 604}
 605
 606/**
 607 * typec_unregister_altmode - Unregister Alternate Mode
 608 * @adev: The alternate mode to be unregistered
 609 *
 610 * Unregister device created with typec_partner_register_altmode(),
 611 * typec_plug_register_altmode() or typec_port_register_altmode().
 612 */
 613void typec_unregister_altmode(struct typec_altmode *adev)
 614{
 615	if (IS_ERR_OR_NULL(adev))
 616		return;
 617	typec_retimer_put(to_altmode(adev)->retimer);
 618	typec_mux_put(to_altmode(adev)->mux);
 619	device_unregister(&adev->dev);
 620}
 621EXPORT_SYMBOL_GPL(typec_unregister_altmode);
 622
 623/* ------------------------------------------------------------------------- */
 624/* Type-C Partners */
 625
 626/**
 627 * typec_partner_set_usb_mode - Assign active USB Mode for the partner
 628 * @partner: USB Type-C partner
 629 * @mode: USB Mode (USB2, USB3 or USB4)
 630 *
 631 * The port drivers can use this function to assign the active USB Mode to
 632 * @partner. The USB Mode can change for example due to Data Reset.
 633 */
 634void typec_partner_set_usb_mode(struct typec_partner *partner, enum usb_mode mode)
 635{
 636	if (!partner || partner->usb_mode == mode)
 637		return;
 638
 639	partner->usb_capability |= BIT(mode - 1);
 640	partner->usb_mode = mode;
 641	sysfs_notify(&partner->dev.kobj, NULL, "usb_mode");
 642}
 643EXPORT_SYMBOL_GPL(typec_partner_set_usb_mode);
 644
 645static ssize_t
 646usb_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
 647{
 648	struct typec_partner *partner = to_typec_partner(dev);
 649	int len = 0;
 650	int i;
 651
 652	for (i = USB_MODE_USB2; i < USB_MODE_USB4 + 1; i++) {
 653		if (!(BIT(i - 1) & partner->usb_capability))
 654			continue;
 655
 656		if (i == partner->usb_mode)
 657			len += sysfs_emit_at(buf, len, "[%s] ", usb_modes[i]);
 658		else
 659			len += sysfs_emit_at(buf, len, "%s ", usb_modes[i]);
 660	}
 661
 662	sysfs_emit_at(buf, len - 1, "\n");
 663
 664	return len;
 665}
 666
 667static ssize_t usb_mode_store(struct device *dev, struct device_attribute *attr,
 668			      const char *buf, size_t size)
 669{
 670	struct typec_partner *partner = to_typec_partner(dev);
 671	struct typec_port *port = to_typec_port(dev->parent);
 672	int mode;
 673	int ret;
 674
 675	if (!port->ops || !port->ops->enter_usb_mode)
 676		return -EOPNOTSUPP;
 677
 678	mode = sysfs_match_string(usb_modes, buf);
 679	if (mode < 0)
 680		return mode;
 681
 682	if (mode == partner->usb_mode)
 683		return size;
 684
 685	ret = port->ops->enter_usb_mode(port, mode);
 686	if (ret)
 687		return ret;
 688
 689	typec_partner_set_usb_mode(partner, mode);
 690
 691	return size;
 692}
 693static DEVICE_ATTR_RW(usb_mode);
 694
 695static ssize_t accessory_mode_show(struct device *dev,
 696				   struct device_attribute *attr,
 697				   char *buf)
 698{
 699	struct typec_partner *p = to_typec_partner(dev);
 700
 701	return sprintf(buf, "%s\n", typec_accessory_modes[p->accessory]);
 702}
 703static DEVICE_ATTR_RO(accessory_mode);
 704
 705static ssize_t supports_usb_power_delivery_show(struct device *dev,
 706						struct device_attribute *attr,
 707						char *buf)
 708{
 709	struct typec_partner *p = to_typec_partner(dev);
 710
 711	return sprintf(buf, "%s\n", str_yes_no(p->usb_pd));
 712}
 713static DEVICE_ATTR_RO(supports_usb_power_delivery);
 714
 715static ssize_t number_of_alternate_modes_show(struct device *dev, struct device_attribute *attr,
 716					      char *buf)
 717{
 718	struct typec_partner *partner;
 719	struct typec_plug *plug;
 720	int num_altmodes;
 721
 722	if (is_typec_partner(dev)) {
 723		partner = to_typec_partner(dev);
 724		num_altmodes = partner->num_altmodes;
 725	} else if (is_typec_plug(dev)) {
 726		plug = to_typec_plug(dev);
 727		num_altmodes = plug->num_altmodes;
 728	} else {
 729		return 0;
 730	}
 731
 732	return sysfs_emit(buf, "%d\n", num_altmodes);
 733}
 734static DEVICE_ATTR_RO(number_of_alternate_modes);
 735
 736static struct attribute *typec_partner_attrs[] = {
 737	&dev_attr_accessory_mode.attr,
 738	&dev_attr_supports_usb_power_delivery.attr,
 739	&dev_attr_number_of_alternate_modes.attr,
 740	&dev_attr_type.attr,
 741	&dev_attr_usb_mode.attr,
 742	&dev_attr_usb_power_delivery_revision.attr,
 743	NULL
 744};
 745
 746static umode_t typec_partner_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
 747{
 748	struct typec_partner *partner = to_typec_partner(kobj_to_dev(kobj));
 749	struct typec_port *port = to_typec_port(partner->dev.parent);
 750
 751	if (attr == &dev_attr_usb_mode.attr) {
 752		if (!partner->usb_capability)
 753			return 0;
 754		if (!port->ops || !port->ops->enter_usb_mode)
 755			return 0444;
 756	}
 757
 758	if (attr == &dev_attr_number_of_alternate_modes.attr) {
 759		if (partner->num_altmodes < 0)
 760			return 0;
 761	}
 762
 763	if (attr == &dev_attr_type.attr)
 764		if (!get_pd_product_type(kobj_to_dev(kobj)))
 765			return 0;
 766
 767	return attr->mode;
 768}
 769
 770static const struct attribute_group typec_partner_group = {
 771	.is_visible = typec_partner_attr_is_visible,
 772	.attrs = typec_partner_attrs
 773};
 774
 775static const struct attribute_group *typec_partner_groups[] = {
 776	&typec_partner_group,
 777	NULL
 778};
 779
 780static void typec_partner_release(struct device *dev)
 781{
 782	struct typec_partner *partner = to_typec_partner(dev);
 783
 784	ida_destroy(&partner->mode_ids);
 785	kfree(partner);
 786}
 787
 788const struct device_type typec_partner_dev_type = {
 789	.name = "typec_partner",
 790	.groups = typec_partner_groups,
 791	.release = typec_partner_release,
 792};
 793
 794static void typec_partner_link_device(struct typec_partner *partner, struct device *dev)
 795{
 796	int ret;
 797
 798	ret = sysfs_create_link(&dev->kobj, &partner->dev.kobj, "typec");
 799	if (ret)
 800		return;
 801
 802	ret = sysfs_create_link(&partner->dev.kobj, &dev->kobj, dev_name(dev));
 803	if (ret) {
 804		sysfs_remove_link(&dev->kobj, "typec");
 805		return;
 806	}
 807
 808	if (partner->attach)
 809		partner->attach(partner, dev);
 810}
 811
 812static void typec_partner_unlink_device(struct typec_partner *partner, struct device *dev)
 813{
 814	sysfs_remove_link(&partner->dev.kobj, dev_name(dev));
 815	sysfs_remove_link(&dev->kobj, "typec");
 816
 817	if (partner->deattach)
 818		partner->deattach(partner, dev);
 819}
 820
 821/**
 822 * typec_partner_set_identity - Report result from Discover Identity command
 823 * @partner: The partner updated identity values
 824 *
 825 * This routine is used to report that the result of Discover Identity USB power
 826 * delivery command has become available.
 827 */
 828int typec_partner_set_identity(struct typec_partner *partner)
 829{
 830	u8 usb_capability = partner->usb_capability;
 831	struct device *dev = &partner->dev;
 832	struct usb_pd_identity *id;
 833
 834	id = get_pd_identity(dev);
 835	if (!id)
 836		return -EINVAL;
 837
 838	if (to_typec_port(dev->parent)->data_role == TYPEC_HOST)  {
 839		u32 devcap = PD_VDO_UFP_DEVCAP(id->vdo[0]);
 840
 841		if (devcap & (DEV_USB2_CAPABLE | DEV_USB2_BILLBOARD))
 842			usb_capability |= USB_CAPABILITY_USB2;
 843		if (devcap & DEV_USB3_CAPABLE)
 844			usb_capability |= USB_CAPABILITY_USB3;
 845		if (devcap & DEV_USB4_CAPABLE)
 846			usb_capability |= USB_CAPABILITY_USB4;
 847	} else {
 848		usb_capability = PD_VDO_DFP_HOSTCAP(id->vdo[0]);
 849	}
 850
 851	if (partner->usb_capability != usb_capability) {
 852		partner->usb_capability = usb_capability;
 853		sysfs_notify(&dev->kobj, NULL, "usb_mode");
 854	}
 855
 856	typec_report_identity(dev);
 857	return 0;
 858}
 859EXPORT_SYMBOL_GPL(typec_partner_set_identity);
 860
 861/**
 862 * typec_partner_set_pd_revision - Set the PD revision supported by the partner
 863 * @partner: The partner to be updated.
 864 * @pd_revision:  USB Power Delivery Specification Revision supported by partner
 865 *
 866 * This routine is used to report that the PD revision of the port partner has
 867 * become available.
 868 */
 869void typec_partner_set_pd_revision(struct typec_partner *partner, u16 pd_revision)
 870{
 871	if (partner->pd_revision == pd_revision)
 872		return;
 873
 874	partner->pd_revision = pd_revision;
 875	sysfs_notify(&partner->dev.kobj, NULL, "usb_power_delivery_revision");
 876	if (pd_revision != 0 && !partner->usb_pd) {
 877		partner->usb_pd = 1;
 878		sysfs_notify(&partner->dev.kobj, NULL,
 879			     "supports_usb_power_delivery");
 880	}
 881	kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE);
 882}
 883EXPORT_SYMBOL_GPL(typec_partner_set_pd_revision);
 884
 885/**
 886 * typec_partner_set_usb_power_delivery - Declare USB Power Delivery Contract.
 887 * @partner: The partner device.
 888 * @pd: The USB PD instance.
 889 *
 890 * This routine can be used to declare USB Power Delivery Contract with @partner
 891 * by linking @partner to @pd which contains the objects that were used during the
 892 * negotiation of the contract.
 893 *
 894 * If @pd is NULL, the link is removed and the contract with @partner has ended.
 895 */
 896int typec_partner_set_usb_power_delivery(struct typec_partner *partner,
 897					 struct usb_power_delivery *pd)
 898{
 899	int ret;
 900
 901	if (IS_ERR_OR_NULL(partner) || partner->pd == pd)
 902		return 0;
 903
 904	if (pd) {
 905		ret = usb_power_delivery_link_device(pd, &partner->dev);
 906		if (ret)
 907			return ret;
 908	} else {
 909		usb_power_delivery_unlink_device(partner->pd, &partner->dev);
 910	}
 911
 912	partner->pd = pd;
 913
 914	return 0;
 915}
 916EXPORT_SYMBOL_GPL(typec_partner_set_usb_power_delivery);
 917
 918/**
 919 * typec_partner_set_num_altmodes - Set the number of available partner altmodes
 920 * @partner: The partner to be updated.
 921 * @num_altmodes: The number of altmodes we want to specify as available.
 922 *
 923 * This routine is used to report the number of alternate modes supported by the
 924 * partner. This value is *not* enforced in alternate mode registration routines.
 925 *
 926 * @partner.num_altmodes is set to -1 on partner registration, denoting that
 927 * a valid value has not been set for it yet.
 928 *
 929 * Returns 0 on success or negative error number on failure.
 930 */
 931int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmodes)
 932{
 933	int ret;
 934
 935	if (num_altmodes < 0)
 936		return -EINVAL;
 937
 938	partner->num_altmodes = num_altmodes;
 939	ret = sysfs_update_group(&partner->dev.kobj, &typec_partner_group);
 940	if (ret < 0)
 941		return ret;
 942
 943	sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes");
 944	kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE);
 945
 946	return 0;
 947}
 948EXPORT_SYMBOL_GPL(typec_partner_set_num_altmodes);
 949
 950/**
 951 * typec_partner_register_altmode - Register USB Type-C Partner Alternate Mode
 952 * @partner: USB Type-C Partner that supports the alternate mode
 953 * @desc: Description of the alternate mode
 954 *
 955 * This routine is used to register each alternate mode individually that
 956 * @partner has listed in response to Discover SVIDs command. The modes for a
 957 * SVID listed in response to Discover Modes command need to be listed in an
 958 * array in @desc.
 959 *
 960 * Returns handle to the alternate mode on success or ERR_PTR on failure.
 961 */
 962struct typec_altmode *
 963typec_partner_register_altmode(struct typec_partner *partner,
 964			       const struct typec_altmode_desc *desc)
 965{
 966	return typec_register_altmode(&partner->dev, desc);
 967}
 968EXPORT_SYMBOL_GPL(typec_partner_register_altmode);
 969
 970/**
 971 * typec_partner_set_svdm_version - Set negotiated Structured VDM (SVDM) Version
 972 * @partner: USB Type-C Partner that supports SVDM
 973 * @svdm_version: Negotiated SVDM Version
 974 *
 975 * This routine is used to save the negotiated SVDM Version.
 976 */
 977void typec_partner_set_svdm_version(struct typec_partner *partner,
 978				   enum usb_pd_svdm_ver svdm_version)
 979{
 980	partner->svdm_version = svdm_version;
 981}
 982EXPORT_SYMBOL_GPL(typec_partner_set_svdm_version);
 983
 984/**
 985 * typec_partner_usb_power_delivery_register - Register Type-C partner USB Power Delivery Support
 986 * @partner: Type-C partner device.
 987 * @desc: Description of the USB PD contract.
 988 *
 989 * This routine is a wrapper around usb_power_delivery_register(). It registers
 990 * USB Power Delivery Capabilities for a Type-C partner device. Specifically,
 991 * it sets the Type-C partner device as a parent for the resulting USB Power Delivery object.
 992 *
 993 * Returns handle to struct usb_power_delivery or ERR_PTR.
 994 */
 995struct usb_power_delivery *
 996typec_partner_usb_power_delivery_register(struct typec_partner *partner,
 997					  struct usb_power_delivery_desc *desc)
 998{
 999	return usb_power_delivery_register(&partner->dev, desc);
1000}
1001EXPORT_SYMBOL_GPL(typec_partner_usb_power_delivery_register);
1002
1003/**
1004 * typec_register_partner - Register a USB Type-C Partner
1005 * @port: The USB Type-C Port the partner is connected to
1006 * @desc: Description of the partner
1007 *
1008 * Registers a device for USB Type-C Partner described in @desc.
1009 *
1010 * Returns handle to the partner on success or ERR_PTR on failure.
1011 */
1012struct typec_partner *typec_register_partner(struct typec_port *port,
1013					     struct typec_partner_desc *desc)
1014{
1015	struct typec_partner *partner;
1016	int ret;
1017
1018	partner = kzalloc(sizeof(*partner), GFP_KERNEL);
1019	if (!partner)
1020		return ERR_PTR(-ENOMEM);
1021
1022	ida_init(&partner->mode_ids);
1023	partner->usb_pd = desc->usb_pd;
1024	partner->accessory = desc->accessory;
1025	partner->num_altmodes = -1;
1026	partner->usb_capability = desc->usb_capability;
1027	partner->pd_revision = desc->pd_revision;
1028	partner->svdm_version = port->cap->svdm_version;
1029	partner->attach = desc->attach;
1030	partner->deattach = desc->deattach;
1031
1032	if (desc->identity) {
1033		/*
1034		 * Creating directory for the identity only if the driver is
1035		 * able to provide data to it.
1036		 */
1037		partner->dev.groups = usb_pd_id_groups;
1038		partner->identity = desc->identity;
1039	}
1040
1041	partner->dev.class = &typec_class;
1042	partner->dev.parent = &port->dev;
1043	partner->dev.type = &typec_partner_dev_type;
1044	dev_set_name(&partner->dev, "%s-partner", dev_name(&port->dev));
1045
1046	if (port->usb2_dev) {
1047		partner->usb_capability |= USB_CAPABILITY_USB2;
1048		partner->usb_mode = USB_MODE_USB2;
1049	}
1050	if (port->usb3_dev) {
1051		partner->usb_capability |= USB_CAPABILITY_USB2 | USB_CAPABILITY_USB3;
1052		partner->usb_mode = USB_MODE_USB3;
1053	}
1054
1055	mutex_lock(&port->partner_link_lock);
1056	ret = device_register(&partner->dev);
1057	if (ret) {
1058		dev_err(&port->dev, "failed to register partner (%d)\n", ret);
1059		mutex_unlock(&port->partner_link_lock);
1060		put_device(&partner->dev);
1061		return ERR_PTR(ret);
1062	}
1063
1064	if (port->usb2_dev)
1065		typec_partner_link_device(partner, port->usb2_dev);
1066	if (port->usb3_dev)
1067		typec_partner_link_device(partner, port->usb3_dev);
1068	mutex_unlock(&port->partner_link_lock);
1069
1070	return partner;
1071}
1072EXPORT_SYMBOL_GPL(typec_register_partner);
1073
1074/**
1075 * typec_unregister_partner - Unregister a USB Type-C Partner
1076 * @partner: The partner to be unregistered
1077 *
1078 * Unregister device created with typec_register_partner().
1079 */
1080void typec_unregister_partner(struct typec_partner *partner)
1081{
1082	struct typec_port *port;
1083
1084	if (IS_ERR_OR_NULL(partner))
1085		return;
1086
1087	port = to_typec_port(partner->dev.parent);
1088
1089	mutex_lock(&port->partner_link_lock);
1090	if (port->usb2_dev) {
1091		typec_partner_unlink_device(partner, port->usb2_dev);
1092		port->usb2_dev = NULL;
1093	}
1094	if (port->usb3_dev) {
1095		typec_partner_unlink_device(partner, port->usb3_dev);
1096		port->usb3_dev = NULL;
1097	}
1098
1099	device_unregister(&partner->dev);
1100	mutex_unlock(&port->partner_link_lock);
1101}
1102EXPORT_SYMBOL_GPL(typec_unregister_partner);
1103
1104/* ------------------------------------------------------------------------- */
1105/* Type-C Cable Plugs */
1106
1107static void typec_plug_release(struct device *dev)
1108{
1109	struct typec_plug *plug = to_typec_plug(dev);
1110
1111	ida_destroy(&plug->mode_ids);
1112	kfree(plug);
1113}
1114
1115static struct attribute *typec_plug_attrs[] = {
1116	&dev_attr_number_of_alternate_modes.attr,
1117	NULL
1118};
1119
1120static umode_t typec_plug_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
1121{
1122	struct typec_plug *plug = to_typec_plug(kobj_to_dev(kobj));
1123
1124	if (attr == &dev_attr_number_of_alternate_modes.attr) {
1125		if (plug->num_altmodes < 0)
1126			return 0;
1127	}
1128
1129	return attr->mode;
1130}
1131
1132static const struct attribute_group typec_plug_group = {
1133	.is_visible = typec_plug_attr_is_visible,
1134	.attrs = typec_plug_attrs
1135};
1136
1137static const struct attribute_group *typec_plug_groups[] = {
1138	&typec_plug_group,
1139	NULL
1140};
1141
1142const struct device_type typec_plug_dev_type = {
1143	.name = "typec_plug",
1144	.groups = typec_plug_groups,
1145	.release = typec_plug_release,
1146};
1147
1148/**
1149 * typec_plug_set_num_altmodes - Set the number of available plug altmodes
1150 * @plug: The plug to be updated.
1151 * @num_altmodes: The number of altmodes we want to specify as available.
1152 *
1153 * This routine is used to report the number of alternate modes supported by the
1154 * plug. This value is *not* enforced in alternate mode registration routines.
1155 *
1156 * @plug.num_altmodes is set to -1 on plug registration, denoting that
1157 * a valid value has not been set for it yet.
1158 *
1159 * Returns 0 on success or negative error number on failure.
1160 */
1161int typec_plug_set_num_altmodes(struct typec_plug *plug, int num_altmodes)
1162{
1163	int ret;
1164
1165	if (num_altmodes < 0)
1166		return -EINVAL;
1167
1168	plug->num_altmodes = num_altmodes;
1169	ret = sysfs_update_group(&plug->dev.kobj, &typec_plug_group);
1170	if (ret < 0)
1171		return ret;
1172
1173	sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes");
1174	kobject_uevent(&plug->dev.kobj, KOBJ_CHANGE);
1175
1176	return 0;
1177}
1178EXPORT_SYMBOL_GPL(typec_plug_set_num_altmodes);
1179
1180/**
1181 * typec_plug_register_altmode - Register USB Type-C Cable Plug Alternate Mode
1182 * @plug: USB Type-C Cable Plug that supports the alternate mode
1183 * @desc: Description of the alternate mode
1184 *
1185 * This routine is used to register each alternate mode individually that @plug
1186 * has listed in response to Discover SVIDs command. The modes for a SVID that
1187 * the plug lists in response to Discover Modes command need to be listed in an
1188 * array in @desc.
1189 *
1190 * Returns handle to the alternate mode on success or ERR_PTR on failure.
1191 */
1192struct typec_altmode *
1193typec_plug_register_altmode(struct typec_plug *plug,
1194			    const struct typec_altmode_desc *desc)
1195{
1196	return typec_register_altmode(&plug->dev, desc);
1197}
1198EXPORT_SYMBOL_GPL(typec_plug_register_altmode);
1199
1200/**
1201 * typec_register_plug - Register a USB Type-C Cable Plug
1202 * @cable: USB Type-C Cable with the plug
1203 * @desc: Description of the cable plug
1204 *
1205 * Registers a device for USB Type-C Cable Plug described in @desc. A USB Type-C
1206 * Cable Plug represents a plug with electronics in it that can response to USB
1207 * Power Delivery SOP Prime or SOP Double Prime packages.
1208 *
1209 * Returns handle to the cable plug on success or ERR_PTR on failure.
1210 */
1211struct typec_plug *typec_register_plug(struct typec_cable *cable,
1212				       struct typec_plug_desc *desc)
1213{
1214	struct typec_plug *plug;
1215	char name[8];
1216	int ret;
1217
1218	plug = kzalloc(sizeof(*plug), GFP_KERNEL);
1219	if (!plug)
1220		return ERR_PTR(-ENOMEM);
1221
1222	sprintf(name, "plug%d", desc->index);
1223
1224	ida_init(&plug->mode_ids);
1225	plug->num_altmodes = -1;
1226	plug->index = desc->index;
1227	plug->dev.class = &typec_class;
1228	plug->dev.parent = &cable->dev;
1229	plug->dev.type = &typec_plug_dev_type;
1230	dev_set_name(&plug->dev, "%s-%s", dev_name(cable->dev.parent), name);
1231
1232	ret = device_register(&plug->dev);
1233	if (ret) {
1234		dev_err(&cable->dev, "failed to register plug (%d)\n", ret);
1235		put_device(&plug->dev);
1236		return ERR_PTR(ret);
1237	}
1238
1239	return plug;
1240}
1241EXPORT_SYMBOL_GPL(typec_register_plug);
1242
1243/**
1244 * typec_unregister_plug - Unregister a USB Type-C Cable Plug
1245 * @plug: The cable plug to be unregistered
1246 *
1247 * Unregister device created with typec_register_plug().
1248 */
1249void typec_unregister_plug(struct typec_plug *plug)
1250{
1251	if (!IS_ERR_OR_NULL(plug))
1252		device_unregister(&plug->dev);
1253}
1254EXPORT_SYMBOL_GPL(typec_unregister_plug);
1255
1256/* Type-C Cables */
1257
1258static const char * const typec_plug_types[] = {
1259	[USB_PLUG_NONE]		= "unknown",
1260	[USB_PLUG_TYPE_A]	= "type-a",
1261	[USB_PLUG_TYPE_B]	= "type-b",
1262	[USB_PLUG_TYPE_C]	= "type-c",
1263	[USB_PLUG_CAPTIVE]	= "captive",
1264};
1265
1266static ssize_t plug_type_show(struct device *dev,
1267			      struct device_attribute *attr, char *buf)
1268{
1269	struct typec_cable *cable = to_typec_cable(dev);
1270
1271	return sprintf(buf, "%s\n", typec_plug_types[cable->type]);
1272}
1273static DEVICE_ATTR_RO(plug_type);
1274
1275static struct attribute *typec_cable_attrs[] = {
1276	&dev_attr_type.attr,
1277	&dev_attr_plug_type.attr,
1278	&dev_attr_usb_power_delivery_revision.attr,
1279	NULL
1280};
1281ATTRIBUTE_GROUPS(typec_cable);
1282
1283static void typec_cable_release(struct device *dev)
1284{
1285	struct typec_cable *cable = to_typec_cable(dev);
1286
1287	kfree(cable);
1288}
1289
1290const struct device_type typec_cable_dev_type = {
1291	.name = "typec_cable",
1292	.groups = typec_cable_groups,
1293	.release = typec_cable_release,
1294};
1295
1296/**
1297 * typec_cable_get - Get a reference to the USB Type-C cable
1298 * @port: The USB Type-C Port the cable is connected to
1299 *
1300 * The caller must decrement the reference count with typec_cable_put() after
1301 * use.
1302 */
1303struct typec_cable *typec_cable_get(struct typec_port *port)
1304{
1305	struct device *dev;
1306
1307	dev = device_find_child(&port->dev, &typec_cable_dev_type,
1308				device_match_type);
1309	if (!dev)
1310		return NULL;
1311
1312	return to_typec_cable(dev);
1313}
1314EXPORT_SYMBOL_GPL(typec_cable_get);
1315
1316/**
1317 * typec_cable_put - Decrement the reference count on USB Type-C cable
1318 * @cable: The USB Type-C cable
1319 */
1320void typec_cable_put(struct typec_cable *cable)
1321{
1322	put_device(&cable->dev);
1323}
1324EXPORT_SYMBOL_GPL(typec_cable_put);
1325
1326/**
1327 * typec_cable_is_active - Check is the USB Type-C cable active or passive
1328 * @cable: The USB Type-C Cable
1329 *
1330 * Return 1 if the cable is active or 0 if it's passive.
1331 */
1332int typec_cable_is_active(struct typec_cable *cable)
1333{
1334	return cable->active;
1335}
1336EXPORT_SYMBOL_GPL(typec_cable_is_active);
1337
1338/**
1339 * typec_cable_set_identity - Report result from Discover Identity command
1340 * @cable: The cable updated identity values
1341 *
1342 * This routine is used to report that the result of Discover Identity USB power
1343 * delivery command has become available.
1344 */
1345int typec_cable_set_identity(struct typec_cable *cable)
1346{
1347	if (!cable->identity)
1348		return -EINVAL;
1349
1350	typec_report_identity(&cable->dev);
1351	return 0;
1352}
1353EXPORT_SYMBOL_GPL(typec_cable_set_identity);
1354
1355/**
1356 * typec_register_cable - Register a USB Type-C Cable
1357 * @port: The USB Type-C Port the cable is connected to
1358 * @desc: Description of the cable
1359 *
1360 * Registers a device for USB Type-C Cable described in @desc. The cable will be
1361 * parent for the optional cable plug devises.
1362 *
1363 * Returns handle to the cable on success or ERR_PTR on failure.
1364 */
1365struct typec_cable *typec_register_cable(struct typec_port *port,
1366					 struct typec_cable_desc *desc)
1367{
1368	struct typec_cable *cable;
1369	int ret;
1370
1371	cable = kzalloc(sizeof(*cable), GFP_KERNEL);
1372	if (!cable)
1373		return ERR_PTR(-ENOMEM);
1374
1375	cable->type = desc->type;
1376	cable->active = desc->active;
1377	cable->pd_revision = desc->pd_revision;
1378
1379	if (desc->identity) {
1380		/*
1381		 * Creating directory for the identity only if the driver is
1382		 * able to provide data to it.
1383		 */
1384		cable->dev.groups = usb_pd_id_groups;
1385		cable->identity = desc->identity;
1386	}
1387
1388	cable->dev.class = &typec_class;
1389	cable->dev.parent = &port->dev;
1390	cable->dev.type = &typec_cable_dev_type;
1391	dev_set_name(&cable->dev, "%s-cable", dev_name(&port->dev));
1392
1393	ret = device_register(&cable->dev);
1394	if (ret) {
1395		dev_err(&port->dev, "failed to register cable (%d)\n", ret);
1396		put_device(&cable->dev);
1397		return ERR_PTR(ret);
1398	}
1399
1400	return cable;
1401}
1402EXPORT_SYMBOL_GPL(typec_register_cable);
1403
1404/**
1405 * typec_unregister_cable - Unregister a USB Type-C Cable
1406 * @cable: The cable to be unregistered
1407 *
1408 * Unregister device created with typec_register_cable().
1409 */
1410void typec_unregister_cable(struct typec_cable *cable)
1411{
1412	if (!IS_ERR_OR_NULL(cable))
1413		device_unregister(&cable->dev);
1414}
1415EXPORT_SYMBOL_GPL(typec_unregister_cable);
1416
1417/* ------------------------------------------------------------------------- */
1418/* USB Type-C ports */
1419
1420/**
1421 * typec_port_set_usb_mode - Set the operational USB mode for the port
1422 * @port: USB Type-C port
1423 * @mode: USB Mode (USB2, USB3 or USB4)
1424 *
1425 * @mode will be used with the next Enter_USB message. Existing connections are
1426 * not affected.
1427 */
1428void typec_port_set_usb_mode(struct typec_port *port, enum usb_mode mode)
1429{
1430	port->usb_mode = mode;
1431}
1432EXPORT_SYMBOL_GPL(typec_port_set_usb_mode);
1433
1434static ssize_t
1435usb_capability_show(struct device *dev, struct device_attribute *attr, char *buf)
1436{
1437	struct typec_port *port = to_typec_port(dev);
1438	int len = 0;
1439	int i;
1440
1441	for (i = USB_MODE_USB2; i < USB_MODE_USB4 + 1; i++) {
1442		if (!(BIT(i - 1) & port->cap->usb_capability))
1443			continue;
1444
1445		if (i == port->usb_mode)
1446			len += sysfs_emit_at(buf, len, "[%s] ", usb_modes[i]);
1447		else
1448			len += sysfs_emit_at(buf, len, "%s ", usb_modes[i]);
1449	}
1450
1451	sysfs_emit_at(buf, len - 1, "\n");
1452
1453	return len;
1454}
1455
1456static ssize_t
1457usb_capability_store(struct device *dev, struct device_attribute *attr,
1458		     const char *buf, size_t size)
1459{
1460	struct typec_port *port = to_typec_port(dev);
1461	int ret = 0;
1462	int mode;
1463
1464	if (!port->ops || !port->ops->default_usb_mode_set)
1465		return -EOPNOTSUPP;
1466
1467	mode = sysfs_match_string(usb_modes, buf);
1468	if (mode < 0)
1469		return mode;
1470
1471	ret = port->ops->default_usb_mode_set(port, mode);
1472	if (ret)
1473		return ret;
1474
1475	port->usb_mode = mode;
1476
1477	return size;
1478}
1479static DEVICE_ATTR_RW(usb_capability);
1480
1481/**
1482 * typec_port_set_usb_power_delivery - Assign USB PD for port.
1483 * @port: USB Type-C port.
1484 * @pd: USB PD instance.
1485 *
1486 * This routine can be used to set the USB Power Delivery Capabilities for @port
1487 * that it will advertise to the partner.
1488 *
1489 * If @pd is NULL, the assignment is removed.
1490 */
1491int typec_port_set_usb_power_delivery(struct typec_port *port, struct usb_power_delivery *pd)
1492{
1493	int ret;
1494
1495	if (IS_ERR_OR_NULL(port) || port->pd == pd)
1496		return 0;
1497
1498	if (pd) {
1499		ret = usb_power_delivery_link_device(pd, &port->dev);
1500		if (ret)
1501			return ret;
1502	} else {
1503		usb_power_delivery_unlink_device(port->pd, &port->dev);
1504	}
1505
1506	port->pd = pd;
1507
1508	return 0;
1509}
1510EXPORT_SYMBOL_GPL(typec_port_set_usb_power_delivery);
1511
1512static ssize_t select_usb_power_delivery_store(struct device *dev,
1513					       struct device_attribute *attr,
1514					       const char *buf, size_t size)
1515{
1516	struct typec_port *port = to_typec_port(dev);
1517	struct usb_power_delivery *pd;
1518	int ret;
1519
1520	if (!port->ops || !port->ops->pd_set)
1521		return -EOPNOTSUPP;
1522
1523	pd = usb_power_delivery_find(buf);
1524	if (!pd)
1525		return -EINVAL;
1526
1527	ret = port->ops->pd_set(port, pd);
1528	if (ret)
1529		return ret;
1530
1531	return size;
1532}
1533
1534static ssize_t select_usb_power_delivery_show(struct device *dev,
1535					      struct device_attribute *attr, char *buf)
1536{
1537	struct typec_port *port = to_typec_port(dev);
1538	struct usb_power_delivery **pds;
1539	int i, ret = 0;
1540
1541	if (!port->ops || !port->ops->pd_get)
1542		return -EOPNOTSUPP;
1543
1544	pds = port->ops->pd_get(port);
1545	if (!pds)
1546		return 0;
1547
1548	for (i = 0; pds[i]; i++) {
1549		if (pds[i] == port->pd)
1550			ret += sysfs_emit_at(buf, ret, "[%s] ", dev_name(&pds[i]->dev));
1551		else
1552			ret += sysfs_emit_at(buf, ret, "%s ", dev_name(&pds[i]->dev));
1553	}
1554
1555	buf[ret - 1] = '\n';
1556
1557	return ret;
1558}
1559static DEVICE_ATTR_RW(select_usb_power_delivery);
1560
1561static struct attribute *port_attrs[] = {
1562	&dev_attr_select_usb_power_delivery.attr,
1563	NULL
1564};
1565
1566static umode_t port_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
1567{
1568	struct typec_port *port = to_typec_port(kobj_to_dev(kobj));
1569
1570	if (!port->pd || !port->ops || !port->ops->pd_get)
1571		return 0;
1572	if (!port->ops->pd_set)
1573		return 0444;
1574
1575	return attr->mode;
1576}
1577
1578static const struct attribute_group pd_group = {
1579	.is_visible = port_attr_is_visible,
1580	.attrs = port_attrs,
1581};
1582
1583static const char * const typec_orientations[] = {
1584	[TYPEC_ORIENTATION_NONE]	= "unknown",
1585	[TYPEC_ORIENTATION_NORMAL]	= "normal",
1586	[TYPEC_ORIENTATION_REVERSE]	= "reverse",
1587};
1588
1589static const char * const typec_roles[] = {
1590	[TYPEC_SINK]	= "sink",
1591	[TYPEC_SOURCE]	= "source",
1592};
1593
1594static const char * const typec_data_roles[] = {
1595	[TYPEC_DEVICE]	= "device",
1596	[TYPEC_HOST]	= "host",
1597};
1598
1599static const char * const typec_port_power_roles[] = {
1600	[TYPEC_PORT_SRC] = "source",
1601	[TYPEC_PORT_SNK] = "sink",
1602	[TYPEC_PORT_DRP] = "dual",
1603};
1604
1605static const char * const typec_port_data_roles[] = {
1606	[TYPEC_PORT_DFP] = "host",
1607	[TYPEC_PORT_UFP] = "device",
1608	[TYPEC_PORT_DRD] = "dual",
1609};
1610
1611static const char * const typec_port_types_drp[] = {
1612	[TYPEC_PORT_SRC] = "dual [source] sink",
1613	[TYPEC_PORT_SNK] = "dual source [sink]",
1614	[TYPEC_PORT_DRP] = "[dual] source sink",
1615};
1616
1617static ssize_t
1618preferred_role_store(struct device *dev, struct device_attribute *attr,
1619		     const char *buf, size_t size)
1620{
1621	struct typec_port *port = to_typec_port(dev);
1622	int role;
1623	int ret;
1624
1625	if (port->cap->type != TYPEC_PORT_DRP) {
1626		dev_dbg(dev, "Preferred role only supported with DRP ports\n");
1627		return -EOPNOTSUPP;
1628	}
1629
1630	if (!port->ops || !port->ops->try_role) {
1631		dev_dbg(dev, "Setting preferred role not supported\n");
1632		return -EOPNOTSUPP;
1633	}
1634
1635	role = sysfs_match_string(typec_roles, buf);
1636	if (role < 0) {
1637		if (sysfs_streq(buf, "none"))
1638			role = TYPEC_NO_PREFERRED_ROLE;
1639		else
1640			return -EINVAL;
1641	}
1642
1643	ret = port->ops->try_role(port, role);
1644	if (ret)
1645		return ret;
1646
1647	port->prefer_role = role;
1648	return size;
1649}
1650
1651static ssize_t
1652preferred_role_show(struct device *dev, struct device_attribute *attr,
1653		    char *buf)
1654{
1655	struct typec_port *port = to_typec_port(dev);
1656
1657	if (port->cap->type != TYPEC_PORT_DRP)
1658		return 0;
1659
1660	if (port->prefer_role < 0)
1661		return 0;
1662
1663	return sprintf(buf, "%s\n", typec_roles[port->prefer_role]);
1664}
1665static DEVICE_ATTR_RW(preferred_role);
1666
1667static ssize_t data_role_store(struct device *dev,
1668			       struct device_attribute *attr,
1669			       const char *buf, size_t size)
1670{
1671	struct typec_port *port = to_typec_port(dev);
1672	int ret;
1673
1674	if (!port->ops || !port->ops->dr_set) {
1675		dev_dbg(dev, "data role swapping not supported\n");
1676		return -EOPNOTSUPP;
1677	}
1678
1679	ret = sysfs_match_string(typec_data_roles, buf);
1680	if (ret < 0)
1681		return ret;
1682
1683	mutex_lock(&port->port_type_lock);
1684	if (port->cap->data != TYPEC_PORT_DRD) {
1685		ret = -EOPNOTSUPP;
1686		goto unlock_and_ret;
1687	}
1688
1689	ret = port->ops->dr_set(port, ret);
1690	if (ret)
1691		goto unlock_and_ret;
1692
1693	ret = size;
1694unlock_and_ret:
1695	mutex_unlock(&port->port_type_lock);
1696	return ret;
1697}
1698
1699static ssize_t data_role_show(struct device *dev,
1700			      struct device_attribute *attr, char *buf)
1701{
1702	struct typec_port *port = to_typec_port(dev);
1703
1704	if (port->cap->data == TYPEC_PORT_DRD)
1705		return sprintf(buf, "%s\n", port->data_role == TYPEC_HOST ?
1706			       "[host] device" : "host [device]");
1707
1708	return sprintf(buf, "[%s]\n", typec_data_roles[port->data_role]);
1709}
1710static DEVICE_ATTR_RW(data_role);
1711
1712static ssize_t power_role_store(struct device *dev,
1713				struct device_attribute *attr,
1714				const char *buf, size_t size)
1715{
1716	struct typec_port *port = to_typec_port(dev);
1717	int ret;
1718
1719	if (!port->ops || !port->ops->pr_set) {
1720		dev_dbg(dev, "power role swapping not supported\n");
1721		return -EOPNOTSUPP;
1722	}
1723
1724	if (port->pwr_opmode != TYPEC_PWR_MODE_PD) {
1725		dev_dbg(dev, "partner unable to swap power role\n");
1726		return -EIO;
1727	}
1728
1729	ret = sysfs_match_string(typec_roles, buf);
1730	if (ret < 0)
1731		return ret;
1732
1733	mutex_lock(&port->port_type_lock);
1734	if (port->port_type != TYPEC_PORT_DRP) {
1735		dev_dbg(dev, "port type fixed at \"%s\"",
1736			     typec_port_power_roles[port->port_type]);
1737		ret = -EOPNOTSUPP;
1738		goto unlock_and_ret;
1739	}
1740
1741	ret = port->ops->pr_set(port, ret);
1742	if (ret)
1743		goto unlock_and_ret;
1744
1745	ret = size;
1746unlock_and_ret:
1747	mutex_unlock(&port->port_type_lock);
1748	return ret;
1749}
1750
1751static ssize_t power_role_show(struct device *dev,
1752			       struct device_attribute *attr, char *buf)
1753{
1754	struct typec_port *port = to_typec_port(dev);
1755
1756	if (port->cap->type == TYPEC_PORT_DRP)
1757		return sprintf(buf, "%s\n", port->pwr_role == TYPEC_SOURCE ?
1758			       "[source] sink" : "source [sink]");
1759
1760	return sprintf(buf, "[%s]\n", typec_roles[port->pwr_role]);
1761}
1762static DEVICE_ATTR_RW(power_role);
1763
1764static ssize_t
1765port_type_store(struct device *dev, struct device_attribute *attr,
1766			const char *buf, size_t size)
1767{
1768	struct typec_port *port = to_typec_port(dev);
1769	int ret;
1770	enum typec_port_type type;
1771
1772	if (port->cap->type != TYPEC_PORT_DRP ||
1773	    !port->ops || !port->ops->port_type_set) {
1774		dev_dbg(dev, "changing port type not supported\n");
1775		return -EOPNOTSUPP;
1776	}
1777
1778	ret = sysfs_match_string(typec_port_power_roles, buf);
1779	if (ret < 0)
1780		return ret;
1781
1782	type = ret;
1783	mutex_lock(&port->port_type_lock);
1784
1785	if (port->port_type == type) {
1786		ret = size;
1787		goto unlock_and_ret;
1788	}
1789
1790	ret = port->ops->port_type_set(port, type);
1791	if (ret)
1792		goto unlock_and_ret;
1793
1794	port->port_type = type;
1795	ret = size;
1796
1797unlock_and_ret:
1798	mutex_unlock(&port->port_type_lock);
1799	return ret;
1800}
1801
1802static ssize_t
1803port_type_show(struct device *dev, struct device_attribute *attr,
1804		char *buf)
1805{
1806	struct typec_port *port = to_typec_port(dev);
1807
1808	if (port->cap->type == TYPEC_PORT_DRP)
1809		return sprintf(buf, "%s\n",
1810			       typec_port_types_drp[port->port_type]);
1811
1812	return sprintf(buf, "[%s]\n", typec_port_power_roles[port->cap->type]);
1813}
1814static DEVICE_ATTR_RW(port_type);
1815
1816static const char * const typec_pwr_opmodes[] = {
1817	[TYPEC_PWR_MODE_USB]	= "default",
1818	[TYPEC_PWR_MODE_1_5A]	= "1.5A",
1819	[TYPEC_PWR_MODE_3_0A]	= "3.0A",
1820	[TYPEC_PWR_MODE_PD]	= "usb_power_delivery",
1821};
1822
1823static ssize_t power_operation_mode_show(struct device *dev,
1824					 struct device_attribute *attr,
1825					 char *buf)
1826{
1827	struct typec_port *port = to_typec_port(dev);
1828
1829	return sprintf(buf, "%s\n", typec_pwr_opmodes[port->pwr_opmode]);
1830}
1831static DEVICE_ATTR_RO(power_operation_mode);
1832
1833static ssize_t vconn_source_store(struct device *dev,
1834				  struct device_attribute *attr,
1835				  const char *buf, size_t size)
1836{
1837	struct typec_port *port = to_typec_port(dev);
1838	bool source;
1839	int ret;
1840
1841	if (!port->cap->pd_revision) {
1842		dev_dbg(dev, "VCONN swap depends on USB Power Delivery\n");
1843		return -EOPNOTSUPP;
1844	}
1845
1846	if (!port->ops || !port->ops->vconn_set) {
1847		dev_dbg(dev, "VCONN swapping not supported\n");
1848		return -EOPNOTSUPP;
1849	}
1850
1851	ret = kstrtobool(buf, &source);
1852	if (ret)
1853		return ret;
1854
1855	ret = port->ops->vconn_set(port, (enum typec_role)source);
1856	if (ret)
1857		return ret;
1858
1859	return size;
1860}
1861
1862static ssize_t vconn_source_show(struct device *dev,
1863				 struct device_attribute *attr, char *buf)
1864{
1865	struct typec_port *port = to_typec_port(dev);
1866
1867	return sprintf(buf, "%s\n",
1868		       str_yes_no(port->vconn_role == TYPEC_SOURCE));
1869}
1870static DEVICE_ATTR_RW(vconn_source);
1871
1872static ssize_t supported_accessory_modes_show(struct device *dev,
1873					      struct device_attribute *attr,
1874					      char *buf)
1875{
1876	struct typec_port *port = to_typec_port(dev);
1877	ssize_t ret = 0;
1878	int i;
1879
1880	for (i = 0; i < ARRAY_SIZE(port->cap->accessory); i++) {
1881		if (port->cap->accessory[i])
1882			ret += sprintf(buf + ret, "%s ",
1883			       typec_accessory_modes[port->cap->accessory[i]]);
1884	}
1885
1886	if (!ret)
1887		return sprintf(buf, "none\n");
1888
1889	buf[ret - 1] = '\n';
1890
1891	return ret;
1892}
1893static DEVICE_ATTR_RO(supported_accessory_modes);
1894
1895static ssize_t usb_typec_revision_show(struct device *dev,
1896				       struct device_attribute *attr,
1897				       char *buf)
1898{
1899	struct typec_port *port = to_typec_port(dev);
1900	u16 rev = port->cap->revision;
1901
1902	return sprintf(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf);
1903}
1904static DEVICE_ATTR_RO(usb_typec_revision);
1905
1906static ssize_t usb_power_delivery_revision_show(struct device *dev,
1907						struct device_attribute *attr,
1908						char *buf)
1909{
1910	u16 rev = 0;
1911
1912	if (is_typec_partner(dev)) {
1913		struct typec_partner *partner = to_typec_partner(dev);
1914
1915		rev = partner->pd_revision;
1916	} else if (is_typec_cable(dev)) {
1917		struct typec_cable *cable = to_typec_cable(dev);
1918
1919		rev = cable->pd_revision;
1920	} else if (is_typec_port(dev)) {
1921		struct typec_port *p = to_typec_port(dev);
1922
1923		rev = p->cap->pd_revision;
1924	}
1925	return sysfs_emit(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf);
1926}
1927
1928static ssize_t orientation_show(struct device *dev,
1929				   struct device_attribute *attr,
1930				   char *buf)
1931{
1932	struct typec_port *port = to_typec_port(dev);
1933
1934	return sprintf(buf, "%s\n", typec_orientations[port->orientation]);
1935}
1936static DEVICE_ATTR_RO(orientation);
1937
1938static struct attribute *typec_attrs[] = {
1939	&dev_attr_data_role.attr,
1940	&dev_attr_power_operation_mode.attr,
1941	&dev_attr_power_role.attr,
1942	&dev_attr_preferred_role.attr,
1943	&dev_attr_supported_accessory_modes.attr,
1944	&dev_attr_usb_power_delivery_revision.attr,
1945	&dev_attr_usb_typec_revision.attr,
1946	&dev_attr_vconn_source.attr,
1947	&dev_attr_port_type.attr,
1948	&dev_attr_orientation.attr,
1949	&dev_attr_usb_capability.attr,
1950	NULL,
1951};
1952
1953static umode_t typec_attr_is_visible(struct kobject *kobj,
1954				     struct attribute *attr, int n)
1955{
1956	struct typec_port *port = to_typec_port(kobj_to_dev(kobj));
1957
1958	if (attr == &dev_attr_data_role.attr) {
1959		if (port->cap->data != TYPEC_PORT_DRD ||
1960		    !port->ops || !port->ops->dr_set)
1961			return 0444;
1962	} else if (attr == &dev_attr_power_role.attr) {
1963		if (port->cap->type != TYPEC_PORT_DRP ||
1964		    !port->ops || !port->ops->pr_set)
1965			return 0444;
1966	} else if (attr == &dev_attr_vconn_source.attr) {
1967		if (!port->cap->pd_revision ||
1968		    !port->ops || !port->ops->vconn_set)
1969			return 0444;
1970	} else if (attr == &dev_attr_preferred_role.attr) {
1971		if (port->cap->type != TYPEC_PORT_DRP ||
1972		    !port->ops || !port->ops->try_role)
1973			return 0444;
1974	} else if (attr == &dev_attr_port_type.attr) {
1975		if (!port->ops || !port->ops->port_type_set)
1976			return 0;
1977		if (port->cap->type != TYPEC_PORT_DRP)
1978			return 0444;
1979	} else if (attr == &dev_attr_orientation.attr) {
1980		if (port->cap->orientation_aware)
1981			return 0444;
1982		return 0;
1983	} else if (attr == &dev_attr_usb_capability.attr) {
1984		if (!port->cap->usb_capability)
1985			return 0;
1986		if (!port->ops || !port->ops->default_usb_mode_set)
1987			return 0444;
1988	}
1989
1990	return attr->mode;
1991}
1992
1993static const struct attribute_group typec_group = {
1994	.is_visible = typec_attr_is_visible,
1995	.attrs = typec_attrs,
1996};
1997
1998static const struct attribute_group *typec_groups[] = {
1999	&typec_group,
2000	&pd_group,
2001	NULL
2002};
2003
2004static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env)
2005{
2006	int ret;
2007
2008	ret = add_uevent_var(env, "TYPEC_PORT=%s", dev_name(dev));
2009	if (ret)
2010		dev_err(dev, "failed to add uevent TYPEC_PORT\n");
2011
2012	return ret;
2013}
2014
2015static void typec_release(struct device *dev)
2016{
2017	struct typec_port *port = to_typec_port(dev);
2018
2019	ida_free(&typec_index_ida, port->id);
2020	ida_destroy(&port->mode_ids);
2021	typec_switch_put(port->sw);
2022	typec_mux_put(port->mux);
2023	typec_retimer_put(port->retimer);
2024	kfree(port->cap);
2025	kfree(port);
2026}
2027
2028const struct device_type typec_port_dev_type = {
2029	.name = "typec_port",
2030	.groups = typec_groups,
2031	.uevent = typec_uevent,
2032	.release = typec_release,
2033};
2034
2035/* --------------------------------------- */
2036/* Driver callbacks to report role updates */
2037
2038static struct typec_partner *typec_get_partner(struct typec_port *port)
2039{
2040	struct device *dev;
2041
2042	dev = device_find_child(&port->dev, &typec_partner_dev_type,
2043				device_match_type);
2044	if (!dev)
2045		return NULL;
2046
2047	return to_typec_partner(dev);
2048}
2049
2050static void typec_partner_attach(struct typec_connector *con, struct device *dev)
2051{
2052	struct typec_port *port = container_of(con, struct typec_port, con);
2053	struct typec_partner *partner;
2054	struct usb_device *udev = to_usb_device(dev);
2055	enum usb_mode usb_mode;
2056
2057	mutex_lock(&port->partner_link_lock);
2058	if (udev->speed < USB_SPEED_SUPER) {
2059		usb_mode = USB_MODE_USB2;
2060		port->usb2_dev = dev;
2061	} else {
2062		usb_mode = USB_MODE_USB3;
2063		port->usb3_dev = dev;
2064	}
2065
2066	partner = typec_get_partner(port);
2067	if (partner) {
2068		typec_partner_set_usb_mode(partner, usb_mode);
2069		typec_partner_link_device(partner, dev);
2070		put_device(&partner->dev);
2071	}
2072	mutex_unlock(&port->partner_link_lock);
2073}
2074
2075static void typec_partner_deattach(struct typec_connector *con, struct device *dev)
2076{
2077	struct typec_port *port = container_of(con, struct typec_port, con);
2078	struct typec_partner *partner;
2079
2080	mutex_lock(&port->partner_link_lock);
2081	partner = typec_get_partner(port);
2082	if (partner) {
2083		typec_partner_unlink_device(partner, dev);
2084		put_device(&partner->dev);
2085	}
2086
2087	if (port->usb2_dev == dev)
2088		port->usb2_dev = NULL;
2089	else if (port->usb3_dev == dev)
2090		port->usb3_dev = NULL;
2091	mutex_unlock(&port->partner_link_lock);
2092}
2093
2094/**
2095 * typec_set_data_role - Report data role change
2096 * @port: The USB Type-C Port where the role was changed
2097 * @role: The new data role
2098 *
2099 * This routine is used by the port drivers to report data role changes.
2100 */
2101void typec_set_data_role(struct typec_port *port, enum typec_data_role role)
2102{
2103	struct typec_partner *partner;
2104
2105	if (port->data_role == role)
2106		return;
2107
2108	port->data_role = role;
2109	sysfs_notify(&port->dev.kobj, NULL, "data_role");
2110	kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
2111
2112	partner = typec_get_partner(port);
2113	if (!partner)
2114		return;
2115
2116	if (partner->identity)
2117		typec_product_type_notify(&partner->dev);
2118
2119	put_device(&partner->dev);
2120}
2121EXPORT_SYMBOL_GPL(typec_set_data_role);
2122
2123/**
2124 * typec_get_data_role - Get port data role
2125 * @port: The USB Type-C Port to query
2126 *
2127 * This routine is used by the altmode drivers to determine if the port is the
2128 * DFP before issuing Enter Mode
2129 */
2130enum typec_data_role typec_get_data_role(struct typec_port *port)
2131{
2132	return port->data_role;
2133}
2134EXPORT_SYMBOL_GPL(typec_get_data_role);
2135
2136/**
2137 * typec_set_pwr_role - Report power role change
2138 * @port: The USB Type-C Port where the role was changed
2139 * @role: The new data role
2140 *
2141 * This routine is used by the port drivers to report power role changes.
2142 */
2143void typec_set_pwr_role(struct typec_port *port, enum typec_role role)
2144{
2145	if (port->pwr_role == role)
2146		return;
2147
2148	port->pwr_role = role;
2149	sysfs_notify(&port->dev.kobj, NULL, "power_role");
2150	kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
2151}
2152EXPORT_SYMBOL_GPL(typec_set_pwr_role);
2153
2154/**
2155 * typec_set_vconn_role - Report VCONN source change
2156 * @port: The USB Type-C Port which VCONN role changed
2157 * @role: Source when @port is sourcing VCONN, or Sink when it's not
2158 *
2159 * This routine is used by the port drivers to report if the VCONN source is
2160 * changes.
2161 */
2162void typec_set_vconn_role(struct typec_port *port, enum typec_role role)
2163{
2164	if (port->vconn_role == role)
2165		return;
2166
2167	port->vconn_role = role;
2168	sysfs_notify(&port->dev.kobj, NULL, "vconn_source");
2169	kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
2170}
2171EXPORT_SYMBOL_GPL(typec_set_vconn_role);
2172
2173/**
2174 * typec_set_pwr_opmode - Report changed power operation mode
2175 * @port: The USB Type-C Port where the mode was changed
2176 * @opmode: New power operation mode
2177 *
2178 * This routine is used by the port drivers to report changed power operation
2179 * mode in @port. The modes are USB (default), 1.5A, 3.0A as defined in USB
2180 * Type-C specification, and "USB Power Delivery" when the power levels are
2181 * negotiated with methods defined in USB Power Delivery specification.
2182 */
2183void typec_set_pwr_opmode(struct typec_port *port,
2184			  enum typec_pwr_opmode opmode)
2185{
2186	struct device *partner_dev;
2187
2188	if (port->pwr_opmode == opmode)
2189		return;
2190
2191	port->pwr_opmode = opmode;
2192	sysfs_notify(&port->dev.kobj, NULL, "power_operation_mode");
2193	kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
2194
2195	partner_dev = device_find_child(&port->dev,
2196					&typec_partner_dev_type,
2197					device_match_type);
2198	if (partner_dev) {
2199		struct typec_partner *partner = to_typec_partner(partner_dev);
2200
2201		if (opmode == TYPEC_PWR_MODE_PD && !partner->usb_pd) {
2202			partner->usb_pd = 1;
2203			sysfs_notify(&partner_dev->kobj, NULL,
2204				     "supports_usb_power_delivery");
2205			kobject_uevent(&partner_dev->kobj, KOBJ_CHANGE);
2206		}
2207		put_device(partner_dev);
2208	}
2209}
2210EXPORT_SYMBOL_GPL(typec_set_pwr_opmode);
2211
2212/**
2213 * typec_find_pwr_opmode - Get the typec power operation mode capability
2214 * @name: power operation mode string
2215 *
2216 * This routine is used to find the typec_pwr_opmode by its string @name.
2217 *
2218 * Returns typec_pwr_opmode if success, otherwise negative error code.
2219 */
2220int typec_find_pwr_opmode(const char *name)
2221{
2222	return match_string(typec_pwr_opmodes,
2223			    ARRAY_SIZE(typec_pwr_opmodes), name);
2224}
2225EXPORT_SYMBOL_GPL(typec_find_pwr_opmode);
2226
2227/**
2228 * typec_find_orientation - Convert orientation string to enum typec_orientation
2229 * @name: Orientation string
2230 *
2231 * This routine is used to find the typec_orientation by its string name @name.
2232 *
2233 * Returns the orientation value on success, otherwise negative error code.
2234 */
2235int typec_find_orientation(const char *name)
2236{
2237	return match_string(typec_orientations, ARRAY_SIZE(typec_orientations),
2238			    name);
2239}
2240EXPORT_SYMBOL_GPL(typec_find_orientation);
2241
2242/**
2243 * typec_find_port_power_role - Get the typec port power capability
2244 * @name: port power capability string
2245 *
2246 * This routine is used to find the typec_port_type by its string name.
2247 *
2248 * Returns typec_port_type if success, otherwise negative error code.
2249 */
2250int typec_find_port_power_role(const char *name)
2251{
2252	return match_string(typec_port_power_roles,
2253			    ARRAY_SIZE(typec_port_power_roles), name);
2254}
2255EXPORT_SYMBOL_GPL(typec_find_port_power_role);
2256
2257/**
2258 * typec_find_power_role - Find the typec one specific power role
2259 * @name: power role string
2260 *
2261 * This routine is used to find the typec_role by its string name.
2262 *
2263 * Returns typec_role if success, otherwise negative error code.
2264 */
2265int typec_find_power_role(const char *name)
2266{
2267	return match_string(typec_roles, ARRAY_SIZE(typec_roles), name);
2268}
2269EXPORT_SYMBOL_GPL(typec_find_power_role);
2270
2271/**
2272 * typec_find_port_data_role - Get the typec port data capability
2273 * @name: port data capability string
2274 *
2275 * This routine is used to find the typec_port_data by its string name.
2276 *
2277 * Returns typec_port_data if success, otherwise negative error code.
2278 */
2279int typec_find_port_data_role(const char *name)
2280{
2281	return match_string(typec_port_data_roles,
2282			    ARRAY_SIZE(typec_port_data_roles), name);
2283}
2284EXPORT_SYMBOL_GPL(typec_find_port_data_role);
2285
2286/* ------------------------------------------ */
2287/* API for Multiplexer/DeMultiplexer Switches */
2288
2289/**
2290 * typec_set_orientation - Set USB Type-C cable plug orientation
2291 * @port: USB Type-C Port
2292 * @orientation: USB Type-C cable plug orientation
2293 *
2294 * Set cable plug orientation for @port.
2295 */
2296int typec_set_orientation(struct typec_port *port,
2297			  enum typec_orientation orientation)
2298{
2299	int ret;
2300
2301	ret = typec_switch_set(port->sw, orientation);
2302	if (ret)
2303		return ret;
2304
2305	port->orientation = orientation;
2306	sysfs_notify(&port->dev.kobj, NULL, "orientation");
2307	kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
2308
2309	return 0;
2310}
2311EXPORT_SYMBOL_GPL(typec_set_orientation);
2312
2313/**
2314 * typec_get_orientation - Get USB Type-C cable plug orientation
2315 * @port: USB Type-C Port
2316 *
2317 * Get current cable plug orientation for @port.
2318 */
2319enum typec_orientation typec_get_orientation(struct typec_port *port)
2320{
2321	return port->orientation;
2322}
2323EXPORT_SYMBOL_GPL(typec_get_orientation);
2324
2325/**
2326 * typec_set_mode - Set mode of operation for USB Type-C connector
2327 * @port: USB Type-C connector
2328 * @mode: Accessory Mode, USB Operation or Safe State
2329 *
2330 * Configure @port for Accessory Mode @mode. This function will configure the
2331 * muxes needed for @mode.
2332 */
2333int typec_set_mode(struct typec_port *port, int mode)
2334{
2335	struct typec_mux_state state = { };
2336
2337	state.mode = mode;
2338
2339	return typec_mux_set(port->mux, &state);
2340}
2341EXPORT_SYMBOL_GPL(typec_set_mode);
2342
2343/* --------------------------------------- */
2344
2345/**
2346 * typec_get_negotiated_svdm_version - Get negotiated SVDM Version
2347 * @port: USB Type-C Port.
2348 *
2349 * Get the negotiated SVDM Version. The Version is set to the port default
2350 * value stored in typec_capability on partner registration, and updated after
2351 * a successful Discover Identity if the negotiated value is less than the
2352 * default value.
2353 *
2354 * Returns usb_pd_svdm_ver if the partner has been registered otherwise -ENODEV.
2355 */
2356int typec_get_negotiated_svdm_version(struct typec_port *port)
2357{
2358	enum usb_pd_svdm_ver svdm_version;
2359	struct device *partner_dev;
2360
2361	partner_dev = device_find_child(&port->dev,
2362					&typec_partner_dev_type,
2363					device_match_type);
2364	if (!partner_dev)
2365		return -ENODEV;
2366
2367	svdm_version = to_typec_partner(partner_dev)->svdm_version;
2368	put_device(partner_dev);
2369
2370	return svdm_version;
2371}
2372EXPORT_SYMBOL_GPL(typec_get_negotiated_svdm_version);
2373
2374/**
2375 * typec_get_cable_svdm_version - Get cable negotiated SVDM Version
2376 * @port: USB Type-C Port.
2377 *
2378 * Get the negotiated SVDM Version for the cable. The Version is set to the port
2379 * default value based on the PD Revision during cable registration, and updated
2380 * after a successful Discover Identity if the negotiated value is less than the
2381 * default.
2382 *
2383 * Returns usb_pd_svdm_ver if the cable has been registered otherwise -ENODEV.
2384 */
2385int typec_get_cable_svdm_version(struct typec_port *port)
2386{
2387	enum usb_pd_svdm_ver svdm_version;
2388	struct device *cable_dev;
2389
2390	cable_dev = device_find_child(&port->dev, &typec_cable_dev_type,
2391				      device_match_type);
2392	if (!cable_dev)
2393		return -ENODEV;
2394
2395	svdm_version = to_typec_cable(cable_dev)->svdm_version;
2396	put_device(cable_dev);
2397
2398	return svdm_version;
2399}
2400EXPORT_SYMBOL_GPL(typec_get_cable_svdm_version);
2401
2402/**
2403 * typec_cable_set_svdm_version - Set negotiated Structured VDM (SVDM) Version
2404 * @cable: USB Type-C Active Cable that supports SVDM
2405 * @svdm_version: Negotiated SVDM Version
2406 *
2407 * This routine is used to save the negotiated SVDM Version.
2408 */
2409void typec_cable_set_svdm_version(struct typec_cable *cable, enum usb_pd_svdm_ver svdm_version)
2410{
2411	cable->svdm_version = svdm_version;
2412}
2413EXPORT_SYMBOL_GPL(typec_cable_set_svdm_version);
2414
2415/**
2416 * typec_get_drvdata - Return private driver data pointer
2417 * @port: USB Type-C port
2418 */
2419void *typec_get_drvdata(struct typec_port *port)
2420{
2421	return dev_get_drvdata(&port->dev);
2422}
2423EXPORT_SYMBOL_GPL(typec_get_drvdata);
2424
2425int typec_get_fw_cap(struct typec_capability *cap,
2426		     struct fwnode_handle *fwnode)
2427{
2428	const char *cap_str;
2429	int ret;
2430
2431	cap->fwnode = fwnode;
2432
2433	ret = fwnode_property_read_string(fwnode, "power-role", &cap_str);
2434	if (ret < 0)
2435		return ret;
2436
2437	ret = typec_find_port_power_role(cap_str);
2438	if (ret < 0)
2439		return ret;
2440	cap->type = ret;
2441
2442	/* USB data support is optional */
2443	ret = fwnode_property_read_string(fwnode, "data-role", &cap_str);
2444	if (ret == 0) {
2445		ret = typec_find_port_data_role(cap_str);
2446		if (ret < 0)
2447			return ret;
2448		cap->data = ret;
2449	}
2450
2451	/* Get the preferred power role for a DRP */
2452	if (cap->type == TYPEC_PORT_DRP) {
2453		cap->prefer_role = TYPEC_NO_PREFERRED_ROLE;
2454
2455		ret = fwnode_property_read_string(fwnode, "try-power-role", &cap_str);
2456		if (ret == 0) {
2457			ret = typec_find_power_role(cap_str);
2458			if (ret < 0)
2459				return ret;
2460			cap->prefer_role = ret;
2461		}
2462	}
2463
2464	return 0;
2465}
2466EXPORT_SYMBOL_GPL(typec_get_fw_cap);
2467
2468/**
2469 * typec_port_register_altmode - Register USB Type-C Port Alternate Mode
2470 * @port: USB Type-C Port that supports the alternate mode
2471 * @desc: Description of the alternate mode
2472 *
2473 * This routine is used to register an alternate mode that @port is capable of
2474 * supporting.
2475 *
2476 * Returns handle to the alternate mode on success or ERR_PTR on failure.
2477 */
2478struct typec_altmode *
2479typec_port_register_altmode(struct typec_port *port,
2480			    const struct typec_altmode_desc *desc)
2481{
2482	struct typec_altmode *adev;
2483	struct typec_mux *mux;
2484	struct typec_retimer *retimer;
2485
2486	mux = typec_mux_get(&port->dev);
2487	if (IS_ERR(mux))
2488		return ERR_CAST(mux);
2489
2490	retimer = typec_retimer_get(&port->dev);
2491	if (IS_ERR(retimer)) {
2492		typec_mux_put(mux);
2493		return ERR_CAST(retimer);
2494	}
2495
2496	adev = typec_register_altmode(&port->dev, desc);
2497	if (IS_ERR(adev)) {
2498		typec_retimer_put(retimer);
2499		typec_mux_put(mux);
2500	} else {
2501		to_altmode(adev)->mux = mux;
2502		to_altmode(adev)->retimer = retimer;
2503	}
2504
2505	return adev;
2506}
2507EXPORT_SYMBOL_GPL(typec_port_register_altmode);
2508
2509void typec_port_register_altmodes(struct typec_port *port,
2510	const struct typec_altmode_ops *ops, void *drvdata,
2511	struct typec_altmode **altmodes, size_t n)
2512{
2513	struct fwnode_handle *child;
2514	struct typec_altmode_desc desc;
2515	struct typec_altmode *alt;
2516	size_t index = 0;
2517	u16 svid;
2518	u32 vdo;
2519	int ret;
2520
2521	struct fwnode_handle *altmodes_node  __free(fwnode_handle) =
2522		device_get_named_child_node(&port->dev, "altmodes");
2523
2524	if (!altmodes_node)
2525		return; /* No altmodes specified */
2526
2527	fwnode_for_each_child_node(altmodes_node, child) {
2528		ret = fwnode_property_read_u16(child, "svid", &svid);
2529		if (ret) {
2530			dev_err(&port->dev, "Error reading svid for altmode %s\n",
2531				fwnode_get_name(child));
2532			continue;
2533		}
2534
2535		ret = fwnode_property_read_u32(child, "vdo", &vdo);
2536		if (ret) {
2537			dev_err(&port->dev, "Error reading vdo for altmode %s\n",
2538				fwnode_get_name(child));
2539			continue;
2540		}
2541
2542		if (index >= n) {
2543			dev_err(&port->dev, "Error not enough space for altmode %s\n",
2544				fwnode_get_name(child));
2545			continue;
2546		}
2547
2548		desc.svid = svid;
2549		desc.vdo = vdo;
2550		desc.mode = index + 1;
2551		alt = typec_port_register_altmode(port, &desc);
2552		if (IS_ERR(alt)) {
2553			dev_err(&port->dev, "Error registering altmode %s\n",
2554				fwnode_get_name(child));
2555			continue;
2556		}
2557
2558		typec_altmode_set_ops(alt, ops);
2559		typec_altmode_set_drvdata(alt, drvdata);
2560		altmodes[index] = alt;
2561		index++;
2562	}
2563}
2564EXPORT_SYMBOL_GPL(typec_port_register_altmodes);
2565
2566/**
2567 * typec_port_register_cable_ops - Register typec_cable_ops to port altmodes
2568 * @altmodes: USB Type-C Port's altmode vector
2569 * @max_altmodes: The maximum number of alt modes supported by the port
2570 * @ops: Cable alternate mode vector
2571 */
2572void typec_port_register_cable_ops(struct typec_altmode **altmodes, int max_altmodes,
2573				   const struct typec_cable_ops *ops)
2574{
2575	int i;
2576
2577	for (i = 0; i < max_altmodes; i++) {
2578		if (!altmodes[i])
2579			return;
2580		altmodes[i]->cable_ops = ops;
2581	}
2582}
2583EXPORT_SYMBOL_GPL(typec_port_register_cable_ops);
2584
2585/**
2586 * typec_register_port - Register a USB Type-C Port
2587 * @parent: Parent device
2588 * @cap: Description of the port
2589 *
2590 * Registers a device for USB Type-C Port described in @cap.
2591 *
2592 * Returns handle to the port on success or ERR_PTR on failure.
2593 */
2594struct typec_port *typec_register_port(struct device *parent,
2595				       const struct typec_capability *cap)
2596{
2597	struct typec_port *port;
2598	int ret;
2599	int id;
2600
2601	port = kzalloc(sizeof(*port), GFP_KERNEL);
2602	if (!port)
2603		return ERR_PTR(-ENOMEM);
2604
2605	id = ida_alloc(&typec_index_ida, GFP_KERNEL);
2606	if (id < 0) {
2607		kfree(port);
2608		return ERR_PTR(id);
2609	}
2610
2611	switch (cap->type) {
2612	case TYPEC_PORT_SRC:
2613		port->pwr_role = TYPEC_SOURCE;
2614		port->vconn_role = TYPEC_SOURCE;
2615		break;
2616	case TYPEC_PORT_SNK:
2617		port->pwr_role = TYPEC_SINK;
2618		port->vconn_role = TYPEC_SINK;
2619		break;
2620	case TYPEC_PORT_DRP:
2621		if (cap->prefer_role != TYPEC_NO_PREFERRED_ROLE)
2622			port->pwr_role = cap->prefer_role;
2623		else
2624			port->pwr_role = TYPEC_SINK;
2625		break;
2626	}
2627
2628	switch (cap->data) {
2629	case TYPEC_PORT_DFP:
2630		port->data_role = TYPEC_HOST;
2631		break;
2632	case TYPEC_PORT_UFP:
2633		port->data_role = TYPEC_DEVICE;
2634		break;
2635	case TYPEC_PORT_DRD:
2636		if (cap->prefer_role == TYPEC_SOURCE)
2637			port->data_role = TYPEC_HOST;
2638		else
2639			port->data_role = TYPEC_DEVICE;
2640		break;
2641	}
2642
2643	ida_init(&port->mode_ids);
2644	mutex_init(&port->port_type_lock);
2645	mutex_init(&port->partner_link_lock);
2646
2647	port->id = id;
2648	port->ops = cap->ops;
2649	port->port_type = cap->type;
2650	port->prefer_role = cap->prefer_role;
2651	port->con.attach = typec_partner_attach;
2652	port->con.deattach = typec_partner_deattach;
2653
2654	if (cap->usb_capability & USB_CAPABILITY_USB4)
2655		port->usb_mode = USB_MODE_USB4;
2656	else if (cap->usb_capability & USB_CAPABILITY_USB3)
2657		port->usb_mode = USB_MODE_USB3;
2658	else if (cap->usb_capability & USB_CAPABILITY_USB2)
2659		port->usb_mode = USB_MODE_USB2;
2660
2661	device_initialize(&port->dev);
2662	port->dev.class = &typec_class;
2663	port->dev.parent = parent;
2664	port->dev.fwnode = cap->fwnode;
2665	port->dev.type = &typec_port_dev_type;
2666	dev_set_name(&port->dev, "port%d", id);
2667	dev_set_drvdata(&port->dev, cap->driver_data);
2668
2669	port->cap = kmemdup(cap, sizeof(*cap), GFP_KERNEL);
2670	if (!port->cap) {
2671		put_device(&port->dev);
2672		return ERR_PTR(-ENOMEM);
2673	}
2674
2675	port->sw = typec_switch_get(&port->dev);
2676	if (IS_ERR(port->sw)) {
2677		ret = PTR_ERR(port->sw);
2678		put_device(&port->dev);
2679		return ERR_PTR(ret);
2680	}
2681
2682	port->mux = typec_mux_get(&port->dev);
2683	if (IS_ERR(port->mux)) {
2684		ret = PTR_ERR(port->mux);
2685		put_device(&port->dev);
2686		return ERR_PTR(ret);
2687	}
2688
2689	port->retimer = typec_retimer_get(&port->dev);
2690	if (IS_ERR(port->retimer)) {
2691		ret = PTR_ERR(port->retimer);
2692		put_device(&port->dev);
2693		return ERR_PTR(ret);
2694	}
2695
2696	port->pd = cap->pd;
2697
2698	ret = device_add(&port->dev);
2699	if (ret) {
2700		dev_err(parent, "failed to register port (%d)\n", ret);
2701		put_device(&port->dev);
2702		return ERR_PTR(ret);
2703	}
2704
2705	ret = usb_power_delivery_link_device(port->pd, &port->dev);
2706	if (ret) {
2707		dev_err(&port->dev, "failed to link pd\n");
2708		device_unregister(&port->dev);
2709		return ERR_PTR(ret);
2710	}
2711
2712	ret = typec_link_ports(port);
2713	if (ret)
2714		dev_warn(&port->dev, "failed to create symlinks (%d)\n", ret);
2715
2716	return port;
2717}
2718EXPORT_SYMBOL_GPL(typec_register_port);
2719
2720/**
2721 * typec_unregister_port - Unregister a USB Type-C Port
2722 * @port: The port to be unregistered
2723 *
2724 * Unregister device created with typec_register_port().
2725 */
2726void typec_unregister_port(struct typec_port *port)
2727{
2728	if (!IS_ERR_OR_NULL(port)) {
2729		typec_unlink_ports(port);
2730		typec_port_set_usb_power_delivery(port, NULL);
2731		device_unregister(&port->dev);
2732	}
2733}
2734EXPORT_SYMBOL_GPL(typec_unregister_port);
2735
2736static int __init typec_init(void)
2737{
2738	int ret;
2739
2740	ret = bus_register(&typec_bus);
2741	if (ret)
2742		return ret;
2743
2744	ret = class_register(&typec_mux_class);
2745	if (ret)
2746		goto err_unregister_bus;
2747
2748	ret = class_register(&retimer_class);
2749	if (ret)
2750		goto err_unregister_mux_class;
2751
2752	ret = class_register(&typec_class);
2753	if (ret)
2754		goto err_unregister_retimer_class;
2755
2756	ret = usb_power_delivery_init();
2757	if (ret)
2758		goto err_unregister_class;
2759
2760	return 0;
2761
2762err_unregister_class:
2763	class_unregister(&typec_class);
2764
2765err_unregister_retimer_class:
2766	class_unregister(&retimer_class);
2767
2768err_unregister_mux_class:
2769	class_unregister(&typec_mux_class);
2770
2771err_unregister_bus:
2772	bus_unregister(&typec_bus);
2773
2774	return ret;
2775}
2776subsys_initcall(typec_init);
2777
2778static void __exit typec_exit(void)
2779{
2780	usb_power_delivery_exit();
2781	class_unregister(&typec_class);
2782	ida_destroy(&typec_index_ida);
2783	bus_unregister(&typec_bus);
2784	class_unregister(&typec_mux_class);
2785	class_unregister(&retimer_class);
2786}
2787module_exit(typec_exit);
2788
2789MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
2790MODULE_LICENSE("GPL v2");
2791MODULE_DESCRIPTION("USB Type-C Connector Class");
~/ Read-only file preview.