mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
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: Alexander Shiyan <shc_work@mail.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c8246fefe2
commit
78adccac1f
1 changed files with 32 additions and 9 deletions
|
@ -32,7 +32,7 @@
|
|||
#define MAX310X_NAME "max310x"
|
||||
#define MAX310X_MAJOR 204
|
||||
#define MAX310X_MINOR 209
|
||||
#define MAX310X_UART_NR 4
|
||||
#define MAX310X_UART_NRMAX 16
|
||||
|
||||
/* MAX310X register definitions */
|
||||
#define MAX310X_RHR_REG (0x00) /* RX FIFO */
|
||||
|
@ -279,9 +279,11 @@ static struct uart_driver max310x_uart = {
|
|||
.dev_name = "ttyMAX",
|
||||
.major = MAX310X_MAJOR,
|
||||
.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)
|
||||
{
|
||||
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)
|
|||
unsigned int sts, ch, flag;
|
||||
|
||||
if (unlikely(rxlen >= port->fifosize)) {
|
||||
dev_warn_ratelimited(port->dev,
|
||||
"Port %i: Possible RX FIFO overrun\n",
|
||||
port->line);
|
||||
dev_warn_ratelimited(port->dev, "Possible RX FIFO overrun\n");
|
||||
port->icount.buf_overrun++;
|
||||
/* Ensure sanity of RX level */
|
||||
rxlen = port->fifosize;
|
||||
|
@ -1193,8 +1193,16 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
|
|||
mutex_init(&s->mutex);
|
||||
|
||||
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 */
|
||||
s->p[i].port.line = i;
|
||||
s->p[i].port.line = line;
|
||||
s->p[i].port.dev = dev;
|
||||
s->p[i].port.irq = irq;
|
||||
s->p[i].port.type = PORT_MAX310X;
|
||||
|
@ -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);
|
||||
/* Initialize queue for changing RS485 mode */
|
||||
INIT_WORK(&s->p[i].rs_work, max310x_rs_proc);
|
||||
|
||||
/* 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 */
|
||||
devtype->power(&s->p[i].port, 0);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
for (i = 0; i < devtype->nr; i++)
|
||||
uart_remove_one_port(&max310x_uart, &s->p[i].port);
|
||||
out_uart:
|
||||
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);
|
||||
|
||||
|
@ -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].rs_work);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1347,6 +1368,8 @@ static int __init max310x_uart_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
bitmap_zero(max310x_lines, MAX310X_UART_NRMAX);
|
||||
|
||||
ret = uart_register_driver(&max310x_uart);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue