コード例 #1
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;
}
コード例 #2
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;
}
コード例 #3
0
int mv_otg_remove(struct platform_device *dev)
{
	struct mv_otg *mvotg = platform_get_drvdata(dev);

	BUG_ON(mvotg != the_transceiver);


	if (mvotg->pdata->vbus) {
		free_irq(mvotg->pdata->vbus->irq, mvotg);
	}
	if (mvotg->pdata->id) {
		free_irq(mvotg->pdata->id->irq, mvotg);
	}

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

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

	if (mvotg->irq)
		free_irq(mvotg->irq, mvotg);

	mv_otg_disable(mvotg);

	if (mvotg->cap_regs)
		iounmap(mvotg->cap_regs);

	if (mvotg->phy_regs)
		iounmap((void *)mvotg->phy_regs);

	otg_set_transceiver(NULL);
	platform_set_drvdata(dev, NULL);

	kfree(mvotg);
	the_transceiver = NULL;

	return 0;
}
コード例 #4
0
static void mv_otg_work(struct work_struct *work)
{
	struct mv_otg *mvotg;
	struct usb_phy *phy;
	struct usb_otg *otg;
	int old_state;

	mvotg = container_of(to_delayed_work(work), struct mv_otg, work);

run:
	/* work queue is single thread, or we need spin_lock to protect */
	phy = &mvotg->phy;
	otg = phy->otg;
	old_state = phy->state;

	if (!mvotg->active)
		return;

	mv_otg_update_inputs(mvotg);
	mv_otg_update_state(mvotg);

	if (old_state != phy->state) {
		dev_info(&mvotg->pdev->dev, "change from state %s to %s\n",
			 state_string[old_state],
			 state_string[phy->state]);

		switch (phy->state) {
		case OTG_STATE_B_IDLE:
			otg->default_a = 0;
			if (old_state == OTG_STATE_B_PERIPHERAL)
				mv_otg_start_periphrals(mvotg, 0);
			mv_otg_reset(mvotg);
			mv_otg_disable(mvotg);
			break;
		case OTG_STATE_B_PERIPHERAL:
			mv_otg_enable(mvotg);
			mv_otg_start_periphrals(mvotg, 1);
			break;
		case OTG_STATE_A_IDLE:
			otg->default_a = 1;
			mv_otg_enable(mvotg);
			if (old_state == OTG_STATE_A_WAIT_VFALL)
				mv_otg_start_host(mvotg, 0);
			mv_otg_reset(mvotg);
			break;
		case OTG_STATE_A_WAIT_VRISE:
			mv_otg_set_vbus(otg, 1);
			break;
		case OTG_STATE_A_WAIT_BCON:
			if (old_state != OTG_STATE_A_HOST)
				mv_otg_start_host(mvotg, 1);
			mv_otg_set_timer(mvotg, A_WAIT_BCON_TIMER,
					 T_A_WAIT_BCON,
					 mv_otg_timer_await_bcon);
			/*
			 * Now, we directly enter A_HOST. So set b_conn = 1
			 * here. In fact, it need host driver to notify us.
			 */
			mvotg->otg_ctrl.b_conn = 1;
			break;
		case OTG_STATE_A_HOST:
			break;
		case OTG_STATE_A_WAIT_VFALL:
			/*
			 * Now, we has exited A_HOST. So set b_conn = 0
			 * here. In fact, it need host driver to notify us.
			 */
			mvotg->otg_ctrl.b_conn = 0;
			mv_otg_set_vbus(otg, 0);
			break;
		case OTG_STATE_A_VBUS_ERR:
			break;
		default:
			break;
		}
		goto run;
	}
}