Merge "usb: dwc3: Add support to LPM L1 remote wakeup for ep0 endpoints"
This commit is contained in:
commit
50c69dd9ec
5 changed files with 28 additions and 8 deletions
|
@ -1021,6 +1021,8 @@ struct dwc3 {
|
||||||
unsigned irq_event_count[MAX_INTR_STATS];
|
unsigned irq_event_count[MAX_INTR_STATS];
|
||||||
unsigned irq_dbg_index;
|
unsigned irq_dbg_index;
|
||||||
|
|
||||||
|
unsigned long l1_remote_wakeup_cnt;
|
||||||
|
|
||||||
wait_queue_head_t wait_linkstate;
|
wait_queue_head_t wait_linkstate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1180,9 +1180,12 @@ static int dwc3_gadget_int_events_show(struct seq_file *s, void *unused)
|
||||||
seq_printf(s, "%d\t", dwc->bh_completion_time[i]);
|
seq_printf(s, "%d\t", dwc->bh_completion_time[i]);
|
||||||
seq_putc(s, '\n');
|
seq_putc(s, '\n');
|
||||||
|
|
||||||
seq_printf(s, "t_pwr evt irq : %lld\t",
|
seq_printf(s, "t_pwr evt irq : %lld\n",
|
||||||
ktime_to_us(dwc->t_pwr_evt_irq));
|
ktime_to_us(dwc->t_pwr_evt_irq));
|
||||||
|
|
||||||
|
seq_printf(s, "l1_remote_wakeup_cnt : %lu\n",
|
||||||
|
dwc->l1_remote_wakeup_cnt);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,8 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
enum dwc3_link_state link_state;
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
spin_lock_irqsave(&dwc->lock, flags);
|
spin_lock_irqsave(&dwc->lock, flags);
|
||||||
if (!dep->endpoint.desc) {
|
if (!dep->endpoint.desc) {
|
||||||
|
@ -252,6 +254,18 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if link stats is in L1 initiate remote wakeup before queuing req */
|
||||||
|
if (dwc->speed != DWC3_DSTS_SUPERSPEED) {
|
||||||
|
link_state = dwc3_get_link_state(dwc);
|
||||||
|
/* in HS this link state is same as L1 */
|
||||||
|
if (link_state == DWC3_LINK_STATE_U2) {
|
||||||
|
dwc->l1_remote_wakeup_cnt++;
|
||||||
|
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||||
|
reg |= DWC3_DCTL_ULSTCHNG_RECOVERY;
|
||||||
|
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dwc3_trace(trace_dwc3_ep0,
|
dwc3_trace(trace_dwc3_ep0,
|
||||||
"queueing request %pK to %s length %d state '%s'",
|
"queueing request %pK to %s length %d state '%s'",
|
||||||
request, dep->name, request->length,
|
request, dep->name, request->length,
|
||||||
|
|
|
@ -1317,13 +1317,6 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline enum dwc3_link_state dwc3_get_link_state(struct dwc3 *dwc)
|
|
||||||
{
|
|
||||||
u32 reg;
|
|
||||||
reg = dwc3_readl(dwc->regs, DWC3_DSTS);
|
|
||||||
return DWC3_DSTS_USBLNKST(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool dwc3_gadget_is_suspended(struct dwc3 *dwc)
|
static bool dwc3_gadget_is_suspended(struct dwc3 *dwc)
|
||||||
{
|
{
|
||||||
if (atomic_read(&dwc->in_lpm) ||
|
if (atomic_read(&dwc->in_lpm) ||
|
||||||
|
|
|
@ -84,6 +84,14 @@ static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req)
|
||||||
list_move_tail(&req->list, &dep->req_queued);
|
list_move_tail(&req->list, &dep->req_queued);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline enum dwc3_link_state dwc3_get_link_state(struct dwc3 *dwc)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
reg = dwc3_readl(dwc->regs, DWC3_DSTS);
|
||||||
|
return DWC3_DSTS_USBLNKST(reg);
|
||||||
|
}
|
||||||
|
|
||||||
void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
||||||
int status);
|
int status);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue