[Skiboot] [PATCH 1/5] uart: Fix Linux pass-through policy
Benjamin Herrenschmidt
benh at kernel.crashing.org
Fri Feb 3 20:51:56 AEDT 2017
This was broken on Rhesus. Also add an nvram way of
overriding the policy
Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
hw/lpc-uart.c | 37 ++++++++++++++++++++++++++++++++++---
include/skiboot.h | 7 +++++--
platforms/astbmc/zaius.c | 3 +++
platforms/rhesus/rhesus.c | 2 +-
4 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/hw/lpc-uart.c b/hw/lpc-uart.c
index 17abe08..d063710 100644
--- a/hw/lpc-uart.c
+++ b/hw/lpc-uart.c
@@ -27,6 +27,7 @@
#include <cpu.h>
#include <chip.h>
#include <io.h>
+#include <nvram.h>
DEFINE_LOG_ENTRY(OPAL_RC_UART_INIT, OPAL_PLATFORM_ERR_EVT, OPAL_UART,
OPAL_CEC_HARDWARE, OPAL_PREDICTIVE_ERR_GENERAL,
@@ -68,6 +69,12 @@ static bool has_irq = false, irq_ok, rx_full, tx_full;
static uint8_t tx_room;
static uint8_t cached_ier;
static void *mmio_uart_base;
+static int uart_console_policy = UART_CONSOLE_OPAL;
+
+void uart_set_console_policy(int policy)
+{
+ uart_console_policy = policy;
+}
static void uart_trace(u8 ctx, u8 cnt, u8 irq_state, u8 in_count)
{
@@ -412,7 +419,7 @@ static void uart_irq(uint32_t chip_id __unused, uint32_t irq_mask __unused)
* Common setup/inits
*/
-void uart_setup_linux_passthrough(void)
+static void uart_setup_os_passthrough(void)
{
char *path;
@@ -423,7 +430,7 @@ void uart_setup_linux_passthrough(void)
prlog(PR_DEBUG, "UART: Enabled as OS pass-through\n");
}
-void uart_setup_opal_console(void)
+static void uart_setup_opal_console(void)
{
/* Add the opal console node */
add_opal_console_node(0, "raw", OUT_BUF_SIZE);
@@ -451,9 +458,33 @@ void uart_setup_opal_console(void)
opal_add_poller(uart_console_poll, NULL);
}
+static void uart_init_opal_console(void)
+{
+ const char *nv_policy;
+
+ /* Update the policy if the corresponding nvram variable
+ * is present
+ */
+ nv_policy = nvram_query("uart-con-policy");
+ if (nv_policy) {
+ if (!strcmp(nv_policy, "opal"))
+ uart_console_policy = UART_CONSOLE_OPAL;
+ else if (!strcmp(nv_policy, "os"))
+ uart_console_policy = UART_CONSOLE_OS;
+ else
+ prlog(PR_WARNING,
+ "UART: Unknown console policy in NVRAM: %s\n",
+ nv_policy);
+ }
+ if (uart_console_policy == UART_CONSOLE_OPAL)
+ uart_setup_opal_console();
+ else
+ uart_setup_os_passthrough();
+}
+
struct opal_con_ops uart_opal_con = {
.name = "OPAL UART console",
- .init = uart_setup_opal_console,
+ .init = uart_init_opal_console,
.read = uart_opal_read,
.write = uart_opal_write,
.space = uart_opal_write_buffer_space,
diff --git a/include/skiboot.h b/include/skiboot.h
index bc716f9..7904eee 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -243,8 +243,11 @@ extern void nvram_init(void);
extern void nvram_read_complete(bool success);
/* UART stuff */
-extern void uart_setup_linux_passthrough(void);
-extern void uart_setup_opal_console(void);
+enum {
+ UART_CONSOLE_OPAL,
+ UART_CONSOLE_OS
+};
+extern void uart_set_console_policy(int policy);
extern bool uart_enabled(void);
/* OCC interrupt */
diff --git a/platforms/astbmc/zaius.c b/platforms/astbmc/zaius.c
index b95be21..2c063d4 100644
--- a/platforms/astbmc/zaius.c
+++ b/platforms/astbmc/zaius.c
@@ -33,6 +33,9 @@ static bool zaius_probe(void)
astbmc_early_init();
psi_set_external_irq_policy(EXTERNAL_IRQ_POLICY_LINUX);
+ /* Setup UART for direct use by Linux */
+ uart_set_console_policy(UART_CONSOLE_OS);
+
return true;
}
diff --git a/platforms/rhesus/rhesus.c b/platforms/rhesus/rhesus.c
index c96f120..0571e22 100644
--- a/platforms/rhesus/rhesus.c
+++ b/platforms/rhesus/rhesus.c
@@ -154,7 +154,7 @@ static void rhesus_init(void)
rhesus_pnor_init();
/* Setup UART for direct use by Linux */
- uart_setup_linux_passthrough();
+ uart_set_console_policy(UART_CONSOLE_OS);
}
static void rhesus_dt_fixup_uart(struct dt_node *lpc, bool has_irq)
--
2.9.3
More information about the Skiboot
mailing list