Exemplo n.º 1
0
static void usb2phy_eye_optimization(struct dwc_otg2 *otg)
{
	void __iomem *addr;
	struct usb_phy *phy;
	struct intel_dwc_otg_pdata *data;

	if (!otg || !otg->otg_data)
		return;

	data = (struct intel_dwc_otg_pdata *)otg->otg_data;

	phy = usb_get_phy(USB_PHY_TYPE_USB2);
	if (!phy)
		return;

	if ((data->usb2_phy_type == USB2_PHY_ULPI) && !!data->ulpi_eye_calibration)
		usb_phy_io_write(phy, data->ulpi_eye_calibration, TUSB1211_VENDOR_SPECIFIC1_SET);
	else if ((data->usb2_phy_type == USB2_PHY_UTMI) && !!data->utmi_eye_calibration) {
		addr = ioremap_nocache(UTMI_PHY_USB2PERPORT, 4);
		if (!addr) {
			otg_info(otg, "UTMI phy register ioremap failed, use default setup!\n");
			usb_put_phy(phy);
			return;
		}
		writel(data->utmi_eye_calibration, addr);
		iounmap(addr);
	} else
		otg_info(otg, "usb2 phy eye optimization fail, use default setup!\n");

	usb_put_phy(phy);
}
Exemplo n.º 2
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);
	twl4030_charger_enable_backup(0, 0);

	/* 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 (!IS_ERR_OR_NULL(bci->transceiver)) {
		usb_unregister_notifier(bci->transceiver, &bci->usb_nb);
		usb_put_phy(bci->transceiver);
	}
	free_irq(bci->irq_bci, bci);
	free_irq(bci->irq_chg, bci);
	power_supply_unregister(bci->usb);
	power_supply_unregister(bci->ac);
	kfree(bci);

	return 0;
}
Exemplo n.º 3
0
static int mv_ehci_remove(struct platform_device *pdev)
{
	struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev);
	struct usb_hcd *hcd = ehci_mv->hcd;
	int clk_i;

	if (hcd->rh_registered)
		usb_remove_hcd(hcd);

	if (!IS_ERR_OR_NULL(ehci_mv->otg)) {
		otg_set_host(ehci_mv->otg->otg, NULL);
		usb_put_phy(ehci_mv->otg);
	}

	if (ehci_mv->mode == MV_USB_MODE_HOST) {
		if (ehci_mv->pdata->set_vbus)
			ehci_mv->pdata->set_vbus(0);

		mv_ehci_disable(ehci_mv);
	}

	iounmap(ehci_mv->cap_regs);
	iounmap(ehci_mv->phy_regs);

	for (clk_i = 0; clk_i < ehci_mv->clknum; clk_i++)
		clk_put(ehci_mv->clk[clk_i]);

	platform_set_drvdata(pdev, NULL);

	kfree(ehci_mv);
	usb_put_hcd(hcd);

	return 0;
}
static int intel_mid_ehci_driver_register(struct pci_driver *host_driver)
{
	struct usb_phy			*otg;
	struct intel_mid_otg_xceiv	*iotg;

	otg = usb_get_phy(USB_PHY_TYPE_USB2);
	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;
	iotg->runtime_suspend_host = ehci_mid_runtime_suspend_host;
	iotg->runtime_resume_host = ehci_mid_runtime_resume_host;

	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;

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

	usb_put_phy(otg);

	return 0;
}
static int dwc_otg_charger_hwdet(bool enable)
{
	int				retval;
	struct usb_phy *phy;
	struct dwc_otg2 *otg = dwc3_get_otg();

	/* Just return if charger detection is not enabled */
	if (!charger_detect_enable(otg))
		return 0;

	phy = usb_get_phy(USB_PHY_TYPE_USB2);
	if (!phy)
		return -ENODEV;

	if (enable) {
		retval = usb_phy_io_write(phy, PWCTRL_HWDETECT,
				TUSB1211_POWER_CONTROL_SET);
		if (retval)
			return retval;
		otg_dbg(otg, "set HWDETECT\n");
	} else {
		retval = usb_phy_io_write(phy, PWCTRL_HWDETECT,
				TUSB1211_POWER_CONTROL_CLR);
		if (retval)
			return retval;
		otg_dbg(otg, "clear HWDETECT\n");
	}
	usb_put_phy(phy);

	return 0;
}
Exemplo n.º 6
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);
	del_timer_sync(&supply_timer);

	if (pdata->is_usb_online)
		power_supply_unregister(&pda_psy_usb);
	if (pdata->is_ac_online)
		power_supply_unregister(&pda_psy_ac);
#if IS_ENABLED(CONFIG_USB_PHY)
	if (!IS_ERR_OR_NULL(transceiver))
		usb_put_phy(transceiver);
#endif
	if (ac_draw) {
		regulator_put(ac_draw);
		ac_draw = NULL;
	}
	if (pdata->exit)
		pdata->exit(dev);

	return 0;
}
Exemplo n.º 7
0
static int ux500_musb_exit(struct musb *musb)
{
	usb_unregister_notifier(musb->xceiv, &musb->nb);

	usb_put_phy(musb->xceiv);

	return 0;
}
static int crystalcove_chgr_remove(struct platform_device *pdev)
{
	struct chgr_info *info =  dev_get_drvdata(&pdev->dev);
	int i;

	free_irq(info->irq, info);
	if (info->otg)
		usb_put_phy(info->otg);
	power_supply_unregister(&info->psy_usb);
	return 0;
}
Exemplo n.º 9
0
Arquivo: da8xx.c Projeto: 7799/linux
static int da8xx_musb_exit(struct musb *musb)
{
	del_timer_sync(&otg_workaround);

	phy_off();

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

	return 0;
}
static int smsc375x_remove(struct i2c_client *client)
{
	struct smsc375x_chip *chip = i2c_get_clientdata(client);

	free_irq(client->irq, chip);
	usb_put_phy(chip->otg);
	extcon_dev_unregister(chip->edev);
	kfree(chip->edev);
	pm_runtime_get_noresume(&chip->client->dev);
	kfree(chip);
	return 0;
}
Exemplo n.º 11
0
static int __devexit isp1704_charger_remove(struct platform_device *pdev)
{
	struct isp1704_charger *isp = platform_get_drvdata(pdev);

	usb_unregister_notifier(isp->phy, &isp->nb);
	power_supply_unregister(&isp->psy);
	usb_put_phy(isp->phy);
	isp1704_charger_set_power(isp, 0);
	kfree(isp);

	return 0;
}
Exemplo n.º 12
0
static int dsps_musb_init(struct musb *musb)
{
	struct device *dev = musb->controller;
	struct musb_hdrc_platform_data *plat = dev->platform_data;
	struct platform_device *pdev = to_platform_device(dev);
	struct dsps_glue *glue = dev_get_drvdata(dev->parent);
	const struct dsps_musb_wrapper *wrp = glue->wrp;
	struct omap_musb_board_data *data = plat->board_data;
	void __iomem *reg_base = musb->ctrl_base;
	u32 rev, val;
	int status;

	/* mentor core register starts at offset of 0x400 from musb base */
	musb->mregs += wrp->musb_core_offset;

	/* NOP driver needs change if supporting dual instance */
	usb_nop_xceiv_register();
	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
	if (IS_ERR_OR_NULL(musb->xceiv))
		return -ENODEV;

	/* Returns zero if e.g. not clocked */
	rev = dsps_readl(reg_base, wrp->revision);
	if (!rev) {
		status = -ENODEV;
		goto err0;
	}

	setup_timer(&glue->timer[pdev->id], otg_timer, (unsigned long) musb);

	/* Reset the musb */
	dsps_writel(reg_base, wrp->control, (1 << wrp->reset));

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

	musb->isr = dsps_interrupt;

	/* reset the otgdisable bit, needed for host mode to work */
	val = dsps_readl(reg_base, wrp->phy_utmi);
	val &= ~(1 << wrp->otg_disable);
	dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);

	/* clear level interrupt */
	dsps_writel(reg_base, wrp->eoi, 0);

	return 0;
err0:
	usb_put_phy(musb->xceiv);
	usb_nop_xceiv_unregister();
	return status;
}
Exemplo n.º 13
0
static int usbhs_hardware_exit(struct platform_device *pdev)
{
	struct usbhs_private *priv = usbhs_get_priv(pdev);

	if (!priv->phy)
		return 0;

	usb_put_phy(priv->phy);
	priv->phy = NULL;

	gpio_free(RCAR_GP_PIN(5, 18));
	return 0;
}
static int fsa9285_remove(struct i2c_client *client)
{
	struct fsa9285_chip *chip = i2c_get_clientdata(client);

	if (chip->pdata->mux_gpio != -1)
		gpio_free(chip->pdata->mux_gpio);
	free_irq(client->irq, chip);
	usb_put_phy(chip->otg);
	extcon_dev_unregister(chip->edev);
	kfree(chip->edev);
	pm_runtime_get_noresume(&chip->client->dev);
	kfree(chip);
	return 0;
}
Exemplo n.º 15
0
static int da8xx_musb_exit(struct musb *musb)
{
	struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent);

	del_timer_sync(&otg_workaround);

	phy_power_off(glue->phy);
	phy_exit(glue->phy);
	clk_disable_unprepare(glue->clk);

	usb_put_phy(musb->xceiv);

	return 0;
}
Exemplo n.º 16
0
static int am35x_musb_exit(struct musb *musb)
{
	struct device *dev = musb->controller;
	struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
	struct omap_musb_board_data *data = plat->board_data;

	del_timer_sync(&otg_workaround);

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

	usb_put_phy(musb->xceiv);

	return 0;
}
Exemplo n.º 17
0
/**
 * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs
 * @dev: USB Host Controller being removed
 * Context: !in_interrupt()
 *
 * Reverses the effect of usb_hcd_omap_probe(), first invoking
 * the HCD's stop() method.  It is always called from a thread
 * context, normally "rmmod", "apmd", or something similar.
 */
static inline void
usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
{
	usb_remove_hcd(hcd);
	if (!IS_ERR_OR_NULL(hcd->phy)) {
		(void) otg_set_host(hcd->phy->otg, 0);
		usb_put_phy(hcd->phy);
	}
	if (machine_is_omap_osk())
		gpio_free(9);
	iounmap(hcd->regs);
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	usb_put_hcd(hcd);
	clk_put(usb_dc_ck);
	clk_put(usb_host_ck);
}
Exemplo n.º 18
0
static int dsps_musb_exit(struct musb *musb)
{
	struct device *dev = musb->controller;
	struct platform_device *pdev = to_platform_device(dev);
	struct dsps_glue *glue = dev_get_drvdata(dev->parent);

	del_timer_sync(&glue->timer[pdev->id]);

	/* Shutdown the on-chip PHY and its PLL. */
	musb_dsps_phy_control(glue, pdev->id, 0);

	/* NOP driver needs change if supporting dual instance */
	usb_put_phy(musb->xceiv);
	usb_nop_xceiv_unregister();

	return 0;
}
Exemplo n.º 19
0
/**
 * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs
 * @dev: USB Host Controller being removed
 * Context: !in_interrupt()
 *
 * Reverses the effect of usb_hcd_omap_probe(), first invoking
 * the HCD's stop() method.  It is always called from a thread
 * context, normally "rmmod", "apmd", or something similar.
 */
static inline void
usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
{
	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
	usb_remove_hcd(hcd);
	omap_ohci_clock_power(0);
	if (!IS_ERR_OR_NULL(hcd->phy)) {
		(void) otg_set_host(hcd->phy->otg, 0);
		usb_put_phy(hcd->phy);
	}
	if (machine_is_omap_osk())
		gpio_free(9);
	iounmap(hcd->regs);
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	usb_put_hcd(hcd);
	clk_put(usb_dc_ck);
	clk_put(usb_host_ck);
}
static int usb_otg_suspend(struct usb_hcd *hcd)
{
	struct usb_phy			*otg;
	struct intel_mid_otg_xceiv	*iotg;

	otg = usb_get_phy(USB_PHY_TYPE_USB2);
	if (otg == NULL) {
		pr_err("%s: failed to get otg transceiver\n", __func__);
		return -EINVAL;
	}
	iotg = otg_to_mid_xceiv(otg);
	pr_info("%s: OTG HNP update suspend\n", __func__);

	atomic_notifier_call_chain(&iotg->iotg_notifier,
				MID_OTG_NOTIFY_HSUSPEND, iotg);
	usb_put_phy(otg);
	return 0;
}
static int usb_otg_resume(struct usb_hcd *hcd)
{
	struct usb_phy			*otg;
	struct intel_mid_otg_xceiv	*iotg;

	otg = usb_get_phy(USB_PHY_TYPE_USB2);
	if (otg == NULL) {
		pr_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);
	usb_put_phy(otg);
	return 0;
}
static void usb2phy_eye_optimization(struct dwc_otg2 *otg)
{
	struct intel_dwc_otg_pdata *data;
	struct usb_phy *phy;

	data = (struct intel_dwc_otg_pdata *)otg->otg_data;

	phy = usb_get_phy(USB_PHY_TYPE_USB2);
	if (!phy)
		return;

	/* Modify VS1 for better quality in eye diagram */
	if (data && data->ti_phy_vs1)
		usb_phy_io_write(phy, data->ti_phy_vs1,
			TUSB1211_VENDOR_SPECIFIC1_SET);

	usb_put_phy(phy);
}
Exemplo n.º 23
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);

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

	return 0;
}
static int xhci_dwc_drv_remove(struct platform_device *pdev)
{
	struct usb_hcd *hcd = platform_get_drvdata(pdev);
	struct usb_phy *usb_phy;
	struct xhci_hcd *xhci = hcd_to_xhci(hcd);

	usb_phy = usb_get_phy(USB_PHY_TYPE_USB2);
	otg_set_host(usb_phy->otg, NULL);
	usb_put_phy(usb_phy);

	if (xhci)
		dwc3_stop_host(hcd);
	usb_put_hcd(hcd);

	pm_runtime_disable(hcd->self.controller);
	pm_runtime_set_suspended(hcd->self.controller);
	wake_lock_destroy(&dwc3_xhci.wakelock);
	return 0;
}
Exemplo n.º 25
0
static int __devexit dwc_otg_driver_remove(struct platform_device *ofdev)
{
	struct device *dev = &ofdev->dev;
	struct dwc_otg_device *dwc_dev = dev_get_drvdata(dev);

	/* Memory allocation for dwc_otg_device may have failed. */
	if (!dwc_dev)
		return 0;

	/* Free the IRQ */
	free_irq(dwc_dev->irq, dwc_dev);
	/* Free external charge pump irq */
	free_irq(dwc_dev->hcd->cp_irq, dwc_dev);

	if (dwc_dev->hcd)
		dwc_otg_hcd_remove(dev);

	if (dwc_dev->pcd)
		dwc_otg_pcd_remove(dev);

	if (dwc_dev->core_if)
		dwc_otg_cil_remove(dwc_dev->core_if);

	if(dwc_dev->core_if->core_params)
		kfree(dwc_dev->core_if->core_params);

	/* Return the memory. */
	if (dwc_dev->base)
		iounmap(dwc_dev->base);

	if (dwc_dev->phys_addr)
		release_mem_region(dwc_dev->phys_addr, dwc_dev->base_len);

	usb_put_phy(dwc_dev->core_if->xceiv);
	dwc_dev->core_if->xceiv = NULL;

	kfree(dwc_dev);

	/* Clear the drvdata pointer. */
	dev_set_drvdata(dev, NULL);
	return 0;
}
Exemplo n.º 26
0
static int dsps_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;
	struct platform_device *pdev = to_platform_device(dev);
	struct dsps_glue *glue = dev_get_drvdata(dev->parent);

	del_timer_sync(&glue->timer[pdev->id]);

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

	/* NOP driver needs change if supporting dual instance */
	usb_put_phy(musb->xceiv);
	usb_nop_xceiv_unregister();

	return 0;
}
static void intel_mid_ehci_driver_unregister(struct pci_driver *host_driver)
{
	struct usb_phy			*otg;
	struct intel_mid_otg_xceiv	*iotg;

	otg = usb_get_phy(USB_PHY_TYPE_USB2);
	if (otg == NULL)
		return;

	iotg = otg_to_mid_xceiv(otg);
	iotg->start_host = NULL;
	iotg->stop_host = NULL;
	iotg->runtime_suspend_host = NULL;
	iotg->runtime_resume_host = NULL;

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

	usb_put_phy(otg);
}
static int xhci_dwc_drv_probe(struct platform_device *pdev)
{
	struct dwc_otg2 *otg;
	struct usb_phy *usb_phy;
	struct dwc_device_par *pdata;
	struct usb_hcd *hcd;
	struct resource *res;
	int retval = 0;
	int ret;

	if (usb_disabled())
		return -ENODEV;

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

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

	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;
	}
	dwc3_xhci.otg_irqnum = res->start;

	hcd = usb_create_hcd(&xhci_dwc_hc_driver,
			&pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		return retval;
	}

	hcd->regs = pdata->io_addr;

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

	usb_phy = usb_get_phy(USB_PHY_TYPE_USB2);
	if (usb_phy)
		otg_set_host(usb_phy->otg, &hcd->self);

	otg = container_of(usb_phy->otg, struct dwc_otg2, otg);
	if (otg) {
		otg->start_host = dwc3_start_host;
		otg->stop_host = dwc3_stop_host;
		otg->suspend_host = dwc3_suspend_host;
		otg->resume_host = dwc3_resume_host;
	}

	usb_put_phy(usb_phy);

	/* Enable wakeup irq */
	hcd->has_wakeup_irq = 1;
	INIT_WORK(&dwc3_xhci.reset_hcd, dwc3_host_reset);
	INIT_WORK(&dwc3_xhci.poll_loopback, dwc3_poll_lp);
	wake_lock_init(&dwc3_xhci.wakelock, WAKE_LOCK_SUSPEND,
			"dwc3_host_wakelock");

	platform_set_drvdata(pdev, hcd);
	pm_runtime_no_callbacks(hcd->self.controller);
	pm_runtime_enable(hcd->self.controller);
	ret = device_create_file(hcd->self.controller, &dev_attr_host_comp_test);
	if (ret < 0)
		dev_err(hcd->self.controller,
			"Can't register sysfs attribute: %d\n", ret);

	return retval;
}
Exemplo n.º 29
0
static int davinci_musb_init(struct musb *musb)
{
	void __iomem	*tibase = musb->ctrl_base;
	u32		revision;
	int 		ret = -ENODEV;

	usb_nop_xceiv_register();
	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
	if (IS_ERR_OR_NULL(musb->xceiv)) {
		ret = -EPROBE_DEFER;
		goto unregister;
	}

	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;

	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);

		deepsleep &= ~DRVVBUS_FORCE;
		__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:
	usb_put_phy(musb->xceiv);
unregister:
	usb_nop_xceiv_unregister();
	return ret;
}
Exemplo n.º 30
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;
	}

	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;
	}

	update_status();
	update_charger();

	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);
	setup_timer(&supply_timer, supply_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;
	}

#if IS_ENABLED(CONFIG_USB_PHY)
	transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
	if (!IS_ERR_OR_NULL(transceiver)) {
		if (!pdata->is_usb_online)
			pdata->is_usb_online = otg_is_usb_online;
		if (!pdata->is_ac_online)
			pdata->is_ac_online = otg_is_ac_online;
	}
#endif

	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 IS_ENABLED(CONFIG_USB_PHY)
	if (!IS_ERR_OR_NULL(transceiver) && pdata->use_otg_notifier) {
		otg_nb.notifier_call = otg_handle_notification;
		ret = usb_register_notifier(transceiver, &otg_nb);
		if (ret) {
			dev_err(dev, "failure to register otg notifier\n");
			goto otg_reg_notifier_failed;
		}
		polling = 0;
	}
#endif

	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;

#if IS_ENABLED(CONFIG_USB_PHY)
otg_reg_notifier_failed:
	if (pdata->is_usb_online && usb_irq)
		free_irq(usb_irq->start, &pda_psy_usb);
#endif
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 IS_ENABLED(CONFIG_USB_PHY)
	if (!IS_ERR_OR_NULL(transceiver))
		usb_put_phy(transceiver);
#endif
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;
}