Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 0dfa93b0cda81f93598fc30620d75a22c14f06d2)
+++ HelenOS.config	(revision c88250553aba5820e5ea6bf156edf1ed176d8737)
@@ -487,9 +487,6 @@
 ! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=serial)&PLATFORM=ia64&MACHINE=i460GX] CONFIG_NS16550 (y/n)
 
-% Support for ARM926 on-chip UART
-! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&MACHINE=integratorcp] CONFIG_ARM926_UART (y/n)
-
-% Support for BCM2835 on-chip UART
-! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&MACHINE=raspberrypi] CONFIG_BCM2835_UART (y/n)
+% Support for PL011 UART
+! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&(MACHINE=integratorcp|MACHINE=raspberrypi)] CONFIG_PL011_UART (y/n)
 
 % Support for Samsung S3C24XX on-chip UART
@@ -527,5 +524,5 @@
 
 % Serial line input module
-! [CONFIG_DSRLNIN=y|(PLATFORM=arm32&MACHINE=gta02)|(PLATFORM=arm32&MACHINE=integratorcp&CONFIG_ARM926_UART=y)|(PLATFORM=arm32&MACHINE=beaglebone&CONFIG_AM335X_UART=y)|(PLATFORM=arm32&MACHINE=beagleboardxm&CONFIG_AMDM37X_UART=y)|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&PROCESSOR=sun4v)|(PLATFORM=arm32&MACHINE=raspberrypi&CONFIG_BCM2835_UART=y)] CONFIG_SRLN (y)
+! [CONFIG_DSRLNIN=y|(PLATFORM=arm32&MACHINE=gta02)|(PLATFORM=arm32&MACHINE=integratorcp&CONFIG_PL011_UART=y)|(PLATFORM=arm32&MACHINE=beaglebone&CONFIG_AM335X_UART=y)|(PLATFORM=arm32&MACHINE=beagleboardxm&CONFIG_AMDM37X_UART=y)|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&PROCESSOR=sun4v)|(PLATFORM=arm32&MACHINE=raspberrypi&CONFIG_PL011_UART=y)] CONFIG_SRLN (y)
 
 % EGA support
Index: kernel/arch/arm32/include/arch/mach/integratorcp/integratorcp.h
===================================================================
--- kernel/arch/arm32/include/arch/mach/integratorcp/integratorcp.h	(revision 0dfa93b0cda81f93598fc30620d75a22c14f06d2)
+++ kernel/arch/arm32/include/arch/mach/integratorcp/integratorcp.h	(revision c88250553aba5820e5ea6bf156edf1ed176d8737)
@@ -46,5 +46,6 @@
 #define ICP_IRQC_MAX_IRQ  8
 #define ICP_KBD_IRQ       3
-#define ICP_TIMER_IRQ    6
+#define ICP_TIMER_IRQ     6
+#define ICP_UART0_IRQ     1
 
 /** Timer frequency */
Index: kernel/arch/arm32/include/arch/mach/raspberrypi/raspberrypi.h
===================================================================
--- kernel/arch/arm32/include/arch/mach/raspberrypi/raspberrypi.h	(revision 0dfa93b0cda81f93598fc30620d75a22c14f06d2)
+++ kernel/arch/arm32/include/arch/mach/raspberrypi/raspberrypi.h	(revision c88250553aba5820e5ea6bf156edf1ed176d8737)
@@ -43,4 +43,6 @@
 extern struct arm_machine_ops raspberrypi_machine_ops;
 
+#define BCM2835_UART0_BASE_ADDRESS   0x20201000
+
 #endif
 
Index: kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
===================================================================
--- kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 0dfa93b0cda81f93598fc30620d75a22c14f06d2)
+++ kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision c88250553aba5820e5ea6bf156edf1ed176d8737)
@@ -37,6 +37,6 @@
 #include <ipc/irq.h>
 #include <console/chardev.h>
+#include <genarch/drivers/pl011/pl011.h>
 #include <genarch/drivers/pl050/pl050.h>
-#include <genarch/drivers/arm926_uart/arm926_uart.h>
 #include <genarch/kbrd/kbrd.h>
 #include <genarch/srln/srln.h>
@@ -61,5 +61,5 @@
 	icp_hw_map_t hw_map;
 	irq_t timer_irq;
-	arm926_uart_t uart;
+	pl011_uart_t uart;
 } icp;
 
@@ -314,7 +314,6 @@
 		stdout_wire(fbdev);
 #endif
-#ifdef CONFIG_ARM926_UART
-	if (arm926_uart_init(&icp.uart, ARM926_UART0_IRQ,
-	    ARM926_UART0_BASE_ADDRESS, sizeof(arm926_uart_regs_t)))
+#ifdef CONFIG_PL011_UART
+	if (pl011_uart_init(&icp.uart, ICP_UART0_IRQ, ICP_UART))
 		stdout_wire(&icp.uart.outdev);
 #endif
@@ -350,11 +349,11 @@
 	    ICP_KBD);
 
-#ifdef CONFIG_ARM926_UART
+#ifdef CONFIG_PL011_UART
         srln_instance_t *srln_instance = srln_init();
         if (srln_instance) {
                 indev_t *sink = stdin_wire();
                 indev_t *srln = srln_wire(srln_instance, sink);
-                arm926_uart_input_wire(&icp.uart, srln);
-		icp_irqc_unmask(ARM926_UART0_IRQ);
+                pl011_uart_input_wire(&icp.uart, srln);
+                icp_irqc_unmask(ICP_UART0_IRQ);
         }
 #endif
Index: kernel/arch/arm32/src/mach/raspberrypi/raspberrypi.c
===================================================================
--- kernel/arch/arm32/src/mach/raspberrypi/raspberrypi.c	(revision 0dfa93b0cda81f93598fc30620d75a22c14f06d2)
+++ kernel/arch/arm32/src/mach/raspberrypi/raspberrypi.c	(revision c88250553aba5820e5ea6bf156edf1ed176d8737)
@@ -36,5 +36,5 @@
 #include <arch/exception.h>
 #include <arch/mach/raspberrypi/raspberrypi.h>
-#include <genarch/drivers/bcm2835/pl011_uart.h>
+#include <genarch/drivers/pl011/pl011.h>
 #include <genarch/drivers/bcm2835/irc.h>
 #include <genarch/drivers/bcm2835/timer.h>
@@ -169,8 +169,7 @@
 static void raspberrypi_output_init(void)
 {
-#ifdef CONFIG_BCM2835_UART
+#ifdef CONFIG_PL011_UART
 	if (pl011_uart_init(&raspi.uart, BCM2835_UART_IRQ,
-			    PL011_UART0_BASE_ADDRESS,
-			    sizeof(pl011_uart_regs_t)))
+			    BCM2835_UART0_BASE_ADDRESS))
 		stdout_wire(&raspi.uart.outdev);
 #endif
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision 0dfa93b0cda81f93598fc30620d75a22c14f06d2)
+++ kernel/genarch/Makefile.inc	(revision c88250553aba5820e5ea6bf156edf1ed176d8737)
@@ -91,12 +91,7 @@
 endif
 
-ifeq ($(CONFIG_ARM926_UART),y)
+ifeq ($(CONFIG_PL011_UART),y)
 	GENARCH_SOURCES += \
-		genarch/src/drivers/arm926_uart/arm926_uart.c
-endif
-
-ifeq ($(CONFIG_BCM2835_UART),y)
-	GENARCH_SOURCES += \
-		genarch/src/drivers/bcm2835/pl011_uart.c
+		genarch/src/drivers/pl011/pl011.c
 endif
 
Index: rnel/genarch/include/genarch/drivers/arm926_uart/arm926_uart.h
===================================================================
--- kernel/genarch/include/genarch/drivers/arm926_uart/arm926_uart.h	(revision 0dfa93b0cda81f93598fc30620d75a22c14f06d2)
+++ 	(revision )
@@ -1,169 +1,0 @@
-/*
- * Copyright (c) 2012 Jan Vesely
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genarch
- * @{
- */
-/**
- * @file
- * @brief ARM926 on-chip UART (PrimeCell UART, PL011) driver.
- */
-
-#ifndef KERN_ARM926_UART_H_
-#define KERN_ARM926_UART_H_
-
-#include <ddi/irq.h>
-#include <console/chardev.h>
-#include <typedefs.h>
-
-
-/** ARM926 User Guide ch. 4.8.5 (p. 106 in the pdf) */
-#define ARM926_UART0_BASE_ADDRESS   0x16000000
-#define ARM926_UART1_BASE_ADDRESS   0x16000000
-
-/** ARM926 User Guide ch. A.1 (p. 124 in the pdf) */
-#define ARM926_UART0_IRQ   1
-#define ARM926_UART1_IRQ   2
-
-/** PrimeCell UART TRM ch. 3.3 (p. 49 in the pdf) */
-typedef struct {
-	/** UART data register */
-	ioport32_t data;
-#define ARM926_UART_DATA_DATA_MASK   0xff
-#define ARM926_UART_DATA_FE_FLAG   (1 <<  7)
-#define ARM926_UART_DATA_PE_FLAG   (1 <<  9)
-#define ARM926_UART_DATA_BE_FLAG   (1 << 10)
-#define ARM926_UART_DATA_OE_FLAG   (1 << 11)
-
-	union {
-		/* Same values that are in upper bits of data register*/
-		const ioport32_t status;
-#define ARM926_UART_STATUS_FE_FLAG   (1 << 0)
-#define ARM926_UART_STATUS_PE_FLAG   (1 << 1)
-#define ARM926_UART_STATUS_BE_FLAG   (1 << 2)
-#define ARM926_UART_STATUS_OE_FLAG   (1 << 3)
-		/* Writing anything clears all errors */
-		ioport32_t error_clear;
-	};
-	uint32_t padd0_[4];
-
-	const ioport32_t flag;
-#define ARM926_UART_FLAG_CTS_FLAG    (1 << 0)
-#define ARM926_UART_FLAG_DSR_FLAG    (1 << 1)
-#define ARM926_UART_FLAG_DCD_FLAG    (1 << 2)
-#define ARM926_UART_FLAG_BUSY_FLAG   (1 << 3)
-#define ARM926_UART_FLAG_RXFE_FLAG   (1 << 4)
-#define ARM926_UART_FLAG_TXFF_FLAG   (1 << 5)
-#define ARM926_UART_FLAG_RXFF_FLAG   (1 << 6)
-#define ARM926_UART_FLAG_TXFE_FLAG   (1 << 7)
-#define ARM926_UART_FLAG_RI_FLAG     (1 << 8)
-	uint32_t padd1_;
-
-	ioport32_t irda_low_power;
-#define ARM926_UART_IRDA_LOW_POWER_MASK   0xff
-
-	ioport32_t int_baud_divisor;
-#define ARM926_UART_INT_BAUD_DIVISOR_MASK   0xffff
-
-	ioport32_t fract_baud_divisor;
-#define ARM926_UART_FRACT_BAUD_DIVISOR_MASK   0x1f
-
-	ioport32_t line_control_high;
-#define ARM926_UART_CONTROLHI_BRK_FLAG    (1 << 0)
-#define ARM926_UART_CONTROLHI_PEN_FLAG    (1 << 1)
-#define ARM926_UART_CONTROLHI_EPS_FLAG    (1 << 2)
-#define ARM926_UART_CONTROLHI_STP2_FLAG   (1 << 3)
-#define ARM926_UART_CONTROLHI_FEN_FLAG    (1 << 4)
-#define ARM926_UART_CONTROLHI_WLEN_MASK   0x3
-#define ARM926_UART_CONTROLHI_WLEN_SHIFT    5
-#define ARM926_UART_CONTROLHI_SPS_FLAG    (1 << 5)
-
-	ioport32_t control;
-#define ARM926_UART_CONTROL_UARTEN_FLAG   (1 << 0)
-#define ARM926_UART_CONTROL_SIREN_FLAG    (1 << 1)
-#define ARM926_UART_CONTROL_SIRLP_FLAG    (1 << 2)
-#define ARM926_UART_CONTROL_LBE_FLAG      (1 << 7)
-#define ARM926_UART_CONTROL_TXE_FLAG      (1 << 8)
-#define ARM926_UART_CONTROL_RXE_FLAG      (1 << 9)
-#define ARM926_UART_CONTROL_DTR_FLAG     (1 << 10)
-#define ARM926_UART_CONTROL_RTS_FLAG     (1 << 11)
-#define ARM926_UART_CONTROL_OUT1_FLAG    (1 << 12)
-#define ARM926_UART_CONTROL_OUT2_FLAG    (1 << 13)
-#define ARM926_UART_CONTROL_RTSE_FLAG    (1 << 14)
-#define ARM926_UART_CONTROL_CTSE_FLAG    (1 << 15)
-
-	ioport32_t interrupt_fifo;
-#define ARM926_UART_INTERRUPTFIFO_TX_MASK   0x7
-#define ARM926_UART_INTERRUPTFIFO_TX_SHIFT    0
-#define ARM926_UART_INTERRUPTFIFO_RX_MASK   0x7
-#define ARM926_UART_INTERRUPTFIFO_RX_SHIFT    3
-
-	/** Interrupt mask register */
-	ioport32_t interrupt_mask;
-	/** Pending interrupts before applying the mask */
-	const ioport32_t raw_interrupt_status;
-	/** Pending interrupts after applying the mask */
-	const ioport32_t masked_interrupt_status;
-	/** Write 1s to clear pending interrupts */
-	ioport32_t interrupt_clear;
-#define ARM926_UART_INTERRUPT_RIM_FLAG    (1 << 0)
-#define ARM926_UART_INTERRUPT_CTSM_FLAG   (1 << 1)
-#define ARM926_UART_INTERRUPT_DCDM_FLAG   (1 << 2)
-#define ARM926_UART_INTERRUPT_DSRM_FLAG   (1 << 3)
-#define ARM926_UART_INTERRUPT_RX_FLAG     (1 << 4)
-#define ARM926_UART_INTERRUPT_TX_FLAG     (1 << 5)
-#define ARM926_UART_INTERRUPT_RT_FLAG     (1 << 6)
-#define ARM926_UART_INTERRUPT_FE_FLAG     (1 << 7)
-#define ARM926_UART_INTERRUPT_PE_FLAG     (1 << 8)
-#define ARM926_UART_INTERRUPT_BE_FLAG     (1 << 9)
-#define ARM926_UART_INTERRUPT_OE_FLAG    (1 << 10)
-#define ARM926_UART_INTERRUPT_ALL           0x3ff
-
-	ioport32_t dma_control;
-#define ARM926_UART_DMACONTROL_RXDMAEN_FLAG    (1 << 0)
-#define ARM926_UART_DMACONTROL_TXDMAEN_FLAG    (1 << 1)
-#define ARM926_UART_DMACONTROL_DMAONERR_FLAG   (1 << 2)
-
-	// TODO There is some reserved space here followed by
-	// peripheral identification registers.
-} arm926_uart_regs_t;
-
-typedef struct {
-	arm926_uart_regs_t *regs;
-	indev_t *indev;
-	outdev_t outdev;
-	irq_t irq;
-} arm926_uart_t;
-
-bool arm926_uart_init(arm926_uart_t *, inr_t, uintptr_t, size_t);
-void arm926_uart_input_wire(arm926_uart_t *, indev_t *);
-
-#endif
-/**
- * @}
- */
Index: rnel/genarch/include/genarch/drivers/bcm2835/pl011_uart.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/pl011_uart.h	(revision 0dfa93b0cda81f93598fc30620d75a22c14f06d2)
+++ 	(revision )
@@ -1,162 +1,0 @@
-/*
- * Copyright (c) 2012 Jan Vesely
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genarch
- * @{
- */
-/**
- * @file
- * @brief PL011 on-chip UART (PrimeCell UART, PL011) driver.
- */
-
-#ifndef KERN_PL011_UART_H_
-#define KERN_PL011_UART_H_
-
-#include <ddi/irq.h>
-#include <console/chardev.h>
-#include <typedefs.h>
-
-#define PL011_UART0_BASE_ADDRESS   0x20201000
-
-/** PrimeCell UART TRM ch. 3.3 (p. 49 in the pdf) */
-typedef struct {
-	/** UART data register */
-	ioport32_t data;
-#define PL011_UART_DATA_DATA_MASK   0xff
-#define PL011_UART_DATA_FE_FLAG   (1 <<  7)
-#define PL011_UART_DATA_PE_FLAG   (1 <<  9)
-#define PL011_UART_DATA_BE_FLAG   (1 << 10)
-#define PL011_UART_DATA_OE_FLAG   (1 << 11)
-
-	union {
-		/* Same values that are in upper bits of data register*/
-		const ioport32_t status;
-#define PL011_UART_STATUS_FE_FLAG   (1 << 0)
-#define PL011_UART_STATUS_PE_FLAG   (1 << 1)
-#define PL011_UART_STATUS_BE_FLAG   (1 << 2)
-#define PL011_UART_STATUS_OE_FLAG   (1 << 3)
-		/* Writing anything clears all errors */
-		ioport32_t error_clear;
-	};
-	uint32_t padd0_[4];
-
-	const ioport32_t flag;
-#define PL011_UART_FLAG_CTS_FLAG    (1 << 0)
-#define PL011_UART_FLAG_DSR_FLAG    (1 << 1)
-#define PL011_UART_FLAG_DCD_FLAG    (1 << 2)
-#define PL011_UART_FLAG_BUSY_FLAG   (1 << 3)
-#define PL011_UART_FLAG_RXFE_FLAG   (1 << 4)
-#define PL011_UART_FLAG_TXFF_FLAG   (1 << 5)
-#define PL011_UART_FLAG_RXFF_FLAG   (1 << 6)
-#define PL011_UART_FLAG_TXFE_FLAG   (1 << 7)
-#define PL011_UART_FLAG_RI_FLAG     (1 << 8)
-	uint32_t padd1_;
-
-	ioport32_t irda_low_power;
-#define PL011_UART_IRDA_LOW_POWER_MASK   0xff
-
-	ioport32_t int_baud_divisor;
-#define PL011_UART_INT_BAUD_DIVISOR_MASK   0xffff
-
-	ioport32_t fract_baud_divisor;
-#define PL011_UART_FRACT_BAUD_DIVISOR_MASK   0x1f
-
-	ioport32_t line_control_high;
-#define PL011_UART_CONTROLHI_BRK_FLAG    (1 << 0)
-#define PL011_UART_CONTROLHI_PEN_FLAG    (1 << 1)
-#define PL011_UART_CONTROLHI_EPS_FLAG    (1 << 2)
-#define PL011_UART_CONTROLHI_STP2_FLAG   (1 << 3)
-#define PL011_UART_CONTROLHI_FEN_FLAG    (1 << 4)
-#define PL011_UART_CONTROLHI_WLEN_MASK   0x3
-#define PL011_UART_CONTROLHI_WLEN_SHIFT    5
-#define PL011_UART_CONTROLHI_SPS_FLAG    (1 << 5)
-
-	ioport32_t control;
-#define PL011_UART_CONTROL_UARTEN_FLAG   (1 << 0)
-#define PL011_UART_CONTROL_SIREN_FLAG    (1 << 1)
-#define PL011_UART_CONTROL_SIRLP_FLAG    (1 << 2)
-#define PL011_UART_CONTROL_LBE_FLAG      (1 << 7)
-#define PL011_UART_CONTROL_TXE_FLAG      (1 << 8)
-#define PL011_UART_CONTROL_RXE_FLAG      (1 << 9)
-#define PL011_UART_CONTROL_DTR_FLAG     (1 << 10)
-#define PL011_UART_CONTROL_RTS_FLAG     (1 << 11)
-#define PL011_UART_CONTROL_OUT1_FLAG    (1 << 12)
-#define PL011_UART_CONTROL_OUT2_FLAG    (1 << 13)
-#define PL011_UART_CONTROL_RTSE_FLAG    (1 << 14)
-#define PL011_UART_CONTROL_CTSE_FLAG    (1 << 15)
-
-	ioport32_t interrupt_fifo;
-#define PL011_UART_INTERRUPTFIFO_TX_MASK   0x7
-#define PL011_UART_INTERRUPTFIFO_TX_SHIFT    0
-#define PL011_UART_INTERRUPTFIFO_RX_MASK   0x7
-#define PL011_UART_INTERRUPTFIFO_RX_SHIFT    3
-
-	/** Interrupt mask register */
-	ioport32_t interrupt_mask;
-	/** Pending interrupts before applying the mask */
-	const ioport32_t raw_interrupt_status;
-	/** Pending interrupts after applying the mask */
-	const ioport32_t masked_interrupt_status;
-	/** Write 1s to clear pending interrupts */
-	ioport32_t interrupt_clear;
-#define PL011_UART_INTERRUPT_RIM_FLAG    (1 << 0)
-#define PL011_UART_INTERRUPT_CTSM_FLAG   (1 << 1)
-#define PL011_UART_INTERRUPT_DCDM_FLAG   (1 << 2)
-#define PL011_UART_INTERRUPT_DSRM_FLAG   (1 << 3)
-#define PL011_UART_INTERRUPT_RX_FLAG     (1 << 4)
-#define PL011_UART_INTERRUPT_TX_FLAG     (1 << 5)
-#define PL011_UART_INTERRUPT_RT_FLAG     (1 << 6)
-#define PL011_UART_INTERRUPT_FE_FLAG     (1 << 7)
-#define PL011_UART_INTERRUPT_PE_FLAG     (1 << 8)
-#define PL011_UART_INTERRUPT_BE_FLAG     (1 << 9)
-#define PL011_UART_INTERRUPT_OE_FLAG    (1 << 10)
-#define PL011_UART_INTERRUPT_ALL           0x3ff
-
-	ioport32_t dma_control;
-#define PL011_UART_DMACONTROL_RXDMAEN_FLAG    (1 << 0)
-#define PL011_UART_DMACONTROL_TXDMAEN_FLAG    (1 << 1)
-#define PL011_UART_DMACONTROL_DMAONERR_FLAG   (1 << 2)
-
-	// TODO There is some reserved space here followed by
-	// peripheral identification registers.
-} pl011_uart_regs_t;
-
-typedef struct {
-	pl011_uart_regs_t *regs;
-	indev_t *indev;
-	outdev_t outdev;
-	irq_t irq;
-} pl011_uart_t;
-
-bool pl011_uart_init(pl011_uart_t *, inr_t, uintptr_t, size_t);
-void pl011_uart_input_wire(pl011_uart_t *, indev_t *);
-
-#endif
-/**
- * @}
- */
Index: kernel/genarch/include/genarch/drivers/pl011/pl011.h
===================================================================
--- kernel/genarch/include/genarch/drivers/pl011/pl011.h	(revision c88250553aba5820e5ea6bf156edf1ed176d8737)
+++ kernel/genarch/include/genarch/drivers/pl011/pl011.h	(revision c88250553aba5820e5ea6bf156edf1ed176d8737)
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2012 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief ARM PrimeCell PL011 UART driver.
+ */
+
+#ifndef KERN_PL011_H_
+#define KERN_PL011_H_
+
+#include <ddi/irq.h>
+#include <console/chardev.h>
+#include <typedefs.h>
+
+/** PrimeCell UART TRM ch. 3.3 (p. 49 in the pdf) */
+typedef struct {
+	/** UART data register */
+	ioport32_t data;
+#define PL011_UART_DATA_DATA_MASK   0xff
+#define PL011_UART_DATA_FE_FLAG   (1 <<  7)
+#define PL011_UART_DATA_PE_FLAG   (1 <<  9)
+#define PL011_UART_DATA_BE_FLAG   (1 << 10)
+#define PL011_UART_DATA_OE_FLAG   (1 << 11)
+
+	union {
+		/* Same values that are in upper bits of data register*/
+		const ioport32_t status;
+#define PL011_UART_STATUS_FE_FLAG   (1 << 0)
+#define PL011_UART_STATUS_PE_FLAG   (1 << 1)
+#define PL011_UART_STATUS_BE_FLAG   (1 << 2)
+#define PL011_UART_STATUS_OE_FLAG   (1 << 3)
+		/* Writing anything clears all errors */
+		ioport32_t error_clear;
+	};
+	uint32_t padd0_[4];
+
+	const ioport32_t flag;
+#define PL011_UART_FLAG_CTS_FLAG    (1 << 0)
+#define PL011_UART_FLAG_DSR_FLAG    (1 << 1)
+#define PL011_UART_FLAG_DCD_FLAG    (1 << 2)
+#define PL011_UART_FLAG_BUSY_FLAG   (1 << 3)
+#define PL011_UART_FLAG_RXFE_FLAG   (1 << 4)
+#define PL011_UART_FLAG_TXFF_FLAG   (1 << 5)
+#define PL011_UART_FLAG_RXFF_FLAG   (1 << 6)
+#define PL011_UART_FLAG_TXFE_FLAG   (1 << 7)
+#define PL011_UART_FLAG_RI_FLAG     (1 << 8)
+	uint32_t padd1_;
+
+	ioport32_t irda_low_power;
+#define PL011_UART_IRDA_LOW_POWER_MASK   0xff
+
+	ioport32_t int_baud_divisor;
+#define PL011_UART_INT_BAUD_DIVISOR_MASK   0xffff
+
+	ioport32_t fract_baud_divisor;
+#define PL011_UART_FRACT_BAUD_DIVISOR_MASK   0x1f
+
+	ioport32_t line_control_high;
+#define PL011_UART_CONTROLHI_BRK_FLAG    (1 << 0)
+#define PL011_UART_CONTROLHI_PEN_FLAG    (1 << 1)
+#define PL011_UART_CONTROLHI_EPS_FLAG    (1 << 2)
+#define PL011_UART_CONTROLHI_STP2_FLAG   (1 << 3)
+#define PL011_UART_CONTROLHI_FEN_FLAG    (1 << 4)
+#define PL011_UART_CONTROLHI_WLEN_MASK   0x3
+#define PL011_UART_CONTROLHI_WLEN_SHIFT    5
+#define PL011_UART_CONTROLHI_SPS_FLAG    (1 << 5)
+
+	ioport32_t control;
+#define PL011_UART_CONTROL_UARTEN_FLAG   (1 << 0)
+#define PL011_UART_CONTROL_SIREN_FLAG    (1 << 1)
+#define PL011_UART_CONTROL_SIRLP_FLAG    (1 << 2)
+#define PL011_UART_CONTROL_LBE_FLAG      (1 << 7)
+#define PL011_UART_CONTROL_TXE_FLAG      (1 << 8)
+#define PL011_UART_CONTROL_RXE_FLAG      (1 << 9)
+#define PL011_UART_CONTROL_DTR_FLAG     (1 << 10)
+#define PL011_UART_CONTROL_RTS_FLAG     (1 << 11)
+#define PL011_UART_CONTROL_OUT1_FLAG    (1 << 12)
+#define PL011_UART_CONTROL_OUT2_FLAG    (1 << 13)
+#define PL011_UART_CONTROL_RTSE_FLAG    (1 << 14)
+#define PL011_UART_CONTROL_CTSE_FLAG    (1 << 15)
+
+	ioport32_t interrupt_fifo;
+#define PL011_UART_INTERRUPTFIFO_TX_MASK   0x7
+#define PL011_UART_INTERRUPTFIFO_TX_SHIFT    0
+#define PL011_UART_INTERRUPTFIFO_RX_MASK   0x7
+#define PL011_UART_INTERRUPTFIFO_RX_SHIFT    3
+
+	/** Interrupt mask register */
+	ioport32_t interrupt_mask;
+	/** Pending interrupts before applying the mask */
+	const ioport32_t raw_interrupt_status;
+	/** Pending interrupts after applying the mask */
+	const ioport32_t masked_interrupt_status;
+	/** Write 1s to clear pending interrupts */
+	ioport32_t interrupt_clear;
+#define PL011_UART_INTERRUPT_RIM_FLAG    (1 << 0)
+#define PL011_UART_INTERRUPT_CTSM_FLAG   (1 << 1)
+#define PL011_UART_INTERRUPT_DCDM_FLAG   (1 << 2)
+#define PL011_UART_INTERRUPT_DSRM_FLAG   (1 << 3)
+#define PL011_UART_INTERRUPT_RX_FLAG     (1 << 4)
+#define PL011_UART_INTERRUPT_TX_FLAG     (1 << 5)
+#define PL011_UART_INTERRUPT_RT_FLAG     (1 << 6)
+#define PL011_UART_INTERRUPT_FE_FLAG     (1 << 7)
+#define PL011_UART_INTERRUPT_PE_FLAG     (1 << 8)
+#define PL011_UART_INTERRUPT_BE_FLAG     (1 << 9)
+#define PL011_UART_INTERRUPT_OE_FLAG    (1 << 10)
+#define PL011_UART_INTERRUPT_ALL           0x3ff
+
+	ioport32_t dma_control;
+#define PL011_UART_DMACONTROL_RXDMAEN_FLAG    (1 << 0)
+#define PL011_UART_DMACONTROL_TXDMAEN_FLAG    (1 << 1)
+#define PL011_UART_DMACONTROL_DMAONERR_FLAG   (1 << 2)
+
+	// TODO There is some reserved space here followed by
+	// peripheral identification registers.
+} pl011_uart_regs_t;
+
+typedef struct {
+	pl011_uart_regs_t *regs;
+	indev_t *indev;
+	outdev_t outdev;
+	irq_t irq;
+} pl011_uart_t;
+
+bool pl011_uart_init(pl011_uart_t *, inr_t, uintptr_t);
+void pl011_uart_input_wire(pl011_uart_t *, indev_t *);
+
+#endif
+/**
+ * @}
+ */
Index: rnel/genarch/src/drivers/arm926_uart/arm926_uart.c
===================================================================
--- kernel/genarch/src/drivers/arm926_uart/arm926_uart.c	(revision 0dfa93b0cda81f93598fc30620d75a22c14f06d2)
+++ 	(revision )
@@ -1,140 +1,0 @@
-/*
- * Copyright (c) 2012 Jan Vesely
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genarch
- * @{
- */
-/**
- * @file
- * @brief ARM926 on-chip UART (PrimeCell UART, PL011) driver.
- */
-
-#include <genarch/drivers/arm926_uart/arm926_uart.h>
-#include <console/chardev.h>
-#include <console/console.h>
-#include <ddi/device.h>
-#include <arch/asm.h>
-#include <mm/slab.h>
-#include <mm/page.h>
-#include <mm/km.h>
-#include <sysinfo/sysinfo.h>
-#include <str.h>
-
-static void arm926_uart_sendb(arm926_uart_t *uart, uint8_t byte)
-{
-	/* Wait for space becoming available in Tx FIFO. */
-	// TODO make pio_read accept consts pointers and remove the cast
-	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & ARM926_UART_FLAG_TXFF_FLAG) != 0)
-		;
-
-	pio_write_32(&uart->regs->data, byte);
-}
-
-static void arm926_uart_putchar(outdev_t *dev, wchar_t ch)
-{
-	arm926_uart_t *uart = dev->data;
-
-	if (!ascii_check(ch)) {
-		arm926_uart_sendb(uart, U_SPECIAL);
-	} else {
-		if (ch == '\n')
-			arm926_uart_sendb(uart, (uint8_t) '\r');
-		arm926_uart_sendb(uart, (uint8_t) ch);
-	}
-}
-
-static outdev_operations_t arm926_uart_ops = {
-	.write = arm926_uart_putchar,
-	.redraw = NULL,
-};
-
-static irq_ownership_t arm926_uart_claim(irq_t *irq)
-{
-	return IRQ_ACCEPT;
-}
-
-static void arm926_uart_irq_handler(irq_t *irq)
-{
-	arm926_uart_t *uart = irq->instance;
-
-	// TODO make pio_read accept const pointers and remove the cast
-	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & ARM926_UART_FLAG_RXFE_FLAG) == 0) {
-		/* We ignore all error flags here */
-		const uint8_t data = pio_read_32(&uart->regs->data);
-		if (uart->indev)
-			indev_push_character(uart->indev, data);
-	}
-	/* Ack interrupts */
-	pio_write_32(&uart->regs->interrupt_clear, ARM926_UART_INTERRUPT_ALL);
-}
-
-bool arm926_uart_init(
-    arm926_uart_t *uart, inr_t interrupt, uintptr_t addr, size_t size)
-{
-	ASSERT(uart);
-	uart->regs = (void*)km_map(addr, size, PAGE_NOT_CACHEABLE);
-
-	ASSERT(uart->regs);
-
-	/* Enable hw flow control */
-	uart->regs->control = 0 |
-	    ARM926_UART_CONTROL_UARTEN_FLAG |
-	    ARM926_UART_CONTROL_RTSE_FLAG |
-	    ARM926_UART_CONTROL_CTSE_FLAG;
-
-	/* Mask all interrupts */
-	uart->regs->interrupt_mask = 0;
-
-	outdev_initialize("arm926_uart_dev", &uart->outdev, &arm926_uart_ops);
-	uart->outdev.data = uart;
-
-	/* Initialize IRQ */
-	irq_initialize(&uart->irq);
-        uart->irq.devno = device_assign_devno();
-        uart->irq.inr = interrupt;
-        uart->irq.claim = arm926_uart_claim;
-        uart->irq.handler = arm926_uart_irq_handler;
-        uart->irq.instance = uart;
-
-	return true;
-}
-
-void arm926_uart_input_wire(arm926_uart_t *uart, indev_t *indev)
-{
-	ASSERT(uart);
-	ASSERT(indev);
-
-	uart->indev = indev;
-	irq_register(&uart->irq);
-	/* Enable receive interrupt */
-	uart->regs->interrupt_mask |= ARM926_UART_INTERRUPT_RX_FLAG;
-}
-
-/** @}
- */
-
Index: rnel/genarch/src/drivers/bcm2835/pl011_uart.c
===================================================================
--- kernel/genarch/src/drivers/bcm2835/pl011_uart.c	(revision 0dfa93b0cda81f93598fc30620d75a22c14f06d2)
+++ 	(revision )
@@ -1,146 +1,0 @@
-/*
- * Copyright (c) 2012 Jan Vesely
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genarch
- * @{
- */
-/**
- * @file
- * @brief PL011 on-chip UART (PrimeCell UART, PL011) driver.
- */
-
-#include <genarch/drivers/bcm2835/pl011_uart.h>
-#include <console/chardev.h>
-#include <console/console.h>
-#include <ddi/device.h>
-#include <arch/asm.h>
-#include <mm/slab.h>
-#include <mm/page.h>
-#include <mm/km.h>
-#include <sysinfo/sysinfo.h>
-#include <str.h>
-
-static void pl011_uart_sendb(pl011_uart_t *uart, uint8_t byte)
-{
-	/* Wait for space becoming available in Tx FIFO. */
-	// TODO make pio_read accept consts pointers and remove the cast
-	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & PL011_UART_FLAG_TXFF_FLAG) != 0)
-		;
-
-	pio_write_32(&uart->regs->data, byte);
-}
-
-static void pl011_uart_putchar(outdev_t *dev, wchar_t ch)
-{
-	pl011_uart_t *uart = dev->data;
-
-	if (!ascii_check(ch)) {
-		pl011_uart_sendb(uart, U_SPECIAL);
-	} else {
-		if (ch == '\n')
-			pl011_uart_sendb(uart, (uint8_t) '\r');
-		pl011_uart_sendb(uart, (uint8_t) ch);
-	}
-}
-
-static outdev_operations_t pl011_uart_ops = {
-	.write = pl011_uart_putchar,
-	.redraw = NULL,
-};
-
-static irq_ownership_t pl011_uart_claim(irq_t *irq)
-{
-	return IRQ_ACCEPT;
-}
-
-static void pl011_uart_irq_handler(irq_t *irq)
-{
-	pl011_uart_t *uart = irq->instance;
-
-	// TODO make pio_read accept const pointers and remove the cast
-	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & PL011_UART_FLAG_RXFE_FLAG) == 0) {
-		/* We ignore all error flags here */
-		const uint8_t data = pio_read_32(&uart->regs->data);
-		if (uart->indev)
-			indev_push_character(uart->indev, data);
-	}
-	/* Ack interrupts */
-	pio_write_32(&uart->regs->interrupt_clear, PL011_UART_INTERRUPT_ALL);
-}
-
-bool pl011_uart_init(pl011_uart_t *uart, inr_t interrupt, uintptr_t addr, size_t size)
-{
-	ASSERT(uart);
-	uart->regs = (void*)km_map(addr, size, PAGE_NOT_CACHEABLE);
-
-	ASSERT(uart->regs);
-
-	uart->regs->control = 0;
-	uart->regs->interrupt_clear = 0x7f;
-	uart->regs->int_baud_divisor = 1;
-	uart->regs->fract_baud_divisor = 40;
-	uart->regs->line_control_high = PL011_UART_CONTROLHI_FEN_FLAG |
-		(3 << PL011_UART_CONTROLHI_WLEN_SHIFT);
-
-	/* Enable TX and RX */
-	uart->regs->control = 0 |
-		PL011_UART_CONTROL_UARTEN_FLAG |
-		PL011_UART_CONTROL_TXE_FLAG |
-		PL011_UART_CONTROL_RXE_FLAG;
-
-	/* Mask all interrupts */
-	uart->regs->interrupt_mask = 0;
-
-	outdev_initialize("pl011_uart_dev", &uart->outdev, &pl011_uart_ops);
-	uart->outdev.data = uart;
-
-	/* Initialize IRQ */
-	irq_initialize(&uart->irq);
-	uart->irq.devno = device_assign_devno();
-	uart->irq.inr = interrupt;
-	uart->irq.claim = pl011_uart_claim;
-	uart->irq.handler = pl011_uart_irq_handler;
-	uart->irq.instance = uart;
-	return true;
-}
-
-void pl011_uart_input_wire(pl011_uart_t *uart, indev_t *indev)
-{
-	ASSERT(uart);
-	ASSERT(indev);
-
-	uart->indev = indev;
-	irq_register(&uart->irq);
-	/* Enable receive interrupt */
-	uart->regs->interrupt_mask |= (PL011_UART_INTERRUPT_RX_FLAG |
-				       PL011_UART_INTERRUPT_RT_FLAG);
-}
-
-/** @}
- */
-
Index: kernel/genarch/src/drivers/pl011/pl011.c
===================================================================
--- kernel/genarch/src/drivers/pl011/pl011.c	(revision c88250553aba5820e5ea6bf156edf1ed176d8737)
+++ kernel/genarch/src/drivers/pl011/pl011.c	(revision c88250553aba5820e5ea6bf156edf1ed176d8737)
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2012 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief ARM PrimeCell PL011 UART driver.
+ */
+
+#include <genarch/drivers/pl011/pl011.h>
+#include <console/chardev.h>
+#include <console/console.h>
+#include <ddi/device.h>
+#include <arch/asm.h>
+#include <mm/slab.h>
+#include <mm/page.h>
+#include <mm/km.h>
+#include <sysinfo/sysinfo.h>
+#include <str.h>
+
+static void pl011_uart_sendb(pl011_uart_t *uart, uint8_t byte)
+{
+	/* Wait for space becoming available in Tx FIFO. */
+	// TODO make pio_read accept consts pointers and remove the cast
+	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & PL011_UART_FLAG_TXFF_FLAG) != 0)
+		;
+
+	pio_write_32(&uart->regs->data, byte);
+}
+
+static void pl011_uart_putchar(outdev_t *dev, wchar_t ch)
+{
+	pl011_uart_t *uart = dev->data;
+
+	if (!ascii_check(ch)) {
+		pl011_uart_sendb(uart, U_SPECIAL);
+	} else {
+		if (ch == '\n')
+			pl011_uart_sendb(uart, (uint8_t) '\r');
+		pl011_uart_sendb(uart, (uint8_t) ch);
+	}
+}
+
+static outdev_operations_t pl011_uart_ops = {
+	.write = pl011_uart_putchar,
+	.redraw = NULL,
+};
+
+static irq_ownership_t pl011_uart_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void pl011_uart_irq_handler(irq_t *irq)
+{
+	pl011_uart_t *uart = irq->instance;
+
+	// TODO make pio_read accept const pointers and remove the cast
+	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & PL011_UART_FLAG_RXFE_FLAG) == 0) {
+		/* We ignore all error flags here */
+		const uint8_t data = pio_read_32(&uart->regs->data);
+		if (uart->indev)
+			indev_push_character(uart->indev, data);
+	}
+	/* Ack interrupts */
+	pio_write_32(&uart->regs->interrupt_clear, PL011_UART_INTERRUPT_ALL);
+}
+
+bool pl011_uart_init(pl011_uart_t *uart, inr_t interrupt, uintptr_t addr)
+{
+	ASSERT(uart);
+	uart->regs = (void*)km_map(addr, sizeof(pl011_uart_regs_t),
+				   PAGE_NOT_CACHEABLE);
+	ASSERT(uart->regs);
+
+	/* Disable UART */
+	uart->regs->control &= ~ PL011_UART_CONTROL_UARTEN_FLAG;
+
+	/* Enable hw flow control */
+	uart->regs->control |=
+		PL011_UART_CONTROL_RTSE_FLAG |
+		PL011_UART_CONTROL_CTSE_FLAG;
+
+	/* Mask all interrupts */
+	uart->regs->interrupt_mask = 0;
+	/* Clear interrupts */
+	uart->regs->interrupt_clear = PL011_UART_INTERRUPT_ALL;
+	/* Enable UART, TX and RX */
+	uart->regs->control |=
+		PL011_UART_CONTROL_UARTEN_FLAG |
+		PL011_UART_CONTROL_TXE_FLAG |
+		PL011_UART_CONTROL_RXE_FLAG;
+
+	outdev_initialize("pl011_uart_dev", &uart->outdev, &pl011_uart_ops);
+	uart->outdev.data = uart;
+
+	/* Initialize IRQ */
+	irq_initialize(&uart->irq);
+	uart->irq.devno = device_assign_devno();
+	uart->irq.inr = interrupt;
+	uart->irq.claim = pl011_uart_claim;
+	uart->irq.handler = pl011_uart_irq_handler;
+	uart->irq.instance = uart;
+
+	return true;
+}
+
+void pl011_uart_input_wire(pl011_uart_t *uart, indev_t *indev)
+{
+	ASSERT(uart);
+	ASSERT(indev);
+
+	uart->indev = indev;
+	irq_register(&uart->irq);
+	/* Enable receive interrupts */
+	uart->regs->interrupt_mask |=
+		PL011_UART_INTERRUPT_RX_FLAG |
+		PL011_UART_INTERRUPT_RT_FLAG;
+}
+
+/** @}
+ */
+
