Hi, Hauke Mehrtens <hauke@xxxxxxxxxx> writes: > From: Rafał Miłecki <zajec5@xxxxxxxxx> > > This fixes problem with controller seeing devices only in some small > percentage of cold boots. > This quirk is also added to the platform data so we can activate it > when we register our platform driver. it would've been nicer if you could add an erratum ID number for future reference together with a more verbose discussion of the problem. You're not describing what the problem is and that's important. > Signed-off-by: Rafał Miłecki <zajec5@xxxxxxxxx> > Signed-off-by: Hauke Mehrtens <hauke@xxxxxxxxxx> > --- > drivers/usb/host/xhci-plat.c | 3 +++ > drivers/usb/host/xhci.c | 57 +++++++++++++++++++++++++++++++++++++--- > drivers/usb/host/xhci.h | 1 + > include/linux/usb/xhci_pdriver.h | 1 + > 4 files changed, 59 insertions(+), 3 deletions(-) > > diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c > index 4fb295b..7cd274b 100644 > --- a/drivers/usb/host/xhci-plat.c > +++ b/drivers/usb/host/xhci-plat.c > @@ -53,6 +53,9 @@ static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) > if ((node && of_property_read_bool(node, "usb3-lpm-capable")) || > (pdata && pdata->usb3_lpm_capable)) > xhci->quirks |= XHCI_LPM_SUPPORT; > + > + if (pdata && pdata->usb3_fake_doorbell) > + xhci->quirks |= XHCI_FAKE_DOORBELL; whenever you add something via pdata, you _must_ make a similar DT change. > diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c > index 643d312..d49be9b 100644 > --- a/drivers/usb/host/xhci.c > +++ b/drivers/usb/host/xhci.c > @@ -122,6 +122,39 @@ int xhci_halt(struct xhci_hcd *xhci) > return ret; > } > > +static int xhci_fake_doorbell(struct xhci_hcd *xhci, int slot_id) > +{ > + u32 temp; > + > + /* alloc a virt device for slot */ > + if (!xhci_alloc_virt_device(xhci, slot_id, NULL, GFP_NOIO)) { > + xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); > + return -ENOMEM; > + } > + > + /* ring fake doorbell for slot_id ep 0 */ > + xhci_ring_ep_doorbell(xhci, slot_id, 0, 0); > + usleep_range(1000, 1500); > + > + /* read the status register to check if HSE is set or not? */ > + temp = readl(&xhci->op_regs->status); > + > + /* clear HSE if set */ > + if (temp & STS_FATAL) { > + xhci_dbg(xhci, "HSE problem detected, status: 0x%x\n", temp); > + temp &= ~(0x1fff); > + temp |= STS_FATAL; > + writel(temp, &xhci->op_regs->status); > + usleep_range(1000, 1500); > + readl(&xhci->op_regs->status); > + } > + > + /* Free virt device */ > + xhci_free_virt_device(xhci, slot_id); > + > + return 0; > +} > + > /* > * Set the run bit and wait for the host to be running. > */ > @@ -568,10 +601,25 @@ int xhci_init(struct usb_hcd *hcd) > > static int xhci_run_finished(struct xhci_hcd *xhci) > { > - if (xhci_start(xhci)) { > - xhci_halt(xhci); > - return -ENODEV; > + int err; > + > + err = xhci_start(xhci); > + if (err) { > + err = -ENODEV; > + goto out_err; > + } add a blank line here > + if (xhci->quirks & XHCI_FAKE_DOORBELL) { > + err = xhci_fake_doorbell(xhci, 1); > + if (err) > + goto out_err; > + > + err = xhci_start(xhci); > + if (err) { > + err = -ENODEV; > + goto out_err; > + } > } > + > xhci->shared_hcd->state = HC_STATE_RUNNING; > xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; > > @@ -581,6 +629,9 @@ static int xhci_run_finished(struct xhci_hcd *xhci) > xhci_dbg_trace(xhci, trace_xhci_dbg_init, > "Finished xhci_run for USB3 roothub"); > return 0; and another one here. > +out_err: > + xhci_halt(xhci); > + return err; > } > > /* > diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h > index 9be7348..8c1faf4 100644 > --- a/drivers/usb/host/xhci.h > +++ b/drivers/usb/host/xhci.h > @@ -1631,6 +1631,7 @@ struct xhci_hcd { > #define XHCI_BROKEN_STREAMS (1 << 19) > #define XHCI_PME_STUCK_QUIRK (1 << 20) > #define XHCI_MTK_HOST (1 << 21) > +#define XHCI_FAKE_DOORBELL (1 << 22) > unsigned int num_active_eps; > unsigned int limit_active_eps; > /* There are two roothubs to keep track of bus suspend info for */ > diff --git a/include/linux/usb/xhci_pdriver.h b/include/linux/usb/xhci_pdriver.h > index 376654b..2b4ea5b 100644 > --- a/include/linux/usb/xhci_pdriver.h > +++ b/include/linux/usb/xhci_pdriver.h > @@ -22,6 +22,7 @@ > */ > struct usb_xhci_pdata { > unsigned usb3_lpm_capable:1; > + unsigned usb3_fake_doorbell:1; missing kernel doc for this new quirk. -- balbi
Attachment:
signature.asc
Description: PGP signature