Beispiel #1
0
/*****************************************************************
 *
 * Function Name: hc_release_hci
 *
 * This function De-allocate all resources  
 *
 * Input:  hci = data structure for the host controller
 *
 * Return value  : 0 
 *                
 *****************************************************************/
static void hc_release_hci (hci_t * hci)
{
	hcipriv_t *hp = &hci->hp;

	DBGFUNC ("Enter hc_release_hci\n");

	/* disconnect all devices */
	if (hci->bus->root_hub)
		usb_disconnect (&hci->bus->root_hub);

	hc_reset (hci);

	if (hp->tl)
		kfree (hp->tl);

	if (hp->hcport > 0) {
		release_region (hp->hcport, 2);
		hp->hcport = 0;
	}

	if (hp->irq >= 0) {
		free_irq (hp->irq, hci);
		hp->irq = -1;
	}

	usb_deregister_bus (hci->bus);
	usb_put_bus (hci->bus);

	list_del_init (&hci->hci_hcd_list);

	kfree (hci);
}
Beispiel #2
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);
}
Beispiel #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);
}
Beispiel #5
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");
}
Beispiel #6
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;
}
Beispiel #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);
}
Beispiel #8
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);
}
Beispiel #9
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);
}
Beispiel #10
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;
	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);
}
Beispiel #11
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));
}
Beispiel #12
0
static int __init arc_ehci_probe(struct device *dev)
{
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	int retval;
	struct arc_usb_config *config;
	struct platform_device *pdev = to_platform_device(dev);

	config = (struct arc_usb_config *)dev->platform_data;
	dbg("\n%s  dev=0x%p  config=0x%p  name=%s\n",
	    __FUNCTION__, dev, config, config->name);

	if (pdev->resource[0].flags != 0
	    || pdev->resource[1].flags != IORESOURCE_IRQ) {
		return -ENODEV;
	}

	dbg("ehci_driver.description=%s  platform_device.name=%s\n",
	    ehci_driver.description, pdev->name);

	/*
	 * do platform specific init: check the clock, grab/config pins, etc.
	 */
	if (config->platform_init() != 0) {
		retval = -EINVAL;
		goto err1;
	}

	hcd = usb_create_hcd(&ehci_driver);
	if (!hcd) {
		retval = 0;
		goto err1;
	}

	ehci = hcd_to_ehci(hcd);
	dev_set_drvdata(dev, ehci);

	dbg("%s: hcd=0x%p  ehci=0x%p\n", __FUNCTION__, hcd, ehci);

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

	hcd->self.controller = dev;
	hcd->self.bus_name = dev->bus_id;
	hcd->product_desc = "Freescale ARC_OTG";

	retval = hcd_buffer_create(hcd);
	if (retval != 0) {
		dev_dbg(dev, "pool alloc failed\n");
		goto err2;
	}

	INIT_LIST_HEAD(&hcd->dev_list);

	retval =
	    request_irq(hcd->irq, usb_hcd_irq, SA_INTERRUPT, pdev->name, hcd);
	if (retval != 0)
		goto err2;

	retval = usb_register_bus(&hcd->self);
	if (retval < 0)
		goto err3;

	retval = ehci_hc_reset(hcd);

	if (retval < 0)
		goto err4;

	if ((retval = ehci_start(hcd)) < 0) {
		goto err4;
	}

	return 0;
      err4:
	usb_deregister_bus(&hcd->self);
      err3:
	free_irq(hcd->irq, hcd);
      err2:
	usb_put_hcd(hcd);
      err1:
	printk("init error, %d\n", retval);
	return retval;
}