Re: Patch for SC16IS7XX

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

please do not top post.

On Thu, 25 Jun 2015 17:05:00 +0200, Michael Allwright wrote:
> Well almost all my issues ;)
> 
> At the moment there is missing support for having more than one
> SC16IS7xx device. Because of this there is a name conflict in sysfs:
> 
> [    3.241912] sysfs: cannot create duplicate filename '/class/tty/ttySC1'
> ...
> [    3.312774] [<c01b157c>] (sysfs_warn_dup) from [<c01b188c>]
> (sysfs_do_create_link_sd.isra.2+0xa8/0xb4)
> [    3.323974] [<c01b188c>] (sysfs_do_create_link_sd.isra.2) from
> [<c03cd5a4>] (device_add+0x200/0x520)
> [    3.333557] [<c03cd5a4>] (device_add) from [<c039d834>]
> (tty_register_device_attr+0x1c8/0x240)
> [    3.333557] [<c039d834>] (tty_register_device_attr) from
> [<c03b8e84>] (uart_add_one_port+0x1c4/0x48c)
> [    3.352294] [<c03b8e84>] (uart_add_one_port) from [<c03c0d0c>]
> (sc16is7xx_i2c_probe+0x334/0x520)
> [    3.353271] [<c03c0d0c>] (sc16is7xx_i2c_probe) from [<c04cc52c>]
> (i2c_device_probe+0xf4/0x14c)
> ...
> 
> I will see if I can find a solution for this. It must be possible as
> the USB serial core has no problem adding ttyUSBX interfaces for each
> device plugged in... Any hints as always would be appreciated.

I think USB does some magic which is not necessary for a simple driver
like sc16is7xx.  Can you try the following patch?

--------->8---------------

>From 2ba8fbbfdbfc77008639de89e021d777324de749 Mon Sep 17 00:00:00 2001
From: Jakub Kicinski <kubakici@xxxxx>
Date: Thu, 25 Jun 2015 18:17:58 +0200
Subject: [PATCH] sc16is7xx: support multiple devices

Signed-off-by: Jakub Kicinski <kubakici@xxxxx>
---
 drivers/tty/serial/sc16is7xx.c | 48 ++++++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index 5ccc698cbbfa..9db22d9f0e0e 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -11,6 +11,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/bitops.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
@@ -29,6 +31,7 @@
 #include <linux/uaccess.h>
 
 #define SC16IS7XX_NAME			"sc16is7xx"
+#define SC16IS7XX_MAX_DEVS		8
 
 /* SC16IS7XX register definitions */
 #define SC16IS7XX_RHR_REG		(0x00) /* RX FIFO */
@@ -318,7 +321,6 @@ struct sc16is7xx_one {
 };
 
 struct sc16is7xx_port {
-	struct uart_driver		uart;
 	struct sc16is7xx_devtype	*devtype;
 	struct regmap			*regmap;
 	struct clk			*clk;
@@ -332,6 +334,12 @@ struct sc16is7xx_port {
 	struct sc16is7xx_one		p[0];
 };
 
+static struct uart_driver sc16is7xx_uart = {
+	.owner		= THIS_MODULE,
+	.dev_name	= "ttySC",
+	.nr		= SC16IS7XX_MAX_DEVS,
+};
+
 #define to_sc16is7xx_port(p,e)	((container_of((p), struct sc16is7xx_port, e)))
 #define to_sc16is7xx_one(p,e)	((container_of((p), struct sc16is7xx_one, e)))
 
@@ -661,7 +669,7 @@ static void sc16is7xx_ist(struct kthread_work *ws)
 	struct sc16is7xx_port *s = to_sc16is7xx_port(ws, irq_work);
 	int i;
 
-	for (i = 0; i < s->uart.nr; ++i)
+	for (i = 0; i < s->devtype->nr_uart; ++i)
 		sc16is7xx_port_irq(s, i);
 }
 
@@ -1134,23 +1142,13 @@ static int sc16is7xx_probe(struct device *dev,
 	s->devtype = devtype;
 	dev_set_drvdata(dev, s);
 
-	/* Register UART driver */
-	s->uart.owner		= THIS_MODULE;
-	s->uart.dev_name	= "ttySC";
-	s->uart.nr		= devtype->nr_uart;
-	ret = uart_register_driver(&s->uart);
-	if (ret) {
-		dev_err(dev, "Registering UART driver failed\n");
-		goto out_clk;
-	}
-
 	init_kthread_worker(&s->kworker);
 	init_kthread_work(&s->irq_work, sc16is7xx_ist);
 	s->kworker_task = kthread_run(kthread_worker_fn, &s->kworker,
 				      "sc16is7xx");
 	if (IS_ERR(s->kworker_task)) {
 		ret = PTR_ERR(s->kworker_task);
-		goto out_uart;
+		goto out_clk;
 	}
 	sched_setscheduler(s->kworker_task, SCHED_FIFO, &sched_param);
 
@@ -1195,7 +1193,7 @@ static int sc16is7xx_probe(struct device *dev,
 		init_kthread_work(&s->p[i].tx_work, sc16is7xx_tx_proc);
 		init_kthread_work(&s->p[i].reg_work, sc16is7xx_reg_proc);
 		/* Register port */
-		uart_add_one_port(&s->uart, &s->p[i].port);
+		uart_add_one_port(&sc16is7xx_uart, &s->p[i].port);
 		/* Go to suspend mode */
 		sc16is7xx_power(&s->p[i].port, 0);
 	}
@@ -1206,8 +1204,8 @@ static int sc16is7xx_probe(struct device *dev,
 	if (!ret)
 		return 0;
 
-	for (i = 0; i < s->uart.nr; i++)
-		uart_remove_one_port(&s->uart, &s->p[i].port);
+	for (i = 0; i < s->devtype->nr_uart; i++)
+		uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port);
 
 #ifdef CONFIG_GPIOLIB
 	if (devtype->nr_gpio)
@@ -1217,9 +1215,6 @@ out_thread:
 #endif
 	kthread_stop(s->kworker_task);
 
-out_uart:
-	uart_unregister_driver(&s->uart);
-
 out_clk:
 	if (!IS_ERR(s->clk))
 		clk_disable_unprepare(s->clk);
@@ -1237,15 +1232,14 @@ static int sc16is7xx_remove(struct device *dev)
 		gpiochip_remove(&s->gpio);
 #endif
 
-	for (i = 0; i < s->uart.nr; i++) {
-		uart_remove_one_port(&s->uart, &s->p[i].port);
+	for (i = 0; i < s->devtype->nr_uart; i++) {
+		uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port);
 		sc16is7xx_power(&s->p[i].port, 0);
 	}
 
 	flush_kthread_worker(&s->kworker);
 	kthread_stop(s->kworker_task);
 
-	uart_unregister_driver(&s->uart);
 	if (!IS_ERR(s->clk))
 		clk_disable_unprepare(s->clk);
 
@@ -1398,7 +1392,14 @@ MODULE_ALIAS("i2c:sc16is7xx");
 
 static int __init sc16is7xx_init(void)
 {
-	int ret = 0;
+	int ret;
+
+	ret = uart_register_driver(&sc16is7xx_uart);
+	if (ret) {
+		pr_err("Registering UART driver failed\n");
+		return ret;
+	}
+
 #ifdef CONFIG_SERIAL_SC16IS7XX_I2C
 	ret = i2c_add_driver(&sc16is7xx_i2c_uart_driver);
 	if (ret < 0) {
@@ -1427,6 +1428,7 @@ static void __exit sc16is7xx_exit(void)
 #ifdef CONFIG_SERIAL_SC16IS7XX_SPI
 	spi_unregister_driver(&sc16is7xx_spi_uart_driver);
 #endif
+	uart_unregister_driver(&sc16is7xx_uart);
 }
 module_exit(sc16is7xx_exit);
 
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux