1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * USB Role Switch Support 4 * 5 * Copyright (C) 2018 Intel Corporation 6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> 7 * Hans de Goede <hdegoede@redhat.com> 8 */ 9 10 #include <linux/component.h> 11 #include <linux/usb/role.h> 12 #include <linux/property.h> 13 #include <linux/device.h> 14 #include <linux/lockdep.h> 15 #include <linux/module.h> 16 #include <linux/mutex.h> 17 #include <linux/slab.h> 18 19 static const struct class role_class = { 20 .name = "usb_role", 21 }; 22 23 struct usb_role_switch { 24 struct device dev; 25 struct lock_class_key key; 26 struct mutex lock; /* device lock*/ 27 struct module *module; /* the module this device depends on */ 28 enum usb_role role; 29 bool registered; 30 31 /* From descriptor */ 32 struct device *usb2_port; 33 struct device *usb3_port; 34 struct device *udc; 35 usb_role_switch_set_t set; 36 usb_role_switch_get_t get; 37 bool allow_userspace_control; 38 }; 39 40 #define to_role_switch(d) container_of(d, struct usb_role_switch, dev) 41 42 static int connector_bind(struct device *dev, struct device *connector, void *data) 43 { 44 int ret; 45 46 ret = sysfs_create_link(&dev->kobj, &connector->kobj, "connector"); 47 if (ret) 48 return ret; 49 50 ret = sysfs_create_link(&connector->kobj, &dev->kobj, "usb-role-switch"); 51 if (ret) 52 sysfs_remove_link(&dev->kobj, "connector"); 53 54 return ret; 55 } 56 57 static void connector_unbind(struct device *dev, struct device *connector, void *data) 58 { 59 sysfs_remove_link(&connector->kobj, "usb-role-switch"); 60 sysfs_remove_link(&dev->kobj, "connector"); 61 } 62 63 static const struct component_ops connector_ops = { 64 .bind = connector_bind, 65 .unbind = connector_unbind, 66 }; 67 68 /** 69 * usb_role_switch_set_role - Set USB role for a switch 70 * @sw: USB role switch 71 * @role: USB role to be switched to 72 * 73 * Set USB role @role for @sw. 74 */ 75 int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role) 76 { 77 int ret; 78 79 if (IS_ERR_OR_NULL(sw)) 80 return 0; 81 82 if (!sw->registered) 83 return -EOPNOTSUPP; 84 85 mutex_lock(&sw->lock); 86 87 ret = sw->set(sw, role); 88 if (!ret) { 89 sw->role = role; 90 kobject_uevent(&sw->dev.kobj, KOBJ_CHANGE); 91 } 92 93 mutex_unlock(&sw->lock); 94 95 return ret; 96 } 97 EXPORT_SYMBOL_GPL(usb_role_switch_set_role); 98 99 /** 100 * usb_role_switch_get_role - Get the USB role for a switch 101 * @sw: USB role switch 102 * 103 * Depending on the role-switch-driver this function returns either a cached 104 * value of the last set role, or reads back the actual value from the hardware. 105 */ 106 enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw) 107 { 108 enum usb_role role; 109 110 if (IS_ERR_OR_NULL(sw) || !sw->registered) 111 return USB_ROLE_NONE; 112 113 mutex_lock(&sw->lock); 114 115 if (sw->get) 116 role = sw->get(sw); 117 else 118 role = sw->role; 119 120 mutex_unlock(&sw->lock); 121 122 return role; 123 } 124 EXPORT_SYMBOL_GPL(usb_role_switch_get_role); 125 126 static void *usb_role_switch_match(const struct fwnode_handle *fwnode, const char *id, 127 void *data) 128 { 129 struct device *dev; 130 131 if (id && !fwnode_property_present(fwnode, id)) 132 return NULL; 133 134 dev = class_find_device_by_fwnode(&role_class, fwnode); 135 136 return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER); 137 } 138 139 static struct usb_role_switch * 140 usb_role_switch_is_parent(struct fwnode_handle *fwnode) 141 { 142 struct fwnode_handle *parent; 143 struct device *dev; 144 145 if (!fwnode_device_is_compatible(fwnode, "usb-b-connector")) 146 return NULL; 147 148 parent = fwnode_get_parent(fwnode); 149 150 if (!fwnode_property_present(parent, "usb-role-switch")) { 151 fwnode_handle_put(parent); 152 return NULL; 153 } 154 155 dev = class_find_device_by_fwnode(&role_class, parent); 156 fwnode_handle_put(parent); 157 return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER); 158 } 159 160 /** 161 * usb_role_switch_get - Find USB role switch linked with the caller 162 * @dev: The caller device 163 * 164 * Finds and returns role switch linked with @dev. The reference count for the 165 * found switch is incremented. 166 */ 167 struct usb_role_switch *usb_role_switch_get(struct device *dev) 168 { 169 struct usb_role_switch *sw; 170 171 sw = usb_role_switch_is_parent(dev_fwnode(dev)); 172 if (!sw) 173 sw = device_connection_find_match(dev, "usb-role-switch", NULL, 174 usb_role_switch_match); 175 176 if (!IS_ERR_OR_NULL(sw)) 177 WARN_ON(!try_module_get(sw->module)); 178 179 return sw; 180 } 181 EXPORT_SYMBOL_GPL(usb_role_switch_get); 182 183 /** 184 * fwnode_usb_role_switch_get - Find USB role switch linked with the caller 185 * @fwnode: The caller device node 186 * 187 * This is similar to the usb_role_switch_get() function above, but it searches 188 * the switch using fwnode instead of device entry. 189 */ 190 struct usb_role_switch *fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) 191 { 192 struct usb_role_switch *sw; 193 194 sw = usb_role_switch_is_parent(fwnode); 195 if (!sw) 196 sw = fwnode_connection_find_match(fwnode, "usb-role-switch", 197 NULL, usb_role_switch_match); 198 if (!IS_ERR_OR_NULL(sw)) 199 WARN_ON(!try_module_get(sw->module)); 200 201 return sw; 202 } 203 EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); 204 205 /** 206 * usb_role_switch_put - Release handle to a switch 207 * @sw: USB Role Switch 208 * 209 * Decrement reference count for @sw. 210 */ 211 void usb_role_switch_put(struct usb_role_switch *sw) 212 { 213 if (!IS_ERR_OR_NULL(sw)) { 214 module_put(sw->module); 215 put_device(&sw->dev); 216 } 217 } 218 EXPORT_SYMBOL_GPL(usb_role_switch_put); 219 220 /** 221 * usb_role_switch_find_by_fwnode - Find USB role switch with its fwnode 222 * @fwnode: fwnode of the USB Role Switch 223 * 224 * Finds and returns role switch with @fwnode. The reference count for the 225 * found switch is incremented. 226 */ 227 struct usb_role_switch * 228 usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode) 229 { 230 struct device *dev; 231 struct usb_role_switch *sw = NULL; 232 233 if (!fwnode) 234 return NULL; 235 236 dev = class_find_device_by_fwnode(&role_class, fwnode); 237 if (dev) { 238 sw = to_role_switch(dev); 239 WARN_ON(!try_module_get(sw->module)); 240 } 241 242 return sw; 243 } 244 EXPORT_SYMBOL_GPL(usb_role_switch_find_by_fwnode); 245 246 static umode_t 247 usb_role_switch_is_visible(struct kobject *kobj, struct attribute *attr, int n) 248 { 249 struct device *dev = kobj_to_dev(kobj); 250 struct usb_role_switch *sw = to_role_switch(dev); 251 252 if (sw->allow_userspace_control) 253 return attr->mode; 254 255 return 0; 256 } 257 258 static const char * const usb_roles[] = { 259 [USB_ROLE_NONE] = "none", 260 [USB_ROLE_HOST] = "host", 261 [USB_ROLE_DEVICE] = "device", 262 }; 263 264 const char *usb_role_string(enum usb_role role) 265 { 266 if (role < 0 || role >= ARRAY_SIZE(usb_roles)) 267 return "unknown"; 268 269 return usb_roles[role]; 270 } 271 EXPORT_SYMBOL_GPL(usb_role_string); 272 273 static ssize_t 274 role_show(struct device *dev, struct device_attribute *attr, char *buf) 275 { 276 struct usb_role_switch *sw = to_role_switch(dev); 277 enum usb_role role = usb_role_switch_get_role(sw); 278 279 return sprintf(buf, "%s\n", usb_roles[role]); 280 } 281 282 static ssize_t role_store(struct device *dev, struct device_attribute *attr, 283 const char *buf, size_t size) 284 { 285 struct usb_role_switch *sw = to_role_switch(dev); 286 int ret; 287 288 ret = sysfs_match_string(usb_roles, buf); 289 if (ret < 0) { 290 bool res; 291 292 /* Extra check if the user wants to disable the switch */ 293 ret = kstrtobool(buf, &res); 294 if (ret || res) 295 return -EINVAL; 296 } 297 298 ret = usb_role_switch_set_role(sw, ret); 299 if (ret) 300 return ret; 301 302 return size; 303 } 304 static DEVICE_ATTR_RW(role); 305 306 static struct attribute *usb_role_switch_attrs[] = { 307 &dev_attr_role.attr, 308 NULL, 309 }; 310 311 static const struct attribute_group usb_role_switch_group = { 312 .is_visible = usb_role_switch_is_visible, 313 .attrs = usb_role_switch_attrs, 314 }; 315 316 static const struct attribute_group *usb_role_switch_groups[] = { 317 &usb_role_switch_group, 318 NULL, 319 }; 320 321 static int usb_role_switch_uevent(const struct device *dev, struct kobj_uevent_env *env) 322 { 323 int ret; 324 325 ret = add_uevent_var(env, "USB_ROLE_SWITCH=%s", dev_name(dev)); 326 if (ret) 327 dev_err(dev, "failed to add uevent USB_ROLE_SWITCH\n"); 328 329 return ret; 330 } 331 332 static void usb_role_switch_release(struct device *dev) 333 { 334 struct usb_role_switch *sw = to_role_switch(dev); 335 336 mutex_destroy(&sw->lock); 337 lockdep_unregister_key(&sw->key); 338 kfree(sw); 339 } 340 341 static const struct device_type usb_role_dev_type = { 342 .name = "usb_role_switch", 343 .groups = usb_role_switch_groups, 344 .uevent = usb_role_switch_uevent, 345 .release = usb_role_switch_release, 346 }; 347 348 /** 349 * usb_role_switch_register - Register USB Role Switch 350 * @parent: Parent device for the switch 351 * @desc: Description of the switch 352 * 353 * USB Role Switch is a device capable or choosing the role for USB connector. 354 * On platforms where the USB controller is dual-role capable, the controller 355 * driver will need to register the switch. On platforms where the USB host and 356 * USB device controllers behind the connector are separate, there will be a 357 * mux, and the driver for that mux will need to register the switch. 358 * 359 * Returns handle to a new role switch or ERR_PTR. The content of @desc is 360 * copied. 361 */ 362 struct usb_role_switch * 363 usb_role_switch_register(struct device *parent, 364 const struct usb_role_switch_desc *desc) 365 { 366 struct usb_role_switch *sw; 367 int ret; 368 369 if (!desc || !desc->set) 370 return ERR_PTR(-EINVAL); 371 372 sw = kzalloc_obj(*sw); 373 if (!sw) 374 return ERR_PTR(-ENOMEM); 375 376 lockdep_register_key(&sw->key); 377 mutex_init_with_key(&sw->lock, &sw->key); 378 379 sw->allow_userspace_control = desc->allow_userspace_control; 380 sw->usb2_port = desc->usb2_port; 381 sw->usb3_port = desc->usb3_port; 382 sw->udc = desc->udc; 383 sw->set = desc->set; 384 sw->get = desc->get; 385 386 sw->module = parent->driver->owner; 387 sw->dev.parent = parent; 388 sw->dev.fwnode = desc->fwnode; 389 sw->dev.class = &role_class; 390 sw->dev.type = &usb_role_dev_type; 391 dev_set_drvdata(&sw->dev, desc->driver_data); 392 dev_set_name(&sw->dev, "%s-role-switch", 393 desc->name ? desc->name : dev_name(parent)); 394 395 sw->registered = true; 396 397 ret = device_register(&sw->dev); 398 if (ret) { 399 sw->registered = false; 400 put_device(&sw->dev); 401 return ERR_PTR(ret); 402 } 403 404 if (dev_fwnode(&sw->dev)) { 405 ret = component_add(&sw->dev, &connector_ops); 406 if (ret) 407 dev_warn(&sw->dev, "failed to add component\n"); 408 } 409 410 /* TODO: Symlinks for the host port and the device controller. */ 411 412 return sw; 413 } 414 EXPORT_SYMBOL_GPL(usb_role_switch_register); 415 416 /** 417 * usb_role_switch_unregister - Unregsiter USB Role Switch 418 * @sw: USB Role Switch 419 * 420 * Unregister switch that was registered with usb_role_switch_register(). 421 */ 422 void usb_role_switch_unregister(struct usb_role_switch *sw) 423 { 424 if (IS_ERR_OR_NULL(sw)) 425 return; 426 sw->registered = false; 427 if (dev_fwnode(&sw->dev)) 428 component_del(&sw->dev, &connector_ops); 429 device_unregister(&sw->dev); 430 } 431 EXPORT_SYMBOL_GPL(usb_role_switch_unregister); 432 433 /** 434 * usb_role_switch_set_drvdata - Assign private data pointer to a switch 435 * @sw: USB Role Switch 436 * @data: Private data pointer 437 */ 438 void usb_role_switch_set_drvdata(struct usb_role_switch *sw, void *data) 439 { 440 dev_set_drvdata(&sw->dev, data); 441 } 442 EXPORT_SYMBOL_GPL(usb_role_switch_set_drvdata); 443 444 /** 445 * usb_role_switch_get_drvdata - Get the private data pointer of a switch 446 * @sw: USB Role Switch 447 */ 448 void *usb_role_switch_get_drvdata(struct usb_role_switch *sw) 449 { 450 return dev_get_drvdata(&sw->dev); 451 } 452 EXPORT_SYMBOL_GPL(usb_role_switch_get_drvdata); 453 454 static int __init usb_roles_init(void) 455 { 456 return class_register(&role_class); 457 } 458 subsys_initcall(usb_roles_init); 459 460 static void __exit usb_roles_exit(void) 461 { 462 class_unregister(&role_class); 463 } 464 module_exit(usb_roles_exit); 465 466 MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>"); 467 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 468 MODULE_LICENSE("GPL v2"); 469 MODULE_DESCRIPTION("USB Role Class"); 470