[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200612164632.25648-6-nsaenzjulienne@suse.de>
Date: Fri, 12 Jun 2020 18:46:33 +0200
From: Nicolas Saenz Julienne <nsaenzjulienne@...e.de>
To: mbrugger@...e.com, u-boot@...ts.denx.de, bmeng.cn@...il.com,
marex@...x.de, linux-kernel@...r.kernel.org
Cc: sjg@...omium.org, m.szyprowski@...sung.com, s.nawrocki@...sung.com,
mark.kettenis@...all.nl,
Nicolas Saenz Julienne <nsaenzjulienne@...e.de>
Subject: [PATCH v4 5/5] usb: xhci-pci: Add reset controller support
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 <nsaenzjulienne@...e.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
Powered by blists - more mailing lists