--- npreal2.c	Fri May 03 11:52:43 2013
+++ npreal2.c	Tue Aug 06 16:58:36 2013
@@ -426,6 +426,39 @@
 static struct semaphore 	npvar_tmp_buf_sem = MUTEX;
 #endif
 
+#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0))
+struct n_tty_data {
+	unsigned int column;
+	unsigned long overrun_time;
+	int num_overrun;
+
+	unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1;
+	unsigned char echo_overrun:1;
+
+	DECLARE_BITMAP(process_char_map, 256);
+	DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE);
+
+	char *read_buf;
+	int read_head;
+	int read_tail;
+	int read_cnt;
+	int minimum_to_wake;
+
+	unsigned char *echo_buf;
+	unsigned int echo_pos;
+	unsigned int echo_cnt;
+
+	int canon_data;
+	unsigned long canon_head;
+	unsigned int canon_column;
+
+	struct mutex atomic_read_lock;
+	struct mutex output_lock;
+	struct mutex echo_lock;
+	raw_spinlock_t read_lock;
+};
+#endif
+
 #if (LINUX_VERSION_CODE < VERSION_CODE(2,4,0))
 static struct inode_operations npreal_net_iops;
 #endif
@@ -3436,7 +3469,21 @@
 }
 #endif
 
-#if ((LINUX_VERSION_CODE > VERSION_CODE(2,6,15)) || ((LINUX_VERSION_CODE == VERSION_CODE(2,6,15)) && defined(FEDORA)))
+#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0))
+static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
+{
+    /* Dumb strategy for now - should keep some stats */
+    /* 	printk("Flip dispose %p\n", b); */
+    if (b->size >= 512)
+        kfree(b);
+    else
+    {
+        b->next = tty->port->buf.free;
+        tty->port->buf.free = b;
+    }
+}
+#endif
+#if ((LINUX_VERSION_CODE > VERSION_CODE(2,6,15) && LINUX_VERSION_CODE < VERSION_CODE(3,8,0)) || ((LINUX_VERSION_CODE == VERSION_CODE(2,6,15)) && defined(FEDORA)))
 static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
 {
     /* Dumb strategy for now - should keep some stats */
@@ -3514,11 +3561,20 @@
         tty->ldisc.receive_buf(tty, cp, fp, count);
         //DBGPRINT(MX_DEBUG_TRACE, "flush %d bytes\n", count);
 #else
-        spin_lock_irqsave(&tty->buf.lock, flags);
+#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0))
+        spin_lock_irqsave(&tty->port->buf.lock, flags);
+	head = tty->port->buf.head;
+#else
+        spin_lock_irqsave(&tty->port->buf.lock, flags);
         head = tty->buf.head;
+#endif
         if (head != NULL)
         {
+#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0))
+            tty->port->buf.head = NULL;
+#else
             tty->buf.head = NULL;
+#endif
             for (;;)
             {
                 count = head->commit - head->read;
@@ -3545,17 +3601,29 @@
                 cp = head->char_buf_ptr + head->read;
                 fp = head->flag_buf_ptr + head->read;
                 head->read += count;
+#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0))
+                spin_unlock_irqrestore(&tty->port->buf.lock, flags);
+#else
                 spin_unlock_irqrestore(&tty->buf.lock, flags);
+#endif
 #if (LINUX_VERSION_CODE >= VERSION_CODE(2,6,27))
                 disc->ops->receive_buf(tty, cp, fp, count);
 #else
                 disc->receive_buf(tty, cp, fp, count);
 #endif
+#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0))
+                spin_lock_irqsave(&tty->port->buf.lock, flags);
+            }
+            tty->port->buf.head = head;
+        }
+        spin_unlock_irqrestore(&tty->port->buf.lock, flags);
+#else
                 spin_lock_irqsave(&tty->buf.lock, flags);
             }
             tty->buf.head = head;
         }
         spin_unlock_irqrestore(&tty->buf.lock, flags);
+#endif
         tty_ldisc_deref(disc);
 #endif
     }
@@ -4303,6 +4371,7 @@
     int cnt;
     struct npreal_struct *info;
     struct tty_struct *	tty;
+    struct n_tty_data *ldata;
 
     /*
      *  Get the node pointer, and quit if it doesn't exist.
@@ -4350,6 +4419,10 @@
         up(&info->rx_semaphore);
         goto done;
     }
+#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0))
+    ldata = tty->disc_data;
+#endif
+
 #if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))
 #if 1
     if(!info->tty->low_latency)
@@ -4392,8 +4465,11 @@
         	* that erase characters will be handled.  Other excess
         	* characters will be beeped.
         	*/
-
-        if (!tty->icanon || tty->canon_data)
+#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0))
+	if (!ldata->icanon || ldata->canon_data)
+#else
+	if (!tty->icanon || tty->canon_data)
+#endif
         {
 #if (LINUX_VERSION_CODE <  VERSION_CODE(2,1,0))
             if (!set_bit(TTY_THROTTLED,&tty->flags))
@@ -4408,9 +4484,15 @@
         up(&info->rx_semaphore);
         goto done;
     }
+#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0))
+    if (!ldata->icanon || ldata->canon_data)
+    {
+        if ((cnt = MIN(cnt,(N_TTY_BUF_SIZE-1) - ldata->read_cnt )) <= 0)
+#else
     if (!tty->icanon || tty->canon_data)
     {
         if ((cnt = MIN(cnt,(N_TTY_BUF_SIZE-1) - tty->read_cnt )) <= 0)
+#endif
         {
 
             /*
