aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/samsung_tty.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/samsung_tty.c')
-rw-r--r--drivers/tty/serial/samsung_tty.c270
1 files changed, 153 insertions, 117 deletions
diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 71d17d804fdabb..a2d07e05c50264 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -21,26 +21,28 @@
* BJD, 04-Nov-2004
*/
-#include <linux/dmaengine.h>
+#include <linux/console.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
#include <linux/dma-mapping.h>
-#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
#include <linux/math.h>
#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
-#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/slab.h>
#include <linux/sysrq.h>
-#include <linux/console.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-#include <linux/serial_s3c.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/cpufreq.h>
-#include <linux/of.h>
+#include <linux/types.h>
+
#include <asm/irq.h>
/* UART name and device definitions */
@@ -73,21 +75,21 @@ struct s3c24xx_uart_info {
enum s3c24xx_port_type type;
unsigned int port_type;
unsigned int fifosize;
- unsigned long rx_fifomask;
- unsigned long rx_fifoshift;
- unsigned long rx_fifofull;
- unsigned long tx_fifomask;
- unsigned long tx_fifoshift;
- unsigned long tx_fifofull;
- unsigned int def_clk_sel;
- unsigned long num_clks;
- unsigned long clksel_mask;
- unsigned long clksel_shift;
- unsigned long ucon_mask;
+ u32 rx_fifomask;
+ u32 rx_fifoshift;
+ u32 rx_fifofull;
+ u32 tx_fifomask;
+ u32 tx_fifoshift;
+ u32 tx_fifofull;
+ u32 clksel_mask;
+ u32 clksel_shift;
+ u32 ucon_mask;
+ u8 def_clk_sel;
+ u8 num_clks;
+ u8 iotype;
/* uart port features */
-
- unsigned int has_divslot:1;
+ bool has_divslot;
};
struct s3c24xx_serial_drv_data {
@@ -196,7 +198,7 @@ static void wr_reg(const struct uart_port *port, u32 reg, u32 val)
/* Byte-order aware bit setting/clearing functions. */
static inline void s3c24xx_set_bit(const struct uart_port *port, int idx,
- unsigned int reg)
+ u32 reg)
{
unsigned long flags;
u32 val;
@@ -209,7 +211,7 @@ static inline void s3c24xx_set_bit(const struct uart_port *port, int idx,
}
static inline void s3c24xx_clear_bit(const struct uart_port *port, int idx,
- unsigned int reg)
+ u32 reg)
{
unsigned long flags;
u32 val;
@@ -233,7 +235,7 @@ static inline const char *s3c24xx_serial_portname(const struct uart_port *port)
return to_platform_device(port->dev)->name;
}
-static int s3c24xx_serial_txempty_nofifo(const struct uart_port *port)
+static bool s3c24xx_serial_txempty_nofifo(const struct uart_port *port)
{
return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE;
}
@@ -242,8 +244,8 @@ static void s3c24xx_serial_rx_enable(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
unsigned long flags;
- unsigned int ucon, ufcon;
int count = 10000;
+ u32 ucon, ufcon;
uart_port_lock_irqsave(port, &flags);
@@ -266,7 +268,7 @@ static void s3c24xx_serial_rx_disable(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
unsigned long flags;
- unsigned int ucon;
+ u32 ucon;
uart_port_lock_irqsave(port, &flags);
@@ -587,8 +589,8 @@ static inline const struct s3c2410_uartcfg
return ourport->cfg;
}
-static int s3c24xx_serial_rx_fifocnt(const struct s3c24xx_uart_port *ourport,
- unsigned long ufstat)
+static unsigned int
+s3c24xx_serial_rx_fifocnt(const struct s3c24xx_uart_port *ourport, u32 ufstat)
{
const struct s3c24xx_uart_info *info = ourport->info;
@@ -660,7 +662,7 @@ static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport)
static void enable_rx_dma(struct s3c24xx_uart_port *ourport)
{
struct uart_port *port = &ourport->port;
- unsigned int ucon;
+ u32 ucon;
/* set Rx mode to DMA mode */
ucon = rd_regl(port, S3C2410_UCON);
@@ -683,7 +685,7 @@ static void enable_rx_dma(struct s3c24xx_uart_port *ourport)
static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
{
struct uart_port *port = &ourport->port;
- unsigned int ucon;
+ u32 ucon;
/* set Rx mode to DMA mode */
ucon = rd_regl(port, S3C2410_UCON);
@@ -708,13 +710,14 @@ static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport);
static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id)
{
- unsigned int utrstat, received;
struct s3c24xx_uart_port *ourport = dev_id;
struct uart_port *port = &ourport->port;
struct s3c24xx_uart_dma *dma = ourport->dma;
struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port);
struct tty_port *t = &port->state->port;
struct dma_tx_state state;
+ unsigned int received;
+ u32 utrstat;
utrstat = rd_regl(port, S3C2410_UTRSTAT);
rd_regl(port, S3C2410_UFSTAT);
@@ -756,9 +759,9 @@ finish:
static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport)
{
struct uart_port *port = &ourport->port;
- unsigned int ufcon, ufstat, uerstat;
+ unsigned int max_count = port->fifosize;
unsigned int fifocnt = 0;
- int max_count = port->fifosize;
+ u32 ufcon, ufstat, uerstat;
u8 ch, flag;
while (max_count-- > 0) {
@@ -778,7 +781,7 @@ static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport)
ch = rd_reg(port, S3C2410_URXH);
if (port->flags & UPF_CONS_FLOW) {
- int txe = s3c24xx_serial_txempty_nofifo(port);
+ bool txe = s3c24xx_serial_txempty_nofifo(port);
if (ourport->rx_enabled) {
if (!txe) {
@@ -942,7 +945,7 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
{
const struct s3c24xx_uart_port *ourport = id;
const struct uart_port *port = &ourport->port;
- unsigned int pend = rd_regl(port, S3C64XX_UINTP);
+ u32 pend = rd_regl(port, S3C64XX_UINTP);
irqreturn_t ret = IRQ_HANDLED;
if (pend & S3C64XX_UINTM_RXD_MSK) {
@@ -961,7 +964,7 @@ static irqreturn_t apple_serial_handle_irq(int irq, void *id)
{
const struct s3c24xx_uart_port *ourport = id;
const struct uart_port *port = &ourport->port;
- unsigned int pend = rd_regl(port, S3C2410_UTRSTAT);
+ u32 pend = rd_regl(port, S3C2410_UTRSTAT);
irqreturn_t ret = IRQ_NONE;
if (pend & (APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO)) {
@@ -980,24 +983,23 @@ static irqreturn_t apple_serial_handle_irq(int irq, void *id)
static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
{
const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
- unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT);
- unsigned long ufcon = rd_regl(port, S3C2410_UFCON);
+ u32 ufstat = rd_regl(port, S3C2410_UFSTAT);
+ u32 ufcon = rd_regl(port, S3C2410_UFCON);
if (ufcon & S3C2410_UFCON_FIFOMODE) {
- if ((ufstat & info->tx_fifomask) != 0 ||
+ if ((ufstat & info->tx_fifomask) ||
(ufstat & info->tx_fifofull))
return 0;
-
- return 1;
+ return TIOCSER_TEMT;
}
- return s3c24xx_serial_txempty_nofifo(port);
+ return s3c24xx_serial_txempty_nofifo(port) ? TIOCSER_TEMT : 0;
}
/* no modem control lines */
static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
{
- unsigned int umstat = rd_reg(port, S3C2410_UMSTAT);
+ u32 umstat = rd_reg(port, S3C2410_UMSTAT);
if (umstat & S3C2410_UMSTAT_CTS)
return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
@@ -1007,8 +1009,8 @@ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- unsigned int umcon = rd_regl(port, S3C2410_UMCON);
- unsigned int ucon = rd_regl(port, S3C2410_UCON);
+ u32 umcon = rd_regl(port, S3C2410_UMCON);
+ u32 ucon = rd_regl(port, S3C2410_UCON);
if (mctrl & TIOCM_RTS)
umcon |= S3C2410_UMCOM_RTS_LOW;
@@ -1028,7 +1030,7 @@ static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
{
unsigned long flags;
- unsigned int ucon;
+ u32 ucon;
uart_port_lock_irqsave(port, &flags);
@@ -1186,7 +1188,7 @@ static void apple_s5l_serial_shutdown(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
- unsigned int ucon;
+ u32 ucon;
ucon = rd_regl(port, S3C2410_UCON);
ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
@@ -1212,7 +1214,7 @@ static int s3c64xx_serial_startup(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
unsigned long flags;
- unsigned int ufcon;
+ u32 ufcon;
int ret;
wr_regl(port, S3C64XX_UINTM, 0xf);
@@ -1257,7 +1259,7 @@ static int apple_s5l_serial_startup(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
unsigned long flags;
- unsigned int ufcon;
+ u32 ufcon;
int ret;
wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
@@ -1292,8 +1294,6 @@ static int apple_s5l_serial_startup(struct uart_port *port)
return ret;
}
-/* power power management control */
-
static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
unsigned int old)
{
@@ -1339,10 +1339,10 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
#define MAX_CLK_NAME_LENGTH 15
-static inline int s3c24xx_serial_getsource(struct uart_port *port)
+static inline u8 s3c24xx_serial_getsource(struct uart_port *port)
{
const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
- unsigned int ucon;
+ u32 ucon;
if (info->num_clks == 1)
return 0;
@@ -1352,11 +1352,10 @@ static inline int s3c24xx_serial_getsource(struct uart_port *port)
return ucon >> info->clksel_shift;
}
-static void s3c24xx_serial_setsource(struct uart_port *port,
- unsigned int clk_sel)
+static void s3c24xx_serial_setsource(struct uart_port *port, u8 clk_sel)
{
const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
- unsigned int ucon;
+ u32 ucon;
if (info->num_clks == 1)
return;
@@ -1372,14 +1371,15 @@ static void s3c24xx_serial_setsource(struct uart_port *port,
static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport,
unsigned int req_baud, struct clk **best_clk,
- unsigned int *clk_num)
+ u8 *clk_num)
{
const struct s3c24xx_uart_info *info = ourport->info;
struct clk *clk;
unsigned long rate;
- unsigned int cnt, baud, quot, best_quot = 0;
+ unsigned int baud, quot, best_quot = 0;
char clkname[MAX_CLK_NAME_LENGTH];
int calc_deviation, deviation = (1 << 30) - 1;
+ u8 cnt;
for (cnt = 0; cnt < info->num_clks; cnt++) {
/* Keep selected clock if provided */
@@ -1472,10 +1472,10 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
struct s3c24xx_uart_port *ourport = to_ourport(port);
struct clk *clk = ERR_PTR(-EINVAL);
unsigned long flags;
- unsigned int baud, quot, clk_sel = 0;
- unsigned int ulcon;
- unsigned int umcon;
+ unsigned int baud, quot;
unsigned int udivslot = 0;
+ u32 ulcon, umcon;
+ u8 clk_sel = 0;
/*
* We don't support modem control lines.
@@ -1737,12 +1737,12 @@ static struct uart_driver s3c24xx_uart_drv = {
static struct s3c24xx_uart_port s3c24xx_serial_ports[UART_NR];
-static void s3c24xx_serial_init_port_default(int index) {
+static void s3c24xx_serial_init_port_default(int index)
+{
struct uart_port *port = &s3c24xx_serial_ports[index].port;
spin_lock_init(&port->lock);
- port->iotype = UPIO_MEM;
port->uartclk = 0;
port->fifosize = 16;
port->flags = UPF_BOOT_AUTOCONF;
@@ -1758,7 +1758,7 @@ static void s3c24xx_serial_resetport(struct uart_port *port,
const struct s3c2410_uartcfg *cfg)
{
const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
+ u32 ucon = rd_regl(port, S3C2410_UCON);
ucon &= (info->clksel_mask | info->ucon_mask);
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
@@ -1776,10 +1776,9 @@ static int s3c24xx_serial_enable_baudclk(struct s3c24xx_uart_port *ourport)
struct device *dev = ourport->port.dev;
const struct s3c24xx_uart_info *info = ourport->info;
char clk_name[MAX_CLK_NAME_LENGTH];
- unsigned int clk_sel;
struct clk *clk;
- int clk_num;
int ret;
+ u8 clk_sel, clk_num;
clk_sel = ourport->cfg->clk_sel ? : info->def_clk_sel;
for (clk_num = 0; clk_num < info->num_clks; clk_num++) {
@@ -1904,7 +1903,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
wr_regl(port, S3C64XX_UINTSP, 0xf);
break;
case TYPE_APPLE_S5L: {
- unsigned int ucon;
+ u32 ucon;
ucon = rd_regl(port, S3C2410_UCON);
ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
@@ -1952,7 +1951,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct s3c24xx_uart_port *ourport;
int index = probe_index;
- int ret, prop = 0;
+ int ret, prop = 0, fifosize_prop = 1;
if (np) {
ret = of_alias_get_id(np, "serial");
@@ -1989,9 +1988,11 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
break;
}
+ ourport->port.iotype = ourport->info->iotype;
+
if (np) {
- of_property_read_u32(np,
- "samsung,uart-fifosize", &ourport->port.fifosize);
+ fifosize_prop = of_property_read_u32(np, "samsung,uart-fifosize",
+ &ourport->port.fifosize);
if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
switch (prop) {
@@ -2009,10 +2010,13 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
}
}
- if (ourport->drv_data->fifosize[index])
- ourport->port.fifosize = ourport->drv_data->fifosize[index];
- else if (ourport->info->fifosize)
- ourport->port.fifosize = ourport->info->fifosize;
+ if (fifosize_prop) {
+ if (ourport->drv_data->fifosize[index])
+ ourport->port.fifosize = ourport->drv_data->fifosize[index];
+ else if (ourport->info->fifosize)
+ ourport->port.fifosize = ourport->info->fifosize;
+ }
+
ourport->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_SAMSUNG_CONSOLE);
/*
@@ -2058,9 +2062,8 @@ static void s3c24xx_serial_remove(struct platform_device *dev)
{
struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
- if (port) {
+ if (port)
uart_remove_one_port(&s3c24xx_uart_drv, port);
- }
uart_unregister_driver(&s3c24xx_uart_drv);
}
@@ -2106,7 +2109,7 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
/* restore IRQ mask */
switch (ourport->info->type) {
case TYPE_S3C6400: {
- unsigned int uintm = 0xf;
+ u32 uintm = 0xf;
if (ourport->tx_enabled)
uintm &= ~S3C64XX_UINTM_TXD_MSK;
@@ -2122,7 +2125,7 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
break;
}
case TYPE_APPLE_S5L: {
- unsigned int ucon;
+ u32 ucon;
int ret;
ret = clk_prepare_enable(ourport->clk);
@@ -2183,27 +2186,27 @@ static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
static struct uart_port *cons_uart;
-static int
-s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
+static bool
+s3c24xx_serial_console_txrdy(struct uart_port *port, u32 ufcon)
{
const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
- unsigned long ufstat, utrstat;
+ u32 ufstat, utrstat;
if (ufcon & S3C2410_UFCON_FIFOMODE) {
/* fifo mode - check amount of data in fifo registers... */
ufstat = rd_regl(port, S3C2410_UFSTAT);
- return (ufstat & info->tx_fifofull) ? 0 : 1;
+ return !(ufstat & info->tx_fifofull);
}
/* in non-fifo mode, we go and use the tx buffer empty */
utrstat = rd_regl(port, S3C2410_UTRSTAT);
- return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0;
+ return utrstat & S3C2410_UTRSTAT_TXE;
}
static bool
-s3c24xx_port_configured(unsigned int ucon)
+s3c24xx_port_configured(u32 ucon)
{
/* consider the serial port configured if the tx/rx mode set */
return (ucon & 0xf) != 0;
@@ -2218,7 +2221,7 @@ s3c24xx_port_configured(unsigned int ucon)
static int s3c24xx_serial_get_poll_char(struct uart_port *port)
{
const struct s3c24xx_uart_port *ourport = to_ourport(port);
- unsigned int ufstat;
+ u32 ufstat;
ufstat = rd_regl(port, S3C2410_UFSTAT);
if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
@@ -2230,8 +2233,8 @@ static int s3c24xx_serial_get_poll_char(struct uart_port *port)
static void s3c24xx_serial_put_poll_char(struct uart_port *port,
unsigned char c)
{
- unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
- unsigned int ucon = rd_regl(port, S3C2410_UCON);
+ u32 ufcon = rd_regl(port, S3C2410_UFCON);
+ u32 ucon = rd_regl(port, S3C2410_UCON);
/* not possible to xmit on unconfigured port */
if (!s3c24xx_port_configured(ucon))
@@ -2247,7 +2250,7 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port,
static void
s3c24xx_serial_console_putchar(struct uart_port *port, unsigned char ch)
{
- unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
+ u32 ufcon = rd_regl(port, S3C2410_UFCON);
while (!s3c24xx_serial_console_txrdy(port, ufcon))
cpu_relax();
@@ -2258,7 +2261,7 @@ static void
s3c24xx_serial_console_write(struct console *co, const char *s,
unsigned int count)
{
- unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
+ u32 ucon = rd_regl(cons_uart, S3C2410_UCON);
unsigned long flags;
bool locked = true;
@@ -2285,12 +2288,10 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
int *parity, int *bits)
{
struct clk *clk;
- unsigned int ulcon;
- unsigned int ucon;
- unsigned int ubrdiv;
unsigned long rate;
- unsigned int clk_sel;
+ u32 ulcon, ucon, ubrdiv;
char clk_name[MAX_CLK_NAME_LENGTH];
+ u8 clk_sel;
ulcon = rd_regl(port, S3C2410_ULCON);
ucon = rd_regl(port, S3C2410_UCON);
@@ -2399,8 +2400,9 @@ static const struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
.name = "Samsung S3C6400 UART",
.type = TYPE_S3C6400,
.port_type = PORT_S3C6400,
+ .iotype = UPIO_MEM,
.fifosize = 64,
- .has_divslot = 1,
+ .has_divslot = true,
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
@@ -2428,7 +2430,8 @@ static const struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
.name = "Samsung S5PV210 UART",
.type = TYPE_S3C6400,
.port_type = PORT_S3C6400,
- .has_divslot = 1,
+ .iotype = UPIO_MEM,
+ .has_divslot = true,
.rx_fifomask = S5PV210_UFSTAT_RXMASK,
.rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
.rx_fifofull = S5PV210_UFSTAT_RXFULL,
@@ -2452,12 +2455,13 @@ static const struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
#endif
#if defined(CONFIG_ARCH_EXYNOS)
-#define EXYNOS_COMMON_SERIAL_DRV_DATA() \
+#define EXYNOS_COMMON_SERIAL_DRV_DATA \
.info = { \
.name = "Samsung Exynos UART", \
.type = TYPE_S3C6400, \
.port_type = PORT_S3C6400, \
- .has_divslot = 1, \
+ .iotype = UPIO_MEM, \
+ .has_divslot = true, \
.rx_fifomask = S5PV210_UFSTAT_RXMASK, \
.rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \
.rx_fifofull = S5PV210_UFSTAT_RXFULL, \
@@ -2476,39 +2480,57 @@ static const struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
} \
static const struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
- EXYNOS_COMMON_SERIAL_DRV_DATA(),
+ EXYNOS_COMMON_SERIAL_DRV_DATA,
.fifosize = { 256, 64, 16, 16 },
};
static const struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
- EXYNOS_COMMON_SERIAL_DRV_DATA(),
+ EXYNOS_COMMON_SERIAL_DRV_DATA,
.fifosize = { 64, 256, 16, 256 },
};
static const struct s3c24xx_serial_drv_data exynos850_serial_drv_data = {
- EXYNOS_COMMON_SERIAL_DRV_DATA(),
+ EXYNOS_COMMON_SERIAL_DRV_DATA,
.fifosize = { 256, 64, 64, 64 },
};
-/*
- * Common drv_data struct for platforms that specify samsung,uart-fifosize in
- * device tree.
- */
-static const struct s3c24xx_serial_drv_data exynos_fifoszdt_serial_drv_data = {
- EXYNOS_COMMON_SERIAL_DRV_DATA(),
+static const struct s3c24xx_serial_drv_data gs101_serial_drv_data = {
+ .info = {
+ .name = "Google GS101 UART",
+ .type = TYPE_S3C6400,
+ .port_type = PORT_S3C6400,
+ .iotype = UPIO_MEM32,
+ .has_divslot = true,
+ .rx_fifomask = S5PV210_UFSTAT_RXMASK,
+ .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
+ .rx_fifofull = S5PV210_UFSTAT_RXFULL,
+ .tx_fifofull = S5PV210_UFSTAT_TXFULL,
+ .tx_fifomask = S5PV210_UFSTAT_TXMASK,
+ .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT,
+ .def_clk_sel = S3C2410_UCON_CLKSEL0,
+ .num_clks = 1,
+ .clksel_mask = 0,
+ .clksel_shift = 0,
+ },
+ .def_cfg = {
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ .has_fracval = 1,
+ },
+ /* samsung,uart-fifosize must be specified in the device tree. */
.fifosize = { 0 },
};
#define EXYNOS4210_SERIAL_DRV_DATA (&exynos4210_serial_drv_data)
#define EXYNOS5433_SERIAL_DRV_DATA (&exynos5433_serial_drv_data)
#define EXYNOS850_SERIAL_DRV_DATA (&exynos850_serial_drv_data)
-#define EXYNOS_FIFOSZDT_DRV_DATA (&exynos_fifoszdt_serial_drv_data)
+#define GS101_SERIAL_DRV_DATA (&gs101_serial_drv_data)
#else
#define EXYNOS4210_SERIAL_DRV_DATA NULL
#define EXYNOS5433_SERIAL_DRV_DATA NULL
#define EXYNOS850_SERIAL_DRV_DATA NULL
-#define EXYNOS_FIFOSZDT_DRV_DATA NULL
+#define GS101_SERIAL_DRV_DATA NULL
#endif
#ifdef CONFIG_ARCH_APPLE
@@ -2517,6 +2539,7 @@ static const struct s3c24xx_serial_drv_data s5l_serial_drv_data = {
.name = "Apple S5L UART",
.type = TYPE_APPLE_S5L,
.port_type = PORT_8250,
+ .iotype = UPIO_MEM,
.fifosize = 16,
.rx_fifomask = S3C2410_UFSTAT_RXMASK,
.rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
@@ -2546,8 +2569,9 @@ static const struct s3c24xx_serial_drv_data artpec8_serial_drv_data = {
.name = "Axis ARTPEC-8 UART",
.type = TYPE_S3C6400,
.port_type = PORT_S3C6400,
+ .iotype = UPIO_MEM,
.fifosize = 64,
- .has_divslot = 1,
+ .has_divslot = true,
.rx_fifomask = S5PV210_UFSTAT_RXMASK,
.rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
.rx_fifofull = S5PV210_UFSTAT_RXFULL,
@@ -2594,7 +2618,7 @@ static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
.driver_data = (kernel_ulong_t)ARTPEC8_SERIAL_DRV_DATA,
}, {
.name = "gs101-uart",
- .driver_data = (kernel_ulong_t)EXYNOS_FIFOSZDT_DRV_DATA,
+ .driver_data = (kernel_ulong_t)GS101_SERIAL_DRV_DATA,
},
{ },
};
@@ -2617,7 +2641,7 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = {
{ .compatible = "axis,artpec8-uart",
.data = ARTPEC8_SERIAL_DRV_DATA },
{ .compatible = "google,gs101-uart",
- .data = EXYNOS_FIFOSZDT_DRV_DATA },
+ .data = GS101_SERIAL_DRV_DATA },
{},
};
MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
@@ -2716,7 +2740,8 @@ static int samsung_early_read(struct console *con, char *s, unsigned int n)
{
struct earlycon_device *dev = con->data;
const struct samsung_early_console_data *data = dev->port.private_data;
- int ch, ufstat, num_read = 0;
+ int num_read = 0;
+ u32 ch, ufstat;
while (num_read < n) {
ufstat = rd_regl(&dev->port, S3C2410_UFSTAT);
@@ -2785,6 +2810,17 @@ OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart",
OF_EARLYCON_DECLARE(artpec8, "axis,artpec8-uart",
s5pv210_early_console_setup);
+static int __init gs101_early_console_setup(struct earlycon_device *device,
+ const char *opt)
+{
+ /* gs101 always expects MMIO32 register accesses. */
+ device->port.iotype = UPIO_MEM32;
+
+ return s5pv210_early_console_setup(device, opt);
+}
+
+OF_EARLYCON_DECLARE(gs101, "google,gs101-uart", gs101_early_console_setup);
+
/* Apple S5L */
static int __init apple_s5l_early_console_setup(struct earlycon_device *device,
const char *opt)