Commit 78adccac authored by Alexander Shiyan's avatar Alexander Shiyan Committed by Greg Kroah-Hartman

serial: max310x: Assign port line automatically

This patch makes assignment of port line automatically,
so now user allow to use several MAX310X chips.
Signed-off-by: default avatarAlexander Shiyan <shc_work@mail.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c8246fef
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#define MAX310X_NAME "max310x" #define MAX310X_NAME "max310x"
#define MAX310X_MAJOR 204 #define MAX310X_MAJOR 204
#define MAX310X_MINOR 209 #define MAX310X_MINOR 209
#define MAX310X_UART_NR 4 #define MAX310X_UART_NRMAX 16
/* MAX310X register definitions */ /* MAX310X register definitions */
#define MAX310X_RHR_REG (0x00) /* RX FIFO */ #define MAX310X_RHR_REG (0x00) /* RX FIFO */
...@@ -279,9 +279,11 @@ static struct uart_driver max310x_uart = { ...@@ -279,9 +279,11 @@ static struct uart_driver max310x_uart = {
.dev_name = "ttyMAX", .dev_name = "ttyMAX",
.major = MAX310X_MAJOR, .major = MAX310X_MAJOR,
.minor = MAX310X_MINOR, .minor = MAX310X_MINOR,
.nr = MAX310X_UART_NR, .nr = MAX310X_UART_NRMAX,
}; };
static DECLARE_BITMAP(max310x_lines, MAX310X_UART_NRMAX);
static u8 max310x_port_read(struct uart_port *port, u8 reg) static u8 max310x_port_read(struct uart_port *port, u8 reg)
{ {
struct max310x_port *s = dev_get_drvdata(port->dev); struct max310x_port *s = dev_get_drvdata(port->dev);
...@@ -600,9 +602,7 @@ static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen) ...@@ -600,9 +602,7 @@ static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
unsigned int sts, ch, flag; unsigned int sts, ch, flag;
if (unlikely(rxlen >= port->fifosize)) { if (unlikely(rxlen >= port->fifosize)) {
dev_warn_ratelimited(port->dev, dev_warn_ratelimited(port->dev, "Possible RX FIFO overrun\n");
"Port %i: Possible RX FIFO overrun\n",
port->line);
port->icount.buf_overrun++; port->icount.buf_overrun++;
/* Ensure sanity of RX level */ /* Ensure sanity of RX level */
rxlen = port->fifosize; rxlen = port->fifosize;
...@@ -1193,8 +1193,16 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, ...@@ -1193,8 +1193,16 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
mutex_init(&s->mutex); mutex_init(&s->mutex);
for (i = 0; i < devtype->nr; i++) { for (i = 0; i < devtype->nr; i++) {
unsigned int line;
line = find_first_zero_bit(max310x_lines, MAX310X_UART_NRMAX);
if (line == MAX310X_UART_NRMAX) {
ret = -ERANGE;
goto out_uart;
}
/* Initialize port data */ /* Initialize port data */
s->p[i].port.line = i; s->p[i].port.line = line;
s->p[i].port.dev = dev; s->p[i].port.dev = dev;
s->p[i].port.irq = irq; s->p[i].port.irq = irq;
s->p[i].port.type = PORT_MAX310X; s->p[i].port.type = PORT_MAX310X;
...@@ -1220,8 +1228,15 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, ...@@ -1220,8 +1228,15 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
INIT_WORK(&s->p[i].md_work, max310x_md_proc); INIT_WORK(&s->p[i].md_work, max310x_md_proc);
/* Initialize queue for changing RS485 mode */ /* Initialize queue for changing RS485 mode */
INIT_WORK(&s->p[i].rs_work, max310x_rs_proc); INIT_WORK(&s->p[i].rs_work, max310x_rs_proc);
/* Register port */ /* Register port */
uart_add_one_port(&max310x_uart, &s->p[i].port); ret = uart_add_one_port(&max310x_uart, &s->p[i].port);
if (ret) {
s->p[i].port.dev = NULL;
goto out_uart;
}
set_bit(line, max310x_lines);
/* Go to suspend mode */ /* Go to suspend mode */
devtype->power(&s->p[i].port, 0); devtype->power(&s->p[i].port, 0);
} }
...@@ -1234,8 +1249,13 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, ...@@ -1234,8 +1249,13 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
dev_err(dev, "Unable to reguest IRQ %i\n", irq); dev_err(dev, "Unable to reguest IRQ %i\n", irq);
for (i = 0; i < devtype->nr; i++) out_uart:
uart_remove_one_port(&max310x_uart, &s->p[i].port); for (i = 0; i < devtype->nr; i++) {
if (s->p[i].port.dev) {
uart_remove_one_port(&max310x_uart, &s->p[i].port);
clear_bit(s->p[i].port.line, max310x_lines);
}
}
mutex_destroy(&s->mutex); mutex_destroy(&s->mutex);
...@@ -1255,6 +1275,7 @@ static int max310x_remove(struct device *dev) ...@@ -1255,6 +1275,7 @@ static int max310x_remove(struct device *dev)
cancel_work_sync(&s->p[i].md_work); cancel_work_sync(&s->p[i].md_work);
cancel_work_sync(&s->p[i].rs_work); cancel_work_sync(&s->p[i].rs_work);
uart_remove_one_port(&max310x_uart, &s->p[i].port); uart_remove_one_port(&max310x_uart, &s->p[i].port);
clear_bit(s->p[i].port.line, max310x_lines);
s->devtype->power(&s->p[i].port, 0); s->devtype->power(&s->p[i].port, 0);
} }
...@@ -1347,6 +1368,8 @@ static int __init max310x_uart_init(void) ...@@ -1347,6 +1368,8 @@ static int __init max310x_uart_init(void)
{ {
int ret; int ret;
bitmap_zero(max310x_lines, MAX310X_UART_NRMAX);
ret = uart_register_driver(&max310x_uart); ret = uart_register_driver(&max310x_uart);
if (ret) if (ret)
return ret; return ret;
......
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