[PATCH 2/2] tty: max310x: Fail probe when external clock crystal is not stable

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

 



On (some) of my boards, it appears that it takes up to three *checks* of
this register's value for the external crystal to settle so that it is
reported as "ready" by the chip. For example, on one of these boards it
always succeeds upon a third try no matter if the individual waits are
for 1ms or for 10ms. The original timeout of 10ms is therefore not ideal
as it was generating false warnings on working HW for me. Let's solve
this by retrying up to 20 times (i.e., 200ms).

With this retrying in place, it is now also possible to fail device
initialization altogether. A stable clock is really required in order to
use this UART, so log an error message and bail out if the chip keeps
saying "nope".

Tested on several MAX14830 PCBs.

Signed-off-by: Jan Kundrát <jan.kundrat@xxxxxxxxx>
---
 drivers/tty/serial/max310x.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index 0e0c2740ec7e..e8cd09d3e86f 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -610,11 +610,14 @@ static int max310x_set_ref_clk(struct device *dev, struct max310x_port *s,
 
 	/* Wait for crystal */
 	if (xtal) {
-		unsigned int val;
-		msleep(10);
-		regmap_read(s->regmap, MAX310X_STS_IRQSTS_REG, &val);
+		unsigned int val, i;
+		for (i = 0; i < 20 && !(val & MAX310X_STS_CLKREADY_BIT); ++i) {
+			msleep(10);
+			regmap_read(s->regmap, MAX310X_STS_IRQSTS_REG, &val);
+		}
 		if (!(val & MAX310X_STS_CLKREADY_BIT)) {
-			dev_warn(dev, "clock is not stable yet\n");
+			dev_err(dev, "clock is not stable\n");
+			return -EAGAIN;
 		}
 	}
 
@@ -1301,6 +1304,10 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
 	}
 
 	uartclk = max310x_set_ref_clk(dev, s, freq, xtal);
+	if (uartclk < 0) {
+		ret = uartclk;
+		goto out_uart;
+	}
 	dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);
 
 	for (i = 0; i < devtype->nr; i++) {
-- 
2.21.0





[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