static int __devinit omap_usb2_probe(struct platform_device *pdev) { struct omap_usb *phy; struct usb_otg *otg; struct clk *optclk; 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->control_dev = omap_control_get(); if (IS_ERR(phy->control_dev)) { dev_err(&pdev->dev, "no control device present in system\n"); return PTR_ERR(phy->control_dev); } phy->is_suspended = 1; omap4_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 = clk_get(phy->dev, "usb_phy_cm_clk32k"); optclk = clk_get(phy->dev, "usb_otg_ss_refclk960m"); if (!IS_ERR(optclk)) phy->optclk = optclk; usb_add_phy(&phy->phy, USB_PHY_TYPE_USB2); platform_set_drvdata(pdev, phy); /* Start with disabled charger detection */ omap_usb_charger_enable(phy->control_dev, 0); pm_runtime_enable(phy->dev); return 0; }
static int mv_u3d_phy_probe(struct platform_device *pdev) { struct mv_u3d_phy *mv_u3d_phy; struct mv_usb_platform_data *pdata; struct device *dev = &pdev->dev; struct resource *res; void __iomem *phy_base; int ret; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "%s: no platform data defined\n", __func__); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing mem resource\n"); return -ENODEV; } phy_base = devm_request_and_ioremap(dev, res); if (!phy_base) { dev_err(dev, "%s: register mapping failed\n", __func__); return -ENXIO; } mv_u3d_phy = devm_kzalloc(dev, sizeof(*mv_u3d_phy), GFP_KERNEL); if (!mv_u3d_phy) return -ENOMEM; mv_u3d_phy->dev = &pdev->dev; mv_u3d_phy->plat = pdata; mv_u3d_phy->base = phy_base; mv_u3d_phy->phy.dev = mv_u3d_phy->dev; mv_u3d_phy->phy.label = "mv-u3d-phy"; mv_u3d_phy->phy.init = mv_u3d_phy_init; mv_u3d_phy->phy.shutdown = mv_u3d_phy_shutdown; ret = usb_add_phy(&mv_u3d_phy->phy, USB_PHY_TYPE_USB3); if (ret) goto err; if (!mv_u3d_phy->clk) mv_u3d_phy->clk = clk_get(mv_u3d_phy->dev, "u3dphy"); platform_set_drvdata(pdev, mv_u3d_phy); dev_info(&pdev->dev, "Initialized Marvell USB 3.0 PHY\n"); err: return ret; }
static int rcar_usb_phy_probe(struct platform_device *pdev) { struct rcar_usb_phy_priv *priv; struct resource *res0, *res1; struct device *dev = &pdev->dev; void __iomem *reg0, *reg1 = NULL; int ret; if (!dev_get_platdata(&pdev->dev)) { dev_err(dev, "No platform data\n"); return -EINVAL; } res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg0 = devm_ioremap_resource(dev, res0); if (IS_ERR(reg0)) return PTR_ERR(reg0); res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (res1) { reg1 = devm_ioremap_resource(dev, res1); if (IS_ERR(reg1)) return PTR_ERR(reg1); } priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(dev, "priv data allocation error\n"); return -ENOMEM; } priv->reg0 = reg0; priv->reg1 = reg1; priv->counter = 0; priv->phy.dev = dev; priv->phy.label = dev_name(dev); priv->phy.init = rcar_usb_phy_init; priv->phy.shutdown = rcar_usb_phy_shutdown; spin_lock_init(&priv->lock); ret = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2); if (ret < 0) { dev_err(dev, "usb phy addition error\n"); return ret; } platform_set_drvdata(pdev, priv); return ret; }
static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) { struct nop_usb_xceiv *nop; int err; nop = kzalloc(sizeof *nop, GFP_KERNEL); if (!nop) return -ENOMEM; nop->phy.otg = kzalloc(sizeof *nop->phy.otg, GFP_KERNEL); if (!nop->phy.otg) { kfree(nop); return -ENOMEM; } nop->dev = &pdev->dev; nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; nop->phy.set_suspend = nop_set_suspend; nop->phy.state = OTG_STATE_UNDEFINED; 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(&nop->phy, USB_PHY_TYPE_USB2); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); goto exit; } platform_set_drvdata(pdev, nop); ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); return 0; exit: kfree(nop->phy.otg); kfree(nop); return err; }
static int tahvo_usb_probe(struct platform_device *pdev) { struct retu_dev *rdev = dev_get_drvdata(pdev->dev.parent); struct tahvo_usb *tu; int ret; tu = devm_kzalloc(&pdev->dev, sizeof(*tu), GFP_KERNEL); if (!tu) return -ENOMEM; tu->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*tu->phy.otg), GFP_KERNEL); if (!tu->phy.otg) return -ENOMEM; tu->pt_dev = pdev; /* Default mode */ #ifdef CONFIG_TAHVO_USB_HOST_BY_DEFAULT tu->tahvo_mode = TAHVO_MODE_HOST; #else tu->tahvo_mode = TAHVO_MODE_PERIPHERAL; #endif mutex_init(&tu->serialize); tu->ick = devm_clk_get(&pdev->dev, "usb_l4_ick"); if (!IS_ERR(tu->ick)) clk_enable(tu->ick); /* * Set initial state, so that we generate kevents only on state changes. */ tu->vbus_state = retu_read(rdev, TAHVO_REG_IDSR) & TAHVO_STAT_VBUS; tu->extcon.name = DRIVER_NAME; tu->extcon.supported_cable = tahvo_cable; tu->extcon.dev.parent = &pdev->dev; ret = extcon_dev_register(&tu->extcon); if (ret) { dev_err(&pdev->dev, "could not register extcon device: %d\n", ret); goto err_disable_clk; } /* Set the initial cable state. */ extcon_set_cable_state(&tu->extcon, "USB-HOST", tu->tahvo_mode == TAHVO_MODE_HOST); extcon_set_cable_state(&tu->extcon, "USB", tu->vbus_state); /* Create OTG interface */ tahvo_usb_power_off(tu); tu->phy.dev = &pdev->dev; tu->phy.state = OTG_STATE_UNDEFINED; tu->phy.label = DRIVER_NAME; tu->phy.set_suspend = tahvo_usb_set_suspend; tu->phy.otg->phy = &tu->phy; tu->phy.otg->set_host = tahvo_usb_set_host; tu->phy.otg->set_peripheral = tahvo_usb_set_peripheral; ret = usb_add_phy(&tu->phy, USB_PHY_TYPE_USB2); if (ret < 0) { dev_err(&pdev->dev, "cannot register USB transceiver: %d\n", ret); goto err_extcon_unreg; } dev_set_drvdata(&pdev->dev, tu); tu->irq = platform_get_irq(pdev, 0); ret = request_threaded_irq(tu->irq, NULL, tahvo_usb_vbus_interrupt, 0, "tahvo-vbus", tu); if (ret) { dev_err(&pdev->dev, "could not register tahvo-vbus irq: %d\n", ret); goto err_remove_phy; } /* Attributes */ ret = sysfs_create_group(&pdev->dev.kobj, &tahvo_attr_group); if (ret) { dev_err(&pdev->dev, "cannot create sysfs group: %d\n", ret); goto err_free_irq; } return 0; err_free_irq: free_irq(tu->irq, tu); err_remove_phy: usb_remove_phy(&tu->phy); err_extcon_unreg: extcon_dev_unregister(&tu->extcon); err_disable_clk: if (!IS_ERR(tu->ick)) clk_disable(tu->ick); return ret; }
static int mv_otg_probe(struct platform_device *pdev) { struct mv_usb_platform_data *pdata = dev_get_platdata(&pdev->dev); struct mv_otg *mvotg; struct usb_otg *otg; struct resource *r; int retval = 0, i; 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); 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.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; for (i = 0; i < OTG_TIMER_NUM; i++) init_timer(&mvotg->otg_ctrl.timer[i]); r = platform_get_resource_byname(mvotg->pdev, IORESOURCE_MEM, "phyregs"); if (r == NULL) { dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); retval = -ENODEV; goto err_destroy_workqueue; } mvotg->phy_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); if (mvotg->phy_regs == NULL) { dev_err(&pdev->dev, "failed to map phy I/O memory\n"); retval = -EFAULT; goto err_destroy_workqueue; } r = platform_get_resource_byname(mvotg->pdev, IORESOURCE_MEM, "capregs"); 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; } /* 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->id) { retval = devm_request_threaded_irq(&pdev->dev, pdata->id->irq, NULL, mv_otg_inputs_irq, IRQF_ONESHOT, "id", mvotg); if (retval) { dev_info(&pdev->dev, "Failed to request irq for ID\n"); pdata->id = NULL; } } if (pdata->vbus) { mvotg->clock_gating = 1; retval = devm_request_threaded_irq(&pdev->dev, pdata->vbus->irq, NULL, mv_otg_inputs_irq, IRQF_ONESHOT, "vbus", mvotg); if (retval) { dev_info(&pdev->dev, "Failed to request irq for VBUS, " "disable clock gating\n"); mvotg->clock_gating = 0; pdata->vbus = NULL; } } 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(&mvotg->phy, USB_PHY_TYPE_USB2); if (retval < 0) { dev_err(&pdev->dev, "can't register transceiver, %d\n", retval); goto err_disable_clk; } 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_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"); return 0; err_remove_phy: usb_remove_phy(&mvotg->phy); err_disable_clk: mv_otg_disable_internal(mvotg); err_destroy_workqueue: flush_workqueue(mvotg->qwork); destroy_workqueue(mvotg->qwork); return retval; }
static int samsung_usbphy_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); if (!phy_mem) { dev_err(dev, "%s: missing mem resource\n", __func__); return -ENODEV; } 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) 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-usbphy"; sphy->phy.init = samsung_usbphy_init; sphy->phy.shutdown = samsung_usbphy_shutdown; 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; spin_lock_init(&sphy->lock); platform_set_drvdata(pdev, sphy); return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2); }
static struct dwc_otg2 *dwc3_otg_alloc(struct device *dev) { struct dwc_otg2 *otg = NULL; struct usb_phy *usb_phy; int retval; otg = kzalloc(sizeof(*otg), GFP_KERNEL); if (!otg) { dev_err(dev, "Alloc otg failed\n"); return NULL; } the_transceiver = otg; otg->otg_data = dev->platform_data; usb_phy = &otg->usb2_phy; otg->otg.phy = usb_phy; otg->usb2_phy.otg = &otg->otg; otg->dev = dev; otg->usb3_phy.dev = otg->dev; otg->usb3_phy.label = "dwc-usb3-phy"; otg->usb3_phy.state = OTG_STATE_UNDEFINED; otg->usb3_phy.otg = &otg->otg; otg->usb2_phy.dev = otg->dev; otg->usb2_phy.label = "dwc-usb2-phy"; otg->usb2_phy.state = OTG_STATE_UNDEFINED; otg->usb2_phy.set_power = dwc3_otg_pdata->set_power; otg->usb2_phy.get_chrg_status = dwc_otg_get_chrg_status; otg->usb2_phy.io_ops = &dwc_otg_io_ops; otg->usb2_phy.otg = &otg->otg; otg->otg.set_host = dwc_otg2_set_host; otg->otg.set_peripheral = dwc_otg2_set_peripheral; ATOMIC_INIT_NOTIFIER_HEAD(&otg->usb2_phy.notifier); ATOMIC_INIT_NOTIFIER_HEAD(&otg->usb3_phy.notifier); otg->state = DWC_STATE_B_IDLE; spin_lock_init(&otg->lock); init_waitqueue_head(&otg->main_wq); /* Register otg notifier to monitor ID and VBus change events */ otg->nb.notifier_call = dwc_otg_handle_notification; usb_register_notifier(&otg->usb2_phy, &otg->nb); otg_dbg(otg, "Version: %s\n", VERSION); retval = usb_add_phy(&otg->usb2_phy, USB_PHY_TYPE_USB2); if (retval) { otg_err(otg, "can't register transceiver, err: %d\n", retval); goto err1; } retval = usb_add_phy(&otg->usb3_phy, USB_PHY_TYPE_USB3); if (retval) { otg_err(otg, "can't register transceiver, err: %d\n", retval); goto err2; } return otg; err2: usb_remove_phy(&otg->usb2_phy); err1: kfree(otg); otg = NULL; return otg; }
static int isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { int status; struct isp1301 *isp; if (the_transceiver) return 0; isp = kzalloc(sizeof *isp, GFP_KERNEL); if (!isp) return 0; isp->phy.otg = kzalloc(sizeof *isp->phy.otg, GFP_KERNEL); if (!isp->phy.otg) { kfree(isp); return 0; } INIT_WORK(&isp->work, isp1301_work); init_timer(&isp->timer); isp->timer.function = isp1301_timer; isp->timer.data = (unsigned long) isp; i2c_set_clientdata(i2c, isp); isp->client = i2c; /* verify the chip (shouldn't be necessary) */ status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); if (status != I2C_VENDOR_ID_PHILIPS) { dev_dbg(&i2c->dev, "not philips id: %d\n", status); goto fail; } status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); if (status != I2C_PRODUCT_ID_PHILIPS_1301) { dev_dbg(&i2c->dev, "not isp1301, %d\n", status); goto fail; } isp->i2c_release = i2c->dev.release; i2c->dev.release = isp1301_release; /* initial development used chiprev 2.00 */ status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE); dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n", status >> 8, status & 0xff); /* make like power-on reset */ isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK); isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI); isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI); isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, ~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN)); isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0); isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); #ifdef CONFIG_USB_OTG status = otg_bind(isp); if (status < 0) { dev_dbg(&i2c->dev, "can't bind OTG\n"); goto fail; } #endif if (machine_is_omap_h2()) { /* full speed signaling by default */ isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SPEED); isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_SPD_SUSP_CTRL); /* IRQ wired at M14 */ omap_cfg_reg(M14_1510_GPIO2); if (gpio_request(2, "isp1301") == 0) gpio_direction_input(2); isp->irq_type = IRQF_TRIGGER_FALLING; } status = request_irq(i2c->irq, isp1301_irq, isp->irq_type, DRIVER_NAME, isp); if (status < 0) { dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", i2c->irq, status); goto fail; } isp->phy.dev = &i2c->dev; isp->phy.label = DRIVER_NAME; isp->phy.set_power = isp1301_set_power, isp->phy.otg->phy = &isp->phy; isp->phy.otg->set_host = isp1301_set_host, isp->phy.otg->set_peripheral = isp1301_set_peripheral, isp->phy.otg->start_srp = isp1301_start_srp, isp->phy.otg->start_hnp = isp1301_start_hnp, enable_vbus_draw(isp, 0); power_down(isp); the_transceiver = isp; #ifdef CONFIG_USB_OTG update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); #endif dump_regs(isp, __func__); #ifdef VERBOSE mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); #endif status = usb_add_phy(&isp->phy, USB_PHY_TYPE_USB2); if (status < 0) dev_err(&i2c->dev, "can't register transceiver, %d\n", status); return 0; fail: kfree(isp->phy.otg); kfree(isp); return -ENODEV; }
static int __init gpio_vbus_probe(struct platform_device *pdev) { struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; struct gpio_vbus_data *gpio_vbus; struct resource *res; int err, gpio, irq; if (!pdata || !gpio_is_valid(pdata->gpio_vbus)) return -EINVAL; gpio = pdata->gpio_vbus; gpio_vbus = kzalloc(sizeof(struct gpio_vbus_data), GFP_KERNEL); if (!gpio_vbus) return -ENOMEM; gpio_vbus->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); if (!gpio_vbus->phy.otg) { kfree(gpio_vbus); return -ENOMEM; } platform_set_drvdata(pdev, gpio_vbus); gpio_vbus->dev = &pdev->dev; gpio_vbus->phy.label = "gpio-vbus"; gpio_vbus->phy.set_power = gpio_vbus_set_power; gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; gpio_vbus->phy.state = OTG_STATE_UNDEFINED; gpio_vbus->phy.otg->phy = &gpio_vbus->phy; gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; err = gpio_request(gpio, "vbus_detect"); if (err) { dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", gpio, err); goto err_gpio; } gpio_direction_input(gpio); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res) { irq = res->start; res->flags &= IRQF_TRIGGER_MASK; res->flags |= IRQF_SAMPLE_RANDOM | IRQF_SHARED; } else irq = gpio_to_irq(gpio); /* if data line pullup is in use, initialize it to "not pulling up" */ gpio = pdata->gpio_pullup; if (gpio_is_valid(gpio)) { err = gpio_request(gpio, "udc_pullup"); if (err) { dev_err(&pdev->dev, "can't request pullup gpio %d, err: %d\n", gpio, err); gpio_free(pdata->gpio_vbus); goto err_gpio; } gpio_direction_output(gpio, pdata->gpio_pullup_inverted); } err = request_irq(irq, gpio_vbus_irq, VBUS_IRQ_FLAGS, "vbus_detect", pdev); if (err) { dev_err(&pdev->dev, "can't request irq %i, err: %d\n", irq, err); goto err_irq; } ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); INIT_WORK(&gpio_vbus->work, gpio_vbus_work); gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); if (IS_ERR(gpio_vbus->vbus_draw)) { dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", PTR_ERR(gpio_vbus->vbus_draw)); gpio_vbus->vbus_draw = NULL; } /* only active when a gadget is registered */ err = usb_add_phy(&gpio_vbus->phy, USB_PHY_TYPE_USB2); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); goto err_otg; } return 0; err_otg: free_irq(irq, &pdev->dev); err_irq: if (gpio_is_valid(pdata->gpio_pullup)) gpio_free(pdata->gpio_pullup); gpio_free(pdata->gpio_vbus); err_gpio: platform_set_drvdata(pdev, NULL); kfree(gpio_vbus->phy.otg); kfree(gpio_vbus); return err; }