[PATCH] serial: Make retrieval of rs485 properties platform-agnostic

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

 



Commit ef838a81dd4d ("serial: Add common rs485 device tree parsing
function") consolidated retrieval of rs485 OF properties in a common
helper function but did not #ifdef it to CONFIG_OF.  The function is
therefore included on ACPI platforms as well even though it's not used.

On the other hand ACPI platforms with rs485 do exist (e.g. Siemens
IOT2040) and they may leverage _DSD to store rs485 properties.  Likewise,
UART platform devices instantiated from an MFD should be able to specify
rs485 properties.  In fact, the tty subsystem maintainer had requested
a "generic" function during review of commit ef838a81dd4d:
https://marc.info/?l=linux-serial&m=150143441725194&w=4

Thus, instead of constraining the helper to OF platforms, make it
platform-agnostic by converting it to device_property_*() functions.

Rename the function accordingly, adjust its signature and make sure that
all existing users have populated the dev pointer in struct uart_port
before calling the helper function as it now dereferences that pointer.

Cc: Jan Kiszka <jan.kiszka@xxxxxxxxxxx>
Cc: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
Cc: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
Signed-off-by: Lukas Wunner <lukas@xxxxxxxxx>
---
@Uwe, could you double-check if rs485 continues to work for you with this
patch applied?

@Everyone, I've changed the function signature to take a struct uart_port
to be consistent with the other functions in serial_core.c.  However this
means that the "dev" pointer in that struct needs to be populated before
uart_get_rs485_mode() can be called.  Otherwise the kernel will oops on
probe, so a driver developer *will* realize there's a problem.  I could
alternatively go back to what Uwe did and pass in a struct device
(instead of a struct device_node) plus a struct serial_rs485.  This would
yield a higher rank on Rusty's API rating scheme.  Let me know what you'd
prefer.  Thanks.

 drivers/tty/serial/atmel_serial.c |  4 ++--
 drivers/tty/serial/fsl_lpuart.c   |  2 +-
 drivers/tty/serial/imx.c          |  4 ++--
 drivers/tty/serial/omap-serial.c  |  2 +-
 drivers/tty/serial/serial_core.c  | 19 +++++++++++--------
 include/linux/serial_core.h       |  2 +-
 6 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 82d9c8e..b7e6349 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -2360,8 +2360,6 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
 	atmel_init_property(atmel_port, pdev);
 	atmel_set_ops(port);
 
-	of_get_rs485_mode(pdev->dev.of_node, &port->rs485);
-
 	port->iotype		= UPIO_MEM;
 	port->flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP;
 	port->ops		= &atmel_pops;
@@ -2393,6 +2391,8 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
 		/* only enable clock when USART is in use */
 	}
 
+	uart_get_rs485_mode(port);
+
 	/* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
 	if (port->rs485.flags & SER_RS485_ENABLED)
 		atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 73d6a7c..ee1ee85 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -2211,7 +2211,7 @@ static int lpuart_probe(struct platform_device *pdev)
 	if (ret)
 		goto failed_attach_port;
 
-	of_get_rs485_mode(np, &sport->port.rs485);
+	uart_get_rs485_mode(&sport->port);
 
 	if (sport->port.rs485.flags & SER_RS485_RX_DURING_TX) {
 		dev_err(&pdev->dev, "driver doesn't support RX during TX\n");
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 76818a2..ca321c5 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2056,8 +2056,6 @@ static int serial_imx_probe_dt(struct imx_port *sport,
 	if (of_get_property(np, "rts-gpios", NULL))
 		sport->have_rtsgpio = 1;
 
-	of_get_rs485_mode(np, &sport->port.rs485);
-
 	return 0;
 }
 #else
@@ -2123,6 +2121,8 @@ static int serial_imx_probe(struct platform_device *pdev)
 	sport->port.flags = UPF_BOOT_AUTOCONF;
 	setup_timer(&sport->timer, imx_timeout, (unsigned long)sport);
 
+	uart_get_rs485_mode(&sport->port);
+
 	sport->gpios = mctrl_gpio_init(&sport->port, 0);
 	if (IS_ERR(sport->gpios))
 		return PTR_ERR(sport->gpios);
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 47ba917..4f69ee8 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1636,7 +1636,7 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up,
 		up->rts_gpio = -EINVAL;
 	}
 
-	of_get_rs485_mode(np, rs485conf);
+	uart_get_rs485_mode(&up->port);
 
 	return 0;
 }
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index f4e6c866..5ebbc4e 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -3027,19 +3027,22 @@ void uart_insert_char(struct uart_port *port, unsigned int status,
 EXPORT_SYMBOL(uart_remove_one_port);
 
 /**
- * of_get_rs485_mode() - Implement parsing rs485 properties
- * @np: uart node
- * @rs485conf: output parameter
+ * uart_get_rs485_mode() - retrieve rs485 properties for given uart port
+ * @port: uart port
  *
  * This function implements the device tree binding described in
  * Documentation/devicetree/bindings/serial/rs485.txt.
+ * Callers must set @port->dev before invoking this function.
  */
-void of_get_rs485_mode(struct device_node *np, struct serial_rs485 *rs485conf)
+void uart_get_rs485_mode(struct uart_port *port)
 {
+	struct serial_rs485 *rs485conf = &port->rs485;
+	struct device *dev = port->dev;
 	u32 rs485_delay[2];
 	int ret;
 
-	ret = of_property_read_u32_array(np, "rs485-rts-delay", rs485_delay, 2);
+	ret = device_property_read_u32_array(dev, "rs485-rts-delay",
+					     rs485_delay, 2);
 	if (!ret) {
 		rs485conf->delay_rts_before_send = rs485_delay[0];
 		rs485conf->delay_rts_after_send = rs485_delay[1];
@@ -3054,13 +3057,13 @@ void of_get_rs485_mode(struct device_node *np, struct serial_rs485 *rs485conf)
 	 */
 	rs485conf->flags &= ~(SER_RS485_RX_DURING_TX | SER_RS485_ENABLED);
 
-	if (of_property_read_bool(np, "rs485-rx-during-tx"))
+	if (device_property_read_bool(dev, "rs485-rx-during-tx"))
 		rs485conf->flags |= SER_RS485_RX_DURING_TX;
 
-	if (of_property_read_bool(np, "linux,rs485-enabled-at-boot-time"))
+	if (device_property_read_bool(dev, "linux,rs485-enabled-at-boot-time"))
 		rs485conf->flags |= SER_RS485_ENABLED;
 }
-EXPORT_SYMBOL_GPL(of_get_rs485_mode);
+EXPORT_SYMBOL_GPL(uart_get_rs485_mode);
 
 MODULE_DESCRIPTION("Serial driver core");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 37b044e..dc2b054 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -504,6 +504,6 @@ static inline int uart_handle_break(struct uart_port *port)
 /*
  * Common device tree parsing helpers
  */
-void of_get_rs485_mode(struct device_node *np, struct serial_rs485 *rs485conf);
+void uart_get_rs485_mode(struct uart_port *port);
 
 #endif /* LINUX_SERIAL_CORE_H */
-- 
2.11.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