summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/8250/8250_exar.c
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2019-07-31 20:05:58 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-09-04 12:43:49 +0200
commitb2b4b8ed3c06e5fc3586234b2dd2bb802b941261 (patch)
treedec84e989cf79dce492786e890bd4e81bd509a7c /drivers/tty/serial/8250/8250_exar.c
parentef4e281ecccd5bc824a52a4b1e8fbdff3614c852 (diff)
downloadlinux-b2b4b8ed3c06e5fc3586234b2dd2bb802b941261.tar.bz2
serial: 8250_exar: Move custom divisor support out from 8250_port
There are Exar custom divisor support in 8250_port which belongs to 8250_exar module. Move it out to the correct module and do not contaminate generic code with it. Cc: Aaron Sierra <asierra@xes-inc.com> Cc: Jan Kiszka <jan.kiszka@siemens.com> Cc: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://lore.kernel.org/r/20190731170558.52897-3-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/8250/8250_exar.c')
-rw-r--r--drivers/tty/serial/8250/8250_exar.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
index 1bf9adea2e61..3a39368e6e47 100644
--- a/drivers/tty/serial/8250/8250_exar.c
+++ b/drivers/tty/serial/8250/8250_exar.c
@@ -140,6 +140,31 @@ static void exar_pm(struct uart_port *port, unsigned int state, unsigned int old
serial_port_out(port, UART_EXAR_SLEEP, state ? 0xff : 0);
}
+/*
+ * XR17V35x UARTs have an extra fractional divisor register (DLD)
+ * Calculate divisor with extra 4-bit fractional portion
+ */
+static unsigned int xr17v35x_get_divisor(struct uart_port *p, unsigned int baud,
+ unsigned int *frac)
+{
+ unsigned int quot_16;
+
+ quot_16 = DIV_ROUND_CLOSEST(p->uartclk, baud);
+ *frac = quot_16 & 0x0f;
+
+ return quot_16 >> 4;
+}
+
+static void xr17v35x_set_divisor(struct uart_port *p, unsigned int baud,
+ unsigned int quot, unsigned int quot_frac)
+{
+ serial8250_do_set_divisor(p, baud, quot, quot_frac);
+
+ /* Preserve bits not related to baudrate; DLD[7:4]. */
+ quot_frac |= serial_port_in(p, 0x2) & 0xf0;
+ serial_port_out(p, 0x2, quot_frac);
+}
+
static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev,
int idx, unsigned int offset,
struct uart_8250_port *port)
@@ -163,6 +188,9 @@ static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev,
status = readb(port->port.membase + UART_EXAR_DVID);
if (status == 0x82 || status == 0x84 || status == 0x88) {
port->port.type = PORT_XR17V35X;
+
+ port->port.get_divisor = xr17v35x_get_divisor;
+ port->port.set_divisor = xr17v35x_set_divisor;
} else {
port->port.type = PORT_XR17D15X;
}