Skip to content

Commit c7c24e7

Browse files
Artur PetrosyanFelipe Balbi
authored andcommitted
usb: dwc2: Change reading of current frame number flow.
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 <[email protected]> Signed-off-by: Felipe Balbi <[email protected]>
1 parent 971b750 commit c7c24e7

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

drivers/usb/dwc2/core.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,9 @@ struct dwc2_hregs_backup {
824824
* @gadget_enabled Peripheral mode sub-driver initialization indicator.
825825
* @ll_hw_enabled Status of low-level hardware resources.
826826
* @hibernated: True if core is hibernated
827+
* @frame_number: Frame number read from the core. For both device
828+
* and host modes. The value ranges are from 0
829+
* to HFNUM_MAX_FRNUM.
827830
* @phy: The otg phy transceiver structure for phy control.
828831
* @uphy: The otg phy transceiver structure for old USB phy
829832
* control.
@@ -897,8 +900,6 @@ struct dwc2_hregs_backup {
897900
* @hs_periodic_bitmap: Bitmap used by the microframe scheduler any time the
898901
* host is in high speed mode; low speed schedules are
899902
* stored elsewhere since we need one per TT.
900-
* @frame_number: Frame number read from the core at SOF. The value ranges
901-
* from 0 to HFNUM_MAX_FRNUM.
902903
* @periodic_qh_count: Count of periodic QHs, if using several eps. Used for
903904
* SOF enable/disable.
904905
* @free_hc_list: Free host channels in the controller. This is a list of
@@ -965,6 +966,7 @@ struct dwc2_hsotg {
965966
unsigned int gadget_enabled:1;
966967
unsigned int ll_hw_enabled:1;
967968
unsigned int hibernated:1;
969+
u16 frame_number;
968970

969971
struct phy *phy;
970972
struct usb_phy *uphy;
@@ -1038,7 +1040,6 @@ struct dwc2_hsotg {
10381040
u16 periodic_usecs;
10391041
unsigned long hs_periodic_bitmap[
10401042
DIV_ROUND_UP(DWC2_HS_SCHEDULE_US, BITS_PER_LONG)];
1041-
u16 frame_number;
10421043
u16 periodic_qh_count;
10431044
bool bus_suspended;
10441045
bool new_connection;

drivers/usb/dwc2/core_intr.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,14 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev)
778778
goto out;
779779
}
780780

781+
/* Reading current frame number value in device or host modes. */
782+
if (dwc2_is_device_mode(hsotg))
783+
hsotg->frame_number = (dwc2_readl(hsotg->regs + DSTS)
784+
& DSTS_SOFFN_MASK) >> DSTS_SOFFN_SHIFT;
785+
else
786+
hsotg->frame_number = (dwc2_readl(hsotg->regs + HFNUM)
787+
& HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
788+
781789
gintsts = dwc2_read_common_intr(hsotg);
782790
if (gintsts & ~GINTSTS_PRTINT)
783791
retval = IRQ_HANDLED;

drivers/usb/dwc2/gadget.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ static bool dwc2_gadget_target_frame_elapsed(struct dwc2_hsotg_ep *hs_ep)
12251225
{
12261226
struct dwc2_hsotg *hsotg = hs_ep->parent;
12271227
u32 target_frame = hs_ep->target_frame;
1228-
u32 current_frame = dwc2_hsotg_read_frameno(hsotg);
1228+
u32 current_frame = hsotg->frame_number;
12291229
bool frame_overrun = hs_ep->frame_overrun;
12301230

12311231
if (!frame_overrun && current_frame >= target_frame)
@@ -1359,8 +1359,15 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
13591359
return 0;
13601360
}
13611361

1362-
while (dwc2_gadget_target_frame_elapsed(hs_ep))
1362+
/* Update current frame number value. */
1363+
hs->frame_number = dwc2_hsotg_read_frameno(hs);
1364+
while (dwc2_gadget_target_frame_elapsed(hs_ep)) {
13631365
dwc2_gadget_incr_frame_num(hs_ep);
1366+
/* Update current frame number value once more as it
1367+
* changes here.
1368+
*/
1369+
hs->frame_number = dwc2_hsotg_read_frameno(hs);
1370+
}
13641371

13651372
if (hs_ep->target_frame != TARGET_FRAME_INITIAL)
13661373
dwc2_hsotg_start_req(hs, hs_ep, hs_req, false);
@@ -2707,6 +2714,8 @@ static void dwc2_gadget_handle_ep_disabled(struct dwc2_hsotg_ep *hs_ep)
27072714
dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req,
27082715
-ENODATA);
27092716
dwc2_gadget_incr_frame_num(hs_ep);
2717+
/* Update current frame number value. */
2718+
hsotg->frame_number = dwc2_hsotg_read_frameno(hsotg);
27102719
} while (dwc2_gadget_target_frame_elapsed(hs_ep));
27112720

27122721
dwc2_gadget_start_next_request(hs_ep);

0 commit comments

Comments
 (0)