Re: [PATCH v2 2/2] usb: xhci: add Broadcom specific fake doorbell

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux