Module Name:    src
Committed By:   skrll
Date:           Wed Jul 25 07:26:18 UTC 2012

Modified Files:
        src/sys/arch/evbarm/dev: plcom.c plcomreg.h plcomvar.h
        src/sys/arch/evbarm/ifpga: ifpgareg.h plcom_ifpga.c
        src/sys/arch/evbarm/integrator: integrator_machdep.c

Log Message:
Add support for the PL011 to plcom. Pull across a bunch of fixes from
com(4) while I'm here and do some other tidyup.

Tested on a RaspberryPi.

PL010 not tested.


To generate a diff of this commit:
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/evbarm/dev/plcom.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/evbarm/dev/plcomreg.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/evbarm/dev/plcomvar.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/evbarm/ifpga/ifpgareg.h
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/evbarm/ifpga/plcom_ifpga.c
cvs rdiff -u -r1.68 -r1.69 \
    src/sys/arch/evbarm/integrator/integrator_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/evbarm/dev/plcom.c
diff -u src/sys/arch/evbarm/dev/plcom.c:1.39 src/sys/arch/evbarm/dev/plcom.c:1.40
--- src/sys/arch/evbarm/dev/plcom.c:1.39	Thu Jul  5 10:56:52 2012
+++ src/sys/arch/evbarm/dev/plcom.c	Wed Jul 25 07:26:17 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: plcom.c,v 1.39 2012/07/05 10:56:52 skrll Exp $	*/
+/*	$NetBSD: plcom.c,v 1.40 2012/07/25 07:26:17 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2001 ARM Ltd
@@ -28,11 +28,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 1999, 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
- * by Charles M. Hannum.
+ * by Charles M. Hannum and Nick Hudson.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -88,13 +88,13 @@
  */
 
 /*
- * COM driver for the Prime Cell PL010 UART, which is similar to the 16C550,
- * but has a completely different programmer's model.
+ * COM driver for the Prime Cell PL010 and PL011 UARTs. Both are is similar to
+ * the 16C550, but have a completely different programmer's model.
  * Derived from the NS16550AF com driver.
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.39 2012/07/05 10:56:52 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.40 2012/07/25 07:26:17 skrll Exp $");
 
 #include "opt_plcom.h"
 #include "opt_ddb.h"
@@ -103,9 +103,6 @@ __KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.
 #include "opt_multiprocessor.h"
 
 #include "rnd.h"
-#ifdef RND_COM
-#include <sys/rnd.h>
-#endif
 
 /*
  * Override cnmagic(9) macro before including <sys/systm.h>.
@@ -138,6 +135,9 @@ __KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.
 #include <sys/kauth.h>
 #include <sys/intr.h>
 #include <sys/bus.h>
+#ifdef RND_COM
+#include <sys/rnd.h>
+#endif
 
 #include <evbarm/dev/plcomreg.h>
 #include <evbarm/dev/plcomvar.h>
@@ -148,7 +148,8 @@ static void plcom_enable_debugport (stru
 
 void	plcom_config	(struct plcom_softc *);
 void	plcom_shutdown	(struct plcom_softc *);
-int	plcomspeed	(long, long);
+int	pl010comspeed	(long, long);
+int	pl011comspeed	(long, long);
 static	u_char	cflag2lcr (tcflag_t);
 int	plcomparam	(struct tty *, struct termios *);
 void	plcomstart	(struct tty *);
@@ -162,11 +163,10 @@ void	tiocm_to_plcom	(struct plcom_softc 
 int	plcom_to_tiocm	(struct plcom_softc *);
 void	plcom_iflush	(struct plcom_softc *);
 
-int	plcom_common_getc (dev_t, bus_space_tag_t, bus_space_handle_t);
-void	plcom_common_putc (dev_t, bus_space_tag_t, bus_space_handle_t, int);
+int	plcom_common_getc (dev_t, struct plcom_instance *);
+void	plcom_common_putc (dev_t, struct plcom_instance *, int);
 
-int	plcominit	(bus_space_tag_t, bus_addr_t, int, int, tcflag_t,
-			    bus_space_handle_t *);
+int	plcominit	(struct plcom_instance *, int, int, tcflag_t);
 
 dev_type_open(plcomopen);
 dev_type_close(plcomclose);
@@ -189,6 +189,8 @@ integrate void plcom_stsoft	(struct plco
 integrate void plcom_schedrx	(struct plcom_softc *);
 void	plcomdiag		(void *);
 
+bool	plcom_intstatus(struct plcom_instance *, u_int *);
+
 extern struct cfdriver plcom_cd;
 
 const struct cdevsw plcom_cdevsw = {
@@ -207,9 +209,9 @@ u_int plcom_rbuf_hiwat = (PLCOM_RING_SIZ
 u_int plcom_rbuf_lowat = (PLCOM_RING_SIZE * 3) / 4;
 
 static int	plcomconsunit = -1;
-static bus_space_tag_t plcomconstag;
-static bus_space_handle_t plcomconsioh;
-static int	plcomconsattached;
+static struct plcom_instance plcomcons_info;
+
+static int plcomconsattached;
 static int plcomconsrate;
 static tcflag_t plcomconscflag;
 static struct cnm_state plcom_cnm_state;
@@ -226,16 +228,14 @@ static int ppscap =
 #ifdef KGDB
 #include <sys/kgdb.h>
 
-static int plcom_kgdb_unit;
-static bus_space_tag_t plcom_kgdb_iot;
-static bus_space_handle_t plcom_kgdb_ioh;
+static struct plcom_instance plcomkgdb_info;
 static int plcom_kgdb_attached;
 
 int	plcom_kgdb_getc (void *);
 void	plcom_kgdb_putc (void *, int);
 #endif /* KGDB */
 
-#define	PLCOMUNIT_MASK	0x7ffff
+#define	PLCOMUNIT_MASK		0x7ffff
 #define	PLCOMDIALOUT_MASK	0x80000
 
 #define	PLCOMUNIT(x)	(minor(x) & PLCOMUNIT_MASK)
@@ -246,10 +246,58 @@ void	plcom_kgdb_putc (void *, int);
 
 #define	BR	BUS_SPACE_BARRIER_READ
 #define	BW	BUS_SPACE_BARRIER_WRITE
-#define PLCOM_BARRIER(t, h, f) bus_space_barrier((t), (h), 0, PLCOM_UART_SIZE, (f))
+#define PLCOM_BARRIER(pi, f)	\
+    bus_space_barrier((pi)->pi_iot, (pi)->pi_ioh, 0, (pi)->pi_size, (f))
+
+static uint8_t
+pread1(struct plcom_instance *pi, bus_size_t reg)
+{
+	if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS))
+		return bus_space_read_1(pi->pi_iot, pi->pi_ioh, reg);
+
+	return bus_space_read_4(pi->pi_iot, pi->pi_ioh, reg & -4) >>
+	    (8 * (reg & 3));
+}
+int nhcr;
+static void
+pwrite1(struct plcom_instance *pi, bus_size_t o, uint8_t val)
+{
+	if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) {
+		bus_space_write_1(pi->pi_iot, pi->pi_ioh, o, val);
+	} else {
+		const size_t shift = 8 * (o & 3);
+		o &= -4;
+		uint32_t tmp = bus_space_read_4(pi->pi_iot, pi->pi_ioh, o);
+		tmp = (val << shift) | (tmp & ~(0xff << shift));
+		bus_space_write_4(pi->pi_iot, pi->pi_ioh, o, tmp);
+	}
+}
+
+static void
+pwritem1(struct plcom_instance *pi, bus_size_t o, const uint8_t *datap,
+    bus_size_t count)
+{
+	if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) {
+		bus_space_write_multi_1(pi->pi_iot, pi->pi_ioh, o, datap, count);
+	} else {
+		KASSERT((o & 3) == 0);
+		while (count--) {
+			bus_space_write_4(pi->pi_iot, pi->pi_ioh, o, *datap++);
+		};
+	}
+}
+
+#define	PREAD1(pi, reg)		pread1(pi, reg)
+#define	PREAD4(pi, reg)		\
+	(bus_space_read_4((pi)->pi_iot, (pi)->pi_ioh, (reg)))
+
+#define	PWRITE1(pi, reg, val)	pwrite1(pi, reg, val)
+#define	PWRITEM1(pi, reg, d, c)	pwritem1(pi, reg, d, c)
+#define	PWRITE4(pi, reg, val)	\
+	(bus_space_write_4((pi)->pi_iot, (pi)->pi_ioh, (reg), (val)))
 
 int
-plcomspeed(long speed, long frequency)
+pl010comspeed(long speed, long frequency)
 {
 #define	divrnd(n, q)	(((n)*2/(q)+1)/2)	/* divide and round off */
 
@@ -274,6 +322,20 @@ plcomspeed(long speed, long frequency)
 #undef	divrnd
 }
 
+int
+pl011comspeed(long speed, long frequency)
+{
+	int denom = 16 * speed;
+	int div = frequency / denom;
+	int rem = frequency % denom;
+	
+	int ibrd = div << 6;
+	int fbrd = (((8 * rem) / speed) + 1) / 2;
+	
+	/* Tolerance? */
+	return ibrd | fbrd;
+}
+
 #ifdef PLCOM_DEBUG
 int	plcom_debug = 0;
 
@@ -301,7 +363,7 @@ plcomstatus(struct plcom_softc *sc, cons
 }
 #endif
 
-/* XXX this function is not used? */
+#if 0
 int
 plcomprobe1(bus_space_tag_t iot, bus_space_handle_t ioh)
 {
@@ -327,6 +389,7 @@ plcomprobe1(bus_space_tag_t iot, bus_spa
 
 	return 1;
 }
+#endif
 
 /*
  * No locking in this routine; it is only called during attach,
@@ -335,55 +398,106 @@ plcomprobe1(bus_space_tag_t iot, bus_spa
 static void
 plcom_enable_debugport(struct plcom_softc *sc)
 {
+	struct plcom_instance *pi = &sc->sc_pi;
 
-	/* Turn on line break interrupt, set carrier. */
-	sc->sc_cr = PL010_CR_RIE | PL010_CR_RTIE | PL01X_CR_UARTEN;
-	bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
+	sc->sc_cr = PL01X_CR_UARTEN;
 	SET(sc->sc_mcr, PL01X_MCR_DTR | PL01X_MCR_RTS);
-	/* XXX device_unit() abuse */
-	sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(sc->sc_dev),
-	    sc->sc_mcr);
+
+	/* Turn on line break interrupt, set carrier. */
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE);
+		PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+		if (sc->sc_set_mcr) {
+			/* XXX device_unit() abuse */
+			sc->sc_set_mcr(sc->sc_set_mcr_arg,
+			    device_unit(sc->sc_dev), sc->sc_mcr);
+		}
+		break;
+	case PLCOM_TYPE_PL011:
+		sc->sc_imsc = PL011_INT_RX | PL011_INT_RT;
+		SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE);
+		SET(sc->sc_cr, PL011_MCR(sc->sc_mcr));
+		PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+		PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+		break;
+	}
+
 }
 
 void
 plcom_attach_subr(struct plcom_softc *sc)
 {
-	int unit = sc->sc_iounit;
-	bus_space_tag_t iot = sc->sc_iot;
-	bus_space_handle_t ioh = sc->sc_ioh;
+	struct plcom_instance *pi = &sc->sc_pi;
 	struct tty *tp;
 
+	aprint_naive("\n");
+
 	callout_init(&sc->sc_diag_callout, 0);
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
 
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+	case PLCOM_TYPE_PL011:
+		break;
+	default:
+		aprint_error_dev(sc->sc_dev,
+		    "Unknown plcom type: %d\n", pi->pi_type);
+		return;
+	}
+
 	/* Disable interrupts before configuring the device. */
 	sc->sc_cr = 0;
+	sc->sc_imsc = 0;
 
-	if (plcomconstag && unit == plcomconsunit) {
+	if (bus_space_is_equal(pi->pi_iot, plcomcons_info.pi_iot) &&
+	    pi->pi_iobase == plcomcons_info.pi_iobase) {
 		plcomconsattached = 1;
 
-		plcomconstag = iot;
-		plcomconsioh = ioh;
-
 		/* Make sure the console is always "hardwired". */
 		delay(1000);			/* wait for output to finish */
 		SET(sc->sc_hwflags, PLCOM_HW_CONSOLE);
 		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
-		/* Must re-enable the console immediately, or we will
-		   hang when trying to print.  */
+		/*
+		 * Must re-enable the console immediately, or we will
+		 * hang when trying to print.
+		 */
 		sc->sc_cr = PL01X_CR_UARTEN;
+		if (pi->pi_type == PLCOM_TYPE_PL011) 
+			SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE);
 	}
 
-	bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
-
-	/* The PL010 has a 16-byte fifo, but the tx interrupt triggers when
-	   there is space for 8 more bytes.  */
-	sc->sc_fifolen = 8;
-	printf("\n");
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+		break;
+		
+	case PLCOM_TYPE_PL011:
+		PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+		PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+		break;
+	}		
+
+	if (sc->sc_fifolen == 0) {
+		switch (pi->pi_type) {
+		case PLCOM_TYPE_PL010:
+			/*
+			 * The PL010 has a 16-byte fifo, but the tx interrupt
+			 * triggers when there is space for 8 more bytes.
+			*/
+			sc->sc_fifolen = 8;
+			break;
+		case PLCOM_TYPE_PL011:
+			/* Some revisions have a 32 byte TX FIFO */
+			sc->sc_fifolen = 16;
+			break;
+		}
+	}
+	aprint_normal("\n");
 
 	if (ISSET(sc->sc_hwflags, PLCOM_HW_TXFIFO_DISABLE)) {
 		sc->sc_fifolen = 1;
-		printf("%s: txfifo disabled\n", device_xname(sc->sc_dev));
+		aprint_normal_dev(sc->sc_dev, "txfifo disabled\n");
 	}
 
 	if (sc->sc_fifolen > 1)
@@ -399,8 +513,8 @@ plcom_attach_subr(struct plcom_softc *sc
 	sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
 	sc->sc_rbavail = plcom_rbuf_size;
 	if (sc->sc_rbuf == NULL) {
-		printf("%s: unable to allocate ring buffer\n",
-		    device_xname(sc->sc_dev));
+		aprint_error_dev(sc->sc_dev,
+		    "unable to allocate ring buffer\n");		
 		return;
 	}
 	sc->sc_ebuf = sc->sc_rbuf + (plcom_rbuf_size << 1);
@@ -413,9 +527,9 @@ plcom_attach_subr(struct plcom_softc *sc
 		/* locate the major number */
 		maj = cdevsw_lookup_major(&plcom_cdevsw);
 
-		cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));
+		tp->t_dev = cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));
 
-		printf("%s: console\n", device_xname(sc->sc_dev));
+		aprint_normal_dev(sc->sc_dev, "console\n");
 	}
 
 #ifdef KGDB
@@ -423,23 +537,28 @@ plcom_attach_subr(struct plcom_softc *sc
 	 * Allow kgdb to "take over" this port.  If this is
 	 * the kgdb device, it has exclusive use.
 	 */
-	if (iot == plcom_kgdb_iot && unit == plcom_kgdb_unit) {
-		plcom_kgdb_attached = 1;
+	if (bus_space_is_equal(iot, plcomkgdb_info.pi_iot) &&
+	    pi->pi_iobase == plcomkgdb_info.pi_iobase) {
+		if (!ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) {
+			plcom_kgdb_attached = 1;
 
-		SET(sc->sc_hwflags, PLCOM_HW_KGDB);
-		printf("%s: kgdb\n", device_xname(sc->sc_dev));
+			SET(sc->sc_hwflags, PLCOM_HW_KGDB);
+		}
+		aprint_normal_dev(sc->sc_dev, "kgdb\n");
 	}
 #endif
 
 	sc->sc_si = softint_establish(SOFTINT_SERIAL, plcomsoft, sc);
 
 #ifdef RND_COM
-	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev)),
-			  RND_TYPE_TTY, 0);
+	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
+	    RND_TYPE_TTY, 0);
 #endif
 
-	/* if there are no enable/disable functions, assume the device
-	   is always enabled */
+	/*
+	 * if there are no enable/disable functions, assume the device
+	 * is always enabled
+	 */
 	if (!sc->enable)
 		sc->enabled = 1;
 
@@ -451,12 +570,21 @@ plcom_attach_subr(struct plcom_softc *sc
 void
 plcom_config(struct plcom_softc *sc)
 {
-	bus_space_tag_t iot = sc->sc_iot;
-	bus_space_handle_t ioh = sc->sc_ioh;
+	struct plcom_instance *pi = &sc->sc_pi;
 
 	/* Disable interrupts before configuring the device. */
 	sc->sc_cr = 0;
-	bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
+	sc->sc_imsc = 0;
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+		break;
+		
+	case PLCOM_TYPE_PL011:
+		PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+		PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+		break;
+	}		
 
 	if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE|PLCOM_HW_KGDB))
 		plcom_enable_debugport(sc);
@@ -486,6 +614,15 @@ plcom_detach(device_t self, int flags)
 	mn |= PLCOMDIALOUT_MASK;
 	vdevgone(maj, mn, mn, VCHR);
 
+	if (sc->sc_rbuf == NULL) {
+		/*
+		 * Ring buffer allocation failed in the plcom_attach_subr,
+		 * only the tty is allocated, and nothing else.
+		 */         
+		tty_free(sc->sc_tty);
+		return 0;
+	}
+
 	/* Free the receive buffer. */
 	free(sc->sc_rbuf, M_DEVBUF);
 
@@ -500,6 +637,7 @@ plcom_detach(device_t self, int flags)
 	/* Unhook the entropy source. */
 	rnd_detach_source(&sc->rnd_source);
 #endif
+	callout_destroy(&sc->sc_diag_callout);
 
 	/* Destroy the lock. */
 	mutex_destroy(&sc->sc_lock);
@@ -524,6 +662,7 @@ plcom_activate(device_t self, enum devac
 void
 plcom_shutdown(struct plcom_softc *sc)
 {
+	struct plcom_instance *pi = &sc->sc_pi;
 	struct tty *tp = sc->sc_tty;
 	mutex_spin_enter(&sc->sc_lock);
 
@@ -553,13 +692,36 @@ plcom_shutdown(struct plcom_softc *sc)
 		mutex_spin_enter(&sc->sc_lock);
 	}
 
+	sc->sc_cr = 0;
+	sc->sc_imsc = 0;
 	/* Turn off interrupts. */
-	if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE))
+	if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) {
 		/* interrupt on break */
-		sc->sc_cr = PL010_CR_RIE | PL010_CR_RTIE | PL01X_CR_UARTEN;
-	else
-		sc->sc_cr = 0;
-	bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
+	
+		sc->sc_cr = PL01X_CR_UARTEN;
+		sc->sc_imsc = 0;
+		switch (pi->pi_type) {
+		case PLCOM_TYPE_PL010:
+			SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE);
+			break;
+		case PLCOM_TYPE_PL011:
+			SET(sc->sc_cr, PL011_CR_RXE);
+			SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX);
+			break;
+		}
+	}
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE);
+		PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+		break;
+	case PLCOM_TYPE_PL011:
+		SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE);
+		SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX);
+		PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+		PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+		break;
+	}
 
 	mutex_spin_exit(&sc->sc_lock);
 	if (sc->disable) {
@@ -576,6 +738,7 @@ int
 plcomopen(dev_t dev, int flag, int mode, struct lwp *l)
 {
 	struct plcom_softc *sc;
+	struct plcom_instance *pi;
 	struct tty *tp;
 	int s;
 	int error;
@@ -588,6 +751,8 @@ plcomopen(dev_t dev, int flag, int mode,
 	if (!device_is_active(sc->sc_dev))
 		return ENXIO;
 
+	pi = &sc->sc_pi;
+
 #ifdef KGDB
 	/*
 	 * If this is the kgdb port, no other use is permitted.
@@ -614,8 +779,8 @@ plcomopen(dev_t dev, int flag, int mode,
 		if (sc->enable) {
 			if ((*sc->enable)(sc)) {
 				splx(s);
-				printf("%s: device enable failed\n",
-				       device_xname(sc->sc_dev));
+				aprint_error_dev(sc->sc_dev,
+				    "device enable failed\n");
 				return EIO;
 			}
 			mutex_spin_enter(&sc->sc_lock);
@@ -627,11 +792,23 @@ plcomopen(dev_t dev, int flag, int mode,
 
 		/* Turn on interrupts. */
 		/* IER_ERXRDY | IER_ERLS | IER_EMSC;  */
-		sc->sc_cr = PL010_CR_RIE | PL010_CR_RTIE | PL010_CR_MSIE | PL01X_CR_UARTEN;
-		bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
-
 		/* Fetch the current modem control status, needed later. */
-		sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, plcom_fr);
+		sc->sc_cr = PL01X_CR_UARTEN;
+		switch (pi->pi_type) {
+		case PLCOM_TYPE_PL010:
+			SET(sc->sc_cr,
+			    PL010_CR_RIE | PL010_CR_RTIE | PL010_CR_MSIE);
+			PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+			sc->sc_msr = PREAD1(pi, PL01XCOM_FR);
+			break;
+		case PLCOM_TYPE_PL011:
+			SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE);
+			SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX |
+			    PL011_INT_MSMASK);
+			PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+			sc->sc_msr = PREAD4(pi, PL01XCOM_FR);
+			break;
+		}
 
 		/* Clear PPS capture state on first open. */
 
@@ -646,7 +823,6 @@ plcomopen(dev_t dev, int flag, int mode,
 		 * Initialize the termios status to the defaults.  Add in the
 		 * sticky bits from TIOCSFLAGS.
 		 */
-		t.c_ispeed = 0;
 		if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) {
 			t.c_ospeed = plcomconsrate;
 			t.c_cflag = plcomconscflag;
@@ -654,6 +830,8 @@ plcomopen(dev_t dev, int flag, int mode,
 			t.c_ospeed = TTYDEF_SPEED;
 			t.c_cflag = TTYDEF_CFLAG;
 		}
+		t.c_ispeed = t.c_ospeed;
+
 		if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
 			SET(t.c_cflag, CLOCAL);
 		if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
@@ -802,12 +980,16 @@ plcomioctl(dev_t dev, u_long cmd, void *
 {
 	struct plcom_softc *sc =
 		device_lookup_private(&plcom_cd, PLCOMUNIT(dev));
-	struct tty *tp = sc->sc_tty;
+	struct tty *tp;
 	int error;
 
+	if (sc == NULL)
+		return ENXIO;
 	if (PLCOM_ISALIVE(sc) == 0)
 		return EIO;
 
+	tp = sc->sc_tty;
+
 	error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l);
 	if (error != EPASSTHROUGH)
 		return error;
@@ -817,6 +999,18 @@ plcomioctl(dev_t dev, u_long cmd, void *
 		return error;
 
 	error = 0;
+	switch (cmd) {
+	case TIOCSFLAGS:
+		error = kauth_authorize_device_tty(l->l_cred,
+		    KAUTH_DEVICE_TTY_PRIVSET, tp);
+		break;
+	default:
+		/* nothing */
+		break;
+	}
+	if (error) {
+		return error;
+	}
 
 	mutex_spin_enter(&sc->sc_lock);
 	switch (cmd) {
@@ -841,10 +1035,6 @@ plcomioctl(dev_t dev, u_long cmd, void *
 		break;
 
 	case TIOCSFLAGS:
-		error = kauth_authorize_device_tty(l->l_cred,
-		    KAUTH_DEVICE_TTY_PRIVSET, tp);
-		if (error)
-			break;
 		sc->sc_swflags = *(int *)data;
 		break;
 
@@ -1085,6 +1275,8 @@ plcom_to_tiocm(struct plcom_softc *sc)
 		SET(ttybits, TIOCM_CTS);
 	if (ISSET(plcombits, PL01X_MSR_DSR))
 		SET(ttybits, TIOCM_DSR);
+	if (ISSET(plcombits, PL011_MSR_RI))
+		SET(ttybits, TIOCM_RI);
 
 	if (sc->sc_cr != 0)
 		SET(ttybits, TIOCM_LE);
@@ -1127,13 +1319,21 @@ plcomparam(struct tty *tp, struct termio
 {
 	struct plcom_softc *sc =
 		device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev));
-	int ospeed;
+	struct plcom_instance *pi = &sc->sc_pi;
+	int ospeed = -1;
 	u_char lcr;
 
 	if (PLCOM_ISALIVE(sc) == 0)
 		return EIO;
 
-	ospeed = plcomspeed(t->c_ospeed, sc->sc_frequency);
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		ospeed = pl010comspeed(t->c_ospeed, sc->sc_frequency);
+		break;
+	case PLCOM_TYPE_PL011:
+		ospeed = pl011comspeed(t->c_ospeed, sc->sc_frequency);
+		break;
+	}
 
 	/* Check requested parameters. */
 	if (ospeed < 0)
@@ -1224,11 +1424,19 @@ plcomparam(struct tty *tp, struct termio
 		SET(sc->sc_mcr, sc->sc_mcr_dtr);
 #endif
 
-	sc->sc_dlbl = ospeed;
-	sc->sc_dlbh = ospeed >> 8;
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		sc->sc_ratel = ospeed & 0xff;
+		sc->sc_rateh = (ospeed >> 8) & 0xff;
+		break;
+	case PLCOM_TYPE_PL011:
+		sc->sc_ratel = ospeed & ((1 << 6) - 1);
+		sc->sc_rateh = ospeed >> 6;
+		break;
+	}
 
 	/* And copy to tty. */
-	tp->t_ispeed = 0;
+	tp->t_ispeed = t->c_ospeed;
 	tp->t_ospeed = t->c_ospeed;
 	tp->t_cflag = t->c_cflag;
 
@@ -1285,8 +1493,7 @@ plcomparam(struct tty *tp, struct termio
 void
 plcom_iflush(struct plcom_softc *sc)
 {
-	bus_space_tag_t iot = sc->sc_iot;
-	bus_space_handle_t ioh = sc->sc_ioh;
+	struct plcom_instance *pi = &sc->sc_pi;
 #ifdef DIAGNOSTIC
 	int reg;
 #endif
@@ -1297,40 +1504,56 @@ plcom_iflush(struct plcom_softc *sc)
 #endif
 	timo = 50000;
 	/* flush any pending I/O */
-	while (! ISSET(bus_space_read_1(iot, ioh, plcom_fr), PL01X_FR_RXFE)
+	while (! ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE)
 	    && --timo)
 #ifdef DIAGNOSTIC
 		reg =
 #else
 		    (void)
 #endif
-		    bus_space_read_1(iot, ioh, plcom_dr);
+		    PREAD1(pi, PL01XCOM_DR);
 #ifdef DIAGNOSTIC
 	if (!timo)
-		printf("%s: plcom_iflush timeout %02x\n", device_xname(sc->sc_dev),
-		       reg);
+		aprint_error_dev(sc->sc_dev, ": %s timeout %02x\n", __func__,
+		    reg);
 #endif
 }
 
 void
 plcom_loadchannelregs(struct plcom_softc *sc)
 {
-	bus_space_tag_t iot = sc->sc_iot;
-	bus_space_handle_t ioh = sc->sc_ioh;
+	struct plcom_instance *pi = &sc->sc_pi;
 
 	/* XXXXX necessary? */
 	plcom_iflush(sc);
 
-	bus_space_write_1(iot, ioh, plcom_cr, 0);
-
-	bus_space_write_1(iot, ioh, plcom_dlbl, sc->sc_dlbl);
-	bus_space_write_1(iot, ioh, plcom_dlbh, sc->sc_dlbh);
-	bus_space_write_1(iot, ioh, plcom_lcr, sc->sc_lcr);
-	/* XXX device_unit() abuse */
-	sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(sc->sc_dev),
-	    sc->sc_mcr_active = sc->sc_mcr);
-
-	bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		PWRITE1(pi, PL010COM_CR, 0);
+		PWRITE1(pi, PL010COM_DLBL, sc->sc_ratel);
+		PWRITE1(pi, PL010COM_DLBH, sc->sc_rateh);
+		PWRITE1(pi, PL010COM_LCR, sc->sc_lcr);
+
+		/* XXX device_unit() abuse */
+		if (sc->sc_set_mcr)
+			sc->sc_set_mcr(sc->sc_set_mcr_arg,
+			    device_unit(sc->sc_dev),
+			    sc->sc_mcr_active = sc->sc_mcr);
+
+		PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+		break;
+
+	case PLCOM_TYPE_PL011:
+		PWRITE4(pi, PL011COM_CR, 0);
+		PWRITE1(pi, PL011COM_FBRD, sc->sc_ratel);
+		PWRITE4(pi, PL011COM_IBRD, sc->sc_rateh);
+		PWRITE1(pi, PL011COM_LCRH, sc->sc_lcr);
+		sc->sc_mcr_active = sc->sc_mcr;
+		CLR(sc->sc_cr, PL011_MCR(PL01X_MCR_RTS | PL01X_MCR_DTR));
+		SET(sc->sc_cr, PL011_MCR(sc->sc_mcr_active));
+		PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+		break;
+	}
 }
 
 int
@@ -1373,6 +1596,8 @@ plcomhwiflow(struct tty *tp, int block)
 void
 plcom_hwiflow(struct plcom_softc *sc)
 {
+	struct plcom_instance *pi = &sc->sc_pi;
+
 	if (sc->sc_mcr_rts == 0)
 		return;
 
@@ -1383,9 +1608,19 @@ plcom_hwiflow(struct plcom_softc *sc)
 		SET(sc->sc_mcr, sc->sc_mcr_rts);
 		SET(sc->sc_mcr_active, sc->sc_mcr_rts);
 	}
-	/* XXX device_unit() abuse */
-	sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(sc->sc_dev),
-	    sc->sc_mcr_active);
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		if (sc->sc_set_mcr)
+			/* XXX device_unit() abuse */
+			sc->sc_set_mcr(sc->sc_set_mcr_arg,
+			     device_unit(sc->sc_dev), sc->sc_mcr_active);
+		break;
+	case PLCOM_TYPE_PL011:
+		CLR(sc->sc_cr, PL011_MCR(PL01X_MCR_RTS | PL01X_MCR_DTR));
+		SET(sc->sc_cr, PL011_MCR(sc->sc_mcr_active));
+		PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+		break;
+	}
 }
 
 
@@ -1394,8 +1629,7 @@ plcomstart(struct tty *tp)
 {
 	struct plcom_softc *sc =
 		device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev));
-	bus_space_tag_t iot = sc->sc_iot;
-	bus_space_handle_t ioh = sc->sc_ioh;
+	struct plcom_instance *pi = &sc->sc_pi;
 	int s;
 
 	if (PLCOM_ISALIVE(sc) == 0)
@@ -1428,9 +1662,19 @@ plcomstart(struct tty *tp)
 	sc->sc_tx_busy = 1;
 
 	/* Enable transmit completion interrupts if necessary. */
-	if (!ISSET(sc->sc_cr, PL010_CR_TIE)) {
-		SET(sc->sc_cr, PL010_CR_TIE);
-		bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		if (!ISSET(sc->sc_cr, PL010_CR_TIE)) {
+			SET(sc->sc_cr, PL010_CR_TIE);
+			PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+		}
+		break;
+	case PLCOM_TYPE_PL011:
+		if (!ISSET(sc->sc_imsc, PL011_INT_TX)) {
+			SET(sc->sc_imsc, PL011_INT_TX);
+			PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+		}
+		break;
 	}
 
 	/* Output the first chunk of the contiguous buffer. */
@@ -1440,7 +1684,7 @@ plcomstart(struct tty *tp)
 		n = sc->sc_tbc;
 		if (n > sc->sc_fifolen)
 			n = sc->sc_fifolen;
-		bus_space_write_multi_1(iot, ioh, plcom_dr, sc->sc_tba, n);
+		PWRITEM1(pi, PL01XCOM_DR, sc->sc_tba, n);
 		sc->sc_tbc -= n;
 		sc->sc_tba += n;
 	}
@@ -1494,6 +1738,7 @@ integrate void
 plcom_rxsoft(struct plcom_softc *sc, struct tty *tp)
 {
 	int (*rint) (int, struct tty *) = tp->t_linesw->l_rint;
+	struct plcom_instance *pi = &sc->sc_pi;
 	u_char *get, *end;
 	u_int cc, scc;
 	u_char rsr;
@@ -1568,8 +1813,18 @@ plcom_rxsoft(struct plcom_softc *sc, str
 		if (cc >= sc->sc_r_lowat) {
 			if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
 				CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
-				SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE);
-				bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
+				switch (pi->pi_type) {
+				case PLCOM_TYPE_PL010:
+					SET(sc->sc_cr,
+					    PL010_CR_RIE | PL010_CR_RTIE);
+					PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+					break;
+				case PLCOM_TYPE_PL011:
+					SET(sc->sc_imsc,
+					    PL011_INT_RX | PL011_INT_RT);
+					PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+					break;
+				}
 			}
 			if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
 				CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
@@ -1653,22 +1908,46 @@ plcomsoft(void *arg)
 	}
 }
 
+bool
+plcom_intstatus(struct plcom_instance *pi, u_int *istatus)
+{
+	bool ret = false;
+	u_int stat = 0;
+
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		stat = PREAD1(pi, PL010COM_IIR);
+		ret = ISSET(stat, PL010_IIR_IMASK);
+		break;
+	case PLCOM_TYPE_PL011:
+		stat = PREAD4(pi, PL011COM_MIS);
+		ret = ISSET(stat, PL011_INT_ALLMASK);
+		break;
+	}
+	*istatus = stat;
+
+	return ret;
+}	
+
 int
 plcomintr(void *arg)
 {
 	struct plcom_softc *sc = arg;
-	bus_space_tag_t iot = sc->sc_iot;
-	bus_space_handle_t ioh = sc->sc_ioh;
+	struct plcom_instance *pi = &sc->sc_pi;
 	u_char *put, *end;
 	u_int cc;
-	u_char rsr, iir;
+	u_int istatus = 0;
+	u_char rsr;
+	bool intr = false;
+
+	PLCOM_BARRIER(pi, BR | BW);
 
 	if (PLCOM_ISALIVE(sc) == 0)
 		return 0;
 
 	mutex_spin_enter(&sc->sc_lock);
-	iir = bus_space_read_1(iot, ioh, plcom_iir);
-	if (! ISSET(iir, PL010_IIR_IMASK)) {
+	intr = plcom_intstatus(pi, &istatus);
+	if (!intr) {
 		mutex_spin_exit(&sc->sc_lock);
 		return 0;
 	}
@@ -1678,21 +1957,21 @@ plcomintr(void *arg)
 	cc = sc->sc_rbavail;
 
 	do {
-		u_char	msr, delta, fr;
+		u_int msr = 0, delta, fr;
+		bool rxintr = false, txintr = false, msintr;
 
-		fr = bus_space_read_1(iot, ioh, plcom_fr);
+		/* don't need RI here*/
+		fr = PREAD1(pi, PL01XCOM_FR);
 
 		if (!ISSET(fr, PL01X_FR_RXFE) &&
 		    !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
 			while (cc > 0) {
 				int cn_trapped = 0;
-				put[0] = bus_space_read_1(iot, ioh,
-				    plcom_dr);
-				rsr = bus_space_read_1(iot, ioh, plcom_rsr);
+				put[0] = PREAD1(pi, PL01XCOM_DR);
+				rsr = PREAD1(pi, PL01XCOM_RSR);
 				/* Clear any error status.  */
 				if (ISSET(rsr, PL01X_RSR_ERROR))
-					bus_space_write_1(iot, ioh, plcom_ecr,
-					    0);
+					PWRITE1(pi, PL01XCOM_ECR, 0);
 				if (ISSET(rsr, PL01X_RSR_BE)) {
 					cn_trapped = 0;
 					cn_check_magic(sc->sc_tty->t_dev,
@@ -1710,11 +1989,10 @@ plcomintr(void *arg)
 
 				put[1] = rsr;
 				cn_trapped = 0;
-				cn_check_magic(sc->sc_tty->t_dev,
-					       put[0], plcom_cnm_state);
+				cn_check_magic(sc->sc_tty->t_dev, put[0],
+				    plcom_cnm_state);
 				if (cn_trapped) {
-					fr = bus_space_read_1(iot, ioh,
-					    plcom_fr);
+					fr = PREAD1(pi, PL01XCOM_FR);
 					if (ISSET(fr, PL01X_FR_RXFE))
 						break;
 
@@ -1725,7 +2003,8 @@ plcomintr(void *arg)
 					put = sc->sc_rbuf;
 				cc--;
 
-				fr = bus_space_read_1(iot, ioh, plcom_fr);
+				/* don't need RI here*/
+				fr = PREAD1(pi, PL01XCOM_FR);
 				if (ISSET(fr, PL01X_FR_RXFE))
 					break;
 			}
@@ -1757,26 +2036,68 @@ plcomintr(void *arg)
 			 */
 			if (!cc) {
 				SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
-				CLR(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE);
-				bus_space_write_1(iot, ioh, plcom_cr,
-				    sc->sc_cr);
+				switch (pi->pi_type) {
+				case PLCOM_TYPE_PL010:
+					CLR(sc->sc_cr,
+					    PL010_CR_RIE | PL010_CR_RTIE);
+					PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+					break;
+				case PLCOM_TYPE_PL011:
+					CLR(sc->sc_imsc,
+					    PL011_INT_RT | PL011_INT_RX);
+					PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+					break;
+				}
 			}
 		} else {
-			if (ISSET(iir, PL010_IIR_RIS)) {
-				bus_space_write_1(iot, ioh, plcom_cr, 0);
-				delay(10);
-				bus_space_write_1(iot, ioh, plcom_cr,
-				    sc->sc_cr);
-				continue;
+			switch (pi->pi_type) {
+			case PLCOM_TYPE_PL010:
+				rxintr = ISSET(istatus, PL010_IIR_RIS);
+				if (rxintr) {
+					PWRITE1(pi, PL010COM_CR, 0);
+					delay(10);
+					PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+					continue;
+				}
+				break;
+			case PLCOM_TYPE_PL011:
+				rxintr = ISSET(istatus, PL011_INT_RX);
+				if (rxintr) {
+					PWRITE4(pi, PL011COM_CR, 0);
+					delay(10);
+					PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+					continue;
+				}
+				break;
 			}
 		}
 
-		msr = bus_space_read_1(iot, ioh, plcom_fr);
+		switch (pi->pi_type) {
+		case PLCOM_TYPE_PL010:
+			msr = PREAD1(pi, PL01XCOM_FR);
+			break;
+		case PLCOM_TYPE_PL011:
+			msr = PREAD4(pi, PL01XCOM_FR);
+			break;
+		}
 		delta = msr ^ sc->sc_msr;
 		sc->sc_msr = msr;
+
 		/* Clear any pending modem status interrupt.  */
-		if (iir & PL010_IIR_MIS)
-			bus_space_write_1(iot, ioh, plcom_icr, 0);
+		switch (pi->pi_type) {
+		case PLCOM_TYPE_PL010:
+			msintr = ISSET(istatus, PL010_IIR_MIS);
+			if (msintr) {
+				PWRITE1(pi, PL010COM_ICR, 0);
+			}
+			break;
+		case PLCOM_TYPE_PL011:
+			msintr = ISSET(istatus, PL011_INT_MSMASK);
+			if (msintr) {
+				PWRITE4(pi, PL011COM_ICR, PL011_INT_MSMASK);
+			}
+			break;
+		}
 		/*
 		 * Pulse-per-second (PSS) signals on edge of DCD?
 		 * Process these even if line discipline is ignoring DCD.
@@ -1847,14 +2168,24 @@ plcomintr(void *arg)
 
 		/* 
 		 * Done handling any receive interrupts. See if data
-		 * can be * transmitted as well. Schedule tx done
-		 * event if no data left * and tty was marked busy.
+		 * can be transmitted as well. Schedule tx done
+		 * event if no data left and tty was marked busy.
 		 */
-		if (ISSET(iir, PL010_IIR_TIS)) {
+		
+		switch (pi->pi_type) {
+		case PLCOM_TYPE_PL010:
+			txintr = ISSET(istatus, PL010_IIR_TIS);
+			break;
+		case PLCOM_TYPE_PL011:
+			txintr = ISSET(istatus, PL011_INT_TX);
+			break;
+		}
+		if (txintr) {
 			/*
 			 * If we've delayed a parameter change, do it
 			 * now, and restart * output.
 			 */
+// PWRITE4(pi, PL011COM_ICR, PL011_INT_TX);
 			if (sc->sc_heldchange) {
 				plcom_loadchannelregs(sc);
 				sc->sc_heldchange = 0;
@@ -1872,19 +2203,29 @@ plcomintr(void *arg)
 				n = sc->sc_tbc;
 				if (n > sc->sc_fifolen)
 					n = sc->sc_fifolen;
-				bus_space_write_multi_1(iot, ioh, plcom_dr,
-				    sc->sc_tba, n);
+				PWRITEM1(pi, PL01XCOM_DR, sc->sc_tba, n);
 				sc->sc_tbc -= n;
 				sc->sc_tba += n;
 			} else {
 				/*
-				 * Disable transmit plcompletion
+				 * Disable transmit completion
 				 * interrupts if necessary.
 				 */
-				if (ISSET(sc->sc_cr, PL010_CR_TIE)) {
-					CLR(sc->sc_cr, PL010_CR_TIE);
-					bus_space_write_1(iot, ioh, plcom_cr,
-					    sc->sc_cr);
+				switch (pi->pi_type) {
+				case PLCOM_TYPE_PL010:
+					if (ISSET(sc->sc_cr, PL010_CR_TIE)) {
+						CLR(sc->sc_cr, PL010_CR_TIE);
+						PWRITE1(pi, PL010COM_CR,
+						    sc->sc_cr);
+					}
+					break;
+				case PLCOM_TYPE_PL011:
+					if (ISSET(sc->sc_imsc, PL011_INT_TX)) {
+						CLR(sc->sc_imsc, PL011_INT_TX);
+						PWRITE4(pi, PL011COM_IMSC,
+						    sc->sc_imsc);
+					}
+					break;
 				}
 				if (sc->sc_tx_busy) {
 					sc->sc_tx_busy = 0;
@@ -1892,8 +2233,8 @@ plcomintr(void *arg)
 				}
 			}
 		}
-	} while (ISSET((iir = bus_space_read_1(iot, ioh, plcom_iir)),
-	    PL010_IIR_IMASK));
+
+	} while (plcom_intstatus(pi, &istatus));
 
 	mutex_spin_exit(&sc->sc_lock);
 
@@ -1901,9 +2242,11 @@ plcomintr(void *arg)
 	softint_schedule(sc->sc_si);
 
 #ifdef RND_COM
-	rnd_add_uint32(&sc->rnd_source, iir | rsr);
+	rnd_add_uint32(&sc->rnd_source, istatus | rsr);
 #endif
 
+	PLCOM_BARRIER(pi, BR | BW);
+
 	return 1;
 }
 
@@ -1921,7 +2264,7 @@ static int plcom_readahead[MAX_READAHEAD
 static int plcom_readaheadcount = 0;
 
 int
-plcom_common_getc(dev_t dev, bus_space_tag_t iot, bus_space_handle_t ioh)
+plcom_common_getc(dev_t dev, struct plcom_instance *pi)
 {
 	int s = splserial();
 	u_char stat, c;
@@ -1940,11 +2283,10 @@ plcom_common_getc(dev_t dev, bus_space_t
 	}
 
 	/* block until a character becomes available */
-	while (ISSET(stat = bus_space_read_1(iot, ioh, plcom_fr), PL01X_FR_RXFE))
+	while (ISSET(stat = PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE))
 		;
 
-	c = bus_space_read_1(iot, ioh, plcom_dr);
-	stat = bus_space_read_1(iot, ioh, plcom_iir);
+	c = PREAD1(pi, PL01XCOM_DR);
 	{
 		int cn_trapped = 0; /* unused */
 #ifdef DDB
@@ -1958,33 +2300,31 @@ plcom_common_getc(dev_t dev, bus_space_t
 }
 
 void
-plcom_common_putc(dev_t dev, bus_space_tag_t iot, bus_space_handle_t ioh,
-    int c)
+plcom_common_putc(dev_t dev, struct plcom_instance *pi, int c)
 {
 	int s = splserial();
 	int timo;
 
 	int cin, stat;
 	if (plcom_readaheadcount < MAX_READAHEAD 
-	     && !ISSET(stat = bus_space_read_1(iot, ioh, plcom_fr), PL01X_FR_RXFE)) {
+	     && !ISSET(stat = PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE)) {
 		int cn_trapped = 0;
-		cin = bus_space_read_1(iot, ioh, plcom_dr);
-		stat = bus_space_read_1(iot, ioh, plcom_iir);
+		cin = PREAD1(pi, PL01XCOM_DR);
 		cn_check_magic(dev, cin, plcom_cnm_state);
 		plcom_readahead[plcom_readaheadcount++] = cin;
 	}
 
 	/* wait for any pending transmission to finish */
 	timo = 150000;
-	while (!ISSET(bus_space_read_1(iot, ioh, plcom_fr), PL01X_FR_TXFE) && --timo)
+	while (!ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_TXFE) && --timo)
 		continue;
 
-	bus_space_write_1(iot, ioh, plcom_dr, c);
-	PLCOM_BARRIER(iot, ioh, BR | BW);
+	PWRITE1(pi, PL01XCOM_DR, c);
+	PLCOM_BARRIER(pi, BR | BW);
 
 	/* wait for this transmission to complete */
 	timo = 1500000;
-	while (!ISSET(bus_space_read_1(iot, ioh, plcom_fr), PL01X_FR_TXFE) && --timo)
+	while (!ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_TXFE) && --timo)
 		continue;
 
 	splx(s);
@@ -1994,20 +2334,49 @@ plcom_common_putc(dev_t dev, bus_space_t
  * Initialize UART for use as console or KGDB line.
  */
 int
-plcominit(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency,
-    tcflag_t cflag, bus_space_handle_t *iohp)
+plcominit(struct plcom_instance *pi, int rate, int frequency, tcflag_t cflag)
 {
-	bus_space_handle_t ioh;
+	u_char lcr;
 
-	if (bus_space_map(iot, iobase, PLCOM_UART_SIZE, 0, &ioh))
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		if (pi->pi_size == 0)
+			pi->pi_size = PL010COM_UART_SIZE;
+		break;
+	case PLCOM_TYPE_PL011:
+		if (pi->pi_size == 0)
+			pi->pi_size = PL011COM_UART_SIZE;
+		break;
+	default:
+		panic("Unknown plcom type");
+	}
+
+	if (bus_space_map(pi->pi_iot, pi->pi_iobase, pi->pi_size, 0,
+	    &pi->pi_ioh))
 		return ENOMEM; /* ??? */
 
-	rate = plcomspeed(rate, frequency);
-	bus_space_write_1(iot, ioh, plcom_cr, 0);
-	bus_space_write_1(iot, ioh, plcom_dlbl, rate);
-	bus_space_write_1(iot, ioh, plcom_dlbh, rate >> 8);
-	bus_space_write_1(iot, ioh, plcom_lcr, cflag2lcr(cflag) | PL01X_LCR_FEN);
-	bus_space_write_1(iot, ioh, plcom_cr, PL01X_CR_UARTEN);
+	lcr = cflag2lcr(cflag) | PL01X_LCR_FEN;
+	switch (pi->pi_type) {
+	case PLCOM_TYPE_PL010:
+		PWRITE1(pi, PL010COM_CR, 0);
+
+		rate = pl010comspeed(rate, frequency);
+		PWRITE1(pi, PL010COM_DLBL, (rate & 0xff));
+		PWRITE1(pi, PL010COM_DLBH, ((rate >> 8) & 0xff));
+		PWRITE1(pi, PL010COM_LCR, lcr);
+		PWRITE1(pi, PL010COM_CR, PL01X_CR_UARTEN);
+		break;
+	case PLCOM_TYPE_PL011:
+		PWRITE4(pi, PL011COM_CR, 0);
+
+		rate = pl011comspeed(rate, frequency);
+		PWRITE1(pi, PL011COM_FBRD, rate & ((1 << 6) - 1));
+		PWRITE4(pi, PL011COM_IBRD, rate >> 6);
+		PWRITE1(pi, PL011COM_LCRH, lcr);
+		PWRITE4(pi, PL011COM_CR,
+		    PL01X_CR_UARTEN | PL011_CR_RXE | PL011_CR_TXE);
+		break;
+	}
 
 #if 0
 	/* Ought to do something like this, but we have no sc to
@@ -2017,7 +2386,6 @@ plcominit(bus_space_tag_t iot, bus_addr_
 	    PL01X_MCR_DTR | PL01X_MCR_RTS);
 #endif
 
-	*iohp = ioh;
 	return 0;
 }
 
@@ -2029,14 +2397,15 @@ struct consdev plcomcons = {
 	NULL, NULL, NODEV, CN_NORMAL
 };
 
-
 int
-plcomcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency,
+plcomcnattach(struct plcom_instance *pi, int rate, int frequency,
     tcflag_t cflag, int unit)
 {
 	int res;
 
-	res = plcominit(iot, iobase, rate, frequency, cflag, &plcomconsioh);
+	plcomcons_info = *pi;
+
+	res = plcominit(&plcomcons_info, rate, frequency, cflag);
 	if (res)
 		return res;
 
@@ -2044,7 +2413,6 @@ plcomcnattach(bus_space_tag_t iot, bus_a
 	cn_init_magic(&plcom_cnm_state);
 	cn_set_magic("\047\001"); /* default magic is BREAK */
 
-	plcomconstag = iot;
 	plcomconsunit = unit;
 	plcomconsrate = rate;
 	plcomconscflag = cflag;
@@ -2055,8 +2423,10 @@ plcomcnattach(bus_space_tag_t iot, bus_a
 void
 plcomcndetach(void)
 {
-	bus_space_unmap(plcomconstag, plcomconsioh, PLCOM_UART_SIZE);
-	plcomconstag = NULL;
+
+	bus_space_unmap(plcomcons_info.pi_iot, plcomcons_info.pi_ioh,
+	    plcomcons_info.pi_size);
+	plcomcons_info.pi_iot = NULL;
 
 	cn_tab = NULL;
 }
@@ -2064,7 +2434,7 @@ plcomcndetach(void)
 int
 plcomcngetc(dev_t dev)
 {
-	return plcom_common_getc(dev, plcomconstag, plcomconsioh);
+	return plcom_common_getc(dev, &plcomcons_info);
 }
 
 /*
@@ -2073,7 +2443,7 @@ plcomcngetc(dev_t dev)
 void
 plcomcnputc(dev_t dev, int c)
 {
-	plcom_common_putc(dev, plcomconstag, plcomconsioh, c);
+	plcom_common_putc(dev, &plcomcons_info, c);
 }
 
 void
@@ -2084,23 +2454,25 @@ plcomcnpollc(dev_t dev, int on)
 
 #ifdef KGDB
 int
-plcom_kgdb_attach(bus_space_tag_t iot, bus_addr_t iobase, int rate,
-   int frequency, tcflag_t cflag, int unit)
+plcom_kgdb_attach(struct plcom_instance *pi, int rate, int frequency,
+    tcflag_t cflag, int unit)
 {
 	int res;
 
-	if (iot == plcomconstag && iobase == plcomconsunit)
+	if (pi->pi_iot == plcomcons_info.pi_iot &&
+	    pi->pi_iobase == plcomcons_info.pi_iobase)
 		return EBUSY; /* cannot share with console */
 
-	res = plcominit(iot, iobase, rate, frequency, cflag, &plcom_kgdb_ioh);
+	res = plcominit(pi, rate, frequency, cflag);
 	if (res)
 		return res;
 
 	kgdb_attach(plcom_kgdb_getc, plcom_kgdb_putc, NULL);
 	kgdb_dev = 123; /* unneeded, only to satisfy some tests */
 
-	plcom_kgdb_iot = iot;
-	plcom_kgdb_unit = unit;
+	plcomkgdb_info.pi_iot = pi->pi_iot;
+	plcomkgdb_info.pi_ioh = pi->pi_ioh;
+	plcomkgdb_info.pi_iobase = pi->pi_iobase;
 
 	return 0;
 }
@@ -2109,6 +2481,7 @@ plcom_kgdb_attach(bus_space_tag_t iot, b
 int
 plcom_kgdb_getc(void *arg)
 {
+
 	return plcom_common_getc(NODEV, plcom_kgdb_iot, plcom_kgdb_ioh);
 }
 
@@ -2123,17 +2496,19 @@ plcom_kgdb_putc(void *arg, int c)
 /* helper function to identify the plcom ports used by
  console or KGDB (and not yet autoconf attached) */
 int
-plcom_is_console(bus_space_tag_t iot, int unit,
+plcom_is_console(bus_space_tag_t iot, bus_addr_t iobase, 
     bus_space_handle_t *ioh)
 {
 	bus_space_handle_t help;
 
 	if (!plcomconsattached &&
-	    iot == plcomconstag && unit == plcomconsunit)
-		help = plcomconsioh;
+	    bus_space_is_equal(iot, plcomcons_info.pi_iot) &&
+	    iobase == plcomcons_info.pi_iobase)
+		help = plcomcons_info.pi_ioh;
 #ifdef KGDB
 	else if (!plcom_kgdb_attached &&
-	    iot == plcom_kgdb_iot && unit == plcom_kgdb_unit)
+	    bus_space_is_equal(iot, plcomkgdb_info.pi_iot) &&
+	    iobase == plcomkgdb_info.pi_iobase) 
 		help = plcom_kgdb_ioh;
 #endif
 	else

Index: src/sys/arch/evbarm/dev/plcomreg.h
diff -u src/sys/arch/evbarm/dev/plcomreg.h:1.3 src/sys/arch/evbarm/dev/plcomreg.h:1.4
--- src/sys/arch/evbarm/dev/plcomreg.h:1.3	Mon May 14 19:40:06 2012
+++ src/sys/arch/evbarm/dev/plcomreg.h	Wed Jul 25 07:26:17 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: plcomreg.h,v 1.3 2012/05/14 19:40:06 skrll Exp $	*/
+/*	$NetBSD: plcomreg.h,v 1.4 2012/07/25 07:26:17 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2001 ARM Ltd
@@ -52,11 +52,12 @@
 #define	PL01X_CR_UARTEN	0x0001	/* Uart enable */
 
 /* interrupt identification register */
-#define	PL010_IIR_IMASK	0x0f
 #define	PL010_IIR_RTIS	0x08
 #define	PL010_IIR_TIS	0x04
 #define	PL010_IIR_RIS	0x02
 #define	PL010_IIR_MIS	0x01
+#define	PL010_IIR_IMASK	\
+    (PL010_IIR_RTIS | PL010_IIR_TIS | PL010_IIR_RIS | PL010_IIR_MIS)
 
 /* line control register */
 #define	PL011_LCR_SPS	0x80	/* Stick parity select */
@@ -77,16 +78,18 @@
 /* modem control register */
 #define	PL01X_MCR_RTS		0x02	/* Request To Send */
 #define	PL01X_MCR_DTR		0x01	/* Data Terminal Ready */
+#define	PL011_MCR(mcr)	((mcr) << 10)	/* MCR to CR bit values for PL011 */
 
 /* receive status register */
 #define	PL01X_RSR_OE	0x08	/* Overrun Error */
 #define	PL01X_RSR_BE	0x04	/* Break */
 #define	PL01X_RSR_PE	0x02	/* Parity Error */
 #define	PL01X_RSR_FE	0x01	/* Framing Error */
-#define	PL01X_RSR_ERROR	(PL01X_RSR_OE | PL01X_RSR_BE | PL01X_RSR_PE | PL01X_RSR_FE)
+#define	PL01X_RSR_ERROR	\
+    (PL01X_RSR_OE | PL01X_RSR_BE | PL01X_RSR_PE | PL01X_RSR_FE)
 
 /* flag register */
-#define	PL01X_FR_RI	0x100	/* Ring Indicator */
+#define	PL011_FR_RI	0x100	/* Ring Indicator */
 #define	PL01X_FR_TXFE	0x080	/* Transmit fifo empty */
 #define	PL01X_FR_RXFF	0x040	/* Recive fifo full */
 #define	PL01X_FR_TXFF	0x020	/* Transmit fifo full */
@@ -101,6 +104,7 @@
 #define	PL01X_MSR_DCD		PL01X_FR_DCD
 #define	PL01X_MSR_DSR		PL01X_FR_DSR
 #define	PL01X_MSR_CTS		PL01X_FR_CTS
+#define	PL011_MSR_RI		PL011_FR_RI
 
 /* All interrupt status/clear registers */
 #define	PL011_INT_OE	0x400
@@ -114,6 +118,12 @@
 #define	PL011_INT_DCD	0x004
 #define	PL011_INT_CTS	0x002
 #define	PL011_INT_RIR	0x001
+#define	PL011_INT_MSMASK \
+    (PL011_INT_DSR | PL011_INT_DCD | PL011_INT_CTS | PL011_INT_RIR)
+
+#define	PL011_INT_ALLMASK \
+    (PL011_INT_RT | PL011_INT_TX | PL011_INT_RX | PL011_INT_MSMASK)
+
 
 /* DMA control registers */
 #define	PL011_DMA_ONERR	0x4
@@ -121,17 +131,27 @@
 #define	PL011_DMA_RXE	0x1
 
 /* Register offsets */
-#define	plcom_dr	0x00
-#define	plcom_rsr	0x04
-#define	plcom_ecr	0x04
-#define	plcom_lcr	0x08
-#define	plcom_dlbh	0x0c
-#define	plcom_dlbl	0x10
-#define	plcom_cr	0x14
-#define	plcom_fr	0x18
-#define	plcom_iir	0x1c
-#define	plcom_icr	0x1c
-#define	plcom_ilpr	0x20
+#define	PL01XCOM_DR	0x00	/* Data Register */
+#define	PL01XCOM_RSR	0x04	/* Receive status register */
+#define	PL01XCOM_ECR	0x04	/* Error clear register - same as RSR */
+#define	PL010COM_LCR	0x08	/* Line Control Register */
+#define	PL010COM_DLBH	0x0c
+#define	PL010COM_DLBL	0x10
+#define	PL010COM_CR	0x14
+#define	PL01XCOM_FR	0x18	/* Flag Register */
+#define	PL010COM_IIR	0x1c
+#define	PL010COM_ICR	0x1c
+#define	PL01XCOM_ILPR	0x20	/* IrDA low-power control register */
+#define	PL011COM_IBRD	0x24	/* Integer baud rate divisor register */
+#define	PL011COM_FBRD	0x28	/* Fractional baud rate divisor register */
+#define	PL011COM_LCRH	0x2c	/* Line control register */
+#define	PL011COM_CR	0x30	/* Control register */
+#define	PL011COM_IFLS	0x34	/* Interrupt FIFO level select register */
+#define	PL011COM_IMSC	0x38	/* Interrupt mask set/clear register */
+#define	PL011COM_RIS	0x3c	/* Raw interrupt status register */
+#define	PL011COM_MIS	0x40	/* Masked interrupt status register */
+#define	PL011COM_ICR	0x44	/* Interrupt clear register register */
+#define	PL011COM_DMACR	0x48	/* DMA control register register */
 
-/* IFPGA specific */
-#define	PLCOM_UART_SIZE	0x24
+#define	PL010COM_UART_SIZE	0x100
+#define	PL011COM_UART_SIZE	0x1000

Index: src/sys/arch/evbarm/dev/plcomvar.h
diff -u src/sys/arch/evbarm/dev/plcomvar.h:1.10 src/sys/arch/evbarm/dev/plcomvar.h:1.11
--- src/sys/arch/evbarm/dev/plcomvar.h:1.10	Sun May 20 10:28:44 2012
+++ src/sys/arch/evbarm/dev/plcomvar.h	Wed Jul 25 07:26:18 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: plcomvar.h,v 1.10 2012/05/20 10:28:44 skrll Exp $	*/
+/*	$NetBSD: plcomvar.h,v 1.11 2012/07/25 07:26:18 skrll Exp $	*/
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
@@ -44,14 +44,16 @@
 #include <sys/timepps.h>
 #include <sys/simplelock.h>
 
-int  plcomcnattach	(bus_space_tag_t, bus_addr_t, int, int, tcflag_t, int);
+struct plcom_instance;
+
+int  plcomcnattach	(struct plcom_instance *, int, int, tcflag_t, int);
 void plcomcndetach	(void);
 
 #ifdef KGDB
-int  plcom_kgdb_attach	(bus_space_tag_t, bus_addr_t, int, int, tcflag_t);
+int  plcom_kgdb_attach	(struct plcom_instance *, int, int, tcflag_t);
 #endif
 
-int  plcom_is_console	(bus_space_tag_t, int, bus_space_handle_t *);
+int  plcom_is_console	(bus_space_tag_t, bus_addr_t, bus_space_handle_t *);
 
 /* Hardware flag masks */
 #define	PLCOM_HW_NOIEN		0x01
@@ -66,18 +68,43 @@ int  plcom_is_console	(bus_space_tag_t, 
 /* Buffer size for character buffer */
 #define	PLCOM_RING_SIZE		2048
 
+struct plcom_instance {
+	u_int			pi_type;
+#define	PLCOM_TYPE_PL010 0
+#define	PLCOM_TYPE_PL011 1
+
+	uint32_t		pi_flags;	/* flags for this PLCOM */
+#define	PLC_FLAG_USE_DMA		0x0001
+#define	PLC_FLAG_32BIT_ACCESS		0x0002
+
+	void 			*pi_cookie;
+
+	bus_space_tag_t		pi_iot;
+	bus_space_handle_t	pi_ioh;
+	bus_addr_t		pi_iobase;
+	bus_addr_t		pi_size;
+	struct plcom_registers	*pi_regs;
+};
+
+struct plcomcons_info {
+	int	rate;
+	int	frequency;
+	int	type;
+
+	tcflag_t	cflag;
+};
+    
 struct plcom_softc {
 	device_t sc_dev;
-	void *sc_si;
+
 	struct tty *sc_tty;
+	void *sc_si;
 
 	struct callout sc_diag_callout;
 
-	bus_addr_t sc_iounit;
-	int sc_frequency;
+ 	int sc_frequency;
 
-	bus_space_tag_t sc_iot;
-	bus_space_handle_t sc_ioh;
+	struct plcom_instance sc_pi;
 
 	u_int sc_overflows,
 	      sc_floods,
@@ -112,12 +139,13 @@ struct plcom_softc {
 			sc_rx_ready;
 
 	volatile u_char sc_heldchange;
-	volatile u_char sc_msr, sc_msr_delta, sc_msr_mask, sc_mcr,
-	    sc_mcr_active, sc_lcr, sc_cr, sc_dlbl, sc_dlbh;
+	volatile u_int sc_cr, sc_ratel, sc_rateh, sc_imsc;
+	volatile u_int sc_msr, sc_msr_delta, sc_msr_mask;
+	volatile u_char sc_mcr, sc_mcr_active, sc_lcr;
 	u_char sc_mcr_dtr, sc_mcr_rts, sc_msr_cts, sc_msr_dcd;
 	u_int sc_fifo;
 
-	/* Support routine to program mcr lines, if present.  */
+	/* Support routine to program mcr lines for PL010, if present.  */
 	void	(*sc_set_mcr)(void *, int, u_int);
 	void	*sc_set_mcr_arg;
 
@@ -139,7 +167,9 @@ struct plcom_softc {
 	kmutex_t		sc_lock;
 };
 
+#if 0
 int  plcomprobe1	(bus_space_tag_t, bus_space_handle_t);
+#endif
 int  plcomintr		(void *);
 void plcom_attach_subr	(struct plcom_softc *);
 int  plcom_detach	(device_t, int);

Index: src/sys/arch/evbarm/ifpga/ifpgareg.h
diff -u src/sys/arch/evbarm/ifpga/ifpgareg.h:1.3 src/sys/arch/evbarm/ifpga/ifpgareg.h:1.4
--- src/sys/arch/evbarm/ifpga/ifpgareg.h:1.3	Sun Dec 11 12:17:09 2005
+++ src/sys/arch/evbarm/ifpga/ifpgareg.h	Wed Jul 25 07:26:18 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: ifpgareg.h,v 1.3 2005/12/11 12:17:09 christos Exp $ */
+/*	$NetBSD: ifpgareg.h,v 1.4 2012/07/25 07:26:18 skrll Exp $ */
 
 /*
  * Copyright (c) 2001 ARM Ltd
@@ -32,6 +32,7 @@
 /* System clock defaults. */
 
 #define IFPGA_UART_CLK			14745600 /* Uart REFCLK freq */
+#define IFPGA_UART_SIZE			0x24
 
 /*
  * IFPGA registers

Index: src/sys/arch/evbarm/ifpga/plcom_ifpga.c
diff -u src/sys/arch/evbarm/ifpga/plcom_ifpga.c:1.13 src/sys/arch/evbarm/ifpga/plcom_ifpga.c:1.14
--- src/sys/arch/evbarm/ifpga/plcom_ifpga.c:1.13	Sun May 20 10:28:44 2012
+++ src/sys/arch/evbarm/ifpga/plcom_ifpga.c	Wed Jul 25 07:26:18 2012
@@ -1,4 +1,4 @@
-/*      $NetBSD: plcom_ifpga.c,v 1.13 2012/05/20 10:28:44 skrll Exp $ */
+/*      $NetBSD: plcom_ifpga.c,v 1.14 2012/07/25 07:26:18 skrll Exp $ */
 
 /*
  * Copyright (c) 2001 ARM Ltd
@@ -32,7 +32,7 @@
 /* Interface to plcom (PL010) serial driver. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: plcom_ifpga.c,v 1.13 2012/05/20 10:28:44 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: plcom_ifpga.c,v 1.14 2012/07/25 07:26:18 skrll Exp $");
 
 #include <sys/types.h>
 #include <sys/device.h>
@@ -75,24 +75,27 @@ plcom_ifpga_attach(device_t parent, devi
 
 	isc->sc_iot = ifa->ifa_iot;
 	isc->sc_ioh = ifa->ifa_sc_ioh;
+
 	sc->sc_dev = self;
-	sc->sc_iounit = device_unit(sc->sc_dev);
+	sc->sc_pi.pi_type = PLCOM_TYPE_PL010;
+	sc->sc_pi.pi_iot = ifa->ifa_iot;
+	sc->sc_pi.pi_iobase = ifa->ifa_addr;
+	sc->sc_pi.pi_size = IFPGA_UART_SIZE;
 	sc->sc_frequency = IFPGA_UART_CLK;
-	sc->sc_iot = ifa->ifa_iot;
 	sc->sc_hwflags = 0;
 	sc->sc_swflags = 0;
 	sc->sc_set_mcr = plcom_ifpga_set_mcr;
 	sc->sc_set_mcr_arg = (void *)isc;
 
-	if (bus_space_map(ifa->ifa_iot, ifa->ifa_addr, PLCOM_UART_SIZE, 0,
-	    &sc->sc_ioh)) {
+	if (bus_space_map(ifa->ifa_iot, ifa->ifa_addr, IFPGA_UART_SIZE, 0,
+	    &sc->sc_pi.pi_ioh)) {
 		printf("%s: unable to map device\n", device_xname(sc->sc_dev));
 		return;
 	}
 
 	plcom_attach_subr(sc);
-	isc->sc_ih = ifpga_intr_establish(ifa->ifa_irq, IPL_SERIAL, plcomintr,
-	    sc);
+	isc->sc_ih = ifpga_intr_establish(ifa->ifa_irq, IPL_SERIAL,
+	    plcomintr, sc);
 	if (isc->sc_ih == NULL)
 		panic("%s: cannot install interrupt handler",
 		    device_xname(sc->sc_dev));

Index: src/sys/arch/evbarm/integrator/integrator_machdep.c
diff -u src/sys/arch/evbarm/integrator/integrator_machdep.c:1.68 src/sys/arch/evbarm/integrator/integrator_machdep.c:1.69
--- src/sys/arch/evbarm/integrator/integrator_machdep.c:1.68	Fri Jul  1 20:39:34 2011
+++ src/sys/arch/evbarm/integrator/integrator_machdep.c	Wed Jul 25 07:26:18 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: integrator_machdep.c,v 1.68 2011/07/01 20:39:34 dyoung Exp $	*/
+/*	$NetBSD: integrator_machdep.c,v 1.69 2012/07/25 07:26:18 skrll Exp $	*/
 
 /*
  * Copyright (c) 2001,2002 ARM Ltd
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: integrator_machdep.c,v 1.68 2011/07/01 20:39:34 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: integrator_machdep.c,v 1.69 2012/07/25 07:26:18 skrll Exp $");
 
 #include "opt_ddb.h"
 #include "opt_pmap_debug.h"
@@ -383,9 +383,6 @@ initarm(void *arg)
 	psize_t memsize;
 	vm_offset_t physical_freestart;
 	vm_offset_t physical_freeend;
-#if NPLCOM > 0 && defined(PLCONSOLE)
-	static struct bus_space plcom_bus_space;
-#endif
 
 	/*
 	 * Heads up ... Setup the CPU / MMU / TLB functions
@@ -402,13 +399,29 @@ initarm(void *arg)
 	 */
 
 	if (PLCOMCNUNIT == 0) {
+		static struct bus_space plcom_bus_space;
+		static struct plcom_instance ifpga_pi0 = {
+			.pi_type = PLCOM_TYPE_PL010,
+			.pi_iot = &plcom_bus_space,
+			.pi_size = IFPGA_UART_SIZE,
+			.pi_iobase = 0x0
+		};
+
 		ifpga_create_io_bs_tag(&plcom_bus_space, (void*)0xfd600000);
-		plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
-		    IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT);
+		plcomcnattach(&ifpga_pi0, plcomcnspeed, IFPGA_UART_CLK,
+		    plcomcnmode, PLCOMCNUNIT);
 	} else if (PLCOMCNUNIT == 1) {
+		static struct bus_space plcom_bus_space;
+		static struct plcom_instance ifpga_pi1 = {
+			.pi_type = PLCOM_TYPE_PL010,
+			.pi_iot = &plcom_bus_space,
+			.pi_size = IFPGA_UART_SIZE,
+			.pi_iobase = 0x0
+		};
+
 		ifpga_create_io_bs_tag(&plcom_bus_space, (void*)0xfd700000);
-		plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
-		    IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT);
+		plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
+		    plcomcnmode, PLCOMCNUNIT);
 	}
 #endif
 
@@ -788,9 +801,6 @@ void
 consinit(void)
 {
 	static int consinit_called = 0;
-#if NPLCOM > 0 && defined(PLCONSOLE)
-	static struct bus_space plcom_bus_space;
-#endif
 #if 0
 	char *console = CONSDEVNAME;
 #endif
@@ -802,17 +812,35 @@ consinit(void)
 
 #if NPLCOM > 0 && defined(PLCONSOLE)
 	if (PLCOMCNUNIT == 0) {
+		static struct bus_space plcom_bus_space;
+		static struct plcom_instance ifpga_pi1 = {
+			.pi_type = PLCOM_TYPE_PL010,
+			.pi_iot = &plcom_bus_space,
+			.pi_size = IFPGA_UART_SIZE,
+			.pi_iobase = 0x0
+		};
+
 		ifpga_create_io_bs_tag(&plcom_bus_space,
 		    (void*)UART0_BOOT_BASE);
-		if (plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
-		    IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT))
+
+		if (plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
+		      plcomcnmode, PLCOMCNUNIT))
 			panic("can't init serial console");
 		return;
 	} else if (PLCOMCNUNIT == 1) {
+		static struct bus_space plcom_bus_space;
+		static struct plcom_instance ifpga_pi1 = {
+			.pi_type = PLCOM_TYPE_PL010,
+			.pi_iot = &plcom_bus_space,
+			.pi_size = IFPGA_UART_SIZE,
+			.pi_iobase = 0x0
+		};
+
 		ifpga_create_io_bs_tag(&plcom_bus_space,
 		    (void*)UART0_BOOT_BASE);
-		if (plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
-		    IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT))
+
+		if (plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
+		      plcomcnmode, PLCOMCNUNIT))
 			panic("can't init serial console");
 		return;
 	}

Reply via email to