cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

class.c (56266B)


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