diff mbox

[10/33] uart: Cleanup initialization and remove simulator hack

Message ID 1466808476-32690-10-git-send-email-benh@kernel.crashing.org
State Accepted
Headers show

Commit Message

Benjamin Herrenschmidt June 24, 2016, 10:47 p.m. UTC
Add more generic support for MMIO based UARTs, simplify code,
use common initialization, and clean up the device-tree
representation as well.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 core/init.c               |   7 ++-
 core/platform.c           |   8 ++-
 hw/lpc-uart.c             | 152 ++++++++++++++++++++--------------------------
 include/console.h         |   1 -
 include/skiboot.h         |   3 +-
 platforms/astbmc/common.c |   4 +-
 platforms/qemu/qemu.c     |   8 +--
 platforms/rhesus/rhesus.c |   8 +--
 8 files changed, 85 insertions(+), 106 deletions(-)

Comments

Michael Neuling July 6, 2016, 6:41 a.m. UTC | #1
CCing Ryan since he wrote some of this code.

Mikey


On Sat, 2016-06-25 at 08:47 +1000, Benjamin Herrenschmidt wrote:
> Add more generic support for MMIO based UARTs, simplify code,
> use common initialization, and clean up the device-tree
> representation as well.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>  core/init.c               |   7 ++-
>  core/platform.c           |   8 ++-
>  hw/lpc-uart.c             | 152 ++++++++++++++++++++--------------------------
>  include/console.h         |   1 -
>  include/skiboot.h         |   3 +-
>  platforms/astbmc/common.c |   4 +-
>  platforms/qemu/qemu.c     |   8 +--
>  platforms/rhesus/rhesus.c |   8 +--
>  8 files changed, 85 insertions(+), 106 deletions(-)
> 
> diff --git a/core/init.c b/core/init.c
> index 67b539b..48f5322 100644
> --- a/core/init.c
> +++ b/core/init.c
> @@ -657,10 +657,13 @@ void __noreturn main_cpu_entry(const void *fdt, u32 master_cpu)
>  	 * to access chips via that path early on.
>  	 */
>  	init_chips();
> +
> +	/* If we detect the mambo simulator, we can enable its special console
> +	 * early on. Do that now.
> +	 */
>  	if (chip_quirk(QUIRK_MAMBO_CALLOUTS))
>  		enable_mambo_console();
> -	if (chip_quirk(QUIRK_SIMICS))
> -		enable_simics_console();
> +
>  	xscom_init();
>  	mfsi_init();
>  
> diff --git a/core/platform.c b/core/platform.c
> index 371cf42..de6e406 100644
> --- a/core/platform.c
> +++ b/core/platform.c
> @@ -98,7 +98,13 @@ opal_call(OPAL_CEC_REBOOT2, opal_cec_reboot2, 2);
>  
>  static void generic_platform_init(void)
>  {
> -	force_dummy_console();
> +	/* Enable a UART if we find one in the device-tree */
> +	uart_init();
> +
> +	if (uart_enabled())
> +		uart_setup_opal_console();
> +	else
> +		force_dummy_console();
>  	fake_rtc_init();
>  }
>  
> diff --git a/hw/lpc-uart.c b/hw/lpc-uart.c
> index 433cdff..6693265 100644
> --- a/hw/lpc-uart.c
> +++ b/hw/lpc-uart.c
> @@ -64,11 +64,10 @@ DEFINE_LOG_ENTRY(OPAL_RC_UART_INIT, OPAL_PLATFORM_ERR_EVT, OPAL_UART,
>  static struct lock uart_lock = LOCK_UNLOCKED;
>  static struct dt_node *uart_node;
>  static uint32_t uart_base;
> -static bool has_irq, irq_ok, rx_full, tx_full;
> +static bool has_irq = false, irq_ok, rx_full, tx_full;
>  static uint8_t tx_room;
>  static uint8_t cached_ier;
> -static bool simics_uart;
> -static void *simics_uart_base;
> +static void *mmio_uart_base;
>  
>  static void uart_trace(u8 ctx, u8 cnt, u8 irq_state, u8 in_count)
>  {
> @@ -83,16 +82,16 @@ static void uart_trace(u8 ctx, u8 cnt, u8 irq_state, u8 in_count)
>  
>  static inline uint8_t uart_read(unsigned int reg)
>  {
> -	if (simics_uart)
> -		return in_8(simics_uart_base + reg);
> +	if (mmio_uart_base)
> +		return in_8(mmio_uart_base + reg);
>  	else
>  		return lpc_inb(uart_base + reg);
>  }
>  
>  static inline void uart_write(unsigned int reg, uint8_t val)
>  {
> -	if (simics_uart)
> -		out_8(simics_uart_base + reg, val);
> +	if (mmio_uart_base)
> +		out_8(mmio_uart_base + reg, val);
>  	else
>  		lpc_outb(val, uart_base + reg);
>  }
> @@ -121,6 +120,7 @@ static void uart_update_ier(void)
>  
>  	if (!has_irq)
>  		return;
> +
>  	/* If we have never got an interrupt, enable them all,
>  	 * the first interrupt received will tell us if interrupts
>  	 * are functional (some boards are missing an EC or FPGA
> @@ -138,6 +138,11 @@ static void uart_update_ier(void)
>  	}
>  }
>  
> +bool uart_enabled(void)
> +{
> +	return mmio_uart_base || uart_base;
> +}
> +
>  /*
>   * Internal console driver (output only)
>   */
> @@ -146,7 +151,7 @@ static size_t uart_con_write(const char *buf, size_t len)
>  	size_t written = 0;
>  
>  	/* If LPC bus is bad, we just swallow data */
> -	if (!lpc_ok() && !simics_uart)
> +	if (!lpc_ok() && !mmio_uart_base)
>  		return written;
>  
>  	lock(&uart_lock);
> @@ -362,7 +367,7 @@ static int64_t uart_opal_read(int64_t term_number, int64_t *length,
>  	uart_trace(TRACE_UART_CTX_READ, read_cnt, tx_full, in_count);
>  
>  	unlock(&uart_lock);
> -	
> +
>  	/* Adjust the OPAL event */
>  	uart_adjust_opal_event();
>  
> @@ -492,15 +497,13 @@ static struct lpc_client uart_lpc_client = {
>  	.interrupt = uart_irq,
>  };
>  
> -void uart_init(bool use_interrupt)
> +void uart_init(void)
>  {
>  	const struct dt_property *prop;
>  	struct dt_node *n;
>  	char *path __unused;
> -	uint32_t chip_id, irq;
> -
> -	if (!lpc_present())
> -		return;
> +	uint32_t chip_id;
> +	const uint32_t *irqp;
>  
>  	/* UART lock is in the console path and thus must block
>  	 * printf re-entrancy
> @@ -512,19 +515,55 @@ void uart_init(bool use_interrupt)
>  	if (!n)
>  		return;
>  
> -	/* Get IO base */
> -	prop = dt_find_property(n, "reg");
> -	if (!prop) {
> -		log_simple_error(&e_info(OPAL_RC_UART_INIT),
> -				"UART: Can't find reg property\n");
> -		return;
> -	}
> -	if (dt_property_get_cell(prop, 0) != OPAL_LPC_IO) {
> -		log_simple_error(&e_info(OPAL_RC_UART_INIT),
> -				"UART: Only supports IO addresses\n");
> -		return;
> +	/* Read the interrupts property if any */
> +	irqp = dt_prop_get_def(n, "interrupts", NULL);
> +
> +	/* Now check if the UART is on the root bus. This is the case of
> +	 * directly mapped UARTs in simulation environments
> +	 */
> +	if (n->parent == dt_root) {
> +		printf("UART: Found at root !\n");
> +		mmio_uart_base = (void *)dt_translate_address(n, 0, NULL);
> +		if (!mmio_uart_base) {
> +			printf("UART: Failed to translate address !\n");
> +			return;
> +		}
> +
> +		/* If it has an interrupt properly, we consider this to be
> +		 * a direct XICS/XIVE interrupt
> +		 */
> +		if (irqp)
> +			has_irq = true;
> +
> +	} else {
> +		if (!lpc_present())
> +			return;
> +
> +		/* Get IO base */
> +		prop = dt_find_property(n, "reg");
> +		if (!prop) {
> +			log_simple_error(&e_info(OPAL_RC_UART_INIT),
> +					 "UART: Can't find reg property\n");
> +			return;
> +		}
> +		if (dt_property_get_cell(prop, 0) != OPAL_LPC_IO) {
> +			log_simple_error(&e_info(OPAL_RC_UART_INIT),
> +					 "UART: Only supports IO addresses\n");
> +			return;
> +		}
> +		uart_base = dt_property_get_cell(prop, 1);
> +
> +		if (irqp) {
> +			uint32_t irq = be32_to_cpu(*irqp);
> +
> +			chip_id = dt_get_chip_id(uart_node);
> +			uart_lpc_client.interrupts = LPC_IRQ(irq);
> +			lpc_register_client(chip_id, &uart_lpc_client);
> +			prlog(PR_DEBUG, "UART: Using LPC IRQ %d\n", irq);
> +			has_irq = true;
> +		}
>  	}
> -	uart_base = dt_property_get_cell(prop, 1);
> +
>  
>  	if (!uart_init_hw(dt_prop_get_u32(n, "current-speed"),
>  			  dt_prop_get_u32(n, "clock-frequency"))) {
> @@ -532,7 +571,6 @@ void uart_init(bool use_interrupt)
>  		dt_add_property_strings(n, "status", "bad");
>  		return;
>  	}
> -	chip_id = dt_get_chip_id(uart_node);
>  
>  	/*
>  	 * Mark LPC used by the console (will mark the relevant
> @@ -542,65 +580,5 @@ void uart_init(bool use_interrupt)
>  
>  	/* Install console backend for printf() */
>  	set_console(&uart_con_driver);
> -
> -	/* On Naples, use the SerIRQ, which Linux will have to share with
> -	 * OPAL as we don't really play the cascaded interrupt game at this
> -	 * point...
> -	 */
> -	if (use_interrupt) {
> -		irq = dt_prop_get_u32(n, "interrupts");
> -		uart_lpc_client.interrupts = LPC_IRQ(irq);
> -		lpc_register_client(chip_id, &uart_lpc_client);
> -		has_irq = true;
> -		prlog(PR_DEBUG, "UART: Using LPC IRQ %d\n", irq);
> -	} else
> -		has_irq = false;
> -}
> -
> -static bool simics_con_poll_read(void) {
> -	uint8_t lsr = uart_read(REG_LSR);
> -	return ((lsr & LSR_DR) != 0);
>  }
>  
> -static size_t simics_con_read(char *buf, size_t len)
> -{
> -	size_t count = 0;
> -	while (count < len) {
> -		if (!simics_con_poll_read())
> -			break;
> -		*(buf++) = uart_read(REG_RBR);
> -		count++;
> -	}
> -	return count;
> -}
> -
> -static struct con_ops simics_con_driver = {
> -	.poll_read = simics_con_poll_read,
> -	.read = simics_con_read,
> -	.write = uart_con_write,
> -};
> -
> -void enable_simics_console() {
> -	struct dt_node *n;
> -
> -	printf("Enabling Simics console\n");
> -
> -	n = dt_find_compatible_node(dt_root, NULL, "ns16550");
> -	if (!n) {
> -		prerror("UART: cannot find ns16550\n");
> -		return;
> -	}
> -
> -	simics_uart_base = (void *)dt_prop_get_u64(n, "console-bar");
> -	simics_uart = 1;
> -	has_irq = false;
> -
> -	if (!uart_init_hw(dt_prop_get_u32(n, "current-speed"),
> -			  dt_prop_get_u32(n, "clock-frequency"))) {
> -		prerror("UART: Initialization failed\n");
> -		dt_add_property_strings(n, "status", "bad");
> -		return;
> -	}
> -
> -	set_console(&simics_con_driver);
> -}
> diff --git a/include/console.h b/include/console.h
> index ecb18c4..b6fc8bf 100644
> --- a/include/console.h
> +++ b/include/console.h
> @@ -67,7 +67,6 @@ extern void console_complete_flush(void);
>  extern int mambo_read(void);
>  extern void mambo_write(const char *buf, size_t count);
>  extern void enable_mambo_console(void);
> -extern void enable_simics_console(void);
>  
>  ssize_t console_write(bool flush_to_drivers, const void *buf, size_t count);
>  
> diff --git a/include/skiboot.h b/include/skiboot.h
> index ded6bb8..1d33389 100644
> --- a/include/skiboot.h
> +++ b/include/skiboot.h
> @@ -203,7 +203,7 @@ extern void probe_phb3(void);
>  extern int phb3_preload_capp_ucode(void);
>  extern void phb3_preload_vpd(void);
>  extern void probe_npu(void);
> -extern void uart_init(bool enable_interrupt);
> +extern void uart_init(void);
>  extern void homer_init(void);
>  extern void occ_pstates_init(void);
>  extern void slw_init(void);
> @@ -228,6 +228,7 @@ extern void nvram_read_complete(bool success);
>  /* UART stuff */
>  extern void uart_setup_linux_passthrough(void);
>  extern void uart_setup_opal_console(void);
> +extern bool uart_enabled(void);
>  
>  /* OCC interrupt */
>  extern void occ_interrupt(uint32_t chip_id);
> diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c
> index 1ed7d42..0699a44 100644
> --- a/platforms/astbmc/common.c
> +++ b/platforms/astbmc/common.c
> @@ -347,8 +347,8 @@ void astbmc_early_init(void)
>  	/* Similarly, some BMCs don't configure the BT interrupt properly */
>  	ast_setup_ibt(BT_IO_BASE, BT_LPC_IRQ);
>  
> -	/* Setup UART and use it as console with interrupts */
> -	uart_init(true);
> +	/* Setup UART and use it as console */
> +	uart_init();
>  
>  	prd_init();
>  }
> diff --git a/platforms/qemu/qemu.c b/platforms/qemu/qemu.c
> index 66a6aa3..a7d2889 100644
> --- a/platforms/qemu/qemu.c
> +++ b/platforms/qemu/qemu.c
> @@ -130,12 +130,8 @@ static bool qemu_probe(void)
>  
>  	psi_set_external_irq_policy(EXTERNAL_IRQ_POLICY_SKIBOOT);
>  
> -	/*
> -	 * Setup UART and use it as console. For now, we
> -	 * don't expose the interrupt as we know it's not
> -	 * working properly yet
> -	 */
> -	uart_init(true);
> +	/* Setup UART and use it as console */
> +	uart_init();
>  
>  	return true;
>  }
> diff --git a/platforms/rhesus/rhesus.c b/platforms/rhesus/rhesus.c
> index 3e2c41b..a3af777 100644
> --- a/platforms/rhesus/rhesus.c
> +++ b/platforms/rhesus/rhesus.c
> @@ -270,12 +270,8 @@ static bool rhesus_probe(void)
>  	/* Add missing bits of device-tree such as the UART */
>  	rhesus_dt_fixup(has_uart_irq);
>  
> -	/*
> -	 * Setup UART and use it as console. For now, we
> -	 * don't expose the interrupt as we know it's not
> -	 * working properly yet
> -	 */
> -	uart_init(has_uart_irq);
> +	/* Setup UART and use it as console */
> +	uart_init();
>  
>  	return true;
>  }
Michael Neuling July 6, 2016, 7:21 a.m. UTC | #2
On Sat, 2016-06-25 at 08:47 +1000, Benjamin Herrenschmidt wrote:
> Add more generic support for MMIO based UARTs, simplify code,
> use common initialization, and clean up the device-tree
> representation as well.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Acked-by: Michael Neuling <mikey@neuling.org>
diff mbox

Patch

diff --git a/core/init.c b/core/init.c
index 67b539b..48f5322 100644
--- a/core/init.c
+++ b/core/init.c
@@ -657,10 +657,13 @@  void __noreturn main_cpu_entry(const void *fdt, u32 master_cpu)
 	 * to access chips via that path early on.
 	 */
 	init_chips();
+
+	/* If we detect the mambo simulator, we can enable its special console
+	 * early on. Do that now.
+	 */
 	if (chip_quirk(QUIRK_MAMBO_CALLOUTS))
 		enable_mambo_console();
-	if (chip_quirk(QUIRK_SIMICS))
-		enable_simics_console();
+
 	xscom_init();
 	mfsi_init();
 
diff --git a/core/platform.c b/core/platform.c
index 371cf42..de6e406 100644
--- a/core/platform.c
+++ b/core/platform.c
@@ -98,7 +98,13 @@  opal_call(OPAL_CEC_REBOOT2, opal_cec_reboot2, 2);
 
 static void generic_platform_init(void)
 {
-	force_dummy_console();
+	/* Enable a UART if we find one in the device-tree */
+	uart_init();
+
+	if (uart_enabled())
+		uart_setup_opal_console();
+	else
+		force_dummy_console();
 	fake_rtc_init();
 }
 
diff --git a/hw/lpc-uart.c b/hw/lpc-uart.c
index 433cdff..6693265 100644
--- a/hw/lpc-uart.c
+++ b/hw/lpc-uart.c
@@ -64,11 +64,10 @@  DEFINE_LOG_ENTRY(OPAL_RC_UART_INIT, OPAL_PLATFORM_ERR_EVT, OPAL_UART,
 static struct lock uart_lock = LOCK_UNLOCKED;
 static struct dt_node *uart_node;
 static uint32_t uart_base;
-static bool has_irq, irq_ok, rx_full, tx_full;
+static bool has_irq = false, irq_ok, rx_full, tx_full;
 static uint8_t tx_room;
 static uint8_t cached_ier;
-static bool simics_uart;
-static void *simics_uart_base;
+static void *mmio_uart_base;
 
 static void uart_trace(u8 ctx, u8 cnt, u8 irq_state, u8 in_count)
 {
@@ -83,16 +82,16 @@  static void uart_trace(u8 ctx, u8 cnt, u8 irq_state, u8 in_count)
 
 static inline uint8_t uart_read(unsigned int reg)
 {
-	if (simics_uart)
-		return in_8(simics_uart_base + reg);
+	if (mmio_uart_base)
+		return in_8(mmio_uart_base + reg);
 	else
 		return lpc_inb(uart_base + reg);
 }
 
 static inline void uart_write(unsigned int reg, uint8_t val)
 {
-	if (simics_uart)
-		out_8(simics_uart_base + reg, val);
+	if (mmio_uart_base)
+		out_8(mmio_uart_base + reg, val);
 	else
 		lpc_outb(val, uart_base + reg);
 }
@@ -121,6 +120,7 @@  static void uart_update_ier(void)
 
 	if (!has_irq)
 		return;
+
 	/* If we have never got an interrupt, enable them all,
 	 * the first interrupt received will tell us if interrupts
 	 * are functional (some boards are missing an EC or FPGA
@@ -138,6 +138,11 @@  static void uart_update_ier(void)
 	}
 }
 
+bool uart_enabled(void)
+{
+	return mmio_uart_base || uart_base;
+}
+
 /*
  * Internal console driver (output only)
  */
@@ -146,7 +151,7 @@  static size_t uart_con_write(const char *buf, size_t len)
 	size_t written = 0;
 
 	/* If LPC bus is bad, we just swallow data */
-	if (!lpc_ok() && !simics_uart)
+	if (!lpc_ok() && !mmio_uart_base)
 		return written;
 
 	lock(&uart_lock);
@@ -362,7 +367,7 @@  static int64_t uart_opal_read(int64_t term_number, int64_t *length,
 	uart_trace(TRACE_UART_CTX_READ, read_cnt, tx_full, in_count);
 
 	unlock(&uart_lock);
-	
+
 	/* Adjust the OPAL event */
 	uart_adjust_opal_event();
 
@@ -492,15 +497,13 @@  static struct lpc_client uart_lpc_client = {
 	.interrupt = uart_irq,
 };
 
-void uart_init(bool use_interrupt)
+void uart_init(void)
 {
 	const struct dt_property *prop;
 	struct dt_node *n;
 	char *path __unused;
-	uint32_t chip_id, irq;
-
-	if (!lpc_present())
-		return;
+	uint32_t chip_id;
+	const uint32_t *irqp;
 
 	/* UART lock is in the console path and thus must block
 	 * printf re-entrancy
@@ -512,19 +515,55 @@  void uart_init(bool use_interrupt)
 	if (!n)
 		return;
 
-	/* Get IO base */
-	prop = dt_find_property(n, "reg");
-	if (!prop) {
-		log_simple_error(&e_info(OPAL_RC_UART_INIT),
-				"UART: Can't find reg property\n");
-		return;
-	}
-	if (dt_property_get_cell(prop, 0) != OPAL_LPC_IO) {
-		log_simple_error(&e_info(OPAL_RC_UART_INIT),
-				"UART: Only supports IO addresses\n");
-		return;
+	/* Read the interrupts property if any */
+	irqp = dt_prop_get_def(n, "interrupts", NULL);
+
+	/* Now check if the UART is on the root bus. This is the case of
+	 * directly mapped UARTs in simulation environments
+	 */
+	if (n->parent == dt_root) {
+		printf("UART: Found at root !\n");
+		mmio_uart_base = (void *)dt_translate_address(n, 0, NULL);
+		if (!mmio_uart_base) {
+			printf("UART: Failed to translate address !\n");
+			return;
+		}
+
+		/* If it has an interrupt properly, we consider this to be
+		 * a direct XICS/XIVE interrupt
+		 */
+		if (irqp)
+			has_irq = true;
+
+	} else {
+		if (!lpc_present())
+			return;
+
+		/* Get IO base */
+		prop = dt_find_property(n, "reg");
+		if (!prop) {
+			log_simple_error(&e_info(OPAL_RC_UART_INIT),
+					 "UART: Can't find reg property\n");
+			return;
+		}
+		if (dt_property_get_cell(prop, 0) != OPAL_LPC_IO) {
+			log_simple_error(&e_info(OPAL_RC_UART_INIT),
+					 "UART: Only supports IO addresses\n");
+			return;
+		}
+		uart_base = dt_property_get_cell(prop, 1);
+
+		if (irqp) {
+			uint32_t irq = be32_to_cpu(*irqp);
+
+			chip_id = dt_get_chip_id(uart_node);
+			uart_lpc_client.interrupts = LPC_IRQ(irq);
+			lpc_register_client(chip_id, &uart_lpc_client);
+			prlog(PR_DEBUG, "UART: Using LPC IRQ %d\n", irq);
+			has_irq = true;
+		}
 	}
-	uart_base = dt_property_get_cell(prop, 1);
+
 
 	if (!uart_init_hw(dt_prop_get_u32(n, "current-speed"),
 			  dt_prop_get_u32(n, "clock-frequency"))) {
@@ -532,7 +571,6 @@  void uart_init(bool use_interrupt)
 		dt_add_property_strings(n, "status", "bad");
 		return;
 	}
-	chip_id = dt_get_chip_id(uart_node);
 
 	/*
 	 * Mark LPC used by the console (will mark the relevant
@@ -542,65 +580,5 @@  void uart_init(bool use_interrupt)
 
 	/* Install console backend for printf() */
 	set_console(&uart_con_driver);
-
-	/* On Naples, use the SerIRQ, which Linux will have to share with
-	 * OPAL as we don't really play the cascaded interrupt game at this
-	 * point...
-	 */
-	if (use_interrupt) {
-		irq = dt_prop_get_u32(n, "interrupts");
-		uart_lpc_client.interrupts = LPC_IRQ(irq);
-		lpc_register_client(chip_id, &uart_lpc_client);
-		has_irq = true;
-		prlog(PR_DEBUG, "UART: Using LPC IRQ %d\n", irq);
-	} else
-		has_irq = false;
-}
-
-static bool simics_con_poll_read(void) {
-	uint8_t lsr = uart_read(REG_LSR);
-	return ((lsr & LSR_DR) != 0);
 }
 
-static size_t simics_con_read(char *buf, size_t len)
-{
-	size_t count = 0;
-	while (count < len) {
-		if (!simics_con_poll_read())
-			break;
-		*(buf++) = uart_read(REG_RBR);
-		count++;
-	}
-	return count;
-}
-
-static struct con_ops simics_con_driver = {
-	.poll_read = simics_con_poll_read,
-	.read = simics_con_read,
-	.write = uart_con_write,
-};
-
-void enable_simics_console() {
-	struct dt_node *n;
-
-	printf("Enabling Simics console\n");
-
-	n = dt_find_compatible_node(dt_root, NULL, "ns16550");
-	if (!n) {
-		prerror("UART: cannot find ns16550\n");
-		return;
-	}
-
-	simics_uart_base = (void *)dt_prop_get_u64(n, "console-bar");
-	simics_uart = 1;
-	has_irq = false;
-
-	if (!uart_init_hw(dt_prop_get_u32(n, "current-speed"),
-			  dt_prop_get_u32(n, "clock-frequency"))) {
-		prerror("UART: Initialization failed\n");
-		dt_add_property_strings(n, "status", "bad");
-		return;
-	}
-
-	set_console(&simics_con_driver);
-}
diff --git a/include/console.h b/include/console.h
index ecb18c4..b6fc8bf 100644
--- a/include/console.h
+++ b/include/console.h
@@ -67,7 +67,6 @@  extern void console_complete_flush(void);
 extern int mambo_read(void);
 extern void mambo_write(const char *buf, size_t count);
 extern void enable_mambo_console(void);
-extern void enable_simics_console(void);
 
 ssize_t console_write(bool flush_to_drivers, const void *buf, size_t count);
 
diff --git a/include/skiboot.h b/include/skiboot.h
index ded6bb8..1d33389 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -203,7 +203,7 @@  extern void probe_phb3(void);
 extern int phb3_preload_capp_ucode(void);
 extern void phb3_preload_vpd(void);
 extern void probe_npu(void);
-extern void uart_init(bool enable_interrupt);
+extern void uart_init(void);
 extern void homer_init(void);
 extern void occ_pstates_init(void);
 extern void slw_init(void);
@@ -228,6 +228,7 @@  extern void nvram_read_complete(bool success);
 /* UART stuff */
 extern void uart_setup_linux_passthrough(void);
 extern void uart_setup_opal_console(void);
+extern bool uart_enabled(void);
 
 /* OCC interrupt */
 extern void occ_interrupt(uint32_t chip_id);
diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c
index 1ed7d42..0699a44 100644
--- a/platforms/astbmc/common.c
+++ b/platforms/astbmc/common.c
@@ -347,8 +347,8 @@  void astbmc_early_init(void)
 	/* Similarly, some BMCs don't configure the BT interrupt properly */
 	ast_setup_ibt(BT_IO_BASE, BT_LPC_IRQ);
 
-	/* Setup UART and use it as console with interrupts */
-	uart_init(true);
+	/* Setup UART and use it as console */
+	uart_init();
 
 	prd_init();
 }
diff --git a/platforms/qemu/qemu.c b/platforms/qemu/qemu.c
index 66a6aa3..a7d2889 100644
--- a/platforms/qemu/qemu.c
+++ b/platforms/qemu/qemu.c
@@ -130,12 +130,8 @@  static bool qemu_probe(void)
 
 	psi_set_external_irq_policy(EXTERNAL_IRQ_POLICY_SKIBOOT);
 
-	/*
-	 * Setup UART and use it as console. For now, we
-	 * don't expose the interrupt as we know it's not
-	 * working properly yet
-	 */
-	uart_init(true);
+	/* Setup UART and use it as console */
+	uart_init();
 
 	return true;
 }
diff --git a/platforms/rhesus/rhesus.c b/platforms/rhesus/rhesus.c
index 3e2c41b..a3af777 100644
--- a/platforms/rhesus/rhesus.c
+++ b/platforms/rhesus/rhesus.c
@@ -270,12 +270,8 @@  static bool rhesus_probe(void)
 	/* Add missing bits of device-tree such as the UART */
 	rhesus_dt_fixup(has_uart_irq);
 
-	/*
-	 * Setup UART and use it as console. For now, we
-	 * don't expose the interrupt as we know it's not
-	 * working properly yet
-	 */
-	uart_init(has_uart_irq);
+	/* Setup UART and use it as console */
+	uart_init();
 
 	return true;
 }