static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; /* * Attempt to find a generic PHY, then look for an old style * USB PHY and then fall back to pdata */ hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy"); if (IS_ERR(hsotg->phy)) { hsotg->phy = NULL; hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2); if (IS_ERR(hsotg->uphy)) hsotg->uphy = NULL; else hsotg->plat = dev_get_platdata(hsotg->dev); } if (hsotg->phy) { /* * If using the generic PHY framework, check if the PHY bus * width is 8-bit and set the phyif appropriately. */ if (phy_get_bus_width(hsotg->phy) == 8) hsotg->phyif = GUSBCFG_PHYIF8; } if (!hsotg->phy && !hsotg->uphy && !hsotg->plat) { dev_err(hsotg->dev, "no platform data or transceiver defined\n"); return -EPROBE_DEFER; } /* Clock */ hsotg->clk = devm_clk_get(hsotg->dev, "otg"); if (IS_ERR(hsotg->clk)) { hsotg->clk = NULL; dev_dbg(hsotg->dev, "cannot get otg clock\n"); } /* Regulators */ for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i]; ret = devm_regulator_bulk_get(hsotg->dev, ARRAY_SIZE(hsotg->supplies), hsotg->supplies); if (ret) { dev_err(hsotg->dev, "failed to request supplies: %d\n", ret); return ret; } return 0; }
static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2"); if (IS_ERR(hsotg->reset)) { ret = PTR_ERR(hsotg->reset); dev_err(hsotg->dev, "error getting reset control %d\n", ret); return ret; } reset_control_deassert(hsotg->reset); /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; /* * Attempt to find a generic PHY, then look for an old style * USB PHY and then fall back to pdata */ hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy"); if (IS_ERR(hsotg->phy)) { ret = PTR_ERR(hsotg->phy); switch (ret) { case -ENODEV: case -ENOSYS: hsotg->phy = NULL; break; case -EPROBE_DEFER: return ret; default: dev_err(hsotg->dev, "error getting phy %d\n", ret); return ret; } } if (!hsotg->phy) { hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2); if (IS_ERR(hsotg->uphy)) { ret = PTR_ERR(hsotg->uphy); switch (ret) { case -ENODEV: case -ENXIO: hsotg->uphy = NULL; break; case -EPROBE_DEFER: return ret; default: dev_err(hsotg->dev, "error getting usb phy %d\n", ret); return ret; } } } hsotg->plat = dev_get_platdata(hsotg->dev); if (hsotg->phy) { /* * If using the generic PHY framework, check if the PHY bus * width is 8-bit and set the phyif appropriately. */ if (phy_get_bus_width(hsotg->phy) == 8) hsotg->phyif = GUSBCFG_PHYIF8; } /* Clock */ hsotg->clk = devm_clk_get(hsotg->dev, "otg"); if (IS_ERR(hsotg->clk)) { hsotg->clk = NULL; dev_dbg(hsotg->dev, "cannot get otg clock\n"); } /* Regulators */ for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i]; ret = devm_regulator_bulk_get(hsotg->dev, ARRAY_SIZE(hsotg->supplies), hsotg->supplies); if (ret) { dev_err(hsotg->dev, "failed to request supplies: %d\n", ret); return ret; } return 0; }
static int dwc3_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct resource *res; struct dwc3 *dwc; struct device *dev = &pdev->dev; int ret = -ENOMEM; void __iomem *regs; void *mem; u8 mode; bool host_only_mode; mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); if (!mem) { dev_err(dev, "not enough memory\n"); return -ENOMEM; } dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); dwc->mem = mem; dwc->notify_event = notify_event; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "missing IRQ\n"); return -ENODEV; } dwc->xhci_resources[1].start = res->start; dwc->xhci_resources[1].end = res->end; dwc->xhci_resources[1].flags = res->flags; dwc->xhci_resources[1].name = res->name; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing memory resource\n"); return -ENODEV; } dwc->xhci_resources[0].start = res->start; dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + DWC3_XHCI_REGS_END; dwc->xhci_resources[0].flags = res->flags; dwc->xhci_resources[0].name = res->name; /* * Request memory region but exclude xHCI regs, * since it will be requested by the xhci-plat driver. */ res = devm_request_mem_region(dev, res->start + DWC3_GLOBALS_REGS_START, resource_size(res) - DWC3_GLOBALS_REGS_START, dev_name(dev)); if (!res) { dev_err(dev, "can't request mem region\n"); return -ENOMEM; } regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!regs) { dev_err(dev, "ioremap failed\n"); return -ENOMEM; } dwc->core_reset_after_phy_init = of_property_read_bool(node, "core_reset_after_phy_init"); dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); host_only_mode = of_property_read_bool(node, "host-only-mode"); dwc->maximum_speed = of_usb_get_maximum_speed(node); if (node) { dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1); } else { dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); } /* default to superspeed if no maximum_speed passed */ if (dwc->maximum_speed == USB_SPEED_UNKNOWN) dwc->maximum_speed = USB_SPEED_SUPER; if (IS_ERR(dwc->usb2_phy)) { ret = PTR_ERR(dwc->usb2_phy); /* * if -ENXIO is returned, it means PHY layer wasn't * enabled, so it makes no sense to return -EPROBE_DEFER * in that case, since no PHY driver will ever probe. */ if (ret == -ENXIO) return ret; dev_err(dev, "no usb2 phy configured\n"); return -EPROBE_DEFER; } if (IS_ERR(dwc->usb3_phy)) { ret = PTR_ERR(dwc->usb2_phy); /* * if -ENXIO is returned, it means PHY layer wasn't * enabled, so it makes no sense to return -EPROBE_DEFER * in that case, since no PHY driver will ever probe. */ if (ret == -ENXIO) return ret; dev_err(dev, "no usb3 phy configured\n"); return -EPROBE_DEFER; } usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); spin_lock_init(&dwc->lock); platform_set_drvdata(pdev, dwc); dwc->regs = regs; dwc->regs_size = resource_size(res); dwc->dev = dev; dev->dma_mask = dev->parent->dma_mask; dev->dma_parms = dev->parent->dma_parms; dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); pm_runtime_no_callbacks(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); dwc3_cache_hwparams(dwc); if (!dwc->ev_buffs) { ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); if (ret) { dev_err(dwc->dev, "failed to allocate event buffers\n"); ret = -ENOMEM; goto err0; } } dwc->nominal_elastic_buffer = of_property_read_bool(node, "nominal-elastic-buffer"); ret = dwc3_core_init(dwc); if (ret) { dev_err(dev, "failed to initialize core\n"); goto err0; } ret = dwc3_event_buffers_setup(dwc); if (ret) { dev_err(dwc->dev, "failed to setup event buffers\n"); goto err1; } if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) mode = DWC3_MODE_HOST; else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) mode = DWC3_MODE_DEVICE; else mode = DWC3_MODE_DRD; /* Override mode if user selects host-only config with DRD core */ if (host_only_mode && (mode == DWC3_MODE_DRD)) { dev_dbg(dev, "host only mode selected\n"); mode = DWC3_MODE_HOST; } switch (mode) { case DWC3_MODE_DEVICE: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); ret = dwc3_gadget_init(dwc); if (ret) { dev_err(dev, "failed to initialize gadget\n"); goto err2; } break; case DWC3_MODE_HOST: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); ret = dwc3_host_init(dwc); if (ret) { dev_err(dev, "failed to initialize host\n"); goto err2; } break; case DWC3_MODE_DRD: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG); ret = dwc3_otg_init(dwc); if (ret) { dev_err(dev, "failed to initialize otg\n"); goto err1; } ret = dwc3_host_init(dwc); if (ret) { dev_err(dev, "failed to initialize host\n"); dwc3_otg_exit(dwc); goto err1; } ret = dwc3_gadget_init(dwc); if (ret) { dev_err(dev, "failed to initialize gadget\n"); dwc3_host_exit(dwc); dwc3_otg_exit(dwc); goto err2; } break; default: dev_err(dev, "Unsupported mode of operation %d\n", mode); goto err2; } dwc->mode = mode; ret = dwc3_debugfs_init(dwc); if (ret) { dev_err(dev, "failed to initialize debugfs\n"); goto err3; } dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_INITIALIZATION_EVENT); return 0; err3: switch (mode) { case DWC3_MODE_DEVICE: dwc3_gadget_exit(dwc); break; case DWC3_MODE_HOST: dwc3_host_exit(dwc); break; case DWC3_MODE_DRD: dwc3_gadget_exit(dwc); dwc3_host_exit(dwc); dwc3_otg_exit(dwc); break; default: /* do nothing */ break; } err2: dwc3_event_buffers_cleanup(dwc); err1: dwc3_core_exit(dwc); err0: dwc3_free_event_buffers(dwc); return ret; }
static int ehci_msm_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct resource *res; struct usb_phy *phy; int ret; dev_dbg(&pdev->dev, "ehci_msm proble\n"); hcd = usb_create_hcd(&msm_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); return -ENOMEM; } hcd->irq = platform_get_irq(pdev, 0); if (hcd->irq < 0) { dev_err(&pdev->dev, "Unable to get IRQ resource\n"); ret = hcd->irq; goto put_hcd; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Unable to get memory resource\n"); ret = -ENODEV; goto put_hcd; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto put_hcd; } /* * OTG driver takes care of PHY initialization, clock management, * powering up VBUS, mapping of registers address space and power * management. */ if (pdev->dev.of_node) phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); else phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR(phy)) { dev_err(&pdev->dev, "unable to find transceiver\n"); ret = -EPROBE_DEFER; goto put_hcd; } ret = otg_set_host(phy->otg, &hcd->self); if (ret < 0) { dev_err(&pdev->dev, "unable to register with transceiver\n"); goto put_hcd; } hcd->phy = phy; device_init_wakeup(&pdev->dev, 1); /* * OTG device parent of HCD takes care of putting * hardware into low power mode. */ pm_runtime_no_callbacks(&pdev->dev); pm_runtime_enable(&pdev->dev); /* FIXME: need to call usb_add_hcd() here? */ return 0; put_hcd: usb_put_hcd(hcd); return ret; }
static int ehci_msm_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct resource *res; int ret; dev_dbg(&pdev->dev, "ehci_msm proble\n"); if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &msm_ehci_dma_mask; if (!pdev->dev.coherent_dma_mask) pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); hcd = usb_create_hcd(&ehci_msm_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); return -ENOMEM; } hcd_to_bus(hcd)->skip_resume = true; hcd->irq = platform_get_irq(pdev, 0); if (hcd->irq < 0) { dev_err(&pdev->dev, "Unable to get IRQ resource\n"); ret = hcd->irq; goto put_hcd; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Unable to get memory resource\n"); ret = -ENODEV; goto put_hcd; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto put_hcd; } /* * OTG driver takes care of PHY initialization, clock management, * powering up VBUS, mapping of registers address space and power * management. */ phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(phy)) { dev_err(&pdev->dev, "unable to find transceiver\n"); ret = -ENODEV; goto put_hcd; } ret = otg_set_host(phy->otg, &hcd->self); if (ret < 0) { dev_err(&pdev->dev, "unable to register with transceiver\n"); goto put_hcd; } hcd->phy = phy; device_init_wakeup(&pdev->dev, 1); pm_runtime_enable(&pdev->dev); msm_bam_set_usb_host_dev(&pdev->dev); return 0; put_hcd: usb_put_hcd(hcd); return ret; }
static int mv_ehci_probe(struct platform_device *pdev) { struct mv_usb_platform_data *pdata = dev_get_platdata(&pdev->dev); struct usb_hcd *hcd; struct ehci_hcd *ehci; struct ehci_hcd_mv *ehci_mv; struct resource *r; int retval = -ENODEV; u32 offset; if (!pdata) { dev_err(&pdev->dev, "missing platform_data\n"); return -ENODEV; } if (usb_disabled()) return -ENODEV; hcd = usb_create_hcd(&mv_ehci_hc_driver, &pdev->dev, "mv ehci"); if (!hcd) return -ENOMEM; ehci_mv = devm_kzalloc(&pdev->dev, sizeof(*ehci_mv), GFP_KERNEL); if (ehci_mv == NULL) { dev_err(&pdev->dev, "cannot allocate ehci_hcd_mv\n"); retval = -ENOMEM; goto err_put_hcd; } platform_set_drvdata(pdev, ehci_mv); ehci_mv->pdata = pdata; ehci_mv->hcd = hcd; ehci_mv->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ehci_mv->clk)) { dev_err(&pdev->dev, "error getting clock\n"); retval = PTR_ERR(ehci_mv->clk); goto err_put_hcd; } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phyregs"); if (r == NULL) { dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); retval = -ENODEV; goto err_put_hcd; } ehci_mv->phy_regs = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(ehci_mv->phy_regs)) { retval = PTR_ERR(ehci_mv->phy_regs); goto err_put_hcd; } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "capregs"); if (!r) { dev_err(&pdev->dev, "no I/O memory resource defined\n"); retval = -ENODEV; goto err_put_hcd; } ehci_mv->cap_regs = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(ehci_mv->cap_regs)) { retval = PTR_ERR(ehci_mv->cap_regs); goto err_put_hcd; } retval = mv_ehci_enable(ehci_mv); if (retval) { dev_err(&pdev->dev, "init phy error %d\n", retval); goto err_put_hcd; } offset = readl(ehci_mv->cap_regs) & CAPLENGTH_MASK; ehci_mv->op_regs = (void __iomem *) ((unsigned long) ehci_mv->cap_regs + offset); hcd->rsrc_start = r->start; hcd->rsrc_len = resource_size(r); hcd->regs = ehci_mv->op_regs; hcd->irq = platform_get_irq(pdev, 0); if (!hcd->irq) { dev_err(&pdev->dev, "Cannot get irq."); retval = -ENODEV; goto err_disable_clk; } ehci = hcd_to_ehci(hcd); ehci->caps = (struct ehci_caps *) ehci_mv->cap_regs; ehci_mv->mode = pdata->mode; if (ehci_mv->mode == MV_USB_MODE_OTG) { ehci_mv->otg = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR(ehci_mv->otg)) { retval = PTR_ERR(ehci_mv->otg); if (retval == -ENXIO) dev_info(&pdev->dev, "MV_USB_MODE_OTG " "must have CONFIG_USB_PHY enabled\n"); else dev_err(&pdev->dev, "unable to find transceiver\n"); goto err_disable_clk; } retval = otg_set_host(ehci_mv->otg->otg, &hcd->self); if (retval < 0) { dev_err(&pdev->dev, "unable to register with transceiver\n"); retval = -ENODEV; goto err_disable_clk; } /* otg will enable clock before use as host */ mv_ehci_disable(ehci_mv); } else { if (pdata->set_vbus) pdata->set_vbus(1); retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); if (retval) { dev_err(&pdev->dev, "failed to add hcd with err %d\n", retval); goto err_set_vbus; } device_wakeup_enable(hcd->self.controller); } if (pdata->private_init) pdata->private_init(ehci_mv->op_regs, ehci_mv->phy_regs); dev_info(&pdev->dev, "successful find EHCI device with regs 0x%p irq %d" " working in %s mode\n", hcd->regs, hcd->irq, ehci_mv->mode == MV_USB_MODE_OTG ? "OTG" : "Host"); return 0; err_set_vbus: if (pdata->set_vbus) pdata->set_vbus(0); err_disable_clk: mv_ehci_disable(ehci_mv); err_put_hcd: usb_put_hcd(hcd); return retval; }
static int dwc3_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct resource *res; struct dwc3 *dwc; struct device *dev = &pdev->dev; int ret = -ENOMEM; void __iomem *regs; void *mem; u8 mode; mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); if (!mem) { dev_err(dev, "not enough memory\n"); return -ENOMEM; } dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); dwc->mem = mem; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "missing IRQ\n"); return -ENODEV; } dwc->xhci_resources[1].start = res->start; dwc->xhci_resources[1].end = res->end; dwc->xhci_resources[1].flags = res->flags; dwc->xhci_resources[1].name = res->name; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing memory resource\n"); return -ENODEV; } dwc->xhci_resources[0].start = res->start; dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + DWC3_XHCI_REGS_END; dwc->xhci_resources[0].flags = res->flags; dwc->xhci_resources[0].name = res->name; /* * Request memory region but exclude xHCI regs, * since it will be requested by the xhci-plat driver. */ res = devm_request_mem_region(dev, res->start + DWC3_GLOBALS_REGS_START, resource_size(res) - DWC3_GLOBALS_REGS_START, dev_name(dev)); if (!res) { dev_err(dev, "can't request mem region\n"); return -ENOMEM; } regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!regs) { dev_err(dev, "ioremap failed\n"); return -ENOMEM; } if (node) { dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1); } else { dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); } if (IS_ERR(dwc->usb2_phy)) { ret = PTR_ERR(dwc->usb2_phy); /* * if -ENXIO is returned, it means PHY layer wasn't * enabled, so it makes no sense to return -EPROBE_DEFER * in that case, since no PHY driver will ever probe. */ if (ret == -ENXIO) return ret; dev_err(dev, "no usb2 phy configured\n"); return -EPROBE_DEFER; } if (IS_ERR(dwc->usb3_phy)) { ret = PTR_ERR(dwc->usb3_phy); /* * if -ENXIO is returned, it means PHY layer wasn't * enabled, so it makes no sense to return -EPROBE_DEFER * in that case, since no PHY driver will ever probe. */ if (ret == -ENXIO) return ret; dev_err(dev, "no usb3 phy configured\n"); return -EPROBE_DEFER; } usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); spin_lock_init(&dwc->lock); platform_set_drvdata(pdev, dwc); dwc->regs = regs; dwc->regs_size = resource_size(res); dwc->dev = dev; dev->dma_mask = dev->parent->dma_mask; dev->dma_parms = dev->parent->dma_parms; dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); if (!strncmp("super", maximum_speed, 5)) dwc->maximum_speed = DWC3_DCFG_SUPERSPEED; else if (!strncmp("high", maximum_speed, 4)) dwc->maximum_speed = DWC3_DCFG_HIGHSPEED; else if (!strncmp("full", maximum_speed, 4)) dwc->maximum_speed = DWC3_DCFG_FULLSPEED1; else if (!strncmp("low", maximum_speed, 3)) dwc->maximum_speed = DWC3_DCFG_LOWSPEED; else dwc->maximum_speed = DWC3_DCFG_SUPERSPEED; dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); pm_runtime_enable(dev); pm_runtime_get_sync(dev); pm_runtime_forbid(dev); dwc3_cache_hwparams(dwc); ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); if (ret) { dev_err(dwc->dev, "failed to allocate event buffers\n"); ret = -ENOMEM; goto err0; } ret = dwc3_core_init(dwc); if (ret) { dev_err(dev, "failed to initialize core\n"); goto err0; } ret = dwc3_event_buffers_setup(dwc); if (ret) { dev_err(dwc->dev, "failed to setup event buffers\n"); goto err1; } if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) mode = DWC3_MODE_HOST; else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) mode = DWC3_MODE_DEVICE; else mode = DWC3_MODE_DRD; switch (mode) { case DWC3_MODE_DEVICE: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); ret = dwc3_gadget_init(dwc); if (ret) { dev_err(dev, "failed to initialize gadget\n"); goto err2; } break; case DWC3_MODE_HOST: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); ret = dwc3_host_init(dwc); if (ret) { dev_err(dev, "failed to initialize host\n"); goto err2; } break; case DWC3_MODE_DRD: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG); ret = dwc3_host_init(dwc); if (ret) { dev_err(dev, "failed to initialize host\n"); goto err2; } ret = dwc3_gadget_init(dwc); if (ret) { dev_err(dev, "failed to initialize gadget\n"); goto err2; } break; default: dev_err(dev, "Unsupported mode of operation %d\n", mode); goto err2; } dwc->mode = mode; ret = dwc3_debugfs_init(dwc); if (ret) { dev_err(dev, "failed to initialize debugfs\n"); goto err3; } pm_runtime_allow(dev); return 0; err3: switch (mode) { case DWC3_MODE_DEVICE: dwc3_gadget_exit(dwc); break; case DWC3_MODE_HOST: dwc3_host_exit(dwc); break; case DWC3_MODE_DRD: dwc3_host_exit(dwc); dwc3_gadget_exit(dwc); break; default: /* do nothing */ break; } err2: dwc3_event_buffers_cleanup(dwc); err1: dwc3_core_exit(dwc); err0: dwc3_free_event_buffers(dwc); return ret; }
static int isp1704_charger_probe(struct platform_device *pdev) { struct isp1704_charger *isp; int ret = -ENODEV; struct power_supply_config psy_cfg = {}; struct isp1704_charger_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *np = pdev->dev.of_node; if (np) { int gpio = of_get_named_gpio(np, "nxp,enable-gpio", 0); if (gpio < 0) { dev_err(&pdev->dev, "missing DT GPIO nxp,enable-gpio\n"); return gpio; } pdata = devm_kzalloc(&pdev->dev, sizeof(struct isp1704_charger_data), GFP_KERNEL); if (!pdata) { ret = -ENOMEM; goto fail0; } pdata->enable_gpio = gpio; dev_info(&pdev->dev, "init gpio %d\n", pdata->enable_gpio); ret = devm_gpio_request_one(&pdev->dev, pdata->enable_gpio, GPIOF_OUT_INIT_HIGH, "isp1704_reset"); if (ret) { dev_err(&pdev->dev, "gpio request failed\n"); goto fail0; } } if (!pdata) { dev_err(&pdev->dev, "missing platform data!\n"); return -ENODEV; } isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL); if (!isp) return -ENOMEM; if (np) isp->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); else isp->phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR(isp->phy)) { ret = PTR_ERR(isp->phy); dev_err(&pdev->dev, "usb_get_phy failed\n"); goto fail0; } isp->dev = &pdev->dev; platform_set_drvdata(pdev, isp); isp1704_charger_set_power(isp, 1); ret = isp1704_test_ulpi(isp); if (ret < 0) { dev_err(&pdev->dev, "isp1704_test_ulpi failed\n"); goto fail1; } isp->psy_desc.name = "isp1704"; isp->psy_desc.type = POWER_SUPPLY_TYPE_USB; isp->psy_desc.properties = power_props; isp->psy_desc.num_properties = ARRAY_SIZE(power_props); isp->psy_desc.get_property = isp1704_charger_get_property; psy_cfg.drv_data = isp; isp->psy = power_supply_register(isp->dev, &isp->psy_desc, &psy_cfg); if (IS_ERR(isp->psy)) { ret = PTR_ERR(isp->psy); dev_err(&pdev->dev, "power_supply_register failed\n"); goto fail1; } /* * REVISIT: using work in order to allow the usb notifications to be * made atomically in the future. */ INIT_WORK(&isp->work, isp1704_charger_work); isp->nb.notifier_call = isp1704_notifier_call; ret = usb_register_notifier(isp->phy, &isp->nb); if (ret) { dev_err(&pdev->dev, "usb_register_notifier failed\n"); goto fail2; } dev_info(isp->dev, "registered with product id %s\n", isp->model); /* * Taking over the D+ pullup. * * FIXME: The device will be disconnected if it was already * enumerated. The charger driver should be always loaded before any * gadget is loaded. */ if (isp->phy->otg->gadget) usb_gadget_disconnect(isp->phy->otg->gadget); if (isp->phy->last_event == USB_EVENT_NONE) isp1704_charger_set_power(isp, 0); /* Detect charger if VBUS is valid (the cable was already plugged). */ if (isp->phy->last_event == USB_EVENT_VBUS && !isp->phy->otg->default_a) schedule_work(&isp->work); return 0; fail2: power_supply_unregister(isp->psy); fail1: isp1704_charger_set_power(isp, 0); fail0: dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret); return ret; }
static int dwc3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct dwc3_platform_data *pdata = dev_get_platdata(dev); struct device_node *node = dev->of_node; struct resource *res; struct dwc3 *dwc; int ret = -ENOMEM; void __iomem *regs; void *mem; mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); if (!mem) { dev_err(dev, "not enough memory\n"); return -ENOMEM; } dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); dwc->mem = mem; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "missing IRQ\n"); return -ENODEV; } dwc->xhci_resources[1].start = res->start; dwc->xhci_resources[1].end = res->end; dwc->xhci_resources[1].flags = res->flags; dwc->xhci_resources[1].name = res->name; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing memory resource\n"); return -ENODEV; } if (node) { dwc->maximum_speed = of_usb_get_maximum_speed(node); dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1); dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); dwc->dr_mode = of_usb_get_dr_mode(node); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->dr_mode = pdata->dr_mode; } else { dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); } /* default to superspeed if no maximum_speed passed */ if (dwc->maximum_speed == USB_SPEED_UNKNOWN) dwc->maximum_speed = USB_SPEED_SUPER; if (IS_ERR(dwc->usb2_phy)) { ret = PTR_ERR(dwc->usb2_phy); if (ret == -ENXIO || ret == -ENODEV) { dwc->usb2_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb2 phy configured\n"); return ret; } } if (IS_ERR(dwc->usb3_phy)) { ret = PTR_ERR(dwc->usb3_phy); if (ret == -ENXIO || ret == -ENODEV) { dwc->usb3_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb3 phy configured\n"); return ret; } } dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy"); if (IS_ERR(dwc->usb2_generic_phy)) { ret = PTR_ERR(dwc->usb2_generic_phy); if (ret == -ENOSYS || ret == -ENODEV) { dwc->usb2_generic_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb2 phy configured\n"); return ret; } } dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy"); if (IS_ERR(dwc->usb3_generic_phy)) { ret = PTR_ERR(dwc->usb3_generic_phy); if (ret == -ENOSYS || ret == -ENODEV) { dwc->usb3_generic_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb3 phy configured\n"); return ret; } } dwc->xhci_resources[0].start = res->start; dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + DWC3_XHCI_REGS_END; dwc->xhci_resources[0].flags = res->flags; dwc->xhci_resources[0].name = res->name; res->start += DWC3_GLOBALS_REGS_START; /* * Request memory region but exclude xHCI regs, * since it will be requested by the xhci-plat driver. */ regs = devm_ioremap_resource(dev, res); if (IS_ERR(regs)) return PTR_ERR(regs); spin_lock_init(&dwc->lock); platform_set_drvdata(pdev, dwc); dwc->regs = regs; dwc->regs_size = resource_size(res); dwc->dev = dev; dev->dma_mask = dev->parent->dma_mask; dev->dma_parms = dev->parent->dma_parms; dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); pm_runtime_enable(dev); pm_runtime_get_sync(dev); pm_runtime_forbid(dev); dwc3_cache_hwparams(dwc); ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); if (ret) { dev_err(dwc->dev, "failed to allocate event buffers\n"); ret = -ENOMEM; goto err0; } if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) dwc->dr_mode = USB_DR_MODE_HOST; else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) dwc->dr_mode = USB_DR_MODE_PERIPHERAL; if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) dwc->dr_mode = USB_DR_MODE_OTG; ret = dwc3_core_init(dwc); if (ret) { dev_err(dev, "failed to initialize core\n"); goto err0; } usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); if (ret < 0) goto err1; ret = phy_power_on(dwc->usb3_generic_phy); if (ret < 0) goto err_usb2phy_power; ret = dwc3_event_buffers_setup(dwc); if (ret) { dev_err(dwc->dev, "failed to setup event buffers\n"); goto err_usb3phy_power; } switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); ret = dwc3_gadget_init(dwc); if (ret) { dev_err(dev, "failed to initialize gadget\n"); goto err2; } break; case USB_DR_MODE_HOST: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); ret = dwc3_host_init(dwc); if (ret) { dev_err(dev, "failed to initialize host\n"); goto err2; } break; case USB_DR_MODE_OTG: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG); ret = dwc3_host_init(dwc); if (ret) { dev_err(dev, "failed to initialize host\n"); goto err2; } ret = dwc3_gadget_init(dwc); if (ret) { dev_err(dev, "failed to initialize gadget\n"); goto err2; } break; default: dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode); goto err2; } ret = dwc3_debugfs_init(dwc); if (ret) { dev_err(dev, "failed to initialize debugfs\n"); goto err3; } pm_runtime_allow(dev); return 0; err3: switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: dwc3_gadget_exit(dwc); break; case USB_DR_MODE_HOST: dwc3_host_exit(dwc); break; case USB_DR_MODE_OTG: dwc3_host_exit(dwc); dwc3_gadget_exit(dwc); break; default: /* do nothing */ break; } err2: dwc3_event_buffers_cleanup(dwc); err_usb3phy_power: phy_power_off(dwc->usb3_generic_phy); err_usb2phy_power: phy_power_off(dwc->usb2_generic_phy); err1: usb_phy_set_suspend(dwc->usb2_phy, 1); usb_phy_set_suspend(dwc->usb3_phy, 1); dwc3_core_exit(dwc); err0: dwc3_free_event_buffers(dwc); return ret; }
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; }
static int axp288_extcon_probe(struct platform_device *pdev) { struct axp288_extcon_info *info; struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); int ret, i, pirq, gpio; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; info->dev = &pdev->dev; info->regmap = axp20x->regmap; info->regmap_irqc = axp20x->regmap_irqc; info->pdata = pdev->dev.platform_data; if (!info->pdata) { /* Try ACPI provided pdata via device properties */ if (!device_property_present(&pdev->dev, "axp288_extcon_data\n")) dev_err(&pdev->dev, "failed to get platform data\n"); return -ENODEV; } platform_set_drvdata(pdev, info); axp288_extcon_log_rsi(info); /* Initialize extcon device */ info->edev = devm_extcon_dev_allocate(&pdev->dev, axp288_extcon_cables); if (IS_ERR(info->edev)) { dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); return PTR_ERR(info->edev); } /* Register extcon device */ ret = devm_extcon_dev_register(&pdev->dev, info->edev); if (ret) { dev_err(&pdev->dev, "failed to register extcon device\n"); return ret; } /* Get otg transceiver phy */ info->otg = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR(info->otg)) { dev_err(&pdev->dev, "failed to get otg transceiver\n"); return PTR_ERR(info->otg); } /* Set up gpio control for USB Mux */ if (info->pdata->gpio_mux_cntl) { gpio = desc_to_gpio(info->pdata->gpio_mux_cntl); ret = devm_gpio_request(&pdev->dev, gpio, "USB_MUX"); if (ret < 0) { dev_err(&pdev->dev, "failed to request the gpio=%d\n", gpio); return ret; } gpiod_direction_output(info->pdata->gpio_mux_cntl, EXTCON_GPIO_MUX_SEL_PMIC); } for (i = 0; i < EXTCON_IRQ_END; i++) { pirq = platform_get_irq(pdev, i); info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); if (info->irq[i] < 0) { dev_err(&pdev->dev, "failed to get virtual interrupt=%d\n", pirq); ret = info->irq[i]; return ret; } ret = devm_request_threaded_irq(&pdev->dev, info->irq[i], NULL, axp288_extcon_isr, IRQF_ONESHOT | IRQF_NO_SUSPEND, pdev->name, info); if (ret) { dev_err(&pdev->dev, "failed to request interrupt=%d\n", info->irq[i]); return ret; } } /* Enable interrupts */ axp288_extcon_enable_irq(info); return 0; }
static int dwc3_core_get_phy(struct dwc3 *dwc) { struct device *dev = dwc->dev; struct device_node *node = dev->of_node; int ret; if (node) { dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1); } else { dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); } if (IS_ERR(dwc->usb2_phy)) { ret = PTR_ERR(dwc->usb2_phy); if (ret == -ENXIO || ret == -ENODEV) { dwc->usb2_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb2 phy configured\n"); return ret; } } if (IS_ERR(dwc->usb3_phy)) { ret = PTR_ERR(dwc->usb3_phy); if (ret == -ENXIO || ret == -ENODEV) { dwc->usb3_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb3 phy configured\n"); return ret; } } dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy"); if (IS_ERR(dwc->usb2_generic_phy)) { ret = PTR_ERR(dwc->usb2_generic_phy); if (ret == -ENOSYS || ret == -ENODEV) { dwc->usb2_generic_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb2 phy configured\n"); return ret; } } dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy"); if (IS_ERR(dwc->usb3_generic_phy)) { ret = PTR_ERR(dwc->usb3_generic_phy); if (ret == -ENOSYS || ret == -ENODEV) { dwc->usb3_generic_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb3 phy configured\n"); return ret; } } return 0; }
static int tegra_ehci_probe(struct platform_device *pdev) { struct resource *res; struct usb_hcd *hcd; struct tegra_ehci_hcd *tegra; struct tegra_usb_platform_data *pdata; int err = 0; int irq; int instance = pdev->id; /* 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 have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &tegra_ehci_dma_mask; pdata = dev_get_platdata(&pdev->dev); tegra = devm_kzalloc(&pdev->dev, sizeof(struct tegra_ehci_hcd), GFP_KERNEL); if (!tegra) { dev_err(&pdev->dev, "memory alloc failed\n"); return -ENOMEM; } mutex_init(&tegra->sync_lock); hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "unable to create HCD\n"); return -ENOMEM; } platform_set_drvdata(pdev, tegra); #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ tegra->boost_requested = false; /* Add boost enable/disable knob */ tegra->boost_enable = true; err = device_create_file(hcd->self.controller, &dev_attr_boost_enable); if (err < 0) goto fail_sysfs; #endif 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, resource_size(res)); if (!hcd->regs) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); err = -ENOMEM; goto fail_io; } /* This is pretty ugly and needs to be fixed when we do only * device-tree probing. Old code relies on the platform_device * numbering that we lack for device-tree-instantiated devices. */ if (instance < 0) { switch (res->start) { case TEGRA_USB_BASE: instance = 0; break; case TEGRA_USB2_BASE: instance = 1; break; case TEGRA_USB3_BASE: instance = 2; break; default: err = -ENODEV; dev_err(&pdev->dev, "unknown usb instance\n"); goto fail_io; } } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "failed to get IRQ\n"); err = -ENODEV; goto fail_io; } tegra->irq = irq; tegra->unaligned_dma_buf_supported = pdata->unaligned_dma_buf_supported; tegra->has_hostpc = pdata->has_hostpc; tegra->phy = tegra_usb_phy_open(pdev); hcd->phy = get_usb_phy(tegra->phy); if (IS_ERR(tegra->phy)) { dev_err(&pdev->dev, "failed to open USB phy\n"); err = -ENXIO; goto fail_io; } err = tegra_usb_phy_power_on(tegra->phy); if (err) { dev_err(&pdev->dev, "failed to power on the phy\n"); goto fail_phy; } err = usb_phy_init(get_usb_phy(tegra->phy)); if (err) { dev_err(&pdev->dev, "failed to init the phy\n"); goto fail_phy; } err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_TRIGGER_HIGH); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD, error=%d\n", err); goto fail_phy; } tegra->ehci = hcd_to_ehci(hcd); if (pdata->port_otg) { tegra->transceiver = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (!IS_ERR_OR_NULL(tegra->transceiver)) otg_set_host(tegra->transceiver->otg, &hcd->self); } tegra_pd_add_device(&pdev->dev); pm_runtime_enable(&pdev->dev); #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ INIT_DELAYED_WORK(&tegra->boost_cpu_freq_work, tegra_ehci_boost_cpu_frequency_work); pm_qos_add_request(&tegra->boost_cpu_freq_req, PM_QOS_CPU_FREQ_MIN, PM_QOS_DEFAULT_VALUE); schedule_delayed_work(&tegra->boost_cpu_freq_work, 12000); tegra->cpu_boost_in_work = true; #endif wake_lock_init(&tegra->ehci_wake_lock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev)); return err; fail_phy: usb_phy_shutdown(get_usb_phy(tegra->phy)); fail_io: #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ device_remove_file(hcd->self.controller, &dev_attr_boost_enable); fail_sysfs: #endif usb_put_hcd(hcd); return err; }
static int pmic_usb_det_drv_probe(struct platform_device *pdev) { struct pmic_usb_det_data *pdata; struct usb_phy *otg_handle; int ret; if (!pdev) return -EINVAL; pdata = devm_kzalloc(&pdev->dev, sizeof(struct pmic_usb_det_data), GFP_KERNEL); if (!pdata) { dev_err(&pdev->dev, "%s: out of memory\n", __func__); return -ENOMEM; } pdata->pdev = &pdev->dev; pdata->vbus_state = -1; pdata->cable_type = POWER_SUPPLY_CHARGER_TYPE_NONE; pdata->usbid_state = -1; pdata->irq_ctyp = -ENXIO; pdata->irq_vbusdet = -ENXIO; pdata->irqwake_vbusdet = false; pdata->irqwake_ctyp = false; pdata->irqwake_idflt = false; pdata->irqwake_idgnd = false; platform_set_drvdata(pdev, pdata); /* Get USB phy */ otg_handle = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(otg_handle)) { dev_err(&pdev->dev, "%s: fail to get OTG transceiver\n", __func__); return -EBUSY; } pdata->otg_handle = otg_handle; /* Get interrupt from device tree */ pdata->irq_vbusdet = platform_get_irq_byname(pdev, "vbusdet"); pdata->irq_ctyp = platform_get_irq_byname(pdev, "ctype"); pdata->irq_idflt = platform_get_irq_byname(pdev, "usbidflt"); pdata->irq_idgnd = platform_get_irq_byname(pdev, "usbidgnd"); if (IS_ERR_VALUE(pdata->irq_vbusdet) || IS_ERR_VALUE(pdata->irq_ctyp) || IS_ERR_VALUE(pdata->irq_idflt) || IS_ERR_VALUE(pdata->irq_idgnd)) { ret = -EBUSY; dev_err(&pdev->dev, "%s: can't get irq, vbus=%d ctyp=%d idflt=%d idgnd=%d\n", __func__, pdata->irq_vbusdet, pdata->irq_ctyp, pdata->irq_idflt, pdata->irq_idgnd); return ret; } ret = pmic_usb_setup_det_irq(pdata); if (ret) return ret; /* Disable the internal detection circuit */ ret = pmic_usb_enable_usb_det(pdata, false); if (ret) return ret; /* Read the VBUS presence status for initial update, and trigger USB type detection if applicable */ ret = pmic_usb_vbus_det(pdata); if (ret) return ret; /* Enable USBID and ACA detection */ ret = pmic_usb_enable_id_aca_det(pdata, true, true); if (ret) return ret; /* Read the USBID and ACA detection result */ ret = pmic_usb_id_det(pdata, false, false); if (ret) return ret; ret = device_init_wakeup(&pdev->dev, true); if (ret) dev_err(&pdev->dev, "%s: can't set wakeup src\n", __func__); return ret; }