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; /* 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)) { 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); } return ehci_irq(hcd); }
static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); struct ehci_regs __iomem *hw = ehci->regs; u32 val; //(weron) if receive more than 100 interrupt during usb resume, it means 3G module already crazy //Here we disable USB interrupt and recover later if (tegra->phy->instance == 1) { if(my_resume_process==1) { count++; if(count>100) { printk("I am crazy!!!\n"); ehci_writel(tegra->ehci, 0, &tegra->ehci->regs->intr_enable); count=0; crazyflag=1; } } else count=0; } if (tegra->phy->instance == 2) { 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 | PORT_CSC | PORT_PEC | PORT_OCC); writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET)); val = readl(&hw->status); if (!(val & STS_PCD)) { spin_unlock(&ehci->lock); return IRQ_NONE; } } spin_unlock (&ehci->lock); } return ehci_irq(hcd); }
static irqreturn_t ehci_msp_irq(struct usb_hcd *hcd) { u32 int_src; struct device *dev = hcd->self.controller; struct platform_device *pdev; struct mspusb_device *mdev; struct ehci_hcd *ehci = hcd_to_ehci(hcd); pdev = to_platform_device(dev); mdev = to_mspusb_device(pdev); int_src = ehci_readl(ehci, &mdev->mab_regs->int_stat); if (int_src & (1 << pdev->id)) return ehci_irq(hcd); return IRQ_NONE; }
/* * Wrapper around the main ehci_irq. Since both USB host controllers are * sharing the same IRQ, need to first determine whether we're the intended * recipient of this interrupt. */ static irqreturn_t ehci_msp_irq(struct usb_hcd *hcd) { u32 int_src; struct device *dev = hcd->self.controller; struct platform_device *pdev; struct mspusb_device *mdev; struct ehci_hcd *ehci = hcd_to_ehci(hcd); /* need to reverse-map a couple of containers to get our device */ pdev = to_platform_device(dev); mdev = to_mspusb_device(pdev); /* Check to see if this interrupt is for this host controller */ int_src = ehci_readl(ehci, &mdev->mab_regs->int_stat); if (int_src & (1 << pdev->id)) return ehci_irq(hcd); /* Not for this device */ return IRQ_NONE; }
static irqreturn_t msm_ehci_irq(struct usb_hcd *hcd) { struct msm_hcd *mhcd = hcd_to_mhcd(hcd); int ret = 0; if (atomic_read(&mhcd->in_lpm)) { dev_dbg(mhcd->dev, "phy async intr\n"); ret = pm_runtime_get(mhcd->dev); if ((ret == 1) || (ret == -EINPROGRESS)) { pm_runtime_put_noidle(mhcd->dev); } else { disable_irq_nosync(hcd->irq); mhcd->async_int = true; } return IRQ_HANDLED; } return ehci_irq(hcd); }
void tegra_ehci_enable_host (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); unsigned long flags; spin_lock_irqsave (&ehci->lock, flags); if (ehci->transceiver->state == OTG_STATE_A_HOST) { if (!ehci->host_reinited) { schedule_work(&ehci->irq_work); spin_unlock_irqrestore (&ehci->lock, flags); return; } else printk(KERN_DEBUG "%s host initialized already\n", __func__); } else if (ehci->transceiver->state == OTG_STATE_A_SUSPEND) { if (!ehci->host_reinited) { printk(KERN_DEBUG "%s host not initialized\n", __func__); spin_unlock_irqrestore (&ehci->lock, flags); return; } else { /* Force the disconnect because otherwise we could get * left in the connected state if the last getPorStatus * request comes in before the HOST -> SUSPEND state * change. */ spin_unlock_irqrestore (&ehci->lock, flags); /* 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; return; } } else printk(KERN_DEBUG "%s unexpected state\n", __func__); spin_unlock_irqrestore (&ehci->lock, flags); ehci_irq(hcd); return; }
static irqreturn_t msm_hsic_irq(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd); u32 status; if (atomic_read(&mehci->in_lpm)) { disable_irq_nosync(hcd->irq); dev_dbg(mehci->dev, "phy async intr\n"); mehci->async_int = true; pm_runtime_get(mehci->dev); return IRQ_HANDLED; } status = ehci_readl(ehci, &ehci->regs->status); if (status & STS_GPTIMER0_INTERRUPT) { int timeleft; dbg_log_event(NULL, "FPR: gpt0_isr", 0); timeleft = GPT_CNT(ehci_readl(ehci, &mehci->timer->gptimer1_ctrl)); if (timeleft) { ehci_writel(ehci, ehci_readl(ehci, &ehci->regs->command) | CMD_RUN, &ehci->regs->command); } else mehci->resume_again = 1; dbg_log_event(NULL, "FPR: timeleft", timeleft); complete(&mehci->gpt0_completion); ehci_writel(ehci, STS_GPTIMER0_INTERRUPT, &ehci->regs->status); } 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); }
int new_usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout) { #ifdef CONFIG_ENABLE_MIPS16 u8 *dma_data=kmalloc(16,GFP_NOIO); #endif struct usb_ctrlrequest *dr; struct urb *urb; volatile int done=0; unsigned long expire; int retry_cnt=0; int status; int retval; #ifdef USB_LOCK_ENABLE unsigned long flags; #endif dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); if (!dr) { return -ENOMEM; } dr->bRequestType= requesttype; dr->bRequest = request; dr->wValue = cpu_to_le16p(&value); dr->wIndex = cpu_to_le16p(&index); dr->wLength = cpu_to_le16p(&size); if((value==0x300)||(value==0x320)) { printk("Can't submit control msg value=%x\n",value); if(size==4) *(u32*)(data)=0; else if(size==1) *(u8*)(data)=0; else if(size==2) *(u16*)(data)=0; kfree(dr); return 0; } #ifdef __LINUX_2_6__ urb = usb_alloc_urb(0, GFP_ATOMIC); #else urb = usb_alloc_urb(0); #endif if (!urb) { kfree(dr); return -ENOMEM; } usb_control_cnt++; if(usb_control_cnt>1) printk("Error usb_control_cnt=%x\n",usb_control_cnt); // printk("fill urb data=%x indx=%x size=%d\n",*(u8*)data,index,size); #ifdef CONFIG_ENABLE_MIPS16 usb_fill_control_urb(urb, dev, pipe, (unsigned char *)dr, (void*)dma_data, size, new_usb_api_blocking_completion, (void *)&done); #else usb_fill_control_urb(urb, dev, pipe, (unsigned char *)dr, data, size, new_usb_api_blocking_completion, (void *)&done); #endif urb->actual_length = 0; #ifdef CONFIG_ENABLE_MIPS16 if(request==RTL8192_REQ_SET_REGS) memcpy(dma_data,data,size); dma_cache_wback_inv((u32)dma_data,size); //rtl_cache_sync_wback(priv, (unsigned int)dma_data, size, 0); #else if(request==RTL8192_REQ_SET_REGS) dma_cache_wback_inv((unsigned long)data, size); #endif #ifdef __LINUX_2_6__ status = usb_submit_urb(urb, GFP_ATOMIC); #else status = usb_submit_urb(urb); #endif if (unlikely(status)) { goto out; } if(timeout) //expire = msecs_to_jiffies(timeout) + jiffies; expire = timeout + jiffies; else expire = 200 + jiffies; //cathy if(expire<200) { if(!in_atomic()) { delay_ms(2100); expire=jiffies+200; } else expire=0xffffffffL; } retry: if(done==1) goto out; if(jiffies>=expire) goto out; #ifndef USB_LOCK_ENABLE if(in_atomic()) #endif { unsigned long flags=0; retry_cnt++; if(retry_cnt>2000) goto out; #ifdef CONFIG_USB_OTG_Driver dwc_otg_hcd_irq(usbhcd, NULL); printk("%s %d done=%x jiffies=%x expire=%x\n",__FUNCTION__,__LINE__,done,jiffies,expire); #elif defined(CONFIG_USB_OTG_HOST_RTL8672) usb_scan_async(dev->bus, 0); #elif defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_RTL8652) { struct usb_hcd *hcd=bus_to_hcd(dev->bus); #ifdef __LINUX_2_6__ struct ehci_hcd *ehci=(struct ehci_hcd *)hcd->hcd_priv; spin_lock_irqsave (&ehci->lock, flags); //scan_async(ehci); ehci_irq(hcd); spin_unlock_irqrestore (&ehci->lock, flags); #else ehci_irq(hcd, NULL); #endif } #endif } #ifndef USB_LOCK_ENABLE else schedule(); #endif goto retry; out: if(retry_cnt>2000) { printk("Timeout! requesttype=%x request=%x value=%x index=%x size=%x retry_cnt=%d\n",requesttype,request,value,index,size,retry_cnt); } if(done==0) { #if 0 printk("USB Timeout!!!\n"); if(!in_atomic()) { usb_kill_urb(urb); } else { printk("in atomic, can't kill urb\n"); } status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status; #else retval = new_usb_kill_urb(urb); status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status; if((status != 0) && (status!= -ETIMEDOUT)) { printk("[%s,%d], urb->status = %d, retval = %d\n", __func__, __LINE__, urb->status, retval); } #endif } else { // printk("index=%x data=%x done\n",index,*(u8*)data); #ifdef CONFIG_ENABLE_MIPS16 if(request==RTL8192_REQ_GET_REGS) memcpy(data,dma_data,size); #endif status = urb->status; } usb_free_urb(urb); #ifdef CONFIG_ENABLE_MIPS16 kfree(dma_data); #endif kfree(dr); usb_control_cnt--; return status; }
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)); } else if (tegra->bus_suspended && tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { printk("%s: no device connected before suspend\n", __func__); spin_unlock(&ehci->lock); return 0; } spin_unlock(&ehci->lock); } irq_status = ehci_irq(hcd); if (pmc_remote_wakeup || tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_HSIC) { 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; }
static irqreturn_t tegra_ehci_irq(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); struct ehci_hcd *ehci = hcd_to_ehci(hcd); irqreturn_t irq_status; bool pmc_remote_wakeup = false; struct platform_device *pdev = container_of(hcd->self.controller, struct platform_device, dev); int ehci_id = pdev->id; spin_lock(&ehci->lock); irq_status = tegra_usb_phy_irq(tegra->phy); if (irq_status == IRQ_NONE) { spin_unlock(&ehci->lock); return irq_status; } if (tegra_usb_phy_remote_wakeup(tegra->phy)) { ehci_info(ehci, "remote wakeup detected on controller.%d\n", ehci_id); /* +SSD_RIL: workaround for remote wake AT timeout. */ if (Modem_is_IMC() && ehci_id == MODEM_EHCI_ID) { debug_gpio_dump(); //trigger_radio_fatal_get_coredump("remote wakeup in PMC"); } else { pmc_remote_wakeup = true; usb_hcd_resume_root_hub(hcd); } /* -SSD_RIL: workaround for remote wake AT timeout. */ spin_unlock(&ehci->lock); return irq_status; } spin_unlock(&ehci->lock); // EHCI_DBG("%s() cmd = 0x%x, int_sts = 0x%x, portsc = 0x%x\n", __func__, // ehci_readl(ehci, &ehci->regs->command), // ehci_readl(ehci, &ehci->regs->status), // ehci_readl(ehci, &ehci->regs->port_status[0])); irq_status = ehci_irq(hcd); if (pmc_remote_wakeup) { ehci->controller_remote_wakeup = false; } if (ehci->controller_remote_wakeup) { ehci->controller_remote_wakeup = false; /* +SSD_RIL: workaround for remote wake hang. */ if (Modem_is_IMC() && ehci_id == MODEM_EHCI_ID) { ehci_info(ehci, "controller.%d remote wakeup detected", ehci_id); debug_gpio_dump(); //trigger_radio_fatal_get_coredump("remote wakeup in controller"); } else { tegra_usb_phy_pre_resume(tegra->phy, true); tegra->port_resuming = 1; } /* -SSD_RIL: workaround for remote wake hang. */ } return irq_status; }