/** * dwc3_otg_interrupt - interrupt handler for dwc3 otg events. * * @irq: irq number. * @_dotg: Pointer to dwc3 otg context structure. */ static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg) { struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg; struct otg_fsm *fsm = &dotg->fsm; u32 oevt, handled_events = 0; irqreturn_t ret = IRQ_NONE; oevt = dwc3_readl(dotg->regs, DWC3_OEVT); /* ID */ if (oevt & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) { fsm->id = dwc3_otg_get_id_state(dotg); handled_events |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT; } /* VBus */ if (oevt & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) { fsm->b_sess_vld = dwc3_otg_get_b_sess_state(dotg); handled_events |= DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT; } if (handled_events) { dwc3_writel(dotg->regs, DWC3_OEVT, handled_events); ret = IRQ_WAKE_THREAD; } return ret; }
/** * dwc3_otg_start * @dwc: pointer to our controller context structure */ int dwc3_otg_start(struct dwc3 *dwc) { struct dwc3_otg *dotg = dwc->dotg; struct otg_fsm *fsm = &dotg->fsm; int ret; if (dotg->ext_otg_ops) { ret = dwc3_ext_otg_start(dotg); if (ret) { dev_err(dwc->dev, "failed to start external OTG\n"); return ret; } } else { dotg->regs = dwc->regs; dwc3_otg_reset(dotg); dotg->fsm.id = dwc3_otg_get_id_state(dotg); dotg->fsm.b_sess_vld = dwc3_otg_get_b_sess_state(dotg); dotg->irq = platform_get_irq(to_platform_device(dwc->dev), 0); ret = devm_request_threaded_irq(dwc->dev, dotg->irq, dwc3_otg_interrupt, dwc3_otg_thread_interrupt, IRQF_SHARED, "dwc3-otg", dotg); if (ret) { dev_err(dwc->dev, "failed to request irq #%d --> %d\n", dotg->irq, ret); return ret; } dwc3_otg_enable_irq(dotg); } dotg->ready = 1; dwc3_otg_run_sm(fsm); return 0; }