/* called during probe() after chip reset completes */ static int ehci_hlwd_reset(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); void __iomem *ehci_ctl; int error; dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); error = ehci_halt(ehci); if (error) goto out; error = ehci_init(hcd); if (error) goto out; ehci_ctl = ioremap(HLWD_EHCI_CTL, 4); if (!ehci_ctl) { printk(KERN_ERR __FILE__ ": ioremap failed\n"); error = -EBUSY; goto out; } /* enable notification of EHCI interrupts */ out_be32(ehci_ctl, in_be32(ehci_ctl) | HLWD_EHCI_CTL_INTE); iounmap(ehci_ctl); ehci->sbrn = 0x20; error = ehci_reset(ehci); ehci_port_power(ehci, 0); out: return error; }
static int ehci_atmel_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval = 0; ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); retval = ehci_halt(ehci); if (retval) return retval; retval = ehci_init(hcd); if (retval) return retval; ehci->sbrn = 0x20; ehci_reset(ehci); ehci_port_power(ehci, 0); return retval; }
static int ehci_xls_setup(struct usb_hcd *hcd) { int retval; struct ehci_hcd *ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); retval = ehci_halt(ehci); if (retval) return retval; retval = ehci_init(hcd); if (retval) return retval; ehci_reset(ehci); return retval; }
/* called during probe() after chip reset completes */ static int ehci_msp_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; ehci->big_endian_mmio = 1; ehci->big_endian_desc = 1; ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); hcd->has_tt = 1; retval = ehci_halt(ehci); if (retval) return retval; ehci_reset(ehci); /* data structure init */ retval = ehci_init(hcd); if (retval) return retval; usb_hcd_tdi_set_mode(ehci); ehci_port_power(ehci, 0); return retval; }
static int ps3_ehci_hc_reset(struct usb_hcd *hcd) { int result; struct ehci_hcd *ehci = hcd_to_ehci(hcd); ehci->big_endian_mmio = 1; ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); result = ehci_halt(ehci); if (result) return result; result = ehci_init(hcd); if (result) return result; ehci_reset(ehci); return result; }
static int ehci_sh_reset(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int ret; ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); ret = ehci_halt(ehci); if (unlikely(ret)) return ret; ret = ehci_init(hcd); if (unlikely(ret)) return ret; ehci->sbrn = 0x20; ehci_reset(ehci); ehci_port_power(ehci, 0); return ret; }
/* called during probe() after chip reset completes */ static int ehci_mxc_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); hcd->has_tt = 1; retval = ehci_halt(ehci); if (retval) return retval; /* data structure init */ retval = ehci_init(hcd); if (retval) return retval; ehci->sbrn = 0x20; ehci_reset(ehci); ehci_port_power(ehci, 0); return 0; }
/* called during probe() after chip reset completes */ static int ehci_msm7201_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; ehci->caps = USB_CAPLENGTH; ehci->regs = USB_CAPLENGTH + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); /* configure other settings */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); hcd->has_tt = 1; ehci->sbrn = HCD_USB2; /* reset and halt controller */ ehci_reset(ehci); retval = ehci_halt(ehci); if (retval) return retval; /* data structure init */ retval = ehci_init(hcd); if (retval) return retval; ehci_reset(ehci); retval = ehci_msm7201_reinit(ehci); return retval; }
static int ehci_mxc_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); hcd->has_tt = 1; retval = ehci_halt(ehci); if (retval) return retval; retval = ehci_init(hcd); if (retval) return retval; ehci->sbrn = 0x20; ehci_reset(ehci); ehci_port_power(ehci, 0); return 0; }
static int s5pv210_ehci_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); usb_host_phy_power_init(pdev); if (s5pv210_hcd == NULL) { dev_info(dev, "Nothing to do for the device (power off)\n"); return 0; } ehci_info(ehci, "resume\n"); pm_runtime_resume(&pdev->dev); s5pv210_start_ehc(); #if defined(CONFIG_ARCH_S5PV310) writel(0x03C00000, hcd->regs + 0x90); #endif if (time_before(jiffies, ehci->next_statechange)) msleep(10); /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } ehci_info(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); (void) ehci_halt(ehci); (void) ehci_reset(ehci); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); hcd->state = HC_STATE_SUSPENDED; return 0; }
static int ar9130_ehci_init(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int ret; ar9130_debug_fn("__enter %s\n",__FUNCTION__); /* EHCI Register offset 0x100 - Info from ChipIdea */ ehci->caps = hcd->regs + 0x100; /* Device/Host Capa Reg*/ ehci->regs = hcd->regs + 0x100 + /* Device/Host Oper Reg*/ HC_LENGTH(readl(&ehci->caps->hc_capbase)); /*Reading HC Structural Parameters */ ehci->hcs_params = readl(&ehci->caps->hcs_params); ar9130_debug_dev("HCS Params %x \n\n",ehci->hcs_params); ar9130_debug_dev("HCC Params %x \n",readl(&ehci->caps->hcc_params)); #if 0 ret = ehci_halt(ehci); if(ret){ return ret; } #endif ret = ehci_init(hcd); if(ret){ return ret; } ehci->is_tdi_rh_tt = 1; /*Informs USB Subsystem abt embedded TT */ ehci->sbrn = 0x20; ehci_reset(ehci); return ret; }
/* called during probe() after chip reset completes */ static int ehci_fsl_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); retval = ehci_halt(ehci); if (retval) return retval; /* data structure init */ retval = ehci_init(hcd); if (retval) return retval; hcd->has_tt = 1; ehci->sbrn = 0x20; ehci_reset(ehci); retval = ehci_fsl_reinit(ehci); return retval; }
/** * ehci_ppc_soc_hcd_init - init echi structure * Context: !in_interrupt() * * Init basic fields like regs for this USB host controller. * */ static int ehci_ppc_soc_hcd_init(struct ehci_hcd *ehci) { u32 temp; spin_lock_init(&ehci->lock); ehci->caps = ehci->hcd.regs; ehci->regs = ehci->hcd.regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "init"); dbg_hcc_params(ehci, "init"); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); ehci_reset(ehci); ehci_port_power(ehci, 0); temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); temp &= 0x0f; if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { ehci_dbg(ehci, "bogus port configuration: " "cc=%d x pcc=%d < ports=%d\n", HCS_N_CC(ehci->hcs_params), HCS_N_PCC(ehci->hcs_params), HCS_N_PORTS(ehci->hcs_params)); } /* force HC to halt state */ return ehci_halt(ehci); }
static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); #ifdef CONFIG_USB_OTG_UTILS struct tegra_hcd_platform_data *pdata; /* initialize the platform data pointer */ pdata = hcd->self.controller->platform_data; if (pdata->otg_mode && ehci->transceiver) { if (ehci->transceiver->state != OTG_STATE_A_HOST) { /* we are not in host mode, return */ return 0; } else { ehci->transceiver->state = OTG_STATE_UNDEFINED; ehci->host_reinited = 0; /* indicate hcd flags, that hardware is not accessable now */ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); } } #endif if (ehci->host_resumed) { /* halt the controller before powering down the phy */ ehci_halt(ehci); tegra_ehci_power_down(hcd); } return 0; }
static int ehci_brcm_resume(struct usb_hcd *hcd) { int ret = 0; brcm_usb_resume(hcd); if (brcm_pm_deep_sleep()) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); usb_root_hub_lost_power(hcd->self.root_hub); /* * SWLINUX-1705: Avoid OUT packet underflows during high memory * bus usage * port_status[0x0f] = Broadcom-proprietary USB_EHCI_INSNREG00 * @ 0x90 */ ehci_writel(ehci, 0x00800040, &ehci->regs->port_status[0x10]); ehci_writel(ehci, 0x00000001, &ehci->regs->port_status[0x12]); (void)ehci_halt(ehci); (void)ehci_reset(ehci); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); /* unblock posted writes */ ehci_readl(ehci, &ehci->regs->command); ehci_writel(ehci, 0, &ehci->regs->intr_enable); /* re-init operational registers */ ehci_writel(ehci, 0, &ehci->regs->segment); ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next); /* restore CMD_RUN, framelist size, and irq threshold */ ehci_writel(ehci, ehci->command, &ehci->regs->command); /* Some controller/firmware combinations need a delay during * which they set up the port statuses. See Bugzilla #8190. */ /* SWLINUX-1929 need extra delay here */ msleep(10); ehci->next_statechange = jiffies + msecs_to_jiffies(5); hcd->state = HC_STATE_RUNNING; /* Now we can safely re-enable irqs */ ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); return 0; } ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd)); ret = ehci_bus_resume(hcd); return ret; }
static int s5p_ehci_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); struct usb_hcd *hcd = s5p_ehci->hcd; struct ehci_hcd *ehci = hcd_to_ehci(hcd); clk_enable(s5p_ehci->clk); s5p_ehci_phy_init(pdev); if (time_before(jiffies, ehci->next_statechange)) msleep(10); /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } ehci_dbg(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); (void) ehci_halt(ehci); (void) ehci_reset(ehci); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); ehci->rh_state = EHCI_RH_SUSPENDED; /* Update runtime PM status and clear runtime_error */ pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); /* Prevent device from runtime suspend during resume time */ pm_runtime_get_sync(dev); return 0; }
int nusmart_ehci_resume(struct platform_device * pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); printk(KERN_DEBUG"%s\n", __func__); //nusmart_start_ehc(); if (time_before(jiffies, ehci->next_statechange)) msleep(100); /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); /* If CF is still set, we maintained PCI Vaux power. * Just undo the effect of ehci_pci_suspend(). */ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } printk(KERN_DEBUG "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); /* Else reset, to cope with power loss or flush-to-storage * style "resume" having let BIOS kick in during reboot. */ (void) ehci_halt(ehci); (void) ehci_reset(ehci); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ //ehci_port_power(ehci, 0); ehci_port_power(ehci, 1); //ehci_port_power(ehci, 2); //ehci_port_power(ehci, 3); hcd->state = HC_STATE_SUSPENDED; return 0; }
static int ehci_hcd_au1xxx_drv_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); alchemy_usb_control(ALCHEMY_USB_EHCI0, 1); // if (time_before(jiffies, ehci->next_statechange)) msleep(100); /* */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); /* */ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; ehci_prepare_ports_for_controller_resume(ehci); if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } ehci_dbg(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); /* */ (void) ehci_halt(ehci); (void) ehci_reset(ehci); /* */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* */ /* */ ehci_port_power(ehci, 1); ehci->rh_state = EHCI_RH_SUSPENDED; return 0; }
static int tegra_ehci_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); int retval; #ifndef CONFIG_ARCH_TEGRA_2x_SOC u32 val; #endif /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = readl(&ehci->caps->hcs_params); ehci->has_hostpc = tegra->has_hostpc; ehci->broken_hostpc_phcd = true; #ifndef CONFIG_ARCH_TEGRA_2x_SOC ehci->has_hostpc = 1; val = readl(hcd->regs + HOSTPC_REG_OFFSET); val &= ~HOSTPC1_DEVLC_STS; val &= ~HOSTPC1_DEVLC_NYT_ASUS; writel(val, hcd->regs + HOSTPC_REG_OFFSET); #endif hcd->has_tt = 1; retval = ehci_halt(ehci); if (retval) return retval; /* data structure init */ retval = ehci_init(hcd); if (retval) return retval; ehci->sbrn = 0x20; ehci->controller_remote_wakeup = false; ehci_reset(ehci); tegra_usb_phy_reset(tegra->phy); #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \ !defined(CONFIG_TEGRA_SILICON_PLATFORM) val = readl(hcd->regs + TEGRA_STREAM_DISABLE); val |= TEGRA_STREAM_DISABLE_OFFSET; writel(val , hcd->regs + TEGRA_STREAM_DISABLE); #endif ehci_port_power(ehci, 1); return retval; }
static int pxau2h_driver_resume (struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); pxau2h_ehci_clk_set(1); if (!info->phy_init || info->phy_init(info->phybase)) { printk("%s phy_init failed\n", __func__); return 0; } if (time_before(jiffies, ehci->next_statechange)) udelay(100); /* Mark hardware accessible again */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); #if 0 /* If CF is still set, we maintained PCI Vaux power. * Just undo the effect of ehci_pci_suspend(). */ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); printk("%s end--------------------------------\n", __func__); return 0; } #endif usb_root_hub_lost_power(hcd->self.root_hub); ehci_halt(ehci); ehci_reset(ehci); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); hcd->state = HC_STATE_SUSPENDED; return 0; }
static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); // maybe restore FLADJ if (time_before(jiffies, ehci->next_statechange)) msleep(100); /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); /* If CF is still set and we aren't resuming from hibernation * then we maintained PCI Vaux power. * Just undo the effect of ehci_pci_suspend(). */ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF && !hibernated) { int mask = INTR_MASK; ehci_prepare_ports_for_controller_resume(ehci); if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } usb_root_hub_lost_power(hcd->self.root_hub); /* Else reset, to cope with power loss or flush-to-storage * style "resume" having let BIOS kick in during reboot. */ (void) ehci_halt(ehci); (void) ehci_reset(ehci); (void) ehci_pci_reinit(ehci, pdev); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); hcd->state = HC_STATE_SUSPENDED; return 0; }
/* * Halt HC, turn off all ports, and let the BIOS use the companion controllers. * Should be called with ehci->lock held. */ static void ehci_silence_controller(struct ehci_hcd *ehci) { ehci_halt(ehci); ehci_turn_off_all_ports(ehci); /* make BIOS/etc use companion controller during reboot */ ehci_writel(ehci, 0, &ehci->regs->configured_flag); /* unblock posted writes */ ehci_readl(ehci, &ehci->regs->configured_flag); }
/* * Work thread function for handling the USB power sequence. * * This work thread is created to avoid the pre-emption from the ISR context. * USB Power Rail and Vbus are controlled based on the USB cable connection. * USB Power rail function and VBUS control function cannot be called from ISR * as NvRmPmuSetVoltage() uses I2C driver, that waits on semaphore * during the I2C transaction this will cause the pre-emption if called in ISR. */ static void tegra_ehci_irq_work(struct work_struct* irq_work) { struct ehci_hcd *ehci = container_of(irq_work, struct ehci_hcd, irq_work); struct usb_hcd *hcd = ehci_to_hcd(ehci); struct tegra_hcd_platform_data *pdata; u32 status; bool kick_rhub = false; pdata = hcd->self.controller->platform_data; #ifdef CONFIG_USB_OTG_UTILS if (pdata->otg_mode && ehci->transceiver) { if (ehci->transceiver->state == OTG_STATE_A_HOST) { if (!ehci->host_reinited) { ehci->host_reinited = 1; tegra_ehci_power_up(hcd); if (hcd->state == HC_STATE_SUSPENDED) kick_rhub = true; tegra_ehci_restart(hcd); } } else if (ehci->transceiver->state == OTG_STATE_A_SUSPEND) { if (ehci->host_reinited) { /* indicate hcd flags, that hardware is not accessible now */ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); ehci_halt(ehci); tegra_ehci_power_down(hcd); ehci->transceiver->state = OTG_STATE_UNDEFINED; ehci->host_reinited = 0; } } } else #endif { if (pdata->id_detect == ID_PIN_CABLE_ID) { /* read otgsc register for ID pin status change */ status = readl(hcd->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); /* Check pin status and enable/disable the power */ if (status & TEGRA_USB_ID_PIN_STATUS) { tegra_ehci_power_down(hcd); } else { tegra_ehci_power_up(hcd); if (hcd->state == HC_STATE_SUSPENDED) kick_rhub = true; } } } if (kick_rhub) { hcd->state = HC_STATE_SUSPENDED; usb_hcd_resume_root_hub(hcd); } }
static int ehci_bus_suspend (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); int port; if (time_before (jiffies, ehci->next_statechange)) msleep(5); del_timer_sync(&ehci->watchdog); del_timer_sync(&ehci->iaa_watchdog); port = HCS_N_PORTS (ehci->hcs_params); spin_lock_irq (&ehci->lock); /* stop schedules, clean any completed work */ if (HC_IS_RUNNING(hcd->state)) { ehci_quiesce (ehci); hcd->state = HC_STATE_QUIESCING; } ehci->command = readl (&ehci->regs->command); if (ehci->reclaim) end_unlink_async(ehci, NULL); ehci_work(ehci, NULL); /* suspend any active/unsuspended ports, maybe allow wakeup */ while (port--) { u32 __iomem *reg = &ehci->regs->port_status [port]; u32 t1 = readl (reg) & ~PORT_RWC_BITS; u32 t2 = t1; if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) t2 |= PORT_SUSPEND; if (device_may_wakeup(&hcd->self.root_hub->dev)) { t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E); t2 |= PORT_WKOC_E; } else { t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E); } if (t1 != t2) { ehci_vdbg (ehci, "port %d, %08x -> %08x\n", port + 1, t1, t2); writel (t2, reg); } } /* turn off now-idle HC */ ehci_halt (ehci); hcd->state = HC_STATE_SUSPENDED; ehci->next_statechange = jiffies + msecs_to_jiffies(10); spin_unlock_irq (&ehci->lock); return 0; }
static int msm_ehci_reset(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct msm_hcd *mhcd = hcd_to_mhcd(hcd); struct msm_usb_host_platform_data *pdata; int retval; ehci->caps = USB_CAPLENGTH; ehci->regs = USB_CAPLENGTH + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* cache the data to minimize the chip reads*/ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); hcd->has_tt = 1; ehci->sbrn = HCD_USB2; retval = ehci_halt(ehci); if (retval) return retval; /* data structure init */ retval = ehci_init(hcd); if (retval) return retval; retval = ehci_reset(ehci); if (retval) return retval; /* bursts of unspecified length. */ writel_relaxed(0, USB_AHBBURST); /* Use the AHB transactor */ writel_relaxed(0x08, USB_AHBMODE); /* Disable streaming mode and select host mode */ writel_relaxed(0x13, USB_USBMODE); pdata = mhcd->dev->platform_data; if (pdata && pdata->use_sec_phy) writel_relaxed(readl_relaxed(USB_PHY_CTRL2) | (1<<16), USB_PHY_CTRL2); if (pdata && pdata->sw_fpr_ctrl) writel_relaxed(readl(USB_GENCONFIG2) | (1<<17), USB_GENCONFIG2); ehci_port_power(ehci, 1); return 0; }
static int ehci_hcd_spmp_drv_suspend(struct platform_device *pdev, pm_message_t message) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct spmp_ehci *spmpehci = (struct spmp_ehci *)hcd_to_ehci(hcd); unsigned long flags; int rc; // return 0; rc = 0; if (time_before(jiffies, ehci->next_statechange)) msleep(10); /* Root hub was already suspended. Disable irq emission and * mark HW unaccessible, bail out if RH has been resumed. Use * the spinlock to properly synchronize with possible pending * RH suspend or resume activity. * * This is still racy as hcd->state is manipulated outside of * any locks =P But that will be a different fix. */ spin_lock_irqsave(&ehci->lock, flags); if (hcd->state != HC_STATE_SUSPENDED) { rc = -EINVAL; goto bail; } ehci_writel(ehci, 0, &ehci->regs->intr_enable); (void)ehci_readl(ehci, &ehci->regs->intr_enable); /* make sure snapshot being resumed re-enumerates everything */ if (message.event == PM_EVENT_PRETHAW) { ehci_halt(ehci); ehci_reset(ehci); } clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); spmp_stop_ehc(spmpehci,&pdev->dev); bail: spin_unlock_irqrestore(&ehci->lock, flags); // could save FLADJ in case of Vaux power loss // ... we'd only use it to handle clock skew return rc; }
static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, u32 mask, u32 done, int usec) { int error; error = handshake(ehci, ptr, mask, done, usec); if (error) { ehci_halt(ehci); ehci_to_hcd(ehci)->state = HC_STATE_HALT; ehci_err(ehci, "force halt; handhake %p %08x %08x -> %d\n", ptr, mask, done, error); } return error; }
/* called during probe() after chip reset completes */ static int ehci_ppc_of_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; retval = ehci_halt(ehci); if (retval) return retval; retval = ehci_init(hcd); if (retval) return retval; ehci->sbrn = 0x20; return ehci_reset(ehci); }
static int tegra_usb_suspend(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); struct ehci_regs __iomem *hw = tegra->ehci->regs; unsigned long flags; spin_lock_irqsave(&tegra->ehci->lock, flags); tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; ehci_halt(tegra->ehci); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); spin_unlock_irqrestore(&tegra->ehci->lock, flags); tegra_ehci_power_down(hcd); return 0; }
static int ehci_spear_drv_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); if (time_before(jiffies, ehci->next_statechange)) msleep(100); if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; ehci_prepare_ports_for_controller_resume(ehci); if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } usb_root_hub_lost_power(hcd->self.root_hub); /* * Else reset, to cope with power loss or flush-to-storage style * "resume" having let BIOS kick in during reboot. */ ehci_halt(ehci); ehci_reset(ehci); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); return 0; }