linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: zoss@devai.org (Zoltan Devai)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 09/15] ARM: uncompress: Introduce ucuart as low-level serial port driver
Date: Sun, 23 Oct 2011 23:10:39 +0200	[thread overview]
Message-ID: <1319404245-12740-9-git-send-email-zoss@devai.org> (raw)
In-Reply-To: <1319404245-12740-1-git-send-email-zoss@devai.org>

This adds the ucuart struct which should be a sufficient
description for being able to print through a serial port.

Generic versions of putc() and flush() using ucuart are also
added, along with initialization helpers, one specifically
for the 8250 family UART and one for the AMBA01X PrimeCell.

The port structure is not declared statically, but inited
through arch_decomp_setup() to have it in the .bss area,
thus in RAM.

Signed-off-by: Zoltan Devai <zoss@devai.org>
---
 arch/arm/boot/compressed/print.c |  128 +++++++++++++++++++++++++++++++++++--
 1 files changed, 121 insertions(+), 7 deletions(-)

diff --git a/arch/arm/boot/compressed/print.c b/arch/arm/boot/compressed/print.c
index 25f0fb2..fbffc99 100644
--- a/arch/arm/boot/compressed/print.c
+++ b/arch/arm/boot/compressed/print.c
@@ -25,18 +25,120 @@ void error(char *x);
 extern unsigned int __machine_arch_type;
 #define arch_id __machine_arch_type
 
+enum ucuart_iotypes {
+	UCUART_IO_MEM32 = 0,
+	UCUART_IO_MEM8,
+};
+
+struct uncompress_uart {
+	void __iomem		*base;
+	int			reg_shift;
+	enum ucuart_iotypes	iotype;
+	int			tx_regoff;
+	int			txfree_regoff;
+	int			txfree_mask;
+	int			txfree_val;
+	int			flush_regoff;
+	int			flush_mask;
+	int			flush_val;
+};
+
+void ucuart_init(int base, int regshift, enum ucuart_iotypes iotype,
+		 int tx_regoff, int txfree_regoff, int txfree_mask,
+		 int txfree_val, int flush_regoff, int flush_mask,
+		 int flush_val);
+
+void ucuart_init_8250(int base, int regshift, enum ucuart_iotypes iotype);
+
+struct uncompress_uart ucuart;
+
 #include <mach/uncompress.h>
 
-#ifdef ARCH_HAVE_DECOMP_SETUP
-void inline decomp_setup(void)
+#ifdef ARCH_HAVE_UCUART_GENERIC
+
+#define ARCH_HAVE_DECOMP_SETUP
+
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+#include <linux/amba/serial.h>
+
+void ucuart_init(int base, int regshift, enum ucuart_iotypes iotype,
+		 int tx_regoff, int txfree_regoff, int txfree_mask,
+		 int txfree_val, int flush_regoff, int flush_mask,
+		 int flush_val)
 {
-	arch_decomp_setup();
+	ucuart.base = (void __iomem *)base;
+	ucuart.reg_shift = regshift;
+	ucuart.iotype = iotype;
+
+	ucuart.tx_regoff = tx_regoff;
+	ucuart.txfree_regoff = txfree_regoff;
+	ucuart.txfree_mask = txfree_mask;
+	ucuart.txfree_val = txfree_val;
+	ucuart.flush_regoff = flush_regoff;
+	ucuart.flush_mask = flush_mask;
+	ucuart.flush_val = flush_val;
 }
-#else /* ARCH_HAVE_DECOMP_SETUP */
-void inline decomp_setup(void)
+
+void inline ucuart_init_8250(int base, int regshift, enum ucuart_iotypes iotype)
 {
+	ucuart_init(base, regshift, iotype, UART_TX,
+			UART_LSR, UART_LSR_THRE, UART_LSR_THRE,
+			UART_LSR, (UART_LSR_TEMT | UART_LSR_THRE),
+			(UART_LSR_TEMT | UART_LSR_THRE));
 }
-#endif /* ARCH_HAVE_DECOMP_SETUP */
+
+void ucuart_init_amba01x(int base)
+{
+	/* Do nothing if the UART is not enabled. */
+	if (!(__raw_readl(base + UART011_CR) & UART01x_CR_UARTEN))
+		return;
+
+	ucuart_init(base, 0, UCUART_IO_MEM32, UART01x_DR,
+			UART01x_FR, UART01x_FR_TXFF, 0,
+			UART01x_FR, UART01x_FR_BUSY, 0);
+}
+
+static inline int uart_read(int regoff)
+{
+	if (ucuart.iotype == UCUART_IO_MEM32)
+		return __raw_readl(ucuart.base + (regoff << ucuart.reg_shift));
+	else
+		return __raw_readb(ucuart.base + (regoff << ucuart.reg_shift));
+}
+
+static inline void uart_write(int regoff, int value)
+{
+	if (ucuart.iotype == UCUART_IO_MEM32)
+		__raw_writel(value, ucuart.base + (regoff << ucuart.reg_shift));
+	else
+		__raw_writeb(value, ucuart.base + (regoff << ucuart.reg_shift));
+}
+
+static inline void putc(int ch)
+{
+	if (!ucuart.base)
+		return;
+
+	if (ucuart.txfree_regoff) {
+		while ((uart_read(ucuart.txfree_regoff) & ucuart.txfree_mask)
+				!= ucuart.txfree_val)
+			barrier();
+	}
+
+	uart_write(ucuart.tx_regoff, ch);
+}
+
+static inline void flush(void)
+{
+	if (ucuart.flush_regoff) {
+		while ((uart_read(ucuart.flush_regoff) & ucuart.flush_mask) !=
+				ucuart.flush_val)
+			barrier();
+	}
+}
+#endif /* ARCH_HAVE_UCUART_GENERIC */
+
 
 #ifdef CONFIG_DEBUG_ICEDCC
 
@@ -91,7 +193,8 @@ static void icedcc_putc(int ch)
 #endif
 
 #define putc(ch)	icedcc_putc(ch)
-#endif
+#define flush()
+#endif /* CONFIG_DEBUG_ICEDCC */
 
 void putstr(const char *ptr)
 {
@@ -120,3 +223,14 @@ void error(char *x)
 
 	while(1);	/* Halt */
 }
+
+#ifdef ARCH_HAVE_DECOMP_SETUP
+void inline decomp_setup(void)
+{
+	arch_decomp_setup();
+}
+#else /* ARCH_HAVE_DECOMP_SETUP */
+void inline decomp_setup(void)
+{
+}
+#endif /* ARCH_HAVE_DECOMP_SETUP */
-- 
1.7.4.1

  parent reply	other threads:[~2011-10-23 21:10 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-23 21:10 [RFC PATCH 01/15] ARM: uncompress.h: Remove unused arch_decomp_wdog defines Zoltan Devai
2011-10-23 21:10 ` [RFC PATCH 02/15] ARM: uncompress: Remove unused definition of ARCH_HAS_DECOMP_WATCHDOG Zoltan Devai
2011-10-23 21:10 ` [RFC PATCH 03/15] ARM: uncompress.h: Introduce ARCH_HAVE_DECOMP_SETUP Zoltan Devai
2011-10-23 21:10 ` [RFC PATCH 04/15] ARM: uncompress: Only call arch_decomp_setup when needed Zoltan Devai
2011-10-24  6:55   ` Uwe Kleine-König
2011-10-23 21:10 ` [RFC PATCH 05/15] ARM: uncompress.h: Remove unused arch_decomp_setup declarations Zoltan Devai
2011-10-23 21:10 ` [RFC PATCH 06/15] ARM: uncompress: Remove unused Trace functions Zoltan Devai
2011-10-23 21:10 ` [RFC PATCH 07/15] ARM: uncompress: Move decompressing related stuff to decompress.c Zoltan Devai
2011-10-24  9:17   ` Russell King - ARM Linux
2011-10-24  9:23     ` Russell King - ARM Linux
2011-10-23 21:10 ` [RFC PATCH 08/15] ARM: uncompress: Rename misc.c to print.c Zoltan Devai
2011-10-24  6:58   ` Uwe Kleine-König
2011-10-23 21:10 ` Zoltan Devai [this message]
2011-10-24  9:26   ` [RFC PATCH 09/15] ARM: uncompress: Introduce ucuart as low-level serial port driver Russell King - ARM Linux
2011-10-23 21:10 ` [RFC PATCH 10/15] ARM: uncompress.h: Convert machines to use the new ucuart driver Zoltan Devai
2011-10-23 21:10 ` [RFC PATCH 11/15] ARM: uncompress: Call arch_decomp_setup by default Zoltan Devai
2011-10-23 21:10 ` [RFC PATCH 12/15] ARM: uncompress.h: make the ucuart driver the default implementation Zoltan Devai
2011-10-23 21:10 ` [RFC PATCH 13/15] ARM: uncompress.h: Cleanup header guards and banners Zoltan Devai
2011-10-24  9:29   ` Russell King - ARM Linux
2011-10-23 21:10 ` [RFC PATCH 14/15] ARM: uncompress: Get decompress UART info from DT Zoltan Devai
2011-10-24  9:30   ` Russell King - ARM Linux
2011-10-25  7:38     ` Tony Lindgren
2011-10-23 21:10 ` [RFC PATCH 15/15] ARM: uncompress: Add documentation Zoltan Devai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1319404245-12740-9-git-send-email-zoss@devai.org \
    --to=zoss@devai.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).