static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_regs __iomem *hw = ehci->regs; struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); u32 val; #ifndef CONFIG_ARCH_TEGRA_2x_SOC /* Fence read for coherency of AHB master intiated writes */ if (tegra->phy->instance == 0) readb(IO_ADDRESS(IO_PPCS_PHYS + USB1_PREFETCH_ID)); else if (tegra->phy->instance == 1) readb(IO_ADDRESS(IO_PPCS_PHYS + USB2_PREFETCH_ID)); else if (tegra->phy->instance == 2) readb(IO_ADDRESS(IO_PPCS_PHYS + USB3_PREFETCH_ID)); #endif if ((tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) && (tegra->ehci->has_hostpc)) { /* check if there is any remote wake event */ if (tegra_usb_phy_is_remotewake_detected(tegra->phy)) { usb_hcd_resume_root_hub(hcd); } } if (tegra->phy->hotplug) { spin_lock(&ehci->lock); val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET); if ((val & TEGRA_USB_PHY_CLK_VALID_INT_STS)) { val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB | TEGRA_USB_PHY_CLK_VALID_INT_STS; writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET)); val = readl(&hw->status); if (!(val & STS_PCD)) { spin_unlock(&ehci->lock); return 0; } val = readl(hcd->regs + TEGRA_USB_PORTSC1_OFFSET); val &= ~(TEGRA_USB_PORTSC1_WKCN | PORT_RWC_BITS); writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET)); } spin_unlock(&ehci->lock); } return ehci_irq(hcd); }
static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_regs __iomem *hw = ehci->regs; struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); u32 val; if ((tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) && (tegra->ehci->has_hostpc)) { /* check if there is any remote wake event */ if (tegra_usb_phy_is_remotewake_detected(tegra->phy)) { spin_lock (&ehci->lock); usb_hcd_resume_root_hub(hcd); spin_unlock (&ehci->lock); } } if (tegra->hotplug) { spin_lock(&ehci->lock); val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET); if ((val & TEGRA_USB_PHY_CLK_VALID_INT_STS)) { val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB | TEGRA_USB_PHY_CLK_VALID_INT_STS; writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET)); val = readl(hcd->regs + TEGRA_USB_PORTSC1_OFFSET); val &= ~TEGRA_USB_PORTSC1_WKCN; writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET)); val = readl(&hw->status); if (!(val & STS_PCD)) { spin_unlock(&ehci->lock); return 0; } } spin_unlock(&ehci->lock); } return ehci_irq(hcd); }
static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_regs __iomem *hw = ehci->regs; struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); u32 val; irqreturn_t irq_status; bool pmc_remote_wakeup = false; /* Fence read for coherency of AHB master intiated writes */ if (tegra->phy->instance == 0) readb(IO_ADDRESS(IO_PPCS_PHYS + USB1_PREFETCH_ID)); else if (tegra->phy->instance == 1) readb(IO_ADDRESS(IO_PPCS_PHYS + USB2_PREFETCH_ID)); else if (tegra->phy->instance == 2) readb(IO_ADDRESS(IO_PPCS_PHYS + USB3_PREFETCH_ID)); if ((tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) && (tegra->ehci->has_hostpc)) { /* check if there is any remote wake event */ if (tegra_usb_phy_is_remotewake_detected(tegra->phy)) { pmc_remote_wakeup = true; spin_lock (&ehci->lock); usb_hcd_resume_root_hub(hcd); spin_unlock (&ehci->lock); } } if (tegra->phy->hotplug) { spin_lock(&ehci->lock); val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET); if ((val & TEGRA_USB_PHY_CLK_VALID_INT_STS)) { val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB | TEGRA_USB_PHY_CLK_VALID_INT_STS; writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET)); val = readl(&hw->status); if (!(val & STS_PCD)) { spin_unlock(&ehci->lock); return 0; } val = readl(hcd->regs + TEGRA_USB_PORTSC1_OFFSET); val &= ~(TEGRA_USB_PORTSC1_WKCN | PORT_RWC_BITS); writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET)); } spin_unlock(&ehci->lock); } irq_status = ehci_irq(hcd); if (pmc_remote_wakeup) { ehci->controller_remote_wakeup = false; } if (ehci->controller_remote_wakeup) { ehci->controller_remote_wakeup = false; /* disable interrupts */ ehci_writel(ehci, 0, &ehci->regs->intr_enable); tegra_usb_phy_preresume(tegra->phy, true); tegra->port_resuming = 1; } return irq_status; }