static int exynos_ohci_resume(struct device *dev) { struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); struct usb_hcd *hcd = exynos_ohci->hcd; clk_prepare_enable(exynos_ohci->clk); if (exynos_ohci->otg) exynos_ohci->otg->set_host(exynos_ohci->otg, &exynos_ohci->hcd->self); exynos_ohci_phy_enable(exynos_ohci); if (exynos_ohci->phy) { /* * We are going to change runtime status to active. * Make sure we get the phy only if we didn't get it before. */ if (pm_runtime_suspended(dev)) pm_runtime_get_sync(exynos_ohci->phy->dev); } ohci_resume(hcd, false); /*Update runtime PM status and clear runtime_error */ pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); return 0; }
static ssize_t store_ohci_power(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); struct usb_hcd *hcd = exynos_ohci->hcd; int power_on; int irq; int retval; if (sscanf(buf, "%d", &power_on) != 1) return -EINVAL; device_lock(dev); if (!power_on && exynos_ohci->power_on) { printk(KERN_DEBUG "%s: EHCI turns off\n", __func__); pm_runtime_forbid(dev); exynos_ohci->power_on = 0; usb_remove_hcd(hcd); exynos_ohci_phy_disable(exynos_ohci); } else if (power_on) { printk(KERN_DEBUG "%s: EHCI turns on\n", __func__); if (exynos_ohci->power_on) { pm_runtime_forbid(dev); usb_remove_hcd(hcd); } else { exynos_ohci_phy_enable(exynos_ohci); } irq = platform_get_irq(pdev, 0); retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval < 0) { dev_err(dev, "Power On Fail\n"); goto exit; } /* * OHCI root hubs are expected to handle remote wakeup. * So, wakeup flag init defaults for root hubs. */ device_wakeup_enable(&hcd->self.root_hub->dev); exynos_ohci->power_on = 1; pm_runtime_allow(dev); } exit: device_unlock(dev); return count; }
static int exynos_ohci_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd); struct platform_device *pdev = to_platform_device(dev); clk_prepare_enable(exynos_ohci->clk); if (exynos_ohci->otg) exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self); exynos_ohci_phy_enable(pdev); ohci_resume(hcd, false); return 0; }
static int exynos_ohci_resume(struct device *dev) { struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); struct usb_hcd *hcd = exynos_ohci->hcd; clk_prepare_enable(exynos_ohci->clk); if (exynos_ohci->otg) exynos_ohci->otg->set_host(exynos_ohci->otg, &exynos_ohci->hcd->self); exynos_ohci_phy_enable(exynos_ohci); ohci_resume(hcd, false); return 0; }
static int exynos_ohci_probe(struct platform_device *pdev) { struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; struct exynos_ohci_hcd *exynos_ohci; struct usb_hcd *hcd; struct ohci_hcd *ohci; struct resource *res; struct usb_phy *phy; int irq; int err; /* * Right now device-tree probed devices don't get dma_mask set. * Since shared usb code relies on it, set it here for now. * Once we move to full device tree support this will vanish off. */ if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; if (!pdev->dev.coherent_dma_mask) pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd), GFP_KERNEL); if (!exynos_ohci) return -ENOMEM; if (of_device_is_compatible(pdev->dev.of_node, "samsung,exynos5440-ohci")) goto skip_phy; phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); if (IS_ERR(phy)) { /* Fallback to pdata */ if (!pdata) { dev_warn(&pdev->dev, "no platform data or transceiver defined\n"); return -EPROBE_DEFER; } else { exynos_ohci->pdata = pdata; } } else { exynos_ohci->phy = phy; exynos_ohci->otg = phy->otg; } skip_phy: exynos_ohci->dev = &pdev->dev; hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); return -ENOMEM; } exynos_ohci->hcd = hcd; exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost"); if (IS_ERR(exynos_ohci->clk)) { dev_err(&pdev->dev, "Failed to get usbhost clock\n"); err = PTR_ERR(exynos_ohci->clk); goto fail_clk; } err = clk_prepare_enable(exynos_ohci->clk); if (err) goto fail_clk; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Failed to get I/O memory\n"); err = -ENXIO; goto fail_io; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap(&pdev->dev, res->start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&pdev->dev, "Failed to remap I/O memory\n"); err = -ENOMEM; goto fail_io; } irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "Failed to get IRQ\n"); err = -ENODEV; goto fail_io; } if (exynos_ohci->otg) exynos_ohci->otg->set_host(exynos_ohci->otg, &exynos_ohci->hcd->self); /* Make sure PHY is initialized */ exynos_ohci_phy_enable(exynos_ohci); if (exynos_ohci->phy) /* * PHY can be runtime suspended (e.g. by EHCI driver), so * make sure PHY is active */ pm_runtime_get_sync(exynos_ohci->phy->dev); ohci = hcd_to_ohci(hcd); ohci_hcd_init(ohci); err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD\n"); goto fail_add_hcd; } platform_set_drvdata(pdev, exynos_ohci); /* * OHCI root hubs are expected to handle remote wakeup. * So, wakeup flag init defaults for root hubs. */ device_wakeup_enable(&hcd->self.root_hub->dev); if (create_ohci_sys_file(ohci)) dev_err(&pdev->dev, "Failed to create ehci sys file\n"); exynos_ohci->lpa_nb.notifier_call = exynos_ohci_lpa_event; exynos_ohci->lpa_nb.next = NULL; exynos_ohci->lpa_nb.priority = 0; err = exynos_pm_register_notifier(&exynos_ohci->lpa_nb); if (err) dev_err(&pdev->dev, "Failed to register lpa notifier\n"); exynos_ohci->power_on = 1; pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; fail_add_hcd: if (exynos_ohci->phy) pm_runtime_put_sync(exynos_ohci->phy->dev); exynos_ohci_phy_disable(exynos_ohci); fail_io: clk_disable_unprepare(exynos_ohci->clk); fail_clk: usb_put_hcd(hcd); return err; }
static int exynos_ohci_probe(struct platform_device *pdev) { struct exynos_ohci_hcd *exynos_ohci; struct usb_hcd *hcd; struct resource *res; struct usb_phy *phy; int irq; int err; /* * Right now device-tree probed devices don't get dma_mask set. * Since shared usb code relies on it, set it here for now. * Once we move to full device tree support this will vanish off. */ err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); if (err) return err; hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); return -ENOMEM; } exynos_ohci = to_exynos_ohci(hcd); if (of_device_is_compatible(pdev->dev.of_node, "samsung,exynos5440-ohci")) goto skip_phy; phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR(phy)) { usb_put_hcd(hcd); dev_warn(&pdev->dev, "no platform data or transceiver defined\n"); return -EPROBE_DEFER; } else { exynos_ohci->phy = phy; exynos_ohci->otg = phy->otg; } skip_phy: exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost"); if (IS_ERR(exynos_ohci->clk)) { dev_err(&pdev->dev, "Failed to get usbhost clock\n"); err = PTR_ERR(exynos_ohci->clk); goto fail_clk; } err = clk_prepare_enable(exynos_ohci->clk); if (err) goto fail_clk; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Failed to get I/O memory\n"); err = -ENXIO; goto fail_io; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap(&pdev->dev, res->start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&pdev->dev, "Failed to remap I/O memory\n"); err = -ENOMEM; goto fail_io; } irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "Failed to get IRQ\n"); err = -ENODEV; goto fail_io; } if (exynos_ohci->otg) exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self); platform_set_drvdata(pdev, hcd); exynos_ohci_phy_enable(pdev); err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD\n"); goto fail_add_hcd; } device_wakeup_enable(hcd->self.controller); return 0; fail_add_hcd: exynos_ohci_phy_disable(pdev); fail_io: clk_disable_unprepare(exynos_ohci->clk); fail_clk: usb_put_hcd(hcd); return err; }