TTY: serialP, merge serial_state and async_struct

This is the final step to get rid of the one of the structures.  A
further cleanup will follow. And I struct serial_state deserves cease
to exist after a switch to tty_port too.

While changing the lines, it removes also pointless tty->driver_data
casts.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 7607c6e..410e8e7 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -45,7 +45,7 @@
 
 #if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
 #define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
- tty->name, (info->state->flags), serial_driver->refcount,info->count,tty->count,s)
+ tty->name, (info->flags), serial_driver->refcount,info->count,tty->count,s)
 #else
 #define DBG_CNT(s)
 #endif
@@ -102,7 +102,7 @@
 
 static unsigned char current_ctl_bits;
 
-static void change_speed(struct async_struct *info, struct ktermios *old);
+static void change_speed(struct serial_state *info, struct ktermios *old);
 static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
 
 
@@ -115,7 +115,7 @@
 #define serial_isroot()	(capable(CAP_SYS_ADMIN))
 
 
-static inline int serial_paranoia_check(struct async_struct *info,
+static inline int serial_paranoia_check(struct serial_state *info,
 					char *name, const char *routine)
 {
 #ifdef SERIAL_PARANOIA_CHECK
@@ -168,7 +168,7 @@
  */
 static void rs_stop(struct tty_struct *tty)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->name, "rs_stop"))
@@ -188,7 +188,7 @@
 
 static void rs_start(struct tty_struct *tty)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->name, "rs_start"))
@@ -229,7 +229,7 @@
  * -----------------------------------------------------------------------
  */
 
-static void receive_chars(struct async_struct *info)
+static void receive_chars(struct serial_state *info)
 {
         int status;
 	int serdatr;
@@ -238,7 +238,7 @@
 	struct	async_icount *icount;
 	int oe = 0;
 
-	icount = &info->state->icount;
+	icount = &info->icount;
 
 	status = UART_LSR_DR; /* We obviously have a character! */
 	serdatr = custom.serdatr;
@@ -295,7 +295,7 @@
 	    printk("handling break....");
 #endif
 	    flag = TTY_BREAK;
-	    if (info->state->flags & ASYNC_SAK)
+	    if (info->flags & ASYNC_SAK)
 	      do_SAK(tty);
 	  } else if (status & UART_LSR_PE)
 	    flag = TTY_PARITY;
@@ -318,14 +318,14 @@
 	return;
 }
 
-static void transmit_chars(struct async_struct *info)
+static void transmit_chars(struct serial_state *info)
 {
 	custom.intreq = IF_TBE;
 	mb();
 	if (info->x_char) {
 	        custom.serdat = info->x_char | 0x100;
 		mb();
-		info->state->icount.tx++;
+		info->icount.tx++;
 		info->x_char = 0;
 		return;
 	}
@@ -341,7 +341,7 @@
 	custom.serdat = info->xmit.buf[info->xmit.tail++] | 0x100;
 	mb();
 	info->xmit.tail = info->xmit.tail & (SERIAL_XMIT_SIZE-1);
-	info->state->icount.tx++;
+	info->icount.tx++;
 
 	if (CIRC_CNT(info->xmit.head,
 		     info->xmit.tail,
@@ -358,7 +358,7 @@
 	}
 }
 
-static void check_modem_status(struct async_struct *info)
+static void check_modem_status(struct serial_state *info)
 {
 	unsigned char status = ciab.pra & (SER_DCD | SER_CTS | SER_DSR);
 	unsigned char dstatus;
@@ -369,14 +369,14 @@
 	current_ctl_bits = status;
 
 	if (dstatus) {
-		icount = &info->state->icount;
+		icount = &info->icount;
 		/* update input line counters */
 		if (dstatus & SER_DSR)
 			icount->dsr++;
 		if (dstatus & SER_DCD) {
 			icount->dcd++;
 #ifdef CONFIG_HARD_PPS
-			if ((info->state->flags & ASYNC_HARDPPS_CD) &&
+			if ((info->flags & ASYNC_HARDPPS_CD) &&
 			    !(status & SER_DCD))
 				hardpps();
 #endif
@@ -386,7 +386,7 @@
 		wake_up_interruptible(&info->delta_msr_wait);
 	}
 
-	if ((info->state->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) {
+	if ((info->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) {
 #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
 		printk("ttyS%d CD now %s...", info->line,
 		       (!(status & SER_DCD)) ? "on" : "off");
@@ -401,7 +401,7 @@
 				tty_hangup(info->tty);
 		}
 	}
-	if (info->state->flags & ASYNC_CTS_FLOW) {
+	if (info->flags & ASYNC_CTS_FLOW) {
 		if (info->tty->hw_stopped) {
 			if (!(status & SER_CTS)) {
 #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
@@ -437,7 +437,7 @@
 static irqreturn_t ser_vbl_int( int irq, void *data)
 {
         /* vbl is just a periodic interrupt we tie into to update modem status */
-	struct async_struct *info = data;
+	struct serial_state *info = data;
 	/*
 	 * TBD - is it better to unregister from this interrupt or to
 	 * ignore it if MSI is clear ?
@@ -449,14 +449,13 @@
 
 static irqreturn_t ser_rx_int(int irq, void *dev_id)
 {
-	struct serial_state *state = dev_id;
-	struct async_struct *info = state->info;
+	struct serial_state *info = dev_id;
 
 #ifdef SERIAL_DEBUG_INTR
 	printk("ser_rx_int...");
 #endif
 
-	if (!info || !info->tty)
+	if (!info->tty)
 		return IRQ_NONE;
 
 	receive_chars(info);
@@ -468,15 +467,14 @@
 
 static irqreturn_t ser_tx_int(int irq, void *dev_id)
 {
-	struct serial_state *state = dev_id;
-	struct async_struct *info = state->info;
+	struct serial_state *info = dev_id;
 
 	if (custom.serdatr & SDR_TBE) {
 #ifdef SERIAL_DEBUG_INTR
 	  printk("ser_tx_int...");
 #endif
 
-	  if (!info || !info->tty)
+	  if (!info->tty)
 		return IRQ_NONE;
 
 	  transmit_chars(info);
@@ -502,7 +500,7 @@
  * ---------------------------------------------------------------
  */
 
-static int startup(struct async_struct * info)
+static int startup(struct serial_state *info)
 {
 	unsigned long flags;
 	int	retval=0;
@@ -514,7 +512,7 @@
 
 	local_irq_save(flags);
 
-	if (info->state->flags & ASYNC_INITIALIZED) {
+	if (info->flags & ASYNC_INITIALIZED) {
 		free_page(page);
 		goto errout;
 	}
@@ -565,13 +563,13 @@
 	 * Set up the tty->alt_speed kludge
 	 */
 	if (info->tty) {
-		if ((info->state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 			info->tty->alt_speed = 57600;
-		if ((info->state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 			info->tty->alt_speed = 115200;
-		if ((info->state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
 			info->tty->alt_speed = 230400;
-		if ((info->state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
 			info->tty->alt_speed = 460800;
 	}
 
@@ -580,7 +578,7 @@
 	 */
 	change_speed(info, NULL);
 
-	info->state->flags |= ASYNC_INITIALIZED;
+	info->flags |= ASYNC_INITIALIZED;
 	local_irq_restore(flags);
 	return 0;
 
@@ -593,15 +591,15 @@
  * This routine will shutdown a serial port; interrupts are disabled, and
  * DTR is dropped if the hangup on close termio flag is on.
  */
-static void shutdown(struct async_struct * info)
+static void shutdown(struct serial_state *info)
 {
 	unsigned long	flags;
 	struct serial_state *state;
 
-	if (!(info->state->flags & ASYNC_INITIALIZED))
+	if (!(info->flags & ASYNC_INITIALIZED))
 		return;
 
-	state = info->state;
+	state = info;
 
 #ifdef SERIAL_DEBUG_OPEN
 	printk("Shutting down serial port %d ....\n", info->line);
@@ -640,7 +638,7 @@
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
 
-	info->state->flags &= ~ASYNC_INITIALIZED;
+	info->flags &= ~ASYNC_INITIALIZED;
 	local_irq_restore(flags);
 }
 
@@ -649,7 +647,7 @@
  * This routine is called to set the UART divisor registers to match
  * the specified baud rate for a serial port.
  */
-static void change_speed(struct async_struct *info,
+static void change_speed(struct serial_state *info,
 			 struct ktermios *old_termios)
 {
 	int	quot = 0, baud_base, baud;
@@ -683,10 +681,10 @@
 	baud = tty_get_baud_rate(info->tty);
 	if (!baud)
 		baud = 9600;	/* B0 transition handled in rs_set_termios */
-	baud_base = info->state->baud_base;
+	baud_base = info->baud_base;
 	if (baud == 38400 &&
-	    ((info->state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
-		quot = info->state->custom_divisor;
+	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+		quot = info->custom_divisor;
 	else {
 		if (baud == 134)
 			/* Special case since 134 is really 134.5 */
@@ -703,8 +701,8 @@
 		if (!baud)
 			baud = 9600;
 		if (baud == 38400 &&
-		    ((info->state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
-			quot = info->state->custom_divisor;
+		    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+			quot = info->custom_divisor;
 		else {
 			if (baud == 134)
 				/* Special case since 134 is really 134.5 */
@@ -717,22 +715,22 @@
 	if (!quot)
 		quot = baud_base / 9600;
 	info->quot = quot;
-	info->timeout = ((info->state->xmit_fifo_size*HZ*bits*quot) / baud_base);
+	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
 	info->timeout += HZ/50;		/* Add .02 seconds of slop */
 
 	/* CTS flow control flag and modem status interrupts */
 	info->IER &= ~UART_IER_MSI;
-	if (info->state->flags & ASYNC_HARDPPS_CD)
+	if (info->flags & ASYNC_HARDPPS_CD)
 		info->IER |= UART_IER_MSI;
 	if (cflag & CRTSCTS) {
-		info->state->flags |= ASYNC_CTS_FLOW;
+		info->flags |= ASYNC_CTS_FLOW;
 		info->IER |= UART_IER_MSI;
 	} else
-		info->state->flags &= ~ASYNC_CTS_FLOW;
+		info->flags &= ~ASYNC_CTS_FLOW;
 	if (cflag & CLOCAL)
-		info->state->flags &= ~ASYNC_CHECK_CD;
+		info->flags &= ~ASYNC_CHECK_CD;
 	else {
-		info->state->flags |= ASYNC_CHECK_CD;
+		info->flags |= ASYNC_CHECK_CD;
 		info->IER |= UART_IER_MSI;
 	}
 	/* TBD:
@@ -791,7 +789,7 @@
 
 static int rs_put_char(struct tty_struct *tty, unsigned char ch)
 {
-	struct async_struct *info;
+	struct serial_state *info;
 	unsigned long flags;
 
 	info = tty->driver_data;
@@ -818,7 +816,7 @@
 
 static void rs_flush_chars(struct tty_struct *tty)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
@@ -843,11 +841,9 @@
 static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count)
 {
 	int	c, ret = 0;
-	struct async_struct *info;
+	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
 
-	info = tty->driver_data;
-
 	if (serial_paranoia_check(info, tty->name, "rs_write"))
 		return 0;
 
@@ -891,7 +887,7 @@
 
 static int rs_write_room(struct tty_struct *tty)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 
 	if (serial_paranoia_check(info, tty->name, "rs_write_room"))
 		return 0;
@@ -900,7 +896,7 @@
 
 static int rs_chars_in_buffer(struct tty_struct *tty)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 
 	if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
 		return 0;
@@ -909,7 +905,7 @@
 
 static void rs_flush_buffer(struct tty_struct *tty)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
@@ -926,7 +922,7 @@
  */
 static void rs_send_xchar(struct tty_struct *tty, char ch)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
         unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->name, "rs_send_char"))
@@ -961,7 +957,7 @@
  */
 static void rs_throttle(struct tty_struct * tty)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
@@ -986,7 +982,7 @@
 
 static void rs_unthrottle(struct tty_struct * tty)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
@@ -1017,11 +1013,10 @@
  * ------------------------------------------------------------
  */
 
-static int get_serial_info(struct async_struct * info,
+static int get_serial_info(struct serial_state *state,
 			   struct serial_struct __user * retinfo)
 {
 	struct serial_struct tmp;
-	struct serial_state *state = info->state;
    
 	if (!retinfo)
 		return -EFAULT;
@@ -1043,11 +1038,11 @@
 	return 0;
 }
 
-static int set_serial_info(struct async_struct * info,
+static int set_serial_info(struct serial_state *state,
 			   struct serial_struct __user * new_info)
 {
 	struct serial_struct new_serial;
- 	struct serial_state old_state, *state;
+	struct serial_state old_state;
 	unsigned int		change_irq,change_port;
 	int 			retval = 0;
 
@@ -1055,7 +1050,6 @@
 		return -EFAULT;
 
 	tty_lock();
-	state = info->state;
 	old_state = *state;
   
 	change_irq = new_serial.irq != state->irq;
@@ -1094,7 +1088,7 @@
 	state->custom_divisor = new_serial.custom_divisor;
 	state->close_delay = new_serial.close_delay * HZ/100;
 	state->closing_wait = new_serial.closing_wait * HZ/100;
-	info->tty->low_latency = (state->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+	state->tty->low_latency = (state->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
 check_and_exit:
 	if (state->flags & ASYNC_INITIALIZED) {
@@ -1102,17 +1096,17 @@
 		     (state->flags & ASYNC_SPD_MASK)) ||
 		    (old_state.custom_divisor != state->custom_divisor)) {
 			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-				info->tty->alt_speed = 57600;
+				state->tty->alt_speed = 57600;
 			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-				info->tty->alt_speed = 115200;
+				state->tty->alt_speed = 115200;
 			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-				info->tty->alt_speed = 230400;
+				state->tty->alt_speed = 230400;
 			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-				info->tty->alt_speed = 460800;
-			change_speed(info, NULL);
+				state->tty->alt_speed = 460800;
+			change_speed(state, NULL);
 		}
 	} else
-		retval = startup(info);
+		retval = startup(state);
 	tty_unlock();
 	return retval;
 }
@@ -1128,7 +1122,7 @@
  * 	    transmit holding register is empty.  This functionality
  * 	    allows an RS485 driver to be written in user space. 
  */
-static int get_lsr_info(struct async_struct * info, unsigned int __user *value)
+static int get_lsr_info(struct serial_state *info, unsigned int __user *value)
 {
 	unsigned char status;
 	unsigned int result;
@@ -1147,7 +1141,7 @@
 
 static int rs_tiocmget(struct tty_struct *tty)
 {
-	struct async_struct * info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned char control, status;
 	unsigned long flags;
 
@@ -1170,7 +1164,7 @@
 static int rs_tiocmset(struct tty_struct *tty, unsigned int set,
 						unsigned int clear)
 {
-	struct async_struct * info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
@@ -1197,7 +1191,7 @@
  */
 static int rs_break(struct tty_struct *tty, int break_state)
 {
-	struct async_struct * info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->name, "rs_break"))
@@ -1222,12 +1216,12 @@
 static int rs_get_icount(struct tty_struct *tty,
 				struct serial_icounter_struct *icount)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	struct async_icount cnow;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	cnow = info->state->icount;
+	cnow = info->icount;
 	local_irq_restore(flags);
 	icount->cts = cnow.cts;
 	icount->dsr = cnow.dsr;
@@ -1247,7 +1241,7 @@
 static int rs_ioctl(struct tty_struct *tty,
 		    unsigned int cmd, unsigned long arg)
 {
-	struct async_struct * info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	struct async_icount cprev, cnow;	/* kernel counter temps */
 	void __user *argp = (void __user *)arg;
 	unsigned long flags;
@@ -1275,7 +1269,7 @@
 
 		case TIOCSERGSTRUCT:
 			if (copy_to_user(argp,
-					 info, sizeof(struct async_struct)))
+					 info, sizeof(struct serial_state)))
 				return -EFAULT;
 			return 0;
 
@@ -1288,7 +1282,7 @@
 		case TIOCMIWAIT:
 			local_irq_save(flags);
 			/* note the counters on entry */
-			cprev = info->state->icount;
+			cprev = info->icount;
 			local_irq_restore(flags);
 			while (1) {
 				interruptible_sleep_on(&info->delta_msr_wait);
@@ -1296,7 +1290,7 @@
 				if (signal_pending(current))
 					return -ERESTARTSYS;
 				local_irq_save(flags);
-				cnow = info->state->icount; /* atomic copy */
+				cnow = info->icount; /* atomic copy */
 				local_irq_restore(flags);
 				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
 				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -1325,7 +1319,7 @@
 
 static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
-	struct async_struct *info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
 	unsigned int cflag = tty->termios->c_cflag;
 
@@ -1385,15 +1379,12 @@
  */
 static void rs_close(struct tty_struct *tty, struct file * filp)
 {
-	struct async_struct * info = tty->driver_data;
-	struct serial_state *state;
+	struct serial_state *state = tty->driver_data;
 	unsigned long flags;
 
-	if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
+	if (!state || serial_paranoia_check(state, tty->name, "rs_close"))
 		return;
 
-	state = info->state;
-
 	local_irq_save(flags);
 
 	if (tty_hung_up_p(filp)) {
@@ -1403,7 +1394,7 @@
 	}
 
 #ifdef SERIAL_DEBUG_OPEN
-	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+	printk("rs_close ttys%d, count = %d\n", state->line, state->count);
 #endif
 	if ((tty->count == 1) && (state->count != 1)) {
 		/*
@@ -1441,7 +1432,7 @@
 	 * interrupt driver to stop checking the data ready bit in the
 	 * line status register.
 	 */
-	info->read_status_mask &= ~UART_LSR_DR;
+	state->read_status_mask &= ~UART_LSR_DR;
 	if (state->flags & ASYNC_INITIALIZED) {
 	        /* disable receive interrupts */
 	        custom.intena = IF_RBF;
@@ -1455,22 +1446,22 @@
 		 * has completely drained; this is especially
 		 * important if there is a transmit FIFO!
 		 */
-		rs_wait_until_sent(tty, info->timeout);
+		rs_wait_until_sent(tty, state->timeout);
 	}
-	shutdown(info);
+	shutdown(state);
 	rs_flush_buffer(tty);
 		
 	tty_ldisc_flush(tty);
 	tty->closing = 0;
-	info->tty = NULL;
-	if (info->blocked_open) {
+	state->tty = NULL;
+	if (state->blocked_open) {
 		if (state->close_delay) {
 			msleep_interruptible(jiffies_to_msecs(state->close_delay));
 		}
-		wake_up_interruptible(&info->open_wait);
+		wake_up_interruptible(&state->open_wait);
 	}
 	state->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-	wake_up_interruptible(&info->close_wait);
+	wake_up_interruptible(&state->close_wait);
 	local_irq_restore(flags);
 }
 
@@ -1479,14 +1470,14 @@
  */
 static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
 {
-	struct async_struct * info = tty->driver_data;
+	struct serial_state *info = tty->driver_data;
 	unsigned long orig_jiffies, char_time;
 	int lsr;
 
 	if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
 		return;
 
-	if (info->state->xmit_fifo_size == 0)
+	if (info->xmit_fifo_size == 0)
 		return; /* Just in case.... */
 
 	orig_jiffies = jiffies;
@@ -1499,7 +1490,7 @@
 	 * Note: we have to use pretty tight timings here to satisfy
 	 * the NIST-PCTS.
 	 */
-	char_time = (info->timeout - HZ/50) / info->state->xmit_fifo_size;
+	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
 	char_time = char_time / 5;
 	if (char_time == 0)
 		char_time = 1;
@@ -1542,18 +1533,15 @@
  */
 static void rs_hangup(struct tty_struct *tty)
 {
-	struct async_struct * info = tty->driver_data;
-	struct serial_state *state = info->state;
+	struct serial_state *info = tty->driver_data;
 
 	if (serial_paranoia_check(info, tty->name, "rs_hangup"))
 		return;
 
-	state = info->state;
-
 	rs_flush_buffer(tty);
 	shutdown(info);
-	state->count = 0;
-	state->flags &= ~ASYNC_NORMAL_ACTIVE;
+	info->count = 0;
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1564,14 +1552,13 @@
  * ------------------------------------------------------------
  */
 static int block_til_ready(struct tty_struct *tty, struct file * filp,
-			   struct async_struct *info)
+			   struct serial_state *info)
 {
 #ifdef DECLARE_WAITQUEUE
 	DECLARE_WAITQUEUE(wait, current);
 #else
 	struct wait_queue wait = { current, NULL };
 #endif
-	struct serial_state *state = info->state;
 	int		retval;
 	int		do_clocal = 0, extra_count = 0;
 	unsigned long	flags;
@@ -1581,11 +1568,11 @@
 	 * until it's done, and then try again.
 	 */
 	if (tty_hung_up_p(filp) ||
-	    (state->flags & ASYNC_CLOSING)) {
-		if (state->flags & ASYNC_CLOSING)
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
 			interruptible_sleep_on(&info->close_wait);
 #ifdef SERIAL_DO_RESTART
-		return ((state->flags & ASYNC_HUP_NOTIFY) ?
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
 			-EAGAIN : -ERESTARTSYS);
 #else
 		return -EAGAIN;
@@ -1598,7 +1585,7 @@
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		state->flags |= ASYNC_NORMAL_ACTIVE;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
@@ -1608,7 +1595,7 @@
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, state->count is dropped by one, so that
+	 * this loop, info->count is dropped by one, so that
 	 * rs_close() knows when to free things.  We restore it upon
 	 * exit, either normal or abnormal.
 	 */
@@ -1616,12 +1603,12 @@
 	add_wait_queue(&info->open_wait, &wait);
 #ifdef SERIAL_DEBUG_OPEN
 	printk("block_til_ready before block: ttys%d, count = %d\n",
-	       state->line, state->count);
+	       info->line, info->count);
 #endif
 	local_irq_save(flags);
 	if (!tty_hung_up_p(filp)) {
 		extra_count = 1;
-		state->count--;
+		info->count--;
 	}
 	local_irq_restore(flags);
 	info->blocked_open++;
@@ -1632,9 +1619,9 @@
 		local_irq_restore(flags);
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
-		    !(state->flags & ASYNC_INITIALIZED)) {
+		    !(info->flags & ASYNC_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
-			if (state->flags & ASYNC_HUP_NOTIFY)
+			if (info->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
 				retval = -ERESTARTSYS;
@@ -1643,7 +1630,7 @@
 #endif
 			break;
 		}
-		if (!(state->flags & ASYNC_CLOSING) &&
+		if (!(info->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (!(ciab.pra & SER_DCD)) ))
 			break;
 		if (signal_pending(current)) {
@@ -1652,7 +1639,7 @@
 		}
 #ifdef SERIAL_DEBUG_OPEN
 		printk("block_til_ready blocking: ttys%d, count = %d\n",
-		       info->line, state->count);
+		       info->line, info->count);
 #endif
 		tty_unlock();
 		schedule();
@@ -1661,46 +1648,15 @@
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(&info->open_wait, &wait);
 	if (extra_count)
-		state->count++;
+		info->count++;
 	info->blocked_open--;
 #ifdef SERIAL_DEBUG_OPEN
 	printk("block_til_ready after blocking: ttys%d, count = %d\n",
-	       info->line, state->count);
+	       info->line, info->count);
 #endif
 	if (retval)
 		return retval;
-	state->flags |= ASYNC_NORMAL_ACTIVE;
-	return 0;
-}
-
-static int get_async_struct(int line, struct async_struct **ret_info)
-{
-	struct async_struct *info;
-	struct serial_state *sstate;
-
-	sstate = rs_table + line;
-	sstate->count++;
-	if (sstate->info) {
-		*ret_info = sstate->info;
-		return 0;
-	}
-	info = kzalloc(sizeof(struct async_struct), GFP_KERNEL);
-	if (!info) {
-		sstate->count--;
-		return -ENOMEM;
-	}
-#ifdef DECLARE_WAITQUEUE
-	init_waitqueue_head(&info->open_wait);
-	init_waitqueue_head(&info->close_wait);
-	init_waitqueue_head(&info->delta_msr_wait);
-#endif
-	info->state = sstate;
-	if (sstate->info) {
-		kfree(info);
-		*ret_info = sstate->info;
-		return 0;
-	}
-	*ret_info = sstate->info = info;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
 	return 0;
 }
 
@@ -1712,32 +1668,29 @@
  */
 static int rs_open(struct tty_struct *tty, struct file * filp)
 {
-	struct async_struct	*info;
+	struct serial_state *info = rs_table + tty->index;
 	int retval;
 
-	retval = get_async_struct(tty->index, &info);
-	if (retval) {
-		return retval;
-	}
-	tty->driver_data = info;
+	info->count++;
 	info->tty = tty;
+	tty->driver_data = info;
 	if (serial_paranoia_check(info, tty->name, "rs_open"))
 		return -ENODEV;
 
 #ifdef SERIAL_DEBUG_OPEN
-	printk("rs_open %s, count = %d\n", tty->name, info->state->count);
+	printk("rs_open %s, count = %d\n", tty->name, info->count);
 #endif
-	info->tty->low_latency = (info->state->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+	tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
 	/*
 	 * If the port is the middle of closing, bail out now
 	 */
 	if (tty_hung_up_p(filp) ||
-	    (info->state->flags & ASYNC_CLOSING)) {
-		if (info->state->flags & ASYNC_CLOSING)
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
 			interruptible_sleep_on(&info->close_wait);
 #ifdef SERIAL_DO_RESTART
-		return ((info->state->flags & ASYNC_HUP_NOTIFY) ?
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
 			-EAGAIN : -ERESTARTSYS);
 #else
 		return -EAGAIN;
@@ -1773,24 +1726,14 @@
 
 static inline void line_info(struct seq_file *m, struct serial_state *state)
 {
-	struct async_struct *info = state->info, scr_info;
 	char	stat_buf[30], control, status;
 	unsigned long flags;
 
 	seq_printf(m, "%d: uart:amiga_builtin",state->line);
 
-	/*
-	 * Figure out the current RS-232 lines
-	 */
-	if (!info) {
-		info = &scr_info;	/* This is just for serial_{in,out} */
-
-		info->quot = 0;
-		info->tty = NULL;
-	}
 	local_irq_save(flags);
 	status = ciab.pra;
-	control = info ? info->MCR : status;
+	control = (state->flags & ASYNC_INITIALIZED) ? state->MCR : status;
 	local_irq_restore(flags);
 
 	stat_buf[0] = 0;
@@ -1806,9 +1749,8 @@
 	if(!(status & SER_DCD))
 		strcat(stat_buf, "|CD");
 
-	if (info->quot) {
-		seq_printf(m, " baud:%d", state->baud_base / info->quot);
-	}
+	if (state->quot)
+		seq_printf(m, " baud:%d", state->baud_base / state->quot);
 
 	seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx);
 
@@ -1938,6 +1880,9 @@
 	state->icount.rx = state->icount.tx = 0;
 	state->icount.frame = state->icount.parity = 0;
 	state->icount.overrun = state->icount.brk = 0;
+	init_waitqueue_head(&state->open_wait);
+	init_waitqueue_head(&state->close_wait);
+	init_waitqueue_head(&state->delta_msr_wait);
 
 	printk(KERN_INFO "ttyS%d is the amiga builtin serial port\n",
 		       state->line);
@@ -1993,7 +1938,6 @@
 {
 	int error;
 	struct serial_state *state = platform_get_drvdata(pdev);
-	struct async_struct *info = state->info;
 
 	/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
 	if ((error = tty_unregister_driver(serial_driver)))
@@ -2001,11 +1945,8 @@
 		       error);
 	put_tty_driver(serial_driver);
 
-	rs_table[0].info = NULL;
-	kfree(info);
-
-	free_irq(IRQ_AMIGA_TBE, rs_table);
-	free_irq(IRQ_AMIGA_RBF, rs_table);
+	free_irq(IRQ_AMIGA_TBE, state);
+	free_irq(IRQ_AMIGA_RBF, state);
 
 	platform_set_drvdata(pdev, NULL);