xhci_free_virt_devices(ctrl);
free(ctrl->erst.entries);
free(ctrl->dcbaa);
+ if (reset_valid(&ctrl->reset))
+ reset_free(&ctrl->reset);
memset(ctrl, '\0', sizeof(struct xhci_ctrl));
}
return ret;
}
+#if CONFIG_IS_ENABLED(DM_USB)
+/**
+ * Resets XHCI Hardware
+ *
+ * @param ctrl pointer to host controller
+ * @return 0 if OK, or a negative error code.
+ */
+static int xhci_reset_hw(struct xhci_ctrl *ctrl)
+{
+ int ret;
+
+ ret = reset_get_by_index(ctrl->dev, 0, &ctrl->reset);
+ if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
+ dev_err(ctrl->dev, "failed to get reset\n");
+ return ret;
+ }
+
+ if (reset_valid(&ctrl->reset)) {
+ ret = reset_assert(&ctrl->reset);
+ if (ret)
+ return ret;
+
+ ret = reset_deassert(&ctrl->reset);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
/**
* Resets the XHCI Controller
*
ctrl->dev = dev;
+ ret = xhci_reset_hw(ctrl);
+ if (ret)
+ goto err;
+
/*
* XHCI needs to issue a Address device command to setup
* proper device context structures, before it can interact
#ifndef HOST_XHCI_H_
#define HOST_XHCI_H_
+#include <reset.h>
#include <asm/types.h>
#include <asm/cache.h>
#include <asm/io.h>
#if CONFIG_IS_ENABLED(DM_USB)
struct udevice *dev;
#endif
+ struct reset_ctl reset;
struct xhci_hccr *hccr; /* R/O registers, not need for volatile */
struct xhci_hcor *hcor;
struct xhci_doorbell_array *dba;