Lines Matching +full:usb +full:- +full:attach
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for onboard USB devices
26 #include <linux/usb.h>
27 #include <linux/usb/hcd.h>
28 #include <linux/usb/onboard_dev.h>
71 const char * const *supply_names = onboard_dev->pdata->supply_names; in onboard_dev_get_regulators()
72 unsigned int num_supplies = onboard_dev->pdata->num_supplies; in onboard_dev_get_regulators()
73 struct device *dev = onboard_dev->dev; in onboard_dev_get_regulators()
78 return dev_err_probe(dev, -EINVAL, "max %d supplies supported!\n", in onboard_dev_get_regulators()
82 onboard_dev->supplies[i].supply = supply_names[i]; in onboard_dev_get_regulators()
84 err = devm_regulator_bulk_get(dev, num_supplies, onboard_dev->supplies); in onboard_dev_get_regulators()
96 err = clk_prepare_enable(onboard_dev->clk); in onboard_dev_power_on()
98 dev_err(onboard_dev->dev, "failed to enable clock: %pe\n", in onboard_dev_power_on()
103 err = regulator_bulk_enable(onboard_dev->pdata->num_supplies, in onboard_dev_power_on()
104 onboard_dev->supplies); in onboard_dev_power_on()
106 dev_err(onboard_dev->dev, "failed to enable supplies: %pe\n", in onboard_dev_power_on()
111 fsleep(onboard_dev->pdata->reset_us); in onboard_dev_power_on()
112 gpiod_set_value_cansleep(onboard_dev->reset_gpio, 0); in onboard_dev_power_on()
113 fsleep(onboard_dev->pdata->power_on_delay_us); in onboard_dev_power_on()
115 onboard_dev->is_powered_on = true; in onboard_dev_power_on()
120 clk_disable_unprepare(onboard_dev->clk); in onboard_dev_power_on()
128 gpiod_set_value_cansleep(onboard_dev->reset_gpio, 1); in onboard_dev_power_off()
130 err = regulator_bulk_disable(onboard_dev->pdata->num_supplies, in onboard_dev_power_off()
131 onboard_dev->supplies); in onboard_dev_power_off()
133 dev_err(onboard_dev->dev, "failed to disable supplies: %pe\n", in onboard_dev_power_off()
138 clk_disable_unprepare(onboard_dev->clk); in onboard_dev_power_off()
140 onboard_dev->is_powered_on = false; in onboard_dev_power_off()
151 if (onboard_dev->always_powered_in_suspend) in onboard_dev_suspend()
154 mutex_lock(&onboard_dev->lock); in onboard_dev_suspend()
156 list_for_each_entry(node, &onboard_dev->udev_list, list) { in onboard_dev_suspend()
157 if (!device_may_wakeup(node->udev->bus->controller)) in onboard_dev_suspend()
160 if (usb_wakeup_enabled_descendants(node->udev)) { in onboard_dev_suspend()
166 mutex_unlock(&onboard_dev->lock); in onboard_dev_suspend()
178 if (onboard_dev->is_powered_on) in onboard_dev_resume()
187 snprintf(buf, size, "usb_dev.%s", dev_name(&udev->dev)); in get_udev_link_name()
197 mutex_lock(&onboard_dev->lock); in onboard_dev_add_usbdev()
199 if (onboard_dev->going_away) { in onboard_dev_add_usbdev()
200 err = -EINVAL; in onboard_dev_add_usbdev()
206 err = -ENOMEM; in onboard_dev_add_usbdev()
210 node->udev = udev; in onboard_dev_add_usbdev()
212 list_add(&node->list, &onboard_dev->udev_list); in onboard_dev_add_usbdev()
214 mutex_unlock(&onboard_dev->lock); in onboard_dev_add_usbdev()
217 WARN_ON(sysfs_create_link(&onboard_dev->dev->kobj, &udev->dev.kobj, in onboard_dev_add_usbdev()
223 mutex_unlock(&onboard_dev->lock); in onboard_dev_add_usbdev()
235 sysfs_remove_link(&onboard_dev->dev->kobj, link_name); in onboard_dev_remove_usbdev()
237 mutex_lock(&onboard_dev->lock); in onboard_dev_remove_usbdev()
239 list_for_each_entry(node, &onboard_dev->udev_list, list) { in onboard_dev_remove_usbdev()
240 if (node->udev == udev) { in onboard_dev_remove_usbdev()
241 list_del(&node->list); in onboard_dev_remove_usbdev()
247 mutex_unlock(&onboard_dev->lock); in onboard_dev_remove_usbdev()
256 return sysfs_emit(buf, "%d\n", onboard_dev->always_powered_in_suspend); in always_powered_in_suspend_show()
271 onboard_dev->always_powered_in_suspend = val; in always_powered_in_suspend_store()
290 !onboard_dev->pdata->is_hub) in onboard_dev_attrs_are_visible()
293 return attr->mode; in onboard_dev_attrs_are_visible()
309 pr_err("Failed to attach USB driver: %pe\n", ERR_PTR(err)); in onboard_dev_attach_usb_driver()
315 struct device *dev = &client->dev; in onboard_dev_5744_i2c_init()
343 return dev_err_probe(dev, ret, "USB Attach with SMBus command failed\n"); in onboard_dev_5744_i2c_init()
347 return -ENODEV; in onboard_dev_5744_i2c_init()
353 struct device *dev = &pdev->dev; in onboard_dev_probe()
360 return -ENOMEM; in onboard_dev_probe()
362 onboard_dev->pdata = device_get_match_data(dev); in onboard_dev_probe()
363 if (!onboard_dev->pdata) in onboard_dev_probe()
364 return -EINVAL; in onboard_dev_probe()
366 if (!onboard_dev->pdata->is_hub) in onboard_dev_probe()
367 onboard_dev->always_powered_in_suspend = true; in onboard_dev_probe()
369 onboard_dev->dev = dev; in onboard_dev_probe()
375 onboard_dev->clk = devm_clk_get_optional(dev, NULL); in onboard_dev_probe()
376 if (IS_ERR(onboard_dev->clk)) in onboard_dev_probe()
377 return dev_err_probe(dev, PTR_ERR(onboard_dev->clk), in onboard_dev_probe()
380 onboard_dev->reset_gpio = devm_gpiod_get_optional(dev, "reset", in onboard_dev_probe()
382 if (IS_ERR(onboard_dev->reset_gpio)) in onboard_dev_probe()
383 return dev_err_probe(dev, PTR_ERR(onboard_dev->reset_gpio), in onboard_dev_probe()
386 mutex_init(&onboard_dev->lock); in onboard_dev_probe()
387 INIT_LIST_HEAD(&onboard_dev->udev_list); in onboard_dev_probe()
395 i2c_node = of_parse_phandle(pdev->dev.of_node, "i2c-bus", 0); in onboard_dev_probe()
405 err = -EPROBE_DEFER; in onboard_dev_probe()
409 if (of_device_is_compatible(pdev->dev.of_node, "usb424,2744") || in onboard_dev_probe()
410 of_device_is_compatible(pdev->dev.of_node, "usb424,5744")) in onboard_dev_probe()
413 put_device(&client->dev); in onboard_dev_probe()
419 * The USB driver might have been detached from the USB devices by in onboard_dev_probe()
421 * make sure to re-attach it if needed. in onboard_dev_probe()
423 * This needs to be done deferred to avoid self-deadlocks on systems in onboard_dev_probe()
437 struct onboard_dev *onboard_dev = dev_get_drvdata(&pdev->dev); in onboard_dev_remove()
441 onboard_dev->going_away = true; in onboard_dev_remove()
443 mutex_lock(&onboard_dev->lock); in onboard_dev_remove()
445 /* unbind the USB devices to avoid dangling references to this device */ in onboard_dev_remove()
446 while (!list_empty(&onboard_dev->udev_list)) { in onboard_dev_remove()
447 node = list_first_entry(&onboard_dev->udev_list, in onboard_dev_remove()
449 udev = node->udev; in onboard_dev_remove()
453 * which acquires onboard_dev->lock. We must release the lock in onboard_dev_remove()
456 get_device(&udev->dev); in onboard_dev_remove()
457 mutex_unlock(&onboard_dev->lock); in onboard_dev_remove()
458 device_release_driver(&udev->dev); in onboard_dev_remove()
459 put_device(&udev->dev); in onboard_dev_remove()
460 mutex_lock(&onboard_dev->lock); in onboard_dev_remove()
463 mutex_unlock(&onboard_dev->lock); in onboard_dev_remove()
479 .name = "onboard-usb-dev",
486 /************************** USB driver **************************/
497 * Returns the onboard_dev platform device that is associated with the USB
506 pdev = of_find_device_by_node(dev->of_node); in _find_onboard_dev()
508 np = of_parse_phandle(dev->of_node, "peer-hub", 0); in _find_onboard_dev()
511 return ERR_PTR(-EINVAL); in _find_onboard_dev()
518 return ERR_PTR(-ENODEV); in _find_onboard_dev()
521 onboard_dev = dev_get_drvdata(&pdev->dev); in _find_onboard_dev()
522 put_device(&pdev->dev); in _find_onboard_dev()
532 return ERR_PTR(-EPROBE_DEFER); in _find_onboard_dev()
540 return !!udev->dev.of_node; in onboard_dev_usbdev_match()
545 struct device *dev = &udev->dev; in onboard_dev_usbdev_probe()
564 struct onboard_dev *onboard_dev = dev_get_drvdata(&udev->dev); in onboard_dev_usbdev_disconnect()
573 { USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 HUB */
574 { USB_DEVICE(VENDOR_ID_GENESYS, 0x0610) }, /* Genesys Logic GL852G USB 2.0 HUB */
575 { USB_DEVICE(VENDOR_ID_GENESYS, 0x0620) }, /* Genesys Logic GL3523 USB 3.1 HUB */
576 { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2412) }, /* USB2412 USB 2.0 HUB */
577 { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 HUB */
578 { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 HUB */
579 { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2744) }, /* USB5744 USB 2.0 HUB */
580 { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x5744) }, /* USB5744 USB 3.0 HUB */
581 { USB_DEVICE(VENDOR_ID_REALTEK, 0x0411) }, /* RTS5411 USB 3.1 HUB */
582 { USB_DEVICE(VENDOR_ID_REALTEK, 0x5411) }, /* RTS5411 USB 2.1 HUB */
583 { USB_DEVICE(VENDOR_ID_REALTEK, 0x0414) }, /* RTS5414 USB 3.2 HUB */
584 { USB_DEVICE(VENDOR_ID_REALTEK, 0x5414) }, /* RTS5414 USB 2.1 HUB */
594 MODULE_DEVICE_TABLE(usb, onboard_dev_id_table);
597 .name = "onboard-usb-dev",
632 MODULE_DESCRIPTION("Driver for discrete onboard USB devices");