static void dwc_otg_remove(struct pci_dev *pdev)
{
	struct dwc_otg2 *otg = the_transceiver;
	int resource, len;

	if (otg->gadget)
		platform_device_unregister(otg->gadget);
	if (otg->host)
		platform_device_unregister(otg->host);

	wake_lock_destroy(&wakelock);

	pm_runtime_forbid(&pdev->dev);
	pm_runtime_set_suspended(&pdev->dev);

	kfree(platform_par);
	iounmap(otg->usb2_phy.io_priv);

	usb_remove_phy(&otg->usb2_phy);
	usb_remove_phy(&otg->usb3_phy);
	kfree(otg);
	otg = NULL;

	resource = pci_resource_start(pdev, 0);
	len = pci_resource_len(pdev, 0);
	release_mem_region(resource, len);

	pci_disable_device(pdev);

	the_transceiver = NULL;
}
Beispiel #2
0
static int am335x_phy_remove(struct platform_device *pdev)
{
	struct am335x_phy *am_phy = platform_get_drvdata(pdev);

	usb_remove_phy(&am_phy->usb_phy_gen.phy);
	return 0;
}
int mv_otg_remove(struct platform_device *pdev)
{
	struct mv_otg *mvotg = platform_get_drvdata(pdev);

	device_init_wakeup(&pdev->dev, 0);

	sysfs_remove_group(&mvotg->pdev->dev.kobj, &inputs_attr_group);

	if (mvotg->qwork) {
		flush_workqueue(mvotg->qwork);
		destroy_workqueue(mvotg->qwork);
	}

	if (mvotg->pdata->extern_attr
		& (MV_USB_HAS_VBUS_DETECTION | MV_USB_HAS_IDPIN_DETECTION))
		pxa_usb_unregister_notifier(mvotg->pdata->id, &mvotg->notifier);

	mv_otg_disable(mvotg);

	clk_unprepare(mvotg->clk);

	pm_qos_remove_request(&mvotg->qos_idle);

	usb_remove_phy(&mvotg->phy);

	return 0;
}
Beispiel #4
0
static int keystone_usbphy_remove(struct platform_device *pdev)
{
	struct keystone_usbphy *k_phy = platform_get_drvdata(pdev);

	usb_remove_phy(&k_phy->usb_phy_gen.phy);

	return 0;
}
Beispiel #5
0
static int rcar_usb_phy_remove(struct platform_device *pdev)
{
	struct rcar_usb_phy_priv *priv = platform_get_drvdata(pdev);

	usb_remove_phy(&priv->phy);

	return 0;
}
Beispiel #6
0
static int usb_phy_gen_xceiv_remove(struct platform_device *pdev)
{
	struct usb_phy_gen_xceiv *nop = platform_get_drvdata(pdev);

	usb_remove_phy(&nop->phy);

	return 0;
}
static int mxs_phy_remove(struct platform_device *pdev)
{
	struct mxs_phy *mxs_phy = platform_get_drvdata(pdev);

	usb_remove_phy(&mxs_phy->phy);

	return 0;
}
Beispiel #8
0
static int omap_usb2_remove(struct platform_device *pdev)
{
	struct omap_usb	*phy = platform_get_drvdata(pdev);

	usb_remove_phy(&phy->phy);
	pm_runtime_disable(phy->dev);

	return 0;
}
Beispiel #9
0
static int __devexit omap_usb2_remove(struct platform_device *pdev)
{
	struct omap_usb	*phy = platform_get_drvdata(pdev);

	usb_remove_phy(&phy->phy);
	platform_set_drvdata(pdev, NULL);

	return 0;
}
Beispiel #10
0
static int isp1301_remove(struct i2c_client *client)
{
	struct isp1301 *isp = i2c_get_clientdata(client);

	usb_remove_phy(&isp->phy);
	isp1301_i2c_client = NULL;

	return 0;
}
Beispiel #11
0
static int nop_usb_xceiv_remove(struct platform_device *pdev)
{
	struct nop_usb_xceiv *nop = platform_get_drvdata(pdev);

	if (!IS_ERR(nop->clk))
		clk_unprepare(nop->clk);

	usb_remove_phy(&nop->phy);

	return 0;
}
Beispiel #12
0
static int omap_usb2_remove(struct platform_device *pdev)
{
	struct omap_usb	*phy = platform_get_drvdata(pdev);

	clk_unprepare(phy->wkupclk);
	if (!IS_ERR(phy->optclk))
		clk_unprepare(phy->optclk);
	usb_remove_phy(&phy->phy);

	return 0;
}
static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev)
{
	struct nop_usb_xceiv *nop = platform_get_drvdata(pdev);

	usb_remove_phy(&nop->phy);

	platform_set_drvdata(pdev, NULL);
	kfree(nop->phy.otg);
	kfree(nop);

	return 0;
}
Beispiel #14
0
static int omap_usb3_remove(struct platform_device *pdev)
{
	struct omap_usb *phy = platform_get_drvdata(pdev);

	clk_unprepare(phy->wkupclk);
	clk_unprepare(phy->optclk);
	usb_remove_phy(&phy->phy);
	if (!pm_runtime_suspended(&pdev->dev))
		pm_runtime_put(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

	return 0;
}
Beispiel #15
0
static int tahvo_usb_remove(struct platform_device *pdev)
{
	struct tahvo_usb *tu = platform_get_drvdata(pdev);

	sysfs_remove_group(&pdev->dev.kobj, &tahvo_attr_group);
	free_irq(tu->irq, tu);
	usb_remove_phy(&tu->phy);
	extcon_dev_unregister(&tu->extcon);
	if (!IS_ERR(tu->ick))
		clk_disable(tu->ick);

	return 0;
}
Beispiel #16
0
static int __exit mv_u3d_phy_remove(struct platform_device *pdev)
{
	struct mv_u3d_phy *mv_u3d_phy = platform_get_drvdata(pdev);

	usb_remove_phy(&mv_u3d_phy->phy);

	if (mv_u3d_phy->clk) {
		clk_put(mv_u3d_phy->clk);
		mv_u3d_phy->clk = NULL;
	}

	return 0;
}
Beispiel #17
0
static int samsung_usbphy_remove(struct platform_device *pdev)
{
	struct samsung_usbphy *sphy = platform_get_drvdata(pdev);

	usb_remove_phy(&sphy->phy);

	if (sphy->pmuregs)
		iounmap(sphy->pmuregs);
	if (sphy->sysreg)
		iounmap(sphy->sysreg);

	return 0;
}
static int msm_ssphy_remove(struct platform_device *pdev)
{
	struct msm_ssphy *phy = platform_get_drvdata(pdev);

	if (!phy)
		return 0;

	usb_remove_phy(&phy->phy);
	msm_ssusb_ldo_enable(phy, 0);
	regulator_disable(phy->vdd);
	msm_ssusb_config_vdd(phy, 0);
	kfree(phy);

	return 0;
}
static int msm_otg_remove(struct platform_device *pdev)
{
	struct msm_otg *motg = platform_get_drvdata(pdev);
	struct usb_phy *phy = &motg->phy;
	int cnt = 0;

	if (phy->otg->host || phy->otg->gadget)
		return -EBUSY;

	msm_otg_debugfs_cleanup();
	cancel_delayed_work_sync(&motg->chg_work);
	cancel_work_sync(&motg->sm_work);

	pm_runtime_resume(&pdev->dev);

	device_init_wakeup(&pdev->dev, 0);
	pm_runtime_disable(&pdev->dev);

	usb_remove_phy(phy);
	disable_irq(motg->irq);

	/*
	 * Put PHY in low power mode.
	 */
	ulpi_read(phy, 0x14);
	ulpi_write(phy, 0x08, 0x09);

	writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC);
	while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
		if (readl(USB_PORTSC) & PORTSC_PHCD)
			break;
		udelay(1);
		cnt++;
	}
	if (cnt >= PHY_SUSPEND_TIMEOUT_USEC)
		dev_err(phy->dev, "Unable to suspend PHY\n");

	clk_disable_unprepare(motg->pclk);
	clk_disable_unprepare(motg->clk);
	if (!IS_ERR(motg->core_clk))
		clk_disable_unprepare(motg->core_clk);
	msm_hsusb_ldo_init(motg, 0);

	pm_runtime_set_suspended(&pdev->dev);

	return 0;
}
Beispiel #20
0
static int mv_otg_remove(struct platform_device *pdev)
{
	struct mv_otg *mvotg = platform_get_drvdata(pdev);

	sysfs_remove_group(&mvotg->pdev->dev.kobj, &inputs_attr_group);

	if (mvotg->qwork) {
		flush_workqueue(mvotg->qwork);
		destroy_workqueue(mvotg->qwork);
	}

	mv_otg_disable(mvotg);

	usb_remove_phy(&mvotg->phy);

	return 0;
}
static int msm_ssphy_qmp_remove(struct platform_device *pdev)
{
	struct msm_ssphy_qmp *phy = platform_get_drvdata(pdev);

	if (!phy)
		return 0;

	usb_remove_phy(&phy->phy);
	msm_ssusb_qmp_ldo_enable(phy, 0);
	regulator_disable(phy->vdd);
	msm_ssusb_qmp_config_vdd(phy, 0);
	clk_disable_unprepare(phy->aux_clk);
	clk_disable_unprepare(phy->cfg_ahb_clk);
	clk_disable_unprepare(phy->pipe_clk);
	kfree(phy);
	return 0;
}
Beispiel #22
0
static int __exit gpio_vbus_remove(struct platform_device *pdev)
{
	struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
	struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
	int gpio = pdata->gpio_vbus;

	regulator_put(gpio_vbus->vbus_draw);

	usb_remove_phy(&gpio_vbus->phy);

	free_irq(gpio_to_irq(gpio), &pdev->dev);
	if (gpio_is_valid(pdata->gpio_pullup))
		gpio_free(pdata->gpio_pullup);
	gpio_free(gpio);
	platform_set_drvdata(pdev, NULL);
	kfree(gpio_vbus->phy.otg);
	kfree(gpio_vbus);

	return 0;
}
static int gpio_vbus_remove(struct platform_device *pdev)
{
	struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
	struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev);
	int gpio = pdata->gpio_vbus;

	device_init_wakeup(&pdev->dev, 0);
	cancel_delayed_work_sync(&gpio_vbus->work);
	regulator_put(gpio_vbus->vbus_draw);

	usb_remove_phy(&gpio_vbus->phy);

	free_irq(gpio_vbus->irq, pdev);
	if (gpio_is_valid(pdata->gpio_pullup))
		gpio_free(pdata->gpio_pullup);
	gpio_free(gpio);
	kfree(gpio_vbus->phy.otg);
	kfree(gpio_vbus);

	return 0;
}
static int msm_hsphy_remove(struct platform_device *pdev)
{
	struct msm_hsphy *phy = platform_get_drvdata(pdev);

	if (!phy)
		return 0;

	usb_remove_phy(&phy->phy);
	clk_disable_unprepare(phy->sleep_clk);

	/* Undo the additional regulator enable */
	if (phy->vdda_force_on)
		msm_hsusb_ldo_enable(phy, 0);
	msm_hsusb_ldo_enable(phy, 0);
	regulator_disable(phy->vdd);
	msm_hsusb_config_vdd(phy, 0);
	if (!phy->suspended)
		atomic_dec(&hsphy_active_count);
	kfree(phy);

	return 0;
}
Beispiel #25
0
static int twl4030_usb_remove(struct platform_device *pdev)
{
	struct twl4030_usb *twl = platform_get_drvdata(pdev);
	int val;

	usb_remove_phy(&twl->phy);
	pm_runtime_get_sync(twl->dev);
	cancel_delayed_work(&twl->id_workaround_work);
	device_remove_file(twl->dev, &dev_attr_vbus);

	/* set transceiver mode to power on defaults */
	twl4030_usb_set_mode(twl, -1);

	/* idle ulpi before powering off */
	if (cable_present(twl->linkstat))
		pm_runtime_put_noidle(twl->dev);
	pm_runtime_mark_last_busy(twl->dev);
	pm_runtime_put_sync_suspend(twl->dev);
	pm_runtime_disable(twl->dev);

	/* autogate 60MHz ULPI clock,
	 * clear dpll clock request for i2c access,
	 * disable 32KHz
	 */
	val = twl4030_usb_read(twl, PHY_CLK_CTRL);
	if (val >= 0) {
		val |= PHY_CLK_CTRL_CLOCKGATING_EN;
		val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK);
		twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val);
	}

	/* disable complete OTG block */
	twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);

	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 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;
}
Beispiel #28
0
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;
}
Beispiel #29
0
static void __exit isp_exit(void)
{
	if (the_transceiver)
		usb_remove_phy(&the_transceiver->phy);
	i2c_del_driver(&isp1301_driver);
}
Beispiel #30
0
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;
}