aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatthew Leach <matthew.leach@arm.com>2012-08-28 16:41:28 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-05 13:18:12 -0700
commit32614aad30549b0e4caf44c26efe8e2b09d597ce (patch)
treea5b55ada04da752a571d260c97c7ec68c4944bf3 /drivers
parentserial: diminish usage of struct serial_uart_config (diff)
downloadlinux-dev-32614aad30549b0e4caf44c26efe8e2b09d597ce.tar.xz
linux-dev-32614aad30549b0e4caf44c26efe8e2b09d597ce.zip
serial: pl011: honour serial aliases in device tree
If the order of UART nodes is changed in the device tree, then tty dev devices are attached to different serial ports causing the console to be directed to a different physical serial port. The "serial" aliases in the device tree should prevent this. This patch ensures that the UART driver creates tty devices that honour these aliases if a device tree is present. Acked-by: Linus Walleij <linus.walleij@linaro.org> Reviewed-by: Will Deacon <will.deacon@arm.com> Acked-by: Rob Herring <rob.herring@calxeda.com> Signed-off-by: Matthew Leach <matthew.leach@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/tty/serial/amba-pl011.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 3322023e38aa..05c15ec7bd21 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -52,6 +52,8 @@
#include <linux/scatterlist.h>
#include <linux/delay.h>
#include <linux/types.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/sizes.h>
@@ -1862,6 +1864,38 @@ static struct uart_driver amba_reg = {
.cons = AMBA_CONSOLE,
};
+static int pl011_probe_dt_alias(int index, struct device *dev)
+{
+ struct device_node *np;
+ static bool seen_dev_with_alias = false;
+ static bool seen_dev_without_alias = false;
+ int ret = index;
+
+ if (!IS_ENABLED(CONFIG_OF))
+ return ret;
+
+ np = dev->of_node;
+ if (!np)
+ return ret;
+
+ ret = of_alias_get_id(np, "serial");
+ if (IS_ERR_VALUE(ret)) {
+ seen_dev_without_alias = true;
+ ret = index;
+ } else {
+ seen_dev_with_alias = true;
+ if (ret >= ARRAY_SIZE(amba_ports) || amba_ports[ret] != NULL) {
+ dev_warn(dev, "requested serial port %d not available.\n", ret);
+ ret = index;
+ }
+ }
+
+ if (seen_dev_with_alias && seen_dev_without_alias)
+ dev_warn(dev, "aliased and non-aliased serial devices found in device tree. Serial port enumeration may be unpredictable.\n");
+
+ return ret;
+}
+
static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
{
struct uart_amba_port *uap;
@@ -1884,6 +1918,8 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
goto out;
}
+ i = pl011_probe_dt_alias(i, &dev->dev);
+
base = ioremap(dev->res.start, resource_size(&dev->res));
if (!base) {
ret = -ENOMEM;