lkml.org 
[lkml]   [2021]   [Feb]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 18/25] tty: serial: samsung_tty: add s3c24xx_port_type
    Date
    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, and adds the ucon_mask port info member to
    avoid having S3C2440 as a distinct type.

    Signed-off-by: Hector Martin <marcan@marcan.st>
    ---
    drivers/tty/serial/samsung_tty.c | 131 ++++++++++++++++++-------------
    1 file changed, 77 insertions(+), 54 deletions(-)

    diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
    index 6b661f3ec1ae..21955be680a4 100644
    --- a/drivers/tty/serial/samsung_tty.c
    +++ b/drivers/tty/serial/samsung_tty.c
    @@ -56,9 +56,15 @@
    /* flag to ignore all characters coming in */
    #define RXSTAT_DUMMY_READ (0x10000000)

    +enum s3c24xx_port_type {
    + TYPE_S3C24XX,
    + TYPE_S3C6400,
    +};
    +
    struct s3c24xx_uart_info {
    char *name;
    - unsigned int type;
    + enum s3c24xx_port_type type;
    + unsigned int port_type;
    unsigned int fifosize;
    unsigned long rx_fifomask;
    unsigned long rx_fifoshift;
    @@ -70,6 +76,7 @@ struct s3c24xx_uart_info {
    unsigned long num_clks;
    unsigned long clksel_mask;
    unsigned long clksel_shift;
    + unsigned long ucon_mask;

    /* uart port features */

    @@ -228,16 +235,6 @@ static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
    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)
    {
    struct s3c24xx_uart_port *ourport = to_ourport(port);
    @@ -289,10 +286,14 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
    if (!ourport->tx_enabled)
    return;

    - if (s3c24xx_serial_has_interrupt_mask(port))
    + switch (ourport->info->type) {
    + case TYPE_S3C6400:
    s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
    - else
    + break;
    + default:
    disable_irq_nosync(ourport->tx_irq);
    + break;
    + }

    if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) {
    dmaengine_pause(dma->tx_chan);
    @@ -353,10 +354,14 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
    u32 ucon;

    /* 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);
    - else
    + break;
    + default:
    disable_irq_nosync(ourport->tx_irq);
    + break;
    + }

    /* Enable tx dma mode */
    ucon = rd_regl(port, S3C2410_UCON);
    @@ -386,11 +391,14 @@ static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
    wr_regl(port, S3C2410_UCON, ucon);

    /* Unmask Tx interrupt */
    - if (s3c24xx_serial_has_interrupt_mask(port))
    - s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD,
    - S3C64XX_UINTM);
    - else
    + switch (ourport->info->type) {
    + case TYPE_S3C6400:
    + s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
    + break;
    + default:
    enable_irq(ourport->tx_irq);
    + break;
    + }

    ourport->tx_mode = S3C24XX_TX_PIO;
    }
    @@ -513,11 +521,14 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)

    if (ourport->rx_enabled) {
    dev_dbg(port->dev, "stopping rx\n");
    - if (s3c24xx_serial_has_interrupt_mask(port))
    - s3c24xx_set_bit(port, S3C64XX_UINTM_RXD,
    - S3C64XX_UINTM);
    - else
    - disable_irq_nosync(ourport->rx_irq);
    + switch (ourport->info->type) {
    + case TYPE_S3C6400:
    + s3c24xx_set_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM);
    + break;
    + default:
    + disable_irq_nosync(ourport->tx_irq);
    + break;
    + }
    ourport->rx_enabled = 0;
    }
    if (dma && dma->rx_chan) {
    @@ -1542,14 +1553,12 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,

    static const char *s3c24xx_serial_type(struct uart_port *port)
    {
    - switch (port->type) {
    - case PORT_S3C2410:
    - return "S3C2410";
    - case PORT_S3C2440:
    - return "S3C2440";
    - case PORT_S3C2412:
    - return "S3C2412";
    - case PORT_S3C6400:
    + struct s3c24xx_uart_port *ourport = to_ourport(port);
    +
    + switch (ourport->info->type) {
    + case TYPE_S3C24XX:
    + return "S3C24XX";
    + case TYPE_S3C6400:
    return "S3C6400/10";
    default:
    return NULL;
    @@ -1576,7 +1585,7 @@ static void s3c24xx_serial_config_port(struct uart_port *port, int flags)

    if (flags & UART_CONFIG_TYPE &&
    s3c24xx_serial_request_port(port) == 0)
    - port->type = info->type;
    + port->type = info->port_type;
    }

    /*
    @@ -1587,7 +1596,7 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
    {
    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 0;
    @@ -1736,14 +1745,9 @@ static void s3c24xx_serial_resetport(struct uart_port *port,
    {
    struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
    unsigned long ucon = rd_regl(port, S3C2410_UCON);
    - unsigned int ucon_mask;

    - ucon_mask = info->clksel_mask;
    - if (info->type == PORT_S3C2440)
    - ucon_mask |= S3C2440_UCON0_DIVMASK;
    -
    - ucon &= ucon_mask;
    - wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
    + ucon &= (info->clksel_mask | info->ucon_mask);
    + wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);

    /* reset both fifos */
    wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
    @@ -1931,11 +1935,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
    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);
    if (ret > 0)
    ourport->tx_irq = ret;
    + break;
    + default:
    + break;
    }
    +
    /*
    * DMA is currently supported only on DT platforms, if DMA properties
    * are specified.
    @@ -1971,10 +1980,14 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
    pr_warn("uart: failed to enable baudclk\n");

    /* 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_UINTP, 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",
    @@ -2046,12 +2059,10 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
    ourport->drv_data->def_cfg;

    switch (ourport->info->type) {
    - case PORT_S3C2410:
    - case PORT_S3C2412:
    - case PORT_S3C2440:
    + case TYPE_S3C24XX:
    ourport->port.ops = &s3c24xx_serial_ops;
    break;
    - case PORT_S3C6400:
    + case TYPE_S3C6400:
    ourport->port.ops = &s3c64xx_serial_ops;
    break;
    }
    @@ -2179,7 +2190,8 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)

    if (port) {
    /* restore IRQ mask */
    - if (s3c24xx_serial_has_interrupt_mask(port)) {
    + switch (ourport->info->type) {
    + case TYPE_S3C6400: {
    unsigned int uintm = 0xf;

    if (ourport->tx_enabled)
    @@ -2193,6 +2205,10 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
    if (!IS_ERR(ourport->baudclk))
    clk_disable_unprepare(ourport->baudclk);
    clk_disable_unprepare(ourport->clk);
    + break;
    + }
    + default:
    + break;
    }
    }

    @@ -2417,7 +2433,8 @@ static struct console s3c24xx_serial_console = {
    static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
    .info = &(struct s3c24xx_uart_info) {
    .name = "Samsung S3C2410 UART",
    - .type = PORT_S3C2410,
    + .type = TYPE_S3C24XX,
    + .port_type = PORT_S3C2410,
    .fifosize = 16,
    .rx_fifomask = S3C2410_UFSTAT_RXMASK,
    .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
    @@ -2444,7 +2461,8 @@ static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
    static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
    .info = &(struct s3c24xx_uart_info) {
    .name = "Samsung S3C2412 UART",
    - .type = PORT_S3C2412,
    + .type = TYPE_S3C24XX,
    + .port_type = PORT_S3C2412,
    .fifosize = 64,
    .has_divslot = 1,
    .rx_fifomask = S3C2440_UFSTAT_RXMASK,
    @@ -2473,7 +2491,8 @@ static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
    static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
    .info = &(struct s3c24xx_uart_info) {
    .name = "Samsung S3C2440 UART",
    - .type = PORT_S3C2440,
    + .type = TYPE_S3C24XX,
    + .port_type = PORT_S3C2440,
    .fifosize = 64,
    .has_divslot = 1,
    .rx_fifomask = S3C2440_UFSTAT_RXMASK,
    @@ -2486,6 +2505,7 @@ static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
    .num_clks = 4,
    .clksel_mask = S3C2412_UCON_CLKMASK,
    .clksel_shift = S3C2412_UCON_CLKSHIFT,
    + .ucon_mask = S3C2440_UCON0_DIVMASK,
    },
    .def_cfg = &(struct s3c2410_uartcfg) {
    .ucon = S3C2410_UCON_DEFAULT,
    @@ -2501,7 +2521,8 @@ static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
    static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
    .info = &(struct s3c24xx_uart_info) {
    .name = "Samsung S3C6400 UART",
    - .type = PORT_S3C6400,
    + .type = TYPE_S3C6400,
    + .port_type = PORT_S3C6400,
    .fifosize = 64,
    .has_divslot = 1,
    .rx_fifomask = S3C2440_UFSTAT_RXMASK,
    @@ -2529,7 +2550,8 @@ static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
    static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
    .info = &(struct s3c24xx_uart_info) {
    .name = "Samsung S5PV210 UART",
    - .type = PORT_S3C6400,
    + .type = TYPE_S3C6400,
    + .port_type = PORT_S3C6400,
    .has_divslot = 1,
    .rx_fifomask = S5PV210_UFSTAT_RXMASK,
    .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
    @@ -2557,7 +2579,8 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
    #define EXYNOS_COMMON_SERIAL_DRV_DATA \
    .info = &(struct s3c24xx_uart_info) { \
    .name = "Samsung Exynos UART", \
    - .type = PORT_S3C6400, \
    + .type = TYPE_S3C6400, \
    + .port_type = PORT_S3C6400, \
    .has_divslot = 1, \
    .rx_fifomask = S5PV210_UFSTAT_RXMASK, \
    .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \
    --
    2.30.0
    \
     
     \ /
      Last update: 2021-02-15 13:27    [W:5.984 / U:0.328 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site