diff options
author | Simon Glass <sjg@chromium.org> | 2015-05-13 07:02:23 -0600 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2015-06-10 19:26:54 -0600 |
commit | 0c5dd9ae2f2e731c5c961fd92fa974aaa3cbdc27 (patch) | |
tree | bacb24a29b43b9d114d8aa98c3f545a597202429 | |
parent | 534f9d3feffdcccc0f21def87bb21b8aebb7ba30 (diff) |
dm: usb: Implement usb_detect_change() for driver model
Support this function with driver model also (CONFIG_DM_USB).
Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | drivers/usb/host/usb-uclass.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index 963464cff9..6e86f4a24a 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -628,6 +628,49 @@ int usb_scan_device(struct udevice *parent, int port, return 0; } +/* + * Detect if a USB device has been plugged or unplugged. + */ +int usb_detect_change(void) +{ + struct udevice *hub; + struct uclass *uc; + int change = 0; + int ret; + + ret = uclass_get(UCLASS_USB_HUB, &uc); + if (ret) + return ret; + + uclass_foreach_dev(hub, uc) { + struct usb_device *udev; + struct udevice *dev; + + if (!device_active(hub)) + continue; + for (device_find_first_child(hub, &dev); + dev; + device_find_next_child(&dev)) { + struct usb_port_status status; + + if (!device_active(dev)) + continue; + + udev = dev_get_parentdata(dev); + if (usb_get_port_status(udev, udev->portnr, &status) + < 0) + /* USB request failed */ + continue; + + if (le16_to_cpu(status.wPortChange) & + USB_PORT_STAT_C_CONNECTION) + change++; + } + } + + return change; +} + int usb_child_post_bind(struct udevice *dev) { struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); |