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

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

	usb_put_transceiver(otg);

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

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

	usb_put_transceiver(otg);
}
static int __init otg_wakelock_init(void)
{
	int ret;

	otgwl_xceiv = usb_get_transceiver();

	if (!otgwl_xceiv) {
		pr_err("%s: No USB transceiver found\n", __func__);
		return -ENODEV;
	}

	snprintf(vbus_lock.name, sizeof(vbus_lock.name), "vbus-%s",
		 dev_name(otgwl_xceiv->dev));
	wake_lock_init(&vbus_lock.wakelock, WAKE_LOCK_SUSPEND,
		       vbus_lock.name);

	otgwl_nb.notifier_call = otgwl_otg_notifications;
	ret = usb_register_notifier(otgwl_xceiv, &otgwl_nb);

	if (ret) {
		pr_err("%s: usb_register_notifier on transceiver %s"
		       " failed\n", __func__,
		       dev_name(otgwl_xceiv->dev));
		otgwl_xceiv = NULL;
		wake_lock_destroy(&vbus_lock.wakelock);
		return ret;
	}

	otgwl_handle_event(otgwl_xceiv->last_event);
	return ret;
}
static int __init exynos5_manta_battery_late_init(void)
{
	int ret;
	struct usb_phy *usb_xceiv;

	ret = power_supply_register(NULL, &manta_battery_psy);
	if (ret)
		pr_err("%s: failed to register power_supply\n",
		       __func__);

	ret = request_threaded_irq(gpio_to_irq(GPIO_OTG_VBUS_SENSE),
				   NULL, ta_int_intr,
				   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
				   IRQF_ONESHOT, "usb_vbus", NULL);
	if (ret) {
		pr_err("%s: usb_vbus irq register failed, ret=%d\n",
		       __func__, ret);
	} else {
		ret = enable_irq_wake(gpio_to_irq(GPIO_OTG_VBUS_SENSE));
		if (ret)
			pr_warn("%s: failed to enable irq_wake for usb_vbus\n",
				__func__);
	}

	ret = request_threaded_irq(gpio_to_irq(GPIO_VBUS_POGO_5V), NULL,
				   ta_int_intr,
				   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
				   IRQF_ONESHOT, "pogo_vbus", NULL);
	if (ret) {
		pr_err("%s: pogo_vbus irq register failed, ret=%d\n",
		       __func__, ret);
	} else {
		ret = enable_irq_wake(gpio_to_irq(GPIO_VBUS_POGO_5V));
		if (ret)
			pr_warn("%s: failed to enable irq_wake for pogo_vbus\n",
				__func__);
	}

	ret = register_pm_notifier(&exynos5_manta_battery_pm_notifier_block);
	if (ret)
		pr_warn("%s: failed to register PM notifier; ret=%d\n",
			__func__, ret);

	usb_xceiv = usb_get_transceiver();

	if (!usb_xceiv) {
		pr_err("%s: No USB transceiver found\n", __func__);
	} else {
		ret = usb_register_notifier(usb_xceiv, &manta_bat_usb_nb);

		if (ret) {
			pr_err("%s: usb_register_notifier on transceiver %s failed\n",
			       __func__, dev_name(usb_xceiv->dev));
		}
	}

	/* get initial charger status */
	change_charger_status(false, false);
	return 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;

	musb->xceiv = usb_get_transceiver();
	if (!musb->xceiv) {
		pr_err("HS USB OTG: no transceiver configured\n");
		return -ENODEV;
	}

	INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work);

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

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

	if (data->interface_type == MUSB_INTERFACE_UTMI) {
		
		l &= ~ULPI_12PIN;       
		l |= UTMI_8BIT;         
	} 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 = usb_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);

	pm_runtime_put_noidle(musb->controller);
	return 0;

err1:
	return status;
}
Example #6
0
static int ux500_musb_init(struct musb *musb)
{
	musb->xceiv = usb_get_transceiver();
	if (!musb->xceiv) {
		pr_err("HS USB OTG: no transceiver configured\n");
		return -ENODEV;
	}

	return 0;
}
Example #7
0
int otg_send_event(enum usb_otg_event event)
{
	struct usb_phy *phy = usb_get_transceiver();
	int ret = -ENOTSUPP;

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

	if (phy)
		usb_put_transceiver(phy);

	return ret;
}
/* the root hub will call this callback when device added/removed */
static void otg_notify(struct usb_device *udev, unsigned action)
{
	struct usb_phy *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 = usb_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:
		usb_put_transceiver(otg);
		return ;
	}
	usb_put_transceiver(otg);
	return;
}
static int usb_otg_resume(struct usb_hcd *hcd)
{
	struct usb_phy *otg;
	struct intel_mid_otg_xceiv *iotg;

	otg = usb_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);
	usb_put_transceiver(otg);
	return 0;
}
static int usb_otg_suspend(struct usb_hcd *hcd)
{
	struct usb_phy *otg;
	struct intel_mid_otg_xceiv *iotg;

	otg = usb_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);
	usb_put_transceiver(otg);
	return 0;
}
Example #11
0
static int da8xx_musb_init(struct musb *musb)
{
	void __iomem *reg_base = musb->ctrl_base;
	u32 rev;

	musb->mregs += DA8XX_MENTOR_CORE_OFFSET;

	/* Returns zero if e.g. not clocked */
	rev = musb_readl(reg_base, DA8XX_USB_REVISION_REG);
	if (!rev)
		goto fail;

	usb_nop_xceiv_register();
	musb->xceiv = usb_get_transceiver();
	if (!musb->xceiv)
		goto fail;

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

	/* Reset the controller */
	musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK);

	/* 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("DA8xx OTG revision %08x, PHY %03x, control %02x\n",
		 rev, __raw_readl(CFGCHIP2),
		 musb_readb(reg_base, DA8XX_USB_CTRL_REG));

	musb->isr = da8xx_musb_interrupt;
	return 0;
fail:
	return -ENODEV;
}
static int ehci_mid_probe(struct pci_dev *pdev,
				const struct pci_device_id *id)
{
	struct hc_driver *driver;
	struct usb_phy *otg;
	struct intel_mid_otg_xceiv *iotg;
	struct intel_mid_otg_pdata *otg_pdata;
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	int irq;
	int retval;

	pr_debug("initializing Intel MID USB OTG Host Controller\n");

	/* we need not call pci_enable_dev since otg transceiver already take
	 * the control of this device and this probe actaully gets called by
	 * otg transceiver driver with HNP protocol.
	 */
	irq = pdev->irq;

	if (!id)
		return -EINVAL;
	driver = (struct hc_driver *)id->driver_data;
	if (!driver)
		return -EINVAL;

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

	ehci = hcd_to_ehci(hcd);
	/* this will be called in ehci_bus_suspend and ehci_bus_resume */
	ehci->otg_suspend = usb_otg_suspend;
	ehci->otg_resume = usb_otg_resume;
	/* this will be called by root hub code */
	hcd->otg_notify = otg_notify;
	otg = usb_get_transceiver();
	if (otg == NULL) {
		printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__);
		retval = -EINVAL;
		goto err1;
	}

	iotg = otg_to_mid_xceiv(otg);
	hcd->regs = iotg->base;

	hcd->rsrc_start = pci_resource_start(pdev, 0);
	hcd->rsrc_len = pci_resource_len(pdev, 0);

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

	otg_pdata = pdev->dev.platform_data;
	if (otg_pdata == NULL) {
		dev_err(&pdev->dev, "Failed to get OTG platform data.\n");
		retval = -ENODEV;
		goto err2;
	}
	hcd->power_budget = otg_pdata->power_budget;

	/* Mandatorily set the controller as remote-wakeup enabled */
	device_set_wakeup_enable(&pdev->dev, true);

	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (retval != 0)
		goto err2;
	retval = otg_set_host(otg->otg, &hcd->self);
	if (!otg->otg->default_a)
		hcd->self.is_b_host = 1;
	usb_put_transceiver(otg);
	return retval;

err2:
	usb_put_hcd(hcd);
err1:
	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
	return retval;
}
Example #13
0
static int xhci_plat_probe(struct platform_device *pdev)
{
	const struct hc_driver	*driver;
	struct xhci_hcd		*xhci;
	struct resource         *res;
	struct usb_hcd		*hcd;
	int			ret;
	int			irq;

	if (usb_disabled())
		return -ENODEV;

	driver = &xhci_plat_xhci_driver;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return -ENODEV;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd)
		return -ENOMEM;

	hcd_to_bus(hcd)->skip_resume = true;
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

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

	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_dbg(&pdev->dev, "error mapping memory\n");
		ret = -EFAULT;
		goto release_mem_region;
	}

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret)
		goto unmap_registers;

	/* USB 2.0 roothub is stored in the platform_device now. */
	hcd = dev_get_drvdata(&pdev->dev);
	xhci = hcd_to_xhci(hcd);
	xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev,
			dev_name(&pdev->dev), hcd);
	if (!xhci->shared_hcd) {
		ret = -ENOMEM;
		goto dealloc_usb2_hcd;
	}

	hcd_to_bus(xhci->shared_hcd)->skip_resume = true;
	/*
	 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
	 * is called by usb_add_hcd().
	 */
	*((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;

	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
	if (ret)
		goto put_usb3_hcd;

	phy = usb_get_transceiver();
	/* Register with OTG if present, ignore USB2 OTG using other PHY */
	if (phy && phy->otg && !(phy->flags & ENABLE_SECONDARY_PHY)) {
		dev_dbg(&pdev->dev, "%s otg support available\n", __func__);
		ret = otg_set_host(phy->otg, &hcd->self);
		if (ret) {
			dev_err(&pdev->dev, "%s otg_set_host failed\n",
				__func__);
			usb_put_transceiver(phy);
			goto put_usb3_hcd;
		}
	} else {
		pm_runtime_no_callbacks(&pdev->dev);
	}

	pm_runtime_put(&pdev->dev);

	return 0;

put_usb3_hcd:
	usb_put_hcd(xhci->shared_hcd);

dealloc_usb2_hcd:
	usb_remove_hcd(hcd);

unmap_registers:
	iounmap(hcd->regs);

release_mem_region:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);

put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
Example #14
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");

    if (!pdev->dev.dma_mask)
        pdev->dev.dma_mask = &msm_ehci_dma_mask;
    if (!pdev->dev.coherent_dma_mask)
        pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);

    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.
     */
    phy = usb_get_transceiver();
    if (!phy) {
        dev_err(&pdev->dev, "unable to find transceiver\n");
        ret = -ENODEV;
        goto unmap;
    }

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

    hcd_to_ehci(hcd)->transceiver = phy;
    device_init_wakeup(&pdev->dev, 1);
    pm_runtime_enable(&pdev->dev);

    return 0;

put_transceiver:
    usb_put_transceiver(phy);
unmap:
    iounmap(hcd->regs);
put_hcd:
    usb_put_hcd(hcd);

    return ret;
}
static int msm_xusb_init_host(struct platform_device *pdev,
                              struct msmusb_hcd *mhcd)
{
    int ret = 0;
    struct msm_otg *otg;
    struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
    struct ehci_hcd *ehci = hcd_to_ehci(hcd);
    struct msm_usb_host_platform_data *pdata = mhcd->pdata;

    switch (PHY_TYPE(pdata->phy_info)) {
    case USB_PHY_INTEGRATED:
        msm_hsusb_rpc_connect();

        if (pdata->vbus_init)
            pdata->vbus_init(1);

        /* VBUS might be present. Turn off vbus */
        if (pdata->vbus_power)
            pdata->vbus_power(pdata->phy_info, 0);

        INIT_WORK(&mhcd->otg_work, msm_hsusb_otg_work);
        mhcd->xceiv = usb_get_transceiver();
        if (!mhcd->xceiv)
            return -ENODEV;
        otg = container_of(mhcd->xceiv, struct msm_otg, phy);
        hcd->regs = otg->regs;
        otg->start_host = msm_hsusb_start_host;

        ret = otg_set_host(mhcd->xceiv->otg, &hcd->self);
        ehci->transceiver = mhcd->xceiv;
        break;
    case USB_PHY_SERIAL_PMIC:
        hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);

        if (!hcd->regs)
            return -EFAULT;
        /* get usb clocks */
        mhcd->alt_core_clk = clk_get(&pdev->dev, "alt_core_clk");
        if (IS_ERR(mhcd->alt_core_clk)) {
            iounmap(hcd->regs);
            return PTR_ERR(mhcd->alt_core_clk);
        }

        mhcd->iface_clk = clk_get(&pdev->dev, "iface_clk");
        if (IS_ERR(mhcd->iface_clk)) {
            iounmap(hcd->regs);
            clk_put(mhcd->alt_core_clk);
            return PTR_ERR(mhcd->iface_clk);
        }
        mhcd->otg_ops.request = msm_hsusb_request_host;
        mhcd->otg_ops.handle = (void *) mhcd;
        ret = msm_xusb_init_phy(mhcd);
        if (ret < 0) {
            iounmap(hcd->regs);
            clk_put(mhcd->alt_core_clk);
            clk_put(mhcd->iface_clk);
        }
        break;
    default:
        pr_err("phy type is bad\n");
    }
    return ret;
}
Example #16
0
static int mv_ehci_probe(struct platform_device *pdev)
{
	struct mv_usb_platform_data *pdata = pdev->dev.platform_data;
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	struct ehci_hcd_mv *ehci_mv;
	struct resource *r;
	int clk_i, retval = -ENODEV;
	u32 offset;
	size_t size;

	if (!pdata) {
		dev_err(&pdev->dev, "missing platform_data\n");
		return -ENODEV;
	}

	if (usb_disabled())
		return -ENODEV;

	hcd = usb_create_hcd(&mv_ehci_hc_driver, &pdev->dev, "mv ehci");
	if (!hcd)
		return -ENOMEM;

	size = sizeof(*ehci_mv) + sizeof(struct clk *) * pdata->clknum;
	ehci_mv = kzalloc(size, GFP_KERNEL);
	if (ehci_mv == NULL) {
		dev_err(&pdev->dev, "cannot allocate ehci_hcd_mv\n");
		retval = -ENOMEM;
		goto err_put_hcd;
	}

	platform_set_drvdata(pdev, ehci_mv);
	ehci_mv->pdata = pdata;
	ehci_mv->hcd = hcd;

	ehci_mv->clknum = pdata->clknum;
	for (clk_i = 0; clk_i < ehci_mv->clknum; clk_i++) {
		ehci_mv->clk[clk_i] =
		    clk_get(&pdev->dev, pdata->clkname[clk_i]);
		if (IS_ERR(ehci_mv->clk[clk_i])) {
			dev_err(&pdev->dev, "error get clck \"%s\"\n",
				pdata->clkname[clk_i]);
			retval = PTR_ERR(ehci_mv->clk[clk_i]);
			goto err_put_clk;
		}
	}

	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phyregs");
	if (r == NULL) {
		dev_err(&pdev->dev, "no phy I/O memory resource defined\n");
		retval = -ENODEV;
		goto err_put_clk;
	}

	ehci_mv->phy_regs = ioremap(r->start, resource_size(r));
	if (ehci_mv->phy_regs == 0) {
		dev_err(&pdev->dev, "failed to map phy I/O memory\n");
		retval = -EFAULT;
		goto err_put_clk;
	}

	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "capregs");
	if (!r) {
		dev_err(&pdev->dev, "no I/O memory resource defined\n");
		retval = -ENODEV;
		goto err_iounmap_phyreg;
	}

	ehci_mv->cap_regs = ioremap(r->start, resource_size(r));
	if (ehci_mv->cap_regs == NULL) {
		dev_err(&pdev->dev, "failed to map I/O memory\n");
		retval = -EFAULT;
		goto err_iounmap_phyreg;
	}

	retval = mv_ehci_enable(ehci_mv);
	if (retval) {
		dev_err(&pdev->dev, "init phy error %d\n", retval);
		goto err_iounmap_capreg;
	}

	offset = readl(ehci_mv->cap_regs) & CAPLENGTH_MASK;
	ehci_mv->op_regs =
		(void __iomem *) ((unsigned long) ehci_mv->cap_regs + offset);

	hcd->rsrc_start = r->start;
	hcd->rsrc_len = r->end - r->start + 1;
	hcd->regs = ehci_mv->op_regs;

	hcd->irq = platform_get_irq(pdev, 0);
	if (!hcd->irq) {
		dev_err(&pdev->dev, "Cannot get irq.");
		retval = -ENODEV;
		goto err_disable_clk;
	}

	ehci = hcd_to_ehci(hcd);
	ehci->caps = (struct ehci_caps *) ehci_mv->cap_regs;
	ehci->regs = (struct ehci_regs *) ehci_mv->op_regs;
	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);

	ehci_mv->mode = pdata->mode;
	if (ehci_mv->mode == MV_USB_MODE_OTG) {
#ifdef CONFIG_USB_OTG_UTILS
		ehci_mv->otg = usb_get_transceiver();
		if (!ehci_mv->otg) {
			dev_err(&pdev->dev,
				"unable to find transceiver\n");
			retval = -ENODEV;
			goto err_disable_clk;
		}

		retval = otg_set_host(ehci_mv->otg->otg, &hcd->self);
		if (retval < 0) {
			dev_err(&pdev->dev,
				"unable to register with transceiver\n");
			retval = -ENODEV;
			goto err_put_transceiver;
		}
		/*                                          */
		mv_ehci_disable(ehci_mv);
#else
		dev_info(&pdev->dev, "MV_USB_MODE_OTG "
			 "must have CONFIG_USB_OTG_UTILS enabled\n");
		goto err_disable_clk;
#endif
	} else {
		if (pdata->set_vbus)
			pdata->set_vbus(1);

		retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
		if (retval) {
			dev_err(&pdev->dev,
				"failed to add hcd with err %d\n", retval);
			goto err_set_vbus;
		}
	}

	if (pdata->private_init)
		pdata->private_init(ehci_mv->op_regs, ehci_mv->phy_regs);

	dev_info(&pdev->dev,
		 "successful find EHCI device with regs 0x%p irq %d"
		 " working in %s mode\n", hcd->regs, hcd->irq,
		 ehci_mv->mode == MV_USB_MODE_OTG ? "OTG" : "Host");

	return 0;

err_set_vbus:
	if (pdata->set_vbus)
		pdata->set_vbus(0);
#ifdef CONFIG_USB_OTG_UTILS
err_put_transceiver:
	if (ehci_mv->otg)
		usb_put_transceiver(ehci_mv->otg);
#endif
err_disable_clk:
	mv_ehci_disable(ehci_mv);
err_iounmap_capreg:
	iounmap(ehci_mv->cap_regs);
err_iounmap_phyreg:
	iounmap(ehci_mv->phy_regs);
err_put_clk:
	for (clk_i--; clk_i >= 0; clk_i--)
		clk_put(ehci_mv->clk[clk_i]);
	platform_set_drvdata(pdev, NULL);
	kfree(ehci_mv);
err_put_hcd:
	usb_put_hcd(hcd);

	return retval;
}
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();
	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;
	}

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

#ifdef CONFIG_USB_OTG_UTILS
	transceiver = usb_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;
	}
#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;
		}
	}

#ifdef CONFIG_USB_OTG_UTILS
	if (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;

#ifdef CONFIG_USB_OTG_UTILS
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);
#ifdef CONFIG_USB_OTG_UTILS
	if (transceiver)
		usb_put_transceiver(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;
}
Example #18
0
static int davinci_musb_init(struct musb *musb)
{
	void __iomem	*tibase = musb->ctrl_base;
	u32		revision;

	usb_nop_xceiv_register();
	musb->xceiv = usb_get_transceiver();
	if (!musb->xceiv)
		goto unregister;

	musb->mregs += DAVINCI_BASE_OFFSET;

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

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

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

	
	musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);

	
	phy_on();

	msleep(5);

	
	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_transceiver(musb->xceiv);
unregister:
	usb_nop_xceiv_unregister();
	return -ENODEV;
}
static int __init twl4030_bci_probe(struct platform_device *pdev)
{
	struct twl4030_bci *bci;
	int ret;
	u32 reg;

	bci = kzalloc(sizeof(*bci), GFP_KERNEL);
	if (bci == NULL)
		return -ENOMEM;

	bci->dev = &pdev->dev;
	bci->irq_chg = platform_get_irq(pdev, 0);
	bci->irq_bci = platform_get_irq(pdev, 1);

	platform_set_drvdata(pdev, bci);

	bci->ac.name = "twl4030_ac";
	bci->ac.type = POWER_SUPPLY_TYPE_MAINS;
	bci->ac.properties = twl4030_charger_props;
	bci->ac.num_properties = ARRAY_SIZE(twl4030_charger_props);
	bci->ac.get_property = twl4030_bci_get_property;

	ret = power_supply_register(&pdev->dev, &bci->ac);
	if (ret) {
		dev_err(&pdev->dev, "failed to register ac: %d\n", ret);
		goto fail_register_ac;
	}

	bci->usb.name = "twl4030_usb";
	bci->usb.type = POWER_SUPPLY_TYPE_USB;
	bci->usb.properties = twl4030_charger_props;
	bci->usb.num_properties = ARRAY_SIZE(twl4030_charger_props);
	bci->usb.get_property = twl4030_bci_get_property;

	ret = power_supply_register(&pdev->dev, &bci->usb);
	if (ret) {
		dev_err(&pdev->dev, "failed to register usb: %d\n", ret);
		goto fail_register_usb;
	}

	ret = request_threaded_irq(bci->irq_chg, NULL,
			twl4030_charger_interrupt, 0, pdev->name, bci);
	if (ret < 0) {
		dev_err(&pdev->dev, "could not request irq %d, status %d\n",
			bci->irq_chg, ret);
		goto fail_chg_irq;
	}

	ret = request_threaded_irq(bci->irq_bci, NULL,
			twl4030_bci_interrupt, 0, pdev->name, bci);
	if (ret < 0) {
		dev_err(&pdev->dev, "could not request irq %d, status %d\n",
			bci->irq_bci, ret);
		goto fail_bci_irq;
	}

	INIT_WORK(&bci->work, twl4030_bci_usb_work);

	bci->transceiver = usb_get_transceiver();
	if (bci->transceiver != NULL) {
		bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;
		usb_register_notifier(bci->transceiver, &bci->usb_nb);
	}

	/* Enable interrupts now. */
	reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 |
		TWL4030_TBATOR1 | TWL4030_BATSTS);
	ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
			       TWL4030_INTERRUPTS_BCIIMR1A);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to unmask interrupts: %d\n", ret);
		goto fail_unmask_interrupts;
	}

	reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV);
	ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
			       TWL4030_INTERRUPTS_BCIIMR2A);
	if (ret < 0)
		dev_warn(&pdev->dev, "failed to unmask interrupts: %d\n", ret);

	twl4030_charger_enable_ac(true);
	twl4030_charger_enable_usb(bci, true);

	return 0;

fail_unmask_interrupts:
	if (bci->transceiver != NULL) {
		usb_unregister_notifier(bci->transceiver, &bci->usb_nb);
		usb_put_transceiver(bci->transceiver);
	}
	free_irq(bci->irq_bci, bci);
fail_bci_irq:
	free_irq(bci->irq_chg, bci);
fail_chg_irq:
	power_supply_unregister(&bci->usb);
fail_register_usb:
	power_supply_unregister(&bci->ac);
fail_register_ac:
	platform_set_drvdata(pdev, NULL);
	kfree(bci);

	return ret;
}
static int tegra_ehci_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct usb_hcd *hcd;
	struct tegra_ehci_hcd *tegra;
	struct tegra_usb_platform_data *pdata;
	int err = 0;
	int irq;
	int instance = pdev->id;

	/* Right now device-tree probed devices don't get dma_mask set.
	 * Since shared usb code relies on it, set it here for now.
	 * Once we have dma capability bindings this can go away.
	 */
	if (!pdev->dev.dma_mask)
		pdev->dev.dma_mask = &tegra_ehci_dma_mask;

	setup_vbus_gpio(pdev);

	tegra = devm_kzalloc(&pdev->dev, sizeof(struct tegra_ehci_hcd),
		GFP_KERNEL);
	if (!tegra) {
		dev_err(&pdev->dev, "memory alloc failed\n");
		return -ENOMEM;
	}

	mutex_init(&tegra->sync_lock);

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

	platform_set_drvdata(pdev, tegra);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "failed to get I/O memory\n");
		err = -ENXIO;
		goto fail_io;
	}
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);
	hcd->regs = ioremap(res->start, resource_size(res));
	if (!hcd->regs) {
		dev_err(&pdev->dev, "failed to remap I/O memory\n");
		err = -ENOMEM;
		goto fail_io;
	}

	/* This is pretty ugly and needs to be fixed when we do only
	 * device-tree probing. Old code relies on the platform_device
	 * numbering that we lack for device-tree-instantiated devices.
	 */
	if (instance < 0) {
		switch (res->start) {
		case TEGRA_USB_BASE:
			instance = 0;
			break;
		case TEGRA_USB2_BASE:
			instance = 1;
			break;
		case TEGRA_USB3_BASE:
			instance = 2;
			break;
		default:
			err = -ENODEV;
			dev_err(&pdev->dev, "unknown usb instance\n");
			goto fail_phy;
		}
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "failed to get IRQ\n");
		err = -ENODEV;
		goto fail_irq;
	}
	tegra->irq = irq;

	pdata = dev_get_platdata(&pdev->dev);
	tegra->unaligned_dma_buf_supported = pdata->unaligned_dma_buf_supported;
	tegra->has_hostpc = pdata->has_hostpc;

	tegra->phy = tegra_usb_phy_open(pdev);
	if (IS_ERR(tegra->phy)) {
		dev_err(&pdev->dev, "failed to open USB phy\n");
		err = -ENXIO;
		goto fail_irq;
	}

	err = tegra_usb_phy_power_on(tegra->phy);
	if (err) {
		dev_err(&pdev->dev, "failed to power on the phy\n");
		goto fail_phy;
	}

	err = usb_phy_init(get_usb_phy(tegra->phy));
	if (err) {
		dev_err(&pdev->dev, "failed to init the phy\n");
		goto fail_phy;
	}

	err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_TRIGGER_HIGH);
	if (err) {
		dev_err(&pdev->dev, "Failed to add USB HCD, error=%d\n", err);
		goto fail_phy;
	}

	err = enable_irq_wake(tegra->irq);
	if (err < 0) {
		dev_warn(&pdev->dev,
				"Couldn't enable USB host mode wakeup, irq=%d, "
				"error=%d\n", irq, err);
		err = 0;
		tegra->irq = 0;
	}

	tegra->ehci = hcd_to_ehci(hcd);

#ifdef CONFIG_USB_OTG_UTILS
	if (pdata->port_otg) {
		tegra->transceiver = usb_get_transceiver();
		if (tegra->transceiver)
			otg_set_host(tegra->transceiver->otg, &hcd->self);
	}
#endif
	return err;

fail_phy:
	usb_phy_shutdown(get_usb_phy(tegra->phy));
fail_irq:
	iounmap(hcd->regs);
fail_io:
	usb_put_hcd(hcd);

	return err;
}
static int ohci_omap_init(struct usb_hcd *hcd)
{
	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
	struct omap_usb_config	*config = hcd->self.controller->platform_data;
	int			need_transceiver = (config->otg != 0);
	int			ret;

	dev_dbg(hcd->self.controller, "starting USB Controller\n");

	if (config->otg) {
		ohci_to_hcd(ohci)->self.otg_port = config->otg;
		/*                                         */
		ohci_to_hcd(ohci)->power_budget = 8;
	}

	/*                                                  */
	need_transceiver = need_transceiver
			|| machine_is_omap_h2() || machine_is_omap_h3();

	if (cpu_is_omap16xx())
		ocpi_enable();

#ifdef	CONFIG_USB_OTG
	if (need_transceiver) {
		ohci->transceiver = usb_get_transceiver();
		if (ohci->transceiver) {
			int	status = otg_set_host(ohci->transceiver->otg,
						&ohci_to_hcd(ohci)->self);
			dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n",
					ohci->transceiver->label, status);
			if (status) {
				if (ohci->transceiver)
					put_device(ohci->transceiver->dev);
				return status;
			}
		} else {
			dev_err(hcd->self.controller, "can't find transceiver\n");
			return -ENODEV;
		}
		ohci->start_hnp = start_hnp;
	}
#endif

	omap_ohci_clock_power(1);

	if (cpu_is_omap15xx()) {
		omap_1510_local_bus_power(1);
		omap_1510_local_bus_init();
	}

	if ((ret = ohci_init(ohci)) < 0)
		return ret;

	/*                                                        */
	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
		u32	rh = roothub_a (ohci);

		/*                                     */
		rh &= ~RH_A_NPS;

		/*                                                  */
		if (machine_is_omap_osk()) {
			ohci_to_hcd(ohci)->power_budget = 250;

			rh &= ~RH_A_NOCP;

			/*                                */
			omap_cfg_reg(W8_1610_GPIO9);
			gpio_request(9, "OHCI overcurrent");
			gpio_direction_input(9);

			/*                                        */
			omap_cfg_reg(W4_USB_HIGHZ);
		}
		ohci_writel(ohci, rh, &ohci->regs->roothub.a);
		ohci->flags &= ~OHCI_QUIRK_HUB_POWER;
	} else if (machine_is_nokia770()) {
		/*                                                 
                      */
		ohci_to_hcd(ohci)->power_budget = 0;
	}

	/*                                                        */
	omap_ohci_transceiver_power(1);

	/*                                                        
                                                          
                                                             
  */

	return 0;
}