[PATCH 7/8] serial: add Exynos specific serial driver

Piotr Wilczek p.wilczek at samsung.com
Wed Dec 11 08:07:38 EST 2013


Signed-off-by: Piotr Wilczek <p.wilczek at samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
---
 Makefile        |    1 +
 serial-exynos.c |   84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 serial-exynos.c

diff --git a/Makefile b/Makefile
index 6074106..78684b7 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@ include Makefile.config
 
 CFLAGS+=-DUART_BASE=$(UART_BASE)
 CFLAGS+=-DNR_BANKS=$(NR_BANKS)
+CFLAGS+=-DUART_PORT=$(UART_PORT)
 
 BOARD_OBJ = board-$(MFG).o
 UART_OBJ = serial-$(UART).o
diff --git a/serial-exynos.c b/serial-exynos.c
new file mode 100644
index 0000000..3ba4fc9
--- /dev/null
+++ b/serial-exynos.c
@@ -0,0 +1,84 @@
+#include "types.h"
+#include "register.h"
+#include "serial.h"
+
+#define EXYNOS_BASE_UART	0x13800000
+#define TX_FIFO_FULL_MASK	(1 << 24)
+
+#define UART_BAUDRATE_115200	115200
+
+union br_rest {
+	unsigned short	slot;		/* udivslot */
+	unsigned char	value;		/* ufracval */
+};
+
+struct s5p_uart {
+	unsigned int	ulcon;
+	unsigned int	ucon;
+	unsigned int	ufcon;
+	unsigned int	umcon;
+	unsigned int	utrstat;
+	unsigned int	uerstat;
+	unsigned int	ufstat;
+	unsigned int	umstat;
+	unsigned char	utxh;
+	unsigned char	res1[3];
+	unsigned char	urxh;
+	unsigned char	res2[3];
+	unsigned int	ubrdiv;
+	union br_rest	rest;
+	unsigned char	res3[0xffd0];
+};
+
+static inline struct s5p_uart *s5p_get_base_uart(int dev_index)
+{
+	u32 offset = dev_index * sizeof(struct s5p_uart);
+	return (struct s5p_uart *)(EXYNOS_BASE_UART + offset);
+}
+
+static inline int s5p_uart_divslot(void)
+{
+	return 0;
+}
+
+static int serial_err_check(const int dev_index, int op)
+{
+	struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
+	unsigned int mask;
+
+	/*
+	 * UERSTAT
+	 * Break Detect	[3]
+	 * Frame Err	[2] : receive operation
+	 * Parity Err	[1] : receive operation
+	 * Overrun Err	[0] : receive operation
+	 */
+	if (op)
+		mask = 0x8;
+	else
+		mask = 0xf;
+
+	return readl((unsigned int)&uart->uerstat) & mask;
+}
+
+/*
+ * Output a single byte to the serial port.
+ */
+void __putch(char c)
+{
+	const int dev_index = UART_PORT;
+
+	struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
+
+	/* wait for room in the tx FIFO */
+	while ((readl((unsigned int)&uart->ufstat) & TX_FIFO_FULL_MASK)) {
+		if (serial_err_check(dev_index, 1))
+			return;
+	}
+
+	writeb(c, (unsigned int)&uart->utxh);
+
+	/* If \n, also do \r */
+	if (c == '\n')
+		__putch('\r');
+}
-- 
1.7.9.5




More information about the linux-arm-kernel mailing list