Example #1
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 #2
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.
 *
 */
static int usb_hcd_fsl_probe(const struct hc_driver *driver,
                             struct platform_device *pdev)
{
    struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
    struct usb_hcd *hcd;
    struct resource *res;
    int irq;
    int retval;
    u32 temp;

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

    /* Need platform data for setup */
    if (!pdata) {
        dev_err(&pdev->dev,
                "No platform data for %s.\n", pdev->dev.bus_id);
        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", pdev->dev.bus_id);
        return -ENODEV;
    }

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

#if defined(CONFIG_USB_OTG)
    if (pdata->operating_mode == FSL_USB2_DR_OTG) {
        res = otg_get_resources();
        if (!res) {
            dev_err(&pdev->dev,
                    "Found HC with no IRQ. Check %s setup!\n",
                    pdev->dev.bus_id);
            return -ENODEV;
        }
        irq = res[1].start;
        hcd->rsrc_start = res[0].start;
        hcd->rsrc_len = res[0].end - res[0].start + 1;
    } else
#endif
    {
        if ((pdev->dev.parent) &&
                (to_platform_device(pdev->dev.parent)->resource)) {
            pdev->resource =
                to_platform_device(pdev->dev.parent)->resource;
            pdev->num_resources =
                to_platform_device(pdev->dev.parent)->num_resources;
        }

        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (!res) {
            dev_err(&pdev->dev,
                    "Found HC with no IRQ. Check %s setup!\n",
                    pdev->dev.bus_id);
            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 (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
                                driver->description)) {
            dev_dbg(&pdev->dev, "controller already in use\n");
            retval = -EBUSY;
            goto err2;
        }
    }

    if (!(pdata->port_enables & FSL_USB2_DONT_REMAP)) {
        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;
        }
        regs_remapped = 1;
    } else
        hcd->regs = (void __iomem *)(u32)(hcd->rsrc_start);

    pdata->regs = hcd->regs;

    /*
     * do platform specific init: check the clock, grab/config pins, etc.
     */
    if (pdata->platform_init && pdata->platform_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;

    fsl_platform_set_vbus_power(pdata, 1);

#ifdef CONFIG_USB_OTG
    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) {
            retval = otg_set_host(ehci->transceiver,
                                  &ehci_to_hcd(ehci)->self);
            if (retval) {
                if (ehci->transceiver)
                    put_device(ehci->transceiver->dev);
                goto err4;
            }
        } else {
            printk(KERN_ERR "can't find transceiver\n");
            retval = -ENODEV;
            goto err4;
        }
    }
#endif

    fsl_platform_set_ahb_burst(hcd);
    ehci_testmode_init(hcd_to_ehci(hcd));
    return retval;

err4:
    if (regs_remapped)
        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", pdev->dev.bus_id, retval);
    if (pdata->platform_uninit)
        pdata->platform_uninit(pdata);
    return retval;
}