diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 47d8dafe9..5a239564b 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -27,6 +27,7 @@
 #include <linux/freezer.h>
 #include <linux/random.h>
 #include <linux/pm_qos.h>
+#include <linux/proc_fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
@@ -36,6 +37,96 @@
 #define USB_VENDOR_GENESYS_LOGIC		0x05e3
 #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND	0x01
 
+static struct list_head oclist_head;
+static LIST_HEAD(oclist_head);
+struct ocdev {
+	struct usb_hub *hub;
+	int port1;
+	struct list_head list;
+};
+
+static void ocdev_add_list( struct usb_hub *hub , int port1)
+{
+	struct ocdev* new_data;
+	new_data = (struct ocdev*)kmalloc(sizeof(struct ocdev), GFP_KERNEL);
+
+	if(new_data){
+		new_data->hub = hub;
+		new_data->port1 = port1;
+		list_add_tail(&new_data->list, &oclist_head);
+	}
+}
+
+static void ocdev_power_on_all(void)
+{
+	struct list_head* pos;
+	struct list_head* next;
+	struct ocdev* data;
+
+	list_for_each_safe(pos , next , &oclist_head){
+		data = list_entry(pos, struct ocdev, list);
+		list_del(pos);
+	    if(data->hub)
+	    {
+	    	usb_hub_set_port_power(data->hub->hdev,data->hub,data->port1,true);
+	    	{
+				int pgood_delay = data->hub->descriptor->bPwrOn2PwrGood * 2;
+				int delay;
+				/* Wait at least 100 msec for power to become stable */
+				delay = max(pgood_delay, (int) 100);
+				msleep(delay);
+	    	}
+	    	usb_wakeup_notification(data->hub->hdev,data->port1);
+	    }
+	    kfree(data);
+	 }
+}
+
+static int ocdev_list_empty(void)
+{
+	return list_empty(&oclist_head);
+}
+
+//	---- Detect USB Over-current error	----
+#define	PROCNAME		"usboc"
+struct	proc_dir_entry	*proc_entry;
+
+static int proc_hub_show(struct seq_file *m, void *p)
+{
+    seq_printf( m, "%d\n", ocdev_list_empty() ? 0 : 1 );
+    return 0;
+}
+
+static int proc_hub_open(struct inode *inode, struct file *file)
+{
+    return single_open(file, proc_hub_show, NULL);
+}
+
+static ssize_t proc_hub_write(struct file *fp, const char *buf, size_t size, loff_t *off)
+{
+	char temp[4];
+	if( copy_from_user(temp,buf,1) ){
+		return -EFAULT;
+	}
+
+    if( strncmp(temp , "0" , 1) == 0 ){
+    	ocdev_power_on_all();
+    }
+
+    return size;
+}
+
+static struct file_operations file_ops = {  
+	.owner = THIS_MODULE,
+	.open = proc_hub_open,
+	.read = seq_read,
+	.write = proc_hub_write,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+//	---- Detect USB Over-current error	----
+
+
 static inline int hub_is_superspeed(struct usb_device *hdev)
 {
 	return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS);
@@ -4896,12 +4987,8 @@ static void hub_events(void)
 					"%d\n", i);
 				usb_clear_port_feature(hdev, i,
 					USB_PORT_FEAT_C_OVER_CURRENT);
-				msleep(100);	/* Cool down */
-				hub_power_on(hub, true);
-				hub_port_status(hub, i, &status, &unused);
-				if (status & USB_PORT_STAT_OVERCURRENT)
-					dev_err(hub_dev, "over-current "
-						"condition on port %d\n", i);
+
+				ocdev_add_list( hub, i );
 			}
 
 			if (portchange & USB_PORT_STAT_C_RESET) {
@@ -5016,6 +5103,13 @@ static int hub_thread(void *__unused)
 	 */
 	set_freezable();
 
+	proc_entry = proc_create( PROCNAME, 0644, NULL, &file_ops );
+    if( proc_entry == NULL ){
+		remove_proc_entry( PROCNAME, (struct proc_dir_entry *)0 );
+		printk( KERN_ALERT "Error: Could not initialize /proc/%s\n", PROCNAME );
+        return -ENOMEM;
+    }
+
 	do {
 		hub_events();
 		wait_event_freezable(khubd_wait,
@@ -5087,6 +5181,8 @@ void usb_hub_cleanup(void)
 	 * individual hub resources. -greg
 	 */
 	usb_deregister(&hub_driver);
+
+	remove_proc_entry( PROCNAME, (struct proc_dir_entry *)0 );
 } /* usb_hub_cleanup() */
 
 static int descriptors_changed(struct usb_device *udev,
