Re: [PATCH] usb: dwc2: Change reading of current frame number flow.

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

 



On 5/5/2018 5:46 PM, Artur Petrosyan wrote:
> The current frame_number is read from core for both
> device and host modes. Reading of the current frame
> number needs to be performed ASAP due to IRQ latency's.
> This is why, it is moved to common interrupt handler.
> 
> Accordingly updated dwc2_gadget_target_frame_elapsed()
> function which uses stored frame_number instead of
> reading frame number.
> 
> In cases when target frame value is incremented
> the frame_number is required to read again.
> 
> Signed-off-by: Artur Petrosyan <arturp@xxxxxxxxxxxx>
> ---

Acked-by: Minas Harutyunyan <hminas@xxxxxxxxxxxx>

>   drivers/usb/dwc2/core.h      |  7 ++++---
>   drivers/usb/dwc2/core_intr.c |  8 ++++++++
>   drivers/usb/dwc2/gadget.c    | 13 +++++++++++--
>   3 files changed, 23 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
> index d83be5651f87..a435db4fe948 100644
> --- a/drivers/usb/dwc2/core.h
> +++ b/drivers/usb/dwc2/core.h
> @@ -813,6 +813,9 @@ struct dwc2_hregs_backup {
>    * @gadget_enabled	Peripheral mode sub-driver initialization indicator.
>    * @ll_hw_enabled	Status of low-level hardware resources.
>    * @hibernated:		True if core is hibernated
> + * @frame_number:       Frame number read from the core. For both device
> + *			and host modes. The value ranges are from 0
> + *			to HFNUM_MAX_FRNUM.
>    * @phy:                The otg phy transceiver structure for phy control.
>    * @uphy:               The otg phy transceiver structure for old USB phy
>    *                      control.
> @@ -886,8 +889,6 @@ struct dwc2_hregs_backup {
>    * @hs_periodic_bitmap: Bitmap used by the microframe scheduler any time the
>    *                      host is in high speed mode; low speed schedules are
>    *                      stored elsewhere since we need one per TT.
> - * @frame_number:       Frame number read from the core at SOF. The value ranges
> - *                      from 0 to HFNUM_MAX_FRNUM.
>    * @periodic_qh_count:  Count of periodic QHs, if using several eps. Used for
>    *                      SOF enable/disable.
>    * @free_hc_list:       Free host channels in the controller. This is a list of
> @@ -954,6 +955,7 @@ struct dwc2_hsotg {
>   	unsigned int gadget_enabled:1;
>   	unsigned int ll_hw_enabled:1;
>   	unsigned int hibernated:1;
> +	u16 frame_number;
>   
>   	struct phy *phy;
>   	struct usb_phy *uphy;
> @@ -1027,7 +1029,6 @@ struct dwc2_hsotg {
>   	u16 periodic_usecs;
>   	unsigned long hs_periodic_bitmap[
>   		DIV_ROUND_UP(DWC2_HS_SCHEDULE_US, BITS_PER_LONG)];
> -	u16 frame_number;
>   	u16 periodic_qh_count;
>   	bool bus_suspended;
>   	bool new_connection;
> diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
> index 2982a155734d..cc90b58b6b3c 100644
> --- a/drivers/usb/dwc2/core_intr.c
> +++ b/drivers/usb/dwc2/core_intr.c
> @@ -778,6 +778,14 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev)
>   		goto out;
>   	}
>   
> +	/* Reading current frame number value in device or host modes. */
> +	if (dwc2_is_device_mode(hsotg))
> +		hsotg->frame_number = (dwc2_readl(hsotg->regs + DSTS)
> +				       & DSTS_SOFFN_MASK) >> DSTS_SOFFN_SHIFT;
> +	else
> +		hsotg->frame_number = (dwc2_readl(hsotg->regs + HFNUM)
> +				       & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
> +
>   	gintsts = dwc2_read_common_intr(hsotg);
>   	if (gintsts & ~GINTSTS_PRTINT)
>   		retval = IRQ_HANDLED;
> diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
> index 6c32bf26e48e..f7343cda3234 100644
> --- a/drivers/usb/dwc2/gadget.c
> +++ b/drivers/usb/dwc2/gadget.c
> @@ -1235,7 +1235,7 @@ static bool dwc2_gadget_target_frame_elapsed(struct dwc2_hsotg_ep *hs_ep)
>   {
>   	struct dwc2_hsotg *hsotg = hs_ep->parent;
>   	u32 target_frame = hs_ep->target_frame;
> -	u32 current_frame = dwc2_hsotg_read_frameno(hsotg);
> +	u32 current_frame = hsotg->frame_number;
>   	bool frame_overrun = hs_ep->frame_overrun;
>   
>   	if (!frame_overrun && current_frame >= target_frame)
> @@ -1350,8 +1350,15 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
>   			return 0;
>   		}
>   
> -		while (dwc2_gadget_target_frame_elapsed(hs_ep))
> +		/* Update current frame number value. */
> +		hs->frame_number = dwc2_hsotg_read_frameno(hs);
> +		while (dwc2_gadget_target_frame_elapsed(hs_ep)) {
>   			dwc2_gadget_incr_frame_num(hs_ep);
> +			/* Update current frame number value once more as it
> +			 * changes here.
> +			 */
> +			hs->frame_number = dwc2_hsotg_read_frameno(hs);
> +		}
>   
>   		if (hs_ep->target_frame != TARGET_FRAME_INITIAL)
>   			dwc2_hsotg_start_req(hs, hs_ep, hs_req, false);
> @@ -2731,6 +2738,8 @@ static void dwc2_gadget_handle_ep_disabled(struct dwc2_hsotg_ep *hs_ep)
>   			dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req,
>   						    -ENODATA);
>   		dwc2_gadget_incr_frame_num(hs_ep);
> +		/* Update current frame number value. */
> +		hsotg->frame_number = dwc2_hsotg_read_frameno(hsotg);
>   	} while (dwc2_gadget_target_frame_elapsed(hs_ep));
>   
>   	dwc2_gadget_start_next_request(hs_ep);
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




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

  Powered by Linux