Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+32 −9
Original line number Diff line number Diff line
@@ -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++)
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;