From: yangkai Date: Sat, 26 Jun 2010 07:50:02 +0000 (+0800) Subject: usb host 1.1 support X-Git-Tag: firefly_0821_release~11378 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=cbeb27b8fe2f2168f2403e37d608cdb49322b610;p=firefly-linux-kernel-4.4.55.git usb host 1.1 support --- diff --git a/arch/arm/mach-rk2818/board-midsdk.c b/arch/arm/mach-rk2818/board-midsdk.c index 534858f6a28c..af1554f20631 100644 --- a/arch/arm/mach-rk2818/board-midsdk.c +++ b/arch/arm/mach-rk2818/board-midsdk.c @@ -432,6 +432,9 @@ static struct platform_device *devices[] __initdata = { #ifdef CONFIG_DWC_OTG &rk2818_device_dwc_otg, #endif +#ifdef CONFIG_RK2818_HOST11 + &rk2818_device_host11, +#endif #ifdef CONFIG_USB_ANDROID &android_usb_device, &usb_mass_storage_device, diff --git a/arch/arm/mach-rk2818/devices.c b/arch/arm/mach-rk2818/devices.c index d6436ae6c729..7f37dea89b7a 100644 --- a/arch/arm/mach-rk2818/devices.c +++ b/arch/arm/mach-rk2818/devices.c @@ -444,6 +444,7 @@ struct platform_device rk2818_nand_device = { }; +#endif /*DWC_OTG*/ static struct resource dwc_otg_resource[] = { { @@ -465,7 +466,28 @@ struct platform_device rk2818_device_dwc_otg = { .num_resources = ARRAY_SIZE(dwc_otg_resource), .resource = dwc_otg_resource, }; +#ifdef CONFIG_RK2818_HOST11 +static struct resource rk2818_host11_resource[] = { + { + .start = IRQ_NR_USB_HOST, + .end = IRQ_NR_USB_HOST, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK2818_USBHOST_PHYS, + .end = RK2818_USBHOST_PHYS + RK2818_USBHOST_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device rk2818_device_host11 = { + .name = "rk2818_host11", + .id = -1, + .num_resources = ARRAY_SIZE(rk2818_host11_resource), + .resource = rk2818_host11_resource, +}; +#endif static char *usb_functions_rockchip[] = { "usb_mass_storage", }; @@ -577,5 +599,4 @@ struct platform_device usb_mass_storage_device = { }, }; -#endif diff --git a/arch/arm/mach-rk2818/devices.h b/arch/arm/mach-rk2818/devices.h index 1e624adeeb26..5575a9044668 100644 --- a/arch/arm/mach-rk2818/devices.h +++ b/arch/arm/mach-rk2818/devices.h @@ -42,6 +42,7 @@ extern struct platform_device rk2818_device_backlight; extern struct platform_device rk2818_device_dsp; extern struct platform_device rk2818_nand_device; extern struct platform_device rk2818_device_dwc_otg; +extern struct platform_device rk2818_device_host11; extern struct platform_device android_usb_device; extern struct platform_device usb_mass_storage_device; diff --git a/arch/arm/mach-rk2818/include/mach/rk2818_iomap.h b/arch/arm/mach-rk2818/include/mach/rk2818_iomap.h index d8ad78b3a563..2740fcc879d6 100644 --- a/arch/arm/mach-rk2818/include/mach/rk2818_iomap.h +++ b/arch/arm/mach-rk2818/include/mach/rk2818_iomap.h @@ -107,7 +107,7 @@ #define RK2818_ESRAM_PHYS 0x100BA000 #define RK2818_ESRAM_SIZE SZ_8K -#define RK2818_USBHOST_PHYS 0x1010000 +#define RK2818_USBHOST_PHYS 0x10100000 #define RK2818_USBHOST_SIZE SZ_256K #define RK2818_UART0_BASE 0xFF100000 diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 34de475f016e..7b393ef73792 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1756,6 +1756,7 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) dev_dbg(&rhdev->dev, "bus %s%s\n", (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "suspend"); if (!hcd->driver->bus_suspend) { + printk("%s,error,everest\n",__func__); status = -ENOENT; } else { hcd->state = HC_STATE_QUIESCING; diff --git a/drivers/usb/dwc_otg/Kconfig b/drivers/usb/dwc_otg/Kconfig index f14014cb31cb..6f70c019c3da 100755 --- a/drivers/usb/dwc_otg/Kconfig +++ b/drivers/usb/dwc_otg/Kconfig @@ -1,5 +1,11 @@ +config RK2818_HOST11 + tristate "RockChip USB Host 1.1 support" + ---help--- + This driver supports Rockchip USB HOST 1.1 + controller in RK281X. + config DWC_OTG - tristate "RockChip DWC_OTG support" + tristate "RockChip USB OTG 2.0 support" ---help--- This driver supports Rockchip DWC_OTG diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.c b/drivers/usb/dwc_otg/dwc_otg_attr.c index 76349b51f0c8..17fa55c7ba7f 100755 --- a/drivers/usb/dwc_otg/dwc_otg_attr.c +++ b/drivers/usb/dwc_otg/dwc_otg_attr.c @@ -270,7 +270,7 @@ #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \ static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \ { \ - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\ + dwc_otg_device_t *otg_dev = _dev->platform_data;\ uint32_t val; \ val = dwc_read_reg32 (_addr_); \ val = (val & (_mask_)) >> _shift_; \ @@ -279,7 +279,7 @@ static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \ #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \ static ssize_t _otg_attr_name_##_store (struct device *_dev, const char *buf, size_t count) \ { \ - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\ + dwc_otg_device_t *otg_dev = _dev->platform_data;\ uint32_t set = simple_strtoul(buf, NULL, 16); \ uint32_t clear = set; \ clear = ((~clear) << _shift_) & _mask_; \ @@ -304,7 +304,7 @@ DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL); #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \ static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \ { \ - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\ + dwc_otg_device_t *otg_dev = _dev->platform_data;\ uint32_t val; \ val = dwc_read_reg32 (_addr_); \ return sprintf (buf, "%s = 0x%08x\n", _string_, val); \ @@ -312,7 +312,7 @@ static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \ #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \ static ssize_t _otg_attr_name_##_store (struct device *_dev, const char *buf, size_t count) \ { \ - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\ + dwc_otg_device_t *otg_dev = _dev->platform_data;\ uint32_t val = simple_strtoul(buf, NULL, 16); \ dev_dbg(_dev, "Storing Address=0x%08x Val=0x%08x\n", (uint32_t)_addr_, val); \ dwc_write_reg32(_addr_, val); \ @@ -337,7 +337,7 @@ DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL); */ static ssize_t regoffset_show( struct device *_dev, char *buf) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset); } @@ -347,7 +347,7 @@ static ssize_t regoffset_show( struct device *_dev, char *buf) static ssize_t regoffset_store( struct device *_dev, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t offset = simple_strtoul(buf, NULL, 16); //dev_dbg(_dev, "Offset=0x%08x\n", offset); if (offset < SZ_256K ) { @@ -368,7 +368,7 @@ DEVICE_ATTR(regoffset, S_IRUGO|S_IWUSR, regoffset_show, regoffset_store); */ static ssize_t regvalue_show( struct device *_dev, char *buf) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t val; volatile uint32_t *addr; @@ -398,7 +398,7 @@ static ssize_t regvalue_show( struct device *_dev, char *buf) static ssize_t regvalue_store( struct device *_dev, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; volatile uint32_t * addr; uint32_t val = simple_strtoul(buf, NULL, 16); //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val); @@ -451,7 +451,7 @@ DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0,otg_dev->core_if->host_if->hprt0,"HPRT0"); */ static ssize_t hnp_show( struct device *_dev, char *buf) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; gotgctl_data_t val; val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl)); return sprintf (buf, "HstNegScs = 0x%x\n", val.b.hstnegscs); @@ -463,7 +463,7 @@ static ssize_t hnp_show( struct device *_dev, char *buf) static ssize_t hnp_store( struct device *_dev, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t in = simple_strtoul(buf, NULL, 16); uint32_t *addr = (uint32_t *)&(otg_dev->core_if->core_global_regs->gotgctl); gotgctl_data_t mem; @@ -484,7 +484,7 @@ DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store); static ssize_t srp_show( struct device *_dev, char *buf) { #ifndef DWC_HOST_ONLY - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; gotgctl_data_t val; val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl)); return sprintf (buf, "SesReqScs = 0x%x\n", val.b.sesreqscs); @@ -502,7 +502,7 @@ static ssize_t srp_store( struct device *_dev, const char *buf, size_t count ) { #ifndef DWC_HOST_ONLY - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; dwc_otg_pcd_initiate_srp(otg_dev->pcd); #endif return count; @@ -517,7 +517,7 @@ DEVICE_ATTR(srp, 0644, srp_show, srp_store); */ static ssize_t buspower_show( struct device *_dev, char *buf) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; hprt0_data_t val; val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0); return sprintf (buf, "Bus Power = 0x%x\n", val.b.prtpwr); @@ -530,7 +530,7 @@ static ssize_t buspower_show( struct device *_dev, char *buf) static ssize_t buspower_store( struct device *_dev, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t on = simple_strtoul(buf, NULL, 16); uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0; hprt0_data_t mem; @@ -553,7 +553,7 @@ DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store); */ static ssize_t bussuspend_show( struct device *_dev, char *buf) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; hprt0_data_t val; val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0); return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp); @@ -565,7 +565,7 @@ static ssize_t bussuspend_show( struct device *_dev, char *buf) static ssize_t bussuspend_store( struct device *_dev, const char *buf, size_t count ) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t in = simple_strtoul(buf, NULL, 16); uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0; hprt0_data_t mem; @@ -583,7 +583,7 @@ DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store); static ssize_t remote_wakeup_show( struct device *_dev, char *buf) { #ifndef DWC_HOST_ONLY - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; dctl_data_t val; val.d32 = dwc_read_reg32( &otg_dev->core_if->dev_if->dev_global_regs->dctl); @@ -604,7 +604,7 @@ static ssize_t remote_wakeup_store( struct device *_dev, const char *buf, { #ifndef DWC_HOST_ONLY uint32_t val = simple_strtoul(buf, NULL, 16); - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; if (val&1) { dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1); } @@ -623,8 +623,7 @@ DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show, */ static ssize_t regdump_show( struct device *_dev, char *buf) { - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); - + dwc_otg_device_t *otg_dev = _dev->platform_data; dwc_otg_dump_global_registers( otg_dev->core_if); if (dwc_otg_is_host_mode(otg_dev->core_if)) { dwc_otg_dump_host_registers( otg_dev->core_if); @@ -642,7 +641,7 @@ DEVICE_ATTR(regdump, S_IRUGO|S_IWUSR, regdump_show, 0); static ssize_t hcddump_show( struct device *_dev, char *buf) { #ifndef DWC_DEVICE_ONLY - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; dwc_otg_hcd_dump_state(otg_dev->hcd); #endif return sprintf( buf, "HCD Dump\n" ); @@ -658,7 +657,7 @@ DEVICE_ATTR(hcddump, S_IRUGO|S_IWUSR, hcddump_show, 0); static ssize_t hcd_frrem_show( struct device *_dev, char *buf) { #ifndef DWC_DEVICE_ONLY - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; dwc_otg_hcd_dump_frrem(otg_dev->hcd); #endif return sprintf( buf, "HCD Dump Frame Remaining\n" ); @@ -677,7 +676,7 @@ static ssize_t rd_reg_test_show( struct device *_dev, char *buf) int i; int time; int start_jiffies; - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", HZ, MSEC_PER_JIFFIE, loops_per_jiffy); @@ -701,7 +700,7 @@ static ssize_t wr_reg_test_show( struct device *_dev, char *buf) int i; int time; int start_jiffies; - dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); + dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t reg_val; printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c index 64a3ff3a5646..1893f6b36102 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.c +++ b/drivers/usb/dwc_otg/dwc_otg_driver.c @@ -77,7 +77,6 @@ static const char dwc_driver_name[] = "dwc_otg"; struct dwc_otg_device_t* g_otgdev = NULL; - /*-------------------------------------------------------------------------*/ /* Encapsulate the module parameter settings */ @@ -150,6 +149,79 @@ static dwc_otg_core_params_t dwc_otg_module_params = { .rx_thr_length = -1, }; +#ifdef CONFIG_RK2818_HOST11 + +struct dwc_otg_device_t* g_host11 = NULL; + +static dwc_otg_core_params_t rk28_host11_module_params = { + .opt = -1, + .otg_cap = -1, + .dma_enable = -1, + .dma_burst_size = -1, + .speed = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .enable_dynamic_fifo = -1, + .data_fifo_size = -1, + .dev_rx_fifo_size = -1, + .dev_nperio_tx_fifo_size = -1, + .dev_perio_tx_fifo_size = + { /* dev_perio_tx_fifo_size_1 */ + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + }, /* 15 */ + .host_rx_fifo_size = -1, + .host_nperio_tx_fifo_size = -1, + //.host_perio_tx_fifo_size = 512, + .host_perio_tx_fifo_size = -1, + .max_transfer_size = -1, + .max_packet_count = -1, + .host_channels = -1, + .dev_endpoints = -1, + .phy_type = -1, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .ts_dline = -1, + .en_multiple_tx_fifo = -1, + .dev_tx_fifo_size = + { /* dev_tx_fifo_size */ + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + }, /* 15 */ + .thr_ctl = -1, + .tx_thr_length = -1, + .rx_thr_length = -1, +}; +#endif /** * This function shows the Driver Version. */ @@ -458,21 +530,22 @@ static int check_parameters(dwc_otg_core_if_t *core_if) { int i; int retval = 0; - + dwc_otg_core_params_t *core_params; + core_params = core_if->core_params; /* Checks if the parameter is outside of its valid range of values */ #define DWC_OTG_PARAM_TEST(_param_,_low_,_high_) \ - ((dwc_otg_module_params._param_ < (_low_)) || \ - (dwc_otg_module_params._param_ > (_high_))) + ((core_params->_param_ < (_low_)) || \ + (core_params->_param_ > (_high_))) /* If the parameter has been set by the user, check that the parameter value is * within the value range of values. If not, report a module error. */ #define DWC_OTG_PARAM_ERR(_param_,_low_,_high_,_string_) \ do { \ - if (dwc_otg_module_params._param_ != -1) { \ + if (core_params->_param_ != -1) { \ if (DWC_OTG_PARAM_TEST(_param_,(_low_),(_high_))) { \ DWC_ERROR("`%d' invalid for parameter `%s'\n", \ - dwc_otg_module_params._param_, _string_); \ - dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \ + core_params->_param_, _string_); \ + core_params->_param_ = dwc_param_##_param_##_default; \ retval ++; \ } \ } \ @@ -502,7 +575,7 @@ static int check_parameters(dwc_otg_core_if_t *core_if) DWC_OTG_PARAM_ERR(ulpi_fs_ls,0,1,"ulpi_fs_ls"); DWC_OTG_PARAM_ERR(ts_dline,0,1,"ts_dline"); - if (dwc_otg_module_params.dma_burst_size != -1) + if (core_params->dma_burst_size != -1) { if (DWC_OTG_PARAM_TEST(dma_burst_size,1,1) && DWC_OTG_PARAM_TEST(dma_burst_size,4,4) && @@ -514,20 +587,20 @@ static int check_parameters(dwc_otg_core_if_t *core_if) DWC_OTG_PARAM_TEST(dma_burst_size,256,256)) { DWC_ERROR("`%d' invalid for parameter `dma_burst_size'\n", - dwc_otg_module_params.dma_burst_size); - dwc_otg_module_params.dma_burst_size = 32; + core_params->dma_burst_size); + core_params->dma_burst_size = 32; retval ++; } } - if (dwc_otg_module_params.phy_utmi_width != -1) + if (core_params->phy_utmi_width != -1) { if (DWC_OTG_PARAM_TEST(phy_utmi_width,8,8) && DWC_OTG_PARAM_TEST(phy_utmi_width,16,16)) { DWC_ERROR("`%d' invalid for parameter `phy_utmi_width'\n", - dwc_otg_module_params.phy_utmi_width); - dwc_otg_module_params.phy_utmi_width = 16; + core_params->phy_utmi_width); + core_params->phy_utmi_width = 16; retval ++; } } @@ -536,13 +609,13 @@ static int check_parameters(dwc_otg_core_if_t *core_if) { /** @todo should be like above */ //DWC_OTG_PARAM_ERR(dev_perio_tx_fifo_size[i],4,768,"dev_perio_tx_fifo_size"); - if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] != -1) + if (core_params->dev_perio_tx_fifo_size[i] != -1) { if (DWC_OTG_PARAM_TEST(dev_perio_tx_fifo_size[i],4,768)) { DWC_ERROR("`%d' invalid for parameter `%s_%d'\n", - dwc_otg_module_params.dev_perio_tx_fifo_size[i], "dev_perio_tx_fifo_size", i); - dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default; + core_params->dev_perio_tx_fifo_size[i], "dev_perio_tx_fifo_size", i); + core_params->dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default; retval ++; } } @@ -554,13 +627,13 @@ static int check_parameters(dwc_otg_core_if_t *core_if) { /** @todo should be like above */ //DWC_OTG_PARAM_ERR(dev_tx_fifo_size[i],4,768,"dev_tx_fifo_size"); - if (dwc_otg_module_params.dev_tx_fifo_size[i] != -1) + if (core_params->dev_tx_fifo_size[i] != -1) { if (DWC_OTG_PARAM_TEST(dev_tx_fifo_size[i],4,768)) { DWC_ERROR("`%d' invalid for parameter `%s_%d'\n", - dwc_otg_module_params.dev_tx_fifo_size[i], "dev_tx_fifo_size", i); - dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default; + core_params->dev_tx_fifo_size[i], "dev_tx_fifo_size", i); + core_params->dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default; retval ++; } } @@ -583,9 +656,9 @@ static int check_parameters(dwc_otg_core_if_t *core_if) #define DWC_OTG_PARAM_SET_DEFAULT(_param_) \ ({ \ int changed = 1; \ - if (dwc_otg_module_params._param_ == -1) { \ + if (core_params->_param_ == -1) { \ changed = 0; \ - dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \ + core_params->_param_ = dwc_param_##_param_##_default; \ } \ changed; \ }) @@ -600,10 +673,10 @@ static int check_parameters(dwc_otg_core_if_t *core_if) int error = 0; \ if (!(_is_valid_)) { \ if (changed) { \ - DWC_ERROR("`%d' invalid for parameter `%s'. Check HW configuration.\n", dwc_otg_module_params._param_,_str_); \ + DWC_ERROR("`%d' invalid for parameter `%s'. Check HW configuration.\n", core_params->_param_,_str_); \ error = 1; \ } \ - dwc_otg_module_params._param_ = (_set_valid_); \ + core_params->_param_ = (_set_valid_); \ } \ error; \ }) @@ -613,7 +686,7 @@ static int check_parameters(dwc_otg_core_if_t *core_if) ({ int valid; valid = 1; - switch (dwc_otg_module_params.otg_cap) { + switch (core_params->otg_cap) { case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE: if (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) valid = 0; break; @@ -640,7 +713,7 @@ static int check_parameters(dwc_otg_core_if_t *core_if) DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE)); retval += DWC_OTG_PARAM_CHECK_VALID(dma_enable,"dma_enable", - ((dwc_otg_module_params.dma_enable == 1) && (core_if->hwcfg2.b.architecture == 0)) ? 0 : 1, + ((core_params->dma_enable == 1) && (core_if->hwcfg2.b.architecture == 0)) ? 0 : 1, 0); retval += DWC_OTG_PARAM_CHECK_VALID(opt,"opt", @@ -655,58 +728,58 @@ static int check_parameters(dwc_otg_core_if_t *core_if) retval += DWC_OTG_PARAM_CHECK_VALID(enable_dynamic_fifo, "enable_dynamic_fifo", - ((dwc_otg_module_params.enable_dynamic_fifo == 0) || + ((core_params->enable_dynamic_fifo == 0) || (core_if->hwcfg2.b.dynamic_fifo == 1)), 0); retval += DWC_OTG_PARAM_CHECK_VALID(data_fifo_size, "data_fifo_size", - (dwc_otg_module_params.data_fifo_size <= core_if->hwcfg3.b.dfifo_depth), + (core_params->data_fifo_size <= core_if->hwcfg3.b.dfifo_depth), core_if->hwcfg3.b.dfifo_depth); retval += DWC_OTG_PARAM_CHECK_VALID(dev_rx_fifo_size, "dev_rx_fifo_size", - (dwc_otg_module_params.dev_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)), + (core_params->dev_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)), dwc_read_reg32(&core_if->core_global_regs->grxfsiz)); retval += DWC_OTG_PARAM_CHECK_VALID(dev_nperio_tx_fifo_size, "dev_nperio_tx_fifo_size", - (dwc_otg_module_params.dev_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)), + (core_params->dev_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)), (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)); retval += DWC_OTG_PARAM_CHECK_VALID(host_rx_fifo_size, "host_rx_fifo_size", - (dwc_otg_module_params.host_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)), + (core_params->host_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)), dwc_read_reg32(&core_if->core_global_regs->grxfsiz)); retval += DWC_OTG_PARAM_CHECK_VALID(host_nperio_tx_fifo_size, "host_nperio_tx_fifo_size", - (dwc_otg_module_params.host_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)), + (core_params->host_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)), (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)); retval += DWC_OTG_PARAM_CHECK_VALID(host_perio_tx_fifo_size, "host_perio_tx_fifo_size", - (dwc_otg_module_params.host_perio_tx_fifo_size <= ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))), + (core_params->host_perio_tx_fifo_size <= ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))), ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))); retval += DWC_OTG_PARAM_CHECK_VALID(max_transfer_size, "max_transfer_size", - (dwc_otg_module_params.max_transfer_size < (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))), + (core_params->max_transfer_size < (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))), ((1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1)); retval += DWC_OTG_PARAM_CHECK_VALID(max_packet_count, "max_packet_count", - (dwc_otg_module_params.max_packet_count < (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))), + (core_params->max_packet_count < (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))), ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1)); retval += DWC_OTG_PARAM_CHECK_VALID(host_channels, "host_channels", - (dwc_otg_module_params.host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)), + (core_params->host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)), (core_if->hwcfg2.b.num_host_chan + 1)); retval += DWC_OTG_PARAM_CHECK_VALID(dev_endpoints, "dev_endpoints", - (dwc_otg_module_params.dev_endpoints <= (core_if->hwcfg2.b.num_dev_ep)), + (core_params->dev_endpoints <= (core_if->hwcfg2.b.num_dev_ep)), core_if->hwcfg2.b.num_dev_ep); /* @@ -724,19 +797,19 @@ static int check_parameters(dwc_otg_core_if_t *core_if) "phy_type", ({ int valid = 0; - if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_UTMI) && + if ((core_params->phy_type == DWC_PHY_TYPE_PARAM_UTMI) && ((core_if->hwcfg2.b.hs_phy_type == 1) || (core_if->hwcfg2.b.hs_phy_type == 3))) { valid = 1; } - else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_ULPI) && + else if ((core_params->phy_type == DWC_PHY_TYPE_PARAM_ULPI) && ((core_if->hwcfg2.b.hs_phy_type == 2) || (core_if->hwcfg2.b.hs_phy_type == 3))) { valid = 1; } - else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) && + else if ((core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) && (core_if->hwcfg2.b.fs_phy_type == 1)) { valid = 1; @@ -759,13 +832,13 @@ static int check_parameters(dwc_otg_core_if_t *core_if) #endif retval += DWC_OTG_PARAM_CHECK_VALID(speed,"speed", - (dwc_otg_module_params.speed == 0) && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1, - dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS ? 1 : 0); + (core_params->speed == 0) && (core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1, + core_params->phy_type == DWC_PHY_TYPE_PARAM_FS ? 1 : 0); retval += DWC_OTG_PARAM_CHECK_VALID(host_ls_low_power_phy_clk, "host_ls_low_power_phy_clk", - ((dwc_otg_module_params.host_ls_low_power_phy_clk == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ) && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1), - ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ : DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)); + ((core_params->host_ls_low_power_phy_clk == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ) && (core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1), + ((core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) ? DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ : DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)); DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ddr); DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ext_vbus); @@ -779,7 +852,7 @@ static int check_parameters(dwc_otg_core_if_t *core_if) #else retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable, "i2c_enable", - (dwc_otg_module_params.i2c_enable == 1) && (core_if->hwcfg3.b.i2c == 0) ? 0 : 1, + (core_params->i2c_enable == 1) && (core_if->hwcfg3.b.i2c == 0) ? 0 : 1, 0); #endif @@ -788,26 +861,26 @@ static int check_parameters(dwc_otg_core_if_t *core_if) int changed = 1; int error = 0; - if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] == -1) + if (core_params->dev_perio_tx_fifo_size[i] == -1) { changed = 0; - dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default; + core_params->dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default; } - if (!(dwc_otg_module_params.dev_perio_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) + if (!(core_params->dev_perio_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) { if (changed) { - DWC_ERROR("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n", dwc_otg_module_params.dev_perio_tx_fifo_size[i],i); + DWC_ERROR("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n", core_params->dev_perio_tx_fifo_size[i],i); error = 1; } - dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]); + core_params->dev_perio_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]); } retval += error; } retval += DWC_OTG_PARAM_CHECK_VALID(en_multiple_tx_fifo,"en_multiple_tx_fifo", - ((dwc_otg_module_params.en_multiple_tx_fifo == 1) && (core_if->hwcfg4.b.ded_fifo_en == 0)) ? 0 : 1, + ((core_params->en_multiple_tx_fifo == 1) && (core_if->hwcfg4.b.ded_fifo_en == 0)) ? 0 : 1, 0); @@ -817,19 +890,19 @@ static int check_parameters(dwc_otg_core_if_t *core_if) int changed = 1; int error = 0; - if (dwc_otg_module_params.dev_tx_fifo_size[i] == -1) + if (core_params->dev_tx_fifo_size[i] == -1) { changed = 0; - dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default; + core_params->dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default; } - if (!(dwc_otg_module_params.dev_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) + if (!(core_params->dev_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) { if (changed) { - DWC_ERROR("%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n", dwc_otg_module_params.dev_tx_fifo_size[i],i); + DWC_ERROR("%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n", core_params->dev_tx_fifo_size[i],i); error = 1; } - dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]); + core_params->dev_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]); } retval += error; @@ -912,7 +985,7 @@ static void dwc_otg_driver_remove(struct platform_device *pdev) */ if (otg_dev->base != NULL) { - // iounmap(otg_dev->base); + iounmap(otg_dev->base); } kfree(otg_dev); @@ -948,6 +1021,7 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) dwc_otg_device_t *dwc_otg_device; int32_t snpsid; int irq; + uint32_t otgreg; /* *Enable usb phy */ @@ -956,7 +1030,15 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) *otg_phy_con1 |= (0x01<<2); *otg_phy_con1 |= (0x01<<3); // exit suspend. *otg_phy_con1 &= ~(0x01<<2); - +#ifndef CONFIG_RK2818_HOST11 + *otg_phy_con1 |= (0x01<<31); +#endif + #if 0 + otgreg = ioremap(RK2818_USBOTG_PHYS,RK2818_USBOTG_SIZE); + printk("otgreg 0x%x",otgreg); + dwc_modify_reg32((uint32_t *)(otgreg+0xc),0x20000000,0x20000000); + dwc_write_reg32((uint32_t *)(otgreg+0x440), 0x1000); + #endif printk("dwc_otg_driver_probe,everest\n"); dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); @@ -970,7 +1052,6 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); dwc_otg_device->reg_offset = 0xFFFFFFFF; - /* * Map the DWC_otg Core memory into virtual address space. */ @@ -981,9 +1062,14 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) dwc_otg_device->base = ioremap(res_base->start,RK2818_USBOTG_SIZE); - - if (!dwc_otg_device->base) + if (dwc_otg_device->base == NULL) + { + dev_err(dev, "ioremap() failed\n"); + retval = -ENOMEM; goto fail; + } + printk("%s otg2.0 reg addr: 0x%x remap:0x%x\n",__func__, + (unsigned)res_base->start, (unsigned)dwc_otg_device->base); #if 0 dwc_otg_device->base = (void*)(USB_OTG_BASE_ADDR_VA); @@ -1128,7 +1214,6 @@ static int dwc_otg_driver_suspend(struct platform_device *_dev , pm_message_t st { struct device *dev = &_dev->dev; dwc_otg_device_t *otg_dev = dev->platform_data; - dwc_otg_pcd_t * pcd = otg_dev->pcd; dwc_otg_core_if_t *core_if = otg_dev->core_if; //gotgctl_data_t gctrl; #if 0 @@ -1137,8 +1222,7 @@ static int dwc_otg_driver_suspend(struct platform_device *_dev , pm_message_t st #endif /* Clear any pending interrupts */ dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); - pcd->intmaskbak = dwc_read_reg32( &core_if->core_global_regs->gintmsk ); - dwc_write_reg32( &core_if->core_global_regs->gintmsk, 0 ); + dwc_otg_disable_global_interrupts(core_if); return 0; } @@ -1146,7 +1230,6 @@ static int dwc_otg_driver_resume(struct platform_device *_dev ) { struct device *dev = &_dev->dev; dwc_otg_device_t *otg_dev = dev->platform_data; - dwc_otg_pcd_t * pcd = otg_dev->pcd; dwc_otg_core_if_t *core_if = otg_dev->core_if; dctl_data_t dctl = {.d32=0}; @@ -1167,7 +1250,7 @@ static int dwc_otg_driver_resume(struct platform_device *_dev ) /* Clear any pending interrupts */ dwc_write_reg32( &global_regs->gintsts, 0xeFFFFFFF); - dwc_write_reg32( &core_if->core_global_regs->gintmsk, pcd->intmaskbak ); + dwc_otg_enable_global_interrupts(core_if); //sendwakeup: if(core_if->usb_wakeup) @@ -1220,7 +1303,251 @@ static struct platform_driver dwc_otg_driver = { .owner = THIS_MODULE}, }; +#ifdef CONFIG_RK2818_HOST11 +static void rk28_host11_driver_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + dwc_otg_device_t *otg_dev = dev->platform_data; + DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, pdev); + + if (otg_dev == NULL) + { + /* Memory allocation for the dwc_otg_device failed. */ + return; + } + + /* + * Free the IRQ + */ + if (otg_dev->common_irq_installed) + { + free_irq( platform_get_irq(to_platform_device(dev),0), otg_dev ); + } + + if (otg_dev->hcd != NULL) + { + dwc_otg_hcd_remove(dev); + } + + if (otg_dev->core_if != NULL) + { + dwc_otg_cil_remove( otg_dev->core_if ); + } + + /* + * Remove the device attributes + */ + //dwc_otg_attr_remove(dev); + + /* + * Return the memory. + */ + if (otg_dev->base != NULL) + { + iounmap(otg_dev->base); + } + kfree(otg_dev); + + /* + * Clear the drvdata pointer. + */ + dev->platform_data = 0; + +} +/** + * This function is called when an lm_device is bound to a + * dwc_otg_driver. It creates the driver components required to + * control the device (CIL, HCD, and PCD) and it initializes the + * device. The driver components are stored in a dwc_otg_device + * structure. A reference to the dwc_otg_device is saved in the + * lm_device. This allows the driver to access the dwc_otg_device + * structure on subsequent calls to driver methods for this device. + * + * @param[in] pdev platform_device definition + */ +static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) +{ + struct resource *res_base; + int retval = 0; + struct device *dev = &pdev->dev; + dwc_otg_device_t *dwc_otg_device; + int32_t snpsid; + int irq; + uint32_t otgreg; + /* + *Enable usb phy + */ + unsigned int * otg_phy_con1 = (unsigned int*)(RK2818_REGFILE_BASE+0x3c); + *otg_phy_con1 &= ~(0x01<<31); // exit suspend. + #if 0 + *otg_phy_con1 |= (0x01<<2); + *otg_phy_con1 |= (0x01<<3); // exit suspend. + *otg_phy_con1 &= ~(0x01<<2); + otgreg = ioremap(RK2818_USBOTG_PHYS,RK2818_USBOTG_SIZE); + printk("%s otg2.0 reg addr: 0x%x",__func__,otgreg); + dwc_modify_reg32((uint32_t *)(otgreg+0xc),0x20000000,0x20000000); + dwc_write_reg32((uint32_t *)(otgreg+0x440), 0x1000); + #endif + printk("%s otg_phy_con1:0x%x,everest\n",__func__,dwc_read_reg32(otg_phy_con1)); + + dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); + + if (dwc_otg_device == 0) + { + dev_err(dev, "kmalloc of dwc_otg_device failed\n"); + retval = -ENOMEM; + goto fail; + } + + memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); + dwc_otg_device->reg_offset = 0xFFFFFFFF; + /* + * Map the DWC_otg Core memory into virtual address space. + */ + + res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_base) + goto fail; + + dwc_otg_device->base = + ioremap(res_base->start,RK2818_USBHOST_SIZE); + printk("%s host1.1 reg addr: 0x%x remap:0x%x\n",__func__, + (unsigned)res_base->start, (unsigned)dwc_otg_device->base); + if (dwc_otg_device->base == NULL) + { + DWC_ERROR("ioremap() failed\n"); + retval = -ENOMEM; + goto fail; + } + DWC_DEBUGPL( DBG_CIL, "base addr for rk28 host11:0x%x\n", (unsigned)dwc_otg_device->base); + /* + * Attempt to ensure this device is really a DWC_otg Controller. + * Read and verify the SNPSID register contents. The value should be + * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX". + */ + snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40)); + if ((snpsid & 0xFFFFF000) != 0x4F542000) + { + printk("%s::snpsid=0x%x,want 0x%x" , __func__ , snpsid , 0x4F542000 ); + dev_err(dev, "Bad value for SNPSID: 0x%08x\n", snpsid); + retval = -EINVAL; + goto fail; + } + + /* + * Initialize driver data to point to the global DWC_otg + * Device structure. + */ + dev->platform_data = dwc_otg_device; + DWC_DEBUGPL(DBG_CIL, "dwc_otg_device=0x%p\n", dwc_otg_device); + g_host11 = dwc_otg_device; + + dwc_otg_device->core_if = dwc_otg_cil_init( dwc_otg_device->base, + &rk28_host11_module_params); + if (dwc_otg_device->core_if == 0) + { + dev_err(dev, "CIL initialization failed!\n"); + retval = -ENOMEM; + goto fail; + } + DWC_DEBUGPL( DBG_CIL, "registering (common) handler for irq%d\n", + irq); + dwc_otg_device->core_if->otg_dev = dwc_otg_device; + /* + * Validate parameter values. + */ + if (check_parameters(dwc_otg_device->core_if) != 0) + { + retval = -EINVAL; + goto fail; + } + + /* + * Create Device Attributes in sysfs + */ + //dwc_otg_attr_create(dev); + + /* + * Disable the global interrupt until all the interrupt + * handlers are installed. + */ + dwc_otg_disable_global_interrupts( dwc_otg_device->core_if ); + /* + * Install the interrupt handler for the common interrupts before + * enabling common interrupts in core_init below. + */ + irq = platform_get_irq(to_platform_device(dev),0); + DWC_DEBUGPL( DBG_CIL, "registering (common) handler for irq%d\n", + irq); + retval = request_irq(irq, dwc_otg_common_irq, + IRQF_SHARED, "dwc_otg", dwc_otg_device ); + if (retval != 0) + { + DWC_ERROR("request of irq%d failed\n", irq); + retval = -EBUSY; + goto fail; + } + else + { + dwc_otg_device->common_irq_installed = 1; + } + + /* + * Initialize the DWC_otg core. + */ + dwc_otg_core_init( dwc_otg_device->core_if ); + + /* + * Initialize the HCD + */ + retval = rk28_host11_hcd_init(dev); + if (retval != 0) + { + DWC_ERROR("rk28_host11_hcd_init failed\n"); + dwc_otg_device->hcd = NULL; + goto fail; + } + /* + * Enable the global interrupt after all the interrupt + * handlers are installed. + */ + dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); + printk("rk28_host11_driver_probe end, everest\n"); + return 0; + + fail: + devm_kfree(&pdev->dev, dwc_otg_device); + printk("rk28_host11_driver_probe fail,everest\n"); + return retval; +} + +static int rk28_host11_driver_suspend(struct platform_device *_dev , pm_message_t state ) +{ + struct device *dev = &_dev->dev; + dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_core_if_t *core_if = otg_dev->core_if; + return 0; +} + +static int rk28_host11_driver_resume(struct platform_device *_dev ) +{ + struct device *dev = &_dev->dev; + dwc_otg_device_t *otg_dev = dev->platform_data; + dwc_otg_core_if_t *core_if = otg_dev->core_if; + return 0; +} + +static struct platform_driver rk28_host11_driver = { + .probe = rk28_host11_driver_probe, + .remove = rk28_host11_driver_remove, + .suspend = rk28_host11_driver_suspend, + .resume = rk28_host11_driver_resume, + .driver = { + .name = "rk2818_host11", + .owner = THIS_MODULE}, +}; +#endif /** * This function is called when the dwc_otg_driver is installed with the * insmod command. It registers the dwc_otg_driver structure with the @@ -1236,7 +1563,6 @@ static int __init dwc_otg_driver_init(void) int retval = 0; //*(unsigned long *)(0xFF040000+0xE00) = 0x0; //Enable USB Port - retval = platform_driver_register(&dwc_otg_driver); if (retval < 0) { @@ -1245,10 +1571,21 @@ static int __init dwc_otg_driver_init(void) } if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_version)) pr_warning("DWC_OTG: Failed to create driver version file\n"); + #ifdef DWC_BOTH_HOST_SLAVE driver_create_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode); #endif - + +#ifdef CONFIG_RK2818_HOST11 + retval = platform_driver_register(&rk28_host11_driver); + if (retval < 0) + { + printk(KERN_ERR "%s retval=%d\n", __func__, retval); + return retval; + } + if (driver_create_file(&rk28_host11_driver.driver, &driver_attr_version)) + pr_warning("DWC_OTG: Failed to create driver version file\n"); +#endif return retval; } module_init(dwc_otg_driver_init); @@ -1269,7 +1606,9 @@ static void __exit dwc_otg_driver_cleanup(void) #endif platform_driver_unregister(&dwc_otg_driver); - +#ifdef CONFIG_RK2818_HOST11 + platform_driver_unregister(&rk28_host11_driver); +#endif //*(unsigned long *)(0xFF040000+0xE00) = 0xF; //Disable USB Port printk(KERN_INFO "%s module removed\n", dwc_driver_name); } diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c index 1a4d4fe09e71..ac94ca2a27b7 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c @@ -55,6 +55,15 @@ #include "dwc_otg_hcd.h" #include "dwc_otg_regs.h" +static int dwc_otg_hcd_suspend(struct usb_hcd *hcd) +{ + return 0; +} + +static int dwc_otg_hcd_resume(struct usb_hcd *hcd) +{ + return 0; +} static const char dwc_otg_hcd_name [] = "dwc_otg_hcd"; @@ -70,8 +79,17 @@ static const struct hc_driver dwc_otg_hc_driver = { //.reset = .start = dwc_otg_hcd_start, - //.suspend = - //.resume = + //.suspend = + //.resume = + + /* yk@rk 20100625 + * core/hcd.c call hcd->driver->bus_suspend + * otherwise system can not be suspended + */ +#ifdef CONFIG_PM + .bus_suspend = dwc_otg_hcd_suspend, + .bus_resume = dwc_otg_hcd_resume, +#endif .stop = dwc_otg_hcd_stop, .urb_enqueue = dwc_otg_hcd_urb_enqueue, @@ -86,7 +104,44 @@ static const struct hc_driver dwc_otg_hc_driver = { //.hub_resume = }; +#ifdef CONFIG_RK2818_HOST11 +static const struct hc_driver rk28_host11_hc_driver = { + + .description = "rk28_host11_hcd", + .product_desc = "DWC OTG Controller", + .hcd_priv_size = sizeof(dwc_otg_hcd_t), + + .irq = dwc_otg_hcd_irq, + + .flags = HCD_MEMORY | HCD_USB2, + + //.reset = + .start = dwc_otg_hcd_start, + //.suspend = + //.resume = + + /* yk@rk 20100625 + * core/hcd.c call hcd->driver->bus_suspend + * otherwise system can not be suspended + */ +#ifdef CONFIG_PM + .bus_suspend = dwc_otg_hcd_suspend, + .bus_resume = dwc_otg_hcd_resume, +#endif + .stop = dwc_otg_hcd_stop, + + .urb_enqueue = dwc_otg_hcd_urb_enqueue, + .urb_dequeue = dwc_otg_hcd_urb_dequeue, + .endpoint_disable = dwc_otg_hcd_endpoint_disable, + .get_frame_number = dwc_otg_hcd_get_frame_number, + + .hub_status_data = dwc_otg_hcd_hub_status_data, + .hub_control = dwc_otg_hcd_hub_control, + //.hub_suspend = + //.hub_resume = +}; +#endif /** * Work queue function for starting the HCD when A-Cable is connected. @@ -364,7 +419,6 @@ static dwc_otg_cil_callbacks_t hcd_cil_callbacks = { .p = 0,//hcd }; - /** * Reset tasklet function */ @@ -403,8 +457,6 @@ static struct tasklet_struct reset_tasklet = { * a negative error on failure. */ extern uint32_t g_dbg_lvl; -extern int register_root_hub(struct usb_hcd * hcd); - int __devinit dwc_otg_hcd_init(struct device *dev) { struct usb_hcd *hcd = NULL; @@ -528,8 +580,8 @@ int __devinit dwc_otg_hcd_init(struct device *dev) } 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); +// DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n", +// dev->bus_id, hcd->self.busnum); return 0; @@ -545,6 +597,163 @@ int __devinit dwc_otg_hcd_init(struct device *dev) return retval; } +#ifdef CONFIG_RK2818_HOST11 +static dwc_otg_cil_callbacks_t rk28_host11_cil_callbacks = { + .start = dwc_otg_hcd_start_cb, + .stop = dwc_otg_hcd_stop_cb, + .disconnect = dwc_otg_hcd_disconnect_cb, + .session_start = dwc_otg_hcd_session_start_cb, + .p = 0,//hcd +}; + +static struct tasklet_struct rk28_host11_reset_tasklet = { + .next = NULL, + .state = 0, + .count = ATOMIC_INIT(0), + .func = reset_tasklet_func, + .data = 0, +}; + +int __devinit rk28_host11_hcd_init(struct device *dev) +{ + struct usb_hcd *hcd = NULL; + dwc_otg_hcd_t *dwc_otg_hcd = NULL; + dwc_otg_device_t *otg_dev = dev->platform_data; + + int num_channels; + int i; + dwc_hc_t *channel; + + int retval = 0; + printk("%s everest\n",__func__); +// g_dbg_lvl = 0xff; + + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n"); +#if 1 //kaiker .these code must execute before usb_create_hcd + /* Set device flags indicating whether the HCD supports DMA. */ + static u64 usb_dmamask = 0xffffffffUL; + if (otg_dev->core_if->dma_enable) { +// DWC_PRINT("Using DMA mode\n"); + dev->dma_mask = &usb_dmamask; + dev->coherent_dma_mask = ~0; + } else { +// DWC_PRINT("Using Slave mode\n"); + dev->dma_mask = (void *)0; + dev->coherent_dma_mask = 0; + } +#endif + + /* + * Allocate memory for the base HCD plus the DWC OTG HCD. + * Initialize the base HCD. + */ + hcd = usb_create_hcd(&rk28_host11_hc_driver, dev, dev_name(dev)); + if (hcd == NULL) { + retval = -ENOMEM; + goto error1; + } + hcd->regs = otg_dev->base; + hcd->self.otg_port = 1; + + /* Initialize the DWC OTG HCD. */ + dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); + dwc_otg_hcd->core_if = otg_dev->core_if; + otg_dev->hcd = dwc_otg_hcd; + + /* Register the HCD CIL Callbacks */ + dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if, + &rk28_host11_cil_callbacks, hcd); + + /* Initialize the non-periodic schedule. */ + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive); + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active); + + /* Initialize the periodic schedule. */ + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive); + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready); + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned); + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued); + + /* + * Create a host channel descriptor for each host channel implemented + * in the controller. Initialize the channel descriptor array. + */ + INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list); + num_channels = dwc_otg_hcd->core_if->core_params->host_channels; + for (i = 0; i < num_channels; i++) { + channel = kmalloc(sizeof(dwc_hc_t), GFP_KERNEL); + if (channel == NULL) { + retval = -ENOMEM; + DWC_ERROR("%s: host channel allocation failed\n", __func__); + goto error2; + } + memset(channel, 0, sizeof(dwc_hc_t)); + channel->hc_num = i; + dwc_otg_hcd->hc_ptr_array[i] = channel; +#ifdef DEBUG + init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]); +#endif + + DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel); + } + + /* Initialize the Connection timeout timer. */ + init_timer( &dwc_otg_hcd->conn_timer ); + + /* Initialize reset tasklet. */ + rk28_host11_reset_tasklet.data = (unsigned long) dwc_otg_hcd; + dwc_otg_hcd->reset_tasklet = &rk28_host11_reset_tasklet; + /* + * 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 dwc_otg_hcd_start method. + */ + retval = usb_add_hcd(hcd, platform_get_irq(to_platform_device(dev), 0), + IRQF_SHARED); + if (retval < 0) { + DWC_ERROR("usb_add_hcd fail,everest\n"); + goto error2; + } + /* + * Allocate space for storing data on status transactions. Normally no + * data is sent, but this space acts as a bit bucket. This must be + * done after usb_add_hcd since that function allocates the DMA buffer + * pool. + */ + if (otg_dev->core_if->dma_enable) { + dwc_otg_hcd->status_buf = + dma_alloc_coherent(dev, + DWC_OTG_HCD_STATUS_BUF_SIZE, + &dwc_otg_hcd->status_buf_dma, + GFP_KERNEL | GFP_DMA); + } else { + dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE, + GFP_KERNEL); + } + if (dwc_otg_hcd->status_buf == NULL) { + retval = -ENOMEM; + 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; + + /* Error conditions */ + error3: + usb_remove_hcd(hcd); + error2: + dwc_otg_hcd_free(hcd); + usb_put_hcd(hcd); + + error1: + printk("dwc_otg_hcd_init error,everest\n"); + return retval; +} +#endif /** * Removes the HCD. * Frees memory and resources associated with the HCD and deregisters the bus. diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.h b/drivers/usb/dwc_otg/dwc_otg_hcd.h index 406024c9720f..92e55a58847e 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.h +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.h @@ -398,6 +398,7 @@ static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t *dwc_otg_hcd) /** @{ */ extern int __init dwc_otg_hcd_init(struct device *_dev); extern void dwc_otg_hcd_remove(struct device *_dev); +extern int __init rk28_host11_hcd_init(struct device *_dev); /** @} */ /** @name Linux HC Driver API Functions */ diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c index fb72f099cfd6..76326dd69a34 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c @@ -114,7 +114,6 @@ void dwc_otg_hcd_qh_free (dwc_otg_qh_t *_qh) void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_urb) { memset (_qh, 0, sizeof (dwc_otg_qh_t)); - /* Initialize QH */ switch (usb_pipetype(_urb->pipe)) { case PIPE_CONTROL: @@ -141,18 +140,21 @@ void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_ur /* FS/LS Enpoint on HS Hub * NOT virtual root hub */ -#if 1 _qh->do_split = 0; + + /* yk@rk 20100625 + * _urb->dev->tt->hub may be null + */ if (((_urb->dev->speed == USB_SPEED_LOW) || (_urb->dev->speed == USB_SPEED_FULL)) && - (_urb->dev->tt) && (_urb->dev->tt->hub->devnum != 1)) + (_urb->dev->tt) && (_urb->dev->tt->hub)&& + (_urb->dev->tt->hub->devnum != 1)) { DWC_DEBUGPL(DBG_HCD, "QH init: EP %d: TT found at hub addr %d, for port %d\n", usb_pipeendpoint(_urb->pipe), _urb->dev->tt->hub->devnum, _urb->dev->ttport); _qh->do_split = 1; } -#endif if (_qh->ep_type == USB_ENDPOINT_XFER_INT || _qh->ep_type == USB_ENDPOINT_XFER_ISOC) { diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.h b/drivers/usb/dwc_otg/dwc_otg_pcd.h index e6f34346cbff..ec8f2f5790a0 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.h +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.h @@ -198,7 +198,6 @@ typedef struct dwc_otg_pcd * every 500 ms. */ struct timer_list check_vbus_timer; struct delayed_work reconnect; - int intmaskbak; } dwc_otg_pcd_t; diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 289553b964c4..2440bac48f88 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2648,6 +2648,7 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, int rc = 0; DBG(fsg, "store_file: \"%s\"\n", buf); + printk("store_file: \"%s\"\n", buf); #if 0 /* disabled because we need to allow closing the backing file if the media was removed */ if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) {