Example #1
0
/* the root hub will call this callback when device added/removed */
static void otg_notify(struct usb_device *udev, unsigned action)
{
	struct otg_transceiver *otg;
	struct intel_mid_otg_xceiv *iotg;

	/* Ignore root hub add/remove event */
	if (!udev->parent) {
		pr_debug("%s Ignore root hub otg_notify\n", __func__);
		return;
	}

	/* Ignore USB devices on external hub */
	if (udev->parent && udev->parent->parent)
		return;

	otg = otg_get_transceiver();
	if (otg == NULL) {
		printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__);
		return;
	}
	iotg = otg_to_mid_xceiv(otg);

	switch (action) {
	case USB_DEVICE_ADD:
		pr_debug("Notify OTG HNP add device\n");
		atomic_notifier_call_chain(&iotg->iotg_notifier,
					MID_OTG_NOTIFY_CONNECT, iotg);
		break;
	case USB_DEVICE_REMOVE:
		pr_debug("Notify OTG HNP delete device\n");
		atomic_notifier_call_chain(&iotg->iotg_notifier,
					MID_OTG_NOTIFY_DISCONN, iotg);
		break;
	case USB_OTG_TESTDEV:
		pr_debug("Notify OTG test device\n");
		atomic_notifier_call_chain(&iotg->iotg_notifier,
					MID_OTG_NOTIFY_TEST, iotg);
		break;
	case USB_OTG_TESTDEV_VBUSOFF:
		pr_debug("Notify OTG test device, Vbusoff mode\n");
		atomic_notifier_call_chain(&iotg->iotg_notifier,
					MID_OTG_NOTIFY_TEST_VBUS_OFF, iotg);
		break;
	default:
		otg_put_transceiver(otg);
		return ;
	}
	otg_put_transceiver(otg);
	return;
}
Example #2
0
static void intel_mid_ehci_driver_unregister(struct pci_driver *host_driver)
{
	struct otg_transceiver		*otg;
	struct intel_mid_otg_xceiv	*iotg;

	otg = otg_get_transceiver();
	if (otg == NULL)
		return ;

	iotg = otg_to_mid_xceiv(otg);
	iotg->start_host = NULL;
	iotg->stop_host = NULL;
#ifdef CONFIG_PM_RUNTIME
	iotg->runtime_suspend_host = NULL;
	iotg->runtime_resume_host = NULL;
#endif
#ifdef CONFIG_USB_SUSPEND
	wake_lock_destroy(&iotg->wake_lock);
#endif

	/* notify host driver is unregistered */
	atomic_notifier_call_chain(&iotg->iotg_notifier,
				MID_OTG_NOTIFY_HOSTREMOVE, iotg);

	otg_put_transceiver(otg);
}
Example #3
0
static int __exit twl4030_bci_remove(struct platform_device *pdev)
{
    struct twl4030_bci *bci = platform_get_drvdata(pdev);

    twl4030_charger_enable_ac(false);
    twl4030_charger_enable_usb(bci, false);

    /* mask interrupts */
    twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
                     TWL4030_INTERRUPTS_BCIIMR1A);
    twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
                     TWL4030_INTERRUPTS_BCIIMR2A);

    if (bci->transceiver != NULL) {
        otg_unregister_notifier(bci->transceiver, &bci->otg_nb);
        otg_put_transceiver(bci->transceiver);
    }
    free_irq(bci->irq_bci, bci);
    free_irq(bci->irq_chg, bci);
    power_supply_unregister(&bci->usb);
    power_supply_unregister(&bci->ac);
    platform_set_drvdata(pdev, NULL);
    kfree(bci);

    return 0;
}
Example #4
0
static int pda_power_remove(struct platform_device *pdev)
{
	if (pdata->is_usb_online && usb_irq)
		free_irq(usb_irq->start, &pda_psy_usb);
	if (pdata->is_ac_online && ac_irq)
		free_irq(ac_irq->start, &pda_psy_ac);

	if (polling)
		del_timer_sync(&polling_timer);
	del_timer_sync(&charger_timer);

	if (pdata->is_usb_online)
		power_supply_unregister(&pda_psy_usb);
	if (pdata->is_ac_online)
		power_supply_unregister(&pda_psy_ac);
#ifdef CONFIG_USB_OTG_UTILS
	if (transceiver)
		otg_put_transceiver(transceiver);
#endif
	if (ac_draw) {
		regulator_put(ac_draw);
		ac_draw = NULL;
	}
	if (pdata->exit)
		pdata->exit(dev);

	return 0;
}
Example #5
0
static int intel_mid_ehci_driver_register(struct pci_driver *host_driver)
{
	struct otg_transceiver		*otg;
	struct intel_mid_otg_xceiv	*iotg;

	otg = otg_get_transceiver();
	if (otg == NULL || host_driver == NULL)
		return -EINVAL;

	iotg = otg_to_mid_xceiv(otg);
	iotg->start_host = ehci_mid_start_host;
	iotg->stop_host = ehci_mid_stop_host;
#ifdef CONFIG_PM_RUNTIME
	iotg->runtime_suspend_host = ehci_mid_runtime_suspend_host;
	iotg->runtime_resume_host = ehci_mid_runtime_resume_host;
#endif
#ifdef CONFIG_SUSPEND
	iotg->suspend_host = ehci_mid_suspend_host;
	iotg->suspend_noirq_host = ehci_mid_suspend_noirq_host;
	iotg->resume_host = ehci_mid_resume_host;
	iotg->resume_noirq_host = ehci_mid_resume_noirq_host;
#endif

#ifdef CONFIG_USB_SUSPEND
	wake_lock_init(&iotg->wake_lock, WAKE_LOCK_SUSPEND, "ehci_wake_lock");
#endif

	/* notify host driver is registered */
	atomic_notifier_call_chain(&iotg->iotg_notifier,
				MID_OTG_NOTIFY_HOSTADD, iotg);

	otg_put_transceiver(otg);

	return 0;
}
int musb_platform_exit(struct musb *musb)
{

	musb_platform_suspend(musb);

	otg_put_transceiver(musb->xceiv);
	return 0;
}
Example #7
0
static int omap2430_musb_exit(struct musb *musb)
{

	omap2430_low_level_exit(musb);
	otg_put_transceiver(musb->xceiv);

	return 0;
}
Example #8
0
static int omap2430_musb_exit(struct musb *musb)
{
	del_timer_sync(&musb_idle_timer);

	omap2430_low_level_exit(musb);
	otg_put_transceiver(musb->xceiv);

	return 0;
}
Example #9
0
int musb_platform_exit(struct musb *musb)
{
	del_timer_sync(&musb_idle_timer);

	musb_platform_suspend(musb);

	otg_put_transceiver(musb->xceiv);
	return 0;
}
Example #10
0
static int tegra_ehci_remove(struct platform_device *pdev)
{
	struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev);
	struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci);

	dev_info(&pdev->dev, "%s+\n", __func__);		//htc_dbg

	if (tegra == NULL || hcd == NULL)
		return -EINVAL;

#ifdef CONFIG_USB_OTG_UTILS
	if (tegra->transceiver) {
		otg_set_host(tegra->transceiver, NULL);
		otg_put_transceiver(tegra->transceiver);
	}
#endif

	if (tegra->irq)
		disable_irq_wake(tegra->irq);

	/* Make sure phy is powered ON to access USB register */
	if(!tegra_usb_phy_hw_accessible(tegra->phy))
		tegra_usb_phy_power_on(tegra->phy);

	pr_info("+%s:usb_remove_hcd\n", __func__);
	uhsic_phy_remove(tegra->phy);
	usb_remove_hcd(hcd);
	usb_put_hcd(hcd);
	ehci_remove = 1;
	tegra_usb_phy_power_off(tegra->phy);
	tegra_usb_phy_close(tegra->phy);
	iounmap(hcd->regs);
	platform_set_drvdata(pdev, NULL);

	//htc++
	#ifdef CONFIG_QCT_9K_MODEM
	if (Modem_is_QCT_MDM9K())
	{
		extern struct platform_device tegra_ehci2_device;

		if (&tegra_ehci2_device == pdev)
		{
			mdm_hsic_ehci_hcd = NULL;
			mdm_hsic_usb_hcd = NULL;
			mdm_hsic_phy = NULL;
			pr_info("%s:: mdm_hsic_ehci_hcd = %x, mdm_hsic_usb_hcd = %x, mdm_hsic_phy = %x\n",
				__func__, (unsigned int)mdm_hsic_ehci_hcd, (unsigned int)mdm_hsic_usb_hcd, (unsigned int)mdm_hsic_phy);
		}
	}
	#endif	//CONFIG_QCT_9K_MODEM
	//htc--

	dev_info(&pdev->dev, "%s-\n", __func__);		//htc_dbg

	return 0;
}
Example #11
0
static int __devinit isp1704_charger_probe(struct platform_device *pdev)
{
	struct isp1704_charger	*isp;
	int			ret = -ENODEV;

	isp = kzalloc(sizeof *isp, GFP_KERNEL);
	if (!isp)
		return -ENOMEM;

	isp->otg = otg_get_transceiver();
	if (!isp->otg)
		goto fail0;

	ret = isp1704_test_ulpi(isp);
	if (ret < 0)
		goto fail1;

	isp->dev = &pdev->dev;
	platform_set_drvdata(pdev, isp);

	isp->psy.name		= "isp1704";
	isp->psy.type		= POWER_SUPPLY_TYPE_USB;
	isp->psy.properties	= power_props;
	isp->psy.num_properties	= ARRAY_SIZE(power_props);
	isp->psy.get_property	= isp1704_charger_get_property;

	ret = power_supply_register(isp->dev, &isp->psy);
	if (ret)
		goto fail1;

	/*
	 * REVISIT: using work in order to allow the otg notifications to be
	 * made atomically in the future.
	 */
	INIT_WORK(&isp->work, isp1704_charger_work);

	isp->nb.notifier_call = isp1704_notifier_call;

	ret = otg_register_notifier(isp->otg, &isp->nb);
	if (ret)
		goto fail2;

	dev_info(isp->dev, "registered with product id %s\n", isp->model);

	return 0;
fail2:
	power_supply_unregister(&isp->psy);
fail1:
	otg_put_transceiver(isp->otg);
fail0:
	kfree(isp);

	dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret);

	return ret;
}
Example #12
0
int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
{
	u8	devctl = musb_readb(musb->mregs, MUSB_DEVCTL);

	devctl |= MUSB_DEVCTL_SESSION;
	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);

	otg_put_transceiver(musb->xceiv);
	return 0;
}
Example #13
0
static int omap2430_musb_exit(struct musb *musb)
{
	del_timer_sync(&musb_idle_timer);

	otg_unregister_notifier(musb->xceiv, &musb->nb);
	destroy_workqueue(musb->otg_notifier_wq);
	omap2430_low_level_exit(musb);
	otg_put_transceiver(musb->xceiv);

	return 0;
}
Example #14
0
static int __devexit isp1704_charger_remove(struct platform_device *pdev)
{
	struct isp1704_charger *isp = platform_get_drvdata(pdev);

	otg_unregister_notifier(isp->otg, &isp->nb);
	power_supply_unregister(&isp->psy);
	otg_put_transceiver(isp->otg);
	kfree(isp);

	return 0;
}
int otg_send_event(enum usb_otg_event event)
{
	struct otg_transceiver *otg = otg_get_transceiver();
	int ret = -ENOTSUPP;

	if (otg && otg->send_event)
		ret = otg->send_event(otg, event);

	if (otg)
		otg_put_transceiver(otg);

	return ret;
}
Example #16
0
static int __devexit ehci_msm_remove(struct platform_device *pdev)
{
	struct usb_hcd *hcd = platform_get_drvdata(pdev);

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

	otg_set_host(otg, NULL);
	otg_put_transceiver(otg);

	usb_put_hcd(hcd);

	return 0;
}
Example #17
0
/**
 * usb_hcd_fsl_remove - shutdown processing for FSL-based HCDs
 * @dev: USB Host Controller being removed
 * Context: !in_interrupt()
 *
 * Reverses the effect of usb_hcd_fsl_probe().
 *
 */
static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
			       struct platform_device *pdev)
{
	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
	struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
	u32 tmp;

	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
		/* Need open clock for register access */
		if (pdata->usb_clock_for_pm)
			pdata->usb_clock_for_pm(true);

		tmp = ehci_readl(ehci, &ehci->regs->port_status[0]);
		if (tmp & PORT_PTS_PHCD) {
			tmp &= ~PORT_PTS_PHCD;
			ehci_writel(ehci, tmp, &ehci->regs->port_status[0]);
			msleep(100);

			if (pdata->usb_clock_for_pm)
				pdata->usb_clock_for_pm(false);
		}
	}

	/* DDD shouldn't we turn off the power here? */
	fsl_platform_set_vbus_power(pdata, 0);

	if (ehci->transceiver) {
		(void)otg_set_host(ehci->transceiver, 0);
		otg_put_transceiver(ehci->transceiver);
	} else {
		release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	}

	usb_remove_hcd(hcd);
	usb_put_hcd(hcd);

	/*
	 * do platform specific un-initialization:
	 * release iomux pins, etc.
	 */
	if (pdata->exit)
		pdata->exit(pdata->pdev);

	iounmap(hcd->regs);
}
Example #18
0
static int usb_otg_suspend(struct usb_hcd *hcd)
{
	struct otg_transceiver *otg;
	struct intel_mid_otg_xceiv *iotg;

	otg = otg_get_transceiver();
	if (otg == NULL) {
		printk(KERN_ERR	"%s Failed to get otg transceiver\n", __func__);
		return -EINVAL;
	}
	iotg = otg_to_mid_xceiv(otg);
	printk(KERN_INFO "%s OTG HNP update suspend\n", __func__);

	atomic_notifier_call_chain(&iotg->iotg_notifier,
				MID_OTG_NOTIFY_HSUSPEND, iotg);
	otg_put_transceiver(otg);
	return 0;
}
Example #19
0
static int am35x_musb_exit(struct musb *musb)
{
	struct device *dev = musb->controller;
	struct musb_hdrc_platform_data *plat = dev->platform_data;
	struct omap_musb_board_data *data = plat->board_data;

	if (is_host_enabled(musb))
		del_timer_sync(&otg_workaround);

	/* Shutdown the on-chip PHY and its PLL. */
	if (data->set_phy_power)
		data->set_phy_power(0);

	otg_put_transceiver(musb->xceiv);
	usb_nop_xceiv_unregister();

	return 0;
}
Example #20
0
static int usb_otg_resume(struct usb_hcd *hcd)
{
	struct otg_transceiver *otg;
	struct intel_mid_otg_xceiv *iotg;

	otg = otg_get_transceiver();
	if (otg == NULL) {
		printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__);
		return -EINVAL;
	}
	iotg = otg_to_mid_xceiv(otg);
	dev_dbg(otg->dev, "%s OTG HNP update resume\n", __func__);

	atomic_notifier_call_chain(&iotg->iotg_notifier,
				MID_OTG_NOTIFY_HRESUME, iotg);
	otg_put_transceiver(otg);
	return 0;
}
Example #21
0
static int usb_free(struct usb_info *ui, int ret)
{
	INFO("usb_free(%d)\n", ret);

	if (ui->xceiv)
		otg_put_transceiver(ui->xceiv);

	if (ui->chg_init)
		ui->chg_init(0);

	if (ui->irq)
		free_irq(ui->irq, 0);
	if (ui->pool)
		dma_pool_destroy(ui->pool);
	if (ui->dma)
		dma_free_coherent(&ui->pdev->dev, 4096, ui->buf, ui->dma);
	kfree(ui);
	pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, DRIVER_NAME);
	pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ, DRIVER_NAME);
	return ret;
}
Example #22
0
static void msm_xusb_uninit_host(struct msmusb_hcd *mhcd)
{
	struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
	struct msm_usb_host_platform_data *pdata = mhcd->pdata;

	switch (PHY_TYPE(pdata->phy_info)) {
	case USB_PHY_INTEGRATED:
		if (pdata->vbus_init)
			pdata->vbus_init(0);
		otg_set_host(mhcd->xceiv, NULL);
		otg_put_transceiver(mhcd->xceiv);
		cancel_work_sync(&mhcd->otg_work);
		break;
	case USB_PHY_SERIAL_PMIC:
		iounmap(hcd->regs);
		clk_put(mhcd->clk);
		clk_put(mhcd->pclk);
		msm_fsusb_reset_phy();
		msm_fsusb_rpc_deinit();
		break;
	default:
		pr_err("phy type is bad\n");
	}
}
Example #23
0
/**
 * usb_hcd_fsl_probe - initialize FSL-based HCDs
 * @drvier: Driver to be used for this HCD
 * @pdev: USB Host Controller being probed
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller.
 *
 */
int usb_hcd_fsl_probe(const struct hc_driver *driver,
		      struct platform_device *pdev)
{
	struct fsl_usb2_platform_data *pdata;
	struct usb_hcd *hcd;
	struct resource *res;
	int irq;
	int retval;

	pr_debug("initializing FSL-SOC USB Controller\n");

	/* Need platform data for setup */
	pdata = (struct fsl_usb2_platform_data *)pdev->dev.platform_data;
	if (!pdata) {
		dev_err(&pdev->dev,
			"No platform data for %s.\n", dev_name(&pdev->dev));
		return -ENODEV;
	}

	/*
	 * This is a host mode driver, verify that we're supposed to be
	 * in host mode.
	 */
	if (!((pdata->operating_mode == FSL_USB2_DR_HOST) ||
	      (pdata->operating_mode == FSL_USB2_MPH_HOST) ||
	      (pdata->operating_mode == FSL_USB2_DR_OTG))) {
		dev_err(&pdev->dev,
			"Non Host Mode configured for %s. Wrong driver linked.\n",
			dev_name(&pdev->dev));
		return -ENODEV;
	}

	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto err1;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev,
			"Found HC with no IRQ. Check %s setup!\n",
			dev_name(&pdev->dev));
		return -ENODEV;
	}
	irq = res->start;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	if (pdata->operating_mode != FSL_USB2_DR_OTG) {
		if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
					driver->description)) {
			dev_dbg(&pdev->dev, "controller already in use\n");
			retval = -EBUSY;
			goto err2;
		}
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);

	if (hcd->regs == NULL) {
		dev_dbg(&pdev->dev, "error mapping memory\n");
		retval = -EFAULT;
		goto err3;
	}
	pdata->regs = hcd->regs;

	/*
	 * do platform specific init: check the clock, grab/config pins, etc.
	 */
	if (pdata->init && pdata->init(pdev)) {
		retval = -ENODEV;
		goto err3;
	}

	fsl_platform_set_host_mode(hcd);
	hcd->power_budget = pdata->power_budget;

	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (retval != 0)
		goto err4;

	if (pdata->operating_mode == FSL_USB2_DR_OTG) {
		struct ehci_hcd *ehci = hcd_to_ehci(hcd);

		dbg("pdev=0x%p  hcd=0x%p  ehci=0x%p\n", pdev, hcd, ehci);

		ehci->transceiver = otg_get_transceiver();
		dbg("ehci->transceiver=0x%p\n", ehci->transceiver);

		if (!ehci->transceiver) {
			printk(KERN_ERR "can't find transceiver\n");
			retval = -ENODEV;
			goto err5;
		}

		retval = otg_set_host(ehci->transceiver, &ehci_to_hcd(ehci)->self);
		if (retval)
			otg_put_transceiver(ehci->transceiver);
	} else if ((pdata->operating_mode == FSL_USB2_MPH_HOST) || \
			(pdata->operating_mode == FSL_USB2_DR_HOST))
		fsl_platform_set_vbus_power(pdata, 1);

	fsl_platform_set_ahb_burst(hcd);
	ehci_testmode_init(hcd_to_ehci(hcd));
	return retval;
err5:
	usb_remove_hcd(hcd);
err4:
	iounmap(hcd->regs);
err3:
	if (pdata->operating_mode != FSL_USB2_DR_OTG)
		release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err2:
	usb_put_hcd(hcd);
err1:
	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
	if (pdata->exit)
		pdata->exit(pdata->pdev);
	return retval;
}
Example #24
0
static int ux500_musb_exit(struct musb *musb)
{
	otg_put_transceiver(musb->xceiv);

	return 0;
}
Example #25
0
static int davinci_musb_init(struct musb *musb)
{
	void __iomem	*tibase = musb->ctrl_base;
	u32		revision;

	usb_nop_xceiv_register(musb->id);
	musb->xceiv = otg_get_transceiver(musb->id);
	if (!musb->xceiv)
		return -ENODEV;

	musb->mregs += DAVINCI_BASE_OFFSET;

	/* returns zero if e.g. not clocked */
	revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
	if (revision == 0)
		goto fail;

	if (is_host_enabled(musb))
		setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);

	davinci_musb_source_power(musb, 0, 1);

	/* dm355 EVM swaps D+/D- for signal integrity, and
	 * is clocked from the main 24 MHz crystal.
	 */
	if (machine_is_davinci_dm355_evm()) {
		u32	phy_ctrl = __raw_readl(USB_PHY_CTRL);

		phy_ctrl &= ~(3 << 9);
		phy_ctrl |= USBPHY_DATAPOL;
		__raw_writel(phy_ctrl, USB_PHY_CTRL);
	}

	/* On dm355, the default-A state machine needs DRVVBUS control.
	 * If we won't be a host, there's no need to turn it on.
	 */
	if (cpu_is_davinci_dm355()) {
		u32	deepsleep = __raw_readl(DM355_DEEPSLEEP);

		if (is_host_enabled(musb)) {
			deepsleep &= ~DRVVBUS_OVERRIDE;
		} else {
			deepsleep &= ~DRVVBUS_FORCE;
			deepsleep |= DRVVBUS_OVERRIDE;
		}
		__raw_writel(deepsleep, DM355_DEEPSLEEP);
	}

	/* reset the controller */
	musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);

	/* start the on-chip PHY and its PLL */
	phy_on();

	msleep(5);

	/* NOTE:  irqs are in mixed mode, not bypass to pure-musb */
	pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n",
		revision, __raw_readl(USB_PHY_CTRL),
		musb_readb(tibase, DAVINCI_USB_CTRL_REG));

	musb->isr = davinci_musb_interrupt;
	return 0;

fail:
	otg_put_transceiver(musb->xceiv);
	usb_nop_xceiv_unregister(musb->id);
	return -ENODEV;
}
Example #26
0
/**
 * musb_platform_init() - Initialize the platform USB driver.
 * @musb: struct musb pointer.
 *
 * This function initialize the USB controller and Phy.
 */
int __init musb_platform_init(struct musb *musb, void *board_data)
{
	int ret;

	usb_nop_xceiv_register();

	musb->xceiv = otg_get_transceiver();
	if (!musb->xceiv) {
		pr_err("U8500 USB : no transceiver configured\n");
		ret = -ENODEV;
		goto cleanup0;
	}

	ret = musb_stm_hs_otg_init(musb);
	if (ret < 0) {
		pr_err("U8500 USB: Failed to init the OTG object\n");
		goto cleanup1;
	}

	if (is_host_enabled(musb))
		musb->board_set_vbus = set_vbus;
	if (is_peripheral_enabled(musb))
		musb->xceiv->set_power = set_power;

	ret = musb_phy_en(musb->board_mode);
	if (ret < 0) {
		pr_err("U8500 USB: Failed to enable PHY\n");
		goto cleanup1;
	}

	if (musb_status == NULL) {
		musb_status = musb;
		spin_lock_init(&musb_ulpi_spinlock);
	}

	/* Registering usb device  for sysfs */
	usbstatus_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);

	if (usbstatus_kobj == NULL) {
		ret = -ENOMEM;
		goto cleanup1;
	}
	usbstatus_kobj->ktype = &ktype_usbstatus;
	kobject_init(usbstatus_kobj, usbstatus_kobj->ktype);

	ret = kobject_set_name(usbstatus_kobj, "usb_status");
	if (ret)
		goto cleanup2;

	ret = kobject_add(usbstatus_kobj, NULL, "usb_status");
	if (ret) {
		goto cleanup2;
	}

	if (musb->board_mode != MUSB_PERIPHERAL) {
		init_timer(&notify_timer);
		notify_timer.expires = jiffies + msecs_to_jiffies(1000);
		notify_timer.function = funct_host_notify_timer;
		notify_timer.data = (unsigned long)musb;
		add_timer(&notify_timer);
	}

	stm_usb_power_wq = create_singlethread_workqueue(
						"stm_usb_power_wq");
	if (stm_usb_power_wq == NULL) {
		ret = -ENOMEM;
		goto cleanup2;
	}

	INIT_WORK(&stm_prcmu_qos, stm_prcmu_qos_work);

	ret = musb_force_detect(musb->board_mode);
	if (ret < 0)
		goto cleanup2;

	return 0;

cleanup2:
	kfree(usbstatus_kobj);
	if (musb->board_mode != MUSB_PERIPHERAL)
		del_timer_sync(&notify_timer);

cleanup1:
	otg_put_transceiver(musb->xceiv);
cleanup0:
	usb_nop_xceiv_unregister();
	return ret;

}
Example #27
0
static int omap2430_musb_init(struct musb *musb)
{
	u32 l;
	int status = 0;
	struct device *dev = musb->controller;
	struct musb_hdrc_platform_data *plat = dev->platform_data;
	struct omap_musb_board_data *data = plat->board_data;

	/* We require some kind of external transceiver, hooked
	 * up through ULPI.  TWL4030-family PMICs include one,
	 * which needs a driver, drivers aren't always needed.
	 */
	musb->xceiv = otg_get_transceiver();
	if (!musb->xceiv) {
		pr_err("HS USB OTG: no transceiver configured\n");
		return -ENODEV;
	}

	musb->otg_notifier_wq = create_singlethread_workqueue("musb-otg");
	if (!musb->otg_notifier_wq) {
		pr_err("HS USB OTG: cannot allocate otg event wq\n");
		status = -ENOMEM;
		goto err1;
	}

	status = pm_runtime_get_sync(dev);
	if (status < 0) {
		dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
		goto err2;
	}

	l = musb_readl(musb->mregs, OTG_INTERFSEL);

	if (data->interface_type == MUSB_INTERFACE_UTMI) {
		/* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
		l &= ~ULPI_12PIN;       /* Disable ULPI */
		l |= UTMI_8BIT;         /* Enable UTMI  */
	} else {
		l |= ULPI_12PIN;
	}

	musb_writel(musb->mregs, OTG_INTERFSEL, l);

	pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
			"sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
			musb_readl(musb->mregs, OTG_REVISION),
			musb_readl(musb->mregs, OTG_SYSCONFIG),
			musb_readl(musb->mregs, OTG_SYSSTATUS),
			musb_readl(musb->mregs, OTG_INTERFSEL),
			musb_readl(musb->mregs, OTG_SIMENABLE));

	musb->nb.notifier_call = musb_otg_notifications;
	status = otg_register_notifier(musb->xceiv, &musb->nb);

	if (status)
		dev_dbg(musb->controller, "notification register failed\n");

	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);

	return 0;

err2:
	destroy_workqueue(musb->otg_notifier_wq);
err1:
	otg_put_transceiver(musb->xceiv);
	pm_runtime_disable(dev);
	return status;
}
Example #28
0
static int ehci_msm_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct resource *res;
	int ret;

	dev_dbg(&pdev->dev, "ehci_msm proble\n");

	hcd = usb_create_hcd(&msm_hc_driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		dev_err(&pdev->dev, "Unable to create HCD\n");
		return  -ENOMEM;
	}

	hcd->irq = platform_get_irq(pdev, 0);
	if (hcd->irq < 0) {
		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
		ret = hcd->irq;
		goto put_hcd;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Unable to get memory resource\n");
		ret = -ENODEV;
		goto put_hcd;
	}

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);
	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto put_hcd;
	}

	/*
	 * OTG driver takes care of PHY initialization, clock management,
	 * powering up VBUS, mapping of registers address space and power
	 * management.
	 */
	otg = otg_get_transceiver();
	if (!otg) {
		dev_err(&pdev->dev, "unable to find transceiver\n");
		ret = -ENODEV;
		goto unmap;
	}

	ret = otg_set_host(otg, &hcd->self);
	if (ret < 0) {
		dev_err(&pdev->dev, "unable to register with transceiver\n");
		goto put_transceiver;
	}

	device_init_wakeup(&pdev->dev, 1);
	/*
	 * OTG device parent of HCD takes care of putting
	 * hardware into low power mode.
	 */
	pm_runtime_no_callbacks(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	return 0;

put_transceiver:
	otg_put_transceiver(otg);
unmap:
	iounmap(hcd->regs);
put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
Example #29
0
static int pda_power_probe(struct platform_device *pdev)
{
	int ret = 0;

	dev = &pdev->dev;

	if (pdev->id != -1) {
		dev_err(dev, "it's meaningless to register several "
			"pda_powers; use id = -1\n");
		ret = -EINVAL;
		goto wrongid;
	}

	pdata = pdev->dev.platform_data;

	if (pdata->init) {
		ret = pdata->init(dev);
		if (ret < 0)
			goto init_failed;
	}

	update_status();

	if (!pdata->wait_for_status)
		pdata->wait_for_status = 500;

	if (!pdata->wait_for_charger)
		pdata->wait_for_charger = 500;

	if (!pdata->polling_interval)
		pdata->polling_interval = 2000;

	if (!pdata->ac_max_uA)
		pdata->ac_max_uA = 500000;

	setup_timer(&charger_timer, charger_timer_func, 0);

	ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac");
	usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb");

	if (pdata->supplied_to) {
		pda_psy_ac.supplied_to = pdata->supplied_to;
		pda_psy_ac.num_supplicants = pdata->num_supplicants;
		pda_psy_usb.supplied_to = pdata->supplied_to;
		pda_psy_usb.num_supplicants = pdata->num_supplicants;
	}

	ac_draw = regulator_get(dev, "ac_draw");
	if (IS_ERR(ac_draw)) {
		dev_dbg(dev, "couldn't get ac_draw regulator\n");
		ac_draw = NULL;
		ret = PTR_ERR(ac_draw);
	}

	transceiver = otg_get_transceiver();
	if (transceiver && !pdata->is_usb_online) {
		pdata->is_usb_online = otg_is_usb_online;
	}
	if (transceiver && !pdata->is_ac_online) {
		pdata->is_ac_online = otg_is_ac_online;
	}

	if (pdata->is_ac_online) {
		ret = power_supply_register(&pdev->dev, &pda_psy_ac);
		if (ret) {
			dev_err(dev, "failed to register %s power supply\n",
				pda_psy_ac.name);
			goto ac_supply_failed;
		}

		if (ac_irq) {
			ret = request_irq(ac_irq->start, power_changed_isr,
					  get_irq_flags(ac_irq), ac_irq->name,
					  &pda_psy_ac);
			if (ret) {
				dev_err(dev, "request ac irq failed\n");
				goto ac_irq_failed;
			}
		} else {
			polling = 1;
		}
	}

	if (pdata->is_usb_online) {
		ret = power_supply_register(&pdev->dev, &pda_psy_usb);
		if (ret) {
			dev_err(dev, "failed to register %s power supply\n",
				pda_psy_usb.name);
			goto usb_supply_failed;
		}

		if (usb_irq) {
			ret = request_irq(usb_irq->start, power_changed_isr,
					  get_irq_flags(usb_irq),
					  usb_irq->name, &pda_psy_usb);
			if (ret) {
				dev_err(dev, "request usb irq failed\n");
				goto usb_irq_failed;
			}
		} else {
			polling = 1;
		}
	}

	if (transceiver && pdata->use_otg_notifier) {
		otg_nb.notifier_call = otg_handle_notification;
		ret = otg_register_notifier(transceiver, &otg_nb);
		if (ret) {
			dev_err(dev, "failure to register otg notifier\n");
			goto otg_reg_notifier_failed;
		}
		polling = 0;
	}

	if (polling) {
		dev_dbg(dev, "will poll for status\n");
		setup_timer(&polling_timer, polling_timer_func, 0);
		mod_timer(&polling_timer,
			  jiffies + msecs_to_jiffies(pdata->polling_interval));
	}

	if (ac_irq || usb_irq)
		device_init_wakeup(&pdev->dev, 1);

	return 0;

otg_reg_notifier_failed:
	if (pdata->is_usb_online && usb_irq)
		free_irq(usb_irq->start, &pda_psy_usb);
usb_irq_failed:
	if (pdata->is_usb_online)
		power_supply_unregister(&pda_psy_usb);
usb_supply_failed:
	if (pdata->is_ac_online && ac_irq)
		free_irq(ac_irq->start, &pda_psy_ac);
	if (transceiver)
		otg_put_transceiver(transceiver);
ac_irq_failed:
	if (pdata->is_ac_online)
		power_supply_unregister(&pda_psy_ac);
ac_supply_failed:
	if (ac_draw) {
		regulator_put(ac_draw);
		ac_draw = NULL;
	}
	if (pdata->exit)
		pdata->exit(dev);
init_failed:
wrongid:
	return ret;
}
Example #30
0
static int omap2430_musb_init(struct musb *musb)
{
	u32 l;
	int status = 0;
	struct device *dev = musb->controller;

	/* We require some kind of external transceiver, hooked
	 * up through ULPI.  TWL4030-family PMICs include one,
	 * which needs a driver, drivers aren't always needed.
	 */
	musb->xceiv = otg_get_transceiver();
	if (!musb->xceiv) {
		pr_err("HS USB OTG: no transceiver configured\n");
		return -ENODEV;
	}

	musb->otg_notifier_wq = create_singlethread_workqueue("musb-otg");
	if (!musb->otg_notifier_wq) {
		pr_err("HS USB OTG: cannot allocate otg event wq\n");
		status = -ENOMEM;
		goto err1;
	}

	status = pm_runtime_get_sync(dev);
	if (status < 0) {
		dev_err(dev, "pm_runtime_get_sync FAILED");
		goto err2;
	}

	/* Set OTG_INTERFSEL to ULPI for correct charger detection.
	 * This should be later set to UTMI.
	 */
	l = musb_readl(musb->mregs, OTG_INTERFSEL);
	l |= ULPI_12PIN;
	musb_writel(musb->mregs, OTG_INTERFSEL, l);

	pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
			"sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
			musb_readl(musb->mregs, OTG_REVISION),
			musb_readl(musb->mregs, OTG_SYSCONFIG),
			musb_readl(musb->mregs, OTG_SYSSTATUS),
			musb_readl(musb->mregs, OTG_INTERFSEL),
			musb_readl(musb->mregs, OTG_SIMENABLE));

	musb->nb.notifier_call = musb_otg_notifications;
	status = otg_register_notifier(musb->xceiv, &musb->nb);

	if (status)
		dev_dbg(musb->controller, "notification register failed\n");

	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);

	return 0;

err2:
	destroy_workqueue(musb->otg_notifier_wq);
err1:
	otg_put_transceiver(musb->xceiv);
	pm_runtime_disable(dev);
	return status;
}