]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
serial: sh-sci: Extend sci_port_params with more port parameters
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Wed, 11 Jan 2017 14:43:36 +0000 (16:43 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Jan 2017 13:17:05 +0000 (14:17 +0100)
The fifo size, overrun register and mask, sampling rate mask and error
mask all depend on the port type only and don't need to be computed at
runtime. Add them to the sci_port_parameters structure.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/sh-sci.c
drivers/tty/serial/sh-sci.h

index d50368e58314cd006707c9d35e9520d289560a42..a8607cacee6cae1a1afac6779af8f58be4e711f1 100644 (file)
@@ -107,6 +107,12 @@ struct plat_sci_reg {
 
 struct sci_port_params {
        const struct plat_sci_reg regs[SCIx_NR_REGS];
+       unsigned int fifosize;
+       unsigned int overrun_reg;
+       unsigned int overrun_mask;
+       unsigned int sampling_rate_mask;
+       unsigned int error_mask;
+       unsigned int error_clear;
 };
 
 struct sci_port {
@@ -115,10 +121,6 @@ struct sci_port {
        /* Platform configuration */
        const struct sci_port_params *params;
        const struct plat_sci_port *cfg;
-       unsigned int            overrun_reg;
-       unsigned int            overrun_mask;
-       unsigned int            error_mask;
-       unsigned int            error_clear;
        unsigned int            sampling_rate_mask;
        resource_size_t         reg_size;
        struct mctrl_gpios      *gpios;
@@ -179,6 +181,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCxSR]         = { 0x04,  8 },
                        [SCxRDR]        = { 0x05,  8 },
                },
+               .fifosize = 1,
+               .overrun_reg = SCxSR,
+               .overrun_mask = SCI_ORER,
+               .sampling_rate_mask = SCI_SR(32),
+               .error_mask = SCI_DEFAULT_ERROR_MASK | SCI_ORER,
+               .error_clear = SCI_ERROR_CLEAR & ~SCI_ORER,
        },
 
        /*
@@ -195,6 +203,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCFCR]         = { 0x0c,  8 },
                        [SCFDR]         = { 0x0e, 16 },
                },
+               .fifosize = 1,
+               .overrun_reg = SCxSR,
+               .overrun_mask = SCI_ORER,
+               .sampling_rate_mask = SCI_SR(32),
+               .error_mask = SCI_DEFAULT_ERROR_MASK | SCI_ORER,
+               .error_clear = SCI_ERROR_CLEAR & ~SCI_ORER,
        },
 
        /*
@@ -213,6 +227,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCPCR]         = { 0x30, 16 },
                        [SCPDR]         = { 0x34, 16 },
                },
+               .fifosize = 64,
+               .overrun_reg = SCxSR,
+               .overrun_mask = SCIFA_ORER,
+               .sampling_rate_mask = SCI_SR_SCIFAB,
+               .error_mask = SCIF_DEFAULT_ERROR_MASK | SCIFA_ORER,
+               .error_clear = SCIF_ERROR_CLEAR & ~SCIFA_ORER,
        },
 
        /*
@@ -232,6 +252,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCPCR]         = { 0x30, 16 },
                        [SCPDR]         = { 0x34, 16 },
                },
+               .fifosize = 256,
+               .overrun_reg = SCxSR,
+               .overrun_mask = SCIFA_ORER,
+               .sampling_rate_mask = SCI_SR_SCIFAB,
+               .error_mask = SCIF_DEFAULT_ERROR_MASK | SCIFA_ORER,
+               .error_clear = SCIF_ERROR_CLEAR & ~SCIFA_ORER,
        },
 
        /*
@@ -251,6 +277,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCSPTR]        = { 0x20, 16 },
                        [SCLSR]         = { 0x24, 16 },
                },
+               .fifosize = 16,
+               .overrun_reg = SCLSR,
+               .overrun_mask = SCLSR_ORER,
+               .sampling_rate_mask = SCI_SR(32),
+               .error_mask = SCIF_DEFAULT_ERROR_MASK,
+               .error_clear = SCIF_ERROR_CLEAR,
        },
 
        /*
@@ -267,6 +299,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCFCR]         = { 0x0c,  8 },
                        [SCFDR]         = { 0x0e, 16 },
                },
+               .fifosize = 16,
+               .overrun_reg = SCLSR,
+               .overrun_mask = SCLSR_ORER,
+               .sampling_rate_mask = SCI_SR(32),
+               .error_mask = SCIF_DEFAULT_ERROR_MASK,
+               .error_clear = SCIF_ERROR_CLEAR,
        },
 
        /*
@@ -285,6 +323,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCSPTR]        = { 0x20, 16 },
                        [SCLSR]         = { 0x24, 16 },
                },
+               .fifosize = 16,
+               .overrun_reg = SCLSR,
+               .overrun_mask = SCLSR_ORER,
+               .sampling_rate_mask = SCI_SR(32),
+               .error_mask = SCIF_DEFAULT_ERROR_MASK,
+               .error_clear = SCIF_ERROR_CLEAR,
        },
 
        /*
@@ -306,6 +350,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCDL]          = { 0x30, 16 },
                        [SCCKS]         = { 0x34, 16 },
                },
+               .fifosize = 16,
+               .overrun_reg = SCLSR,
+               .overrun_mask = SCLSR_ORER,
+               .sampling_rate_mask = SCI_SR(32),
+               .error_mask = SCIF_DEFAULT_ERROR_MASK,
+               .error_clear = SCIF_ERROR_CLEAR,
        },
 
        /*
@@ -327,6 +377,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCDL]          = { 0x30, 16 },
                        [SCCKS]         = { 0x34, 16 },
                },
+               .fifosize = 128,
+               .overrun_reg = SCLSR,
+               .overrun_mask = SCLSR_ORER,
+               .sampling_rate_mask = SCI_SR_RANGE(8, 32),
+               .error_mask = SCIF_DEFAULT_ERROR_MASK,
+               .error_clear = SCIF_ERROR_CLEAR,
        },
 
        /*
@@ -345,6 +401,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCFDR]         = { 0x1c, 16 },
                        [SCLSR]         = { 0x24, 16 },
                },
+               .fifosize = 16,
+               .overrun_reg = SCLSR,
+               .overrun_mask = SCLSR_ORER,
+               .sampling_rate_mask = SCI_SR(32),
+               .error_mask = SCIF_DEFAULT_ERROR_MASK,
+               .error_clear = SCIF_ERROR_CLEAR,
        },
 
        /*
@@ -366,6 +428,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCSPTR]        = { 0x24, 16 },
                        [SCLSR]         = { 0x28, 16 },
                },
+               .fifosize = 16,
+               .overrun_reg = SCLSR,
+               .overrun_mask = SCLSR_ORER,
+               .sampling_rate_mask = SCI_SR(32),
+               .error_mask = SCIF_DEFAULT_ERROR_MASK,
+               .error_clear = SCIF_ERROR_CLEAR,
        },
 
        /*
@@ -383,6 +451,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                        [SCFCR]         = { 0x18, 16 },
                        [SCFDR]         = { 0x1c, 16 },
                },
+               .fifosize = 16,
+               .overrun_reg = SCxSR,
+               .overrun_mask = SCIFA_ORER,
+               .sampling_rate_mask = SCI_SR(16),
+               .error_mask = SCIF_DEFAULT_ERROR_MASK | SCIFA_ORER,
+               .error_clear = SCIF_ERROR_CLEAR & ~SCIFA_ORER,
        },
 };
 
@@ -545,7 +619,7 @@ static void sci_clear_SCxSR(struct uart_port *port, unsigned int mask)
        if (port->type == PORT_SCI) {
                /* Just store the mask */
                serial_port_out(port, SCxSR, mask);
-       } else if (to_sci_port(port)->overrun_mask == SCIFA_ORER) {
+       } else if (to_sci_port(port)->params->overrun_mask == SCIFA_ORER) {
                /* SCIFA/SCIFB and SCIF on SH7705/SH7720/SH7721 */
                /* Only clear the status bits we want to clear */
                serial_port_out(port, SCxSR,
@@ -640,11 +714,13 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
 
 static int sci_txfill(struct uart_port *port)
 {
+       struct sci_port *s = to_sci_port(port);
+       unsigned int fifo_mask = (s->params->fifosize << 1) - 1;
        const struct plat_sci_reg *reg;
 
        reg = sci_getreg(port, SCTFDR);
        if (reg->size)
-               return serial_port_in(port, SCTFDR) & ((port->fifosize << 1) - 1);
+               return serial_port_in(port, SCTFDR) & fifo_mask;
 
        reg = sci_getreg(port, SCFDR);
        if (reg->size)
@@ -660,15 +736,17 @@ static int sci_txroom(struct uart_port *port)
 
 static int sci_rxfill(struct uart_port *port)
 {
+       struct sci_port *s = to_sci_port(port);
+       unsigned int fifo_mask = (s->params->fifosize << 1) - 1;
        const struct plat_sci_reg *reg;
 
        reg = sci_getreg(port, SCRFDR);
        if (reg->size)
-               return serial_port_in(port, SCRFDR) & ((port->fifosize << 1) - 1);
+               return serial_port_in(port, SCRFDR) & fifo_mask;
 
        reg = sci_getreg(port, SCFDR);
        if (reg->size)
-               return serial_port_in(port, SCFDR) & ((port->fifosize << 1) - 1);
+               return serial_port_in(port, SCFDR) & fifo_mask;
 
        return (serial_port_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
 }
@@ -879,7 +957,7 @@ static int sci_handle_errors(struct uart_port *port)
        struct sci_port *s = to_sci_port(port);
 
        /* Handle overruns */
-       if (status & s->overrun_mask) {
+       if (status & s->params->overrun_mask) {
                port->icount.overrun++;
 
                /* overrun error */
@@ -945,14 +1023,14 @@ static int sci_handle_fifo_overrun(struct uart_port *port)
        int copied = 0;
        u16 status;
 
-       reg = sci_getreg(port, s->overrun_reg);
+       reg = sci_getreg(port, s->params->overrun_reg);
        if (!reg->size)
                return 0;
 
-       status = serial_port_in(port, s->overrun_reg);
-       if (status & s->overrun_mask) {
-               status &= ~s->overrun_mask;
-               serial_port_out(port, s->overrun_reg, status);
+       status = serial_port_in(port, s->params->overrun_reg);
+       if (status & s->params->overrun_mask) {
+               status &= ~s->params->overrun_mask;
+               serial_port_out(port, s->params->overrun_reg, status);
 
                port->icount.overrun++;
 
@@ -1541,12 +1619,10 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
 
        ssr_status = serial_port_in(port, SCxSR);
        scr_status = serial_port_in(port, SCSCR);
-       if (s->overrun_reg == SCxSR)
+       if (s->params->overrun_reg == SCxSR)
                orer_status = ssr_status;
-       else {
-               if (sci_getreg(port, s->overrun_reg)->size)
-                       orer_status = serial_port_in(port, s->overrun_reg);
-       }
+       else if (sci_getreg(port, s->params->overrun_reg)->size)
+               orer_status = serial_port_in(port, s->params->overrun_reg);
 
        err_enabled = scr_status & port_rx_irq_mask(port);
 
@@ -1572,7 +1648,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
                ret = sci_br_interrupt(irq, ptr);
 
        /* Overrun Interrupt */
-       if (orer_status & s->overrun_mask) {
+       if (orer_status & s->params->overrun_mask) {
                sci_handle_fifo_overrun(port);
                ret = IRQ_HANDLED;
        }
@@ -2590,51 +2666,13 @@ static int sci_init_single(struct platform_device *dev,
        if (unlikely(sci_port->params == NULL))
                return -EINVAL;
 
-       switch (p->type) {
-       case PORT_SCIFB:
-               port->fifosize = 256;
-               sci_port->overrun_reg = SCxSR;
-               sci_port->overrun_mask = SCIFA_ORER;
-               sci_port->sampling_rate_mask = SCI_SR_SCIFAB;
-               break;
-       case PORT_HSCIF:
-               port->fifosize = 128;
-               sci_port->overrun_reg = SCLSR;
-               sci_port->overrun_mask = SCLSR_ORER;
-               sci_port->sampling_rate_mask = SCI_SR_RANGE(8, 32);
-               break;
-       case PORT_SCIFA:
-               port->fifosize = 64;
-               sci_port->overrun_reg = SCxSR;
-               sci_port->overrun_mask = SCIFA_ORER;
-               sci_port->sampling_rate_mask = SCI_SR_SCIFAB;
-               break;
-       case PORT_SCIF:
-               port->fifosize = 16;
-               if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) {
-                       sci_port->overrun_reg = SCxSR;
-                       sci_port->overrun_mask = SCIFA_ORER;
-                       sci_port->sampling_rate_mask = SCI_SR(16);
-               } else {
-                       sci_port->overrun_reg = SCLSR;
-                       sci_port->overrun_mask = SCLSR_ORER;
-                       sci_port->sampling_rate_mask = SCI_SR(32);
-               }
-               break;
-       default:
-               port->fifosize = 1;
-               sci_port->overrun_reg = SCxSR;
-               sci_port->overrun_mask = SCI_ORER;
-               sci_port->sampling_rate_mask = SCI_SR(32);
-               break;
-       }
-
        /* SCIFA on sh7723 and sh7724 need a custom sampling rate that doesn't
         * match the SoC datasheet, this should be investigated. Let platform
         * data override the sampling rate for now.
         */
-       if (p->sampling_rate)
-               sci_port->sampling_rate_mask = SCI_SR(p->sampling_rate);
+       sci_port->sampling_rate_mask = p->sampling_rate
+                                    ? SCI_SR(p->sampling_rate)
+                                    : sci_port->params->sampling_rate_mask;
 
        if (!early) {
                ret = sci_init_clocks(sci_port, &dev->dev);
@@ -2650,29 +2688,10 @@ static int sci_init_single(struct platform_device *dev,
        sci_port->break_timer.function = sci_break_timer;
        init_timer(&sci_port->break_timer);
 
-       /*
-        * Establish some sensible defaults for the error detection.
-        */
-       if (p->type == PORT_SCI) {
-               sci_port->error_mask = SCI_DEFAULT_ERROR_MASK;
-               sci_port->error_clear = SCI_ERROR_CLEAR;
-       } else {
-               sci_port->error_mask = SCIF_DEFAULT_ERROR_MASK;
-               sci_port->error_clear = SCIF_ERROR_CLEAR;
-       }
-
-       /*
-        * Make the error mask inclusive of overrun detection, if
-        * supported.
-        */
-       if (sci_port->overrun_reg == SCxSR) {
-               sci_port->error_mask |= sci_port->overrun_mask;
-               sci_port->error_clear &= ~sci_port->overrun_mask;
-       }
-
        port->type              = p->type;
        port->flags             = UPF_FIXED_PORT | UPF_BOOT_AUTOCONF | p->flags;
        port->regshift          = p->regshift;
+       port->fifosize          = sci_port->params->fifosize;
 
        /*
         * The UART port needs an IRQ value, so we peg this to the RX IRQ
index ffa6d688c335f252c453e821f246b4bbe357ea88..08073f0db732cf18b1b235f34e61010896671597 100644 (file)
@@ -151,12 +151,12 @@ enum {
 #define SCxSR_PER(port)                (((port)->type == PORT_SCI) ? SCI_PER    : SCIF_PER)
 #define SCxSR_BRK(port)                (((port)->type == PORT_SCI) ? 0x00       : SCIF_BRK)
 
-#define SCxSR_ERRORS(port)     (to_sci_port(port)->error_mask)
+#define SCxSR_ERRORS(port)     (to_sci_port(port)->params->error_mask)
 
 #define SCxSR_RDxF_CLEAR(port) \
        (((port)->type == PORT_SCI) ? SCI_RDxF_CLEAR : SCIF_RDxF_CLEAR)
 #define SCxSR_ERROR_CLEAR(port) \
-       (to_sci_port(port)->error_clear)
+       (to_sci_port(port)->params->error_clear)
 #define SCxSR_TDxE_CLEAR(port) \
        (((port)->type == PORT_SCI) ? SCI_TDxE_CLEAR : SCIF_TDxE_CLEAR)
 #define SCxSR_BREAK_CLEAR(port) \