aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Elder <elder@linaro.org>2014-07-11 08:06:11 -0500
committerAlex Elder <elder@linaro.org>2014-07-11 08:06:11 -0500
commitc2ecb91ba181da15e1aa79cd51a37eb127fd0d1e (patch)
treebf5aaeb9e3cb8c4d26628393aeff5a2a93ede214
parent68252424a7c757ce0a534696e22e1770408bc01d (diff)
serial: 8250_dw: support high baudrates if possiblereview/dw8250_clock-v3
Currently, for device tree based systems, the Synopsys DesignWare 8250 driver assumes its UART clock runs at a fixed rate. If a "real" clock was set up using the common clock framework, and that clock's rate is adjustable, it may be possible to support a wider range of baud rates by changing the UART clock rate. This is done by setting up a uart_port->set_termios method that requests a clock rate change if a different rate might make it more likely to achieve a specified baud. Signed-off-by: Alex Elder <elder@linaro.org>
-rw-r--r--drivers/tty/serial/8250/8250_dw.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index c531fa42f83..cc7403a47dd 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -251,6 +251,21 @@ static void dw8250_setup_port(struct uart_8250_port *up)
up->capabilities |= UART_CAP_AFE;
}
+/*
+ * Returns true if the UART clock's rate can be adjusted in order to
+ * achieve higher baud rates.
+ */
+static bool dw8250_adjustable_clk(struct uart_port *p)
+{
+ struct device_node *np = p->dev->of_node;
+
+ if (of_device_is_compatible(np, "brcm,bcm11351-dw-apb-uart"))
+ return true;
+ if (of_device_is_compatible(np, "brcm,bcm21664-dw-apb-uart"))
+ return true;
+ return false;
+}
+
static int dw8250_probe_of(struct uart_port *p,
struct dw8250_data *data)
{
@@ -258,6 +273,9 @@ static int dw8250_probe_of(struct uart_port *p,
u32 val;
bool has_ucv = true;
+ if (dw8250_adjustable_clk(p))
+ p->set_termios = dw8250_set_termios;
+
if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) {
#ifdef __BIG_ENDIAN
/*
@@ -492,6 +510,8 @@ static const struct dev_pm_ops dw8250_pm_ops = {
static const struct of_device_id dw8250_of_match[] = {
{ .compatible = "snps,dw-apb-uart" },
{ .compatible = "cavium,octeon-3860-uart" },
+ { .compatible = "brcm,bcm11351-dw-apb-uart" },
+ { .compatible = "brcm,bcm21664-dw-apb-uart" },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, dw8250_of_match);