usb: core: hub: Create platform devices for onboard hubs in hub_probe()
authorMatthias Kaehlcke <mka@chromium.org>
Thu, 30 Jun 2022 19:35:30 +0000 (12:35 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Jul 2022 12:53:50 +0000 (14:53 +0200)
Call onboard_hub_create/destroy_pdevs() from hub_probe/disconnect()
to create/destroy platform devices for onboard USB hubs that may be
connected to the hub. The onboard hubs must have nodes in the
device tree.

onboard_hub_create/destroy_pdevs() are NOPs unless
CONFIG_USB_ONBOARD_HUB=y/m.

Also add a field to struct usb_hub to keep track of the onboard hub
platform devices that are owned by the hub.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
Link: https://lore.kernel.org/r/20220630123445.v24.4.Ic9dd36078f9d803de82ca01a6700c58b8e4de27e@changeid
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/hub.c
drivers/usb/core/hub.h

index b7f66dc..2633acd 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/usb/hcd.h>
+#include <linux/usb/onboard_hub.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/quirks.h>
 #include <linux/workqueue.h>
@@ -1752,6 +1753,8 @@ static void hub_disconnect(struct usb_interface *intf)
        if (hub->quirk_disable_autosuspend)
                usb_autopm_put_interface(intf);
 
+       onboard_hub_destroy_pdevs(&hub->onboard_hub_devs);
+
        kref_put(&hub->kref, hub_release);
 }
 
@@ -1869,6 +1872,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
        INIT_DELAYED_WORK(&hub->leds, led_work);
        INIT_DELAYED_WORK(&hub->init_work, NULL);
        INIT_WORK(&hub->events, hub_event);
+       INIT_LIST_HEAD(&hub->onboard_hub_devs);
        spin_lock_init(&hub->irq_urb_lock);
        timer_setup(&hub->irq_urb_retry, hub_retry_irq_urb, 0);
        usb_get_intf(intf);
@@ -1889,8 +1893,11 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
                usb_autopm_get_interface_no_resume(intf);
        }
 
-       if (hub_configure(hub, &desc->endpoint[0].desc) >= 0)
+       if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) {
+               onboard_hub_create_pdevs(hdev, &hub->onboard_hub_devs);
+
                return 0;
+       }
 
        hub_disconnect(intf);
        return -ENODEV;
index 3fcb380..b292585 100644 (file)
@@ -73,6 +73,7 @@ struct usb_hub {
        spinlock_t              irq_urb_lock;
        struct timer_list       irq_urb_retry;
        struct usb_port         **ports;
+       struct list_head        onboard_hub_devs;
 };
 
 /**