/*Internal function of isr */ static void process_port_intr(struct usb_hcd *hcd) { hprt_t hprt; /* by ss1, clear_hprt; */ struct sec_otghost *otghost = hcd_to_sec_otghost(hcd); hprt.d32 = read_reg_32(HPRT); otg_dbg(OTG_DBG_ISR, "Port Interrupt() : HPRT = 0x%x\n", hprt.d32); if (hprt.b.prtconndet) { otg_dbg(true, "detect connection"); otghost->port_flag.b.port_connect_status_change = 1; if (hprt.b.prtconnsts) otghost->port_flag.b.port_connect_status = 1; /* wake_lock(&otghost->wake_lock); */ } if (hprt.b.prtenchng) { otg_dbg(true, "port enable/disable changed\n"); otghost->port_flag.b.port_enable_change = 1; // kevinh - it seems the hw implicitly disables the interface on unplug, so mark that we are unplugged if(!hprt.b.prtconnsts) { otghost->port_flag.b.port_connect_status_change = 1; otghost->port_flag.b.port_connect_status = 0; } } if (hprt.b.prtovrcurrchng) { otg_dbg(true, "over current condition is changed\n"); if (hprt.b.prtovrcurract) { otg_dbg(true, "port_over_current_change = 1\n"); otghost->port_flag.b.port_over_current_change = 1; } else { otghost->port_flag.b.port_over_current_change = 0; } /* defer otg power control into a kernel thread */ queue_work(otghost->wq, &otghost->work); } hprt.b.prtena = 0; /* prtena를 writeclear시키면 안됨. */ /* hprt.b.prtpwr = 0; */ hprt.b.prtrst = 0; hprt.b.prtconnsts = 0; write_reg_32(HPRT, hprt.d32); }
static int s5pc110_stop_otg(void) { struct sec_otghost *otghost = NULL; struct sec_otghost_data *otgdata = NULL; pr_info("+++++ OTG STOP\n"); otg_dbg(OTG_DBG_OTGHCDI_DRIVER, "s5pc110_stop_otg\n"); otghost = hcd_to_sec_otghost(g_pUsbHcd); #ifdef CONFIG_USB_HOST_NOTIFY host_notify_dev_unregister(&g_pUsbHcd->ndev); #endif otg_hcd_deinit_modules(otghost); destroy_workqueue(otghost->wq); wake_unlock(&otghost->wake_lock); wake_lock_destroy(&otghost->wake_lock); usb_remove_hcd(g_pUsbHcd); #if 1 if (g_pUDCBase == S3C_VA_HSOTG) { pr_info("otg release_mem_region\n"); release_mem_region(g_pUsbHcd->rsrc_start, g_pUsbHcd->rsrc_len); } #endif usb_put_hcd(g_pUsbHcd); otgdata = otghost->otg_data; if (otgdata && otgdata->phy_exit && otgdata->pdev) { pr_info("otg phy_off\n"); otgdata->phy_exit(0); } return 0; }
* * @brief Main interrupt processing routine * * @param None * * @return None * * @remark * */ static inline void otg_handle_interrupt(struct usb_hcd *hcd) { gintsts_t clearIntr = {.d32 = 0}; gintsts_t gintsts = {.d32 = 0}; struct sec_otghost *otghost = hcd_to_sec_otghost(hcd); gintsts.d32 = read_reg_32(GINTSTS) & read_reg_32(GINTMSK); otg_dbg(OTG_DBG_ISR, "otg_handle_interrupt - GINTSTS=0x%8x\n", gintsts.d32); if (gintsts.b.wkupintr) { otg_dbg(true, "Wakeup Interrupt\n"); clearIntr.b.wkupintr = 1; } if (gintsts.b.disconnect) { otg_dbg(true, "Disconnect Interrupt\n"); otghost->port_flag.b.port_connect_status_change = 1; otghost->port_flag.b.port_connect_status = 0;
static int s5pc110_start_otg(u32 regs) { int ret_val = 0; u32 reg_val = 0; struct platform_device *pdev = g_pdev; struct sec_otghost *otghost = NULL; struct sec_otghost_data *otg_data = dev_get_platdata(&pdev->dev); otg_dbg(OTG_DBG_OTGHCDI_DRIVER, "s3c_otg_drv_probe\n"); pr_info("otg probe start : 0x%x\n", regs); /*init for host mode*/ /** Allocate memory for the base HCD & Initialize the base HCD. */ g_pUsbHcd = usb_create_hcd(&s5pc110_otg_hc_driver, &pdev->dev, "s3cotg");/*pdev->dev.bus_id*/ if (g_pUsbHcd == NULL) { ret_val = -ENOMEM; otg_err(OTG_DBG_OTGHCDI_DRIVER, "failed to usb_create_hcd\n"); goto err_out_clk; } #if 1 pr_info("otg probe regs : 0x%p\n", otg_data->regs); if (!regs) { pr_info("otg mapping hcd resource\n"); /* mapping hcd resource & device resource*/ g_pUsbHcd->rsrc_start = pdev->resource[0].start; g_pUsbHcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; if (!request_mem_region(g_pUsbHcd->rsrc_start, g_pUsbHcd->rsrc_len, gHcdName)) { otg_err(OTG_DBG_OTGHCDI_DRIVER, "failed to request_mem_region\n"); ret_val = -EBUSY; goto err_out_create_hcd; } pr_info("otg rsrc_start %llu, ren %llu\n", g_pUsbHcd->rsrc_start, g_pUsbHcd->rsrc_len); pr_info("otg regs : %p\n", S3C_VA_HSOTG); /* Physical address => Virtual address */ g_pUsbHcd->regs = S3C_VA_HSOTG; g_pUDCBase = (u8 *)g_pUsbHcd->regs; } else g_pUDCBase = (u8 *)regs; #endif pr_info("otg g_pUDCBase 0x%p\n", g_pUDCBase); g_pUsbHcd->self.otg_port = 1; otghost = hcd_to_sec_otghost(g_pUsbHcd); if (otghost == NULL) { otg_err(true, "failed to get otghost hcd\n"); ret_val = USB_ERR_FAIL; goto err_out_create_hcd; } otghost->otg_data = otg_data; INIT_WORK(&otghost->work, otg_power_work); otghost->wq = create_singlethread_workqueue("sec_otghostd"); /* call others' init() */ ret_val = otg_hcd_init_modules(otghost); if (ret_val != USB_ERR_SUCCESS) { otg_err(OTG_DBG_OTGHCDI_DRIVER, "failed to otg_hcd_init_modules\n"); ret_val = USB_ERR_FAIL; goto err_out_create_hcd; } /** * Attempt to ensure this device is really a s5pc110 USB-OTG Controller. * Read and verify the SNPSID register contents. The value should be * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX". */ reg_val = read_reg_32(0x40); pr_info("otg reg 0x40 = %x\n", reg_val); if ((reg_val & 0xFFFFF000) != 0x4F542000) { otg_err(OTG_DBG_OTGHCDI_DRIVER, "Bad value for SNPSID: 0x%x\n", reg_val); ret_val = -EINVAL; goto err_out_create_hcd_init; } #ifdef CONFIG_USB_HOST_NOTIFY if (otg_data->host_notify) { g_pUsbHcd->host_notify = otg_data->host_notify; g_pUsbHcd->ndev.name = dev_name(&pdev->dev); ret_val = host_notify_dev_register(&g_pUsbHcd->ndev); if (ret_val) { otg_err(OTG_DBG_OTGHCDI_DRIVER, "Failed to host_notify_dev_register\n"); goto err_out_create_hcd_init; } } #endif #ifdef CONFIG_USB_SEC_WHITELIST if (otg_data->sec_whlist_table_num) g_pUsbHcd->sec_whlist_table_num = otg_data->sec_whlist_table_num; #endif /* * Finish generic HCD initialization and start the HCD. This function * allocates the DMA buffer pool, registers the USB bus, requests the * IRQ line, and calls s5pc110_otghcd_start method. */ ret_val = usb_add_hcd(g_pUsbHcd, pdev->resource[1].start, IRQF_DISABLED); if (ret_val < 0) { otg_err(OTG_DBG_OTGHCDI_DRIVER, "Failed to add hcd driver\n"); goto err_out_host_notify_register; } otg_dbg(OTG_DBG_OTGHCDI_DRIVER, "OTG HCD Initialized HCD, bus=%s, usbbus=%d\n", "C110 OTG Controller", g_pUsbHcd->self.busnum); /* otg_print_registers(); */ wake_lock_init(&otghost->wake_lock, WAKE_LOCK_SUSPEND, "usb_otg"); wake_lock(&otghost->wake_lock); return USB_ERR_SUCCESS; err_out_host_notify_register: #ifdef CONFIG_USB_HOST_NOTIFY host_notify_dev_unregister(&g_pUsbHcd->ndev); #endif err_out_create_hcd_init: otg_hcd_deinit_modules(otghost); if (!regs) release_mem_region(g_pUsbHcd->rsrc_start, g_pUsbHcd->rsrc_len); err_out_create_hcd: usb_put_hcd(g_pUsbHcd); err_out_clk: return ret_val; }