void usb_disconnect() { struct usb_event evt; evt.event = USB_EVENT_DISCONNECT; if (static_data->usb_event_cb) { static_data->usb_event_cb(&evt); } if (dwc_otg_device->core_if->pcd_cb) { DWC_FREE(dwc_otg_device->core_if->pcd_cb); dwc_otg_device->core_if->pcd_cb = NULL; } if (dwc_otg_device->pcd) { dwc_otg_pcd_remove(dwc_otg_device->pcd); dwc_otg_device->pcd = NULL; } if (dwc_otg_device->core_if) { dwc_otg_cil_remove(dwc_otg_device->core_if); dwc_otg_device->core_if = NULL; } /* Disable clock */ MMIO_REG_VAL(AHB_CTRL_REG) &= ~CCU_USB_CLK_EN; /* Stopping USB PLL */ MMIO_REG_VAL(USB_PLL_CFG0) &= ~USB_PLL_PDLD; /* Disable regulator */ gpio_write(SOC_GPIO_32, VENABLE_USB_REGULATOR, 0); }
/** * Cleanup the PCD. */ void pcd_remove( struct platform_device *_dev ) { dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev); struct sprd_usb_platform_data *pdata= _dev->dev.platform_data; dwc_otg_pcd_t *pcd = otg_dev->pcd; int plug_irq; DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev); usb_del_gadget_udc(&gadget_wrapper->gadget); /* * Free the IRQ */ free_irq(platform_get_irq(_dev, 0), pcd); plug_irq = usb_get_vbus_irq(); usb_free_vbus_irq(plug_irq,pdata->gpio_chgdet); dwc_otg_pcd_remove(pcd); destroy_workqueue(gadget_wrapper->detect_wq); destroy_workqueue(gadget_wrapper->cable2pc_wq); wake_lock_destroy(&usb_wake_lock); switch_dev_unregister(&gadget_wrapper->sdev); free_wrapper(gadget_wrapper); pcd = 0; }
void pcd_remove( struct dwc_otg_device *_dev ) { dwc_otg_device_t *otg_dev = _dev; dwc_otg_pcd_t *pcd = otg_dev->pcd; DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev); /* * Free the IRQ */ //free_irq(_dev->irq, pcd); dwc_otg_pcd_remove(otg_dev->pcd); free_wrapper(gadget_wrapper); otg_dev->pcd = 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; }
/** * Cleanup the PCD. */ void pcd_remove(struct platform_device *_dev) { dwc_otg_device_t *otg_dev = platform_get_otgdata(_dev); dwc_otg_pcd_t *pcd = otg_dev->pcd; int irq; DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev); /* * Free the IRQ */ irq = platform_get_irq(_dev, 0); if(irq >= 0) { free_irq(irq, pcd); } dwc_otg_pcd_remove(otg_dev->pcd); free_wrapper(gadget_wrapper); otg_dev->pcd = 0; }
/** * Cleanup the PCD. */ void pcd_remove( struct platform_device *_dev ) { dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev); dwc_otg_pcd_t *pcd = otg_dev->pcd; int plug_irq; DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev); /* * Free the IRQ */ //free_irq(_dev->irq, pcd); plug_irq = usb_get_vbus_irq(); usb_free_vbus_irq(plug_irq); dwc_otg_pcd_remove(pcd); destroy_workqueue(gadget_wrapper->detect_wq); wake_lock_destroy(&usb_wake_lock); switch_dev_unregister(&gadget_wrapper->sdev); free_wrapper(gadget_wrapper); pcd = 0; }
static int __devinit dwc_otg_driver_probe(struct platform_device *ofdev) { int retval; struct dwc_otg_device *dwc_dev; struct device *dev = &ofdev->dev; struct resource res; ulong gusbcfg_addr; u32 usbcfg = 0; struct resource *nres = 0; #ifdef CONFIG_OF u32 prop; u32 prop_array[15]; #endif dwc_dev = kzalloc(sizeof(*dwc_dev), GFP_KERNEL); if (!dwc_dev) { dev_err(dev, "kmalloc of dwc_otg_device failed\n"); retval = -ENOMEM; goto fail_dwc_dev; } /* Retrieve the memory and IRQ resources. */ dwc_dev->irq = platform_get_irq(ofdev, 0); if (dwc_dev->irq == NO_IRQ) { dev_err(dev, "no device irq\n"); retval = -ENODEV; goto fail_of_irq; } nres = platform_get_resource(ofdev, IORESOURCE_MEM, 0); res = *nres; if(nres == 0) { dev_err(dev, "%s: Can't get USB-OTG register address\n", __func__); retval = -ENOMEM; goto fail_of_irq; } dwc_dev->phys_addr = res.start; dwc_dev->base_len = res.end - res.start + 1; if (!request_mem_region(dwc_dev->phys_addr, dwc_dev->base_len, dwc_driver_name)) { dev_err(dev, "request_mem_region failed\n"); retval = -EBUSY; goto fail_of_irq; } /* Map the DWC_otg Core memory into virtual address space. */ dwc_dev->base = ioremap(platform_get_resource(ofdev, IORESOURCE_MEM, 0)->start, SZ_256K); if (!dwc_dev->base) { dev_err(dev, "ioremap() failed\n"); retval = -ENOMEM; goto fail_ioremap; } dev_dbg(dev, "mapped base=0x%08x\n", (__force u32)dwc_dev->base); /* * Initialize driver data to point to the global DWC_otg * Device structure. */ dev_set_drvdata(dev, dwc_dev);//driver dwc_dev->core_if = dwc_otg_cil_init(dwc_dev->base, &dwc_otg_module_params); if (!dwc_dev->core_if) { dev_err(dev, "CIL initialization failed!\n"); retval = -ENOMEM; goto fail_cil_init; } /* * Set the wqfunc of this core_if as "not set" */ dwc_dev->core_if->wqfunc_setup_done = 0; /* * Validate parameter values after dwc_otg_cil_init. */ if (check_parameters(dwc_dev->core_if)) { retval = -EINVAL; goto fail_check_param; } #ifdef CONFIG_OF if(!of_property_read_u32(ofdev->dev.of_node, "dma-mask", (u32*)&dwc_otg_dma_mask)) { dev->dma_mask = &dwc_otg_dma_mask; } else { dev->dma_mask = NULL; } if(!of_property_read_u32(ofdev->dev.of_node, "ulpi-ddr", &prop)) { dwc_otg_module_params.phy_ulpi_ddr = prop; } if(!of_property_read_u32(ofdev->dev.of_node, "host-rx-fifo-size", &prop)) { dwc_otg_module_params.host_rx_fifo_size = prop; } if(!of_property_read_u32(ofdev->dev.of_node, "dev-rx-fifo-size", &prop)) { dwc_otg_module_params.dev_rx_fifo_size = prop; } if(!of_property_read_u32(ofdev->dev.of_node, "host-nperio-tx-fifo-size", &prop)) { dwc_otg_module_params.host_nperio_tx_fifo_size = prop; } if(!of_property_read_u32(ofdev->dev.of_node, "dev-nperio-tx-fifo-size", &prop)) { dwc_otg_module_params.dev_nperio_tx_fifo_size = prop; } if(!of_property_read_u32(ofdev->dev.of_node, "host-perio-tx-fifo-size", &prop)) { dwc_otg_module_params.host_perio_tx_fifo_size = prop; } if(!of_property_read_u32_array(ofdev->dev.of_node, "dev-perio-tx-fifo-size", prop_array, MAX_PERIO_FIFOS)) { int i; for(i=0; i<MAX_PERIO_FIFOS; i++) dwc_otg_module_params.dev_tx_fifo_size[i] = prop_array[i]; } if(!of_property_read_u32_array(ofdev->dev.of_node, "dev-tx-fifo-size", prop_array, MAX_TX_FIFOS)) { int i; for(i=0; i<MAX_TX_FIFOS; i++) dwc_otg_module_params.dev_perio_tx_fifo_size[i] = prop_array[i]; } #endif usb_nop_xceiv_register(); dwc_dev->core_if->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (!dwc_dev->core_if->xceiv) { retval = -ENODEV; goto fail_xceiv; } dwc_set_feature(dwc_dev->core_if); /* Initialize the DWC_otg core. */ dwc_otg_core_init(dwc_dev->core_if); /* * Disable the global interrupt until all the interrupt * handlers are installed. */ spin_lock(&dwc_dev->lock); dwc_otg_disable_global_interrupts(dwc_dev->core_if); spin_unlock(&dwc_dev->lock); /* * Install the interrupt handler for the common interrupts before * enabling common interrupts in core_init below. */ retval = request_irq(dwc_dev->irq, dwc_otg_common_irq, IRQF_SHARED, "dwc_otg", dwc_dev); if (retval) { dev_err(dev, "request of irq%d failed retval: %d\n", dwc_dev->irq, retval); retval = -EBUSY; goto fail_req_irq; } else { dwc_dev->common_irq_installed = 1; } if (!dwc_has_feature(dwc_dev->core_if, DWC_HOST_ONLY)) { //if (dwc_has_feature(dwc_dev->core_if, DWC_DEVICE_ONLY)) { /* Initialize the PCD */ retval = dwc_otg_pcd_init(dev); if (retval) { dev_err(dev, "dwc_otg_pcd_init failed\n"); dwc_dev->pcd = NULL; goto fail_req_irq; } } gusbcfg_addr = (ulong) (dwc_dev->core_if->core_global_regs) + DWC_GUSBCFG; if (!dwc_has_feature(dwc_dev->core_if, DWC_DEVICE_ONLY)) { //if (dwc_has_feature(dwc_dev->core_if, DWC_HOST_ONLY)) { /* Initialize the HCD and force_host_mode */ usbcfg = dwc_reg_read(gusbcfg_addr, 0); usbcfg |= DWC_USBCFG_FRC_HST_MODE; dwc_reg_write(gusbcfg_addr, 0, usbcfg); retval = dwc_otg_hcd_init(dev, dwc_dev); if (retval) { dev_err(dev, "dwc_otg_hcd_init failed\n"); dwc_dev->hcd = NULL; goto fail_hcd; } /* configure chargepump interrupt */ dwc_dev->hcd->cp_irq = platform_get_irq_byname(ofdev, "chargepumpirq"); if(dwc_dev->hcd->cp_irq != -ENXIO) { retval = request_irq(dwc_dev->hcd->cp_irq, dwc_otg_externalchgpump_irq, IRQF_SHARED, "dwc_otg_ext_chg_pump", dwc_dev); if (retval) { dev_err(dev, "request of irq failed retval: %d\n", retval); retval = -EBUSY; goto fail_hcd; } else { dev_dbg(dev, "%s: ExtChgPump Detection " "IRQ registered\n", dwc_driver_name); } } } /* * Enable the global interrupt after all the interrupt * handlers are installed. */ dwc_otg_enable_global_interrupts(dwc_dev->core_if); #if 0 usbcfg = dwc_reg_read(gusbcfg_addr, 0); usbcfg &= ~DWC_USBCFG_FRC_HST_MODE; dwc_reg_write(gusbcfg_addr, 0, usbcfg); #endif return 0; fail_hcd: free_irq(dwc_dev->irq, dwc_dev); if (!dwc_has_feature(dwc_dev->core_if, DWC_HOST_ONLY)) { if (dwc_dev->pcd) dwc_otg_pcd_remove(dev); } fail_req_irq: usb_put_phy(dwc_dev->core_if->xceiv); fail_xceiv: usb_nop_xceiv_unregister(); fail_check_param: dwc_otg_cil_remove(dwc_dev->core_if); fail_cil_init: dev_set_drvdata(dev, NULL); iounmap(dwc_dev->base); fail_ioremap: release_mem_region(dwc_dev->phys_addr, dwc_dev->base_len); fail_of_irq: kfree(dwc_dev); fail_dwc_dev: return retval; }