Commit aaf14405 authored by Hector Martin's avatar Hector Martin Committed by Greg Kroah-Hartman

tty: serial: samsung_tty: Add s3c24xx_port_type

This decouples the TTY layer PORT_ types, which are exposed to
userspace, from the driver-internal flag of what kind of port this is.

This removes s3c24xx_serial_has_interrupt_mask, which was just checking
for a specific type anyway.
Signed-off-by: default avatarHector Martin <marcan@marcan.st>
Reviewed-by: default avatarKrzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Tested-by: default avatarKrzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Link: https://lore.kernel.org/r/20210304213902.83903-21-marcan@marcan.stSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 64689163
...@@ -56,9 +56,15 @@ ...@@ -56,9 +56,15 @@
/* flag to ignore all characters coming in */ /* flag to ignore all characters coming in */
#define RXSTAT_DUMMY_READ (0x10000000) #define RXSTAT_DUMMY_READ (0x10000000)
enum s3c24xx_port_type {
TYPE_S3C24XX,
TYPE_S3C6400,
};
struct s3c24xx_uart_info { struct s3c24xx_uart_info {
char *name; char *name;
unsigned int type; enum s3c24xx_port_type type;
unsigned int port_type;
unsigned int fifosize; unsigned int fifosize;
unsigned long rx_fifomask; unsigned long rx_fifomask;
unsigned long rx_fifoshift; unsigned long rx_fifoshift;
...@@ -229,16 +235,6 @@ static int s3c24xx_serial_txempty_nofifo(struct uart_port *port) ...@@ -229,16 +235,6 @@ static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE; return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE;
} }
/*
* s3c64xx and later SoC's include the interrupt mask and status registers in
* the controller itself, unlike the s3c24xx SoC's which have these registers
* in the interrupt controller. Check if the port type is s3c64xx or higher.
*/
static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port)
{
return to_ourport(port)->info->type == PORT_S3C6400;
}
static void s3c24xx_serial_rx_enable(struct uart_port *port) static void s3c24xx_serial_rx_enable(struct uart_port *port)
{ {
struct s3c24xx_uart_port *ourport = to_ourport(port); struct s3c24xx_uart_port *ourport = to_ourport(port);
...@@ -290,10 +286,14 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port) ...@@ -290,10 +286,14 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
if (!ourport->tx_enabled) if (!ourport->tx_enabled)
return; return;
if (s3c24xx_serial_has_interrupt_mask(port)) switch (ourport->info->type) {
case TYPE_S3C6400:
s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM); s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
else break;
default:
disable_irq_nosync(ourport->tx_irq); disable_irq_nosync(ourport->tx_irq);
break;
}
if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) { if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) {
dmaengine_pause(dma->tx_chan); dmaengine_pause(dma->tx_chan);
...@@ -354,10 +354,14 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport) ...@@ -354,10 +354,14 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
u32 ucon; u32 ucon;
/* Mask Tx interrupt */ /* Mask Tx interrupt */
if (s3c24xx_serial_has_interrupt_mask(port)) switch (ourport->info->type) {
case TYPE_S3C6400:
s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM); s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
else break;
default:
disable_irq_nosync(ourport->tx_irq); disable_irq_nosync(ourport->tx_irq);
break;
}
/* Enable tx dma mode */ /* Enable tx dma mode */
ucon = rd_regl(port, S3C2410_UCON); ucon = rd_regl(port, S3C2410_UCON);
...@@ -387,11 +391,15 @@ static void enable_tx_pio(struct s3c24xx_uart_port *ourport) ...@@ -387,11 +391,15 @@ static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
wr_regl(port, S3C2410_UCON, ucon); wr_regl(port, S3C2410_UCON, ucon);
/* Unmask Tx interrupt */ /* Unmask Tx interrupt */
if (s3c24xx_serial_has_interrupt_mask(port)) switch (ourport->info->type) {
case TYPE_S3C6400:
s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD, s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD,
S3C64XX_UINTM); S3C64XX_UINTM);
else break;
default:
enable_irq(ourport->tx_irq); enable_irq(ourport->tx_irq);
break;
}
ourport->tx_mode = S3C24XX_TX_PIO; ourport->tx_mode = S3C24XX_TX_PIO;
} }
...@@ -514,11 +522,15 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port) ...@@ -514,11 +522,15 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)
if (ourport->rx_enabled) { if (ourport->rx_enabled) {
dev_dbg(port->dev, "stopping rx\n"); dev_dbg(port->dev, "stopping rx\n");
if (s3c24xx_serial_has_interrupt_mask(port)) switch (ourport->info->type) {
case TYPE_S3C6400:
s3c24xx_set_bit(port, S3C64XX_UINTM_RXD, s3c24xx_set_bit(port, S3C64XX_UINTM_RXD,
S3C64XX_UINTM); S3C64XX_UINTM);
else break;
default:
disable_irq_nosync(ourport->rx_irq); disable_irq_nosync(ourport->rx_irq);
break;
}
ourport->rx_enabled = 0; ourport->rx_enabled = 0;
} }
if (dma && dma->rx_chan) { if (dma && dma->rx_chan) {
...@@ -1543,14 +1555,12 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, ...@@ -1543,14 +1555,12 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
static const char *s3c24xx_serial_type(struct uart_port *port) static const char *s3c24xx_serial_type(struct uart_port *port)
{ {
switch (port->type) { struct s3c24xx_uart_port *ourport = to_ourport(port);
case PORT_S3C2410:
return "S3C2410"; switch (ourport->info->type) {
case PORT_S3C2440: case TYPE_S3C24XX:
return "S3C2440"; return "S3C24XX";
case PORT_S3C2412: case TYPE_S3C6400:
return "S3C2412";
case PORT_S3C6400:
return "S3C6400/10"; return "S3C6400/10";
default: default:
return NULL; return NULL;
...@@ -1577,7 +1587,7 @@ static void s3c24xx_serial_config_port(struct uart_port *port, int flags) ...@@ -1577,7 +1587,7 @@ static void s3c24xx_serial_config_port(struct uart_port *port, int flags)
if (flags & UART_CONFIG_TYPE && if (flags & UART_CONFIG_TYPE &&
s3c24xx_serial_request_port(port) == 0) s3c24xx_serial_request_port(port) == 0)
port->type = info->type; port->type = info->port_type;
} }
/* /*
...@@ -1588,7 +1598,7 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser) ...@@ -1588,7 +1598,7 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
{ {
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
if (ser->type != PORT_UNKNOWN && ser->type != info->type) if (ser->type != PORT_UNKNOWN && ser->type != info->port_type)
return -EINVAL; return -EINVAL;
return 0; return 0;
...@@ -1927,11 +1937,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, ...@@ -1927,11 +1937,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
ourport->tx_irq = ret + 1; ourport->tx_irq = ret + 1;
} }
if (!s3c24xx_serial_has_interrupt_mask(port)) { switch (ourport->info->type) {
case TYPE_S3C24XX:
ret = platform_get_irq(platdev, 1); ret = platform_get_irq(platdev, 1);
if (ret > 0) if (ret > 0)
ourport->tx_irq = ret; ourport->tx_irq = ret;
break;
default:
break;
} }
/* /*
* DMA is currently supported only on DT platforms, if DMA properties * DMA is currently supported only on DT platforms, if DMA properties
* are specified. * are specified.
...@@ -1967,10 +1982,14 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, ...@@ -1967,10 +1982,14 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
pr_warn("uart: failed to enable baudclk\n"); pr_warn("uart: failed to enable baudclk\n");
/* Keep all interrupts masked and cleared */ /* Keep all interrupts masked and cleared */
if (s3c24xx_serial_has_interrupt_mask(port)) { switch (ourport->info->type) {
case TYPE_S3C6400:
wr_regl(port, S3C64XX_UINTM, 0xf); wr_regl(port, S3C64XX_UINTM, 0xf);
wr_regl(port, S3C64XX_UINTP, 0xf); wr_regl(port, S3C64XX_UINTP, 0xf);
wr_regl(port, S3C64XX_UINTSP, 0xf); wr_regl(port, S3C64XX_UINTSP, 0xf);
break;
default:
break;
} }
dev_dbg(port->dev, "port: map=%pa, mem=%p, irq=%d (%d,%d), clock=%u\n", dev_dbg(port->dev, "port: map=%pa, mem=%p, irq=%d (%d,%d), clock=%u\n",
...@@ -2042,12 +2061,10 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) ...@@ -2042,12 +2061,10 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
ourport->drv_data->def_cfg; ourport->drv_data->def_cfg;
switch (ourport->info->type) { switch (ourport->info->type) {
case PORT_S3C2410: case TYPE_S3C24XX:
case PORT_S3C2412:
case PORT_S3C2440:
ourport->port.ops = &s3c24xx_serial_ops; ourport->port.ops = &s3c24xx_serial_ops;
break; break;
case PORT_S3C6400: case TYPE_S3C6400:
ourport->port.ops = &s3c64xx_serial_ops; ourport->port.ops = &s3c64xx_serial_ops;
break; break;
} }
...@@ -2175,7 +2192,8 @@ static int s3c24xx_serial_resume_noirq(struct device *dev) ...@@ -2175,7 +2192,8 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
if (port) { if (port) {
/* restore IRQ mask */ /* restore IRQ mask */
if (s3c24xx_serial_has_interrupt_mask(port)) { switch (ourport->info->type) {
case TYPE_S3C6400: {
unsigned int uintm = 0xf; unsigned int uintm = 0xf;
if (ourport->tx_enabled) if (ourport->tx_enabled)
...@@ -2189,6 +2207,10 @@ static int s3c24xx_serial_resume_noirq(struct device *dev) ...@@ -2189,6 +2207,10 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
if (!IS_ERR(ourport->baudclk)) if (!IS_ERR(ourport->baudclk))
clk_disable_unprepare(ourport->baudclk); clk_disable_unprepare(ourport->baudclk);
clk_disable_unprepare(ourport->clk); clk_disable_unprepare(ourport->clk);
break;
}
default:
break;
} }
} }
...@@ -2413,7 +2435,8 @@ static struct console s3c24xx_serial_console = { ...@@ -2413,7 +2435,8 @@ static struct console s3c24xx_serial_console = {
static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = { static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
.info = &(struct s3c24xx_uart_info) { .info = &(struct s3c24xx_uart_info) {
.name = "Samsung S3C2410 UART", .name = "Samsung S3C2410 UART",
.type = PORT_S3C2410, .type = TYPE_S3C24XX,
.port_type = PORT_S3C2410,
.fifosize = 16, .fifosize = 16,
.rx_fifomask = S3C2410_UFSTAT_RXMASK, .rx_fifomask = S3C2410_UFSTAT_RXMASK,
.rx_fifoshift = S3C2410_UFSTAT_RXSHIFT, .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
...@@ -2440,7 +2463,8 @@ static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = { ...@@ -2440,7 +2463,8 @@ static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = { static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
.info = &(struct s3c24xx_uart_info) { .info = &(struct s3c24xx_uart_info) {
.name = "Samsung S3C2412 UART", .name = "Samsung S3C2412 UART",
.type = PORT_S3C2412, .type = TYPE_S3C24XX,
.port_type = PORT_S3C2412,
.fifosize = 64, .fifosize = 64,
.has_divslot = 1, .has_divslot = 1,
.rx_fifomask = S3C2440_UFSTAT_RXMASK, .rx_fifomask = S3C2440_UFSTAT_RXMASK,
...@@ -2469,7 +2493,8 @@ static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = { ...@@ -2469,7 +2493,8 @@ static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = { static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
.info = &(struct s3c24xx_uart_info) { .info = &(struct s3c24xx_uart_info) {
.name = "Samsung S3C2440 UART", .name = "Samsung S3C2440 UART",
.type = PORT_S3C2440, .type = TYPE_S3C24XX,
.port_type = PORT_S3C2440,
.fifosize = 64, .fifosize = 64,
.has_divslot = 1, .has_divslot = 1,
.rx_fifomask = S3C2440_UFSTAT_RXMASK, .rx_fifomask = S3C2440_UFSTAT_RXMASK,
...@@ -2498,7 +2523,8 @@ static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = { ...@@ -2498,7 +2523,8 @@ static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = { static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
.info = &(struct s3c24xx_uart_info) { .info = &(struct s3c24xx_uart_info) {
.name = "Samsung S3C6400 UART", .name = "Samsung S3C6400 UART",
.type = PORT_S3C6400, .type = TYPE_S3C6400,
.port_type = PORT_S3C6400,
.fifosize = 64, .fifosize = 64,
.has_divslot = 1, .has_divslot = 1,
.rx_fifomask = S3C2440_UFSTAT_RXMASK, .rx_fifomask = S3C2440_UFSTAT_RXMASK,
...@@ -2526,7 +2552,8 @@ static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = { ...@@ -2526,7 +2552,8 @@ static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
.info = &(struct s3c24xx_uart_info) { .info = &(struct s3c24xx_uart_info) {
.name = "Samsung S5PV210 UART", .name = "Samsung S5PV210 UART",
.type = PORT_S3C6400, .type = TYPE_S3C6400,
.port_type = PORT_S3C6400,
.has_divslot = 1, .has_divslot = 1,
.rx_fifomask = S5PV210_UFSTAT_RXMASK, .rx_fifomask = S5PV210_UFSTAT_RXMASK,
.rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
...@@ -2554,7 +2581,8 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { ...@@ -2554,7 +2581,8 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
#define EXYNOS_COMMON_SERIAL_DRV_DATA \ #define EXYNOS_COMMON_SERIAL_DRV_DATA \
.info = &(struct s3c24xx_uart_info) { \ .info = &(struct s3c24xx_uart_info) { \
.name = "Samsung Exynos UART", \ .name = "Samsung Exynos UART", \
.type = PORT_S3C6400, \ .type = TYPE_S3C6400, \
.port_type = PORT_S3C6400, \
.has_divslot = 1, \ .has_divslot = 1, \
.rx_fifomask = S5PV210_UFSTAT_RXMASK, \ .rx_fifomask = S5PV210_UFSTAT_RXMASK, \
.rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \ .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment