예제 #1
0
/**
 * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs
 * @dev: USB Host Controller being removed
 * Context: !in_interrupt()
 *
 * Reverses the effect of usb_hcd_omap_probe(), first invoking
 * the HCD's stop() method.  It is always called from a thread
 * context, normally "rmmod", "apmd", or something similar.
 *
 */
void usb_hcd_omap_remove (struct usb_hcd *hcd, struct omap_dev *dev)
{
	struct usb_device	*hub;
	void *base;

	info ("remove: %s, state %x", hcd->self.bus_name, hcd->state);

	if (in_interrupt ())
		BUG ();

	hub = hcd->self.root_hub;
	hcd->state = USB_STATE_QUIESCING;

	dbg ("%s: roothub graceful disconnect", hcd->self.bus_name);
	usb_disconnect (&hub);

	hcd->driver->stop (hcd);
	hcd_buffer_destroy (hcd);
	hcd->state = USB_STATE_HALT;

	free_irq (hcd->irq, hcd);

	usb_deregister_bus (&hcd->self);

	base = hcd->regs;
	hcd->driver->hcd_free (hcd);

	omap_stop_hc(dev);

	release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1);
}
예제 #2
0
/**
 * usb_hcd_ppc_soc_remove - shutdown processing for On-Chip HCDs
 * @pdev: USB Host Controller being removed
 * Context: !in_interrupt()
 *
 * Reverses the effect of usb_hcd_ppc_soc_probe().
 * It is always called from a thread
 * context, normally "rmmod", "apmd", or something similar.
 *
 */
static void usb_hcd_ppc_soc_remove(struct platform_device *pdev)
{
	struct usb_hcd	*hcd;
	struct resource	*res;

	hcd = dev_get_drvdata(&pdev->dev);
	if (!hcd)
		return;

	if (in_interrupt())
		BUG();

	if (HCD_IS_RUNNING(hcd->state))
		hcd->state = USB_STATE_QUIESCING;

	usb_disconnect(&hcd->self.root_hub);

	hcd->driver->stop(hcd);
	del_timer_sync(&hcd->rh_timer);
	hcd_buffer_destroy(hcd);
	hcd->state = USB_STATE_HALT;
	dev_set_drvdata(&pdev->dev, NULL);


	free_irq(hcd->irq, hcd);
	iounmap(hcd->regs);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res) {
		release_mem_region(res->start, res->end - res->start + 1);
	}

	usb_deregister_bus (&hcd->self);

	pr_debug("Removed PPC-SOC EHCI USB Controller\n");
}
예제 #3
0
/**
 * usb_hcd_ppc_soc_remove - shutdown processing for On-Chip HCDs
 * @pdev: USB Host Controller being removed
 * Context: !in_interrupt()
 *
 * Reverses the effect of usb_hcd_ppc_soc_probe(), first invoking
 * the HCD's stop() method.  It is always called from a thread
 * context, normally "rmmod", "apmd", or something similar.
 *
 */
static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd, struct platform_device *pdev)
{
	struct resource *res;

	pr_debug(__FILE__ ": remove: %s, state %x\n", hcd->self.bus_name,
								hcd->state);
	if (in_interrupt())
		BUG();

	hcd->state = USB_STATE_QUIESCING;

	pr_debug("%s: roothub graceful disconnect\n", hcd->self.bus_name);
	usb_disconnect(&hcd->self.root_hub);

	hcd->driver->stop(hcd);
	hcd->state = USB_STATE_HALT;

	free_irq(hcd->irq, hcd);
	hcd_buffer_destroy(hcd);

	usb_deregister_bus(&hcd->self);

	iounmap(hcd->regs);
	kfree(hcd);

	pr_debug("stopping PPC-SOC USB Controller\n");

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	release_mem_region(res->start, res->end - res->start + 1);
}
예제 #4
0
/**
 * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs
 * @dev: USB Host Controller being removed
 * Context: !in_interrupt()
 *
 * Reverses the effect of usb_hcd_omap_probe(), first invoking
 * the HCD's stop() method.  It is always called from a thread
 * context, normally "rmmod", "apmd", or something similar.
 *
 */
void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
{
	dev_info(&pdev->dev, "remove: state %x\n", hcd->state);

	if (in_interrupt ())
		BUG ();

	hcd->state = USB_STATE_QUIESCING;

	dev_dbg(&pdev->dev, "roothub graceful disconnect\n");
	usb_disconnect (&hcd->self.root_hub);

	hcd->driver->stop (hcd);
	hcd_buffer_destroy (hcd);
	hcd->state = USB_STATE_HALT;

	if (machine_is_omap_osk())
		omap_free_gpio(9);

	free_irq (hcd->irq, hcd);

	usb_deregister_bus (&hcd->self);

	omap_stop_hc(pdev);

	release_mem_region(pdev->resource[0].start, 
			   pdev->resource[0].end - pdev->resource[0].start + 1);
}
예제 #5
0
/**
 * usb_hcd_pxa27x_remove - shutdown processing for pxa27x-based HCDs
 * @dev: USB Host Controller being removed
 * Context: !in_interrupt()
 *
 * Reverses the effect of usb_hcd_pxa27x_probe(), first invoking
 * the HCD's stop() method.  It is always called from a thread
 * context, normally "rmmod", "apmd", or something similar.
 *
 */
void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev)
{
	void *base;

	pr_debug ("remove: %s, state %x", hcd->self.bus_name, hcd->state);

	if (in_interrupt ())
		BUG ();

	hcd->state = USB_STATE_QUIESCING;

	pr_debug ("%s: roothub graceful disconnect", hcd->self.bus_name);
	usb_disconnect (&hcd->self.root_hub);

	hcd->driver->stop (hcd);
	hcd->state = USB_STATE_HALT;

	free_irq (hcd->irq, hcd);
	hcd_buffer_destroy (hcd);

	usb_deregister_bus (&hcd->self);

	base = hcd->regs;
	hcd->driver->hcd_free (hcd);

	pxa27x_stop_hc(dev);
	release_mem_region(dev->resource[0].start,
			   dev->resource[0].end - dev->resource[0].start + 1);
}
/**
 * usb_remove_hcd - shutdown processing for generic HCDs
 * @hcd: the usb_hcd structure to remove
 * Context: !in_interrupt()
 *
 * Disconnects the root hub, then reverses the effects of usb_add_hcd(),
 * invoking the HCD's stop() method.
 */
void mtk_usb_remove_hcd(struct usb_hcd *hcd)
{
	dev_info(hcd->self.controller, "remove, state %x\n", hcd->state);

	if (HC_IS_RUNNING (hcd->state))
		hcd->state = HC_STATE_QUIESCING;

	dev_dbg(hcd->self.controller, "roothub graceful disconnect\n");
#if 0
	spin_lock_irq (&hcd_root_hub_lock);
	hcd->rh_registered = 0;
	spin_unlock_irq (&hcd_root_hub_lock);
#endif
#if 0 //#ifdef CONFIG_USB_SUSPEND
	cancel_work_sync(&hcd->wakeup_work);
#endif
#if 0
	sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group);
	mutex_lock(&usb_bus_list_lock);
	usb_disconnect(&hcd->self.root_hub);
	mutex_unlock(&usb_bus_list_lock);
#endif
	hcd->driver->stop(hcd);
	hcd->state = HC_STATE_HALT;
#if 0
	hcd->poll_rh = 0;
	del_timer_sync(&hcd->rh_timer);
#endif
	if (hcd->irq >= 0)
		free_irq(hcd->irq, hcd);
#if 0
	usb_deregister_bus(&hcd->self);
#endif
	hcd_buffer_destroy(hcd);
}
예제 #7
0
/**
 * usb_hcd_pci_remove - shutdown processing for PCI-based HCDs
 * @dev: USB Host Controller being removed
 * Context: !in_interrupt()
 *
 * Reverses the effect of usb_hcd_pci_probe(), first invoking
 * the HCD's stop() method.  It is always called from a thread
 * context, normally "rmmod", "apmd", or something similar.
 *
 * Store this function in the HCD's struct pci_driver as remove().
 */
void usb_hcd_pci_remove (struct pci_dev *dev)
{
	struct usb_hcd		*hcd;

	hcd = pci_get_drvdata(dev);
	if (!hcd)
		return;
	dev_info (hcd->self.controller, "remove, state %x\n", hcd->state);

	if (in_interrupt ())
		BUG ();

	if (HCD_IS_RUNNING (hcd->state))
		hcd->state = USB_STATE_QUIESCING;

	dev_dbg (hcd->self.controller, "roothub graceful disconnect\n");
	usb_disconnect (&hcd->self.root_hub);

	hcd->driver->stop (hcd);
	hcd_buffer_destroy (hcd);
	hcd->state = USB_STATE_HALT;
	pci_set_drvdata(dev, NULL);

	free_irq (hcd->irq, hcd);
	if (hcd->driver->flags & HCD_MEMORY) {
		iounmap (hcd->regs);
		release_mem_region (pci_resource_start (dev, 0),
			pci_resource_len (dev, 0));
	} else {
		release_region (pci_resource_start (dev, hcd->region),
			pci_resource_len (dev, hcd->region));
	}

	usb_deregister_bus (&hcd->self);
}
예제 #8
0
static int __init_or_module arc_ehci_remove(struct device *dev)
{
	struct ehci_hcd *ehci = dev_get_drvdata(dev);
	struct usb_hcd *hcd = ehci_to_hcd(ehci);
	struct arc_usb_config *config;

	config = (struct arc_usb_config *)dev->platform_data;

	dbg("%s  dev=0x%p\n", __FUNCTION__, dev);

	if (HCD_IS_RUNNING(hcd->state))
		hcd->state = USB_STATE_QUIESCING;

	usb_disconnect(&hcd->self.root_hub);

	hcd->driver->stop(hcd);

	hcd_buffer_destroy(hcd);

	usb_deregister_bus(&hcd->self);

	free_irq(hcd->irq, hcd);

	usb_put_hcd(hcd);

	/*
	 * do platform specific un-initialization:
	 * release iomux pins, etc.
	 */
	config->platform_uninit();

	return 0;
}
예제 #9
0
/**
 * hcd_buffer_create - initialize buffer pools
 * @hcd: the bus whose buffer pools are to be initialized
 * Context: !in_interrupt()
 *
 * Call this as part of initializing a host controller that uses the dma
 * memory allocators.  It initializes some pools of dma-coherent memory that
 * will be shared by all drivers using that controller, or returns a negative
 * errno value on error.
 *
 * Call hcd_buffer_destroy() to clean up after using those pools.
 */
int hcd_buffer_create (struct usb_hcd *hcd)
{
	char		name [16];
	int 		i, size;

	for (i = 0; i < HCD_BUFFER_POOLS; i++) { 
		if (!(size = pool_max [i]))
			continue;
		snprintf (name, sizeof name, "buffer-%d", size);
		hcd->pool [i] = dma_pool_create (name, hcd->self.controller,
				size, size, 0);
		if (!hcd->pool [i]) {
			hcd_buffer_destroy (hcd);
			return -ENOMEM;
		}
	}
	return 0;
}
예제 #10
0
파일: hcd-pci.c 프로젝트: kidoz/cxbx
/**
 * usb_hcd_pci_remove - shutdown processing for PCI-based HCDs
 * @dev: USB Host Controller being removed
 * Context: !in_interrupt()
 *
 * Reverses the effect of usb_hcd_pci_probe(), first invoking
 * the HCD's stop() method.  It is always called from a thread
 * context, normally "rmmod", "apmd", or something similar.
 *
 * Store this function in the HCD's struct pci_driver as remove().
 */
void usb_hcd_pci_remove (struct pci_dev *dev)
{
	struct usb_hcd		*hcd;
	struct usb_device	*hub;

	hcd = pci_get_drvdata(dev);
	if (!hcd)
		return;
	dev_info (hcd->controller, "remove, state %x\n", hcd->state);

	if (in_interrupt ())
		BUG ();

	hub = hcd->self.root_hub;
	hcd->state = USB_STATE_QUIESCING;

	dev_dbg (hcd->controller, "roothub graceful disconnect\n");
	usb_disconnect (&hub);

	hcd->driver->stop (hcd);
	hcd_buffer_destroy (hcd);
	hcd->state = USB_STATE_HALT;
	pci_set_drvdata (dev, 0);

	free_irq (hcd->irq, hcd);
	if (hcd->driver->flags & HCD_MEMORY) {
		iounmap (hcd->regs);
		release_mem_region (pci_resource_start (dev, 0),
			pci_resource_len (dev, 0));
	} else {
		release_region (pci_resource_start (dev, hcd->region),
			pci_resource_len (dev, hcd->region));
	}

	usb_deregister_bus (&hcd->self);
	if (atomic_read (&hcd->self.refcnt) != 1) {
		dev_warn (hcd->controller,
			"dangling refs (%d) to bus %d!\n",
			atomic_read (&hcd->self.refcnt) - 1,
			hcd->self.busnum);
	}
	hcd->driver->hcd_free (hcd);
}
예제 #11
0
파일: buffer.c 프로젝트: rcplay/snake-os
/**
 * hcd_buffer_create - initialize buffer pools
 * @hcd: the bus whose buffer pools are to be initialized
 * Context: !in_interrupt()
 *
 * Call this as part of initializing a host controller that uses the dma
 * memory allocators.  It initializes some pools of dma-coherent memory that
 * will be shared by all drivers using that controller, or returns a negative
 * errno value on error.
 *
 * Call hcd_buffer_destroy() to clean up after using those pools.
 */
int hcd_buffer_create (struct usb_hcd *hcd)
{
    char		name [16];
    int 		i, size;

#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100) && !defined(CONFIG_ARCH_CETUSPLUS)
    if (!hcd->self.controller->dma_mask)
        return 0;
#endif

    for (i = 0; i < HCD_BUFFER_POOLS; i++) {
        if (!(size = pool_max [i]))
            continue;
        snprintf (name, sizeof name, "buffer-%d", size);
        hcd->pool [i] = dma_pool_create (name, hcd->self.controller,
                                         size, size, 0);
        if (!hcd->pool [i]) {
            hcd_buffer_destroy (hcd);
            return -ENOMEM;
        }
    }
    return 0;
}
예제 #12
0
void usb_hcd_superh_remove(struct usb_hcd *hcd, struct platform_device *dev)
{
	pr_debug("remove: %s, state %x", hcd->self.bus_name, hcd->state);

	if (in_interrupt())
		BUG();

	hcd->state = USB_STATE_QUIESCING;

	pr_debug("%s: roothub graceful disconnect", hcd->self.bus_name);
	usb_disconnect(&hcd->self.root_hub);

	hcd->driver->stop(hcd);
	hcd->state = USB_STATE_HALT;

	free_irq(hcd->irq, hcd);
	hcd_buffer_destroy(hcd);

	usb_deregister_bus(&hcd->self);

	superh_stop_hc(dev);
	release_mem_region((unsigned long)hcd->regs, sizeof(struct ohci_regs));
}
예제 #13
0
/**
 * usb_hcd_pxa27x_probe - initialize pxa27x-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_pxa27x_probe (const struct hc_driver *driver,
			  struct usb_hcd **hcd_out,
			  struct platform_device *dev)
{
	int retval;
	struct usb_hcd *hcd = 0;

	unsigned int *addr = NULL;

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

	pxa27x_start_hc(dev);

	/* Select Power Management Mode */
	pxa27x_ohci_select_pmm( PMM_PERPORT_MODE );

	/* If choosing PMM_PERPORT_MODE, we should set the port power before we use it. */
	if (pxa27x_ohci_set_port_power(1) < 0)
		printk(KERN_ERR "Setting port 1 power failed.\n");

	if (pxa27x_ohci_clear_port_power(2) < 0)
		printk(KERN_ERR "Setting port 2 power failed.\n");

	if (pxa27x_ohci_clear_port_power(3) < 0)
		printk(KERN_ERR "Setting port 3 power failed.\n");

	addr = ioremap(dev->resource[0].start,
		       dev->resource[0].end - dev->resource[0].start + 1);
	if (!addr) {
		pr_debug("ioremap failed");
		retval = -ENOMEM;
		goto err1;
	}

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

	if(dev->resource[1].flags != IORESOURCE_IRQ){
		pr_debug ("resource[1] is not IORESOURCE_IRQ");
		retval = -ENOMEM;
		goto err1;
	}

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

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

	retval = request_irq (hcd->irq, usb_hcd_irq, SA_INTERRUPT,
			      hcd->description, hcd);
	if (retval != 0) {
		pr_debug("request_irq(%d) failed with retval %d\n",hcd->irq,retval);
		retval = -EBUSY;
		goto err2;
	}

	pr_debug ("%s (pxa27x) at 0x%p, irq %d",
	     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 = "pxa27x";
	hcd->product_desc = "PXA27x OHCI";

	INIT_LIST_HEAD (&hcd->dev_list);

	usb_register_bus (&hcd->self);

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

	*hcd_out = hcd;
	return 0;

 err2:
	hcd_buffer_destroy (hcd);
	if (hcd)
		driver->hcd_free(hcd);
 err1:
	pxa27x_stop_hc(dev);
	release_mem_region(dev->resource[0].start,
				dev->resource[0].end
			   - dev->resource[0].start + 1);
	return retval;
}
/**
 * usb_add_hcd - finish generic HCD structure initialization and register
 * @hcd: the usb_hcd structure to initialize
 * @irqnum: Interrupt line to allocate
 * @irqflags: Interrupt type flags
 *
 * Finish the remaining parts of generic HCD initialization: allocate the
 * buffers of consistent memory, register the bus, request the IRQ line,
 * and call the driver's reset() and start() routines.
 */
int mtk_usb_add_hcd(struct usb_hcd *hcd,
		unsigned int irqnum, unsigned long irqflags)
{
	int retval;
	struct usb_device *rhdev;
	dev_info(hcd->self.controller, "%s\n", hcd->product_desc);

	hcd->authorized_default = hcd->wireless? 0 : 1;
	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

	/* HC is in reset state, but accessible.  Now do the one-time init,
	 * bottom up so that hcds can customize the root hubs before khubd
	 * starts talking to them.  (Note, bus id is assigned early too.)
	 */
	if ((retval = hcd_buffer_create(hcd)) != 0) {
		dev_dbg(hcd->self.controller, "pool alloc failed\n");
		return retval;
	}
	
	if ((rhdev = mtk_usb_alloc_rhdev(NULL, &hcd->self, 0)) == NULL) {
		dev_err(hcd->self.controller, "unable to allocate root hub\n");
		retval = -ENOMEM;
		goto err_allocate_root_hub;
	}
	hcd->self.root_hub = rhdev;
#if 0
	if ((retval = usb_register_bus(&hcd->self)) < 0)
		goto err_register_bus;

	if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
		dev_err(hcd->self.controller, "unable to allocate root hub\n");
		retval = -ENOMEM;
		goto err_allocate_root_hub;
	}

	switch (hcd->driver->flags & HCD_MASK) {
	case HCD_USB11:
		rhdev->speed = USB_SPEED_FULL;
		break;
	case HCD_USB2:
		rhdev->speed = USB_SPEED_HIGH;
		break;
	case HCD_USB3:
		rhdev->speed = USB_SPEED_SUPER;
		break;
	default:
		goto err_allocate_root_hub;
	}
	hcd->self.root_hub = rhdev;

	/* wakeup flag init defaults to "everything works" for root hubs,
	 * but drivers can override it in reset() if needed, along with
	 * recording the overall controller's system wakeup capability.
	 */
	device_init_wakeup(&rhdev->dev, 1);
#endif

	/* "reset" is misnamed; its role is now one-time init. the controller
	 * should already have been reset (and boot firmware kicked off etc).
	 */
	printk(KERN_DEBUG "call xhci_mtk_setup\n");
	if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
		dev_err(hcd->self.controller, "can't setup\n");
		goto err_hcd_driver_setup;
	}
#if 0
	/* NOTE: root hub and controller capabilities may not be the same */
	if (device_can_wakeup(hcd->self.controller)
			&& device_can_wakeup(&hcd->self.root_hub->dev))
		dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
#endif
	/* enable irqs just before we start the controller */
	if (hcd->driver->irq) {

		/* IRQF_DISABLED doesn't work as advertised when used together
		 * with IRQF_SHARED. As usb_hcd_irq() will always disable
		 * interrupts we can remove it here.
		 */
		if (irqflags & IRQF_SHARED)
			irqflags &= ~IRQF_DISABLED;

		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
				hcd->driver->description, hcd->self.busnum);
		if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
				hcd->irq_descr, hcd)) != 0) {
			dev_err(hcd->self.controller,
					"request interrupt %d failed\n", irqnum);
			goto err_request_irq;
		}
		hcd->irq = irqnum;
		dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum,
				(hcd->driver->flags & HCD_MEMORY) ?
					"io mem" : "io base",
					(unsigned long long)hcd->rsrc_start);
	} else {
		hcd->irq = -1;
		if (hcd->rsrc_start)
			dev_info(hcd->self.controller, "%s 0x%08llx\n",
					(hcd->driver->flags & HCD_MEMORY) ?
					"io mem" : "io base",
					(unsigned long long)hcd->rsrc_start);
	}

	if ((retval = hcd->driver->start(hcd)) < 0) {
		dev_err(hcd->self.controller, "startup error %d\n", retval);
		goto err_hcd_driver_start;
	}
#if 0
	/* starting here, usbcore will pay attention to this root hub */
	rhdev->bus_mA = min(500u, hcd->power_budget);
	if ((retval = register_root_hub(hcd)) != 0)
		goto err_register_root_hub;

	retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);
	if (retval < 0) {
		printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n",
		       retval);
		goto error_create_attr_group;
	}
	if (hcd->uses_new_polling && hcd->poll_rh)
		usb_hcd_poll_rh_status(hcd);
#endif
	return retval;

error_create_attr_group:
	mutex_lock(&usb_bus_list_lock);
	usb_disconnect(&hcd->self.root_hub);
	mutex_unlock(&usb_bus_list_lock);
err_register_root_hub:
	hcd->driver->stop(hcd);
err_hcd_driver_start:
	if (hcd->irq >= 0)
		free_irq(irqnum, hcd);
err_request_irq:
err_hcd_driver_setup:
	hcd->self.root_hub = NULL;
	usb_put_dev(rhdev);
#if 1
err_allocate_root_hub:
	hcd->driver->stop(hcd);
#endif
err_register_bus:
	hcd_buffer_destroy(hcd);
	return retval;
} 
예제 #15
0
/**
 * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller.
 *
 * Store this function in the HCD's struct pci_driver as probe().
 */
static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
			  struct usb_hcd **hcd_out,
			  struct platform_device *pdev)
{
	int retval;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd	*ohci;
	struct resource *res;
	int irq;

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

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		pr_debug(__FILE__ ": no irq\n");
		return -ENODEV;
	}
	irq = res->start;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		pr_debug(__FILE__ ": no reg addr\n");
		return -ENODEV;
	}
	if (!request_mem_region(res->start, res->end - res->start + 1,
					hcd_name)) {
		pr_debug(__FILE__ ": request_mem_region failed\n");
		return -EBUSY;
	}

	hcd = driver->hcd_alloc ();
	if (!hcd){
		pr_debug(__FILE__ ": hcd_alloc failed\n");
		retval = -ENOMEM;
		goto err1;
	}

	ohci = hcd_to_ohci(hcd);

	ohci->flags |= OHCI_BIG_ENDIAN;

	hcd->driver = (struct hc_driver *) driver;
	hcd->description = driver->description;
	hcd->irq = irq;
	hcd->regs = (struct ohci_regs *) ioremap(res->start,
						res->end - res->start + 1);
	if (!hcd->regs) {
		pr_debug(__FILE__ ": ioremap failed\n");
		retval = -ENOMEM;
		goto err2;
	}

	hcd->self.controller = &pdev->dev;

	retval = hcd_buffer_create(hcd);
	if (retval) {
		pr_debug(__FILE__ ": pool alloc fail\n");
		goto err3;
	}

	retval = request_irq(hcd->irq, usb_hcd_irq, SA_INTERRUPT,
				hcd_name, hcd);
	if (retval) {
		pr_debug(__FILE__ ": request_irq failed, returned %d\n",
								retval);
		retval = -EBUSY;
		goto err4;
	}

	info("%s (PPC-SOC) at 0x%p, irq %d\n",
	      hcd_name, 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 = "PPC-SOC USB";
	hcd->product_desc = "PPC-SOC OHCI";

	INIT_LIST_HEAD(&hcd->dev_list);

	usb_register_bus(&hcd->self);

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

	*hcd_out = hcd;
	return 0;

 err4:
	hcd_buffer_destroy(hcd);
 err3:
	iounmap(hcd->regs);
 err2:
	dev_set_drvdata(&pdev->dev, NULL);
 err1:
	pr_debug("Removing PPC-SOC USB Controller\n");
	release_mem_region(res->start, res->end - res->start + 1);
	return retval;
}
예제 #16
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;
}
예제 #17
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;
}
예제 #18
0
/**
 * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller.
 *
 * Store this function in the HCD's struct pci_driver as probe().
 */
static int usb_hcd_ppc_soc_probe(struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval;
	struct usb_hcd *hcd;
	struct ehci_hcd	*ehci;
	struct resource *res;
	unsigned long res_len;
	int irq;

	pr_debug("Initializing PPC-SOC EHCI USB Controller\n");

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		pr_debug(__FILE__ ": no irq\n");
		return -ENODEV;
	}
	irq = res->start;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		pr_debug(__FILE__ ": no reg addr\n");
		return -ENODEV;
	}
	hcd = driver->hcd_alloc();
	if (!hcd)
		return -ENOMEM;

	ehci = hcd_to_ehci(hcd);
	ehci->big_endian = 1;

	res_len = res->end - res->start + 1;
	if (!request_mem_region(res->start, res_len, hcd_name)) {
		pr_debug(__FILE__ ": request_mem_region failed\n");
		retval = -EBUSY;
		goto err1;
	}

	hcd->regs = ioremap64(res->start, res_len);
	if (!hcd->regs) {
		pr_debug(__FILE__ ": ioremap failed\n");
		retval = -ENOMEM;
		goto err2;
	}

	dev_set_drvdata(&pdev->dev, hcd);
	hcd->driver = driver;
	hcd->description = driver->description;
	hcd->self.bus_name = pdev->dev.bus_id;
	hcd->product_desc = "PPC-SOC EHCI USB";
	hcd->self.controller = &pdev->dev;

	if ((retval = hcd_buffer_create(hcd)) != 0) {
		pr_debug(__FILE__ ": hcd_buffer_create failed\n");
		retval = -ENOMEM;
		goto err3;
	}

	hcd->state = USB_STATE_HALT;

	retval = request_irq(irq, usb_hcd_irq, SA_SHIRQ,
				hcd->description, hcd);
	if (retval != 0) {
		pr_debug(__FILE__ ": request_irq failed\n");
		retval = -ENODEV;
		goto err4;
	}

	hcd->irq = irq;
	usb_bus_init(&hcd->self);
	hcd->self.op = &usb_hcd_operations;
	hcd->self.release = &usb_hcd_release;
	hcd->self.hcpriv = (void *) hcd;
	init_timer(&hcd->rh_timer);

	INIT_LIST_HEAD(&hcd->dev_list);

	usb_register_bus(&hcd->self);

	if ((retval = driver->start(hcd)) < 0) {
		dev_err(hcd->self.controller, "init error %d\n", retval);
		usb_hcd_ppc_soc_remove(pdev);
	}
	return retval;

err4:
	hcd_buffer_destroy(hcd);
err3:
	iounmap(hcd->regs);
err2:
	release_mem_region(res->start, res_len);
err1:
	kfree(hcd);
	return retval;
}
예제 #19
0
int usb_hcd_superh_probe(const struct hc_driver *driver,
			 struct usb_hcd **hcd_out, struct platform_device *dev)
{
	int retval;
	struct usb_hcd *hcd = 0;

	if (!request_mem_region
	    (SH_OHCI_REGS_BASE, sizeof(struct ohci_regs), hcd_name)) {
		dbg("controller already in use");
		return -EBUSY;
	}

	superh_start_hc(dev);

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

	hcd->driver = (struct hc_driver *)driver;
	hcd->irq = SH_OHCI_IRQ;
	hcd->regs = (void *)SH_OHCI_REGS_BASE;
	dev->dev.dma_mask = &superh_dmamask;
	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_superh_hcim_irq, SA_INTERRUPT,
			     hcd->driver->description, hcd);
	if (retval != 0) {
		dbg("request_irq failed");
		retval = -EBUSY;
		goto err2;
	}

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

	hcd->self.bus_name = "superh";

	usb_register_bus(&hcd->self);

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

      err2:
	hcd_buffer_destroy(hcd);
      err1:
	kfree(hcd);
	superh_stop_hc(dev);
	release_mem_region((unsigned long)hcd->regs, sizeof(struct ohci_regs));
	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;
}