summaryrefslogtreecommitdiff
path: root/core/drivers/sprd_uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/drivers/sprd_uart.c')
-rw-r--r--core/drivers/sprd_uart.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/core/drivers/sprd_uart.c b/core/drivers/sprd_uart.c
index fdaa1b6..c77f595 100644
--- a/core/drivers/sprd_uart.c
+++ b/core/drivers/sprd_uart.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2016, Spreadtrum Communications Inc.
+ * Copyright (c) 2017, Linaro Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,8 +25,10 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <io.h>
#include <drivers/sprd_uart.h>
+#include <io.h>
+#include <keep.h>
+#include <util.h>
/* Register definitions */
#define UART_TXD 0x0000
@@ -36,43 +39,57 @@
#define STS1_RXF_CNT_MASK 0x00ff /* Rx FIFO data counter mask */
#define STS1_TXF_CNT_MASK 0xff00 /* Tx FIFO data counter mask */
-static uint32_t sprd_uart_read(vaddr_t base, uint32_t reg)
+static vaddr_t chip_to_base(struct serial_chip *chip)
{
- return read32(base + reg);
-}
+ struct sprd_uart_data *pd =
+ container_of(chip, struct sprd_uart_data, chip);
-static void sprd_uart_write(vaddr_t base, uint32_t reg, uint32_t value)
-{
- write32(value, base + reg);
+ return io_pa_or_va(&pd->base);
}
-static void sprd_uart_wait_xmit_done(vaddr_t base)
+static void sprd_uart_flush(struct serial_chip *chip)
{
- while (sprd_uart_read(base, UART_STS1) & STS1_TXF_CNT_MASK)
+ vaddr_t base = chip_to_base(chip);
+
+ while (read32(base + UART_STS1) & STS1_TXF_CNT_MASK)
;
}
-static void sprd_uart_wait_rx_data(vaddr_t base)
+static bool sprd_uart_have_rx_data(struct serial_chip *chip)
{
- while (!(sprd_uart_read(base, UART_STS1) & STS1_RXF_CNT_MASK))
- ;
+ vaddr_t base = chip_to_base(chip);
+
+ return !!(read32(base + UART_STS1) & STS1_RXF_CNT_MASK);
}
-void sprd_uart_flush(vaddr_t base)
+static void sprd_uart_putc(struct serial_chip *chip, int ch)
{
- sprd_uart_wait_xmit_done(base);
+ vaddr_t base = chip_to_base(chip);
+
+ sprd_uart_flush(chip);
+ write32(base + UART_TXD, ch);
}
-void sprd_uart_putc(vaddr_t base, unsigned char ch)
+static int sprd_uart_getchar(struct serial_chip *chip)
{
- sprd_uart_wait_xmit_done(base);
+ vaddr_t base = chip_to_base(chip);
+
+ while (!sprd_uart_have_rx_data(chip))
+ ;
- sprd_uart_write(base, UART_TXD, (uint32_t)ch);
+ return read32(base + UART_RXD) & 0xff;
}
-unsigned char sprd_uart_getc(vaddr_t base)
-{
- sprd_uart_wait_rx_data(base);
+static const struct serial_ops sprd_uart_ops = {
+ .flush = sprd_uart_flush,
+ .getchar = sprd_uart_getchar,
+ .have_rx_data = sprd_uart_have_rx_data,
+ .putc = sprd_uart_putc,
+};
+KEEP_PAGER(sprd_uart_ops);
- return sprd_uart_read(base, UART_RXD) & 0xff;
+void sprd_uart_init(struct sprd_uart_data *pd, paddr_t base)
+{
+ pd->base.pa = base;
+ pd->chip.ops = &sprd_uart_ops;
}