Blame SOURCES/kexec-tools-2.0.8-arm64-wait-for-transmit-completion-before-next-chara.patch

de80c6
From d6da3c31a2b00b3db5462ffef7c389977416f280 Mon Sep 17 00:00:00 2001
de80c6
Message-Id: <d6da3c31a2b00b3db5462ffef7c389977416f280.1429703426.git.panand@redhat.com>
de80c6
In-Reply-To: <de1db775d6e9b51f014442677863b57b8566c510.1429703426.git.panand@redhat.com>
de80c6
References: <de1db775d6e9b51f014442677863b57b8566c510.1429703426.git.panand@redhat.com>
de80c6
From: Pratyush Anand <panand@redhat.com>
de80c6
Date: Thu, 16 Apr 2015 14:00:03 +0530
de80c6
Subject: [PATCH 15/15] arm64: wait for transmit completion before next
de80c6
 character transmission
de80c6
de80c6
Previous transmission must be completed before next character to be
de80c6
transmitted, otherwise TX buffer may saturate and we will not see all
de80c6
the characters on screen.
de80c6
de80c6
Signed-off-by: Pratyush Anand <panand@redhat.com>
de80c6
---
de80c6
 purgatory/arch/arm64/purgatory-arm64.c | 24 +++++++++++++++++++++++-
de80c6
 1 file changed, 23 insertions(+), 1 deletion(-)
de80c6
de80c6
diff --git a/purgatory/arch/arm64/purgatory-arm64.c b/purgatory/arch/arm64/purgatory-arm64.c
de80c6
index 25960c30bd05..3a1c9243bfa2 100644
de80c6
--- a/purgatory/arch/arm64/purgatory-arm64.c
de80c6
+++ b/purgatory/arch/arm64/purgatory-arm64.c
de80c6
@@ -11,15 +11,37 @@ extern uint32_t *arm64_sink;
de80c6
 extern void (*arm64_kernel_entry)(uint64_t);
de80c6
 extern uint64_t arm64_dtb_addr;
de80c6
 
de80c6
+static void wait_for_xmit_complete(void)
de80c6
+{
de80c6
+	volatile uint32_t status;
de80c6
+	volatile uint32_t *status_reg;
de80c6
+
de80c6
+	/*
de80c6
+	 * Since most of the UART with ARM platform has LSR register at
de80c6
+	 * offset 0x14 and should have value as 0x60 for TX empty, so we
de80c6
+	 * have hardcoded these values. Can modify in future if need
de80c6
+	 * arises.
de80c6
+	 */
de80c6
+	status_reg = (volatile uint32_t *)((uint64_t)arm64_sink + 0x14);
de80c6
+	while (1) {
de80c6
+		status = *status_reg;
de80c6
+		if ((status & 0x60) == 0x60)
de80c6
+			break;
de80c6
+	}
de80c6
+}
de80c6
+
de80c6
 void putchar(int ch)
de80c6
 {
de80c6
 	if (!arm64_sink)
de80c6
 		return;
de80c6
 
de80c6
+	wait_for_xmit_complete();
de80c6
 	*arm64_sink = ch;
de80c6
 
de80c6
-	if (ch == '\n')
de80c6
+	if (ch == '\n') {
de80c6
+		wait_for_xmit_complete();
de80c6
 		*arm64_sink = '\r';
de80c6
+	}
de80c6
 }
de80c6
 
de80c6
 void setup_arch(void)
de80c6
-- 
de80c6
2.1.0
de80c6