From 6251d862ded47e760c464a5400433f4c285c92a0 Mon Sep 17 00:00:00 2001 From: hxy Date: Thu, 26 Aug 2010 14:49:04 +0800 Subject: [PATCH] usb:add usb host1.1 for 3G modem --- arch/arm/configs/rk2818_info_defconfig | 161 +++++++++++++++++++- arch/arm/mach-rk2818/clock.c | 5 +- drivers/usb/core/hub.c | 23 +-- drivers/usb/dwc_otg/dwc_otg_attr.c | 81 ++++++---- drivers/usb/dwc_otg/dwc_otg_cil.c | 98 ++++++------ drivers/usb/dwc_otg/dwc_otg_cil_intr.c | 2 +- drivers/usb/dwc_otg/dwc_otg_driver.c | 188 ++++++++++++++++++++---- drivers/usb/dwc_otg/dwc_otg_hcd.c | 169 ++++++++++++++++++--- drivers/usb/dwc_otg/dwc_otg_hcd.h | 5 +- drivers/usb/dwc_otg/dwc_otg_hcd_intr.c | 79 ++++++++-- drivers/usb/dwc_otg/dwc_otg_hcd_queue.c | 44 ++++-- drivers/usb/dwc_otg/dwc_otg_pcd.c | 40 +++-- drivers/usb/dwc_otg/dwc_otg_pcd_intr.c | 7 +- drivers/usb/serial/option.c | 5 + 14 files changed, 720 insertions(+), 187 deletions(-) diff --git a/arch/arm/configs/rk2818_info_defconfig b/arch/arm/configs/rk2818_info_defconfig index ba48ece1099f..de4429d7447b 100755 --- a/arch/arm/configs/rk2818_info_defconfig +++ b/arch/arm/configs/rk2818_info_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.32.9 -# Sat Aug 21 11:03:43 2010 +# Thu Aug 26 13:15:43 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -429,11 +429,15 @@ CONFIG_BT_HIDP=y # # Bluetooth device drivers # +# CONFIG_BT_HCIBTUSB is not set # CONFIG_BT_HCIBTSDIO is not set CONFIG_BT_HCIUART=y CONFIG_BT_HCIUART_H4=y # CONFIG_BT_HCIUART_BCSP is not set # CONFIG_BT_HCIUART_LL is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set # CONFIG_BT_HCIVHCI is not set # CONFIG_BT_MRVL is not set # CONFIG_BT_HCIBCM4325 is not set @@ -548,6 +552,7 @@ CONFIG_MTD_NAND=y CONFIG_MTD_NAND_RK2818=y # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set # CONFIG_MTD_ONENAND is not set # @@ -565,6 +570,7 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -645,6 +651,15 @@ CONFIG_BCM4329_NVRAM_PATH="/etc/firmware/nvram_bcm4329_B23.txt" # # Enable WiMAX (Networking options) to see the WiMAX drivers # + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set CONFIG_PPP=y # CONFIG_PPP_MULTILINK is not set @@ -709,6 +724,7 @@ CONFIG_TOUCHSCREEN_XPT2046_SPI=y # CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI is not set # CONFIG_TOUCHSCREEN_XPT2046_320X480_SPI is not set # CONFIG_TOUCHSCREEN_XPT2046_320X480_CBN_SPI is not set +# CONFIG_TOUCHSCREEN_IT7250 is not set # CONFIG_TOUCHSCREEN_AD7879_I2C is not set # CONFIG_TOUCHSCREEN_AD7879_SPI is not set # CONFIG_TOUCHSCREEN_AD7879 is not set @@ -1043,6 +1059,9 @@ CONFIG_SND_JACK=y # CONFIG_SND_DRIVERS is not set # CONFIG_SND_ARM is not set # CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set CONFIG_SND_SOC=y CONFIG_SND_ROCKCHIP_SOC=y CONFIG_SND_ROCKCHIP_SOC_I2S=y @@ -1060,15 +1079,135 @@ CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set # CONFIG_USB_MUSB_HDRC is not set # CONFIG_USB_GADGET_MUSB_HDRC is not set +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + # # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +# CONFIG_USB_EZUSB is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +CONFIG_USB_SERIAL_OPTION=y +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set @@ -1117,12 +1256,12 @@ CONFIG_USB_ANDROID_RNDIS_WCEIS=y # # CONFIG_USB_GPIO_VBUS is not set # CONFIG_NOP_USB_XCEIV is not set -# CONFIG_RK2818_HOST11 is not set +CONFIG_RK2818_HOST11=y CONFIG_DWC_OTG=y # CONFIG_DWC_OTG_DEBUG is not set # CONFIG_DWC_OTG_HOST_ONLY is not set -CONFIG_DWC_OTG_DEVICE_ONLY=y -# CONFIG_DWC_OTG_BOTH_HOST_SLAVE is not set +# CONFIG_DWC_OTG_DEVICE_ONLY is not set +CONFIG_DWC_OTG_BOTH_HOST_SLAVE=y # CONFIG_DWC_OTG_NORMAL_PREFERENCE is not set # CONFIG_DWC_OTG_HOST_PREFERENCE is not set CONFIG_DWC_OTG_DEVICE_PREFERENCE=y @@ -1235,7 +1374,13 @@ CONFIG_RTC_HYM8563=y # CONFIG_STAGING=y # CONFIG_STAGING_EXCLUDE_BUILD is not set +# CONFIG_USB_IP_COMMON is not set +# CONFIG_PRISM2_USB is not set # CONFIG_ECHO is not set +# CONFIG_COMEDI is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_INPUT_MIMIO is not set +# CONFIG_TRANZPORT is not set # # Android @@ -1265,6 +1410,11 @@ CONFIG_ANDROID_LOW_MEMORY_KILLER=y # CONFIG_DST is not set # CONFIG_POHMELFS is not set # CONFIG_PLAN9AUTH is not set +# CONFIG_LINE6_USB is not set +# CONFIG_USB_SERIAL_QUATECH2 is not set +# CONFIG_USB_SERIAL_QUATECH_USB2 is not set +# CONFIG_VT6656 is not set +# CONFIG_FB_UDL is not set # # RAR Register Driver @@ -1291,6 +1441,7 @@ CONFIG_RK2818_POWER=y # CMMB # # CONFIG_CMMB is not set + # # File systems # diff --git a/arch/arm/mach-rk2818/clock.c b/arch/arm/mach-rk2818/clock.c index 2696864f8b86..62b30881d54d 100644 --- a/arch/arm/mach-rk2818/clock.c +++ b/arch/arm/mach-rk2818/clock.c @@ -1301,8 +1301,11 @@ static struct rk2818_freq_info rk2818_freqs[] = { //X OP(768, 350, 768, 24, 1, 16, 41, 41), // OP(720, 350, 720, 24, 1, 15, 41, 21), // OP(672, 350, 672, 24, 1, 14, 41, 21), -// OP(624, 350, 624, 24, 1, 13, 41, 21), +#if defined(CONFIG_MACH_INFO) + OP(624, 350, 624, 24, 1, 13, 31, 21), +#else OP(600, 350, 600, 24, 1, 12, 41, 21), +#endif // OP(576, 350, 576, 24, 1, 12, 41, 21), // OP(528, 350, 528, 24, 1, 11, 41, 21), // OP(480, 350, 480, 24, 1, 10, 41, 21), diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1f747c68b545..c6341922eac1 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1170,7 +1170,8 @@ static void hub_disconnect(struct usb_interface *intf) kref_put(&hub->kref, hub_release); } - +struct usb_hub *g_root_hub20 = NULL; +struct usb_hub *g_root_hub11 = NULL; static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *desc; @@ -1221,7 +1222,13 @@ descriptor_error: dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n"); return -ENOMEM; } - + if(hdev->parent == NULL) + { + if(!g_root_hub20) + g_root_hub20 = hub; + else if(!g_root_hub11) + g_root_hub11 = hub; + } kref_init(&hub->kref); INIT_LIST_HEAD(&hub->event_list); hub->intfdev = &intf->dev; @@ -3381,15 +3388,13 @@ loop: } /* end while (1) */ } -// cmy@091222: µ±¿ªHost¶Ë¿ÚËùÁ¬½ÓµÄÉ豸£¬¹©host/slaveÇл»Óà -void hub_disconnect_device() + +/* yk@rk 20100730 + * disconnect all devices on root hub + */ +void hub_disconnect_device(struct usb_hub *hub) { - if(g_usb_device) - { - struct usb_hub *hub = hdev_to_hub(g_usb_device->parent); - // cmy: ¶Ï¿ªÉ豸Á¬½Ó hub_port_connect_change(hub, 1, 0, 0x2); - } } static int hub_thread(void *__unused) diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.c b/drivers/usb/dwc_otg/dwc_otg_attr.c index 17fa55c7ba7f..ef77142600e4 100755 --- a/drivers/usb/dwc_otg/dwc_otg_attr.c +++ b/drivers/usb/dwc_otg/dwc_otg_attr.c @@ -268,7 +268,7 @@ * MACROs for defining sysfs attribute */ #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) \ +static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \ { \ dwc_otg_device_t *otg_dev = _dev->platform_data;\ uint32_t val; \ @@ -277,7 +277,7 @@ static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \ return sprintf (buf, "%s = 0x%x\n", _string_, val); \ } #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) \ +static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \ { \ dwc_otg_device_t *otg_dev = _dev->platform_data;\ uint32_t set = simple_strtoul(buf, NULL, 16); \ @@ -302,7 +302,7 @@ DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL); * MACROs for defining sysfs attribute for 32-bit registers */ #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \ -static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \ +static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \ { \ dwc_otg_device_t *otg_dev = _dev->platform_data;\ uint32_t val; \ @@ -310,7 +310,7 @@ static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \ return sprintf (buf, "%s = 0x%08x\n", _string_, val); \ } #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) \ +static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \ { \ dwc_otg_device_t *otg_dev = _dev->platform_data;\ uint32_t val = simple_strtoul(buf, NULL, 16); \ @@ -335,17 +335,19 @@ DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL); /** * Show the register offset of the Register Access. */ -static ssize_t regoffset_show( struct device *_dev, char *buf) +static ssize_t regoffset_show( struct device *_dev, + struct device_attribute *attr, char *buf) { dwc_otg_device_t *otg_dev = _dev->platform_data; + return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset); } /** * Set the register offset for the next Register Access Read/Write */ -static ssize_t regoffset_store( struct device *_dev, const char *buf, - size_t count ) +static ssize_t regoffset_store( struct device *_dev, struct device_attribute *attr, + const char *buf, size_t count ) { dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t offset = simple_strtoul(buf, NULL, 16); @@ -366,7 +368,8 @@ DEVICE_ATTR(regoffset, S_IRUGO|S_IWUSR, regoffset_show, regoffset_store); * Show the value of the register at the offset in the reg_offset * attribute. */ -static ssize_t regvalue_show( struct device *_dev, char *buf) +static ssize_t regvalue_show( struct device *_dev, + struct device_attribute *attr, char *buf) { dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t val; @@ -395,8 +398,9 @@ static ssize_t regvalue_show( struct device *_dev, char *buf) * attribute. * */ -static ssize_t regvalue_store( struct device *_dev, const char *buf, - size_t count ) +static ssize_t regvalue_store( struct device *_dev, + struct device_attribute *attr, + const char *buf, size_t count ) { dwc_otg_device_t *otg_dev = _dev->platform_data; volatile uint32_t * addr; @@ -449,7 +453,8 @@ DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0,otg_dev->core_if->host_if->hprt0,"HPRT0"); /** * Show the HNP status bit */ -static ssize_t hnp_show( struct device *_dev, char *buf) +static ssize_t hnp_show( struct device *_dev, + struct device_attribute *attr, char *buf) { dwc_otg_device_t *otg_dev = _dev->platform_data; gotgctl_data_t val; @@ -460,8 +465,9 @@ static ssize_t hnp_show( struct device *_dev, char *buf) /** * Set the HNP Request bit */ -static ssize_t hnp_store( struct device *_dev, const char *buf, - size_t count ) +static ssize_t hnp_store( struct device *_dev, + struct device_attribute *attr, + const char *buf, size_t count ) { dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t in = simple_strtoul(buf, NULL, 16); @@ -481,7 +487,8 @@ DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store); /** * Show the SRP status bit */ -static ssize_t srp_show( struct device *_dev, char *buf) +static ssize_t srp_show( struct device *_dev, + struct device_attribute *attr, char *buf) { #ifndef DWC_HOST_ONLY dwc_otg_device_t *otg_dev = _dev->platform_data; @@ -498,8 +505,9 @@ static ssize_t srp_show( struct device *_dev, char *buf) /** * Set the SRP Request bit */ -static ssize_t srp_store( struct device *_dev, const char *buf, - size_t count ) +static ssize_t srp_store( struct device *_dev, + struct device_attribute *attr, + const char *buf, size_t count ) { #ifndef DWC_HOST_ONLY dwc_otg_device_t *otg_dev = _dev->platform_data; @@ -515,7 +523,8 @@ DEVICE_ATTR(srp, 0644, srp_show, srp_store); /** * Show the Bus Power status */ -static ssize_t buspower_show( struct device *_dev, char *buf) +static ssize_t buspower_show( struct device *_dev, + struct device_attribute *attr, char *buf) { dwc_otg_device_t *otg_dev = _dev->platform_data; hprt0_data_t val; @@ -527,8 +536,9 @@ static ssize_t buspower_show( struct device *_dev, char *buf) /** * Set the Bus Power status */ -static ssize_t buspower_store( struct device *_dev, const char *buf, - size_t count ) +static ssize_t buspower_store( struct device *_dev, + struct device_attribute *attr, + const char *buf, size_t count ) { dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t on = simple_strtoul(buf, NULL, 16); @@ -551,7 +561,8 @@ DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store); /** * Show the Bus Suspend status */ -static ssize_t bussuspend_show( struct device *_dev, char *buf) +static ssize_t bussuspend_show( struct device *_dev, + struct device_attribute *attr, char *buf) { dwc_otg_device_t *otg_dev = _dev->platform_data; hprt0_data_t val; @@ -562,8 +573,9 @@ static ssize_t bussuspend_show( struct device *_dev, char *buf) /** * Set the Bus Suspend status */ -static ssize_t bussuspend_store( struct device *_dev, const char *buf, - size_t count ) +static ssize_t bussuspend_store( struct device *_dev, + struct device_attribute *attr, + const char *buf, size_t count ) { dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t in = simple_strtoul(buf, NULL, 16); @@ -580,7 +592,8 @@ DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store); /** * Show the status of Remote Wakeup. */ -static ssize_t remote_wakeup_show( struct device *_dev, char *buf) +static ssize_t remote_wakeup_show( struct device *_dev, + struct device_attribute *attr,char *buf) { #ifndef DWC_HOST_ONLY dwc_otg_device_t *otg_dev = _dev->platform_data; @@ -599,8 +612,9 @@ static ssize_t remote_wakeup_show( struct device *_dev, char *buf) * flag is set. * */ -static ssize_t remote_wakeup_store( struct device *_dev, const char *buf, - size_t count ) +static ssize_t remote_wakeup_store( struct device *_dev, + struct device_attribute *attr, + const char *buf, size_t count ) { #ifndef DWC_HOST_ONLY uint32_t val = simple_strtoul(buf, NULL, 16); @@ -614,14 +628,15 @@ static ssize_t remote_wakeup_store( struct device *_dev, const char *buf, #endif return count; } -DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show, +static DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show, remote_wakeup_store); /** * Dump global registers and either host or device registers (depending on the * current mode of the core). */ -static ssize_t regdump_show( struct device *_dev, char *buf) +static ssize_t regdump_show( struct device *_dev, + struct device_attribute *attr, char *buf) { dwc_otg_device_t *otg_dev = _dev->platform_data; dwc_otg_dump_global_registers( otg_dev->core_if); @@ -638,7 +653,8 @@ DEVICE_ATTR(regdump, S_IRUGO|S_IWUSR, regdump_show, 0); /** * Dump the current hcd state. */ -static ssize_t hcddump_show( struct device *_dev, char *buf) +static ssize_t hcddump_show( struct device *_dev, + struct device_attribute *attr, char *buf) { #ifndef DWC_DEVICE_ONLY dwc_otg_device_t *otg_dev = _dev->platform_data; @@ -654,7 +670,8 @@ DEVICE_ATTR(hcddump, S_IRUGO|S_IWUSR, hcddump_show, 0); * determine average interrupt latency. Frame remaining is also shown for * start transfer and two additional sample points. */ -static ssize_t hcd_frrem_show( struct device *_dev, char *buf) +static ssize_t hcd_frrem_show( struct device *_dev, + struct device_attribute *attr, char *buf) { #ifndef DWC_DEVICE_ONLY dwc_otg_device_t *otg_dev = _dev->platform_data; @@ -671,7 +688,8 @@ DEVICE_ATTR(hcd_frrem, S_IRUGO|S_IWUSR, hcd_frrem_show, 0); */ #define RW_REG_COUNT 10000000 #define MSEC_PER_JIFFIE 1000/HZ -static ssize_t rd_reg_test_show( struct device *_dev, char *buf) +static ssize_t rd_reg_test_show( struct device *_dev, + struct device_attribute *attr, char *buf) { int i; int time; @@ -695,7 +713,8 @@ DEVICE_ATTR(rd_reg_test, S_IRUGO|S_IWUSR, rd_reg_test_show, 0); * Displays the time required to write the GNPTXFSIZ register many times (the * output shows the number of times the register is written). */ -static ssize_t wr_reg_test_show( struct device *_dev, char *buf) +static ssize_t wr_reg_test_show( struct device *_dev, + struct device_attribute *attr, char *buf) { int i; int time; diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c index 9baa41691706..273357b71091 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil.c @@ -67,7 +67,7 @@ #include "dwc_otg_driver.h" #include "dwc_otg_cil.h" #define SCU_BASE_ADDR_VA RK2818_SCU_BASE -static dwc_otg_core_if_t * dwc_core_if; +static dwc_otg_core_if_t * dwc_core_if = NULL; /** * This function is called to initialize the DWC_otg CSR data * structures. The register addresses in the device and host @@ -212,6 +212,7 @@ dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *_reg_base_addr, core_if->srp_timer_started = 0; core_if->usb_wakeup = 0; + if(dwc_core_if == NULL) dwc_core_if = core_if; return core_if; } @@ -383,7 +384,7 @@ static uint32_t calc_num_in_eps(dwc_otg_core_if_t *_core_if) for(i = 0; i < num_eps; ++i) { - if(!(hwcfg1 & 0x1)) + if((hwcfg1 & 0x3) == 0x01) num_in_eps++; hwcfg1 >>= 2; @@ -413,7 +414,7 @@ static uint32_t calc_num_out_eps(dwc_otg_core_if_t *_core_if) for(i = 0; i < num_eps; ++i) { - if(!(hwcfg1 & 0x2)) + if((hwcfg1 & 0x3) == 0x02) num_out_eps++; hwcfg1 >>= 2; @@ -1051,6 +1052,16 @@ void dwc_otg_hc_init(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc) } } } +#if 1 + //yk@rk 20100714 + if((_core_if->core_params->host_channels <= 2)&& + _hc->ep_is_in && + _hc->ep_type == DWC_OTG_EP_TYPE_BULK) + { + //DWC_PRINT("%s bulk in\n",__func__); + hc_intr_mask.b.nak = 1; + } +#endif } else { @@ -1223,8 +1234,6 @@ void dwc_otg_hc_halt(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc, dwc_otg_halt_status_e _halt_status) { - gnptxsts_data_t nptxsts; - hptxsts_data_t hptxsts; hcchar_data_t hcchar; dwc_otg_hc_regs_t *hc_regs; dwc_otg_core_global_regs_t *global_regs; @@ -1289,56 +1298,38 @@ void dwc_otg_hc_halt(dwc_otg_core_if_t *_core_if, * happen when a transfer is aborted by a higher level in * the stack. */ -#ifdef DEBUG + DWC_PRINT("*** %s: Channel %d, _hc->halt_pending already set ***\n", __func__, _hc->hc_num); +#ifdef DEBUG /* dwc_otg_dump_global_registers(_core_if); */ /* dwc_otg_dump_host_registers(_core_if); */ #endif return; } + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); - hcchar.b.chen = 1; - hcchar.b.chdis = 1; - - if (!_core_if->dma_enable) - { - /* Check for space in the request queue to issue the halt. */ - if (_hc->ep_type == DWC_OTG_EP_TYPE_CONTROL || - _hc->ep_type == DWC_OTG_EP_TYPE_BULK) - { - nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts); - if (nptxsts.b.nptxqspcavail == 0) - { - hcchar.b.chen = 0; - } - } - else - { - hptxsts.d32 = dwc_read_reg32(&host_global_regs->hptxsts); - if ((hptxsts.b.ptxqspcavail == 0) || (_core_if->queuing_high_bandwidth)) - { - hcchar.b.chen = 0; - } - } - } - - dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); - - _hc->halt_status = _halt_status; - - if (hcchar.b.chen) + //hcchar.b.chen = 1; + //hcchar.b.chdis = 1; + if(hcchar.b.chen) { + hcchar.b.chen = 0; + hcchar.b.chdis = 1; + //hcchar.b.epdir = 0; + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); + _hc->halt_pending = 1; _hc->halt_on_queue = 0; - } - else + _hc->halt_status = _halt_status; + } + else { + DWC_PRINT("%s channel already halt!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", __func__); _hc->halt_on_queue = 1; } - + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num); DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32); DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", _hc->halt_pending); @@ -2898,7 +2889,8 @@ void dwc_otg_core_reset(dwc_otg_core_if_t *_core_if) { dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs; volatile grstctl_t greset = { .d32 = 0}; - gusbcfg_data_t usbcfg = { .d32 = 0 }; + volatile gusbcfg_data_t usbcfg = { .d32 = 0 }; + volatile gintsts_data_t gintsts = { .d32 = 0 }; int count = 0; DWC_DEBUGPL(DBG_CILV, "%s\n", __func__); /* Wait for AHB master IDLE state. */ @@ -2950,7 +2942,21 @@ void dwc_otg_core_reset(dwc_otg_core_if_t *_core_if) dwc_write_reg32( &global_regs->gusbcfg, usbcfg.d32 ); /* Wait for 3 PHY Clocks*/ //DWC_PRINT("100ms\n"); - MDELAY(100); + mdelay(10); + count = 0; + if(usbcfg.b.force_hst_mode) + do + { + gintsts.d32 = dwc_read_reg32( &global_regs->gintsts); + if (++count > 100) + { + DWC_WARN("%s() ERROR! Force host mode GINTSTS=%0x\n", __func__, + gintsts.d32); + break; + } + mdelay(5); + } + while (gintsts.b.curmode != DWC_HOST_MODE); } @@ -2987,22 +2993,20 @@ extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if, _cb->p = _p; } -void rk28_usb_force_disconnect( void ) +void rk28_usb_force_disconnect( dwc_otg_core_if_t *core_if ) { gotgctl_data_t gctrl; dctl_data_t dctl = {.d32=0}; - if( dwc_core_if == NULL ) - return ; - gctrl.d32 = dwc_read_reg32( &dwc_core_if->core_global_regs->gotgctl ); + gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl ); if( !gctrl.b.bsesvld ) return ; printk("%s\n" , __func__); /* soft disconnect */ - dctl.d32 = dwc_read_reg32( &dwc_core_if->dev_if->dev_global_regs->dctl ); + dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); dctl.b.sftdiscon = 1; - dwc_write_reg32( &dwc_core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); + dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); } /** diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c index 481c1b04de7e..783a48a1e323 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c @@ -407,9 +407,9 @@ int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *_core_if) MDELAY(100); if (++count > 10000) *(uint32_t*)NULL=0; } - _core_if->op_state = B_PERIPHERAL; hcd_stop(_core_if); + _core_if->op_state = B_PERIPHERAL; pcd->phy_suspend = 1; pcd->vbus_status = 0; dwc_otg_pcd_start_vbus_timer( pcd ); diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c index 1893f6b36102..8ab58fa8f00c 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.c +++ b/drivers/usb/dwc_otg/dwc_otg_driver.c @@ -75,7 +75,7 @@ static const char dwc_driver_name[] = "dwc_otg"; -struct dwc_otg_device_t* g_otgdev = NULL; +dwc_otg_device_t* g_otgdev = NULL; /*-------------------------------------------------------------------------*/ /* Encapsulate the module parameter settings */ @@ -151,7 +151,7 @@ static dwc_otg_core_params_t dwc_otg_module_params = { #ifdef CONFIG_RK2818_HOST11 -struct dwc_otg_device_t* g_host11 = NULL; +dwc_otg_device_t* g_host11 = NULL; static dwc_otg_core_params_t rk28_host11_module_params = { .opt = -1, @@ -255,12 +255,14 @@ 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); +extern struct usb_hub *g_root_hub20; +extern struct usb_hub *g_root_hub11; #ifdef DWC_BOTH_HOST_SLAVE extern void hcd_start( dwc_otg_core_if_t *_core_if ); extern int rk28_usb_suspend( int exitsuspend ); -extern void hub_disconnect_device(); -extern void rk28_usb_force_disconnect( void ); +extern void hub_disconnect_device(struct usb_hub *hub); +extern void rk28_usb_force_disconnect( dwc_otg_core_if_t *core_if ); static ssize_t force_usb_mode_show(struct device_driver *_drv, char *_buf) { @@ -298,13 +300,13 @@ void dwc_otg_force_host(dwc_otg_core_if_t *core_if) { rk28_usb_suspend( 1 ); } + del_timer(&otg_dev->pcd->check_vbus_timer); + rk28_usb_force_disconnect(core_if); if (core_if->pcd_cb && core_if->pcd_cb->stop ) { core_if->pcd_cb->stop( core_if->pcd_cb->p ); } - del_timer(&otg_dev->pcd->check_vbus_timer); - rk28_usb_force_disconnect(); - core_if->op_state = A_HOST; + //core_if->op_state = A_HOST; /* * Initialize the Core for Host mode. */ @@ -316,16 +318,16 @@ void dwc_otg_force_host(dwc_otg_core_if_t *core_if) void dwc_otg_force_device(dwc_otg_core_if_t *core_if) { dwc_otg_device_t *otg_dev = g_otgdev; + dwc_otg_disable_global_interrupts( core_if ); + hub_disconnect_device(g_root_hub20); + if (core_if->hcd_cb && core_if->hcd_cb->stop) { + core_if->hcd_cb->stop( core_if->hcd_cb->p ); + } if(core_if->op_state == B_PERIPHERAL) { printk("dwc_otg_force_device,already in B_PERIPHERAL,everest\n"); return; } - dwc_otg_disable_global_interrupts( core_if ); - hub_disconnect_device(); - if (core_if->hcd_cb && core_if->hcd_cb->stop) { - core_if->hcd_cb->stop( core_if->hcd_cb->p ); - } otg_dev->core_if->op_state = B_PERIPHERAL; /* Reset the Controller */ dwc_otg_core_reset( core_if ); @@ -360,11 +362,10 @@ static void dwc_otg_set_gusbcfg(dwc_otg_core_if_t *core_if, int mode) static ssize_t force_usb_mode_store(struct device_driver *_drv, const char *_buf, size_t _count ) { - int new_mode = simple_strtoul(_buf, NULL, 10); + int new_mode = simple_strtoul(_buf, NULL, 16); dwc_otg_device_t *otg_dev = g_otgdev; dwc_otg_core_if_t *core_if = otg_dev->core_if; - dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; - + DWC_PRINT("%s %d->%d\n",__func__, core_if->usb_mode, new_mode); if(core_if->usb_mode == new_mode) { return _count; @@ -458,7 +459,7 @@ static ssize_t force_usb_mode_store(struct device_driver *_drv, const char *_buf default: break; } - return 0; + return _count; } int otg_debug( int action ) { @@ -772,10 +773,11 @@ static int check_parameters(dwc_otg_core_if_t *core_if) (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)); +// yk@rk use 1 channel in host 1.1 retval += DWC_OTG_PARAM_CHECK_VALID(host_channels, "host_channels", (core_params->host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)), - (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", @@ -919,7 +921,7 @@ static int check_parameters(dwc_otg_core_if_t *core_if) * This function is the top level interrupt handler for the Common * (Device and host modes) interrupts. */ -static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev, struct pt_regs *_r) +static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev) { dwc_otg_device_t *otg_dev = _dev; int32_t retval = IRQ_NONE; @@ -937,7 +939,7 @@ static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev, struct pt_regs *_r) * * @param[in] pdev */ -static void dwc_otg_driver_remove(struct platform_device *pdev) +static int dwc_otg_driver_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; dwc_otg_device_t *otg_dev = dev->platform_data; @@ -946,7 +948,7 @@ static void dwc_otg_driver_remove(struct platform_device *pdev) if (otg_dev == NULL) { /* Memory allocation for the dwc_otg_device failed. */ - return; + return 0; } /* @@ -1000,6 +1002,7 @@ static void dwc_otg_driver_remove(struct platform_device *pdev) dwc_otg_module_params.host_nperio_tx_fifo_size = -1; dwc_otg_module_params.dev_rx_fifo_size = -1; #endif + return 0; } /** @@ -1215,6 +1218,11 @@ 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_core_if_t *core_if = otg_dev->core_if; + if(core_if->op_state == A_HOST) + { + printk("%s,A_HOST mode\n", __func__); + return 0; + } //gotgctl_data_t gctrl; #if 0 if( __rkusb_debug_mod() ) @@ -1235,6 +1243,11 @@ static int dwc_otg_driver_resume(struct platform_device *_dev ) dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; + if(core_if->op_state == A_HOST) + { + printk("%s,A_HOST mode\n", __func__); + return 0; + } #if 0 if( __rkusb_debug_mod() ) goto sendwakeup; @@ -1304,7 +1317,117 @@ static struct platform_driver dwc_otg_driver = { }; #ifdef CONFIG_RK2818_HOST11 -static void rk28_host11_driver_remove(struct platform_device *pdev) + +void rk28_host11_driver_enable(dwc_otg_core_if_t *core_if) +{ + unsigned int * otg_phy_con1 = (unsigned int*)(RK2818_REGFILE_BASE+0x3c); + unsigned int * scu_clkgate1_con = (unsigned int*)(RK2818_SCU_BASE+0x20); + /* + * enable usb phy & clockgate host controller + */ + core_if->usb_mode == USB_MODE_FORCE_HOST; + core_if->op_state = A_HOST; + dwc_modify_reg32(scu_clkgate1_con,0x80000000,0); //clock gate enable + udelay(10); + dwc_modify_reg32(otg_phy_con1,0x80000000,0);// exit suspend. + mdelay(10); + + /* + * Initialize the Core for Host mode. + */ + dwc_otg_core_init(core_if); + dwc_otg_enable_global_interrupts(core_if); + hcd_start( core_if ); +} + +void rk28_host11_driver_disable(dwc_otg_core_if_t *core_if) +{ + unsigned int * otg_phy_con1 = (unsigned int*)(RK2818_REGFILE_BASE+0x3c); + unsigned int * scu_clkgate1_con = (unsigned int*)(RK2818_SCU_BASE+0x20); + dwc_otg_disable_global_interrupts( core_if ); + hub_disconnect_device(g_root_hub11); + if (core_if->hcd_cb && core_if->hcd_cb->stop) { + core_if->hcd_cb->stop( core_if->hcd_cb->p ); + } + /* + *disable usb phy & clockgate host controller + */ + dwc_modify_reg32(otg_phy_con1,0x80000000,0x80000000);// exit suspend. + mdelay(10); + dwc_modify_reg32(scu_clkgate1_con,0x80000000,0x80000000); //clock gate enable +} +extern void dwc_otg_hcd_remove(struct device *_dev); +extern int __devinit rk28_host11_hcd_init(struct device *_dev); + +static int s_host11_enable = 0; + +static ssize_t enable_usb11_show(struct device_driver *_drv, char *_buf) +{ + return sprintf(_buf, "%d\n", s_host11_enable); +} + +static ssize_t enable_usb11_store(struct device_driver *_drv, const char *_buf, + size_t _count ) +{ + int enabled = simple_strtoul(_buf, NULL, 16); + dwc_otg_device_t *otg_dev = g_host11; + dwc_otg_core_if_t *core_if = otg_dev->core_if; + printk("enable usb11: %d\n", enabled); + + if(enabled) + {// enable usb1.1 + printk("BEGIN enable\n"); + if(s_host11_enable){ + printk("HOST1.1 already enable\n"); + return _count; + } + rk28_host11_driver_enable(core_if); +#if 0 + GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT); + GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_LOW); + msleep(10); + + GPIOSetPinDirection(GPIOPortB_Pin0, GPIO_OUT); + GPIOSetPinLevel(GPIOPortB_Pin0, GPIO_HIGH); + msleep(10); + + GPIOSetPinDirection(GPIOPortG_Pin0, GPIO_OUT); + GPIOSetPinLevel(GPIOPortG_Pin0, GPIO_HIGH); + msleep(10); + + GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT); + GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_HIGH); +#endif + s_host11_enable = 1; + printk("END\n"); + } + else + {// disable usb1.1 +// cmy: + printk("BEGIN disable\n"); + rk28_host11_driver_disable(core_if); +#if 0 + GPIOSetPinDirection(GPIOPortB_Pin0, GPIO_OUT); + GPIOSetPinLevel(GPIOPortB_Pin0, GPIO_LOW); + msleep(10); + + GPIOSetPinDirection(GPIOPortG_Pin0, GPIO_OUT); + GPIOSetPinLevel(GPIOPortG_Pin0, GPIO_LOW); + msleep(10); + + GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT); + GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_LOW); +#endif + s_host11_enable = 0; + printk("END\n"); + } + + return _count; +} + +static DRIVER_ATTR(enable_usb11, 0666/*S_IRUGO|S_IWUSR*/, enable_usb11_show, enable_usb11_store); + +static int rk28_host11_driver_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; dwc_otg_device_t *otg_dev = dev->platform_data; @@ -1313,7 +1436,7 @@ static void rk28_host11_driver_remove(struct platform_device *pdev) if (otg_dev == NULL) { /* Memory allocation for the dwc_otg_device failed. */ - return; + return 0; } /* @@ -1353,6 +1476,7 @@ static void rk28_host11_driver_remove(struct platform_device *pdev) */ dev->platform_data = 0; + return 0; } /** @@ -1524,17 +1648,17 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) 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; + //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; + //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; } @@ -1571,9 +1695,11 @@ 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"); + if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_debuglevel)) + pr_warning("DWC_OTG: Failed to create driver debug level file\n"); #ifdef DWC_BOTH_HOST_SLAVE - driver_create_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode); + retval = driver_create_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode); #endif #ifdef CONFIG_RK2818_HOST11 @@ -1583,8 +1709,7 @@ static int __init dwc_otg_driver_init(void) 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"); + retval = driver_create_file(&rk28_host11_driver.driver, &driver_attr_enable_usb11); #endif return retval; } @@ -1601,6 +1726,7 @@ static void __exit dwc_otg_driver_cleanup(void) printk(KERN_DEBUG "dwc_otg_driver_cleanup()\n"); driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version); + driver_remove_file(&dwc_otg_driver.driver, &driver_attr_debuglevel); #ifdef DWC_BOTH_HOST_SLAVE driver_remove_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode); #endif diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c index ac94ca2a27b7..79502141b6f1 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c @@ -57,11 +57,111 @@ static int dwc_otg_hcd_suspend(struct usb_hcd *hcd) { - return 0; +#if 1 + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_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) + { + printk("%s, usb device mode\n", __func__); + return 0; + } + hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); + DWC_PRINT("%s, HPRT0:0x%x\n",__func__,hprt0.d32); + //partial power-down + if(!hprt0.b.prtsusp) + { + //hprt0.d32 = 0; + hprt0.b.prtsusp = 1; + hprt0.b.prtena = 0; + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); + } + udelay(10); + hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); + DWC_PRINT("%s, HPRT0:0x%x\n",__func__,hprt0.d32); + if(!hprt0.b.prtsusp) + { + //hprt0.d32 = 0; + hprt0.b.prtsusp = 1; + hprt0.b.prtena = 0; + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); + } + mdelay(5); +#if 1 + pcgcctl.d32 = dwc_read_reg32(core_if->pcgcctl); + pcgcctl.b.pwrclmp = 1;//power clamp + dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32); + udelay(1); + //pcgcctl.b.rstpdwnmodule = 1;//reset PDM + pcgcctl.b.stoppclk = 1;//stop phy clk + dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32); +#endif +#endif + //power off + return 0; } static int dwc_otg_hcd_resume(struct usb_hcd *hcd) { +#if 1 + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (hcd); + dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; + hprt0_data_t hprt0; + pcgcctl_data_t pcgcctl; + gintmsk_data_t gintmsk; + + if(core_if->op_state == B_PERIPHERAL) + { + printk("%s, usb device mode\n", __func__); + return 0; + } +#if 1 + //partial power-down + //power on + pcgcctl.d32 = dwc_read_reg32(core_if->pcgcctl);; + pcgcctl.b.stoppclk = 0;//stop phy clk + dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32); + udelay(1); + pcgcctl.b.pwrclmp = 0;//power clamp + 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); + + hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); + DWC_PRINT("%s, HPRT0:0x%x\n",__func__,hprt0.d32); + hprt0.b.prtpwr = 1; + hprt0.b.prtres = 1; + hprt0.b.prtena = 0; + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); + mdelay(20); + hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); + DWC_PRINT("%s, HPRT0:0x%x\n",__func__,hprt0.d32); + //hprt0.d32 = 0; + hprt0.b.prtpwr = 1; + hprt0.b.prtres = 0; + hprt0.b.prtena = 0; + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); + hprt0.d32 = 0; + hprt0.b.prtpwr = 1; + hprt0.b.prtena = 0; + hprt0.b.prtconndet = 1; + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); + + hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); + DWC_PRINT("%s, HPRT0:0x%x\n",__func__,hprt0.d32); + + gintmsk.b.portintr = 1; + dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32); + mdelay(10); +#endif return 0; } @@ -468,10 +568,6 @@ int __devinit dwc_otg_hcd_init(struct device *dev) dwc_hc_t *channel; int retval = 0; - printk("dwc_otg_hcd_init everest\n"); -// 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; @@ -485,6 +581,10 @@ int __devinit dwc_otg_hcd_init(struct device *dev) dev->coherent_dma_mask = 0; } #endif + printk("dwc_otg_hcd_init everest\n"); +// g_dbg_lvl = 0xff; + + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n"); /* * Allocate memory for the base HCD plus the DWC OTG HCD. @@ -500,6 +600,9 @@ int __devinit dwc_otg_hcd_init(struct device *dev) /* Initialize the DWC OTG HCD. */ dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); + + spin_lock_init(&dwc_otg_hcd->global_lock); + dwc_otg_hcd->core_if = otg_dev->core_if; otg_dev->hcd = dwc_otg_hcd; @@ -625,10 +728,6 @@ int __devinit rk28_host11_hcd_init(struct device *dev) 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; @@ -642,6 +741,10 @@ int __devinit rk28_host11_hcd_init(struct device *dev) dev->coherent_dma_mask = 0; } #endif + printk("%s everest\n",__func__); +// g_dbg_lvl = 0xff; + + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n"); /* * Allocate memory for the base HCD plus the DWC OTG HCD. @@ -660,6 +763,9 @@ int __devinit rk28_host11_hcd_init(struct device *dev) dwc_otg_hcd->core_if = otg_dev->core_if; otg_dev->hcd = dwc_otg_hcd; + spin_lock_init(&dwc_otg_hcd->global_lock); + + /* Register the HCD CIL Callbacks */ dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if, &rk28_host11_cil_callbacks, hcd); @@ -826,11 +932,13 @@ int dwc_otg_hcd_start(struct usb_hcd *_hcd) { dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd); dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; + unsigned long flags; struct usb_device *udev; struct usb_bus *bus; DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n"); + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); #if 0 unsigned int regvalue; printk("__________________________________________________________________\n"); @@ -886,6 +994,7 @@ int dwc_otg_hcd_start(struct usb_hcd *_hcd) } hcd_reinit(dwc_otg_hcd); out: + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); return 0; } @@ -1109,8 +1218,11 @@ int dwc_otg_hcd_urb_enqueue(struct usb_hcd *_hcd, retval = usb_hcd_link_urb_to_ep(_hcd, _urb); if (retval) + { + printk("%s, usb_hcd_link_urb_to_ep error\n", __func__); return retval; - local_irq_save(flags); + } + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); #if 1 /* * Make sure the start of frame interrupt is enabled now that @@ -1145,7 +1257,8 @@ int dwc_otg_hcd_urb_enqueue(struct usb_hcd *_hcd, dwc_otg_hcd_qtd_free(qtd); } out: - local_irq_restore(flags); + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); + return retval; } @@ -1169,10 +1282,10 @@ int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, struct urb *_urb, int _status) return -1; } qh = (dwc_otg_qh_t *) _ep->hcpriv; - local_irq_save(flags); + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); retval = usb_hcd_check_unlink_urb(_hcd, _urb, _status); if (retval) { - local_irq_restore(flags); + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); return retval; } @@ -1217,7 +1330,7 @@ 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 - local_irq_restore(flags); + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); _urb->hcpriv = NULL; usb_hcd_unlink_urb_from_ep(_hcd, _urb); /* Higher layer software sets URB status. */ @@ -1237,9 +1350,12 @@ void dwc_otg_hcd_endpoint_disable(struct usb_hcd *_hcd, struct usb_host_endpoint *_ep) { + unsigned long flags; dwc_otg_qh_t *qh; dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd); + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, " "endpoint=%d\n", _ep->desc.bEndpointAddress, dwc_ep_addr_to_endpoint(_ep->desc.bEndpointAddress)); @@ -1258,6 +1374,8 @@ void dwc_otg_hcd_endpoint_disable(struct usb_hcd *_hcd, _ep->hcpriv = NULL; } + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); + return; } @@ -1266,11 +1384,19 @@ void dwc_otg_hcd_endpoint_disable(struct usb_hcd *_hcd, * interrupt. * * This function is called by the USB core when an interrupt occurs */ -irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *_hcd, - struct pt_regs *_regs) +irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *_hcd) { + irqreturn_t result; + unsigned long flags; dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd); - return IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd)); + + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); + + result = IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd)); + + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); + + return result; } /** Creates Status Change bitmap for the root hub and root port. The bitmap is @@ -1829,6 +1955,7 @@ int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd, u16 _wLength) { int retval = 0; + unsigned long flags; dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd); dwc_otg_core_if_t *core_if = hcd_to_dwc_otg_hcd (_hcd)->core_if; @@ -1836,6 +1963,7 @@ int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd, hprt0_data_t hprt0 = {.d32 = 0}; uint32_t port_status; + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); switch (_typeReq) { case ClearHubFeature: @@ -2221,6 +2349,7 @@ int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd, break; } + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); return retval; } @@ -2440,9 +2569,15 @@ dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *_hcd) qh_ptr = _hcd->non_periodic_sched_inactive.next; num_channels = _hcd->core_if->core_params->host_channels; while (qh_ptr != &_hcd->non_periodic_sched_inactive && + /*yk@rk 20100714 (_hcd->non_periodic_channels < num_channels - _hcd->periodic_channels) && + */ !list_empty(&_hcd->free_hc_list)) { + + if((num_channels > 2)&&(_hcd->non_periodic_channels >= + num_channels - _hcd->periodic_channels)) + break; qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry); assign_and_init_hc(_hcd, qh); diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.h b/drivers/usb/dwc_otg/dwc_otg_hcd.h index 92e55a58847e..18ddb3ea1923 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.h +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.h @@ -361,6 +361,8 @@ typedef struct dwc_otg_hcd { /* Tasket to do a reset */ struct tasklet_struct *reset_tasklet; + spinlock_t global_lock; + #ifdef DEBUG uint32_t frrem_samples; uint64_t frrem_accum; @@ -416,8 +418,7 @@ extern int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd, int status); extern void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep); -extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd, - struct pt_regs *regs); +extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd); extern int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd, char *buf); extern int dwc_otg_hcd_hub_control(struct usb_hcd *hcd, diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c index 7a646272b9f2..8e24b6173e05 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c @@ -55,6 +55,7 @@ int32_t dwc_otg_hcd_handle_intr (dwc_otg_hcd_t *_dwc_otg_hcd) if (dwc_otg_is_host_mode(core_if)) { gintsts.d32 = dwc_otg_read_core_intr(core_if); if (!gintsts.d32) { + DWC_PRINT("%s,GINTSTS = 0\n",__func__); return 0; } @@ -467,17 +468,23 @@ int32_t dwc_otg_hcd_handle_port_intr (dwc_otg_hcd_t *_dwc_otg_hcd) * host channel interrupt and handles them appropriately. */ int32_t dwc_otg_hcd_handle_hc_intr (dwc_otg_hcd_t *_dwc_otg_hcd) { - int hcnum; + int i; int retval = 0; - struct list_head *qh_entry; - dwc_otg_qh_t *qh; haint_data_t haint; /* Clear appropriate bits in HCINTn to clear the interrupt bit in * GINTSTS */ haint.d32 = dwc_otg_read_host_all_channels_intr(_dwc_otg_hcd->core_if); - +#if 1 + for (i = 0; i < _dwc_otg_hcd->core_if->core_params->host_channels; i++) { + if (haint.b2.chint & (1 << i)) + retval |= dwc_otg_hcd_handle_hc_n_intr(_dwc_otg_hcd, i); + } +#else + int hcnum; + struct list_head *qh_entry; + dwc_otg_qh_t *qh; /* yk@rk 20100511 * USB Spec2.0 11.18.4 * for all periodic endpoints that have split transactions scheduled within @@ -505,6 +512,7 @@ int32_t dwc_otg_hcd_handle_hc_intr (dwc_otg_hcd_t *_dwc_otg_hcd) retval |= dwc_otg_hcd_handle_hc_n_intr (_dwc_otg_hcd, hcnum); } } +#endif return retval; } @@ -784,9 +792,19 @@ static void release_channel(dwc_otg_hcd_t *_hcd, dwc_otg_transaction_type_e tr_type; int free_qtd; + int continue_trans = 0; + DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n", __func__, _hc->hc_num, _halt_status); - + if((!_hc->halt_pending)|| +// (!list_empty(&_hcd->non_periodic_sched_inactive)) + (_hcd->core_if->core_params->host_channels > 2)|| + (!_hc->ep_is_in)|| + (_hc->ep_type != DWC_OTG_EP_TYPE_BULK) + ) + { + continue_trans = 1; + } switch (_halt_status) { case DWC_OTG_HC_XFER_URB_COMPLETE: free_qtd = 1; @@ -848,12 +866,23 @@ static void release_channel(dwc_otg_hcd_t *_hcd, */ break; } - - /* Try to queue more transfers now that there's a free channel. */ - tr_type = dwc_otg_hcd_select_transactions(_hcd); - if (tr_type != DWC_OTG_TRANSACTION_NONE) { - dwc_otg_hcd_queue_transactions(_hcd, tr_type); + if(continue_trans) + { + /* Try to queue more transfers now that there's a free channel. */ + tr_type = dwc_otg_hcd_select_transactions(_hcd); + if (tr_type != DWC_OTG_TRANSACTION_NONE) { + dwc_otg_hcd_queue_transactions(_hcd, tr_type); + } } + /* + * Make sure the start of frame interrupt is enabled now that + * we know we should have queued data. The SOF interrupt + * handler automatically disables itself when idle to reduce + * the number of interrupts. See dwc_otg_hcd_handle_sof_intr() + * for the disable + */ + dwc_modify_reg32(&_hcd->core_if->core_global_regs->gintmsk, 0, + DWC_SOF_INTR_MASK); } /** @@ -1201,6 +1230,12 @@ static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *_hcd, * occurs. The core will continue transferring data. */ _qtd->error_count = 0; + //yk@rk 20100714 + #if 1 + if((_hcd->core_if->core_params->host_channels <= 2) + &&(!_hc->halt_pending)) + dwc_otg_hc_halt(_hcd->core_if, _hc, DWC_OTG_HC_XFER_NAK); + #endif goto handle_nak_done; } @@ -1238,6 +1273,8 @@ static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *_hcd, } handle_nak_done: + clear_hc_int(_hc_regs,nak); + if(_hcd->core_if->core_params->host_channels > 2) disable_hc_int(_hc_regs,nak); return 1; @@ -1697,6 +1734,23 @@ static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *_hcd, hcint.d32 = dwc_read_reg32(&_hc_regs->hcint); hcintmsk.d32 = dwc_read_reg32(&_hc_regs->hcintmsk); + if((!hcint.b.xfercomp)&& + (_hcd->core_if->core_params->host_channels <= 2)&& + (_hc->halt_pending)&& + (_hc->ep_is_in)&& + (_hc->ep_type == DWC_OTG_EP_TYPE_BULK)) + { + if(hcint.b.ack && !hcintmsk.b.ack) + { + //DWC_PRINT("Halt pending, ack!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + handle_hc_xfercomp_intr(_hcd, _hc, _hc_regs, _qtd); + return; + } + release_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK); + clear_hc_int(_hc_regs,chhltd); + return; + } + if (hcint.b.xfercomp) { /** @todo This is here because of a possible hardware bug. Spec * says that on SPLIT-ISOC OUT transfers in DMA mode that a HALT @@ -1745,6 +1799,10 @@ static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *_hcd, * split transfers. Start splits halt on ACK. */ handle_hc_ack_intr(_hcd, _hc, _hc_regs, _qtd); + } else if(hcint.b.datatglerr){ + DWC_PRINT("%s, DATA toggle error\n"); + dwc_debug(1); + clear_hc_int(_hc_regs,chhltd); } else { if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR || _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { @@ -1764,6 +1822,7 @@ static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *_hcd, "for halting is unknown, hcint 0x%08x, intsts 0x%08x\n", __func__, _hc->hc_num, hcint.d32, dwc_read_reg32(&_hcd->core_if->core_global_regs->gintsts)); + clear_hc_int(_hc_regs,chhltd); } } } diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c index 76326dd69a34..120080356f65 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c @@ -86,10 +86,8 @@ void dwc_otg_hcd_qh_free (dwc_otg_qh_t *_qh) { dwc_otg_qtd_t *qtd; struct list_head *pos; - unsigned long flags; /* Free each QTD in the QTD list */ - local_irq_save (flags); for (pos = _qh->qtd_list.next; pos != &_qh->qtd_list; pos = _qh->qtd_list.next) @@ -98,7 +96,6 @@ void dwc_otg_hcd_qh_free (dwc_otg_qh_t *_qh) qtd = dwc_list_to_qtd (pos); dwc_otg_hcd_qtd_free (qtd); } - local_irq_restore (flags); kfree (_qh); return; @@ -145,6 +142,8 @@ void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_ur /* yk@rk 20100625 * _urb->dev->tt->hub may be null */ + if((_urb->dev->tt)&&(!_urb->dev->tt->hub)) + printk("%s tt->hub null!\n",__func__); if (((_urb->dev->speed == USB_SPEED_LOW) || (_urb->dev->speed == USB_SPEED_FULL)) && (_urb->dev->tt) && (_urb->dev->tt->hub)&& @@ -163,10 +162,15 @@ void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_ur /** @todo Account for split transfers in the bus time. */ int bytecount = dwc_hb_mult(_qh->maxp) * dwc_max_packet(_qh->maxp); + /* + * The results from usb_calc_bus_time are in nanosecs, + * so divide the result by 1000 to convert to + * microsecs expected by this driver + */ _qh->usecs = usb_calc_bus_time(_urb->dev->speed, usb_pipein(_urb->pipe), (_qh->ep_type == USB_ENDPOINT_XFER_ISOC), - bytecount); + bytecount) / 1000; /* Start in a slightly future (micro)frame. */ _qh->sched_frame = dwc_frame_num_inc(_hcd->frame_number, @@ -237,8 +241,9 @@ static int periodic_channel_available(dwc_otg_hcd_t *_hcd) * non-periodic transactions. */ int status; +/*yk@rk modified for usb host 1.1*/ +#if 0 int num_channels; - num_channels = _hcd->core_if->core_params->host_channels; if ((_hcd->periodic_channels + _hcd->non_periodic_channels < num_channels) && (_hcd->periodic_channels < num_channels - 1)) { @@ -250,7 +255,9 @@ static int periodic_channel_available(dwc_otg_hcd_t *_hcd) _hcd->non_periodic_channels); status = -ENOSPC; } - +#else + status = 0; +#endif return status; } @@ -392,10 +399,12 @@ static int schedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) */ int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) { - //unsigned long flags; int status = 0; - //local_irq_save(flags); + if (!spin_is_locked(&_hcd->global_lock)) { + //pr_err("%s don't have hcd->global_lock\n", __func__); + //BUG(); + } if (!list_empty(&_qh->qh_list_entry)) { /* QH already in a schedule. */ @@ -454,9 +463,10 @@ static void deschedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) * @param[in] _qh QH to remove from schedule. */ void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) { - unsigned long flags; - - local_irq_save(flags); + if (!spin_is_locked(&_hcd->global_lock)) { + //pr_err("%s don't have hcd->global_lock\n", __func__); + //BUG(); + } if (list_empty(&_qh->qh_list_entry)) { /* QH is not in a schedule. */ @@ -473,7 +483,7 @@ void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) } done: - local_irq_restore(flags); + ; } /** @@ -491,14 +501,16 @@ void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) */ void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int sched_next_periodic_split) { - unsigned long flags; - local_irq_save(flags); - + if (!spin_is_locked(&_hcd->global_lock)) { + //pr_err("%s don't have hcd->global_lock\n", __func__); + //BUG(); + } if (dwc_qh_is_non_per(_qh)) { dwc_otg_hcd_qh_remove(_hcd, _qh); if (!list_empty(&_qh->qtd_list)) { /* Add back to inactive non-periodic schedule. */ dwc_otg_hcd_qh_add(_hcd, _qh); + return; } } else { uint16_t frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(_hcd)); @@ -554,7 +566,7 @@ void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int sched } } - local_irq_restore(flags); + } /** diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.c b/drivers/usb/dwc_otg/dwc_otg_pcd.c index bee5e0783cfc..4394e6ca420f 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.c @@ -330,7 +330,16 @@ static int dwc_otg_pcd_ep_enable(struct usb_ep *_ep, ep->dwc_ep.tx_fifo_num = assign_tx_fifo(pcd->otg_dev->core_if); } #endif - ep->dwc_ep.tx_fifo_num = ep->dwc_ep.num ; /* 1,3,5 */ + /* yk@rk + * ep0 -- tx fifo 0 + * ep1 -- tx fifo 1 + * ep3 -- tx fifo 2 + * ep5 -- tx fifo 3 + */ + if(ep->dwc_ep.num == 0) + ep->dwc_ep.tx_fifo_num = 0; + else + ep->dwc_ep.tx_fifo_num = (ep->dwc_ep.num>>1)+1 ; /* 1,3,5 */ } /* Set initial data PID. */ if ((_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == @@ -398,7 +407,7 @@ static int dwc_otg_pcd_ep_disable(struct usb_ep *_ep) * @param _gfp_flags the GFP_* flags to use. */ static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *_ep, - int _gfp_flags) + gfp_t _gfp_flags) { dwc_otg_pcd_request_t *req; DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d)\n", __func__, _ep, _gfp_flags); @@ -536,7 +545,7 @@ static void dwc_otg_pcd_free_buffer(struct usb_ep *_ep, void *_buf, * flag. */ static int dwc_otg_pcd_ep_queue(struct usb_ep *_ep, - struct usb_request *_req, int _gfp_flags) + struct usb_request *_req, gfp_t _gfp_flags) { int prevented = 0; dwc_otg_pcd_request_t *req; @@ -557,13 +566,12 @@ static int dwc_otg_pcd_ep_queue(struct usb_ep *_ep, /* 20091226,HSL@RK */ if ( !list_empty(&req->queue) ) { - return -EINVAL; - printk("%s::req not empty,done it error!\n" , __func__ ); - while(!list_empty(&req->queue) ) { - ep = container_of(_ep, dwc_otg_pcd_ep_t, ep); - request_done(ep, req, -ECONNABORTED); - } - + printk("%s::ep %s req not empty,done it error!\n" , __func__, _ep->name); + return -EINVAL; + while(!list_empty(&req->queue) ) { + ep = container_of(_ep, dwc_otg_pcd_ep_t, ep); + request_done(ep, req, -ECONNABORTED); + } } ep = container_of(_ep, dwc_otg_pcd_ep_t, ep); @@ -1026,7 +1034,7 @@ void dwc_otg_pcd_update_otg( dwc_otg_pcd_t *_pcd, const unsigned _reset ) * This function is the top level PCD interrupt handler. */ static irqreturn_t -dwc_otg_pcd_irq(int _irq, void *_dev, struct pt_regs *_r) +dwc_otg_pcd_irq(int _irq, void *_dev) { dwc_otg_pcd_t *pcd = _dev; int32_t retval = IRQ_NONE; @@ -1599,11 +1607,13 @@ void dwc_otg_msc_unlock(void) static void dwc_phy_reconnect(struct work_struct *work) { - dwc_otg_pcd_t *pcd = container_of(work, dwc_otg_pcd_t, reconnect.work);; - dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); + dwc_otg_pcd_t *pcd; + dwc_otg_core_if_t *core_if; gotgctl_data_t gctrl; dctl_data_t dctl = {.d32=0}; + pcd = container_of(work, dwc_otg_pcd_t, reconnect.work); + core_if = GET_CORE_IF(pcd); gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl ); if( gctrl.b.bsesvld ) { dwc_otg_msc_lock(); @@ -1978,6 +1988,10 @@ int rk28_msc_switch(int action) return 0; } #else +int dwc_otg_set_vbus_status(int status) +{ + return 0; +} int rk28_usb_suspend( int exitsuspend ) { return 0; diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c index 9b7c83d9c116..bfa4850bf507 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c @@ -37,7 +37,7 @@ #include "dwc_otg_pcd.h" -#define DEBUG_EP0 +//#define DEBUG_EP0 /* request functions defined in "dwc_otg_pcd.c" */ extern void request_done( dwc_otg_pcd_ep_t *_ep, dwc_otg_pcd_request_t *_req, @@ -875,6 +875,7 @@ int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *_pcd) gusbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg); if (_pcd->gadget.speed == USB_SPEED_HIGH) { + depctl.b.mps = 0x200; if (GET_CORE_IF(_pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_ULPI) { /* ULPI interface */ @@ -925,6 +926,7 @@ int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *_pcd) } else { + depctl.b.mps = 0x40; /* Full or low speed */ gusbcfg.b.usbtrdtim = 9; } @@ -936,14 +938,12 @@ int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *_pcd) dwc_write_reg32( &GET_CORE_IF(_pcd)->core_global_regs->gintsts, gintsts.d32 ); /* enable ep2out */ - depctl.d32 = 0; depctl.b.setd0pid = 1; dwc_write_reg32( &GET_CORE_IF(_pcd)->dev_if->in_ep_regs[1]->diepctl, depctl.d32); depctl.b.snak = 1; depctl.b.txfnum = 2; depctl.b.eptype = 2; depctl.b.usbactep = 1; - depctl.b.mps = 0x200; dwc_write_reg32( &GET_CORE_IF(_pcd)->dev_if->out_ep_regs[2]->doepctl, depctl.d32 ); return 1; } @@ -2536,7 +2536,6 @@ int32_t dwc_otg_pcd_handle_out_nak_effective( dwc_otg_pcd_t *_pcd ) * All interrupt registers are processed from LSB to MSB. * */ - extern void dwc_otg_dump_global_registers(dwc_otg_core_if_t *_core_if); int32_t dwc_otg_pcd_handle_intr( dwc_otg_pcd_t *_pcd ) { dwc_otg_core_if_t *core_if = GET_CORE_IF(_pcd); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index be3dff16d7c4..1f84257851a5 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -344,8 +344,13 @@ static int option_resume(struct usb_serial *serial); #define HAIER_VENDOR_ID 0x201e #define HAIER_PRODUCT_CE100 0x2009 +/* Thinkwill products */ +#define THINKWILL_VENDOR_ID 0x19f5 +#define THINKWILL_PRODUCT_ID 0x9909 + static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, + { USB_DEVICE(THINKWILL_VENDOR_ID,THINKWILL_PRODUCT_ID)}, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD) }, -- 2.34.1