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