2020-04-03 09:25:25

by Michal Simek

[permalink] [raw]
Subject: [PATCH 0/7] serial: uartps: Revert dynamic port allocation

Hi,

there were several changes done in past in uartps drivers which have been
also done in uartlite driver.
Here is the thread about it
https://lore.kernel.org/linux-serial/20191203152738.GF10631@localhost/

This series reverts all patches which enabled dynamic port allocation and
returning driver to the previous state. There were added some features in
meantime which are not affected by this series.

Thanks,
Michal


Michal Simek (7):
Revert "serial: uartps: Fix uartps_major handling"
Revert "serial: uartps: Use the same dynamic major number for all
ports"
Revert "serial: uartps: Fix error path when alloc failed"
Revert "serial: uartps: Do not allow use aliases >=
MAX_UART_INSTANCES"
Revert "serial: uartps: Change uart ID port allocation"
Revert "serial: uartps: Move Port ID to device data structure"
Revert "serial: uartps: Register own uart console and driver
structures"

drivers/tty/serial/xilinx_uartps.c | 211 +++++++----------------------
1 file changed, 49 insertions(+), 162 deletions(-)

--
2.26.0


2020-04-03 09:25:35

by Michal Simek

[permalink] [raw]
Subject: [PATCH 4/7] Revert "serial: uartps: Do not allow use aliases >= MAX_UART_INSTANCES"

This reverts commit 2088cfd882d0403609bdf426e9b24372fe1b8337.

As Johan says, this driver needs a lot more work and these changes are
only going in the wrong direction:
https://lkml.kernel.org/r/20190523091839.GC568@localhost

Reported-by: Johan Hovold <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
---

drivers/tty/serial/xilinx_uartps.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 412bfc51f546..9db3cd120057 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1712,8 +1712,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
err_out_id:
mutex_lock(&bitmap_lock);
- if (cdns_uart_data->id < MAX_UART_INSTANCES)
- clear_bit(cdns_uart_data->id, bitmap);
+ clear_bit(cdns_uart_data->id, bitmap);
mutex_unlock(&bitmap_lock);
return rc;
}
@@ -1738,8 +1737,7 @@ static int cdns_uart_remove(struct platform_device *pdev)
rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
port->mapbase = 0;
mutex_lock(&bitmap_lock);
- if (cdns_uart_data->id < MAX_UART_INSTANCES)
- clear_bit(cdns_uart_data->id, bitmap);
+ clear_bit(cdns_uart_data->id, bitmap);
mutex_unlock(&bitmap_lock);
clk_disable_unprepare(cdns_uart_data->uartclk);
clk_disable_unprepare(cdns_uart_data->pclk);
--
2.26.0

2020-04-03 09:25:45

by Michal Simek

[permalink] [raw]
Subject: [PATCH 6/7] Revert "serial: uartps: Move Port ID to device data structure"

This reverts commit bed25ac0e2b6ab8f9aed2d20bc9c3a2037311800.

As Johan says, this driver needs a lot more work and these changes are
only going in the wrong direction:
https://lkml.kernel.org/r/20190523091839.GC568@localhost

Reported-by: Johan Hovold <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
---

drivers/tty/serial/xilinx_uartps.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 58f0fa07ecdb..41d9c2f188f0 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -189,7 +189,6 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255");
* @pclk: APB clock
* @cdns_uart_driver: Pointer to UART driver
* @baud: Current baud rate
- * @id: Port ID
* @clk_rate_change_nb: Notifier block for clock changes
* @quirks: Flags for RXBS support.
*/
@@ -199,7 +198,6 @@ struct cdns_uart {
struct clk *pclk;
struct uart_driver *cdns_uart_driver;
unsigned int baud;
- int id;
struct notifier_block clk_rate_change_nb;
u32 quirks;
bool cts_override;
@@ -1412,7 +1410,7 @@ MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
*/
static int cdns_uart_probe(struct platform_device *pdev)
{
- int rc, irq;
+ int rc, id, irq;
struct uart_port *port;
struct resource *res;
struct cdns_uart *cdns_uart_data;
@@ -1438,18 +1436,18 @@ static int cdns_uart_probe(struct platform_device *pdev)
return -ENOMEM;

/* Look for a serialN alias */
- cdns_uart_data->id = of_alias_get_id(pdev->dev.of_node, "serial");
- if (cdns_uart_data->id < 0)
- cdns_uart_data->id = 0;
+ id = of_alias_get_id(pdev->dev.of_node, "serial");
+ if (id < 0)
+ id = 0;

- if (cdns_uart_data->id >= CDNS_UART_NR_PORTS) {
+ if (id >= CDNS_UART_NR_PORTS) {
dev_err(&pdev->dev, "Cannot get uart_port structure\n");
return -ENODEV;
}

/* There is a need to use unique driver name */
driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d",
- CDNS_UART_NAME, cdns_uart_data->id);
+ CDNS_UART_NAME, id);
if (!driver_name)
return -ENOMEM;

@@ -1457,7 +1455,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
cdns_uart_uart_driver->driver_name = driver_name;
cdns_uart_uart_driver->dev_name = CDNS_UART_TTY_NAME;
cdns_uart_uart_driver->major = CDNS_UART_MAJOR;
- cdns_uart_uart_driver->minor = cdns_uart_data->id;
+ cdns_uart_uart_driver->minor = id;
cdns_uart_uart_driver->nr = 1;

#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
@@ -1468,7 +1466,7 @@ static int cdns_uart_probe(struct platform_device *pdev)

strncpy(cdns_uart_console->name, CDNS_UART_TTY_NAME,
sizeof(cdns_uart_console->name));
- cdns_uart_console->index = cdns_uart_data->id;
+ cdns_uart_console->index = id;
cdns_uart_console->write = cdns_uart_console_write;
cdns_uart_console->device = uart_console_device;
cdns_uart_console->setup = cdns_uart_console_setup;
@@ -1490,7 +1488,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
* registration because tty_driver structure is not filled.
* name_base is 0 by default.
*/
- cdns_uart_uart_driver->tty_driver->name_base = cdns_uart_data->id;
+ cdns_uart_uart_driver->tty_driver->name_base = id;

match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
if (match && match->data) {
--
2.26.0

2020-04-03 09:25:51

by Michal Simek

[permalink] [raw]
Subject: [PATCH 5/7] Revert "serial: uartps: Change uart ID port allocation"

This reverts commit ae1cca3fa3478be92948dbbcd722390272032ade.

With setting up NR_PORTS to 16 to be able to use serial2 and higher
aliases and don't loose functionality which was intended by these changes.

As Johan says, this driver needs a lot more work and these changes are
only going in the wrong direction:
https://lkml.kernel.org/r/20190523091839.GC568@localhost

Reported-by: Johan Hovold <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
---

drivers/tty/serial/xilinx_uartps.c | 111 ++++-------------------------
1 file changed, 13 insertions(+), 98 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 9db3cd120057..58f0fa07ecdb 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -27,6 +27,7 @@
#define CDNS_UART_TTY_NAME "ttyPS"
#define CDNS_UART_NAME "xuartps"
#define CDNS_UART_MAJOR 0 /* use dynamic node allocation */
+#define CDNS_UART_NR_PORTS 16
#define CDNS_UART_FIFO_SIZE 64 /* FIFO size */
#define CDNS_UART_REGISTER_SPACE 0x1000
#define TX_TIMEOUT 500000
@@ -1403,90 +1404,6 @@ static const struct of_device_id cdns_uart_of_match[] = {
};
MODULE_DEVICE_TABLE(of, cdns_uart_of_match);

-/*
- * Maximum number of instances without alias IDs but if there is alias
- * which target "< MAX_UART_INSTANCES" range this ID can't be used.
- */
-#define MAX_UART_INSTANCES 32
-
-/* Stores static aliases list */
-static DECLARE_BITMAP(alias_bitmap, MAX_UART_INSTANCES);
-static int alias_bitmap_initialized;
-
-/* Stores actual bitmap of allocated IDs with alias IDs together */
-static DECLARE_BITMAP(bitmap, MAX_UART_INSTANCES);
-/* Protect bitmap operations to have unique IDs */
-static DEFINE_MUTEX(bitmap_lock);
-
-static int cdns_get_id(struct platform_device *pdev)
-{
- int id, ret;
-
- mutex_lock(&bitmap_lock);
-
- /* Alias list is stable that's why get alias bitmap only once */
- if (!alias_bitmap_initialized) {
- ret = of_alias_get_alias_list(cdns_uart_of_match, "serial",
- alias_bitmap, MAX_UART_INSTANCES);
- if (ret && ret != -EOVERFLOW) {
- mutex_unlock(&bitmap_lock);
- return ret;
- }
-
- alias_bitmap_initialized++;
- }
-
- /* Make sure that alias ID is not taken by instance without alias */
- bitmap_or(bitmap, bitmap, alias_bitmap, MAX_UART_INSTANCES);
-
- dev_dbg(&pdev->dev, "Alias bitmap: %*pb\n",
- MAX_UART_INSTANCES, bitmap);
-
- /* Look for a serialN alias */
- id = of_alias_get_id(pdev->dev.of_node, "serial");
- if (id < 0) {
- dev_warn(&pdev->dev,
- "No serial alias passed. Using the first free id\n");
-
- /*
- * Start with id 0 and check if there is no serial0 alias
- * which points to device which is compatible with this driver.
- * If alias exists then try next free position.
- */
- id = 0;
-
- for (;;) {
- dev_info(&pdev->dev, "Checking id %d\n", id);
- id = find_next_zero_bit(bitmap, MAX_UART_INSTANCES, id);
-
- /* No free empty instance */
- if (id == MAX_UART_INSTANCES) {
- dev_err(&pdev->dev, "No free ID\n");
- mutex_unlock(&bitmap_lock);
- return -EINVAL;
- }
-
- dev_dbg(&pdev->dev, "The empty id is %d\n", id);
- /* Check if ID is empty */
- if (!test_and_set_bit(id, bitmap)) {
- /* Break the loop if bit is taken */
- dev_dbg(&pdev->dev,
- "Selected ID %d allocation passed\n",
- id);
- break;
- }
- dev_dbg(&pdev->dev,
- "Selected ID %d allocation failed\n", id);
- /* if taking bit fails then try next one */
- id++;
- }
- }
-
- mutex_unlock(&bitmap_lock);
-
- return id;
-}
-
/**
* cdns_uart_probe - Platform driver probe
* @pdev: Pointer to the platform device structure
@@ -1520,17 +1437,21 @@ static int cdns_uart_probe(struct platform_device *pdev)
if (!cdns_uart_uart_driver)
return -ENOMEM;

- cdns_uart_data->id = cdns_get_id(pdev);
+ /* Look for a serialN alias */
+ cdns_uart_data->id = of_alias_get_id(pdev->dev.of_node, "serial");
if (cdns_uart_data->id < 0)
- return cdns_uart_data->id;
+ cdns_uart_data->id = 0;
+
+ if (cdns_uart_data->id >= CDNS_UART_NR_PORTS) {
+ dev_err(&pdev->dev, "Cannot get uart_port structure\n");
+ return -ENODEV;
+ }

/* There is a need to use unique driver name */
driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d",
CDNS_UART_NAME, cdns_uart_data->id);
- if (!driver_name) {
- rc = -ENOMEM;
- goto err_out_id;
- }
+ if (!driver_name)
+ return -ENOMEM;

cdns_uart_uart_driver->owner = THIS_MODULE;
cdns_uart_uart_driver->driver_name = driver_name;
@@ -1559,7 +1480,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
rc = uart_register_driver(cdns_uart_uart_driver);
if (rc < 0) {
dev_err(&pdev->dev, "Failed to register driver\n");
- goto err_out_id;
+ return rc;
}

cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;
@@ -1710,10 +1631,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
clk_disable_unprepare(cdns_uart_data->pclk);
err_out_unregister_driver:
uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
-err_out_id:
- mutex_lock(&bitmap_lock);
- clear_bit(cdns_uart_data->id, bitmap);
- mutex_unlock(&bitmap_lock);
+
return rc;
}

@@ -1736,9 +1654,6 @@ static int cdns_uart_remove(struct platform_device *pdev)
#endif
rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
port->mapbase = 0;
- mutex_lock(&bitmap_lock);
- clear_bit(cdns_uart_data->id, bitmap);
- mutex_unlock(&bitmap_lock);
clk_disable_unprepare(cdns_uart_data->uartclk);
clk_disable_unprepare(cdns_uart_data->pclk);
pm_runtime_disable(&pdev->dev);
--
2.26.0

2020-04-03 09:26:32

by Michal Simek

[permalink] [raw]
Subject: [PATCH 7/7] Revert "serial: uartps: Register own uart console and driver structures"

This reverts commit 024ca329bfb9a948f76eaff3243e21b7e70182f2.

As Johan says, this driver needs a lot more work and these changes are
only going in the wrong direction:
https://lkml.kernel.org/r/20190523091839.GC568@localhost

Reported-by: Johan Hovold <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
---

drivers/tty/serial/xilinx_uartps.c | 95 +++++++++++++-----------------
1 file changed, 40 insertions(+), 55 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 41d9c2f188f0..ac137b6a1dc1 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -27,6 +27,7 @@
#define CDNS_UART_TTY_NAME "ttyPS"
#define CDNS_UART_NAME "xuartps"
#define CDNS_UART_MAJOR 0 /* use dynamic node allocation */
+#define CDNS_UART_MINOR 0 /* works best with devtmpfs */
#define CDNS_UART_NR_PORTS 16
#define CDNS_UART_FIFO_SIZE 64 /* FIFO size */
#define CDNS_UART_REGISTER_SPACE 0x1000
@@ -1132,6 +1133,8 @@ static const struct uart_ops cdns_uart_ops = {
#endif
};

+static struct uart_driver cdns_uart_uart_driver;
+
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
/**
* cdns_uart_console_putchar - write the character to the FIFO buffer
@@ -1271,6 +1274,16 @@ static int cdns_uart_console_setup(struct console *co, char *options)

return uart_set_options(port, co, baud, parity, bits, flow);
}
+
+static struct console cdns_uart_console = {
+ .name = CDNS_UART_TTY_NAME,
+ .write = cdns_uart_console_write,
+ .device = uart_console_device,
+ .setup = cdns_uart_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1, /* Specified on the cmdline (e.g. console=ttyPS ) */
+ .data = &cdns_uart_uart_driver,
+};
#endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */

#ifdef CONFIG_PM_SLEEP
@@ -1402,6 +1415,9 @@ static const struct of_device_id cdns_uart_of_match[] = {
};
MODULE_DEVICE_TABLE(of, cdns_uart_of_match);

+/* Temporary variable for storing number of instances */
+static int instances;
+
/**
* cdns_uart_probe - Platform driver probe
* @pdev: Pointer to the platform device structure
@@ -1415,11 +1431,6 @@ static int cdns_uart_probe(struct platform_device *pdev)
struct resource *res;
struct cdns_uart *cdns_uart_data;
const struct of_device_id *match;
- struct uart_driver *cdns_uart_uart_driver;
- char *driver_name;
-#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
- struct console *cdns_uart_console;
-#endif

cdns_uart_data = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_data),
GFP_KERNEL);
@@ -1429,12 +1440,6 @@ static int cdns_uart_probe(struct platform_device *pdev)
if (!port)
return -ENOMEM;

- cdns_uart_uart_driver = devm_kzalloc(&pdev->dev,
- sizeof(*cdns_uart_uart_driver),
- GFP_KERNEL);
- if (!cdns_uart_uart_driver)
- return -ENOMEM;
-
/* Look for a serialN alias */
id = of_alias_get_id(pdev->dev.of_node, "serial");
if (id < 0)
@@ -1445,50 +1450,25 @@ static int cdns_uart_probe(struct platform_device *pdev)
return -ENODEV;
}

- /* There is a need to use unique driver name */
- driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d",
- CDNS_UART_NAME, id);
- if (!driver_name)
- return -ENOMEM;
-
- cdns_uart_uart_driver->owner = THIS_MODULE;
- cdns_uart_uart_driver->driver_name = driver_name;
- cdns_uart_uart_driver->dev_name = CDNS_UART_TTY_NAME;
- cdns_uart_uart_driver->major = CDNS_UART_MAJOR;
- cdns_uart_uart_driver->minor = id;
- cdns_uart_uart_driver->nr = 1;
-
+ if (!cdns_uart_uart_driver.state) {
+ cdns_uart_uart_driver.owner = THIS_MODULE;
+ cdns_uart_uart_driver.driver_name = CDNS_UART_NAME;
+ cdns_uart_uart_driver.dev_name = CDNS_UART_TTY_NAME;
+ cdns_uart_uart_driver.major = CDNS_UART_MAJOR;
+ cdns_uart_uart_driver.minor = CDNS_UART_MINOR;
+ cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS;
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
- cdns_uart_console = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_console),
- GFP_KERNEL);
- if (!cdns_uart_console)
- return -ENOMEM;
-
- strncpy(cdns_uart_console->name, CDNS_UART_TTY_NAME,
- sizeof(cdns_uart_console->name));
- cdns_uart_console->index = id;
- cdns_uart_console->write = cdns_uart_console_write;
- cdns_uart_console->device = uart_console_device;
- cdns_uart_console->setup = cdns_uart_console_setup;
- cdns_uart_console->flags = CON_PRINTBUFFER;
- cdns_uart_console->data = cdns_uart_uart_driver;
- cdns_uart_uart_driver->cons = cdns_uart_console;
+ cdns_uart_uart_driver.cons = &cdns_uart_console;
#endif

- rc = uart_register_driver(cdns_uart_uart_driver);
- if (rc < 0) {
- dev_err(&pdev->dev, "Failed to register driver\n");
- return rc;
+ rc = uart_register_driver(&cdns_uart_uart_driver);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Failed to register driver\n");
+ return rc;
+ }
}

- cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;
-
- /*
- * Setting up proper name_base needs to be done after uart
- * registration because tty_driver structure is not filled.
- * name_base is 0 by default.
- */
- cdns_uart_uart_driver->tty_driver->name_base = id;
+ cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver;

match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
if (match && match->data) {
@@ -1566,6 +1546,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
port->ops = &cdns_uart_ops;
port->fifosize = CDNS_UART_FIFO_SIZE;
port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_XILINX_PS_UART_CONSOLE);
+ port->line = id;

/*
* Register the port.
@@ -1597,7 +1578,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
console_port = port;
#endif

- rc = uart_add_one_port(cdns_uart_uart_driver, port);
+ rc = uart_add_one_port(&cdns_uart_uart_driver, port);
if (rc) {
dev_err(&pdev->dev,
"uart_add_one_port() failed; err=%i\n", rc);
@@ -1607,12 +1588,15 @@ static int cdns_uart_probe(struct platform_device *pdev)
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
/* This is not port which is used for console that's why clean it up */
if (console_port == port &&
- !(cdns_uart_uart_driver->cons->flags & CON_ENABLED))
+ !(cdns_uart_uart_driver.cons->flags & CON_ENABLED))
console_port = NULL;
#endif

cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node,
"cts-override");
+
+ instances++;
+
return 0;

err_out_pm_disable:
@@ -1628,8 +1612,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
err_out_clk_dis_pclk:
clk_disable_unprepare(cdns_uart_data->pclk);
err_out_unregister_driver:
- uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
-
+ if (!instances)
+ uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
return rc;
}

@@ -1664,7 +1648,8 @@ static int cdns_uart_remove(struct platform_device *pdev)
console_port = NULL;
#endif

- uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
+ if (!--instances)
+ uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
return rc;
}

--
2.26.0

2020-04-03 09:26:48

by Michal Simek

[permalink] [raw]
Subject: [PATCH 3/7] Revert "serial: uartps: Fix error path when alloc failed"

This reverts commit 32cf21ac4edd6c0d5b9614368a83bcdc68acb031.

As Johan says, this driver needs a lot more work and these changes are
only going in the wrong direction:
https://lkml.kernel.org/r/20190523091839.GC568@localhost

Reported-by: Johan Hovold <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
---

drivers/tty/serial/xilinx_uartps.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 4e3fefa70b56..412bfc51f546 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1542,10 +1542,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
cdns_uart_console = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_console),
GFP_KERNEL);
- if (!cdns_uart_console) {
- rc = -ENOMEM;
- goto err_out_id;
- }
+ if (!cdns_uart_console)
+ return -ENOMEM;

strncpy(cdns_uart_console->name, CDNS_UART_TTY_NAME,
sizeof(cdns_uart_console->name));
--
2.26.0

2020-04-03 09:27:00

by Michal Simek

[permalink] [raw]
Subject: [PATCH 1/7] Revert "serial: uartps: Fix uartps_major handling"

This reverts commit 5e9bd2d70ae7c00a95a22994abf1eef728649e64.

As Johan says, this driver needs a lot more work and these changes are
only going in the wrong direction:
https://lkml.kernel.org/r/20190523091839.GC568@localhost

Reported-by: Johan Hovold <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
---

drivers/tty/serial/xilinx_uartps.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 6b26f767768e..b858fb14833d 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1564,6 +1564,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
goto err_out_id;
}

+ uartps_major = cdns_uart_uart_driver->tty_driver->major;
cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;

/*
@@ -1694,7 +1695,6 @@ static int cdns_uart_probe(struct platform_device *pdev)
console_port = NULL;
#endif

- uartps_major = cdns_uart_uart_driver->tty_driver->major;
cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node,
"cts-override");
return 0;
@@ -1756,12 +1756,6 @@ static int cdns_uart_remove(struct platform_device *pdev)
console_port = NULL;
#endif

- /* If this is last instance major number should be initialized */
- mutex_lock(&bitmap_lock);
- if (bitmap_empty(bitmap, MAX_UART_INSTANCES))
- uartps_major = 0;
- mutex_unlock(&bitmap_lock);
-
uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
return rc;
}
--
2.26.0

2020-04-03 09:33:14

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 0/7] serial: uartps: Revert dynamic port allocation

On Fri, Apr 03, 2020 at 11:24:29AM +0200, Michal Simek wrote:
> Hi,
>
> there were several changes done in past in uartps drivers which have been
> also done in uartlite driver.
> Here is the thread about it
> https://lore.kernel.org/linux-serial/20191203152738.GF10631@localhost/
>
> This series reverts all patches which enabled dynamic port allocation and
> returning driver to the previous state. There were added some features in
> meantime which are not affected by this series.

Should this go into 5.7-final as it's causing problems now, and
backported as well? Or can it wait until 5.8-rc1?

thanks,

greg k-h

2020-04-03 09:46:11

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 0/7] serial: uartps: Revert dynamic port allocation

On Fri, Apr 03, 2020 at 11:37:46AM +0200, Michal Simek wrote:
> On 03. 04. 20 11:32, Greg KH wrote:
> > On Fri, Apr 03, 2020 at 11:24:29AM +0200, Michal Simek wrote:
> >> Hi,
> >>
> >> there were several changes done in past in uartps drivers which have been
> >> also done in uartlite driver.
> >> Here is the thread about it
> >> https://lore.kernel.org/linux-serial/20191203152738.GF10631@localhost/
> >>
> >> This series reverts all patches which enabled dynamic port allocation and
> >> returning driver to the previous state. There were added some features in
> >> meantime which are not affected by this series.
> >
> > Should this go into 5.7-final as it's causing problems now, and
> > backported as well? Or can it wait until 5.8-rc1?
>
> These patches have been added to v4.20. It means all version from that
> are affected.
>
> The issue I am aware of is when you setup stdout-path =
> "serialX:115200n8" where X is not 0.
>
> But as was discussed the concept is based on Johan wrong that's why it
> can be consider as bug fix.

Ok, I'll queue these up after 5.7-rc1 is out, for inclusion in
5.7-final, and cc: for stable, as I agree, they should all be reverted.
Thanks for doing the work.

greg k-h

2020-04-03 09:52:26

by Michal Simek

[permalink] [raw]
Subject: Re: [PATCH 0/7] serial: uartps: Revert dynamic port allocation

On 03. 04. 20 11:44, Greg KH wrote:
> On Fri, Apr 03, 2020 at 11:37:46AM +0200, Michal Simek wrote:
>> On 03. 04. 20 11:32, Greg KH wrote:
>>> On Fri, Apr 03, 2020 at 11:24:29AM +0200, Michal Simek wrote:
>>>> Hi,
>>>>
>>>> there were several changes done in past in uartps drivers which have been
>>>> also done in uartlite driver.
>>>> Here is the thread about it
>>>> https://lore.kernel.org/linux-serial/20191203152738.GF10631@localhost/
>>>>
>>>> This series reverts all patches which enabled dynamic port allocation and
>>>> returning driver to the previous state. There were added some features in
>>>> meantime which are not affected by this series.
>>>
>>> Should this go into 5.7-final as it's causing problems now, and
>>> backported as well? Or can it wait until 5.8-rc1?
>>
>> These patches have been added to v4.20. It means all version from that
>> are affected.
>>
>> The issue I am aware of is when you setup stdout-path =
>> "serialX:115200n8" where X is not 0.
>>
>> But as was discussed the concept is based on Johan wrong that's why it
>> can be consider as bug fix.
>
> Ok, I'll queue these up after 5.7-rc1 is out, for inclusion in
> 5.7-final, and cc: for stable, as I agree, they should all be reverted.
> Thanks for doing the work.

Thanks. I am definitely interested to hear more how this could be done
differently because that hardcoded limits are painful.
On FPGAs you can have a lot of uarts for whatever reason and users are
using DT aliases to have consistent naming.
Specifically on Xilinx devices we are using uartps which is ttyPS,
uartlite which is ttyUL, ns16500 which is ttyS and also pl011 which is
ttyAMA.
Only ttyAMA or ttyPS on one chip are possible.

And right now you can't have serial0 alias pointed ttyPS0 and another
serial0 pointed to ttyUL0 or ttyS0. That's why others are shifted and we
can reach that hardcoded NR_UART limit easily.
And this was the reason why I have done these patches in past to remove
any limit from these drivers and if user asks for serial100 alias you
simply get ttyPS100 node.

Johan mentioned any solution use in USB stack but I haven't really had a
time to take a look at it how feasible it is to bring back to all drivers.

Thanks,
Michal


2020-04-03 09:55:21

by Michal Simek

[permalink] [raw]
Subject: [PATCH 2/7] Revert "serial: uartps: Use the same dynamic major number for all ports"

This reverts commit ab262666018de6f4e206b021386b93ed0c164316.

As Johan says, this driver needs a lot more work and these changes are
only going in the wrong direction:
https://lkml.kernel.org/r/20190523091839.GC568@localhost

Reported-by: Johan Hovold <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
---

drivers/tty/serial/xilinx_uartps.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index b858fb14833d..4e3fefa70b56 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -26,13 +26,13 @@

#define CDNS_UART_TTY_NAME "ttyPS"
#define CDNS_UART_NAME "xuartps"
+#define CDNS_UART_MAJOR 0 /* use dynamic node allocation */
#define CDNS_UART_FIFO_SIZE 64 /* FIFO size */
#define CDNS_UART_REGISTER_SPACE 0x1000
#define TX_TIMEOUT 500000

/* Rx Trigger level */
static int rx_trigger_level = 56;
-static int uartps_major;
module_param(rx_trigger_level, uint, 0444);
MODULE_PARM_DESC(rx_trigger_level, "Rx trigger level, 1-63 bytes");

@@ -1535,7 +1535,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
cdns_uart_uart_driver->owner = THIS_MODULE;
cdns_uart_uart_driver->driver_name = driver_name;
cdns_uart_uart_driver->dev_name = CDNS_UART_TTY_NAME;
- cdns_uart_uart_driver->major = uartps_major;
+ cdns_uart_uart_driver->major = CDNS_UART_MAJOR;
cdns_uart_uart_driver->minor = cdns_uart_data->id;
cdns_uart_uart_driver->nr = 1;

@@ -1564,7 +1564,6 @@ static int cdns_uart_probe(struct platform_device *pdev)
goto err_out_id;
}

- uartps_major = cdns_uart_uart_driver->tty_driver->major;
cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;

/*
--
2.26.0

2020-04-03 10:01:41

by Michal Simek

[permalink] [raw]
Subject: Re: [PATCH 0/7] serial: uartps: Revert dynamic port allocation

On 03. 04. 20 11:32, Greg KH wrote:
> On Fri, Apr 03, 2020 at 11:24:29AM +0200, Michal Simek wrote:
>> Hi,
>>
>> there were several changes done in past in uartps drivers which have been
>> also done in uartlite driver.
>> Here is the thread about it
>> https://lore.kernel.org/linux-serial/20191203152738.GF10631@localhost/
>>
>> This series reverts all patches which enabled dynamic port allocation and
>> returning driver to the previous state. There were added some features in
>> meantime which are not affected by this series.
>
> Should this go into 5.7-final as it's causing problems now, and
> backported as well? Or can it wait until 5.8-rc1?

These patches have been added to v4.20. It means all version from that
are affected.

The issue I am aware of is when you setup stdout-path =
"serialX:115200n8" where X is not 0.

But as was discussed the concept is based on Johan wrong that's why it
can be consider as bug fix.

Thanks,
Michal

2020-04-03 15:58:56

by Michal Simek

[permalink] [raw]
Subject: Re: [PATCH 0/7] serial: uartps: Revert dynamic port allocation

On 03. 04. 20 17:48, Maarten Brock wrote:
> On 2020-04-03 11:51, Michal Simek wrote:
>>
>> Thanks. I am definitely interested to hear more how this could be done
>> differently because that hardcoded limits are painful.
>> On FPGAs you can have a lot of uarts for whatever reason and users are
>> using DT aliases to have consistent naming.
>> Specifically on Xilinx devices we are using uartps which is ttyPS,
>> uartlite which is ttyUL, ns16500 which is ttyS and also pl011 which is
>> ttyAMA.
>> Only ttyAMA or ttyPS on one chip are possible.
>>
>> And right now you can't have serial0 alias pointed ttyPS0 and another
>> serial0 pointed to ttyUL0 or ttyS0. That's why others are shifted and we
>> can reach that hardcoded NR_UART limit easily.
>> And this was the reason why I have done these patches in past to remove
>> any limit from these drivers and if user asks for serial100 alias you
>> simply get ttyPS100 node.
>
> I would argue that the trouble originates from every uart driver using
> its own naming scheme and thereby creating separate namespaces. If all
> uarts would register as /dev/ttySnn then the serialN alias method would
> work. These non-overlapping namespaces is something the linux kernel
> driver community has allowed to happen.
>
> If the namespaces are not abandoned and disallowed, then the serialN
> alias method must no longer be used for any driver that does not create
> /dev/ttySnn devices. Every namespace will require its own alias base.
> Or forget about deriving the number from an alias and set the number in
> a property in the device tree node itself. The latter has my preference.

Uartlite and as I see ucc_uart are only two driver which are using
port-number property for this purpose.
And IIRC this property was the part of any spec long time ago.

Thanks,
Michal

2020-04-03 16:21:10

by Maarten Brock

[permalink] [raw]
Subject: Re: [PATCH 0/7] serial: uartps: Revert dynamic port allocation

On 2020-04-03 11:51, Michal Simek wrote:
>
> Thanks. I am definitely interested to hear more how this could be done
> differently because that hardcoded limits are painful.
> On FPGAs you can have a lot of uarts for whatever reason and users are
> using DT aliases to have consistent naming.
> Specifically on Xilinx devices we are using uartps which is ttyPS,
> uartlite which is ttyUL, ns16500 which is ttyS and also pl011 which is
> ttyAMA.
> Only ttyAMA or ttyPS on one chip are possible.
>
> And right now you can't have serial0 alias pointed ttyPS0 and another
> serial0 pointed to ttyUL0 or ttyS0. That's why others are shifted and
> we
> can reach that hardcoded NR_UART limit easily.
> And this was the reason why I have done these patches in past to remove
> any limit from these drivers and if user asks for serial100 alias you
> simply get ttyPS100 node.

I would argue that the trouble originates from every uart driver using
its own naming scheme and thereby creating separate namespaces. If all
uarts would register as /dev/ttySnn then the serialN alias method would
work. These non-overlapping namespaces is something the linux kernel
driver community has allowed to happen.

If the namespaces are not abandoned and disallowed, then the serialN
alias method must no longer be used for any driver that does not create
/dev/ttySnn devices. Every namespace will require its own alias base.
Or forget about deriving the number from an alias and set the number in
a property in the device tree node itself. The latter has my preference.

Maarten