コード例 #1
0
ファイル: dwc2_coreintr.c プロジェクト: yazshel/netbsd-kernel
/*
 * This interrupt indicates that the DWC_otg controller has detected a
 * resume or remote wakeup sequence. If the DWC_otg controller is in
 * low power mode, the handler must brings the controller out of low
 * power mode. The controller automatically begins resume signaling.
 * The handler schedules a time to stop resume signaling.
 */
static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
{
    int ret;
    dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n");
    dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);

    if (dwc2_is_device_mode(hsotg)) {
        dev_dbg(hsotg->dev, "DSTS=0x%0x\n", DWC2_READ_4(hsotg, DSTS));
        if (hsotg->lx_state == DWC2_L2) {
            u32 dctl = DWC2_READ_4(hsotg, DCTL);

            /* Clear Remote Wakeup Signaling */
            dctl &= ~DCTL_RMTWKUPSIG;
            DWC2_WRITE_4(hsotg, DCTL, dctl);
            ret = dwc2_exit_hibernation(hsotg, true);
            if (ret && (ret != -ENOTSUPP))
                dev_err(hsotg->dev, "exit hibernation failed\n");

            call_gadget(hsotg, resume);
        }
        /* Change to L0 state */
        hsotg->lx_state = DWC2_L0;
    } else {
        if (hsotg->lx_state != DWC2_L1) {
            u32 pcgcctl = DWC2_READ_4(hsotg, PCGCTL);

            /* Restart the Phy Clock */
            pcgcctl &= ~PCGCTL_STOPPCLK;
            DWC2_WRITE_4(hsotg, PCGCTL, pcgcctl);
            callout_reset(&hsotg->wkp_timer, mstohz(71),
                          dwc2_wakeup_detected, hsotg);
        } else {
            /* Change to L0 state */
            hsotg->lx_state = DWC2_L0;
        }
    }

    /* Clear interrupt */
    DWC2_WRITE_4(hsotg, GINTSTS, GINTSTS_WKUPINT);
}
コード例 #2
0
ファイル: core_intr.c プロジェクト: DenisLug/mptcp
/*
 * This interrupt indicates that the DWC_otg controller has detected a
 * resume or remote wakeup sequence. If the DWC_otg controller is in
 * low power mode, the handler must brings the controller out of low
 * power mode. The controller automatically begins resume signaling.
 * The handler schedules a time to stop resume signaling.
 */
static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
{
	int ret;
	dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n");
	dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);

	if (dwc2_is_device_mode(hsotg)) {
		dev_dbg(hsotg->dev, "DSTS=0x%0x\n", readl(hsotg->regs + DSTS));
		if (hsotg->lx_state == DWC2_L2) {
			u32 dctl = readl(hsotg->regs + DCTL);

			/* Clear Remote Wakeup Signaling */
			dctl &= ~DCTL_RMTWKUPSIG;
			writel(dctl, hsotg->regs + DCTL);
			ret = dwc2_exit_hibernation(hsotg, true);
			if (ret && (ret != -ENOTSUPP))
				dev_err(hsotg->dev, "exit hibernation failed\n");

			call_gadget(hsotg, resume);
		}
		/* Change to L0 state */
		hsotg->lx_state = DWC2_L0;
	} else {
		if (hsotg->lx_state != DWC2_L1) {
			u32 pcgcctl = readl(hsotg->regs + PCGCTL);

			/* Restart the Phy Clock */
			pcgcctl &= ~PCGCTL_STOPPCLK;
			writel(pcgcctl, hsotg->regs + PCGCTL);
			mod_timer(&hsotg->wkp_timer,
				  jiffies + msecs_to_jiffies(71));
		} else {
			/* Change to L0 state */
			hsotg->lx_state = DWC2_L0;
		}
	}

	/* Clear interrupt */
	writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS);
}