summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/usb/host
diff options
context:
space:
mode:
authorKevin2014-11-15 10:00:36 +0800
committerKevin2014-11-15 10:00:36 +0800
commit9d40ac5867b9aefe0722bc1f110b965ff294d30d (patch)
treede942df665fac4bac0d9cb7ae86910fe937b0c1a /ANDROID_3.4.5/drivers/usb/host
parent392e8802486cb573b916e746010e141a75f507e6 (diff)
downloadFOSSEE-netbook-kernel-source-9d40ac5867b9aefe0722bc1f110b965ff294d30d.tar.gz
FOSSEE-netbook-kernel-source-9d40ac5867b9aefe0722bc1f110b965ff294d30d.tar.bz2
FOSSEE-netbook-kernel-source-9d40ac5867b9aefe0722bc1f110b965ff294d30d.zip
add via modify part source code for wm8880 4.4 kitkat
Diffstat (limited to 'ANDROID_3.4.5/drivers/usb/host')
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/Kconfig15
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/ehci-hcd.c51
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/ehci-hub.c337
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/ehci-pci.c29
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/ehci-q.c7
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/ehci-sched.c7
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/ehci.h23
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/pci-quirks.c9
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/uhci-hcd.c9
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/uhci-hub.c11
-rw-r--r--ANDROID_3.4.5/drivers/usb/host/uhci-pci.c26
11 files changed, 490 insertions, 34 deletions
diff --git a/ANDROID_3.4.5/drivers/usb/host/Kconfig b/ANDROID_3.4.5/drivers/usb/host/Kconfig
index f788eb86..302bae2a 100644
--- a/ANDROID_3.4.5/drivers/usb/host/Kconfig
+++ b/ANDROID_3.4.5/drivers/usb/host/Kconfig
@@ -63,6 +63,21 @@ config USB_EHCI_HCD
To compile this driver as a module, choose M here: the
module will be called ehci-hcd.
+#CharlesTu, for test mode #
+config USB_EHCI_EHSET
+ bool "Embedded High-speed Host Electrical Test Support (EXPERIMENTAL)"
+ depends on USB_EHCI_HCD
+ default y
+ ---help---
+ This option is only used if you are developing firmware for
+ an embedded device with a Hi-speed USB Host or OTG port.
+
+ If you say Y here, software support for the Embedded High-speed
+ Host Electrical Tests will be added to the EHCI driver. This is
+ one of the tests performed during High-speed USB Host certification
+ testing.
+
+ If you are at all unsure then say N here.
config USB_EHCI_ROOT_HUB_TT
bool "Root Hub Transaction Translators"
depends on USB_EHCI_HCD
diff --git a/ANDROID_3.4.5/drivers/usb/host/ehci-hcd.c b/ANDROID_3.4.5/drivers/usb/host/ehci-hcd.c
index bb73df65..dabd379f 100644
--- a/ANDROID_3.4.5/drivers/usb/host/ehci-hcd.c
+++ b/ANDROID_3.4.5/drivers/usb/host/ehci-hcd.c
@@ -130,6 +130,10 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
/*-------------------------------------------------------------------------*/
+extern unsigned int usb_storage_id;
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+unsigned int usb_param[2] = {0xff};
+
static void
timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
{
@@ -599,6 +603,14 @@ static void ehci_stop (struct usb_hcd *hcd)
ehci_readl(ehci, &ehci->regs->status));
}
+int env_mos_gpio;
+unsigned int env_active;
+unsigned int env_port;
+unsigned int env_bitmap;
+unsigned int env_ctraddr;
+unsigned int env_ocaddr;
+unsigned int env_odaddr;
+
/* one-time init, only for memory state */
static int ehci_init(struct usb_hcd *hcd)
{
@@ -607,7 +619,14 @@ static int ehci_init(struct usb_hcd *hcd)
int retval;
u32 hcc_params;
struct ehci_qh_hw *hw;
-
+ char usb_env_name[] = "wmt.usb.param";
+ char usb_env_val[20] = "0";
+ int varlen = 20;
+
+ char usb_resume_env_name[] = "wmt.gpo.usb";
+ char usb_resume_env_val[80] = "0";
+ int varlen_resume = 80;
+
spin_lock_init(&ehci->lock);
/*
@@ -720,7 +739,37 @@ static int ehci_init(struct usb_hcd *hcd)
temp |= hird << 24;
}
ehci->command = temp;
+
+ if(wmt_getsyspara(usb_env_name, usb_env_val, &varlen) == 0) {
+ sscanf(usb_env_val,"%X:%X", &usb_param[0],&usb_param[1]);
+ //printk("usb_param[0] =%x ,usb_param[1]=%x \n",usb_param[0],usb_param[1]);
+ if (usb_param[0] & 0x01) {
+ if(usb_param[1] <= 0x03 ) {
+ usb_storage_id = usb_param[1]+1;
+ //printk("usb_storage_id =%x , it should be small than or equal 4 .\n",usb_storage_id);
+ } else {
+ usb_storage_id = 2;// default port B
+ }
+ } else {
+ usb_storage_id=0; //disable
+ }
+ }
+
+ if(wmt_getsyspara(usb_resume_env_name, usb_resume_env_val, &varlen_resume) == 0) {
+ sscanf(usb_resume_env_val,"%d:%X:%X:%X:%X:%X", &env_mos_gpio,&env_active,&env_bitmap,&env_ctraddr,&env_ocaddr,&env_odaddr);
+
+ if (env_active) {
+ env_port = (env_active >> 4);
+ env_active &= 0x1;
+ env_ctraddr = ((env_ctraddr & 0xffffff) | 0xfe000000);
+ env_ocaddr = ((env_ocaddr & 0xffffff) | 0xfe000000);
+ env_odaddr = ((env_odaddr & 0xffffff) | 0xfe000000);
+ }
+ } else
+ env_active = 0;
+ printk("env_mos_gpio=%d env_active =%x ,env_port=%x env_bitmap=%x env_ctraddr=%x env_ocaddr=%x env_odaddr=%x \n",env_mos_gpio,env_active,env_port,env_bitmap,env_ctraddr,env_ocaddr,env_odaddr);
+
/* Accept arbitrarily long scatter-gather lists */
if (!(hcd->driver->flags & HCD_LOCAL_MEM))
hcd->self.sg_tablesize = ~0;
diff --git a/ANDROID_3.4.5/drivers/usb/host/ehci-hub.c b/ANDROID_3.4.5/drivers/usb/host/ehci-hub.c
index 38fe0762..714ca48b 100644
--- a/ANDROID_3.4.5/drivers/usb/host/ehci-hub.c
+++ b/ANDROID_3.4.5/drivers/usb/host/ehci-hub.c
@@ -128,6 +128,9 @@ static int __maybe_unused ehci_port_change(struct ehci_hcd *ehci)
return 0;
}
+extern char enable_ehci_wake;
+extern char enable_ehci_disc_wakeup;
+
static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
bool suspending, bool do_wakeup)
{
@@ -171,10 +174,13 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
* If we are resuming the controller, set the wakeup flags.
*/
if (!suspending) {
- if (t1 & PORT_CONNECT)
- t2 |= PORT_WKOC_E | PORT_WKDISC_E;
- else
- t2 |= PORT_WKOC_E | PORT_WKCONN_E;
+ if (enable_ehci_wake && enable_ehci_disc_wakeup) {
+ if (t1 & PORT_CONNECT)
+ t2 |= PORT_WKOC_E | PORT_WKDISC_E;
+ else
+ t2 |= PORT_WKOC_E | PORT_WKCONN_E;
+ } else
+ t2 |= PORT_WKOC_E;
}
ehci_vdbg(ehci, "port %d, %08x -> %08x\n",
port + 1, t1, t2);
@@ -254,7 +260,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
if (t1 & PORT_OWNER)
set_bit(port, &ehci->owned_ports);
else if ((t1 & PORT_PE) && !(t1 & PORT_SUSPEND)) {
- t2 |= PORT_SUSPEND;
+ if (enable_ehci_wake)
+ t2 |= PORT_SUSPEND;
+ else
+ t2 &= ~PORT_PE;// CharlesTu, disable port
set_bit(port, &ehci->bus_suspended);
}
@@ -265,10 +274,13 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
* condition happens here(connection change during bits
* set), the port change detection will finally fix it.
*/
- if (t1 & PORT_CONNECT)
- t2 |= PORT_WKOC_E | PORT_WKDISC_E;
- else
- t2 |= PORT_WKOC_E | PORT_WKCONN_E;
+ if (enable_ehci_wake && enable_ehci_disc_wakeup) {
+ if (t1 & PORT_CONNECT)
+ t2 |= PORT_WKOC_E | PORT_WKDISC_E;
+ else
+ t2 |= PORT_WKOC_E | PORT_WKCONN_E;
+ } else
+ t2 |= PORT_WKOC_E;
}
if (t1 != t2) {
@@ -602,6 +614,16 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
* controller by the user.
*/
+ /*
+ *CharlesTu,2009.08.17,patch Trancend 8GB usb device ,
+ *copy and fast hot plug reset slowly issue.
+ *Due to Transcend 8GB device ,connect slowly and reset_done clear 0
+ */
+ /*if (!(temp & PORT_CONNECT))*/
+ if (!(temp & (PORT_CONNECT|PORT_RESET)))
+ ehci->reset_done [i] = 0;
+
+
if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend)
|| (ehci->reset_done[i] && time_after_eq(
jiffies, ehci->reset_done[i]))) {
@@ -611,6 +633,27 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
buf [1] |= 1 << (i - 7);
status = STS_PCD;
}
+ /*CharlesTu,090415,patch usb card reader plug/unplug fastly
+ * port fail issue. Due to the port reset assert and not clear.
+ */
+ if ((temp & PORT_RESET)
+ && time_after (jiffies, ehci->reset_done [i])) {
+ /*printk("port reset \n");*/
+ /* force reset to complete */
+ ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
+ &ehci->regs->port_status [i]);
+ /* REVISIT: some hardware needs 550+ usec to clear
+ * this bit; seems too long to spin routinely...
+ */
+ retval = handshake(ehci,
+ &ehci->regs->port_status [i],
+ PORT_RESET, 0, 750);
+ if (retval != 0) {
+ ehci_err (ehci, "port %d reset error %d\n",
+ i + 1, retval);
+
+ }
+ }
}
/* FIXME autosuspend idle root hubs */
spin_unlock_irqrestore (&ehci->lock, flags);
@@ -653,6 +696,190 @@ ehci_hub_descriptor (
}
/*-------------------------------------------------------------------------*/
+/*{CharlesTu,2010.08.26, for test mode --------------------------------*/
+#ifdef CONFIG_USB_EHCI_EHSET
+
+static int
+single_step_set_feature( struct usb_hcd *hcd, u8 port)
+{
+ struct usb_bus *bus = hcd_to_bus(hcd);
+ struct usb_device *udev;
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+ struct list_head qtd_list;
+ struct list_head setup_list;
+ struct list_head data_list;
+ struct ehci_qtd *qtd;
+ struct urb urb;
+ struct usb_ctrlrequest setup_packet;
+ char data_buffer[USB_DT_DEVICE_SIZE];
+
+ ehci_info (ehci, "Testing SINGLE_STEP_SET_FEATURE\n");
+
+ if (bus == NULL) {
+ ehci_err (ehci, "EHSET: usb_bus pointer is NULL\n");
+ return -EPIPE;
+ }
+
+ udev = bus->root_hub;
+ if (udev == NULL) {
+ ehci_err (ehci, "EHSET: root_hub pointer is NULL\n");
+ return -EPIPE;
+ }
+ /* Charles, modify for MVL5 */
+ /*udev = udev->children[port - 1];*/
+ udev = udev->children[port ];
+
+ if (udev == NULL) {
+ ehci_err (ehci, "EHSET: No test device found on port %d\n",
+ port);
+ return -EPIPE;
+ }
+
+ setup_packet.bRequestType = USB_DIR_IN;
+ setup_packet.bRequest = USB_REQ_GET_DESCRIPTOR;
+ setup_packet.wValue = (USB_DT_DEVICE << 8);
+ setup_packet.wIndex = 0;
+ setup_packet.wLength = USB_DT_DEVICE_SIZE;
+
+ INIT_LIST_HEAD (&qtd_list);
+ INIT_LIST_HEAD (&setup_list);
+ INIT_LIST_HEAD (&data_list);
+
+ urb.transfer_buffer_length = USB_DT_DEVICE_SIZE;
+ urb.dev = udev;
+ urb.pipe = usb_rcvctrlpipe(udev, 0);
+ /* Charles, modify for MVL5 */
+ urb.hcpriv = udev->ep0.hcpriv;
+ /*urb.hcpriv = udev->ep0.hcpriv; */
+
+ urb.setup_packet = (char *)&setup_packet;
+ urb.transfer_buffer = data_buffer;
+ urb.transfer_flags = URB_HCD_DRIVER_TEST;
+ //spin_lock_init(&urb.lock);
+
+ urb.setup_dma = dma_map_single( hcd->self.controller,
+ urb.setup_packet,
+ sizeof (struct usb_ctrlrequest),
+ DMA_TO_DEVICE);
+ urb.transfer_dma = dma_map_single (
+ hcd->self.controller,
+ urb.transfer_buffer,
+ sizeof (struct usb_ctrlrequest),
+ DMA_TO_DEVICE);
+
+ if (!urb.setup_dma || !urb.transfer_dma) {
+ ehci_err (ehci, "dma_map_single Failed\n");
+ return -EBUSY;
+ }
+
+ if (!qh_urb_transaction (ehci, &urb, &qtd_list, GFP_ATOMIC)) {
+ ehci_err (ehci, "qh_urb_transaction Failed\n");
+ return -EBUSY;
+ }
+
+ qtd = container_of (qtd_list.next, struct ehci_qtd, qtd_list);
+ list_del_init (&qtd->qtd_list);
+ list_add (&qtd->qtd_list, &setup_list);
+ qtd = container_of (qtd_list.next, struct ehci_qtd, qtd_list);
+ list_del_init (&qtd->qtd_list);
+ list_add (&qtd->qtd_list, &data_list);
+ qtd = container_of (qtd_list.next, struct ehci_qtd, qtd_list);
+ list_del_init (&qtd->qtd_list);
+ ehci_qtd_free (ehci, qtd);
+
+ ehci_info (ehci, "Sending SETUP PHASE\n");
+ /* Charles, modify for MVL5 */
+ //if (submit_async (ehci, &udev->ep0, &urb, &setup_list, GFP_ATOMIC)) {
+ if (submit_async (ehci, &urb, &setup_list, GFP_ATOMIC)) {
+ ehci_err (ehci, "Failed to queue up qtds\n");
+ return -EBUSY;
+ }
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(msecs_to_jiffies(15000));
+ urb.status = 0;
+ urb.actual_length = 0;
+
+ ehci_info (ehci, "Sending DATA PHASE\n");
+ /* Charles, modify for MVL5 */
+ //if (submit_async (ehci, &udev->ep0, &urb, &data_list, GFP_ATOMIC)) {
+
+ if (submit_async (ehci, &urb, &setup_list, GFP_ATOMIC)) {
+
+ ehci_err (ehci, "Failed to queue up qtds\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+static void stop_test(struct ehci_hcd *ehci)
+{
+ volatile unsigned int temp32 = 0;
+ //int ports = 0,i = 0;
+
+ /*reset HC */
+ temp32 = readl(&ehci->regs->command);
+ ehci_info(ehci, "command before set reset 0x%8.8x\n", temp32);
+ temp32 |= 0x00000002;
+ writel(temp32, &ehci->regs->command);
+ temp32 = readl (&ehci->regs->command);
+ ehci_info(ehci, "command after set reset 0x%8.8x\n", temp32);
+ while ((readl(&ehci->regs->command)) & 0x00000002)
+ ;
+
+ /*set CF bit*/
+ temp32 = readl(&ehci->regs->configured_flag);
+ ehci_info(ehci, "CF before set CF 0x%8.8x\n", temp32);
+ if (!temp32)
+ writel (FLAG_CF, &ehci->regs->configured_flag);
+ temp32 = readl(&ehci->regs->configured_flag);
+ while (!((readl(&ehci->regs->configured_flag)) & 0x00000001))
+ ;
+ ehci_info(ehci, "CF after set CF 0x%8.8x\n", temp32);
+
+
+}
+#endif
+/*CharlesTu}-------------------------------------------------------------*/
+
+static int handshake_wmt (struct ehci_hcd *ehci, void __iomem *ptr,
+ u32 mask, u32 done, int usec)
+{
+ u32 result;
+ u32 result1;
+ int usec_250;
+
+ if (usec > 1000)
+ usec_250 = usec - 261;
+ else
+ usec_250 = usec;
+
+ do {
+ result = ehci_readl(ehci, ptr);
+ result1 = result;
+ if (result == ~(u32)0) /* card removed */
+ return -ENODEV;
+ result &= mask;
+ if (result == done)
+ return 0;
+ udelay (1);
+ usec--;
+ if (usec == usec_250) {
+ ehci_writel(ehci,
+ result1 & ~(PORT_RWC_BITS | PORT_RESUME | PORT_SUSPEND),
+ ptr);
+// printk("*2nd clear resume\n");
+ }
+ } while (usec > 0);
+ return -ETIMEDOUT;
+}
+
+extern unsigned int env_active;
+extern unsigned int env_port;
+extern unsigned int env_bitmap;
+extern unsigned int env_ctraddr;
+extern unsigned int env_ocaddr;
+extern unsigned int env_odaddr;
static int ehci_hub_control (
struct usb_hcd *hcd,
@@ -670,7 +897,8 @@ static int ehci_hub_control (
u32 temp, temp1, status;
unsigned long flags;
int retval = 0;
- unsigned selector;
+ unsigned selector=0;
+ u8 port_num = 0; //CharlesTu, for testmode
/*
* FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR.
@@ -742,7 +970,8 @@ static int ehci_hub_control (
spin_lock_irqsave(&ehci->lock, flags);
}
/* resume signaling for 20 msec */
- temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
+ //temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
+ temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS | PORT_SUSPEND);
ehci_writel(ehci, temp | PORT_RESUME, status_reg);
ehci->reset_done[wIndex] = jiffies
+ msecs_to_jiffies(20);
@@ -839,11 +1068,28 @@ static int ehci_hub_control (
/* stop resume signaling */
temp = ehci_readl(ehci, status_reg);
+// ehci_writel(ehci,
+// temp & ~(PORT_RWC_BITS | PORT_RESUME),
+// status_reg);
+ if ((env_active) && (env_port == wIndex)) {
+ *((volatile unsigned char *)(env_ctraddr)) |= env_bitmap;
+ *((volatile unsigned char *)(env_ocaddr)) |= env_bitmap;
+ *((volatile unsigned char *)(env_odaddr)) |= env_bitmap;
+ }
ehci_writel(ehci,
- temp & ~(PORT_RWC_BITS | PORT_RESUME),
- status_reg);
+ temp & ~(PORT_RWC_BITS | PORT_RESUME | PORT_SUSPEND),
+ status_reg);
clear_bit(wIndex, &ehci->resuming_ports);
- retval = handshake(ehci, status_reg,
+
+ udelay(1);
+
+ if ((env_active) && (env_port == wIndex)) {
+ *((volatile unsigned char *)(env_odaddr)) &= (~env_bitmap);
+ }
+
+// retval = handshake(ehci, status_reg,
+// PORT_RESUME, 0, 2000 /* 2msec */);
+ retval = handshake_wmt(ehci, status_reg,
PORT_RESUME, 0, 2000 /* 2msec */);
if (retval != 0) {
ehci_err(ehci,
@@ -984,7 +1230,12 @@ static int ehci_hub_control (
* mode if we have hostpc feature
*/
temp &= ~PORT_WKCONN_E;
- temp |= PORT_WKDISC_E | PORT_WKOC_E;
+
+ if (enable_ehci_wake && enable_ehci_disc_wakeup)
+ temp |= PORT_WKDISC_E | PORT_WKOC_E;
+ else
+ temp |= PORT_WKOC_E;
+
ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
if (hostpc_reg) {
spin_unlock_irqrestore(&ehci->lock, flags);
@@ -1040,12 +1291,13 @@ static int ehci_hub_control (
* or else system reboot). See EHCI 2.3.9 and 4.14 for info
* about the EHCI-specific stuff.
*/
+/*
case USB_PORT_FEAT_TEST:
if (!selector || selector > 5)
goto error;
ehci_quiesce(ehci);
- /* Put all enabled ports into suspend */
+ // Put all enabled ports into suspend
while (ports--) {
u32 __iomem *sreg =
&ehci->regs->port_status[ports];
@@ -1060,6 +1312,59 @@ static int ehci_hub_control (
temp |= selector << 16;
ehci_writel(ehci, temp, status_reg);
break;
+*/
+ /*{CharlesTu, 2010.8.26, for test mode */
+ case USB_PORT_FEAT_TEST:
+ ehci_info(ehci, "selector : %x\n ", selector);
+ //selector = (wIndex >> 8) & 0xff;
+ port_num = (wIndex) & 0xff;
+ ehci_info(ehci, "USB_PORT_FEAT_TEST : running test %x "
+ "on port %d\n", selector, port_num);
+ if (!selector || selector > 5)
+ ehci_info(ehci, "USB_PORT_FEAT_TEST 1: running test %x "
+ "on port %d\n", selector, port_num);
+
+ switch (selector) {
+ case USB_PORT_TEST_J:
+ case USB_PORT_TEST_K:
+ case USB_PORT_TEST_SE0_NAK:
+ case USB_PORT_TEST_PACKET:
+ case USB_PORT_TEST_FORCE_ENABLE:
+ ehci_quiesce(ehci);
+ ehci_halt(ehci);
+#ifdef CONFIG_USB_EHCI_EHSET
+ stop_test(ehci);
+#endif
+ temp = ehci_readl(ehci, &ehci->regs->command);
+ temp &= 0xfffffffe;
+ writel(temp, &ehci->regs->command);
+
+ temp = readl(&ehci->regs->port_status [(wIndex & 0x00ff)]);
+ temp &= 0xfff0ffff;
+ writel(temp, &ehci->regs->port_status[port_num]);
+ temp |= selector << 16;
+ writel(temp, &ehci->regs->port_status[port_num]);
+ break;
+#ifdef CONFIG_USB_EHCI_EHSET
+ case USB_PORT_TEST_SINGLE_STEP_SET_FEATURE:
+ spin_unlock_irqrestore (&ehci->lock, flags);
+ if (single_step_set_feature(hcd, port_num)) {
+ spin_lock_irqsave (&ehci->lock, flags);
+ goto error;
+ }
+ spin_lock_irqsave (&ehci->lock, flags);
+ break;
+#endif
+
+ default:
+ goto error;
+ ehci_quiesce(ehci);
+ ehci_halt(ehci);
+ temp |= selector << 16;
+ writel (temp, &ehci->regs->port_status[port_num - 1]);
+ }
+ break;
+ /*CharlesTu} */
default:
goto error;
diff --git a/ANDROID_3.4.5/drivers/usb/host/ehci-pci.c b/ANDROID_3.4.5/drivers/usb/host/ehci-pci.c
index 12348179..49726685 100644
--- a/ANDROID_3.4.5/drivers/usb/host/ehci-pci.c
+++ b/ANDROID_3.4.5/drivers/usb/host/ehci-pci.c
@@ -27,6 +27,8 @@
/*-------------------------------------------------------------------------*/
+extern char enable_ehci_wake;
+
/* called after powerup, by probe or system-pm "wakeup" */
static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
{
@@ -334,7 +336,7 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
unsigned long flags;
int rc = 0;
-
+ u16 pmc_enable = 0;
if (time_before(jiffies, ehci->next_statechange))
msleep(10);
@@ -352,7 +354,12 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
// could save FLADJ in case of Vaux power loss
// ... we'd only use it to handle clock skew
-
+ //CharlesTu,for PM high memory
+ if (enable_ehci_wake) {
+ pci_read_config_word(to_pci_dev(hcd->self.controller), 0x84, &pmc_enable);
+ pmc_enable |= 0x103;
+ pci_write_config_word(to_pci_dev(hcd->self.controller), 0x84, pmc_enable);
+ }
return rc;
}
@@ -399,6 +406,13 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
* a '1' to the port switchover registers should have no effect if the
* port was already switched over.
*/
+ u16 pmc_enable = 0;
+ //CharlesTu,for PM high memory
+ if (enable_ehci_wake) {
+ pci_read_config_word(pdev, 0x84, &pmc_enable);
+ pmc_enable &= ~0x03;
+ pci_write_config_word(pdev, 0x84, pmc_enable);
+ }
if (usb_is_intel_switchable_ehci(pdev))
ehci_enable_xhci_companion();
@@ -409,7 +423,11 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
/* Mark hardware accessible again as we are out of D3 state by now */
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
+ /*CharlesTu,2011.01,21,move ahead,due to vbus lost when suspend
+ * when resume ehci hub activate ,type= HUB_RESET_RESUME
+ */
+ if (!enable_ehci_wake)
+ usb_root_hub_lost_power(hcd->self.root_hub);
/* If CF is still set and we aren't resuming from hibernation
* then we maintained PCI Vaux power.
* Just undo the effect of ehci_pci_suspend().
@@ -425,8 +443,9 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
ehci_readl(ehci, &ehci->regs->intr_enable);
return 0;
}
-
- usb_root_hub_lost_power(hcd->self.root_hub);
+ /*CharlesTu,2011.01,21,move ahead,due to vbus lost when suspend*/
+ if (enable_ehci_wake)
+ usb_root_hub_lost_power(hcd->self.root_hub);
/* Else reset, to cope with power loss or flush-to-storage
* style "resume" having let BIOS kick in during reboot.
diff --git a/ANDROID_3.4.5/drivers/usb/host/ehci-q.c b/ANDROID_3.4.5/drivers/usb/host/ehci-q.c
index 36ca5077..9e11e38a 100644
--- a/ANDROID_3.4.5/drivers/usb/host/ehci-q.c
+++ b/ANDROID_3.4.5/drivers/usb/host/ehci-q.c
@@ -286,7 +286,12 @@ __acquires(ehci->lock)
status,
urb->actual_length, urb->transfer_buffer_length);
#endif
-
+ /*{CharlesTu, 2008.12.26, for test mode */
+#ifdef CONFIG_USB_EHCI_EHSET
+ if (likely(urb->transfer_flags == URB_HCD_DRIVER_TEST))
+ return;
+#endif
+ /*CharlesTu}*/
/* complete() can reenter this HCD */
usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
spin_unlock (&ehci->lock);
diff --git a/ANDROID_3.4.5/drivers/usb/host/ehci-sched.c b/ANDROID_3.4.5/drivers/usb/host/ehci-sched.c
index a60679cb..757e3463 100644
--- a/ANDROID_3.4.5/drivers/usb/host/ehci-sched.c
+++ b/ANDROID_3.4.5/drivers/usb/host/ehci-sched.c
@@ -655,7 +655,8 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
qh_put (qh);
/* maybe turn off periodic schedule */
- return disable_periodic(ehci);
+ //return disable_periodic(ehci);
+ return 0;
}
static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
@@ -1767,7 +1768,7 @@ itd_complete (
ehci_urb_done(ehci, urb, 0);
retval = true;
urb = NULL;
- (void) disable_periodic(ehci);
+ //(void) disable_periodic(ehci); gri
ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
@@ -2163,7 +2164,7 @@ sitd_complete (
ehci_urb_done(ehci, urb, 0);
retval = true;
urb = NULL;
- (void) disable_periodic(ehci);
+ //(void) disable_periodic(ehci);//gri
ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
diff --git a/ANDROID_3.4.5/drivers/usb/host/ehci.h b/ANDROID_3.4.5/drivers/usb/host/ehci.h
index 2694ed65..f04172ef 100644
--- a/ANDROID_3.4.5/drivers/usb/host/ehci.h
+++ b/ANDROID_3.4.5/drivers/usb/host/ehci.h
@@ -771,5 +771,26 @@ static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
#endif /* DEBUG */
/*-------------------------------------------------------------------------*/
-
+/*{CharlesTu, 2010.08.26, for test mode */
+
+static struct list_head *
+qh_urb_transaction (
+ struct ehci_hcd *ehci,
+ struct urb *urb,
+ struct list_head *head,
+ gfp_t flags
+);
+
+static int submit_async (
+ struct ehci_hcd *ehci,
+ struct urb *urb,
+ struct list_head *qtd_list,
+ gfp_t mem_flags
+) ;
+
+static inline void ehci_qtd_free (
+ struct ehci_hcd *ehci,
+ struct ehci_qtd *qtd);
+
+/*CharlesTu}*/
#endif /* __LINUX_EHCI_HCD_H */
diff --git a/ANDROID_3.4.5/drivers/usb/host/pci-quirks.c b/ANDROID_3.4.5/drivers/usb/host/pci-quirks.c
index df0828cb..2efade76 100644
--- a/ANDROID_3.4.5/drivers/usb/host/pci-quirks.c
+++ b/ANDROID_3.4.5/drivers/usb/host/pci-quirks.c
@@ -389,7 +389,7 @@ EXPORT_SYMBOL_GPL(uhci_reset_hc);
*/
int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
{
- u16 legsup;
+ //u16 legsup;
unsigned int cmd, intr;
/*
@@ -402,16 +402,19 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
*
* If any of these conditions are violated we do a complete reset.
*/
+ #if 0
pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup);
if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) {
dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n",
__func__, legsup);
goto reset_needed;
}
+ #endif
cmd = inw(base + UHCI_USBCMD);
- if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) ||
- !(cmd & UHCI_USBCMD_EGSM)) {
+// if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) ||
+// !(cmd & UHCI_USBCMD_EGSM)) {
+ if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_EGSM)) {
dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n",
__func__, cmd);
goto reset_needed;
diff --git a/ANDROID_3.4.5/drivers/usb/host/uhci-hcd.c b/ANDROID_3.4.5/drivers/usb/host/uhci-hcd.c
index e4db3506..3e0d2a8c 100644
--- a/ANDROID_3.4.5/drivers/usb/host/uhci-hcd.c
+++ b/ANDROID_3.4.5/drivers/usb/host/uhci-hcd.c
@@ -89,6 +89,8 @@ static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state);
static void wakeup_rh(struct uhci_hcd *uhci);
static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+
/*
* Calculate the link pointer DMA value for the first Skeleton QH in a frame.
*/
@@ -338,6 +340,11 @@ __acquires(uhci->lock)
uhci->RD_enable = !!int_enable;
uhci_writew(uhci, int_enable, USBINTR);
+ //gri
+ uhci_writew(uhci, 0, USBCMD);
+ mb();
+ while (!(uhci_readw(uhci, USBSTS) & USBSTS_HCH));
+ //
uhci_writew(uhci, egsm_enable | USBCMD_CF, USBCMD);
mb();
udelay(5);
@@ -855,7 +862,7 @@ static int __init uhci_hcd_init(void)
int retval = -ENOMEM;
if (usb_disabled())
- return -ENODEV;
+ return -ENODEV;
printk(KERN_INFO "uhci_hcd: " DRIVER_DESC "%s\n",
ignore_oc ? ", overcurrent ignored" : "");
diff --git a/ANDROID_3.4.5/drivers/usb/host/uhci-hub.c b/ANDROID_3.4.5/drivers/usb/host/uhci-hub.c
index 768d5429..fb0da10f 100644
--- a/ANDROID_3.4.5/drivers/usb/host/uhci-hub.c
+++ b/ANDROID_3.4.5/drivers/usb/host/uhci-hub.c
@@ -98,9 +98,12 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
{
int status;
int i;
+ u16 tmp;
+
if (uhci_readw(uhci, port_addr) & SUSPEND_BITS) {
CLR_RH_PORTSTAT(SUSPEND_BITS);
+ wmb();
if (test_bit(port, &uhci->resuming_ports))
set_bit(port, &uhci->port_c_suspend);
@@ -110,9 +113,13 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
* Experiments show that some controllers take longer, so
* we'll poll for completion. */
for (i = 0; i < 10; ++i) {
- if (!(uhci_readw(uhci, port_addr) & SUSPEND_BITS))
- break;
udelay(1);
+ tmp = uhci_readw(uhci, port_addr);
+ //if (!(uhci_readw(uhci, port_addr) & SUSPEND_BITS)){
+ //printk("uhci_finish_suspend 01\n");
+ if (!(tmp & SUSPEND_BITS)){
+ break;
+ }
}
}
clear_bit(port, &uhci->resuming_ports);
diff --git a/ANDROID_3.4.5/drivers/usb/host/uhci-pci.c b/ANDROID_3.4.5/drivers/usb/host/uhci-pci.c
index c300bd2f..2de5a93b 100644
--- a/ANDROID_3.4.5/drivers/usb/host/uhci-pci.c
+++ b/ANDROID_3.4.5/drivers/usb/host/uhci-pci.c
@@ -18,6 +18,7 @@
*/
#include "pci-quirks.h"
+#include <mach/hardware.h>
/*
* Make sure the controller is completely inactive, unable to
@@ -162,11 +163,16 @@ static void uhci_shutdown(struct pci_dev *pdev)
#ifdef CONFIG_PM
+extern char enable_ehci_wake;
+extern char enable_uhci0_wake;
+extern char enable_uhci1_wake;
+
static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
struct pci_dev *pdev = to_pci_dev(uhci_dev(uhci));
int rc = 0;
+ u16 pmc_enable = 0;
dev_dbg(uhci_dev(uhci), "%s\n", __func__);
@@ -192,6 +198,12 @@ static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
pci_write_config_byte(pdev, USBRES_INTEL,
USBPORT1EN | USBPORT2EN);
}
+ //CharlesTu, for PM
+ if (((hcd->self.busnum == 2) && enable_uhci0_wake) || ((hcd->self.busnum == 3) && enable_uhci1_wake)){
+ pci_read_config_word(to_pci_dev(uhci_dev(uhci)), 0x84, &pmc_enable);
+ pmc_enable |= 0x103;
+ pci_write_config_word(to_pci_dev(uhci_dev(uhci)), 0x84, pmc_enable);
+ }
done_okay:
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
@@ -203,7 +215,19 @@ done:
static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-
+ u16 pmc_enable = 0;
+ /*CharlesTu,2009.08.30,patch uhci device disconnet irq nobody care issue
+ * Before clear D3 mode ,disable UHCI resume interrupt
+ * The right sequence: disconnect->wakeup->D0 mode->clear resume.
+ */
+ if (enable_ehci_wake){
+ REG8_VAL(USB20_HOST_DEVICE_CFG_BASE_ADDR+0x0304) &= ~0x02;
+ REG8_VAL(USB20_HOST_DEVICE_CFG_BASE_ADDR+0x1504) &= ~0x02;
+
+ pci_read_config_word(to_pci_dev(uhci_dev(uhci)), 0x84, &pmc_enable);
+ pmc_enable &= ~0x03;
+ pci_write_config_word(to_pci_dev(uhci_dev(uhci)), 0x84, pmc_enable);
+ }
dev_dbg(uhci_dev(uhci), "%s\n", __func__);
/* Since we aren't in D3 any more, it's safe to set this flag