From mboxrd@z Thu Jan 1 00:00:00 1970
From: p.wilczek@samsung.com (Piotr Wilczek)
Date: Wed, 11 Dec 2013 14:07:38 +0100
Subject: [PATCH 7/8] serial: add Exynos specific serial driver
In-Reply-To: <1386767259-15693-1-git-send-email-p.wilczek@samsung.com>
References: <1386767259-15693-1-git-send-email-p.wilczek@samsung.com>
Message-ID: <1386767259-15693-8-git-send-email-p.wilczek@samsung.com>
To: linux-arm-kernel@lists.infradead.org
List-Id: linux-arm-kernel.lists.infradead.org
Signed-off-by: Piotr Wilczek
Signed-off-by: Kyungmin Park
---
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