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