]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
serial: 8250_dw: switch to use 8250_dwlib library
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tue, 6 Aug 2019 09:43:17 +0000 (12:43 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Sep 2019 10:43:52 +0000 (12:43 +0200)
Since we have a common library module for Synopsys DesignWare UART,
let us use it.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20190806094322.64987-4-andriy.shevchenko@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_dw.c
drivers/tty/serial/8250/Kconfig

index 010d0a292e73c236ac731d7c9cd7b438ae07c235..1c72fdc2dd3780112338641b3d47d400840bfecf 100644 (file)
 
 #include <asm/byteorder.h>
 
-#include "8250.h"
+#include "8250_dwlib.h"
 
 /* Offsets for the DesignWare specific registers */
 #define DW_UART_USR    0x1f /* UART Status Register */
-#define DW_UART_DLF    0xc0 /* Divisor Latch Fraction Register */
-#define DW_UART_CPR    0xf4 /* Component Parameter Register */
-#define DW_UART_UCV    0xf8 /* UART Component Version */
-
-/* Component Parameter Register bits */
-#define DW_UART_CPR_ABP_DATA_WIDTH     (3 << 0)
-#define DW_UART_CPR_AFCE_MODE          (1 << 4)
-#define DW_UART_CPR_THRE_MODE          (1 << 5)
-#define DW_UART_CPR_SIR_MODE           (1 << 6)
-#define DW_UART_CPR_SIR_LP_MODE                (1 << 7)
-#define DW_UART_CPR_ADDITIONAL_FEATURES        (1 << 8)
-#define DW_UART_CPR_FIFO_ACCESS                (1 << 9)
-#define DW_UART_CPR_FIFO_STAT          (1 << 10)
-#define DW_UART_CPR_SHADOW             (1 << 11)
-#define DW_UART_CPR_ENCODED_PARMS      (1 << 12)
-#define DW_UART_CPR_DMA_EXTRA          (1 << 13)
-#define DW_UART_CPR_FIFO_MODE          (0xff << 16)
-/* Helper for fifo size calculation */
-#define DW_UART_CPR_FIFO_SIZE(a)       (((a >> 16) & 0xff) * 16)
 
 /* DesignWare specific register fields */
 #define DW_UART_MCR_SIRE               BIT(6)
 
 struct dw8250_data {
+       struct dw8250_port_data data;
+
        u8                      usr_reg;
-       u8                      dlf_size;
-       int                     line;
        int                     msr_mask_on;
        int                     msr_mask_off;
        struct clk              *clk;
        struct clk              *pclk;
        struct reset_control    *rst;
-       struct uart_8250_dma    dma;
 
        unsigned int            skip_autocfg:1;
        unsigned int            uart_16550_compatible:1;
 };
 
-static inline u32 dw8250_readl_ext(struct uart_port *p, int offset)
+static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data)
 {
-       if (p->iotype == UPIO_MEM32BE)
-               return ioread32be(p->membase + offset);
-       return readl(p->membase + offset);
-}
-
-static inline void dw8250_writel_ext(struct uart_port *p, int offset, u32 reg)
-{
-       if (p->iotype == UPIO_MEM32BE)
-               iowrite32be(reg, p->membase + offset);
-       else
-               writel(reg, p->membase + offset);
+       return container_of(data, struct dw8250_data, data);
 }
 
 static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
 {
-       struct dw8250_data *d = p->private_data;
+       struct dw8250_data *d = to_dw8250_data(p->private_data);
 
        /* Override any modem control signals if needed */
        if (offset == UART_MSR) {
@@ -160,7 +130,7 @@ static void dw8250_tx_wait_empty(struct uart_port *p)
 
 static void dw8250_serial_out38x(struct uart_port *p, int offset, int value)
 {
-       struct dw8250_data *d = p->private_data;
+       struct dw8250_data *d = to_dw8250_data(p->private_data);
 
        /* Allow the TX to drain before we reconfigure */
        if (offset == UART_LCR)
@@ -175,7 +145,7 @@ static void dw8250_serial_out38x(struct uart_port *p, int offset, int value)
 
 static void dw8250_serial_out(struct uart_port *p, int offset, int value)
 {
-       struct dw8250_data *d = p->private_data;
+       struct dw8250_data *d = to_dw8250_data(p->private_data);
 
        writeb(value, p->membase + (offset << p->regshift));
 
@@ -202,7 +172,7 @@ static unsigned int dw8250_serial_inq(struct uart_port *p, int offset)
 
 static void dw8250_serial_outq(struct uart_port *p, int offset, int value)
 {
-       struct dw8250_data *d = p->private_data;
+       struct dw8250_data *d = to_dw8250_data(p->private_data);
 
        value &= 0xff;
        __raw_writeq(value, p->membase + (offset << p->regshift));
@@ -216,7 +186,7 @@ static void dw8250_serial_outq(struct uart_port *p, int offset, int value)
 
 static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
 {
-       struct dw8250_data *d = p->private_data;
+       struct dw8250_data *d = to_dw8250_data(p->private_data);
 
        writel(value, p->membase + (offset << p->regshift));
 
@@ -233,7 +203,7 @@ static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
 
 static void dw8250_serial_out32be(struct uart_port *p, int offset, int value)
 {
-       struct dw8250_data *d = p->private_data;
+       struct dw8250_data *d = to_dw8250_data(p->private_data);
 
        iowrite32be(value, p->membase + (offset << p->regshift));
 
@@ -252,7 +222,7 @@ static unsigned int dw8250_serial_in32be(struct uart_port *p, int offset)
 static int dw8250_handle_irq(struct uart_port *p)
 {
        struct uart_8250_port *up = up_to_u8250p(p);
-       struct dw8250_data *d = p->private_data;
+       struct dw8250_data *d = to_dw8250_data(p->private_data);
        unsigned int iir = p->serial_in(p, UART_IIR);
        unsigned int status;
        unsigned long flags;
@@ -306,7 +276,7 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
                               struct ktermios *old)
 {
        unsigned int baud = tty_termios_baud_rate(termios);
-       struct dw8250_data *d = p->private_data;
+       struct dw8250_data *d = to_dw8250_data(p->private_data);
        long rate;
        int ret;
 
@@ -368,37 +338,6 @@ static bool dw8250_idma_filter(struct dma_chan *chan, void *param)
        return param == chan->device->dev;
 }
 
-/*
- * divisor = div(I) + div(F)
- * "I" means integer, "F" means fractional
- * quot = div(I) = clk / (16 * baud)
- * frac = div(F) * 2^dlf_size
- *
- * let rem = clk % (16 * baud)
- * we have: div(F) * (16 * baud) = rem
- * so frac = 2^dlf_size * rem / (16 * baud) = (rem << dlf_size) / (16 * baud)
- */
-static unsigned int dw8250_get_divisor(struct uart_port *p,
-                                      unsigned int baud,
-                                      unsigned int *frac)
-{
-       unsigned int quot, rem, base_baud = baud * 16;
-       struct dw8250_data *d = p->private_data;
-
-       quot = p->uartclk / base_baud;
-       rem = p->uartclk % base_baud;
-       *frac = DIV_ROUND_CLOSEST(rem << d->dlf_size, base_baud);
-
-       return quot;
-}
-
-static void dw8250_set_divisor(struct uart_port *p, unsigned int baud,
-                              unsigned int quot, unsigned int quot_frac)
-{
-       dw8250_writel_ext(p, DW_UART_DLF, quot_frac);
-       serial8250_do_set_divisor(p, baud, quot, quot_frac);
-}
-
 static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
 {
        if (p->dev->of_node) {
@@ -437,59 +376,12 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
        /* Platforms with iDMA 64-bit */
        if (platform_get_resource_byname(to_platform_device(p->dev),
                                         IORESOURCE_MEM, "lpss_priv")) {
-               data->dma.rx_param = p->dev->parent;
-               data->dma.tx_param = p->dev->parent;
-               data->dma.fn = dw8250_idma_filter;
+               data->data.dma.rx_param = p->dev->parent;
+               data->data.dma.tx_param = p->dev->parent;
+               data->data.dma.fn = dw8250_idma_filter;
        }
 }
 
-static void dw8250_setup_port(struct uart_port *p)
-{
-       struct uart_8250_port *up = up_to_u8250p(p);
-       u32 reg;
-
-       /*
-        * If the Component Version Register returns zero, we know that
-        * ADDITIONAL_FEATURES are not enabled. No need to go any further.
-        */
-       reg = dw8250_readl_ext(p, DW_UART_UCV);
-       if (!reg)
-               return;
-
-       dev_dbg(p->dev, "Designware UART version %c.%c%c\n",
-               (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff);
-
-       dw8250_writel_ext(p, DW_UART_DLF, ~0U);
-       reg = dw8250_readl_ext(p, DW_UART_DLF);
-       dw8250_writel_ext(p, DW_UART_DLF, 0);
-
-       if (reg) {
-               struct dw8250_data *d = p->private_data;
-
-               d->dlf_size = fls(reg);
-               p->get_divisor = dw8250_get_divisor;
-               p->set_divisor = dw8250_set_divisor;
-       }
-
-       reg = dw8250_readl_ext(p, DW_UART_CPR);
-       if (!reg)
-               return;
-
-       /* Select the type based on fifo */
-       if (reg & DW_UART_CPR_FIFO_MODE) {
-               p->type = PORT_16550A;
-               p->flags |= UPF_FIXED_TYPE;
-               p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
-               up->capabilities = UART_CAP_FIFO;
-       }
-
-       if (reg & DW_UART_CPR_AFCE_MODE)
-               up->capabilities |= UART_CAP_AFE;
-
-       if (reg & DW_UART_CPR_SIR_MODE)
-               up->capabilities |= UART_CAP_IRDA;
-}
-
 static int dw8250_probe(struct platform_device *pdev)
 {
        struct uart_8250_port uart = {}, *up = &uart;
@@ -534,9 +426,9 @@ static int dw8250_probe(struct platform_device *pdev)
        if (!data)
                return -ENOMEM;
 
-       data->dma.fn = dw8250_fallback_dma_filter;
+       data->data.dma.fn = dw8250_fallback_dma_filter;
        data->usr_reg = DW_UART_USR;
-       p->private_data = data;
+       p->private_data = &data->data;
 
        data->uart_16550_compatible = device_property_read_bool(dev,
                                                "snps,uart-16550-compatible");
@@ -632,14 +524,14 @@ static int dw8250_probe(struct platform_device *pdev)
 
        /* If we have a valid fifosize, try hooking up DMA */
        if (p->fifosize) {
-               data->dma.rxconf.src_maxburst = p->fifosize / 4;
-               data->dma.txconf.dst_maxburst = p->fifosize / 4;
-               up->dma = &data->dma;
+               data->data.dma.rxconf.src_maxburst = p->fifosize / 4;
+               data->data.dma.txconf.dst_maxburst = p->fifosize / 4;
+               up->dma = &data->data.dma;
        }
 
-       data->line = serial8250_register_8250_port(up);
-       if (data->line < 0) {
-               err = data->line;
+       data->data.line = serial8250_register_8250_port(up);
+       if (data->data.line < 0) {
+               err = data->data.line;
                goto err_reset;
        }
 
@@ -671,7 +563,7 @@ static int dw8250_remove(struct platform_device *pdev)
 
        pm_runtime_get_sync(dev);
 
-       serial8250_unregister_port(data->line);
+       serial8250_unregister_port(data->data.line);
 
        reset_control_assert(data->rst);
 
@@ -692,7 +584,7 @@ static int dw8250_suspend(struct device *dev)
 {
        struct dw8250_data *data = dev_get_drvdata(dev);
 
-       serial8250_suspend_port(data->line);
+       serial8250_suspend_port(data->data.line);
 
        return 0;
 }
@@ -701,7 +593,7 @@ static int dw8250_resume(struct device *dev)
 {
        struct dw8250_data *data = dev_get_drvdata(dev);
 
-       serial8250_resume_port(data->line);
+       serial8250_resume_port(data->data.line);
 
        return 0;
 }
index d628258fb4cfcedafea78bfed0e1d887ddbbf463..90abf97b378da3977ec1f18cf95cd938f983b48c 100644 (file)
@@ -357,6 +357,7 @@ config SERIAL_8250_FSL
 config SERIAL_8250_DW
        tristate "Support for Synopsys DesignWare 8250 quirks"
        depends on SERIAL_8250
+       select SERIAL_8250_DWLIB
        help
          Selecting this option will enable handling of the extra features
          present in the Synopsys DesignWare APB UART.