Some atypical users of xhci-pci might need to manually reset their xHCI
controller before starting the HCD setup. Check if a reset controller
device is available to the PCI bus and trigger a reset.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulie...@suse.de>
---
 drivers/usb/host/xhci-pci.c | 38 +++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 9fb6d2f763..710524fbb1 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -10,9 +10,14 @@
 #include <init.h>
 #include <log.h>
 #include <pci.h>
+#include <reset.h>
 #include <usb.h>
 #include <usb/xhci.h>
 
+struct xhci_pci_platdata {
+       struct reset_ctl reset;
+};
+
 static void xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr,
                          struct xhci_hcor **ret_hcor)
 {
@@ -39,14 +44,43 @@ static void xhci_pci_init(struct udevice *dev, struct 
xhci_hccr **ret_hccr,
 
 static int xhci_pci_probe(struct udevice *dev)
 {
+       struct xhci_pci_platdata *plat = dev_get_platdata(dev);
        struct xhci_hccr *hccr;
        struct xhci_hcor *hcor;
+       int ret;
+
+       ret = reset_get_by_index(dev, 0, &plat->reset);
+       if (ret && ret != -ENOENT) {
+               dev_err(dev, "failed to get reset\n");
+               return ret;
+       }
+
+       if (reset_valid(&plat->reset)) {
+               ret = reset_assert(&plat->reset);
+               if (ret)
+                       return ret;
+
+               ret = reset_deassert(&plat->reset);
+               if (ret)
+                       return ret;
+       }
 
        xhci_pci_init(dev, &hccr, &hcor);
 
        return xhci_register(dev, hccr, hcor);
 }
 
+static int xhci_pci_remove(struct udevice *dev)
+{
+       struct xhci_pci_platdata *plat = dev_get_platdata(dev);
+
+       xhci_deregister(dev);
+       if (reset_valid(&plat->reset))
+               reset_free(&plat->reset);
+
+       return 0;
+}
+
 static const struct udevice_id xhci_pci_ids[] = {
        { .compatible = "xhci-pci" },
        { }
@@ -56,10 +90,10 @@ U_BOOT_DRIVER(xhci_pci) = {
        .name   = "xhci_pci",
        .id     = UCLASS_USB,
        .probe = xhci_pci_probe,
-       .remove = xhci_deregister,
+       .remove = xhci_pci_remove,
        .of_match = xhci_pci_ids,
        .ops    = &xhci_usb_ops,
-       .platdata_auto_alloc_size = sizeof(struct usb_platdata),
+       .platdata_auto_alloc_size = sizeof(struct xhci_pci_platdata),
        .priv_auto_alloc_size = sizeof(struct xhci_ctrl),
        .flags  = DM_FLAG_ALLOC_PRIV_DMA,
 };
-- 
2.26.2

Reply via email to