static int am335x_phy_probe(struct platform_device *pdev) { struct am335x_phy *am_phy; struct device *dev = &pdev->dev; int ret; am_phy = devm_kzalloc(dev, sizeof(*am_phy), GFP_KERNEL); if (!am_phy) return -ENOMEM; am_phy->phy_ctrl = am335x_get_phy_control(dev); if (!am_phy->phy_ctrl) return -EPROBE_DEFER; am_phy->id = of_alias_get_id(pdev->dev.of_node, "phy"); if (am_phy->id < 0) { dev_err(&pdev->dev, "Missing PHY id: %d\n", am_phy->id); return am_phy->id; } ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, NULL); if (ret) return ret; ret = usb_add_phy_dev(&am_phy->usb_phy_gen.phy); if (ret) return ret; am_phy->usb_phy_gen.phy.init = am335x_init; am_phy->usb_phy_gen.phy.shutdown = am335x_shutdown; platform_set_drvdata(pdev, am_phy); return 0; }
static int usb_phy_gen_xceiv_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct usb_phy_gen_xceiv *nop; int err; nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); if (!nop) return -ENOMEM; err = usb_phy_gen_create_phy(dev, nop, dev_get_platdata(&pdev->dev)); if (err) return err; nop->phy.init = usb_gen_phy_init; nop->phy.shutdown = usb_gen_phy_shutdown; err = usb_add_phy_dev(&nop->phy); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); return err; } platform_set_drvdata(pdev, nop); return 0; }
static int keystone_usbphy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct keystone_usbphy *k_phy; struct resource *res; int ret; k_phy = devm_kzalloc(dev, sizeof(*k_phy), GFP_KERNEL); if (!k_phy) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); k_phy->phy_ctrl = devm_ioremap_resource(dev, res); if (IS_ERR(k_phy->phy_ctrl)) return PTR_ERR(k_phy->phy_ctrl); ret = usb_phy_gen_create_phy(dev, &k_phy->usb_phy_gen, NULL); if (ret) return ret; k_phy->usb_phy_gen.phy.init = keystone_usbphy_init; k_phy->usb_phy_gen.phy.shutdown = keystone_usbphy_shutdown; platform_set_drvdata(pdev, k_phy); ret = usb_add_phy_dev(&k_phy->usb_phy_gen.phy); if (ret) return ret; return 0; }
static int isp1301_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { struct isp1301 *isp; struct usb_phy *phy; isp = devm_kzalloc(&client->dev, sizeof(*isp), GFP_KERNEL); if (!isp) return -ENOMEM; isp->client = client; mutex_init(&isp->mutex); phy = &isp->phy; phy->label = DRV_NAME; phy->init = isp1301_phy_init; phy->set_vbus = isp1301_phy_set_vbus; phy->type = USB_PHY_TYPE_USB2; i2c_set_clientdata(client, isp); usb_add_phy_dev(phy); isp1301_i2c_client = client; return 0; }
static int usb_phy_gen_xceiv_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct usb_phy_gen_xceiv_platform_data *pdata = dev_get_platdata(&pdev->dev); struct usb_phy_gen_xceiv *nop; enum usb_phy_type type = USB_PHY_TYPE_USB2; int err; u32 clk_rate = 0; bool needs_vcc = false; nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); if (!nop) return -ENOMEM; nop->reset_active_low = true; /* default behaviour */ if (dev->of_node) { struct device_node *node = dev->of_node; enum of_gpio_flags flags; if (of_property_read_u32(node, "clock-frequency", &clk_rate)) clk_rate = 0; needs_vcc = of_property_read_bool(node, "vcc-supply"); nop->gpio_reset = of_get_named_gpio_flags(node, "reset-gpios", 0, &flags); if (nop->gpio_reset == -EPROBE_DEFER) return -EPROBE_DEFER; nop->reset_active_low = flags & OF_GPIO_ACTIVE_LOW; } else if (pdata) { type = pdata->type; clk_rate = pdata->clk_rate; needs_vcc = pdata->needs_vcc; nop->gpio_reset = pdata->gpio_reset; } err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc); if (err) return err; nop->phy.init = usb_gen_phy_init; nop->phy.shutdown = usb_gen_phy_shutdown; err = usb_add_phy_dev(&nop->phy); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); return err; } platform_set_drvdata(pdev, nop); return 0; return err; }
static int samsung_usb3phy_probe(struct platform_device *pdev) { struct samsung_usbphy *sphy; struct samsung_usbphy_data *pdata = dev_get_platdata(&pdev->dev); struct device *dev = &pdev->dev; struct resource *phy_mem; void __iomem *phy_base; struct clk *clk; int ret; phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); phy_base = devm_ioremap_resource(dev, phy_mem); if (IS_ERR(phy_base)) return PTR_ERR(phy_base); sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); if (!sphy) return -ENOMEM; clk = devm_clk_get(dev, "usbdrd30"); if (IS_ERR(clk)) { dev_err(dev, "Failed to get device clock\n"); return PTR_ERR(clk); } sphy->dev = dev; if (dev->of_node) { ret = samsung_usbphy_parse_dt(sphy); if (ret < 0) return ret; } else { if (!pdata) { dev_err(dev, "no platform data specified\n"); return -EINVAL; } } sphy->plat = pdata; sphy->regs = phy_base; sphy->clk = clk; sphy->phy.dev = sphy->dev; sphy->phy.label = "samsung-usb3phy"; sphy->phy.type = USB_PHY_TYPE_USB3; sphy->phy.init = samsung_usb3phy_init; sphy->phy.shutdown = samsung_usb3phy_shutdown; sphy->drv_data = samsung_usbphy_get_driver_data(pdev); sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy); if (sphy->ref_clk_freq < 0) return -EINVAL; spin_lock_init(&sphy->lock); platform_set_drvdata(pdev, sphy); return usb_add_phy_dev(&sphy->phy); }
static int mxs_phy_probe(struct platform_device *pdev) { struct resource *res; void __iomem *base; struct clk *clk; struct mxs_phy *mxs_phy; int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "can't get device resources\n"); return -ENOENT; } base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { dev_err(&pdev->dev, "can't get the clock, err=%ld", PTR_ERR(clk)); return PTR_ERR(clk); } mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL); if (!mxs_phy) { dev_err(&pdev->dev, "Failed to allocate USB PHY structure!\n"); return -ENOMEM; } mxs_phy->phy.io_priv = base; mxs_phy->phy.dev = &pdev->dev; mxs_phy->phy.label = DRIVER_NAME; mxs_phy->phy.init = mxs_phy_init; mxs_phy->phy.shutdown = mxs_phy_shutdown; mxs_phy->phy.set_suspend = mxs_phy_suspend; mxs_phy->phy.notify_connect = mxs_phy_on_connect; mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; ATOMIC_INIT_NOTIFIER_HEAD(&mxs_phy->phy.notifier); mxs_phy->clk = clk; platform_set_drvdata(pdev, &mxs_phy->phy); ret = usb_add_phy_dev(&mxs_phy->phy); if (ret) return ret; return 0; }
static int am335x_phy_probe(struct platform_device *pdev) { struct am335x_phy *am_phy; struct device *dev = &pdev->dev; int ret; am_phy = devm_kzalloc(dev, sizeof(*am_phy), GFP_KERNEL); if (!am_phy) return -ENOMEM; am_phy->phy_ctrl = am335x_get_phy_control(dev); if (!am_phy->phy_ctrl) return -EPROBE_DEFER; am_phy->id = of_alias_get_id(pdev->dev.of_node, "phy"); if (am_phy->id < 0) { dev_err(&pdev->dev, "Missing PHY id: %d\n", am_phy->id); return am_phy->id; } am_phy->dr_mode = of_usb_get_dr_mode_by_phy(pdev->dev.of_node, -1); ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, NULL); if (ret) return ret; ret = usb_add_phy_dev(&am_phy->usb_phy_gen.phy); if (ret) return ret; am_phy->usb_phy_gen.phy.init = am335x_init; am_phy->usb_phy_gen.phy.shutdown = am335x_shutdown; platform_set_drvdata(pdev, am_phy); device_init_wakeup(dev, true); /* * If we leave PHY wakeup enabled then AM33XX wakes up * immediately from DS0. To avoid this we mark dev->power.can_wakeup * to false. The same is checked in suspend routine to decide * on whether to enable PHY wakeup or not. * PHY wakeup works fine in standby mode, there by allowing us to * handle remote wakeup, wakeup on disconnect and connect. */ device_set_wakeup_enable(dev, false); phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false); return 0; }
static int usb_phy_generic_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct usb_phy_generic *nop; int err; nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); if (!nop) return -ENOMEM; err = usb_phy_gen_create_phy(dev, nop, dev_get_platdata(&pdev->dev)); if (err) return err; if (nop->gpiod_vbus) { err = devm_request_threaded_irq(&pdev->dev, gpiod_to_irq(nop->gpiod_vbus), NULL, nop_gpio_vbus_thread, VBUS_IRQ_FLAGS, "vbus_detect", nop); if (err) { dev_err(&pdev->dev, "can't request irq %i, err: %d\n", gpiod_to_irq(nop->gpiod_vbus), err); return err; } nop->phy.otg->state = gpiod_get_value(nop->gpiod_vbus) ? OTG_STATE_B_PERIPHERAL : OTG_STATE_B_IDLE; } nop->phy.init = usb_gen_phy_init; nop->phy.shutdown = usb_gen_phy_shutdown; err = usb_add_phy_dev(&nop->phy); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); return err; } platform_set_drvdata(pdev, nop); return 0; }
static int twl4030_usb_probe(struct platform_device *pdev) { struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev); struct twl4030_usb *twl; struct phy *phy; int status, err; struct usb_otg *otg; struct device_node *np = pdev->dev.of_node; struct phy_provider *phy_provider; struct phy_init_data *init_data = NULL; twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); if (!twl) return -ENOMEM; if (np) of_property_read_u32(np, "usb_mode", (enum twl4030_usb_mode *)&twl->usb_mode); else if (pdata) { twl->usb_mode = pdata->usb_mode; init_data = pdata->init_data; } else { dev_err(&pdev->dev, "twl4030 initialized without pdata\n"); return -EINVAL; } otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); if (!otg) return -ENOMEM; twl->dev = &pdev->dev; twl->irq = platform_get_irq(pdev, 0); twl->vbus_supplied = false; twl->asleep = 1; twl->linkstat = OMAP_MUSB_UNKNOWN; twl->phy.dev = twl->dev; twl->phy.label = "twl4030"; twl->phy.otg = otg; twl->phy.type = USB_PHY_TYPE_USB2; otg->phy = &twl->phy; otg->set_host = twl4030_set_host; otg->set_peripheral = twl4030_set_peripheral; phy = devm_phy_create(twl->dev, NULL, &ops, init_data); if (IS_ERR(phy)) { dev_dbg(&pdev->dev, "Failed to create PHY\n"); return PTR_ERR(phy); } phy_set_drvdata(phy, twl); phy_provider = devm_of_phy_provider_register(twl->dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); /* init spinlock for workqueue */ spin_lock_init(&twl->lock); INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work); err = twl4030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); return err; } usb_add_phy_dev(&twl->phy); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); /* Our job is to use irqs and status from the power module * to keep the transceiver disabled when nothing's connected. * * FIXME we actually shouldn't start enabling it until the * USB controller drivers have said they're ready, by calling * set_host() and/or set_peripheral() ... OTG_capable boards * need both handles, otherwise just one suffices. */ twl->irq_enabled = true; status = devm_request_threaded_irq(twl->dev, twl->irq, NULL, twl4030_usb_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq, status); return status; } dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); return 0; }
static int omap_usb2_probe(struct platform_device *pdev) { struct omap_usb *phy; struct phy *generic_phy; struct resource *res; struct phy_provider *phy_provider; struct usb_otg *otg; struct device_node *node = pdev->dev.of_node; struct device_node *control_node; struct platform_device *control_pdev; const struct of_device_id *of_id; struct usb_phy_data *phy_data; of_id = of_match_device(of_match_ptr(omap_usb2_id_table), &pdev->dev); if (!of_id) return -EINVAL; phy_data = (struct usb_phy_data *)of_id->data; phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); if (!phy) { dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n"); return -ENOMEM; } otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); if (!otg) { dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n"); return -ENOMEM; } phy->dev = &pdev->dev; phy->phy.dev = phy->dev; phy->phy.label = phy_data->label; phy->phy.otg = otg; phy->phy.type = USB_PHY_TYPE_USB2; if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { res = platform_get_resource(pdev, IORESOURCE_MEM, 0); phy->phy_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(phy->phy_base)) return PTR_ERR(phy->phy_base); phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT; } control_node = of_parse_phandle(node, "ctrl-module", 0); if (!control_node) { dev_err(&pdev->dev, "Failed to get control device phandle\n"); return -EINVAL; } control_pdev = of_find_device_by_node(control_node); if (!control_pdev) { dev_err(&pdev->dev, "Failed to get control device\n"); return -EINVAL; } phy->control_dev = &control_pdev->dev; omap_control_phy_power(phy->control_dev, 0); otg->set_host = omap_usb_set_host; otg->set_peripheral = omap_usb_set_peripheral; if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS) otg->set_vbus = omap_usb_set_vbus; if (phy_data->flags & OMAP_USB2_HAS_START_SRP) otg->start_srp = omap_usb_start_srp; otg->phy = &phy->phy; platform_set_drvdata(pdev, phy); generic_phy = devm_phy_create(phy->dev, &ops, NULL); if (IS_ERR(generic_phy)) return PTR_ERR(generic_phy); phy_set_drvdata(generic_phy, phy); pm_runtime_enable(phy->dev); phy_provider = devm_of_phy_provider_register(phy->dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) { pm_runtime_disable(phy->dev); return PTR_ERR(phy_provider); } phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); if (IS_ERR(phy->wkupclk)) { dev_warn(&pdev->dev, "unable to get wkupclk, trying old name\n"); phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); if (IS_ERR(phy->wkupclk)) { dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); return PTR_ERR(phy->wkupclk); } else { dev_warn(&pdev->dev, "found usb_phy_cm_clk32k, please fix DTS\n"); } } clk_prepare(phy->wkupclk); phy->optclk = devm_clk_get(phy->dev, "refclk"); if (IS_ERR(phy->optclk)) { dev_dbg(&pdev->dev, "unable to get refclk, trying old name\n"); phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); if (IS_ERR(phy->optclk)) { dev_dbg(&pdev->dev, "unable to get usb_otg_ss_refclk960m\n"); } else { dev_warn(&pdev->dev, "found usb_otg_ss_refclk960m, please fix DTS\n"); } } else { clk_prepare(phy->optclk); } usb_add_phy_dev(&phy->phy); return 0; }
static int mv_otg_probe(struct platform_device *pdev) { struct mv_usb_platform_data *pdata = pdev->dev.platform_data; struct mv_otg *mvotg; struct usb_otg *otg; struct resource *r; int retval = 0, i; struct device_node *np = pdev->dev.of_node; const __be32 *prop; unsigned int proplen; if (pdata == NULL) { dev_err(&pdev->dev, "failed to get platform data\n"); return -ENODEV; } mvotg = devm_kzalloc(&pdev->dev, sizeof(*mvotg), GFP_KERNEL); if (!mvotg) { dev_err(&pdev->dev, "failed to allocate memory!\n"); return -ENOMEM; } otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); if (!otg) return -ENOMEM; platform_set_drvdata(pdev, mvotg); mvotg->pdev = pdev; mvotg->pdata = pdata; mvotg->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(mvotg->clk)) return PTR_ERR(mvotg->clk); clk_prepare(mvotg->clk); mvotg->qwork = create_singlethread_workqueue("mv_otg_queue"); if (!mvotg->qwork) { dev_dbg(&pdev->dev, "cannot create workqueue for OTG\n"); return -ENOMEM; } INIT_DELAYED_WORK(&mvotg->work, mv_otg_work); /* OTG common part */ mvotg->pdev = pdev; mvotg->phy.dev = &pdev->dev; mvotg->phy.type = USB_PHY_TYPE_USB2; mvotg->phy.otg = otg; mvotg->phy.label = driver_name; mvotg->phy.state = OTG_STATE_UNDEFINED; otg->phy = &mvotg->phy; otg->set_host = mv_otg_set_host; otg->set_peripheral = mv_otg_set_peripheral; otg->set_vbus = mv_otg_set_vbus; mv_otg_phy_bind_device(mvotg); for (i = 0; i < OTG_TIMER_NUM; i++) init_timer(&mvotg->otg_ctrl.timer[i]); r = platform_get_resource(mvotg->pdev, IORESOURCE_MEM, 0); if (r == NULL) { dev_err(&pdev->dev, "no I/O memory resource defined\n"); retval = -ENODEV; goto err_destroy_workqueue; } mvotg->cap_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); if (mvotg->cap_regs == NULL) { dev_err(&pdev->dev, "failed to map I/O memory\n"); retval = -EFAULT; goto err_destroy_workqueue; } mvotg->outer_phy = devm_usb_get_phy_dev(&pdev->dev, MV_USB2_PHY_INDEX); if (IS_ERR_OR_NULL(mvotg->outer_phy)) { retval = PTR_ERR(mvotg->outer_phy); if (retval != -EPROBE_DEFER) dev_err(&pdev->dev, "can not find outer phy\n"); goto err_destroy_workqueue; } /* we will acces controller register, so enable the udc controller */ retval = mv_otg_enable_internal(mvotg); if (retval) { dev_err(&pdev->dev, "mv otg enable error %d\n", retval); goto err_destroy_workqueue; } mvotg->op_regs = (struct mv_otg_regs __iomem *) ((unsigned long) mvotg->cap_regs + (readl(mvotg->cap_regs) & CAPLENGTH_MASK)); if (pdata->extern_attr & (MV_USB_HAS_VBUS_DETECTION | MV_USB_HAS_IDPIN_DETECTION)) { mvotg->notifier.notifier_call = mv_otg_notifier_callback; pxa_usb_register_notifier(mvotg->pdata->id, &mvotg->notifier); if (pdata->extern_attr & MV_USB_HAS_VBUS_DETECTION) { mvotg->clock_gating = 1; pxa_usb_extern_call(mvotg->pdata->id, vbus, init); } if (pdata->extern_attr & MV_USB_HAS_IDPIN_DETECTION) pxa_usb_extern_call(mvotg->pdata->id, idpin, init); } if (pdata->disable_otg_clock_gating) mvotg->clock_gating = 0; mv_otg_reset(mvotg); mv_otg_init_irq(mvotg); r = platform_get_resource(mvotg->pdev, IORESOURCE_IRQ, 0); if (r == NULL) { dev_err(&pdev->dev, "no IRQ resource defined\n"); retval = -ENODEV; goto err_disable_clk; } mvotg->irq = r->start; if (devm_request_irq(&pdev->dev, mvotg->irq, mv_otg_irq, IRQF_SHARED, driver_name, mvotg)) { dev_err(&pdev->dev, "Request irq %d for OTG failed\n", mvotg->irq); mvotg->irq = 0; retval = -ENODEV; goto err_disable_clk; } retval = usb_add_phy_dev(&mvotg->phy); if (retval < 0) { dev_err(&pdev->dev, "can't register transceiver, %d\n", retval); goto err_disable_clk; } prop = of_get_property(np, "lpm-qos", &proplen); if (!prop) { pr_err("lpm-qos config in DT for mv_otg is not defined\n"); goto err_disable_clk; } else mvotg->lpm_qos = be32_to_cpup(prop); mvotg->qos_idle.name = mvotg->pdev->name; pm_qos_add_request(&mvotg->qos_idle, PM_QOS_CPUIDLE_BLOCK, PM_QOS_CPUIDLE_BLOCK_DEFAULT_VALUE); retval = sysfs_create_group(&pdev->dev.kobj, &inputs_attr_group); if (retval < 0) { dev_dbg(&pdev->dev, "Can't register sysfs attr group: %d\n", retval); goto err_remove_otg_phy; } spin_lock_init(&mvotg->wq_lock); if (spin_trylock(&mvotg->wq_lock)) { mv_otg_run_state_machine(mvotg, 2 * HZ); spin_unlock(&mvotg->wq_lock); } dev_info(&pdev->dev, "successful probe OTG device %s clock gating.\n", mvotg->clock_gating ? "with" : "without"); device_init_wakeup(&pdev->dev, 1); return 0; err_remove_otg_phy: usb_remove_phy(&mvotg->phy); pm_qos_remove_request(&mvotg->qos_idle); err_disable_clk: mv_otg_disable_internal(mvotg); if (pdata->extern_attr & (MV_USB_HAS_VBUS_DETECTION | MV_USB_HAS_IDPIN_DETECTION)) pxa_usb_unregister_notifier(mvotg->pdata->id, &mvotg->notifier); err_destroy_workqueue: flush_workqueue(mvotg->qwork); destroy_workqueue(mvotg->qwork); return retval; }
static int omap_usb2_probe(struct platform_device *pdev) { struct omap_usb *phy; struct phy *generic_phy; struct resource *res; struct phy_provider *phy_provider; struct usb_otg *otg; struct device_node *node = pdev->dev.of_node; struct device_node *control_node; struct platform_device *control_pdev; const struct of_device_id *of_id; struct usb_phy_data *phy_data; of_id = of_match_device(omap_usb2_id_table, &pdev->dev); if (!of_id) return -EINVAL; phy_data = (struct usb_phy_data *)of_id->data; phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); if (!otg) return -ENOMEM; phy->dev = &pdev->dev; phy->phy.dev = phy->dev; phy->phy.label = phy_data->label; phy->phy.otg = otg; phy->phy.type = USB_PHY_TYPE_USB2; phy->mask = phy_data->mask; phy->power_on = phy_data->power_on; phy->power_off = phy_data->power_off; if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { res = platform_get_resource(pdev, IORESOURCE_MEM, 0); phy->phy_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(phy->phy_base)) return PTR_ERR(phy->phy_base); phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT; } phy->syscon_phy_power = syscon_regmap_lookup_by_phandle(node, "syscon-phy-power"); if (IS_ERR(phy->syscon_phy_power)) { dev_dbg(&pdev->dev, "can't get syscon-phy-power, using control device\n"); phy->syscon_phy_power = NULL; control_node = of_parse_phandle(node, "ctrl-module", 0); if (!control_node) { dev_err(&pdev->dev, "Failed to get control device phandle\n"); return -EINVAL; } control_pdev = of_find_device_by_node(control_node); if (!control_pdev) { dev_err(&pdev->dev, "Failed to get control device\n"); return -EINVAL; } phy->control_dev = &control_pdev->dev; } else { if (of_property_read_u32_index(node, "syscon-phy-power", 1, &phy->power_reg)) { dev_err(&pdev->dev, "couldn't get power reg. offset\n"); return -EINVAL; } } phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); if (IS_ERR(phy->wkupclk)) { if (PTR_ERR(phy->wkupclk) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_warn(&pdev->dev, "unable to get wkupclk %ld, trying old name\n", PTR_ERR(phy->wkupclk)); phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); if (IS_ERR(phy->wkupclk)) { if (PTR_ERR(phy->wkupclk) != -EPROBE_DEFER) dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); return PTR_ERR(phy->wkupclk); } else { dev_warn(&pdev->dev, "found usb_phy_cm_clk32k, please fix DTS\n"); } } phy->optclk = devm_clk_get(phy->dev, "refclk"); if (IS_ERR(phy->optclk)) { if (PTR_ERR(phy->optclk) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_dbg(&pdev->dev, "unable to get refclk, trying old name\n"); phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); if (IS_ERR(phy->optclk)) { if (PTR_ERR(phy->optclk) != -EPROBE_DEFER) { dev_dbg(&pdev->dev, "unable to get usb_otg_ss_refclk960m\n"); } } else { dev_warn(&pdev->dev, "found usb_otg_ss_refclk960m, please fix DTS\n"); } } otg->set_host = omap_usb_set_host; otg->set_peripheral = omap_usb_set_peripheral; if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS) otg->set_vbus = omap_usb_set_vbus; if (phy_data->flags & OMAP_USB2_HAS_START_SRP) otg->start_srp = omap_usb_start_srp; otg->usb_phy = &phy->phy; platform_set_drvdata(pdev, phy); pm_runtime_enable(phy->dev); generic_phy = devm_phy_create(phy->dev, NULL, &ops); if (IS_ERR(generic_phy)) { pm_runtime_disable(phy->dev); return PTR_ERR(generic_phy); } phy_set_drvdata(generic_phy, phy); omap_usb_power_off(generic_phy); phy_provider = devm_of_phy_provider_register(phy->dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) { pm_runtime_disable(phy->dev); return PTR_ERR(phy_provider); } usb_add_phy_dev(&phy->phy); return 0; }
static int omap_usb3_probe(struct platform_device *pdev) { struct omap_usb *phy; struct resource *res; phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); if (!phy) { dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n"); return -ENOMEM; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); phy->pll_ctrl_base = devm_request_and_ioremap(&pdev->dev, res); if (!phy->pll_ctrl_base) { dev_err(&pdev->dev, "ioremap of pll_ctrl failed\n"); return -ENOMEM; } phy->dev = &pdev->dev; phy->phy.dev = phy->dev; phy->phy.label = "omap-usb3"; phy->phy.init = omap_usb3_init; phy->phy.set_suspend = omap_usb3_suspend; phy->phy.type = USB_PHY_TYPE_USB3; phy->is_suspended = 1; phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); if (IS_ERR(phy->wkupclk)) { dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); return PTR_ERR(phy->wkupclk); } clk_prepare(phy->wkupclk); phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); if (IS_ERR(phy->optclk)) { dev_err(&pdev->dev, "unable to get usb_otg_ss_refclk960m\n"); return PTR_ERR(phy->optclk); } clk_prepare(phy->optclk); phy->sys_clk = devm_clk_get(phy->dev, "sys_clkin"); if (IS_ERR(phy->sys_clk)) { pr_err("%s: unable to get sys_clkin\n", __func__); return -EINVAL; } phy->control_dev = omap_get_control_dev(); if (IS_ERR(phy->control_dev)) { dev_dbg(&pdev->dev, "Failed to get control device\n"); return -ENODEV; } omap_control_usb3_phy_power(phy->control_dev, 0); usb_add_phy_dev(&phy->phy); platform_set_drvdata(pdev, phy); pm_runtime_enable(phy->dev); pm_runtime_get(&pdev->dev); return 0; }
static int omap_usb2_probe(struct platform_device *pdev) { struct omap_usb *phy; struct phy *generic_phy; struct phy_provider *phy_provider; struct usb_otg *otg; struct device_node *node = pdev->dev.of_node; struct device_node *control_node; struct platform_device *control_pdev; if (!node) return -EINVAL; phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); if (!phy) { dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n"); return -ENOMEM; } otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); if (!otg) { dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n"); return -ENOMEM; } phy->dev = &pdev->dev; phy->phy.dev = phy->dev; phy->phy.label = "omap-usb2"; phy->phy.set_suspend = omap_usb2_suspend; phy->phy.otg = otg; phy->phy.type = USB_PHY_TYPE_USB2; control_node = of_parse_phandle(node, "ctrl-module", 0); if (!control_node) { dev_err(&pdev->dev, "Failed to get control device phandle\n"); return -EINVAL; } control_pdev = of_find_device_by_node(control_node); if (!control_pdev) { dev_err(&pdev->dev, "Failed to get control device\n"); return -EINVAL; } phy->control_dev = &control_pdev->dev; phy->is_suspended = 1; omap_control_usb_phy_power(phy->control_dev, 0); otg->set_host = omap_usb_set_host; otg->set_peripheral = omap_usb_set_peripheral; otg->set_vbus = omap_usb_set_vbus; otg->start_srp = omap_usb_start_srp; otg->phy = &phy->phy; platform_set_drvdata(pdev, phy); pm_runtime_enable(phy->dev); generic_phy = devm_phy_create(phy->dev, &ops, NULL); if (IS_ERR(generic_phy)) return PTR_ERR(generic_phy); phy_set_drvdata(generic_phy, phy); phy_provider = devm_of_phy_provider_register(phy->dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); if (IS_ERR(phy->wkupclk)) { dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); return PTR_ERR(phy->wkupclk); } clk_prepare(phy->wkupclk); phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); if (IS_ERR(phy->optclk)) dev_vdbg(&pdev->dev, "unable to get refclk960m\n"); else clk_prepare(phy->optclk); usb_add_phy_dev(&phy->phy); return 0; }
static int msm_ssphy_qmp_probe(struct platform_device *pdev) { struct msm_ssphy_qmp *phy; struct device *dev = &pdev->dev; struct resource *res; int ret = 0; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qmp_phy_base"); phy->base = devm_ioremap_resource(dev, res); if (IS_ERR(phy->base)) return PTR_ERR(phy->base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qmp_ahb2phy_base"); phy->ahb2phy = devm_ioremap_resource(dev, res); if (IS_ERR(phy->ahb2phy)) { dev_err(dev, "couldn't find qmp_ahb2phy_base address.\n"); return PTR_ERR(phy->ahb2phy); } ret = of_property_read_u32_array(dev->of_node, "qcom,vdd-voltage-level", (u32 *) phy->vdd_levels, ARRAY_SIZE(phy->vdd_levels)); if (ret) { dev_err(dev, "error reading qcom,vdd-voltage-level property\n"); return ret; } phy->vdd = devm_regulator_get(dev, "vdd"); if (IS_ERR(phy->vdd)) { dev_err(dev, "unable to get vdd supply\n"); return PTR_ERR(phy->vdd); } phy->vdda18 = devm_regulator_get(dev, "vdda18"); if (IS_ERR(phy->vdda18)) { dev_err(dev, "unable to get vdda18 supply\n"); return PTR_ERR(phy->vdda18); } ret = msm_ssusb_qmp_config_vdd(phy, 1); if (ret) { dev_err(dev, "ssusb vdd_dig configuration failed\n"); return ret; } ret = regulator_enable(phy->vdd); if (ret) { dev_err(dev, "unable to enable the ssusb vdd_dig\n"); goto unconfig_ss_vdd; } ret = msm_ssusb_qmp_ldo_enable(phy, 1); if (ret) { dev_err(dev, "ssusb vreg enable failed\n"); goto disable_ss_vdd; } phy->ldo_clk = devm_clk_get(dev, "ldo_clk"); if (!IS_ERR(phy->ldo_clk)) clk_prepare_enable(phy->ldo_clk); platform_set_drvdata(pdev, phy); if (of_property_read_bool(dev->of_node, "qcom,vbus-valid-override")) phy->phy.flags |= PHY_VBUS_VALID_OVERRIDE; phy->override_pll_cal = of_property_read_bool(dev->of_node, "qcom,override-pll-calibration"); if (phy->override_pll_cal) dev_dbg(dev, "Override PHY PLL calibration is enabled.\n"); phy->switch_pipe_clk_src = !of_property_read_bool(dev->of_node, "qcom,no-pipe-clk-switch"); phy->phy.dev = dev; phy->phy.init = msm_ssphy_qmp_init; phy->phy.set_suspend = msm_ssphy_qmp_set_suspend; phy->phy.set_params = msm_ssphy_qmp_set_params; phy->phy.notify_connect = msm_ssphy_qmp_notify_connect; phy->phy.notify_disconnect = msm_ssphy_qmp_notify_disconnect; phy->phy.reset = msm_ssphy_qmp_reset; phy->phy.type = USB_PHY_TYPE_USB3; ret = usb_add_phy_dev(&phy->phy); if (ret) goto disable_ss_ldo; return 0; disable_ss_ldo: if (!IS_ERR(phy->ldo_clk)) clk_disable_unprepare(phy->ldo_clk); msm_ssusb_qmp_ldo_enable(phy, 0); disable_ss_vdd: regulator_disable(phy->vdd); unconfig_ss_vdd: msm_ssusb_qmp_config_vdd(phy, 0); return ret; }
static int msm_hsphy_probe(struct platform_device *pdev) { struct msm_hsphy *phy; struct device *dev = &pdev->dev; struct resource *res; int ret = 0; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) { ret = -ENOMEM; goto err_ret; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core"); if (!res) { dev_err(dev, "missing memory base resource\n"); ret = -ENODEV; goto err_ret; } phy->base = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!phy->base) { dev_err(dev, "ioremap failed\n"); ret = -ENODEV; goto err_ret; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tcsr"); if (res) { phy->tcsr = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!phy->tcsr) { dev_err(dev, "tcsr ioremap failed\n"); return -ENODEV; } /* switch MUX to let SNPS controller use the primary HSPHY */ writel_relaxed(readl_relaxed(phy->tcsr) | TCSR_USB30_CONTROL, phy->tcsr); } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_csr"); if (res) { phy->csr = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!phy->csr) { dev_err(dev, "phy_csr ioremap failed\n"); return -ENODEV; } } if (of_get_property(dev->of_node, "qcom,primary-phy", NULL)) { dev_dbg(dev, "secondary HSPHY\n"); phy->phy.flags |= ENABLE_SECONDARY_PHY; } ret = of_property_read_u32_array(dev->of_node, "qcom,vdd-voltage-level", (u32 *) phy->vdd_levels, ARRAY_SIZE(phy->vdd_levels)); if (ret) { dev_err(dev, "error reading qcom,vdd-voltage-level property\n"); goto err_ret; } phy->ext_vbus_id = of_property_read_bool(dev->of_node, "qcom,ext-vbus-id"); phy->phy.dev = dev; phy->vdd = devm_regulator_get(dev, "vdd"); if (IS_ERR(phy->vdd)) { dev_err(dev, "unable to get vdd supply\n"); ret = PTR_ERR(phy->vdd); goto err_ret; } if (of_get_property(dev->of_node, "vddcx-supply", NULL)) { phy->vddcx = devm_regulator_get(dev, "vddcx"); if (IS_ERR(phy->vddcx)) { dev_err(dev, "unable to get vddcx supply\n"); ret = PTR_ERR(phy->vddcx); goto err_ret; } } phy->vdda33 = devm_regulator_get(dev, "vdda33"); if (IS_ERR(phy->vdda33)) { dev_err(dev, "unable to get vdda33 supply\n"); ret = PTR_ERR(phy->vdda33); goto err_ret; } phy->vdda18 = devm_regulator_get(dev, "vdda18"); if (IS_ERR(phy->vdda18)) { dev_err(dev, "unable to get vdda18 supply\n"); ret = PTR_ERR(phy->vdda18); goto err_ret; } ret = msm_hsusb_config_vdd(phy, 1); if (ret) { dev_err(dev, "hsusb vdd_dig configuration failed\n"); goto err_ret; } ret = regulator_enable(phy->vdd); if (ret) { dev_err(dev, "unable to enable the hsusb vdd_dig\n"); goto unconfig_hs_vdd; } if (phy->vddcx) { ret = regulator_enable(phy->vddcx); if (ret) { dev_err(dev, "unable to enable vddcx\n"); goto unconfig_hs_vdd; } } ret = msm_hsusb_ldo_enable(phy, 1); if (ret) { dev_err(dev, "hsusb vreg enable failed\n"); goto disable_hs_vdd; } phy->sleep_clk = devm_clk_get(&pdev->dev, "phy_sleep_clk"); if (IS_ERR(phy->sleep_clk)) { dev_err(&pdev->dev, "failed to get phy_sleep_clk\n"); ret = PTR_ERR(phy->sleep_clk); goto disable_hs_ldo; } clk_prepare_enable(phy->sleep_clk); phy->sleep_clk_reset = of_property_read_bool(dev->of_node, "qcom,sleep-clk-reset"); if (of_property_read_u32(dev->of_node, "qcom,hsphy-init", &phy->hsphy_init_seq)) dev_dbg(dev, "unable to read hsphy init seq\n"); else if (!phy->hsphy_init_seq) dev_warn(dev, "hsphy init seq cannot be 0. Using POR value\n"); if (of_property_read_u32(dev->of_node, "qcom,hsphy-host-init", &phy->hsphy_host_init_seq)) dev_dbg(dev, "unable to read hsphy host init seq\n"); else if (!phy->hsphy_host_init_seq) dev_warn(dev, "hsphy host init seq cannot be 0. Using POR value\n"); if (of_property_read_u32(dev->of_node, "qcom,num-ports", &phy->num_ports)) phy->num_ports = 1; else if (phy->num_ports > 3) { dev_err(dev, " number of ports more that 3 is not supported\n"); goto disable_clk; } phy->set_pllbtune = of_property_read_bool(dev->of_node, "qcom,set-pllbtune"); /* * If this workaround flag is enabled, the HW requires the 1.8 and 3.x * regulators to be kept ON when entering suspend. The easiest way to * do that is to call regulator_enable() an additional time here, * since it will keep the regulators' reference counts nonzero. */ phy->vdda_force_on = of_property_read_bool(dev->of_node, "qcom,vdda-force-on"); if (phy->vdda_force_on) { ret = msm_hsusb_ldo_enable(phy, 1); if (ret) goto disable_clk; } platform_set_drvdata(pdev, phy); if (of_property_read_bool(dev->of_node, "qcom,vbus-valid-override")) phy->phy.flags |= PHY_VBUS_VALID_OVERRIDE; phy->phy.init = msm_hsphy_init; phy->phy.set_suspend = msm_hsphy_set_suspend; phy->phy.notify_connect = msm_hsphy_notify_connect; phy->phy.notify_disconnect = msm_hsphy_notify_disconnect; phy->phy.reset = msm_hsphy_reset; /*FIXME: this conflicts with dwc3_otg */ /*phy->phy.type = USB_PHY_TYPE_USB2; */ phy->phy.set_params = msm_hsphy_set_params; ret = usb_add_phy_dev(&phy->phy); if (ret) goto disable_clk; atomic_inc(&hsphy_active_count); return 0; disable_clk: clk_disable_unprepare(phy->sleep_clk); disable_hs_ldo: msm_hsusb_ldo_enable(phy, 0); disable_hs_vdd: if (phy->vddcx) regulator_disable(phy->vddcx); regulator_disable(phy->vdd); unconfig_hs_vdd: msm_hsusb_config_vdd(phy, 0); err_ret: return ret; }
static int msm_ssphy_qmp_probe(struct platform_device *pdev) { struct msm_ssphy_qmp *phy; struct device *dev = &pdev->dev; struct resource *res; int ret = 0; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing memory base resource\n"); return -ENODEV; } phy->base = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!phy->base) { dev_err(dev, "ioremap failed\n"); return -ENODEV; } ret = of_property_read_u32_array(dev->of_node, "qcom,vdd-voltage-level", (u32 *) phy->vdd_levels, ARRAY_SIZE(phy->vdd_levels)); if (ret) { dev_err(dev, "error reading qcom,vdd-voltage-level property\n"); return ret; } phy->vdd = devm_regulator_get(dev, "vdd"); if (IS_ERR(phy->vdd)) { dev_err(dev, "unable to get vdd supply\n"); return PTR_ERR(phy->vdd); } phy->vdda18 = devm_regulator_get(dev, "vdda18"); if (IS_ERR(phy->vdda18)) { dev_err(dev, "unable to get vdda18 supply\n"); return PTR_ERR(phy->vdda18); } ret = msm_ssusb_qmp_config_vdd(phy, 1); if (ret) { dev_err(dev, "ssusb vdd_dig configuration failed\n"); return ret; } ret = regulator_enable(phy->vdd); if (ret) { dev_err(dev, "unable to enable the ssusb vdd_dig\n"); goto unconfig_ss_vdd; } ret = msm_ssusb_qmp_ldo_enable(phy, 1); if (ret) { dev_err(dev, "ssusb vreg enable failed\n"); goto disable_ss_vdd; } platform_set_drvdata(pdev, phy); if (of_property_read_bool(dev->of_node, "qcom,vbus-valid-override")) phy->phy.flags |= PHY_VBUS_VALID_OVERRIDE; phy->phy.dev = dev; phy->phy.init = msm_ssphy_qmp_init; phy->phy.set_suspend = msm_ssphy_qmp_set_suspend; phy->phy.set_params = msm_ssphy_qmp_set_params; phy->phy.notify_connect = msm_ssphy_qmp_notify_connect; phy->phy.notify_disconnect = msm_ssphy_qmp_notify_disconnect; phy->phy.reset = msm_ssphy_qmp_reset; phy->phy.type = USB_PHY_TYPE_USB3; ret = msm_ssphy_qmp_init_clocks(phy); if (ret) { dev_err(dev, "Fail to init qmp phy clocks\n"); goto disable_ss_ldo; } ret = usb_add_phy_dev(&phy->phy); if (ret) goto disable_ss_ldo; return 0; disable_ss_ldo: msm_ssusb_qmp_ldo_enable(phy, 0); disable_ss_vdd: regulator_disable(phy->vdd); unconfig_ss_vdd: msm_ssusb_qmp_config_vdd(phy, 0); return ret; }
static int nop_usb_xceiv_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; struct nop_usb_xceiv *nop; enum usb_phy_type type = USB_PHY_TYPE_USB2; int err; u32 clk_rate = 0; bool needs_vcc = false; bool needs_reset = false; nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL); if (!nop) return -ENOMEM; nop->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*nop->phy.otg), GFP_KERNEL); if (!nop->phy.otg) return -ENOMEM; if (dev->of_node) { struct device_node *node = dev->of_node; if (of_property_read_u32(node, "clock-frequency", &clk_rate)) clk_rate = 0; needs_vcc = of_property_read_bool(node, "vcc-supply"); needs_reset = of_property_read_bool(node, "reset-supply"); } else if (pdata) { type = pdata->type; clk_rate = pdata->clk_rate; needs_vcc = pdata->needs_vcc; needs_reset = pdata->needs_reset; } nop->clk = devm_clk_get(&pdev->dev, "main_clk"); if (IS_ERR(nop->clk)) { dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n", PTR_ERR(nop->clk)); } if (!IS_ERR(nop->clk) && clk_rate) { err = clk_set_rate(nop->clk, clk_rate); if (err) { dev_err(&pdev->dev, "Error setting clock rate\n"); return err; } } if (!IS_ERR(nop->clk)) { err = clk_prepare(nop->clk); if (err) { dev_err(&pdev->dev, "Error preparing clock\n"); return err; } } nop->vcc = devm_regulator_get(&pdev->dev, "vcc"); if (IS_ERR(nop->vcc)) { dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n", PTR_ERR(nop->vcc)); if (needs_vcc) return -EPROBE_DEFER; } nop->reset = devm_regulator_get(&pdev->dev, "reset"); if (IS_ERR(nop->reset)) { dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n", PTR_ERR(nop->reset)); if (needs_reset) return -EPROBE_DEFER; } nop->dev = &pdev->dev; nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; nop->phy.set_suspend = nop_set_suspend; nop->phy.init = nop_init; nop->phy.shutdown = nop_shutdown; nop->phy.state = OTG_STATE_UNDEFINED; nop->phy.type = type; nop->phy.otg->phy = &nop->phy; nop->phy.otg->set_host = nop_set_host; nop->phy.otg->set_peripheral = nop_set_peripheral; err = usb_add_phy_dev(&nop->phy); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); goto err_add; } platform_set_drvdata(pdev, nop); ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); return 0; err_add: if (!IS_ERR(nop->clk)) clk_unprepare(nop->clk); return err; }
static int samsung_usb2phy_probe(struct platform_device *pdev) { struct samsung_usbphy *sphy; struct usb_otg *otg; struct samsung_usbphy_data *pdata = pdev->dev.platform_data; const struct samsung_usbphy_drvdata *drv_data; struct device *dev = &pdev->dev; struct resource *phy_mem; void __iomem *phy_base; struct clk *clk; int ret; phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); phy_base = devm_ioremap_resource(dev, phy_mem); if (IS_ERR(phy_base)) return PTR_ERR(phy_base); sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); if (!sphy) return -ENOMEM; otg = devm_kzalloc(dev, sizeof(*otg), GFP_KERNEL); if (!otg) return -ENOMEM; drv_data = samsung_usbphy_get_driver_data(pdev); if (drv_data->cpu_type == TYPE_EXYNOS5250 || drv_data->cpu_type == TYPE_EXYNOS5) clk = devm_clk_get(dev, "usbhost"); else clk = devm_clk_get(dev, "otg"); if (IS_ERR(clk)) { dev_err(dev, "Failed to get otg clock\n"); return PTR_ERR(clk); } sphy->dev = dev; if (dev->of_node) { ret = samsung_usbphy_parse_dt(sphy); if (ret < 0) return ret; } else { if (!pdata) { dev_err(dev, "no platform data specified\n"); return -EINVAL; } } sphy->plat = pdata; sphy->regs = phy_base; sphy->clk = clk; sphy->drv_data = drv_data; sphy->phy.dev = sphy->dev; sphy->phy.label = "samsung-usb2phy"; sphy->phy.type = USB_PHY_TYPE_USB2; sphy->phy.init = samsung_usb2phy_init; sphy->phy.shutdown = samsung_usb2phy_shutdown; sphy->phy.is_active = samsung_usb2phy_is_active; sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy); sphy->phy.otg = otg; sphy->phy.otg->phy = &sphy->phy; sphy->phy.otg->set_host = samsung_usbphy_set_host; if (of_property_read_u32(sphy->dev->of_node, "samsung,hsicphy_en_mask", (u32 *)&drv_data->hsicphy_en_mask)) dev_dbg(dev, "Failed to get hsicphy_en_mask\n"); else if (of_property_read_u32(sphy->dev->of_node, "samsung,hsicphy_reg_offset", (u32 *)&drv_data->hsicphy_reg_offset)) dev_dbg(dev, "Failed to get hsicphy_en_mask\n"); else sphy->has_hsic_pmureg = true; spin_lock_init(&sphy->lock); ret = clk_prepare(sphy->clk); if (ret) { dev_err(dev, "clk_prepare failed\n"); return ret; } platform_set_drvdata(pdev, sphy); ret = usb_add_phy_dev(&sphy->phy); if (ret) { dev_err(dev, "Failed to add PHY\n"); goto err1; } return 0; err1: clk_unprepare(sphy->clk); return ret; }
static int msm_otg_probe(struct platform_device *pdev) { struct regulator_bulk_data regs[3]; int ret = 0; struct device_node *np = pdev->dev.of_node; struct msm_otg_platform_data *pdata; struct resource *res; struct msm_otg *motg; struct usb_phy *phy; void __iomem *phy_select; motg = devm_kzalloc(&pdev->dev, sizeof(struct msm_otg), GFP_KERNEL); if (!motg) { dev_err(&pdev->dev, "unable to allocate msm_otg\n"); return -ENOMEM; } pdata = dev_get_platdata(&pdev->dev); if (!pdata) { if (!np) return -ENXIO; ret = msm_otg_read_dt(pdev, motg); if (ret) return ret; } motg->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), GFP_KERNEL); if (!motg->phy.otg) { dev_err(&pdev->dev, "unable to allocate msm_otg\n"); return -ENOMEM; } phy = &motg->phy; phy->dev = &pdev->dev; motg->phy_reset_clk = devm_clk_get(&pdev->dev, np ? "phy" : "usb_phy_clk"); if (IS_ERR(motg->phy_reset_clk)) { dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); motg->phy_reset_clk = NULL; } motg->clk = devm_clk_get(&pdev->dev, np ? "core" : "usb_hs_clk"); if (IS_ERR(motg->clk)) { dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); return PTR_ERR(motg->clk); } /* * If USB Core is running its protocol engine based on CORE CLK, * CORE CLK must be running at >55Mhz for correct HSUSB * operation and USB core cannot tolerate frequency changes on * CORE CLK. */ motg->pclk = devm_clk_get(&pdev->dev, np ? "iface" : "usb_hs_pclk"); if (IS_ERR(motg->pclk)) { dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); return PTR_ERR(motg->pclk); } /* * USB core clock is not present on all MSM chips. This * clock is introduced to remove the dependency on AXI * bus frequency. */ motg->core_clk = devm_clk_get(&pdev->dev, np ? "alt_core" : "usb_hs_core_clk"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -EINVAL; motg->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!motg->regs) return -ENOMEM; /* * NOTE: The PHYs can be multiplexed between the chipidea controller * and the dwc3 controller, using a single bit. It is important that * the dwc3 driver does not set this bit in an incompatible way. */ if (motg->phy_number) { phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4); if (!phy_select) return -ENOMEM; /* Enable second PHY with the OTG port */ writel(0x1, phy_select); } dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); motg->irq = platform_get_irq(pdev, 0); if (motg->irq < 0) { dev_err(&pdev->dev, "platform_get_irq failed\n"); return motg->irq; } regs[0].supply = "vddcx"; regs[1].supply = "v3p3"; regs[2].supply = "v1p8"; ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs); if (ret) return ret; motg->vddcx = regs[0].consumer; motg->v3p3 = regs[1].consumer; motg->v1p8 = regs[2].consumer; clk_set_rate(motg->clk, 60000000); clk_prepare_enable(motg->clk); clk_prepare_enable(motg->pclk); if (!IS_ERR(motg->core_clk)) clk_prepare_enable(motg->core_clk); ret = msm_hsusb_init_vddcx(motg, 1); if (ret) { dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); goto disable_clks; } ret = msm_hsusb_ldo_init(motg, 1); if (ret) { dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); goto disable_vddcx; } ret = msm_hsusb_ldo_set_mode(motg, 1); if (ret) { dev_err(&pdev->dev, "hsusb vreg enable failed\n"); goto disable_ldo; } writel(0, USB_USBINTR); writel(0, USB_OTGSC); INIT_WORK(&motg->sm_work, msm_otg_sm_work); INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); ret = devm_request_irq(&pdev->dev, motg->irq, msm_otg_irq, IRQF_SHARED, "msm_otg", motg); if (ret) { dev_err(&pdev->dev, "request irq failed\n"); goto disable_ldo; } phy->init = msm_phy_init; phy->set_power = msm_otg_set_power; phy->notify_disconnect = msm_phy_notify_disconnect; phy->type = USB_PHY_TYPE_USB2; phy->io_ops = &msm_otg_io_ops; phy->otg->phy = &motg->phy; phy->otg->set_host = msm_otg_set_host; phy->otg->set_peripheral = msm_otg_set_peripheral; msm_usb_reset(phy); ret = usb_add_phy_dev(&motg->phy); if (ret) { dev_err(&pdev->dev, "usb_add_phy failed\n"); goto disable_ldo; } platform_set_drvdata(pdev, motg); device_init_wakeup(&pdev->dev, 1); if (motg->pdata->mode == USB_DR_MODE_OTG && motg->pdata->otg_control == OTG_USER_CONTROL) { ret = msm_otg_debugfs_init(motg); if (ret) dev_dbg(&pdev->dev, "Can not create mode change file\n"); } pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; disable_ldo: msm_hsusb_ldo_init(motg, 0); disable_vddcx: msm_hsusb_init_vddcx(motg, 0); disable_clks: clk_disable_unprepare(motg->pclk); clk_disable_unprepare(motg->clk); if (!IS_ERR(motg->core_clk)) clk_disable_unprepare(motg->core_clk); return ret; }
static int omap_usb2_probe(struct platform_device *pdev) { struct omap_usb *phy; struct usb_otg *otg; phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); if (!phy) { dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n"); return -ENOMEM; } otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); if (!otg) { dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n"); return -ENOMEM; } phy->dev = &pdev->dev; phy->phy.dev = phy->dev; phy->phy.label = "omap-usb2"; phy->phy.set_suspend = omap_usb2_suspend; phy->phy.otg = otg; phy->phy.type = USB_PHY_TYPE_USB2; phy->control_dev = omap_get_control_dev(); if (IS_ERR(phy->control_dev)) { dev_dbg(&pdev->dev, "Failed to get control device\n"); return -ENODEV; } phy->is_suspended = 1; omap_control_usb_phy_power(phy->control_dev, 0); otg->set_host = omap_usb_set_host; otg->set_peripheral = omap_usb_set_peripheral; otg->set_vbus = omap_usb_set_vbus; otg->start_srp = omap_usb_start_srp; otg->phy = &phy->phy; phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); if (IS_ERR(phy->wkupclk)) { dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); return PTR_ERR(phy->wkupclk); } clk_prepare(phy->wkupclk); phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); if (IS_ERR(phy->optclk)) dev_vdbg(&pdev->dev, "unable to get refclk960m\n"); else clk_prepare(phy->optclk); usb_add_phy_dev(&phy->phy); platform_set_drvdata(pdev, phy); pm_runtime_enable(phy->dev); return 0; }