Ejemplo n.º 1
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.
 */
int usb_hcd_omap_probe (const struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd *ohci;

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

	usb_host_ck = clk_get(0, "usb_hhc_ck");
	if (IS_ERR(usb_host_ck))
		return PTR_ERR(usb_host_ck);

	hcd = usb_create_hcd (driver, &pdev->dev, pdev->dev.bus_id);
	if (!hcd) {
		retval = -ENOMEM;
		goto err0;
	}
	hcd->rsrc_start = pdev->resource[0].start;
	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;

	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 = (void __iomem *) (int) IO_ADDRESS(hcd->rsrc_start);

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

	retval = omap_start_hc(ohci, pdev);
	if (retval < 0)
		goto err2;

	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), SA_INTERRUPT);
	if (retval == 0)
		return retval;

	omap_stop_hc(pdev);
err2:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
	usb_put_hcd(hcd);
err0:
	clk_put(usb_host_ck);
	return retval;
}
Ejemplo n.º 2
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.
 */
int usb_hcd_omap_probe (const struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd *ohci;

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

	if (!request_mem_region(pdev->resource[0].start, 
				pdev->resource[0].end - pdev->resource[0].start + 1, hcd_name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		return -EBUSY;
	}

	hcd = usb_create_hcd (driver);
	if (hcd == NULL){
		dev_dbg(&pdev->dev, "hcd_alloc failed\n");
		retval = -ENOMEM;
		goto err1;
	}
	dev_set_drvdata(&pdev->dev, hcd);
	ohci = hcd_to_ohci(hcd);
	ohci_hcd_init(ohci);

	hcd->irq = pdev->resource[1].start;
	hcd->regs = (void *)pdev->resource[0].start;
	hcd->self.controller = &pdev->dev;

	retval = omap_start_hc(ohci, pdev);
	if (retval < 0)
		goto err2;

	retval = hcd_buffer_create (hcd);
	if (retval != 0) {
		dev_dbg(&pdev->dev, "pool alloc fail\n");
		goto err2;
	}

	retval = request_irq (hcd->irq, usb_hcd_irq, 
			      SA_INTERRUPT, hcd->driver->description, hcd);
	if (retval != 0) {
		dev_dbg(&pdev->dev, "request_irq failed\n");
		retval = -EBUSY;
		goto err3;
	}

	dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);

	hcd->self.bus_name = pdev->dev.bus_id;
	usb_register_bus (&hcd->self);

	if ((retval = driver->start (hcd)) < 0) 
	{
		usb_hcd_omap_remove(hcd, pdev);
		return retval;
	}

	return 0;

 err3:
	hcd_buffer_destroy (hcd);
 err2:
	dev_set_drvdata(&pdev->dev, NULL);
	usb_put_hcd(hcd);
 err1:
	omap_stop_hc(pdev);

	release_mem_region(pdev->resource[0].start, 
			   pdev->resource[0].end - pdev->resource[0].start + 1);

	return retval;
}
Ejemplo n.º 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.
 */
int usb_hcd_omap_probe (const struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd *ohci;

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

	if (!request_mem_region(pdev->resource[0].start, 
				pdev->resource[0].end - pdev->resource[0].start + 1, hcd_name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		return -EBUSY;
	}

	hcd = driver->hcd_alloc ();
	if (hcd == NULL){
		dev_dbg(&pdev->dev, "hcd_alloc failed\n");
		retval = -ENOMEM;
		goto err1;
	}
	dev_set_drvdata(&pdev->dev, hcd);
	ohci = hcd_to_ohci(hcd);

	hcd->driver = (struct hc_driver *) driver;
	hcd->description = driver->description;
	hcd->irq = pdev->resource[1].start;
	hcd->regs = (void *)pdev->resource[0].start;
	hcd->self.controller = &pdev->dev;

	retval = omap_start_hc(ohci, pdev);
	if (retval < 0)
		goto err1;

	retval = hcd_buffer_create (hcd);
	if (retval != 0) {
		dev_dbg(&pdev->dev, "pool alloc fail\n");
		goto err1;
	}

	retval = request_irq (hcd->irq, usb_hcd_irq, 
#ifdef CONFIG_PREEMPT_HARDIRQS
			      0, hcd->description, hcd);
#else
			      SA_INTERRUPT, hcd->description, hcd);
#endif
	if (retval != 0) {
		dev_dbg(&pdev->dev, "request_irq failed\n");
		retval = -EBUSY;
		goto err2;
	}

	dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);

	usb_bus_init (&hcd->self);
	hcd->self.op = &usb_hcd_operations;
	hcd->self.release = &usb_hcd_release;
	hcd->self.hcpriv = (void *) hcd;
	hcd->self.bus_name = pdev->dev.bus_id;
	hcd->product_desc = "OMAP OHCI";

	INIT_LIST_HEAD (&hcd->dev_list);
	usb_register_bus (&hcd->self);

	if ((retval = driver->start (hcd)) < 0) 
	{
		usb_hcd_omap_remove(hcd, pdev);
		return retval;
	}

	return 0;

 err2:
	hcd_buffer_destroy (hcd);
 err1:
	kfree(hcd);
	omap_stop_hc(pdev);

	release_mem_region(pdev->resource[0].start, 
			   pdev->resource[0].end - pdev->resource[0].start + 1);

	dev_set_drvdata(&pdev->dev, 0);
	return retval;
}
/**
 * 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.
 *
 * Store this function in the HCD's struct pci_driver as probe().
 */
int usb_hcd_omap_probe (const struct hc_driver *driver,
			  struct usb_hcd **hcd_out,
			  struct omap_dev *dev)
{
	int retval;
	struct usb_hcd *hcd = 0;

	if (!request_mem_region(dev->res.start, 
				dev->res.end - dev->res.start + 1, hcd_name)) {
		dbg("request_mem_region failed");
		return -EBUSY;
	}

	omap_start_hc(dev);

	hcd = driver->hcd_alloc ();
	if (hcd == NULL){
		dbg ("hcd_alloc failed");
		retval = -ENOMEM;
		goto err1;
	}

	hcd->driver = (struct hc_driver *) driver;
	hcd->description = driver->description;
	hcd->irq = dev->irq[0];
	hcd->regs = dev->mapbase;
	hcd->self.controller = &dev->dev;

	retval = hcd_buffer_create (hcd);
	if (retval != 0) {
		dbg ("pool alloc fail");
		goto err1;
	}

	retval = request_irq (hcd->irq, 
			      usb_hcd_omap_hcim_irq, 
			      SA_INTERRUPT, hcd->description, hcd);
	if (retval != 0) {
		dbg("request_irq failed");
		retval = -EBUSY;
		goto err2;
	}

	info ("%s (OMAP) at 0x%p, irq %d\n",
	      hcd->description, hcd->regs, hcd->irq);

	usb_bus_init (&hcd->self);
	hcd->self.op = &usb_hcd_operations;
	hcd->self.hcpriv = (void *) hcd;
	hcd->self.bus_name = "omap";
	hcd->product_desc = "OMAP OHCI";

	INIT_LIST_HEAD (&hcd->dev_list);
	usb_register_bus (&hcd->self);

	if ((retval = driver->start (hcd)) < 0) 
	{
		usb_hcd_omap_remove(hcd, dev);
		return retval;
	}

	*hcd_out = hcd;
	return 0;

 err2:
	hcd_buffer_destroy (hcd);
	if (hcd)
		driver->hcd_free(hcd);
 err1:
	omap_stop_hc(dev);

	release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1);

	return retval;
}