Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: max310x: Check the clock readiness

This chip has a diagnostics status bit informing about the state and
stability of the clock subsystem. According to the datasheet (STSint
register, bit 5, ClockReady), this bit works with the crystal
oscillator, but even without the PLL. Therefore:

- ensure that the clock check is done even when PLL is not active
- warn when the chip thinks that the clock is not ready yet

There are HW features which would let us wait asynchronously (there's a
maskable IRQ for that bit), but I think that even this simple check is a
net improvement. It would have saved me two days of debugging :).

Signed-off-by: Jan Kundrát <jan.kundrat@cesnet.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Jan Kundrát and committed by
Greg Kroah-Hartman
4cf9a888 c884f871

+10 -4
+10 -4
drivers/tty/serial/max310x.c
··· 531 531 return 1; 532 532 } 533 533 534 - static int max310x_set_ref_clk(struct max310x_port *s, unsigned long freq, 535 - bool xtal) 534 + static int max310x_set_ref_clk(struct device *dev, struct max310x_port *s, 535 + unsigned long freq, bool xtal) 536 536 { 537 537 unsigned int div, clksrc, pllcfg = 0; 538 538 long besterr = -1; ··· 588 588 regmap_write(s->regmap, MAX310X_CLKSRC_REG, clksrc); 589 589 590 590 /* Wait for crystal */ 591 - if (pllcfg && xtal) 591 + if (xtal) { 592 + unsigned int val; 592 593 msleep(10); 594 + regmap_read(s->regmap, MAX310X_STS_IRQSTS_REG, &val); 595 + if (!(val & MAX310X_STS_CLKREADY_BIT)) { 596 + dev_warn(dev, "clock is not stable yet\n"); 597 + } 598 + } 593 599 594 600 return (int)bestfreq; 595 601 } ··· 1266 1260 MAX310X_MODE1_AUTOSLEEP_BIT); 1267 1261 } 1268 1262 1269 - uartclk = max310x_set_ref_clk(s, freq, xtal); 1263 + uartclk = max310x_set_ref_clk(dev, s, freq, xtal); 1270 1264 dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk); 1271 1265 1272 1266 mutex_init(&s->mutex);