static int ohci_omap_resume(struct device *dev, u32 level) { struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); int status = 0; if (level != RESUME_POWER_ON) return 0; switch (dev->power.power_state) { case 0: break; case 4: if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; omap_ohci_clock_power(1); /* FALLTHROUGH */ default: dev_dbg(dev, "resume from %d\n", dev->power.power_state); #ifdef CONFIG_USB_SUSPEND /* get extra cleanup even if remote wakeup isn't in use */ status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); #else down(&ohci_to_hcd(ohci)->self.root_hub->serialize); status = ohci_hub_resume(ohci_to_hcd(ohci)); up(&ohci_to_hcd(ohci)->self.root_hub->serialize); #endif if (status == 0) dev->power.power_state = 0; break; } return status; }
static void omap_start_hc(struct omap_dev *dev) { printk(KERN_DEBUG __FILE__ ": starting OMAP OHCI USB Controller\n"); /* * Set the HMC mode for the USB ports */ #if 0 /* See note about the Innovator wiring above */ if (omap_is_innovator()) hmc_mode = 4; /* 0: function 1: host 2: host */ #endif if (cpu_is_omap_1610()) ocpi_enable(); omap_usb_set_hmc_mode(hmc_mode); omap_ohci_clock_power(1); omap_ohci_transceiver_power(1); if (cpu_is_omap_1510()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } if (cpu_is_omap_1610()) omap_1610_usb_init(hmc_mode); //omap_enable_device(dev); }
static int ohci_omap_suspend(struct device *dev, u32 state, u32 level) { struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); int status = -EINVAL; if (level != SUSPEND_POWER_DOWN) return 0; if (state <= dev->power.power_state) return 0; dev_dbg(dev, "suspend to %d\n", state); down(&ohci_to_hcd(ohci)->self.root_hub->serialize); status = ohci_hub_suspend(ohci_to_hcd(ohci)); if (status == 0) { if (state >= 4) { omap_ohci_clock_power(0); ohci_to_hcd(ohci)->self.root_hub->state = USB_STATE_SUSPENDED; state = 4; } ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; dev->power.power_state = state; } up(&ohci_to_hcd(ohci)->self.root_hub->serialize); return status; }
static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message) { struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev)); if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; omap_ohci_clock_power(0); return 0; }
static int ohci_omap_resume(struct platform_device *dev) { struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev)); if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; omap_ohci_clock_power(1); dev->dev.power.power_state = PMSG_ON; usb_hcd_resume_root_hub(platform_get_drvdata(dev)); return 0; }
static int ohci_omap_resume(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct ohci_hcd *ohci = hcd_to_ohci(hcd); if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; omap_ohci_clock_power(1); ohci_finish_controller_resume(hcd); return 0; }
static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message) { struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev)); if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; omap_ohci_clock_power(0); ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; dev->dev.power.power_state = PMSG_SUSPEND; return 0; }
static int ohci_omap_suspend(struct platform_device *pdev, pm_message_t message) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ohci_hcd *ohci = hcd_to_ohci(hcd); bool do_wakeup = device_may_wakeup(&pdev->dev); int ret; if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; ret = ohci_suspend(hcd, do_wakeup); if (ret) return ret; omap_ohci_clock_power(0); return ret; }
/** * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs * @dev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of usb_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static inline void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) { dev_dbg(hcd->self.controller, "stopping USB Controller\n"); usb_remove_hcd(hcd); omap_ohci_clock_power(0); if (!IS_ERR_OR_NULL(hcd->phy)) { (void) otg_set_host(hcd->phy->otg, 0); usb_put_phy(hcd->phy); } if (machine_is_omap_osk()) gpio_free(9); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); clk_put(usb_dc_ck); clk_put(usb_host_ck); }
static int ohci_omap_init(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct omap_usb_config *config = hcd->self.controller->platform_data; int need_transceiver = (config->otg != 0); int ret; dev_dbg(hcd->self.controller, "starting USB Controller\n"); if (config->otg) { ohci_to_hcd(ohci)->self.otg_port = config->otg; /* */ ohci_to_hcd(ohci)->power_budget = 8; } /* */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); if (cpu_is_omap16xx()) ocpi_enable(); #ifdef CONFIG_USB_OTG if (need_transceiver) { ohci->transceiver = usb_get_transceiver(); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver->otg, &ohci_to_hcd(ohci)->self); dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n", ohci->transceiver->label, status); if (status) { if (ohci->transceiver) put_device(ohci->transceiver->dev); return status; } } else { dev_err(hcd->self.controller, "can't find transceiver\n"); return -ENODEV; } ohci->start_hnp = start_hnp; } #endif omap_ohci_clock_power(1); if (cpu_is_omap15xx()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } if ((ret = ohci_init(ohci)) < 0) return ret; /* */ if (machine_is_omap_osk() || machine_is_omap_innovator()) { u32 rh = roothub_a (ohci); /* */ rh &= ~RH_A_NPS; /* */ if (machine_is_omap_osk()) { ohci_to_hcd(ohci)->power_budget = 250; rh &= ~RH_A_NOCP; /* */ omap_cfg_reg(W8_1610_GPIO9); gpio_request(9, "OHCI overcurrent"); gpio_direction_input(9); /* */ omap_cfg_reg(W4_USB_HIGHZ); } ohci_writel(ohci, rh, &ohci->regs->roothub.a); ohci->flags &= ~OHCI_QUIRK_HUB_POWER; } else if (machine_is_nokia770()) { /* */ ohci_to_hcd(ohci)->power_budget = 0; } /* */ omap_ohci_transceiver_power(1); /* */ return 0; }
/** * usb_hcd_omap_probe - initialize OMAP-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ static int usb_hcd_omap_probe (const struct hc_driver *driver, struct platform_device *pdev) { int retval, irq; struct usb_hcd *hcd = 0; struct ohci_hcd *ohci; if (pdev->num_resources != 2) { printk(KERN_ERR "hcd probe: invalid num_resources: %i\n", pdev->num_resources); return -ENODEV; } if (pdev->resource[0].flags != IORESOURCE_MEM || pdev->resource[1].flags != IORESOURCE_IRQ) { printk(KERN_ERR "hcd probe: invalid resource type\n"); return -ENODEV; } usb_host_ck = clk_get(0, "usb_hhc_ck"); if (IS_ERR(usb_host_ck)) return PTR_ERR(usb_host_ck); if (!cpu_is_omap1510()) usb_dc_ck = clk_get(0, "usb_dc_ck"); else usb_dc_ck = clk_get(0, "lb_ck"); if (IS_ERR(usb_dc_ck)) { clk_put(usb_host_ck); return PTR_ERR(usb_dc_ck); } hcd = usb_create_hcd (driver, &pdev->dev, pdev->dev.bus_id); if (!hcd) { retval = -ENOMEM; goto err0; } hcd->rsrc_start = pdev->resource[0].start; hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_dbg(&pdev->dev, "request_mem_region failed\n"); retval = -EBUSY; goto err1; } hcd->regs = (void __iomem *) (int) IO_ADDRESS(hcd->rsrc_start); ohci = hcd_to_ohci(hcd); ohci_hcd_init(ohci); host_initialized = 0; host_enabled = 1; irq = platform_get_irq(pdev, 0); if (irq < 0) { retval = -ENXIO; goto err2; } retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); if (retval) goto err2; host_initialized = 1; if (!host_enabled) omap_ohci_clock_power(0); return 0; err2: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err1: usb_put_hcd(hcd); err0: clk_put(usb_dc_ck); clk_put(usb_host_ck); return retval; }
static void ohci_omap_stop(struct usb_hcd *hcd) { dev_dbg(hcd->self.controller, "stopping USB Controller\n"); omap_ohci_clock_power(0); }
static int ohci_omap_init(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct omap_usb_config *config = hcd->self.controller->platform_data; int need_transceiver = (config->otg != 0); int ret; dev_dbg(hcd->self.controller, "starting USB Controller\n"); if (config->otg) { ohci_to_hcd(ohci)->self.otg_port = config->otg; /* default/minimum OTG power budget: 8 mA */ ohci_to_hcd(ohci)->power_budget = 8; } /* boards can use OTG transceivers in non-OTG modes */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); if (cpu_is_omap16xx()) ocpi_enable(); #ifdef CONFIG_ARCH_OMAP_OTG if (need_transceiver) { ohci->transceiver = otg_get_transceiver(); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver, &ohci_to_hcd(ohci)->self); dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n", ohci->transceiver->label, status); if (status) { if (ohci->transceiver) put_device(ohci->transceiver->dev); return status; } } else { dev_err(hcd->self.controller, "can't find transceiver\n"); return -ENODEV; } } #endif omap_ohci_clock_power(1); if (cpu_is_omap1510()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } if ((ret = ohci_init(ohci)) < 0) return ret; /* board-specific power switching and overcurrent support */ if (machine_is_omap_osk() || machine_is_omap_innovator()) { u32 rh = roothub_a (ohci); /* power switching (ganged by default) */ rh &= ~RH_A_NPS; /* TPS2045 switch for internal transceiver (port 1) */ if (machine_is_omap_osk()) { ohci_to_hcd(ohci)->power_budget = 250; rh &= ~RH_A_NOCP; /* gpio9 for overcurrent detction */ omap_cfg_reg(W8_1610_GPIO9); omap_request_gpio(9); omap_set_gpio_direction(9, 1 /* IN */); /* for paranoia's sake: disable USB.PUEN */ omap_cfg_reg(W4_USB_HIGHZ); } ohci_writel(ohci, rh, &ohci->regs->roothub.a); distrust_firmware = 0; } else if (machine_is_nokia770()) { /* We require a self-powered hub, which should have * plenty of power. */ ohci_to_hcd(ohci)->power_budget = 0; } /* FIXME khubd hub requests should manage power switching */ omap_ohci_transceiver_power(1); /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized * too, so all configured ports use the right signaling now. */ return 0; }
static int ohci_omap_reset(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct omap_usb_config *config = dev_get_platdata(hcd->self.controller); int need_transceiver = (config->otg != 0); int ret; dev_dbg(hcd->self.controller, "starting USB Controller\n"); if (config->otg) { hcd->self.otg_port = config->otg; /* default/minimum OTG power budget: 8 mA */ hcd->power_budget = 8; } /* boards can use OTG transceivers in non-OTG modes */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); /* XXX OMAP16xx only */ if (config->ocpi_enable) config->ocpi_enable(); #ifdef CONFIG_USB_OTG if (need_transceiver) { hcd->phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!IS_ERR_OR_NULL(hcd->phy)) { int status = otg_set_host(hcd->phy->otg, &ohci_to_hcd(ohci)->self); dev_dbg(hcd->self.controller, "init %s phy, status %d\n", hcd->phy->label, status); if (status) { usb_put_phy(hcd->phy); return status; } } else { dev_err(hcd->self.controller, "can't find phy\n"); return -ENODEV; } ohci->start_hnp = start_hnp; } #endif omap_ohci_clock_power(1); if (cpu_is_omap15xx()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } ret = ohci_setup(hcd); if (ret < 0) return ret; if (config->otg || config->rwc) { ohci->hc_control = OHCI_CTRL_RWC; writel(OHCI_CTRL_RWC, &ohci->regs->control); } /* board-specific power switching and overcurrent support */ if (machine_is_omap_osk() || machine_is_omap_innovator()) { u32 rh = roothub_a (ohci); /* power switching (ganged by default) */ rh &= ~RH_A_NPS; /* TPS2045 switch for internal transceiver (port 1) */ if (machine_is_omap_osk()) { ohci_to_hcd(ohci)->power_budget = 250; rh &= ~RH_A_NOCP; /* gpio9 for overcurrent detction */ omap_cfg_reg(W8_1610_GPIO9); gpio_request(9, "OHCI overcurrent"); gpio_direction_input(9); /* for paranoia's sake: disable USB.PUEN */ omap_cfg_reg(W4_USB_HIGHZ); } ohci_writel(ohci, rh, &ohci->regs->roothub.a); ohci->flags &= ~OHCI_QUIRK_HUB_POWER; } else if (machine_is_nokia770()) { /* We require a self-powered hub, which should have * plenty of power. */ ohci_to_hcd(ohci)->power_budget = 0; } /* FIXME khubd hub requests should manage power switching */ omap_ohci_transceiver_power(1); /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized * too, so all configured ports use the right signaling now. */ return 0; }
/** * usb_hcd_omap_probe - initialize OMAP-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ static int usb_hcd_omap_probe (const struct hc_driver *driver, struct platform_device *pdev) { int retval, irq; struct usb_hcd *hcd = 0; struct ohci_hcd *ohci; if (pdev->num_resources != 2) { printk(KERN_ERR "hcd probe: invalid num_resources: %i\n", pdev->num_resources); return -ENODEV; } if (pdev->resource[0].flags != IORESOURCE_MEM || pdev->resource[1].flags != IORESOURCE_IRQ) { printk(KERN_ERR "hcd probe: invalid resource type\n"); return -ENODEV; } #ifndef CONFIG_ARCH_OMAP34XX usb_host_ck = clk_get(0, "usb_hhc_ck"); if (IS_ERR(usb_host_ck)) return PTR_ERR(usb_host_ck); if (!cpu_is_omap15xx()) usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck"); else usb_dc_ck = clk_get(&pdev->dev, "lb_ck"); if (IS_ERR(usb_dc_ck)) { clk_put(usb_host_ck); return PTR_ERR(usb_dc_ck); } #endif hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { retval = -ENOMEM; goto err0; } #if defined(CONFIG_ARCH_OMAP34XX) clk_enable(clk_get(NULL, "usbhost_ick")); clk_enable(clk_get(NULL, "usbtll_ick")); clk_enable(clk_get(NULL, "usbtll_fck")); clk_enable(clk_get(NULL, "usbhost_120m_fck")); clk_enable(clk_get(NULL, "usbhost_48m_fck")); #endif hcd->rsrc_start = pdev->resource[0].start; hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_dbg(&pdev->dev, "request_mem_region failed\n"); retval = -EBUSY; goto err1; } hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&pdev->dev, "can't ioremap OHCI HCD\n"); retval = -ENOMEM; goto err2; } ohci = hcd_to_ohci(hcd); ohci_hcd_init(ohci); host_initialized = 0; host_enabled = 1; irq = platform_get_irq(pdev, 0); if (irq < 0) { retval = -ENXIO; goto err3; } retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); if (retval) goto err3; host_initialized = 1; if (!host_enabled) omap_ohci_clock_power(0); return 0; err3: iounmap(hcd->regs); err2: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err1: usb_put_hcd(hcd); err0: #ifndef CONFIG_ARCH_OMAP34XX clk_put(usb_dc_ck); clk_put(usb_host_ck); #endif return retval; }
static int omap_start_hc(struct ohci_hcd *ohci, struct platform_device *pdev) { struct omap_usb_config *config = pdev->dev.platform_data; int need_transceiver = (config->otg != 0); dev_dbg(&pdev->dev, "starting USB Controller\n"); if (config->otg) { ohci->hcd.self.otg_port = config->otg; /* default/minimum OTG power budget: 8 mA */ ohci->power_budget = 8; } /* boards can use OTG transceivers in non-OTG modes */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); if (cpu_is_omap16xx()) ocpi_enable(); #ifdef CONFIG_ARCH_OMAP_OTG if (need_transceiver) { ohci->transceiver = otg_get_transceiver(); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver, &ohci->hcd.self); dev_dbg(&pdev->dev, "init %s transceiver, status %d\n", ohci->transceiver->label, status); if (status) { if (ohci->transceiver) put_device(ohci->transceiver->dev); return status; } } else { dev_err(&pdev->dev, "can't find transceiver\n"); return -ENODEV; } } #endif if (machine_is_omap_osk()) { omap_request_gpio(9); omap_set_gpio_direction(9, 1); omap_set_gpio_dataout(9, 1); } omap_ohci_clock_power(1); omap_ohci_transceiver_power(1); if (cpu_is_omap1510()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized * too, so all configured ports use the right signaling now. */ return 0; }
static void omap_stop_hc(struct platform_device *pdev) { dev_dbg(&pdev->dev, "stopping USB Controller\n"); omap_ohci_clock_power(0); }