/**
 * Removes the HCD.
 * Frees memory and resources associated with the HCD and deregisters the bus.
 */
void hcd_remove(struct platform_device *_dev)
{
	dwc_otg_device_t *otg_dev = platform_get_otgdata(_dev);
	dwc_otg_hcd_t *dwc_otg_hcd;
	struct usb_hcd *hcd;

	DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");

	if (!otg_dev) {
		DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
		return;
	}

	dwc_otg_hcd = otg_dev->hcd;

	if (!dwc_otg_hcd) {
		DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
		return;
	}

	hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);

	if (!hcd) {
		DWC_DEBUGPL(DBG_ANY,
			    "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n",
			    __func__);
		return;
	}
	usb_remove_hcd(hcd);
	dwc_otg_hcd_set_priv_data(dwc_otg_hcd, NULL);
	dwc_otg_hcd_remove(dwc_otg_hcd);
	usb_put_hcd(hcd);
}
示例#2
0
static int __devexit dwc_otg_driver_remove(struct platform_device *ofdev)
{
	struct device *dev = &ofdev->dev;
	struct dwc_otg_device *dwc_dev = dev_get_drvdata(dev);

	/* Memory allocation for dwc_otg_device may have failed. */
	if (!dwc_dev)
		return 0;

	/* Free the IRQ */
	free_irq(dwc_dev->irq, dwc_dev);
	/* Free external charge pump irq */
	free_irq(dwc_dev->hcd->cp_irq, dwc_dev);

	if (dwc_dev->hcd)
		dwc_otg_hcd_remove(dev);

	if (dwc_dev->pcd)
		dwc_otg_pcd_remove(dev);

	if (dwc_dev->core_if)
		dwc_otg_cil_remove(dwc_dev->core_if);

	if(dwc_dev->core_if->core_params)
		kfree(dwc_dev->core_if->core_params);

	/* Return the memory. */
	if (dwc_dev->base)
		iounmap(dwc_dev->base);

	if (dwc_dev->phys_addr)
		release_mem_region(dwc_dev->phys_addr, dwc_dev->base_len);

	usb_put_phy(dwc_dev->core_if->xceiv);
	dwc_dev->core_if->xceiv = NULL;

	kfree(dwc_dev);

	/* Clear the drvdata pointer. */
	dev_set_drvdata(dev, NULL);
	return 0;
}