diff mbox series

[v3,05/10] serial: 8250: dw: Allow to use a fallback CPR value if not synthesized

Message ID 20220329152430.756947-6-miquel.raynal@bootlin.com (mailing list archive)
State Superseded
Delegated to: Geert Uytterhoeven
Headers show
Series serial: 8250: dw: RZN1 DMA support | expand

Commit Message

Miquel Raynal March 29, 2022, 3:24 p.m. UTC
DW UART controllers can be synthesized without the CPR register.
In this case, allow to the platform information to provide a CPR value.

Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
Co-developed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/tty/serial/8250/8250_dwlib.c | 9 +++++++++
 drivers/tty/serial/8250/8250_dwlib.h | 1 +
 2 files changed, 10 insertions(+)

Comments

Andy Shevchenko March 29, 2022, 3:49 p.m. UTC | #1
On Tue, Mar 29, 2022 at 05:24:25PM +0200, Miquel Raynal wrote:
> DW UART controllers can be synthesized without the CPR register.
> In this case, allow to the platform information to provide a CPR value.

> +	const struct dw8250_platform_data *pdata = device_get_match_data(p->dev);

Hmm... So, we will have two functions that do the same.
Perhaps you may store somewhere the pdata pointer (or contents) once
and call these functions at the time that the pdata is known to be set.
That's how usual pattern looks like. Calling device_get_match_data()
several times is unusual and potentially might be error prone.

...

>  	reg = dw8250_readl_ext(p, DW_UART_CPR);
> +	if (!reg) {

> +		if (pdata)
> +			reg = pdata->cpr;

If you store the content this becomes something like:

		reg = data->pdata.cpr;

But, please experiment a bit with it and choose the best option.

> +		dev_dbg(p->dev, "CPR is not available, using %x instead\n", reg);
> +	}

> +

No need of this blank line.

>  	if (!reg)
>  		return;
diff mbox series

Patch

diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c
index 622d3b0d89e7..6c4fe1792eb5 100644
--- a/drivers/tty/serial/8250/8250_dwlib.c
+++ b/drivers/tty/serial/8250/8250_dwlib.c
@@ -5,6 +5,7 @@ 
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/property.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_core.h>
 
@@ -90,6 +91,7 @@  EXPORT_SYMBOL_GPL(dw8250_do_set_termios);
 void dw8250_setup_port(struct uart_port *p)
 {
 	struct uart_8250_port *up = up_to_u8250p(p);
+	const struct dw8250_platform_data *pdata = device_get_match_data(p->dev);
 	u32 reg;
 
 	/*
@@ -116,6 +118,13 @@  void dw8250_setup_port(struct uart_port *p)
 	}
 
 	reg = dw8250_readl_ext(p, DW_UART_CPR);
+	if (!reg) {
+		if (pdata)
+			reg = pdata->cpr;
+
+		dev_dbg(p->dev, "CPR is not available, using %x instead\n", reg);
+	}
+
 	if (!reg)
 		return;
 
diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h
index 7dfc2d6361e5..19c530b7fd1d 100644
--- a/drivers/tty/serial/8250/8250_dwlib.h
+++ b/drivers/tty/serial/8250/8250_dwlib.h
@@ -23,6 +23,7 @@  struct dw8250_port_data {
 
 struct dw8250_platform_data {
 	unsigned int quirks;
+	u32 cpr;
 };
 
 struct dw8250_data {