From: yangkai Date: Mon, 27 Dec 2010 08:46:37 +0000 (+0800) Subject: add sysfs switch for usbhost X-Git-Tag: firefly_0821_release~10881 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=557a35c81fa98d6a64bd829c9eedb3d684415227;p=firefly-linux-kernel-4.4.55.git add sysfs switch for usbhost --- diff --git a/drivers/usb/dwc_otg/Kconfig b/drivers/usb/dwc_otg/Kconfig index 24267cd81b1a..004b92d016aa 100755 --- a/drivers/usb/dwc_otg/Kconfig +++ b/drivers/usb/dwc_otg/Kconfig @@ -5,6 +5,11 @@ config USB11_HOST This driver supports Rockchip USB 1.1 HOST controller. +config USB11_HOST_EN + bool "---usb1.1 host controller enable" + depends on USB11_HOST + default y + config USB20_HOST tristate "Rockchip USB 2.0 host controller" depends on USB @@ -12,6 +17,11 @@ config USB20_HOST This driver supports Rockchip USB2.0 host controller. +config USB20_HOST_EN + bool "---usb2.0 host controller enable" + depends on USB20_HOST + default y + config USB20_OTG tristate "RockChip USB 2.0 OTG controller" depends on USB||USB_GADGET @@ -43,14 +53,19 @@ config DWC_OTG_DEVICE_ONLY endchoice config DWC_CONN_EN - bool "connect to PC when vbus detect" - default y + bool "---connect to PC when vbus detect" depends on DWC_OTG_DEVICE_ONLY + default y help USB2.0 OTG controller always polling the USB vbus if selected, device will connect to PC automatic +config USB20_OTG_EN + bool "---usb2.0 otg host controller enable" + depends on DWC_OTG_HOST_ONLY + default y + config DWC_OTG_DEBUG bool "DWC_OTG debug messages" depends on USB11_HOST || USB20_HOST || USB20_OTG diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.c b/drivers/usb/dwc_otg/dwc_otg_attr.c index 9fb2024a5888..710c9ca9e27b 100755 --- a/drivers/usb/dwc_otg/dwc_otg_attr.c +++ b/drivers/usb/dwc_otg/dwc_otg_attr.c @@ -735,7 +735,7 @@ static ssize_t wr_reg_test_show( struct device *_dev, } DEVICE_ATTR(wr_reg_test, S_IRUGO|S_IWUSR, wr_reg_test_show, 0); -extern int dwc_debug(int flag); +extern int dwc_debug(dwc_otg_core_if_t *core_if, int flag); static ssize_t debug_show( struct device *_dev, struct device_attribute *attr, char *buf) { @@ -753,11 +753,15 @@ static ssize_t debug_store( struct device *_dev, const char *buf, size_t count ) { uint32_t val = simple_strtoul(buf, NULL, 16); - dwc_debug(val); + dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_dump_global_registers( otg_dev->core_if); + dwc_debug(otg_dev->core_if,val); return count; } DEVICE_ATTR(debug, S_IRUGO|S_IWUSR, debug_show, debug_store); + + /**@}*/ /** diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c index 853777fea799..387d1e4c7126 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil.c @@ -65,6 +65,7 @@ #include "dwc_otg_regs.h" #include "dwc_otg_driver.h" #include "dwc_otg_cil.h" +#include "dwc_otg_pcd.h" static dwc_otg_core_if_t * dwc_core_if = NULL; /** * This function is called to initialize the DWC_otg CSR data @@ -3335,9 +3336,11 @@ void dwc_otg_dump_flags(dwc_otg_core_if_t *_core_if) DWC_PRINT("core_if->usb_mode = %x\n",_core_if->usb_mode); DWC_PRINT("core_if->usb_wakeup = %x\n",_core_if->usb_wakeup); } -int dwc_debug(int flag) +int dwc_debug(dwc_otg_core_if_t *core_if, int flag) { - dwc_otg_core_if_t *core_if = dwc_core_if; + //dwc_otg_core_if_t *core_if = dwc_core_if; + struct dwc_otg_device *otg_dev; + dwc_otg_pcd_t * pcd; switch(flag) { case 1: @@ -3345,8 +3348,9 @@ int dwc_debug(int flag) dwc_otg_dump_host_registers(core_if); break; case 2: - dwc_otg_dump_global_registers(core_if); - dwc_otg_dump_dev_registers(core_if); + otg_dev = core_if->otg_dev; + pcd = otg_dev->pcd; + pcd->vbus_status = 0; break; case 3: dump_scu_regs(); diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.h b/drivers/usb/dwc_otg/dwc_otg_cil.h index 9027ff2b6658..003c689cfbc4 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.h +++ b/drivers/usb/dwc_otg/dwc_otg_cil.h @@ -922,5 +922,5 @@ extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if, extern void dwc_otg_cil_register_hcd_callbacks( dwc_otg_core_if_t *_core_if, dwc_otg_cil_callbacks_t *_cb, void *_p); -extern int dwc_debug(int flag); +extern int dwc_debug(dwc_otg_core_if_t *core_if, int flag); #endif diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c index ebbb9da51bd5..0f53243432e0 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.c +++ b/drivers/usb/dwc_otg/dwc_otg_driver.c @@ -331,17 +331,66 @@ static ssize_t dbg_level_store(struct device_driver *_drv, const char *_buf, } static DRIVER_ATTR(debuglevel, S_IRUGO|S_IWUSR, dbg_level_show, dbg_level_store); -#ifdef CONFIG_DWC_OTG_DEVICE_ONLY +static ssize_t dwc_otg_enable_show( struct device *_dev, + struct device_attribute *attr, char *buf) +{ + dwc_otg_device_t *otg_dev = _dev->platform_data; + return sprintf (buf, "%d\n", otg_dev->hcd->host_enabled); +} + +static ssize_t dwc_otg_enable_store( struct device *_dev, + struct device_attribute *attr, + const char *buf, size_t count ) +{ + dwc_otg_device_t *otg_dev = _dev->platform_data; + dwc_otg_core_if_t *_core_if = otg_dev->core_if; + struct platform_device *pdev = to_platform_device(_dev); + uint32_t val = simple_strtoul(buf, NULL, 16); + if(otg_dev->hcd->host_enabled == val) + return count; + + otg_dev->hcd->host_enabled = val; + if(val == 0) // enable -> disable + { + DWC_PRINT("disable host controller:%s\n",pdev->name); + #if 1 + if (_core_if->hcd_cb && _core_if->hcd_cb->disconnect) { + _core_if->hcd_cb->disconnect( _core_if->hcd_cb->p ); + } + #endif + if (_core_if->hcd_cb && _core_if->hcd_cb->stop) { + _core_if->hcd_cb->stop( _core_if->hcd_cb->p ); + } + clk_disable(otg_dev->phyclk); + clk_disable(otg_dev->ahbclk); + } + else if(val == 1) + { + DWC_PRINT("enable host controller:%s\n",pdev->name); + clk_enable(otg_dev->phyclk); + clk_enable(otg_dev->ahbclk); + if (_core_if->hcd_cb && _core_if->hcd_cb->start) { + _core_if->hcd_cb->start( _core_if->hcd_cb->p ); + } + } + + return count; +} +static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, dwc_otg_enable_show, dwc_otg_enable_store); + static ssize_t dwc_otg_conn_en_show(struct device_driver *_drv, char *_buf) { +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY dwc_otg_device_t *otg_dev = g_otgdev; dwc_otg_pcd_t *_pcd = otg_dev->pcd; return sprintf (_buf, "%d\n", _pcd->conn_en); +#endif } static ssize_t dwc_otg_conn_en_store(struct device_driver *_drv, const char *_buf, size_t _count) { +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY int enable = simple_strtoul(_buf, NULL, 10); dwc_otg_device_t *otg_dev = g_otgdev; dwc_otg_pcd_t *_pcd = otg_dev->pcd; @@ -349,8 +398,10 @@ static ssize_t dwc_otg_conn_en_store(struct device_driver *_drv, const char *_bu _pcd->conn_en = enable; return _count; +#endif } static DRIVER_ATTR(dwc_otg_conn_en, S_IRUGO|S_IWUSR, dwc_otg_conn_en_show, dwc_otg_conn_en_store); +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY static ssize_t vbus_status_show(struct device_driver *_drv, char *_buf) { dwc_otg_device_t *otg_dev = g_otgdev; @@ -1004,6 +1055,9 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) * Create Device Attributes in sysfs */ dwc_otg_attr_create(dev); +#ifdef CONFIG_DWC_OTG_HOST_ONLY + retval |= device_create_file(dev, &dev_attr_enable); +#endif /* * Disable the global interrupt until all the interrupt @@ -1079,6 +1133,12 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) * handlers are installed. */ dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); +#ifdef CONFIG_DWC_OTG_HOST_ONLY +#ifndef CONFIG_USB20_OTG_EN + clk_disable(otg_dev->phyclk); + clk_disable(otg_dev->ahbclk); +#endif +#endif DWC_PRINT("dwc_otg_driver_probe end, everest\n"); return 0; fail: @@ -1379,6 +1439,7 @@ static __devinit int host11_driver_probe(struct platform_device *pdev) * Create Device Attributes in sysfs */ dwc_otg_attr_create(dev); + retval |= device_create_file(dev, &dev_attr_enable); /* * Disable the global interrupt until all the interrupt @@ -1425,6 +1486,10 @@ static __devinit int host11_driver_probe(struct platform_device *pdev) * handlers are installed. */ dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); +#ifndef CONFIG_USB11_HOST_EN + clk_disable(phyclk); + clk_disable(ahbclk); +#endif DWC_PRINT("host11_driver_probe end, everest\n"); return 0; @@ -1665,6 +1730,7 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) * Create Device Attributes in sysfs */ dwc_otg_attr_create(dev); + retval |= device_create_file(dev, &dev_attr_enable); /* * Disable the global interrupt until all the interrupt @@ -1712,6 +1778,10 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) * handlers are installed. */ dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); +#ifndef CONFIG_USB20_HOST_EN + clk_disable(phyclk); + clk_disable(ahbclk); +#endif DWC_PRINT("host20_driver_probe end, everest\n"); return 0; diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c index 021b62b297d6..ff0453726a58 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c @@ -62,7 +62,6 @@ static int dwc_otg_hcd_suspend(struct usb_hcd *hcd) dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; hprt0_data_t hprt0; pcgcctl_data_t pcgcctl; - //dwc_debug(1); if(core_if->op_state == B_PERIPHERAL) { @@ -129,8 +128,6 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd) dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32); udelay(2); #endif - //dwc_debug(3); - //dwc_debug(1); gintmsk.d32 = dwc_read_reg32(&core_if->core_global_regs->gintmsk); gintmsk.b.portintr = 0; dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32); @@ -386,7 +383,7 @@ static void kill_urbs_in_qh_list(dwc_otg_hcd_t *_hcd, struct list_head *_qh_list } } } - +#if 0 /** * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic * and periodic schedules. The QTD associated with each URB is removed from @@ -402,7 +399,7 @@ static void kill_all_urbs(dwc_otg_hcd_t *_hcd) kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_assigned); kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_queued); } - +#endif /** * HCD Callback function for disconnect of the HCD. * @@ -453,7 +450,8 @@ static int32_t dwc_otg_hcd_disconnect_cb( void *_p ) } /* Respond with an error status to all URBs in the schedule. */ - kill_all_urbs(dwc_otg_hcd); + // yk@20101227 handle kernel panic bug when disconnect + //kill_all_urbs(dwc_otg_hcd); if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) { /* Clean up any host channels that were in use. */ @@ -638,6 +636,12 @@ int __devinit dwc_otg_hcd_init(struct device *dev) dwc_otg_hcd->core_if = otg_dev->core_if; otg_dev->hcd = dwc_otg_hcd; + +#ifdef CONFIG_USB20_OTG_EN + dwc_otg_hcd->host_enabled = 1; +#else + dwc_otg_hcd->host_enabled = 0; +#endif /* Register the HCD CIL Callbacks */ dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if, @@ -714,7 +718,7 @@ int __devinit dwc_otg_hcd_init(struct device *dev) DWC_ERROR("%s: status_buf allocation failed\n", __func__); goto error3; } - + DWC_PRINT("%s end,everest\n",__func__); // DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n", // dev->bus_id, hcd->self.busnum); @@ -795,6 +799,12 @@ int __devinit host11_hcd_init(struct device *dev) dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); dwc_otg_hcd->core_if = otg_dev->core_if; otg_dev->hcd = dwc_otg_hcd; + +#ifdef CONFIG_USB11_HOST_EN + dwc_otg_hcd->host_enabled = 1; +#else + dwc_otg_hcd->host_enabled = 0; +#endif spin_lock_init(&dwc_otg_hcd->global_lock); @@ -955,6 +965,12 @@ int __devinit host20_hcd_init(struct device *dev) dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); dwc_otg_hcd->core_if = otg_dev->core_if; otg_dev->hcd = dwc_otg_hcd; + +#ifdef CONFIG_USB20_HOST_EN + dwc_otg_hcd->host_enabled = 1; +#else + dwc_otg_hcd->host_enabled = 0; +#endif spin_lock_init(&dwc_otg_hcd->global_lock); @@ -1034,10 +1050,8 @@ int __devinit host20_hcd_init(struct device *dev) DWC_ERROR("%s: status_buf allocation failed\n", __func__); goto error3; } - + DWC_PRINT("%s end,everest\n",__func__); -// DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n", -// dev->bus_id, hcd->self.busnum); return 0; @@ -1164,7 +1178,7 @@ int dwc_otg_hcd_start(struct usb_hcd *_hcd) } /* Initialize the bus state. If the core is in Device Mode * HALT the USB bus and return. */ - if (dwc_otg_is_device_mode (core_if)) { + if (!dwc_otg_hcd->host_enabled || dwc_otg_is_device_mode (core_if)) { DWC_PRINT("dwc_otg_hcd_start controller in device mode,everest\n"); //_hcd->state = HC_STATE_HALT; goto out; @@ -1467,6 +1481,7 @@ int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, struct urb *_urb, int _status) if(urb_qtd == NULL) { DWC_PRINT("%s,urb_qtd is null\n",__func__); + goto urb_qtd_null; //return -1; } dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd); @@ -1510,6 +1525,8 @@ int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, struct urb *_urb, int _status) dwc_otg_hcd_qh_remove(dwc_otg_hcd, qh); } #endif + +urb_qtd_null: spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); _urb->hcpriv = NULL; usb_hcd_unlink_urb_from_ep(_hcd, _urb); diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.h b/drivers/usb/dwc_otg/dwc_otg_hcd.h index 18ddb3ea1923..262f2289dd05 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.h +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.h @@ -382,6 +382,9 @@ typedef struct dwc_otg_hcd { uint64_t hfnum_other_frrem_accum_b; #endif + /** Flag to indicate whether host controller is enabled. */ + uint8_t host_enabled; + } dwc_otg_hcd_t; /** Gets the dwc_otg_hcd from a struct usb_hcd */ diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c index 150ec592d975..74a41c9566b4 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c @@ -1764,7 +1764,6 @@ static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *_hcd, handle_hc_ack_intr(_hcd, _hc, _hc_regs, _qtd); } else if(hcint.b.datatglerr){ DWC_PRINT("%s, DATA toggle error, Channel %d\n",__func__, _hc->hc_num); - dwc_debug(1); clear_hc_int(_hc_regs,chhltd); } else { if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||