Exemplo n.º 1
0
static int ohci_hcd_s5p_drv_runtime_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct s5p_ohci_platdata *pdata = pdev->dev.platform_data;
	struct s5p_ohci_hcd *s5p_ohci = platform_get_drvdata(pdev);
	struct usb_hcd *hcd = s5p_ohci->hcd;
#ifdef CONFIG_USB_EXYNOS_SWITCH
	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
#endif
	if (dev->power.is_suspended)
		return 0;

	if (pdata->phy_resume)
		pdata->phy_resume(pdev, S5P_USB_PHY_HOST);
	/* Mark hardware accessible again as we are out of D3 state by now */
	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

#ifdef CONFIG_USB_EXYNOS_SWITCH
	if (samsung_board_rev_is_0_0())
		ohci_writel (ohci, RH_HS_LPSC, &ohci->regs->roothub.status);
#endif

	ohci_finish_controller_resume(hcd);
	return 0;
}
Exemplo n.º 2
0
static int s5p_ehci_runtime_suspend(struct device *dev)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
#ifdef CONFIG_USB_EXYNOS_SWITCH
    struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
    struct usb_hcd *hcd = s5p_ehci->hcd;
    struct ehci_hcd *ehci = hcd_to_ehci(hcd);
#endif
    if (pdata && pdata->phy_suspend)
        pdata->phy_suspend(pdev, S5P_USB_PHY_HOST);

#ifdef CONFIG_USB_EXYNOS_SWITCH
    if (samsung_board_rev_is_0_0()) {
        ehci_hub_control(hcd,
                         ClearPortFeature,
                         USB_PORT_FEAT_POWER,
                         1, NULL, 0);
        /* Flush those writes */
        ehci_readl(ehci, &ehci->regs->command);

        msleep(20);
    }
#endif
    return 0;
}
Exemplo n.º 3
0
static int s5p_ehci_runtime_resume(struct device *dev)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
    struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
    struct usb_hcd *hcd = s5p_ehci->hcd;
    struct ehci_hcd *ehci = hcd_to_ehci(hcd);
    int rc = 0;

    if (dev->power.is_suspended)
        return 0;

    /* platform device isn't suspended */
    if (pdata && pdata->phy_resume)
        rc = pdata->phy_resume(pdev, S5P_USB_PHY_HOST);

    if (rc) {
        s5p_ehci_configurate(hcd);

        /* emptying the schedule aborts any urbs */
        spin_lock_irq(&ehci->lock);
        if (ehci->reclaim)
            end_unlink_async(ehci);
        ehci_work(ehci);
        spin_unlock_irq(&ehci->lock);

        usb_root_hub_lost_power(hcd->self.root_hub);

        ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
        ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
        (void)ehci_readl(ehci, &ehci->regs->intr_enable);

        /* here we "know" root ports should always stay powered */
        ehci_port_power(ehci, 1);

        hcd->state = HC_STATE_SUSPENDED;
#ifdef CONFIG_USB_EXYNOS_SWITCH
    } else {
        if (samsung_board_rev_is_0_0()) {
            ehci_hub_control(ehci_to_hcd(ehci),
                             SetPortFeature,
                             USB_PORT_FEAT_POWER,
                             1, NULL, 0);
            /* Flush those writes */
            ehci_readl(ehci, &ehci->regs->command);
            msleep(20);
        }
#endif
    }

    return 0;
}
Exemplo n.º 4
0
static int ohci_hcd_s5p_drv_runtime_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct s5p_ohci_platdata *pdata = pdev->dev.platform_data;
	struct s5p_ohci_hcd *s5p_ohci = platform_get_drvdata(pdev);
	struct usb_hcd *hcd = s5p_ohci->hcd;
	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
	unsigned long flags;
	int rc = 0;

	/* Root hub was already suspended. Disable irq emission and
	 * mark HW unaccessible, bail out if RH has been resumed. Use
	 * the spinlock to properly synchronize with possible pending
	 * RH suspend or resume activity.
	 *
	 * This is still racy as hcd->state is manipulated outside of
	 * any locks =P But that will be a different fix.
	 */
	spin_lock_irqsave(&ohci->lock, flags);
	if (hcd->state != HC_STATE_SUSPENDED && hcd->state != HC_STATE_HALT) {
		spin_unlock_irqrestore(&ohci->lock, flags);
		err("Not ready %s", hcd->self.bus_name);
		return rc;
	}

	ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
	(void)ohci_readl(ohci, &ohci->regs->intrdisable);

	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
	spin_unlock_irqrestore(&ohci->lock, flags);

#ifdef CONFIG_USB_EXYNOS_SWITCH
	if (samsung_board_rev_is_0_0())
		ohci_writel (ohci, RH_HS_LPS, &ohci->regs->roothub.status);
#endif
	if (pdata->phy_suspend)
		pdata->phy_suspend(pdev, S5P_USB_PHY_HOST);

	return rc;
}
Exemplo n.º 5
0
static int __devinit ohci_hcd_s5p_drv_probe(struct platform_device *pdev)
{
	struct s5p_ohci_platdata *pdata;
	struct s5p_ohci_hcd *s5p_ohci;
	struct usb_hcd  *hcd = NULL;
	struct ohci_hcd *ohci;
	struct resource *res;
	int irq;
	int err;

	pdata = pdev->dev.platform_data;
	if (!pdata) {
		dev_err(&pdev->dev, "No platform data defined\n");
		return -EINVAL;
	}

	s5p_ohci = kzalloc(sizeof(struct s5p_ohci_hcd), GFP_KERNEL);
	if (!s5p_ohci)
		return -ENOMEM;

	s5p_ohci->dev = &pdev->dev;

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

	s5p_ohci->hcd = hcd;
	s5p_ohci->clk = clk_get(&pdev->dev, "usbhost");

	if (IS_ERR(s5p_ohci->clk)) {
		dev_err(&pdev->dev, "Failed to get usbhost clock\n");
		err = PTR_ERR(s5p_ohci->clk);
		goto fail_clk;
	}

	err = clk_enable(s5p_ohci->clk);
	if (err)
		goto fail_clken;

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

	irq = platform_get_irq(pdev, 0);
	if (!irq) {
		dev_err(&pdev->dev, "Failed to get IRQ\n");
		err = -ENODEV;
		goto fail;
	}

	if (pdata->phy_init)
		pdata->phy_init(pdev, S5P_USB_PHY_HOST);

	ohci = hcd_to_ohci(hcd);
	ohci_hcd_init(ohci);
#ifdef CONFIG_USB_EXYNOS_SWITCH
	if (samsung_board_rev_is_0_0())
		ohci->flags |= OHCI_QUIRK_SUPERIO;
#endif

	err = usb_add_hcd(hcd, irq,
				IRQF_DISABLED | IRQF_SHARED);

	if (err) {
		dev_err(&pdev->dev, "Failed to add USB HCD\n");
		goto fail;
	}

	platform_set_drvdata(pdev, s5p_ohci);

	create_ohci_sys_file(ohci);
	s5p_ohci->power_on = 1;

#ifdef CONFIG_USB_EXYNOS_SWITCH
	if (samsung_board_rev_is_0_0()) {
		ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
		(void)ohci_readl(ohci, &ohci->regs->intrdisable);

		ohci_writel (ohci, RH_HS_LPS, &ohci->regs->roothub.status);
	}
#endif
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
	return 0;

fail:
	iounmap(hcd->regs);
fail_io:
	clk_disable(s5p_ohci->clk);
fail_clken:
	clk_put(s5p_ohci->clk);
fail_clk:
	usb_put_hcd(hcd);
fail_hcd:
	kfree(s5p_ohci);
	return err;
}
Exemplo n.º 6
0
static int __devinit s5p_ehci_probe(struct platform_device *pdev)
{
    struct s5p_ehci_platdata *pdata;
    struct s5p_ehci_hcd *s5p_ehci;
    struct usb_hcd *hcd;
    struct ehci_hcd *ehci;
    struct resource *res;
    int irq;
    int err;

    pdata = pdev->dev.platform_data;
    if (!pdata) {
        dev_err(&pdev->dev, "No platform data defined\n");
        return -EINVAL;
    }

    s5p_ehci = kzalloc(sizeof(struct s5p_ehci_hcd), GFP_KERNEL);
    if (!s5p_ehci)
        return -ENOMEM;

    s5p_ehci->dev = &pdev->dev;

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

    s5p_ehci->hcd = hcd;
    s5p_ehci->clk = clk_get(&pdev->dev, "usbhost");

    if (IS_ERR(s5p_ehci->clk)) {
        dev_err(&pdev->dev, "Failed to get usbhost clock\n");
        err = PTR_ERR(s5p_ehci->clk);
        goto fail_clk;
    }

    err = clk_enable(s5p_ehci->clk);
    if (err)
        goto fail_clken;

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

    irq = platform_get_irq(pdev, 0);
    if (!irq) {
        dev_err(&pdev->dev, "Failed to get IRQ\n");
        err = -ENODEV;
        goto fail;
    }

    if (pdata->phy_init)
        pdata->phy_init(pdev, S5P_USB_PHY_HOST);

    ehci = hcd_to_ehci(hcd);
    ehci->caps = hcd->regs;
    ehci->regs = hcd->regs +
                 HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase));

    s5p_ehci_configurate(hcd);

    dbg_hcs_params(ehci, "reset");
    dbg_hcc_params(ehci, "reset");

    /* cache this readonly data; minimize chip reads */
    ehci->hcs_params = readl(&ehci->caps->hcs_params);

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

    platform_set_drvdata(pdev, s5p_ehci);

    create_ehci_sys_file(ehci);
    s5p_ehci->power_on = 1;

#ifdef CONFIG_USB_EXYNOS_SWITCH
    if (samsung_board_rev_is_0_0())
        ehci_hub_control(ehci_to_hcd(ehci),
                         ClearPortFeature,
                         USB_PORT_FEAT_POWER,
                         1, NULL, 0);
#endif
#ifdef CONFIG_USB_SUSPEND
    pm_runtime_set_active(&pdev->dev);
    pm_runtime_enable(&pdev->dev);
#endif
    return 0;

fail:
    iounmap(hcd->regs);
fail_io:
    clk_disable(s5p_ehci->clk);
fail_clken:
    clk_put(s5p_ehci->clk);
fail_clk:
    usb_put_hcd(hcd);
fail_hcd:
    kfree(s5p_ehci);
    return err;
}