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 exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) { struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); u32 phy_base; int ret = 0; dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); if (!dp_phy_node) { dp->phy = devm_phy_get(dp->dev, "dp"); return PTR_ERR_OR_ZERO(dp->phy); } if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) { dev_err(dp->dev, "failed to get reg for dptx-phy\n"); ret = -EINVAL; goto err; } if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", &dp->enable_mask)) { dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); ret = -EINVAL; goto err; } dp->phy_addr = ioremap(phy_base, SZ_4); if (!dp->phy_addr) { dev_err(dp->dev, "failed to ioremap dp-phy\n"); ret = -ENOMEM; goto err; } err: of_node_put(dp_phy_node); return ret; }
static int msm_ahci_init_phy(struct msm_ahci_host *host) { int ret = 0; struct device *dev = host->ahci_pdev->dev.parent; host->phy = devm_phy_get(dev, "sata-6g"); if (IS_ERR(host->phy)) { ret = PTR_ERR(host->phy); dev_err(dev, "PHY get failed %d\n", ret); goto out; } ret = phy_init(host->phy); if (ret) { dev_err(dev, "PHY initialization failed %d\n", ret); goto out; } ret = phy_power_on(host->phy); if (ret) { dev_err(dev, "PHY power on failed %d\n", ret); goto out; } host->phy_powered_on = true; /* asic0 and rbc0 clks needs to be ungated only after phy power on */ ret = msm_ahci_setup_asic_rbc_clks(host, true); if (ret) { dev_err(dev, "failed to enable asic0/rbc0 clks %d", ret); goto out; } out: return ret; }
static int histb_pcie_probe(struct platform_device *pdev) { struct histb_pcie *hipcie; struct dw_pcie *pci; struct pcie_port *pp; struct resource *res; struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev; enum of_gpio_flags of_flags; unsigned long flag = GPIOF_DIR_OUT; int ret; hipcie = devm_kzalloc(dev, sizeof(*hipcie), GFP_KERNEL); if (!hipcie) return -ENOMEM; pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); if (!pci) return -ENOMEM; hipcie->pci = pci; pp = &pci->pp; pci->dev = dev; pci->ops = &dw_pcie_ops; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control"); hipcie->ctrl = devm_ioremap_resource(dev, res); if (IS_ERR(hipcie->ctrl)) { dev_err(dev, "cannot get control reg base\n"); return PTR_ERR(hipcie->ctrl); } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc-dbi"); pci->dbi_base = devm_ioremap_resource(dev, res); if (IS_ERR(pci->dbi_base)) { dev_err(dev, "cannot get rc-dbi base\n"); return PTR_ERR(pci->dbi_base); } hipcie->vpcie = devm_regulator_get_optional(dev, "vpcie"); if (IS_ERR(hipcie->vpcie)) { if (PTR_ERR(hipcie->vpcie) == -EPROBE_DEFER) return -EPROBE_DEFER; hipcie->vpcie = NULL; } hipcie->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &of_flags); if (of_flags & OF_GPIO_ACTIVE_LOW) flag |= GPIOF_ACTIVE_LOW; if (gpio_is_valid(hipcie->reset_gpio)) { ret = devm_gpio_request_one(dev, hipcie->reset_gpio, flag, "PCIe device power control"); if (ret) { dev_err(dev, "unable to request gpio\n"); return ret; } } hipcie->aux_clk = devm_clk_get(dev, "aux"); if (IS_ERR(hipcie->aux_clk)) { dev_err(dev, "Failed to get PCIe aux clk\n"); return PTR_ERR(hipcie->aux_clk); } hipcie->pipe_clk = devm_clk_get(dev, "pipe"); if (IS_ERR(hipcie->pipe_clk)) { dev_err(dev, "Failed to get PCIe pipe clk\n"); return PTR_ERR(hipcie->pipe_clk); } hipcie->sys_clk = devm_clk_get(dev, "sys"); if (IS_ERR(hipcie->sys_clk)) { dev_err(dev, "Failed to get PCIEe sys clk\n"); return PTR_ERR(hipcie->sys_clk); } hipcie->bus_clk = devm_clk_get(dev, "bus"); if (IS_ERR(hipcie->bus_clk)) { dev_err(dev, "Failed to get PCIe bus clk\n"); return PTR_ERR(hipcie->bus_clk); } hipcie->soft_reset = devm_reset_control_get(dev, "soft"); if (IS_ERR(hipcie->soft_reset)) { dev_err(dev, "couldn't get soft reset\n"); return PTR_ERR(hipcie->soft_reset); } hipcie->sys_reset = devm_reset_control_get(dev, "sys"); if (IS_ERR(hipcie->sys_reset)) { dev_err(dev, "couldn't get sys reset\n"); return PTR_ERR(hipcie->sys_reset); } hipcie->bus_reset = devm_reset_control_get(dev, "bus"); if (IS_ERR(hipcie->bus_reset)) { dev_err(dev, "couldn't get bus reset\n"); return PTR_ERR(hipcie->bus_reset); } if (IS_ENABLED(CONFIG_PCI_MSI)) { pp->msi_irq = platform_get_irq_byname(pdev, "msi"); if (pp->msi_irq < 0) { dev_err(dev, "Failed to get MSI IRQ\n"); return pp->msi_irq; } } hipcie->phy = devm_phy_get(dev, "phy"); if (IS_ERR(hipcie->phy)) { dev_info(dev, "no pcie-phy found\n"); hipcie->phy = NULL; /* fall through here! * if no pcie-phy found, phy init * should be done under boot! */ } else { phy_init(hipcie->phy); } pp->root_bus_nr = -1; pp->ops = &histb_pcie_host_ops; platform_set_drvdata(pdev, hipcie); ret = histb_pcie_host_enable(pp); if (ret) { dev_err(dev, "failed to enable host\n"); return ret; } ret = dw_pcie_host_init(pp); if (ret) { dev_err(dev, "failed to initialize host\n"); return ret; } return 0; }
static int ohci_da8xx_probe(struct platform_device *pdev) { struct da8xx_ohci_hcd *da8xx_ohci; struct usb_hcd *hcd; struct resource *mem; int error, irq; hcd = usb_create_hcd(&ohci_da8xx_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) return -ENOMEM; da8xx_ohci = to_da8xx_ohci(hcd); da8xx_ohci->hcd = hcd; da8xx_ohci->usb11_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(da8xx_ohci->usb11_clk)) { error = PTR_ERR(da8xx_ohci->usb11_clk); if (error != -EPROBE_DEFER) dev_err(&pdev->dev, "Failed to get clock.\n"); goto err; } da8xx_ohci->usb11_phy = devm_phy_get(&pdev->dev, "usb-phy"); if (IS_ERR(da8xx_ohci->usb11_phy)) { error = PTR_ERR(da8xx_ohci->usb11_phy); if (error != -EPROBE_DEFER) dev_err(&pdev->dev, "Failed to get phy.\n"); goto err; } da8xx_ohci->vbus_reg = devm_regulator_get_optional(&pdev->dev, "vbus"); if (IS_ERR(da8xx_ohci->vbus_reg)) { error = PTR_ERR(da8xx_ohci->vbus_reg); if (error == -ENODEV) { da8xx_ohci->vbus_reg = NULL; } else if (error == -EPROBE_DEFER) { goto err; } else { dev_err(&pdev->dev, "Failed to get regulator\n"); goto err; } } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(hcd->regs)) { error = PTR_ERR(hcd->regs); goto err; } hcd->rsrc_start = mem->start; hcd->rsrc_len = resource_size(mem); irq = platform_get_irq(pdev, 0); if (irq < 0) { error = -ENODEV; goto err; } error = usb_add_hcd(hcd, irq, 0); if (error) goto err; device_wakeup_enable(hcd->self.controller); error = ohci_da8xx_register_notify(hcd); if (error) goto err_remove_hcd; return 0; err_remove_hcd: usb_remove_hcd(hcd); err: usb_put_hcd(hcd); return error; }
static int spear13xx_pcie_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct spear13xx_pcie *spear13xx_pcie; struct pcie_port *pp; struct device_node *np = dev->of_node; struct resource *dbi_base; int ret; spear13xx_pcie = devm_kzalloc(dev, sizeof(*spear13xx_pcie), GFP_KERNEL); if (!spear13xx_pcie) return -ENOMEM; spear13xx_pcie->phy = devm_phy_get(dev, "pcie-phy"); if (IS_ERR(spear13xx_pcie->phy)) { ret = PTR_ERR(spear13xx_pcie->phy); if (ret == -EPROBE_DEFER) dev_info(dev, "probe deferred\n"); else dev_err(dev, "couldn't get pcie-phy\n"); return ret; } phy_init(spear13xx_pcie->phy); spear13xx_pcie->clk = devm_clk_get(dev, NULL); if (IS_ERR(spear13xx_pcie->clk)) { dev_err(dev, "couldn't get clk for pcie\n"); return PTR_ERR(spear13xx_pcie->clk); } ret = clk_prepare_enable(spear13xx_pcie->clk); if (ret) { dev_err(dev, "couldn't enable clk for pcie\n"); return ret; } pp = &spear13xx_pcie->pp; pp->dev = dev; dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); pp->dbi_base = devm_ioremap_resource(dev, dbi_base); if (IS_ERR(pp->dbi_base)) { dev_err(dev, "couldn't remap dbi base %p\n", dbi_base); ret = PTR_ERR(pp->dbi_base); goto fail_clk; } spear13xx_pcie->app_base = pp->dbi_base + 0x2000; if (of_property_read_bool(np, "st,pcie-is-gen1")) spear13xx_pcie->is_gen1 = true; ret = spear13xx_add_pcie_port(spear13xx_pcie, pdev); if (ret < 0) goto fail_clk; platform_set_drvdata(pdev, spear13xx_pcie); return 0; fail_clk: clk_disable_unprepare(spear13xx_pcie->clk); return ret; }
static int ahci_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ahci_platform_data *pdata = dev_get_platdata(dev); const struct platform_device_id *id = platform_get_device_id(pdev); struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0]; const struct ata_port_info *ppi[] = { &pi, NULL }; struct ahci_host_priv *hpriv; struct ata_host *host; struct resource *mem; int irq; int n_ports; int i; int rc; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(dev, "no mmio space\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); if (irq <= 0) { dev_err(dev, "no irq\n"); return -EINVAL; } if (pdata && pdata->ata_port_info) pi = *pdata->ata_port_info; hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) { dev_err(dev, "can't alloc ahci_host_priv\n"); return -ENOMEM; } hpriv->flags |= (unsigned long)pi.private_data; hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); if (!hpriv->mmio) { dev_err(dev, "can't map %pR\n", mem); return -ENOMEM; } hpriv->clk = clk_get(dev, NULL); if (IS_ERR(hpriv->clk)) { dev_err(dev, "can't get clock\n"); } else { rc = clk_prepare_enable(hpriv->clk); if (rc) { dev_err(dev, "clock prepare enable failed"); goto free_clk; } } hpriv->phy = devm_phy_get(dev, "sata-phy"); if (IS_ERR(hpriv->phy)) { dev_dbg(dev, "can't get sata-phy\n"); /* return only if -EPROBE_DEFER */ if (PTR_ERR(hpriv->phy) == -EPROBE_DEFER) { rc = -EPROBE_DEFER; goto disable_unprepare_clk; } } if (!IS_ERR(hpriv->phy)) { phy_init(hpriv->phy); phy_power_on(hpriv->phy); } /* * Some platforms might need to prepare for mmio region access, * which could be done in the following init call. So, the mmio * region shouldn't be accessed before init (if provided) has * returned successfully. */ if (pdata && pdata->init) { rc = pdata->init(dev, hpriv->mmio); if (rc) goto disable_phy; } ahci_save_initial_config(dev, hpriv, pdata ? pdata->force_port_map : 0, pdata ? pdata->mask_port_map : 0); /* prepare host */ if (hpriv->cap & HOST_CAP_NCQ) pi.flags |= ATA_FLAG_NCQ; if (hpriv->cap & HOST_CAP_PMP) pi.flags |= ATA_FLAG_PMP; ahci_set_em_messages(hpriv, &pi); /* CAP.NP sometimes indicate the index of the last enabled * port, at other times, that of the last possible port, so * determining the maximum port number requires looking at * both CAP.NP and port_map. */ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); host = ata_host_alloc_pinfo(dev, ppi, n_ports); if (!host) { rc = -ENOMEM; goto pdata_exit; } host->private_data = hpriv; if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) host->flags |= ATA_HOST_PARALLEL_SCAN; else dev_info(dev, "SSS flag set, parallel bus scan disabled\n"); if (pi.flags & ATA_FLAG_EM) ahci_reset_em(host); for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; ata_port_desc(ap, "mmio %pR", mem); ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80); /* set enclosure management message type */ if (ap->flags & ATA_FLAG_EM) ap->em_message_type = hpriv->em_msg_type; /* disabled/not-implemented port */ if (!(hpriv->port_map & (1 << i))) ap->ops = &ata_dummy_port_ops; } rc = ahci_reset_controller(host); if (rc) goto pdata_exit; ahci_init_controller(host); ahci_print_info(host, "platform"); rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, &ahci_platform_sht); if (rc) goto pdata_exit; return 0; pdata_exit: if (pdata && pdata->exit) pdata->exit(dev); disable_phy: if (!IS_ERR(hpriv->phy)) { phy_power_off(hpriv->phy); phy_exit(hpriv->phy); } disable_unprepare_clk: if (!IS_ERR(hpriv->clk)) clk_disable_unprepare(hpriv->clk); free_clk: if (!IS_ERR(hpriv->clk)) clk_put(hpriv->clk); return rc; }
static int exynos_dp_bind(struct device *dev, struct device *master, void *data) { struct exynos_dp_device *dp = dev_get_drvdata(dev); struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm_dev = data; struct resource *res; unsigned int irq_flags; int ret = 0; dp->dev = &pdev->dev; dp->dpms_mode = DRM_MODE_DPMS_OFF; dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev); if (IS_ERR(dp->video_info)) return PTR_ERR(dp->video_info); dp->phy = devm_phy_get(dp->dev, "dp"); if (IS_ERR(dp->phy)) { dev_err(dp->dev, "no DP phy configured\n"); ret = PTR_ERR(dp->phy); if (ret) { /* * phy itself is not enabled, so we can move forward * assigning NULL to phy pointer. */ if (ret == -ENOSYS || ret == -ENODEV) dp->phy = NULL; else return ret; } } if (!dp->panel) { ret = exynos_dp_dt_parse_panel(dp); if (ret) return ret; } dp->clock = devm_clk_get(&pdev->dev, "dp"); if (IS_ERR(dp->clock)) { dev_err(&pdev->dev, "failed to get clock\n"); return PTR_ERR(dp->clock); } clk_prepare_enable(dp->clock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dp->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dp->reg_base)) return PTR_ERR(dp->reg_base); dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0); if (gpio_is_valid(dp->hpd_gpio)) { /* * Set up the hotplug GPIO from the device tree as an interrupt. * Simply specifying a different interrupt in the device tree * doesn't work since we handle hotplug rather differently when * using a GPIO. We also need the actual GPIO specifier so * that we can get the current state of the GPIO. */ ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN, "hpd_gpio"); if (ret) { dev_err(&pdev->dev, "failed to get hpd gpio\n"); return ret; } dp->irq = gpio_to_irq(dp->hpd_gpio); irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; } else { dp->hpd_gpio = -ENODEV; dp->irq = platform_get_irq(pdev, 0); irq_flags = 0; } if (dp->irq == -ENXIO) { dev_err(&pdev->dev, "failed to get irq\n"); return -ENODEV; } INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug); exynos_dp_phy_init(dp); exynos_dp_init_dp(dp); ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, irq_flags, "exynos-dp", dp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); return ret; } disable_irq(dp->irq); dp->drm_dev = drm_dev; return exynos_drm_create_enc_conn(drm_dev, &dp->display); }
static int dsps_musb_init(struct musb *musb) { struct device *dev = musb->controller; struct dsps_glue *glue = dev_get_drvdata(dev->parent); struct platform_device *parent = to_platform_device(dev->parent); const struct dsps_musb_wrapper *wrp = glue->wrp; void __iomem *reg_base; struct resource *r; u32 rev, val; int ret; r = platform_get_resource_byname(parent, IORESOURCE_MEM, "control"); reg_base = devm_ioremap_resource(dev, r); if (IS_ERR(reg_base)) return PTR_ERR(reg_base); musb->ctrl_base = reg_base; /* NOP driver needs change if supporting dual instance */ musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, "phys", 0); if (IS_ERR(musb->xceiv)) return PTR_ERR(musb->xceiv); musb->phy = devm_phy_get(dev->parent, "usb2-phy"); /* Returns zero if e.g. not clocked */ rev = musb_readl(reg_base, wrp->revision); if (!rev) return -ENODEV; if (IS_ERR(musb->phy)) { musb->phy = NULL; } else { ret = phy_init(musb->phy); if (ret < 0) return ret; ret = phy_power_on(musb->phy); if (ret) { phy_exit(musb->phy); return ret; } } timer_setup(&musb->dev_timer, otg_timer, 0); /* Reset the musb */ musb_writel(reg_base, wrp->control, (1 << wrp->reset)); musb->isr = dsps_interrupt; /* reset the otgdisable bit, needed for host mode to work */ val = musb_readl(reg_base, wrp->phy_utmi); val &= ~(1 << wrp->otg_disable); musb_writel(musb->ctrl_base, wrp->phy_utmi, val); /* * Check whether the dsps version has babble control enabled. * In latest silicon revision the babble control logic is enabled. * If MUSB_BABBLE_CTL returns 0x4 then we have the babble control * logic enabled. */ val = musb_readb(musb->mregs, MUSB_BABBLE_CTL); if (val & MUSB_BABBLE_RCV_DISABLE) { glue->sw_babble_enabled = true; val |= MUSB_BABBLE_SW_SESSION_CTRL; musb_writeb(musb->mregs, MUSB_BABBLE_CTL, val); } dsps_mod_timer(glue, -1); return dsps_musb_dbg_init(musb, glue); }
static int st_ehci_platform_probe(struct platform_device *dev) { struct usb_hcd *hcd; struct resource *res_mem; struct usb_ehci_pdata *pdata = &ehci_platform_defaults; struct st_ehci_platform_priv *priv; struct ehci_hcd *ehci; int err, irq, clk = 0; if (usb_disabled()) return -ENODEV; irq = platform_get_irq(dev, 0); if (irq < 0) { dev_err(&dev->dev, "no irq provided"); return irq; } res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res_mem) { dev_err(&dev->dev, "no memory resource provided"); return -ENXIO; } hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, dev_name(&dev->dev)); if (!hcd) return -ENOMEM; platform_set_drvdata(dev, hcd); dev->dev.platform_data = pdata; priv = hcd_to_ehci_priv(hcd); ehci = hcd_to_ehci(hcd); priv->phy = devm_phy_get(&dev->dev, "usb"); if (IS_ERR(priv->phy)) { err = PTR_ERR(priv->phy); goto err_put_hcd; } for (clk = 0; clk < USB_MAX_CLKS; clk++) { priv->clks[clk] = of_clk_get(dev->dev.of_node, clk); if (IS_ERR(priv->clks[clk])) { err = PTR_ERR(priv->clks[clk]); if (err == -EPROBE_DEFER) goto err_put_clks; priv->clks[clk] = NULL; break; } } /* some SoCs don't have a dedicated 48Mhz clock, but those that do need the rate to be explicitly set */ priv->clk48 = devm_clk_get(&dev->dev, "clk48"); if (IS_ERR(priv->clk48)) { dev_info(&dev->dev, "48MHz clk not found\n"); priv->clk48 = NULL; } priv->pwr = devm_reset_control_get_optional(&dev->dev, "power"); if (IS_ERR(priv->pwr)) { err = PTR_ERR(priv->pwr); if (err == -EPROBE_DEFER) goto err_put_clks; priv->pwr = NULL; } priv->rst = devm_reset_control_get_optional(&dev->dev, "softreset"); if (IS_ERR(priv->rst)) { err = PTR_ERR(priv->rst); if (err == -EPROBE_DEFER) goto err_put_clks; priv->rst = NULL; } if (pdata->power_on) { err = pdata->power_on(dev); if (err < 0) goto err_put_clks; } hcd->rsrc_start = res_mem->start; hcd->rsrc_len = resource_size(res_mem); hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto err_put_clks; } err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) goto err_put_clks; device_wakeup_enable(hcd->self.controller); platform_set_drvdata(dev, hcd); return err; err_put_clks: while (--clk >= 0) clk_put(priv->clks[clk]); err_put_hcd: if (pdata == &ehci_platform_defaults) dev->dev.platform_data = NULL; usb_put_hcd(hcd); return err; }
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 __init dra7xx_pcie_probe(struct platform_device *pdev) { u32 reg; int ret; int irq; int i; int phy_count; struct phy **phy; void __iomem *base; struct resource *res; struct dra7xx_pcie *dra7xx; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; char name[10]; dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); if (!dra7xx) return -ENOMEM; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "missing IRQ resource\n"); return -EINVAL; } ret = devm_request_irq(dev, irq, dra7xx_pcie_irq_handler, IRQF_SHARED, "dra7xx-pcie-main", dra7xx); if (ret) { dev_err(dev, "failed to request irq\n"); return ret; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf"); base = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!base) return -ENOMEM; phy_count = of_property_count_strings(np, "phy-names"); if (phy_count < 0) { dev_err(dev, "unable to find the strings\n"); return phy_count; } phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL); if (!phy) return -ENOMEM; for (i = 0; i < phy_count; i++) { snprintf(name, sizeof(name), "pcie-phy%d", i); phy[i] = devm_phy_get(dev, name); if (IS_ERR(phy[i])) return PTR_ERR(phy[i]); ret = phy_init(phy[i]); if (ret < 0) goto err_phy; ret = phy_power_on(phy[i]); if (ret < 0) { phy_exit(phy[i]); goto err_phy; } } dra7xx->base = base; dra7xx->phy = phy; dra7xx->dev = dev; dra7xx->phy_count = phy_count; pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (IS_ERR_VALUE(ret)) { dev_err(dev, "pm_runtime_get_sync failed\n"); goto err_phy; } reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD); reg &= ~LTSSM_EN; dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); platform_set_drvdata(pdev, dra7xx); ret = add_pcie_port(dra7xx, pdev); if (ret < 0) goto err_add_port; return 0; err_add_port: pm_runtime_put(dev); pm_runtime_disable(dev); err_phy: while (--i >= 0) { phy_power_off(phy[i]); phy_exit(phy[i]); } return ret; }
static int exynos_dp_bind(struct device *dev, struct device *master, void *data) { struct exynos_dp_device *dp = dev_get_drvdata(dev); struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm_dev = data; struct drm_encoder *encoder = &dp->encoder; struct resource *res; unsigned int irq_flags; int pipe, ret = 0; dp->dev = &pdev->dev; dp->dpms_mode = DRM_MODE_DPMS_OFF; dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev); if (IS_ERR(dp->video_info)) return PTR_ERR(dp->video_info); dp->phy = devm_phy_get(dp->dev, "dp"); if (IS_ERR(dp->phy)) { dev_err(dp->dev, "no DP phy configured\n"); ret = PTR_ERR(dp->phy); if (ret) { /* * phy itself is not enabled, so we can move forward * assigning NULL to phy pointer. */ if (ret == -ENOSYS || ret == -ENODEV) dp->phy = NULL; else return ret; } } if (!dp->panel && !dp->ptn_bridge) { ret = exynos_dp_dt_parse_panel(dp); if (ret) return ret; } dp->clock = devm_clk_get(&pdev->dev, "dp"); if (IS_ERR(dp->clock)) { dev_err(&pdev->dev, "failed to get clock\n"); return PTR_ERR(dp->clock); } clk_prepare_enable(dp->clock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dp->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dp->reg_base)) return PTR_ERR(dp->reg_base); dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0); if (gpio_is_valid(dp->hpd_gpio)) { /* * Set up the hotplug GPIO from the device tree as an interrupt. * Simply specifying a different interrupt in the device tree * doesn't work since we handle hotplug rather differently when * using a GPIO. We also need the actual GPIO specifier so * that we can get the current state of the GPIO. */ ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN, "hpd_gpio"); if (ret) { dev_err(&pdev->dev, "failed to get hpd gpio\n"); return ret; } dp->irq = gpio_to_irq(dp->hpd_gpio); irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; } else { dp->hpd_gpio = -ENODEV; dp->irq = platform_get_irq(pdev, 0); irq_flags = 0; } if (dp->irq == -ENXIO) { dev_err(&pdev->dev, "failed to get irq\n"); return -ENODEV; } INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug); ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, irq_flags, "exynos-dp", dp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); return ret; } disable_irq(dp->irq); dp->drm_dev = drm_dev; pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev, EXYNOS_DISPLAY_TYPE_LCD); if (pipe < 0) return pipe; encoder->possible_crtcs = 1 << pipe; DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs); ret = exynos_dp_create_connector(encoder); if (ret) { DRM_ERROR("failed to create connector ret = %d\n", ret); drm_encoder_cleanup(encoder); return ret; } return 0; }
static int da8xx_probe(struct platform_device *pdev) { struct resource musb_resources[2]; struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); struct da8xx_glue *glue; struct platform_device_info pinfo; struct clk *clk; struct device_node *np = pdev->dev.of_node; int ret; glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); if (!glue) return -ENOMEM; clk = devm_clk_get(&pdev->dev, "usb20"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "failed to get clock\n"); return PTR_ERR(clk); } glue->phy = devm_phy_get(&pdev->dev, "usb-phy"); if (IS_ERR(glue->phy)) { if (PTR_ERR(glue->phy) != -EPROBE_DEFER) dev_err(&pdev->dev, "failed to get phy\n"); return PTR_ERR(glue->phy); } glue->dev = &pdev->dev; glue->clk = clk; if (IS_ENABLED(CONFIG_OF) && np) { pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; pdata->config = &da8xx_config; pdata->mode = musb_get_mode(&pdev->dev); pdata->power = get_vbus_power(&pdev->dev); } pdata->platform_ops = &da8xx_ops; glue->usb_phy = usb_phy_generic_register(); ret = PTR_ERR_OR_ZERO(glue->usb_phy); if (ret) { dev_err(&pdev->dev, "failed to register usb_phy\n"); return ret; } platform_set_drvdata(pdev, glue); memset(musb_resources, 0x00, sizeof(*musb_resources) * ARRAY_SIZE(musb_resources)); musb_resources[0].name = pdev->resource[0].name; musb_resources[0].start = pdev->resource[0].start; musb_resources[0].end = pdev->resource[0].end; musb_resources[0].flags = pdev->resource[0].flags; musb_resources[1].name = pdev->resource[1].name; musb_resources[1].start = pdev->resource[1].start; musb_resources[1].end = pdev->resource[1].end; musb_resources[1].flags = pdev->resource[1].flags; pinfo = da8xx_dev_info; pinfo.parent = &pdev->dev; pinfo.res = musb_resources; pinfo.num_res = ARRAY_SIZE(musb_resources); pinfo.data = pdata; pinfo.size_data = sizeof(*pdata); glue->musb = platform_device_register_full(&pinfo); ret = PTR_ERR_OR_ZERO(glue->musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); usb_phy_generic_unregister(glue->usb_phy); } return ret; }
int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, struct analogix_dp_plat_data *plat_data) { struct platform_device *pdev = to_platform_device(dev); struct analogix_dp_device *dp; struct resource *res; unsigned int irq_flags; int ret; if (!plat_data) { dev_err(dev, "Invalided input plat_data\n"); return -EINVAL; } dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL); if (!dp) return -ENOMEM; dev_set_drvdata(dev, dp); dp->dev = &pdev->dev; dp->dpms_mode = DRM_MODE_DPMS_OFF; mutex_init(&dp->panel_lock); dp->panel_is_modeset = false; /* * platform dp driver need containor_of the plat_data to get * the driver private data, so we need to store the point of * plat_data, not the context of plat_data. */ dp->plat_data = plat_data; ret = analogix_dp_dt_parse_pdata(dp); if (ret) return ret; dp->phy = devm_phy_get(dp->dev, "dp"); if (IS_ERR(dp->phy)) { dev_err(dp->dev, "no DP phy configured\n"); ret = PTR_ERR(dp->phy); if (ret) { /* * phy itself is not enabled, so we can move forward * assigning NULL to phy pointer. */ if (ret == -ENOSYS || ret == -ENODEV) dp->phy = NULL; else return ret; } } dp->clock = devm_clk_get(&pdev->dev, "dp"); if (IS_ERR(dp->clock)) { dev_err(&pdev->dev, "failed to get clock\n"); return PTR_ERR(dp->clock); } clk_prepare_enable(dp->clock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dp->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dp->reg_base)) return PTR_ERR(dp->reg_base); dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd"); dp->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpios", 0); if (!gpio_is_valid(dp->hpd_gpio)) dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0); if (gpio_is_valid(dp->hpd_gpio)) { /* * Set up the hotplug GPIO from the device tree as an interrupt. * Simply specifying a different interrupt in the device tree * doesn't work since we handle hotplug rather differently when * using a GPIO. We also need the actual GPIO specifier so * that we can get the current state of the GPIO. */ ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN, "hpd_gpio"); if (ret) { dev_err(&pdev->dev, "failed to get hpd gpio\n"); return ret; } dp->irq = gpio_to_irq(dp->hpd_gpio); irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; } else { dp->hpd_gpio = -ENODEV; dp->irq = platform_get_irq(pdev, 0); irq_flags = 0; } if (dp->irq == -ENXIO) { dev_err(&pdev->dev, "failed to get irq\n"); return -ENODEV; } pm_runtime_enable(dev); pm_runtime_get_sync(dev); phy_power_on(dp->phy); analogix_dp_init_dp(dp); ret = devm_request_threaded_irq(&pdev->dev, dp->irq, analogix_dp_hardirq, analogix_dp_irq_thread, irq_flags, "analogix-dp", dp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); goto err_disable_pm_runtime; } disable_irq(dp->irq); dp->drm_dev = drm_dev; dp->encoder = dp->plat_data->encoder; dp->aux.name = "DP-AUX"; dp->aux.transfer = analogix_dpaux_transfer; dp->aux.dev = &pdev->dev; ret = drm_dp_aux_register(&dp->aux); if (ret) goto err_disable_pm_runtime; ret = analogix_dp_create_bridge(drm_dev, dp); if (ret) { DRM_ERROR("failed to create bridge (%d)\n", ret); drm_encoder_cleanup(dp->encoder); goto err_disable_pm_runtime; } phy_power_off(dp->phy); pm_runtime_put(dev); return 0; err_disable_pm_runtime: phy_power_off(dp->phy); pm_runtime_put(dev); pm_runtime_disable(dev); return ret; }
static int omap2430_musb_init(struct musb *musb) { u32 l; int status = 0; struct device *dev = musb->controller; struct omap2430_glue *glue = dev_get_drvdata(dev->parent); struct musb_hdrc_platform_data *plat = dev_get_platdata(dev); struct omap_musb_board_data *data = plat->board_data; /* We require some kind of external transceiver, hooked * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ if (dev->parent->of_node) { musb->phy = devm_phy_get(dev->parent, "usb2-phy"); /* We can't totally remove musb->xceiv as of now because * musb core uses xceiv.state and xceiv.otg. Once we have * a separate state machine to handle otg, these can be moved * out of xceiv and then we can start using the generic PHY * framework */ musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0); } else { musb->xceiv = devm_usb_get_phy_dev(dev, 0); musb->phy = devm_phy_get(dev, "usb"); } if (IS_ERR(musb->xceiv)) { status = PTR_ERR(musb->xceiv); if (status == -ENXIO) return status; dev_dbg(dev, "HS USB OTG: no transceiver configured\n"); return -EPROBE_DEFER; } if (IS_ERR(musb->phy)) { dev_err(dev, "HS USB OTG: no PHY configured\n"); return PTR_ERR(musb->phy); } musb->isr = omap2430_musb_interrupt; phy_init(musb->phy); phy_power_on(musb->phy); l = musb_readl(musb->mregs, OTG_INTERFSEL); if (data->interface_type == MUSB_INTERFACE_UTMI) { /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */ l &= ~ULPI_12PIN; /* Disable ULPI */ l |= UTMI_8BIT; /* Enable UTMI */ } else { l |= ULPI_12PIN; } musb_writel(musb->mregs, OTG_INTERFSEL, l); dev_dbg(dev, "HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", musb_readl(musb->mregs, OTG_REVISION), musb_readl(musb->mregs, OTG_SYSCONFIG), musb_readl(musb->mregs, OTG_SYSSTATUS), musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); if (glue->status != MUSB_UNKNOWN) omap_musb_set_mailbox(glue); return 0; }
static int ehci_platform_probe(struct platform_device *dev) { struct usb_hcd *hcd; struct resource *res_mem; struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); struct ehci_platform_priv *priv; struct ehci_hcd *ehci; const char *phy_name; int err, irq, phy_num, clk = 0; if (usb_disabled()) return -ENODEV; /* * Use reasonable defaults so platforms don't have to provide these * with DT probing on ARM. */ if (!pdata) pdata = &ehci_platform_defaults; err = dma_coerce_mask_and_coherent(&dev->dev, pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32)); if (err) return err; irq = platform_get_irq(dev, 0); if (irq < 0) { dev_err(&dev->dev, "no irq provided"); return irq; } hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, dev_name(&dev->dev)); if (!hcd) return -ENOMEM; platform_set_drvdata(dev, hcd); dev->dev.platform_data = pdata; priv = hcd_to_ehci_priv(hcd); ehci = hcd_to_ehci(hcd); if (pdata == &ehci_platform_defaults && dev->dev.of_node) { if (of_property_read_bool(dev->dev.of_node, "big-endian-regs")) ehci->big_endian_mmio = 1; if (of_property_read_bool(dev->dev.of_node, "big-endian-desc")) ehci->big_endian_desc = 1; if (of_property_read_bool(dev->dev.of_node, "big-endian")) ehci->big_endian_mmio = ehci->big_endian_desc = 1; if (of_property_read_bool(dev->dev.of_node, "needs-reset-on-resume")) pdata->reset_on_resume = 1; priv->num_phys = of_count_phandle_with_args(dev->dev.of_node, "phys", "#phy-cells"); priv->num_phys = priv->num_phys > 0 ? priv->num_phys : 1; priv->phys = devm_kcalloc(&dev->dev, priv->num_phys, sizeof(struct phy *), GFP_KERNEL); if (!priv->phys) return -ENOMEM; for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { err = of_property_read_string_index( dev->dev.of_node, "phy-names", phy_num, &phy_name); if (err < 0) { if (priv->num_phys > 1) { dev_err(&dev->dev, "phy-names not provided"); goto err_put_hcd; } else phy_name = "usb"; } priv->phys[phy_num] = devm_phy_get(&dev->dev, phy_name); if (IS_ERR(priv->phys[phy_num])) { err = PTR_ERR(priv->phys[phy_num]); if ((priv->num_phys > 1) || (err == -EPROBE_DEFER)) goto err_put_hcd; priv->phys[phy_num] = NULL; } } for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { priv->clks[clk] = of_clk_get(dev->dev.of_node, clk); if (IS_ERR(priv->clks[clk])) { err = PTR_ERR(priv->clks[clk]); if (err == -EPROBE_DEFER) goto err_put_clks; priv->clks[clk] = NULL; break; } } } priv->rst = devm_reset_control_get_optional(&dev->dev, NULL); if (IS_ERR(priv->rst)) { err = PTR_ERR(priv->rst); if (err == -EPROBE_DEFER) goto err_put_clks; priv->rst = NULL; } else { err = reset_control_deassert(priv->rst); if (err) goto err_put_clks; } if (pdata->big_endian_desc) ehci->big_endian_desc = 1; if (pdata->big_endian_mmio) ehci->big_endian_mmio = 1; #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO if (ehci->big_endian_mmio) { dev_err(&dev->dev, "Error: CONFIG_USB_EHCI_BIG_ENDIAN_MMIO not set\n"); err = -EINVAL; goto err_reset; } #endif #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC if (ehci->big_endian_desc) { dev_err(&dev->dev, "Error: CONFIG_USB_EHCI_BIG_ENDIAN_DESC not set\n"); err = -EINVAL; goto err_reset; } #endif if (pdata->power_on) { err = pdata->power_on(dev); if (err < 0) goto err_reset; } res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto err_power; } hcd->rsrc_start = res_mem->start; hcd->rsrc_len = resource_size(res_mem); err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) goto err_power; device_wakeup_enable(hcd->self.controller); platform_set_drvdata(dev, hcd); return err; err_power: if (pdata->power_off) pdata->power_off(dev); err_reset: if (priv->rst) reset_control_assert(priv->rst); err_put_clks: while (--clk >= 0) clk_put(priv->clks[clk]); err_put_hcd: if (pdata == &ehci_platform_defaults) dev->dev.platform_data = NULL; usb_put_hcd(hcd); return err; }
static int __init dra7xx_pcie_probe(struct platform_device *pdev) { u32 reg; int ret; int irq; int i; int phy_count; struct phy **phy; void __iomem *base; struct resource *res; struct dra7xx_pcie *dra7xx; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; char name[10]; int gpio_sel; enum of_gpio_flags flags; unsigned long gpio_flags; dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); if (!dra7xx) return -ENOMEM; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "missing IRQ resource\n"); return -EINVAL; } ret = devm_request_irq(dev, irq, dra7xx_pcie_irq_handler, IRQF_SHARED, "dra7xx-pcie-main", dra7xx); if (ret) { dev_err(dev, "failed to request irq\n"); return ret; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf"); base = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!base) return -ENOMEM; phy_count = of_property_count_strings(np, "phy-names"); if (phy_count < 0) { dev_err(dev, "unable to find the strings\n"); return phy_count; } phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL); if (!phy) return -ENOMEM; for (i = 0; i < phy_count; i++) { snprintf(name, sizeof(name), "pcie-phy%d", i); phy[i] = devm_phy_get(dev, name); if (IS_ERR(phy[i])) return PTR_ERR(phy[i]); ret = phy_init(phy[i]); if (ret < 0) goto err_phy; ret = phy_power_on(phy[i]); if (ret < 0) { phy_exit(phy[i]); goto err_phy; } } dra7xx->base = base; dra7xx->phy = phy; dra7xx->dev = dev; dra7xx->phy_count = phy_count; pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "pm_runtime_get_sync failed\n"); goto err_get_sync; } gpio_sel = of_get_gpio_flags(dev->of_node, 0, &flags); if (gpio_is_valid(gpio_sel)) { gpio_flags = (flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH; ret = devm_gpio_request_one(dev, gpio_sel, gpio_flags, "pcie_reset"); if (ret) { dev_err(&pdev->dev, "gpio%d request failed, ret %d\n", gpio_sel, ret); goto err_gpio; } } else if (gpio_sel == -EPROBE_DEFER) { ret = -EPROBE_DEFER; goto err_gpio; } reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD); reg &= ~LTSSM_EN; dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); platform_set_drvdata(pdev, dra7xx); ret = dra7xx_add_pcie_port(dra7xx, pdev); if (ret < 0) goto err_gpio; return 0; err_gpio: pm_runtime_put(dev); err_get_sync: pm_runtime_disable(dev); err_phy: while (--i >= 0) { phy_power_off(phy[i]); phy_exit(phy[i]); } 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 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; }
/** * ahci_platform_get_resources - Get platform resources * @pdev: platform device to get resources for * * This function allocates an ahci_host_priv struct, and gets the following * resources, storing a reference to them inside the returned struct: * * 1) mmio registers (IORESOURCE_MEM 0, mandatory) * 2) regulator for controlling the targets power (optional) * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node, * or for non devicetree enabled platforms a single clock * 4) phy (optional) * * RETURNS: * The allocated ahci_host_priv on success, otherwise an ERR_PTR value */ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ahci_host_priv *hpriv; struct clk *clk; int i, rc = -ENOMEM; if (!devres_open_group(dev, NULL, GFP_KERNEL)) return ERR_PTR(-ENOMEM); hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) goto err_out; devres_add(dev, hpriv); hpriv->mmio = devm_ioremap_resource(dev, platform_get_resource(pdev, IORESOURCE_MEM, 0)); if (IS_ERR(hpriv->mmio)) { dev_err(dev, "no mmio space\n"); rc = PTR_ERR(hpriv->mmio); goto err_out; } hpriv->target_pwr = devm_regulator_get_optional(dev, "target"); if (IS_ERR(hpriv->target_pwr)) { rc = PTR_ERR(hpriv->target_pwr); if (rc == -EPROBE_DEFER) goto err_out; hpriv->target_pwr = NULL; } for (i = 0; i < AHCI_MAX_CLKS; i++) { /* * For now we must use clk_get(dev, NULL) for the first clock, * because some platforms (da850, spear13xx) are not yet * converted to use devicetree for clocks. For new platforms * this is equivalent to of_clk_get(dev->of_node, 0). */ if (i == 0) clk = clk_get(dev, NULL); else clk = of_clk_get(dev->of_node, i); if (IS_ERR(clk)) { rc = PTR_ERR(clk); if (rc == -EPROBE_DEFER) goto err_out; break; } hpriv->clks[i] = clk; } hpriv->phy = devm_phy_get(dev, "sata-phy"); if (IS_ERR(hpriv->phy)) { rc = PTR_ERR(hpriv->phy); switch (rc) { case -ENODEV: case -ENOSYS: /* continue normally */ hpriv->phy = NULL; break; case -EPROBE_DEFER: goto err_out; default: dev_err(dev, "couldn't get sata-phy\n"); goto err_out; } } pm_runtime_enable(dev); pm_runtime_get_sync(dev); hpriv->got_runtime_pm = true; devres_remove_group(dev, NULL); return hpriv; err_out: devres_release_group(dev, NULL); return ERR_PTR(rc); }