示例#1
0
/**
 * ehci_hcd_omap_drv_probe - initialize TI-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 *
 */
static int ehci_hcd_omap_drv_probe(struct platform_device *dev)
{
	int retval = 0;
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;

	dev_dbg(&dev->dev, "ehci_hcd_omap_drv_probe()\n");

	if (usb_disabled())
		return -ENODEV;

	if (dev->resource[1].flags != IORESOURCE_IRQ) {
		dev_dbg(&dev->dev, "resource[1] is not IORESOURCE_IRQ\n");
		retval = -ENOMEM;
	}

	hcd = usb_create_hcd(&ehci_omap_hc_driver, &dev->dev, dev->dev.bus_id);
	if (!hcd)
		return -ENOMEM;

	retval = omap_start_ehc(dev, hcd);
	if (retval)
		return retval;

	hcd->rsrc_start = 0;
	hcd->rsrc_len = 0;
	hcd->rsrc_start = dev->resource[0].start;
	hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&dev->dev, "ioremap failed\n");
		return -ENOMEM;
	}

	ehci = hcd_to_ehci(hcd);
	ehci->caps = hcd->regs;

	ehci->sbrn = 0x20;

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

	/* SET 1 micro-frame Interrupt interval */
	writel(readl(&ehci->regs->command) | (1<<16), &ehci->regs->command);

	retval = usb_add_hcd(hcd, dev->resource[1].start,
				IRQF_DISABLED | IRQF_SHARED);
	if (retval == 0)
		return retval;

	dev_dbg(hcd->self.controller, "ERR: add_hcd\n");
	omap_stop_ehc(dev, hcd);
	iounmap(hcd->regs);
	usb_put_hcd(hcd);

	return retval;
}
/**
 * ehci_hcd_omap_probe - initialize TI-based HCDs
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int ehci_hcd_omap_probe(struct platform_device *pdev)
{
	struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data;
	struct ehci_hcd_omap *omap;
	struct resource *res;
	struct usb_hcd *hcd;

	int irq = platform_get_irq(pdev, 0);
	int ret = -ENODEV;

	printk(KERN_DEBUG " ehci_hcd_omap_probe\n");

	if (!pdata) {
		dev_dbg(&pdev->dev, "missing platform_data\n");
		goto err_pdata;
	}

	if (usb_disabled())
	{
		printk(KERN_DEBUG " usb_disabled\n");
		goto err_disabled;
	}

	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
	printk(KERN_DEBUG " kzalloc done\n");
	
	if (!omap) {
		printk(KERN_DEBUG " problem with memory allocation\n");
		ret = -ENOMEM;
		goto err_disabled;
	}

	hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
			dev_name(&pdev->dev));
	printk(KERN_DEBUG " usb_create hcd done\n");
	if (!hcd) {
		printk(KERN_DEBUG " failed to create HCD\n");
		dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
		ret = -ENOMEM;
		goto err_create_hcd;
	}

	platform_set_drvdata(pdev, omap);
	omap->dev		= &pdev->dev;
	omap->phy_reset		= pdata->phy_reset;
	omap->reset_gpio_port[0]	= pdata->reset_gpio_port[0];
	omap->reset_gpio_port[1]	= pdata->reset_gpio_port[1];
	omap->reset_gpio_port[2]	= pdata->reset_gpio_port[2];
	omap->port_mode[0]		= pdata->port_mode[0];
	omap->port_mode[1]		= pdata->port_mode[1];
	omap->port_mode[2]		= pdata->port_mode[2];
	omap->ehci		= hcd_to_ehci(hcd);
	omap->ehci->sbrn	= 0x20;
	omap->suspended = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	printk(KERN_DEBUG " platform get ressources 0 done\n");

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

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		printk(KERN_DEBUG " EHCI ioremap failed\n");
		dev_err(&pdev->dev, "EHCI ioremap failed\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	/* we know this is the memory we want, no need to ioremap again */
	omap->ehci->caps = hcd->regs;
	omap->ehci_base = hcd->regs;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	printk(KERN_DEBUG " platform get ressources 1 done\n");
	
	omap->uhh_base = ioremap(res->start, resource_size(res));
	if (!omap->uhh_base) {
		printk(KERN_DEBUG " UHH ioremap failed\n");
		dev_err(&pdev->dev, "UHH ioremap failed\n");
		ret = -ENOMEM;
		goto err_uhh_ioremap;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	printk(KERN_DEBUG " platform get ressources 2 done\n");
	

	ret = omap_start_ehc(omap, hcd);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to start ehci\n");
		printk(KERN_DEBUG " failed to start ehci\n");
		goto err_start;
	}

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

	dbg_hcs_params(omap->ehci, "reset");
	dbg_hcc_params(omap->ehci, "reset");

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

	/* SET 1 micro-frame Interrupt interval */
	writel(readl(&omap->ehci->regs->command) | (1 << 16),
			&omap->ehci->regs->command);

	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
		goto err_add_hcd;
	}

	printk(KERN_DEBUG " add hcd done\n");

	return 0;

err_add_hcd:
	omap_stop_ehc(omap, hcd);

err_start:
	//iounmap(omap->tll_base);

err_tll_ioremap:
	iounmap(omap->uhh_base);

err_uhh_ioremap:
	iounmap(hcd->regs);

err_ioremap:
	usb_put_hcd(hcd);

err_create_hcd:
	kfree(omap);
err_disabled:
err_pdata:
	return ret;
}
示例#3
0
/**
 * usb_hcd_omap_probe - initialize OMAP-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int usb_hcd_omap_probe (const struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval, irq;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd *ohci;
#ifdef CONFIG_MACH_MAPPHONE
	struct ehci_hcd_omap *omap;
	struct omap_usb_config *pdata = pdev->dev.platform_data;
	struct resource *res;
	int ret = -ENODEV;
	retval = 0;
#else
	if (pdev->num_resources != 2) {
		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
		       pdev->num_resources);
		return -ENODEV;
	}

	if (pdev->resource[0].flags != IORESOURCE_MEM
			|| pdev->resource[1].flags != IORESOURCE_IRQ) {
		printk(KERN_ERR "hcd probe: invalid resource type\n");
		return -ENODEV;
	}
#endif

#ifndef CONFIG_ARCH_OMAP34XX
	usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck");
	if (IS_ERR(usb_host_ck))
		return PTR_ERR(usb_host_ck);

	if (!cpu_is_omap15xx())
		usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck");
	else
		usb_dc_ck = clk_get(&pdev->dev, "lb_ck");

	if (IS_ERR(usb_dc_ck)) {
		clk_put(usb_host_ck);
		return PTR_ERR(usb_dc_ck);
	}
#endif

#ifdef CONFIG_MACH_MAPPHONE
	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
	if (!omap) {
		ret = -ENOMEM;
		goto err0;
	}
#endif

	hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto err0;
	}
#ifndef CONFIG_MACH_MAPPHONE
#if defined(CONFIG_ARCH_OMAP34XX)
	clk_enable(clk_get(NULL, "usbhost_ick"));
	clk_enable(clk_get(NULL, "usbtll_ick"));
	clk_enable(clk_get(NULL, "usbtll_fck"));
	clk_enable(clk_get(NULL, "usbhost_120m_fck"));
	clk_enable(clk_get(NULL, "usbhost_48m_fck"));
#endif
	hcd->rsrc_start = pdev->resource[0].start;
	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
#else
	platform_set_drvdata(pdev, hcd);
	omap->dev		= pdev;
	memcpy(&omap->port_data, &pdata->port_data, sizeof(omap->port_data));

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

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		retval = -EBUSY;
		goto err1;
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "can't ioremap OHCI HCD\n");
		retval = -ENOMEM;
		goto err2;
	}

	ohci = hcd_to_ohci(hcd);
	ohci_hcd_init(ohci);

	host_initialized = 0;
	host_enabled = 1;
#ifdef CONFIG_MACH_MAPPHONE
	ohci_irq_num = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	omap->uhh_base = ioremap(res->start, resource_size(res));
	if (!omap->uhh_base) {
		dev_err(&pdev->dev, "UHH ioremap failed\n");
		ret = -ENOMEM;
		goto err3;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	omap->tll_base = ioremap(res->start, resource_size(res));
	if (!omap->tll_base) {
		dev_err(&pdev->dev, "TLL ioremap failed\n");
		ret = -ENOMEM;
		goto err4;
	}
#endif

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		retval = -ENXIO;
#ifdef CONFIG_MACH_MAPPHONE
		goto err5;
#else
		goto err3;
#endif
	}
#ifdef CONFIG_MACH_MAPPHONE
	retval = omap_start_ehc(omap, hcd);
	if (retval) {
		dev_dbg(&pdev->dev, "failed to start ohci\n");
		goto err5;
	}
#endif
	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
	if (retval)
#ifndef CONFIG_MACH_MAPPHONE
		goto err3;
#else
		goto err5;
	else
/**
 * ehci_hcd_omap_probe - initialize TI-based HCDs
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int ehci_hcd_omap_probe(struct platform_device *pdev)
{
	struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data;
	struct ehci_hcd_omap *omap;
	struct resource *res;
	struct usb_hcd *hcd;

	int irq = platform_get_irq(pdev, 0);
	int ret = -ENODEV;
	int i;
	char supply[7];

	if (!pdata) {
		dev_dbg(&pdev->dev, "missing platform_data\n");
		goto err_pdata;
	}

	if (usb_disabled())
		goto err_disabled;

	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
	if (!omap) {
		ret = -ENOMEM;
		goto err_disabled;
	}

	hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
			dev_name(&pdev->dev));
	if (!hcd) {
		dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
		ret = -ENOMEM;
		goto err_create_hcd;
	}

	platform_set_drvdata(pdev, omap);
	omap->dev		= &pdev->dev;
	omap->phy_reset		= pdata->phy_reset;
	omap->reset_gpio_port[0]	= pdata->reset_gpio_port[0];
	omap->reset_gpio_port[1]	= pdata->reset_gpio_port[1];
	omap->reset_gpio_port[2]	= pdata->reset_gpio_port[2];
	omap->port_mode[0]		= pdata->port_mode[0];
	omap->port_mode[1]		= pdata->port_mode[1];
	omap->port_mode[2]		= pdata->port_mode[2];
	omap->ehci		= hcd_to_ehci(hcd);
	omap->ehci->sbrn	= 0x20;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	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, "EHCI ioremap failed\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	/* we know this is the memory we want, no need to ioremap again */
	omap->ehci->caps = hcd->regs;
	omap->ehci_base = hcd->regs;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	omap->uhh_base = ioremap(res->start, resource_size(res));
	if (!omap->uhh_base) {
		dev_err(&pdev->dev, "UHH ioremap failed\n");
		ret = -ENOMEM;
		goto err_uhh_ioremap;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	omap->tll_base = ioremap(res->start, resource_size(res));
	if (!omap->tll_base) {
		dev_err(&pdev->dev, "TLL ioremap failed\n");
		ret = -ENOMEM;
		goto err_tll_ioremap;
	}

	/* get ehci regulator and enable */
	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
		if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) {
			omap->regulator[i] = NULL;
			continue;
		}
		snprintf(supply, sizeof(supply), "hsusb%d", i);
		omap->regulator[i] = regulator_get(omap->dev, supply);
		if (IS_ERR(omap->regulator[i])) {
			omap->regulator[i] = NULL;
			dev_dbg(&pdev->dev,
			"failed to get ehci port%d regulator\n", i);
		} else {
			regulator_enable(omap->regulator[i]);
		}
	}

	ret = omap_start_ehc(omap, hcd);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to start ehci\n");
		goto err_start;
	}

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

	dbg_hcs_params(omap->ehci, "reset");
	dbg_hcc_params(omap->ehci, "reset");

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

	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
		goto err_add_hcd;
	}

	/* root ports should always stay powered */
	ehci_port_power(omap->ehci, 1);

	return 0;

err_add_hcd:
	omap_stop_ehc(omap, hcd);

err_start:
	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
		if (omap->regulator[i]) {
			regulator_disable(omap->regulator[i]);
			regulator_put(omap->regulator[i]);
		}
	}
	iounmap(omap->tll_base);

err_tll_ioremap:
	iounmap(omap->uhh_base);

err_uhh_ioremap:
	iounmap(hcd->regs);

err_ioremap:
	usb_put_hcd(hcd);

err_create_hcd:
	kfree(omap);
err_disabled:
err_pdata:
	return ret;
}
示例#5
0
/**
 * ehci_hcd_omap_probe - initialize TI-based HCDs
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int ehci_hcd_omap_probe(struct platform_device *pdev)
{
	struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data;
	struct ehci_hcd_omap *omap;
	struct resource *res;
	struct usb_hcd *hcd;

	int irq = platform_get_irq(pdev, 0);
	int ret = -ENODEV;
	int i;
	char supply[7];
	char supply_aux[11];

	if (!pdata) {
		dev_dbg(&pdev->dev, "missing platform_data\n");
		goto err_pdata;
	}

	if (usb_disabled())
		goto err_disabled;

	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
	if (!omap) {
		ret = -ENOMEM;
		goto err_disabled;
	}

	/* Electrical test support
	 * Interface is /sys/devices/platform/ehci-omap.0/portn
	 */
	if (pdata->port_mode[0] != EHCI_HCD_OMAP_MODE_UNKNOWN)
		ret = device_create_file(&pdev->dev, &dev_attr_port1);
	if (pdata->port_mode[1] != EHCI_HCD_OMAP_MODE_UNKNOWN)
		ret = device_create_file(&pdev->dev, &dev_attr_port2);
	if (pdata->port_mode[2] != EHCI_HCD_OMAP_MODE_UNKNOWN)
		ret = device_create_file(&pdev->dev, &dev_attr_port3);

	ghcd = hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
			dev_name(&pdev->dev));
	if (!hcd) {
		dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
		ret = -ENOMEM;
		goto err_create_hcd;
	}

	platform_set_drvdata(pdev, omap);
	omap->dev		= &pdev->dev;
	omap->phy_reset		= pdata->phy_reset;
	omap->reset_gpio_port[0]	= pdata->reset_gpio_port[0];
	omap->reset_gpio_port[1]	= pdata->reset_gpio_port[1];
	omap->reset_gpio_port[2]	= pdata->reset_gpio_port[2];
	omap->port_mode[0]		= pdata->port_mode[0];
	omap->port_mode[1]		= pdata->port_mode[1];
	omap->port_mode[2]		= pdata->port_mode[2];
	omap->aux[0]			= pdata->aux[0];
	omap->aux[1]			= pdata->aux[1];
	omap->aux[2]			= pdata->aux[2];
	omap->ehci		= hcd_to_ehci(hcd);
	omap->ehci->sbrn	= 0x20;
	gb_omap = omap;
	omap->suspended = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	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, "EHCI ioremap failed\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	/* we know this is the memory we want, no need to ioremap again */
	omap->ehci->caps = hcd->regs;
	omap->ehci_base = hcd->regs;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	omap->uhh_base = ioremap(res->start, resource_size(res));
	if (!omap->uhh_base) {
		dev_err(&pdev->dev, "UHH ioremap failed\n");
		ret = -ENOMEM;
		goto err_uhh_ioremap;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	omap->tll_base = ioremap(res->start, resource_size(res));
	if (!omap->tll_base) {
		dev_err(&pdev->dev, "TLL ioremap failed\n");
		ret = -ENOMEM;
		goto err_tll_ioremap;
	}

	/* get ehci regulator and enable */
	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
		if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) {
			omap->regulator[i] = NULL;
			continue;
		}
		snprintf(supply, 7, "hsusb%d", i);
		omap->regulator[i] = regulator_get(omap->dev, supply);
		if (IS_ERR(omap->regulator[i])) {
			dev_dbg(&pdev->dev,
			"failed to get ehci port%d regulator\n", i);
			omap->regulator[i] = NULL;
		} else {
			regulator_enable(omap->regulator[i]);
		}

		/* enable auxiliary supply if required */
		if (omap->aux[i]) {
			snprintf(supply_aux, 11, "hsusb%d-aux", i);
			omap->regulator_aux[i] =
				regulator_get(omap->dev, supply_aux);
			if (IS_ERR(omap->regulator_aux[i])) {
				dev_dbg(&pdev->dev,
				"failed to get ehci port%d aux regulator\n", i);
				omap->regulator[i] = NULL;
			} else {
				regulator_enable(omap->regulator_aux[i]);
			}
		}
	}

	ret = omap_start_ehc(omap, hcd);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to start ehci\n");
		goto err_start;
	}

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

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

	/* SET 1 micro-frame Interrupt interval */
	writel(readl(&omap->ehci->regs->command) | (1 << 16),
			&omap->ehci->regs->command);

	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
		goto err_add_hcd;
	}

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

	return 0;

err_add_hcd:
	omap_stop_ehc(omap, hcd);

err_start:
	iounmap(omap->tll_base);

err_tll_ioremap:
	iounmap(omap->uhh_base);

err_uhh_ioremap:
	iounmap(hcd->regs);

err_ioremap:
	usb_put_hcd(hcd);

err_create_hcd:
	kfree(omap);
err_disabled:
err_pdata:
	return ret;
}
示例#6
0
/**
 * ehci_hcd_omap_probe - initialize TI-based HCDs
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int ehci_hcd_omap_probe(struct platform_device *pdev)
{
	struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data;
	struct ehci_hcd_omap *omap;
	struct resource *res;
	struct usb_hcd *hcd;

	int irq = platform_get_irq(pdev, 0);
	int ret = -ENODEV;
	int i;
	char supply[7];
	char supply_aux[11];

	if (!pdata) {
		dev_dbg(&pdev->dev, "missing platform_data\n");
		goto err_pdata;
	}

	if (usb_disabled())
		goto err_disabled;

	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
	if (!omap) {
		ret = -ENOMEM;
		goto err_disabled;
	}

	/* Electrical test support
	 * Interface is /sys/devices/platform/ehci-omap.0/portn
	 */
	if (pdata->port_mode[0] != EHCI_HCD_OMAP_MODE_UNKNOWN)
		ret = device_create_file(&pdev->dev, &dev_attr_port1);
	if (pdata->port_mode[1] != EHCI_HCD_OMAP_MODE_UNKNOWN)
		ret = device_create_file(&pdev->dev, &dev_attr_port2);
	if (pdata->port_mode[2] != EHCI_HCD_OMAP_MODE_UNKNOWN)
		ret = device_create_file(&pdev->dev, &dev_attr_port3);

	ghcd = hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
			dev_name(&pdev->dev));
	if (!hcd) {
		dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
		ret = -ENOMEM;
		goto err_create_hcd;
	}

	platform_set_drvdata(pdev, omap);
	omap->dev		= &pdev->dev;
	omap->phy_reset		= pdata->phy_reset;
	omap->reset_gpio_port[0]	= pdata->reset_gpio_port[0];
	omap->reset_gpio_port[1]	= pdata->reset_gpio_port[1];
	omap->reset_gpio_port[2]	= pdata->reset_gpio_port[2];
	omap->port_mode[0]		= pdata->port_mode[0];
	omap->port_mode[1]		= pdata->port_mode[1];
	omap->port_mode[2]		= pdata->port_mode[2];
	omap->aux[0]			= pdata->aux[0];
	omap->aux[1]			= pdata->aux[1];
	omap->aux[2]			= pdata->aux[2];
	omap->ehci		= hcd_to_ehci(hcd);
	omap->ehci->sbrn	= 0x20;
	gb_omap = omap;
	omap->suspended = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	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, "EHCI ioremap failed\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	/* we know this is the memory we want, no need to ioremap again */
	omap->ehci->caps = hcd->regs;
	omap->ehci_base = hcd->regs;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	omap->uhh_base = ioremap(res->start, resource_size(res));
	if (!omap->uhh_base) {
		dev_err(&pdev->dev, "UHH ioremap failed\n");
		ret = -ENOMEM;
		goto err_uhh_ioremap;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	omap->tll_base = ioremap(res->start, resource_size(res));
	if (!omap->tll_base) {
		dev_err(&pdev->dev, "TLL ioremap failed\n");
		ret = -ENOMEM;
		goto err_tll_ioremap;
	}

	/* get ehci regulator and enable */
	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
		if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) {
			omap->regulator[i] = NULL;
			continue;
		}
		snprintf(supply, 7, "hsusb%d", i);
		omap->regulator[i] = regulator_get(omap->dev, supply);
		if (IS_ERR(omap->regulator[i])) {
			dev_dbg(&pdev->dev,
			"failed to get ehci port%d regulator\n", i);
			omap->regulator[i] = NULL;
		} else {
			regulator_enable(omap->regulator[i]);
		}

		/* enable auxiliary supply if required */
		if (omap->aux[i]) {
			snprintf(supply_aux, 11, "hsusb%d-aux", i);
			omap->regulator_aux[i] =
				regulator_get(omap->dev, supply_aux);
			if (IS_ERR(omap->regulator_aux[i])) {
				dev_dbg(&pdev->dev,
				"failed to get ehci port%d aux regulator\n", i);
				omap->regulator[i] = NULL;
			} else {
				regulator_enable(omap->regulator_aux[i]);
			}
		}
	}

	ret = omap_start_ehc(omap, hcd);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to start ehci\n");
		goto err_start;
	}

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

	dbg_hcs_params(omap->ehci, "reset");
	dbg_hcc_params(omap->ehci, "reset");

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

	/* SET 1 micro-frame Interrupt interval */
	writel(readl(&omap->ehci->regs->command) | (1 << 16),
			&omap->ehci->regs->command);

	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
		goto err_add_hcd;
	}

	if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) &&
			gpio_is_valid(omap->reset_gpio_port[0])) {
		gpio_request(omap->reset_gpio_port[0], "HSUSB0 reset");
		gpio_direction_output(omap->reset_gpio_port[0], 0);
	}

	if ((omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) &&
			gpio_is_valid(omap->reset_gpio_port[1])) {
		gpio_request(omap->reset_gpio_port[1], "HSUSB1 reset");
		gpio_direction_output(omap->reset_gpio_port[1], 0);
	}

	/* reset the USB PHY */
	if (omap->phy_reset)
		ehci_omap_phy_reset(omap);

	/* root ports should always stay powered */
	ehci_port_power(omap->ehci, 1);

#ifdef CONFIG_LOGIC_OMAP3530_USB3320_HACK
	{
		struct usb_device *rdev = hcd->self.root_hub;

		omap->ehci->no_selective_suspend = 1;
		
		// Kill the auto suspend delay for the root hub
		// Since we only have one port used, it's better
		// if we go down right away.
		if(rdev)
		{
		    rdev->autosuspend_delay = 0;
		}
	}
#endif

#ifdef CONFIG_LOGIC_OMAP3530_USB3320_HACK
	usb3320_hack_init(ehci_hcd_omap_hack_handler, &pdev->dev);
#endif

        // Default wakeup enable should be off.
        device_init_wakeup(&pdev->dev, 1);
        device_set_wakeup_enable(&pdev->dev, 0);

	return 0;

err_add_hcd:
	omap_stop_ehc(omap, hcd);

err_start:
	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
		if (omap->regulator[i]) {
			regulator_disable(omap->regulator[i]);
			regulator_put(omap->regulator[i]);
		}
	}
	iounmap(omap->tll_base);

err_tll_ioremap:
	iounmap(omap->uhh_base);

err_uhh_ioremap:
	iounmap(hcd->regs);

err_ioremap:
	usb_put_hcd(hcd);
	kfree(omap);

err_create_hcd:
	kfree(omap);
err_disabled:
err_pdata:
	return ret;
}
示例#7
0
/**
 * ehci_hcd_omap_probe - initialize TI-based HCDs
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int ehci_hcd_omap_probe(struct platform_device *pdev)
{
	struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data;
	struct ehci_hcd_omap *omap;
	struct resource *res;
	struct usb_hcd *hcd;

	int irq = platform_get_irq(pdev, 0);
	int ret = -ENODEV;

	if (!pdata) {
		dev_dbg(&pdev->dev, "missing platform_data\n");
		goto err_pdata;
	}

#ifdef CONFIG_MAPPHONE_2NDBOOT

	/* FIXME: Find proper defines for the addresses */

	/* We need to get the interrupts in order */
	printk(KERN_INFO "EHCI-OMAP: Fixing after 2nd-boot\n");
  
	/* Mask IRQs */
	omap_writel(0x2000, 0x482000cc);
  
	/* Reset USBINTR */
	omap_writel(0x00, 0x48064818);
  
	/* Set ERROR status on everything (this may not be necessary) */
	omap_writel(0x3f, 0x48064814);
  
	/* Clear HCINTERRUPTSTATUS */
	omap_writel(0x4000007f, 0x4806440c);
  
	/* Clear HCINTERRUPTDISABLE */
	omap_writel(0xc000007f, 0x48064414);

#endif

	if (usb_disabled())
		goto err_disabled;

#ifdef CONFIG_MAPPHONE_2NDBOOT

	/* Enable IRQs */
	omap_writel(0x0, 0x4806201c);

	/* Set them to event pending */
	omap_writel(0x7, 0x48062018);

#endif

	ret = request_irq(78, usbtll_irq, IRQF_DISABLED | IRQF_SHARED,
				"usbtll", pdev);
	if (ret < 0) {
		printk(KERN_ERR "\nCan't get USBTLL IRQ\n");
		goto err_disabled;
	}

	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
	if (!omap) {
		ret = -ENOMEM;
		goto err_create_hcd;
	}

	hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
			dev_name(&pdev->dev));
	if (!hcd) {
		dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
		ret = -ENOMEM;
		goto err_create_hcd;
	}

	platform_set_drvdata(pdev, omap);
	omap->dev		= pdev;

	memcpy(&omap->port_data, &pdata->port_data, sizeof(omap->port_data));

	omap->ehci		= hcd_to_ehci(hcd);
	omap->ehci->sbrn	= 0x20;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	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, "EHCI ioremap failed\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	/* we know this is the memory we want, no need to ioremap again */
	omap->ehci->caps = hcd->regs;
	omap->ehci_base = hcd->regs;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	omap->uhh_base = ioremap(res->start, resource_size(res));
	if (!omap->uhh_base) {
		dev_err(&pdev->dev, "UHH ioremap failed\n");
		ret = -ENOMEM;
		goto err_uhh_ioremap;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	omap->tll_base = ioremap(res->start, resource_size(res));
	if (!omap->tll_base) {
		dev_err(&pdev->dev, "TLL ioremap failed\n");
		ret = -ENOMEM;
		goto err_tll_ioremap;
	}

#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_init(&omap->ehci->wake_lock_ehci_rwu,
			WAKE_LOCK_SUSPEND, "ehci_rwu");
	wake_lock_init(&omap->ehci->wake_lock_ehci_pm,
			WAKE_LOCK_SUSPEND, "ehci_pm");
#endif

	ret = omap_start_ehc(omap, hcd);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to start ehci\n");
		goto err_start;
	}

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

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

	/* SET 1 micro-frame Interrupt interval */
	writel(readl(&omap->ehci->regs->command) | (1 << 16),
			&omap->ehci->regs->command);

	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
		goto err_add_hcd;
	}

	return 0;

err_add_hcd:
	omap_stop_ehc(omap, hcd);

err_start:
	iounmap(omap->tll_base);

err_tll_ioremap:
	iounmap(omap->uhh_base);

err_uhh_ioremap:
	iounmap(hcd->regs);

err_ioremap:
	usb_put_hcd(hcd);

err_create_hcd:
err_disabled:
err_pdata:
	return ret;
}