diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b992546c394d5c1e5aac6dd823d6875d506b9846..b58f015554b703f8cd982658f3cf732e4b5c75c8 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -51,82 +51,10 @@
 #include "gadget_chips.h"
 
 
-/* Wait Cond */
-
-#define __wait_cond_interruptible(wq, condition, lock, flags, ret)	\
-do {									\
-	wait_queue_t __wait;						\
-	init_waitqueue_entry(&__wait, current);				\
-									\
-	add_wait_queue(&wq, &__wait);					\
-	for (;;) {							\
-		set_current_state(TASK_INTERRUPTIBLE);			\
-		if (condition)						\
-			break;						\
-		if (!signal_pending(current)) {				\
-			spin_unlock_irqrestore(lock, flags);		\
-			schedule();					\
-			spin_lock_irqsave(lock, flags);			\
-			continue;					\
-		}							\
-		ret = -ERESTARTSYS;					\
-		break;							\
-	}								\
-	current->state = TASK_RUNNING;					\
-	remove_wait_queue(&wq, &__wait);				\
-} while (0)
-	
-#define wait_cond_interruptible(wq, condition, lock, flags)		\
-({									\
-	int __ret = 0;							\
-	if (!(condition))						\
-		__wait_cond_interruptible(wq, condition, lock, flags,	\
-						__ret);			\
-	__ret;								\
-})
-
-#define __wait_cond_interruptible_timeout(wq, condition, lock, flags, 	\
-						timeout, ret)		\
-do {									\
-	signed long __timeout = timeout;				\
-	wait_queue_t __wait;						\
-	init_waitqueue_entry(&__wait, current);				\
-									\
-	add_wait_queue(&wq, &__wait);					\
-	for (;;) {							\
-		set_current_state(TASK_INTERRUPTIBLE);			\
-		if (__timeout == 0)					\
-			break;						\
-		if (condition)						\
-			break;						\
-		if (!signal_pending(current)) {				\
-			spin_unlock_irqrestore(lock, flags);		\
-			__timeout = schedule_timeout(__timeout);	\
-			spin_lock_irqsave(lock, flags);			\
-			continue;					\
-		}							\
-		ret = -ERESTARTSYS;					\
-		break;							\
-	}								\
-	current->state = TASK_RUNNING;					\
-	remove_wait_queue(&wq, &__wait);				\
-} while (0)
-	
-#define wait_cond_interruptible_timeout(wq, condition, lock, flags,	\
-						timeout)		\
-({									\
-	int __ret = 0;							\
-	if (!(condition))						\
-		__wait_cond_interruptible_timeout(wq, condition, lock,	\
-						flags, timeout, __ret);	\
-	__ret;								\
-})
-
-
 /* Defines */
 
-#define GS_VERSION_STR			"v2.0"
-#define GS_VERSION_NUM			0x0200
+#define GS_VERSION_STR			"v2.1"
+#define GS_VERSION_NUM			0x0201
 
 #define GS_LONG_NAME			"Gadget Serial"
 #define GS_SHORT_NAME			"g_serial"
@@ -843,6 +771,18 @@ exit_unlock_dev:
 /*
  * gs_close
  */
+
+#define GS_WRITE_FINISHED_EVENT_SAFELY(p)			\
+({								\
+	unsigned long flags;					\
+	int cond;						\
+								\
+	spin_lock_irqsave(&(p)->port_lock, flags);		\
+	cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \
+	spin_unlock_irqrestore(&(p)->port_lock, flags);		\
+	cond;							\
+})
+
 static void gs_close(struct tty_struct *tty, struct file *file)
 {
 	unsigned long flags;
@@ -888,10 +828,9 @@ static void gs_close(struct tty_struct *tty, struct file *file)
 	/* at most GS_CLOSE_TIMEOUT seconds */
 	if (gs_buf_data_avail(port->port_write_buf) > 0) {
 		spin_unlock_irqrestore(&port->port_lock, flags);
-		wait_cond_interruptible_timeout(port->port_write_wait,
-		port->port_dev == NULL
-		|| gs_buf_data_avail(port->port_write_buf) == 0,
-		&port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ);
+		wait_event_interruptible_timeout(port->port_write_wait,
+					GS_WRITE_FINISHED_EVENT_SAFELY(port),
+					GS_CLOSE_TIMEOUT * HZ);
 		spin_lock_irqsave(&port->port_lock, flags);
 	}