This patch adds device tree support for serial_ns16550 driver. Tested with pcduino (allwinner a10). Signed-off-by: NISHIMOTO Hiroki <hiroki.nishimoto.if@xxxxxxxxx> --- .../devicetree/bindings/serial/ns16550_serial.txt | 34 ++++++++++++++ drivers/serial/serial_ns16550.c | 53 ++++++++++++++++++++-- 2 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/serial/ns16550_serial.txt diff --git a/Documentation/devicetree/bindings/serial/ns16550_serial.txt b/Documentation/devicetree/bindings/serial/ns16550_serial.txt new file mode 100644 index 0000000..848f949 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/ns16550_serial.txt @@ -0,0 +1,34 @@ +* NS16550 UART + +Required properties: +- compatible : "ns16550_serial" +- reg : offset and length of the register set for the device. + + +Optional properties: +- clock-frequency : the input clock frequency for the UART. +- reg-shift : quantity to shift the register offsets by. If this property is + not present then the register offsets are not shifted. +- reg-io-width : the size (in bytes) of the IO accesses that should be + performed on the device. If this property is not present then single byte + accesses are used. +- disable-fifo : + 0: enable tx/rx fifo (default value) + 1: disable tx/rx fifo +- console-stdin : activate stdin on this console. +- console-stdout : activate stdout on this console. +- console-stderr : activate stderr on this console. + +Example: + + serial@0x01c28000 { + compatible = "ns16550_serial"; + reg = <0x01c28000 0x400>; + clock-frequency = <24000000>; + reg-shift = <2>; + reg-io-width = <4>; + disable-fifo = <0>; + console-stdin; + console-stdout; + console-stderr; + }; diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index b7913aa..bed9640 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -57,7 +57,7 @@ static uint32_t ns16550_read(struct console_device *cdev, uint32_t off) { struct device_d *dev = cdev->dev; struct NS16550_plat *plat = (struct NS16550_plat *)dev->platform_data; - int width = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK; + int width = plat->flags & IORESOURCE_MEM_TYPE_MASK; off <<= plat->shift; @@ -87,7 +87,7 @@ static void ns16550_write(struct console_device *cdev, uint32_t val, { struct device_d *dev = cdev->dev; struct NS16550_plat *plat = (struct NS16550_plat *)dev->platform_data; - int width = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK; + int width = plat->flags & IORESOURCE_MEM_TYPE_MASK; off <<= plat->shift; @@ -234,8 +234,46 @@ static int ns16550_probe(struct device_d *dev) struct NS16550_plat *plat = (struct NS16550_plat *)dev->platform_data; /* we do expect platform specific data */ - if (plat == NULL) + if (!plat && !dev->device_node) return -EINVAL; + + if (dev->device_node) { + unsigned int width, fifo; + struct device_node *node = dev->device_node; + + plat = xzalloc(sizeof(*plat)); + + of_property_read_u32(node, "clock-frequency", &plat->clock); + of_property_read_u32(node, "reg-shift", &plat->shift); + + if (!of_property_read_u32(node, "disable-fifo", &fifo) && fifo == 1) + plat->flags |= NS16650_FLAG_DISABLE_FIFO; + + if (!of_property_read_u32(node, "reg-io-width", &width)) { + switch (width) { + case 1: + plat->flags |= IORESOURCE_MEM_8BIT; + break; + case 2: + plat->flags |= IORESOURCE_MEM_16BIT; + break; + case 4: + plat->flags |= IORESOURCE_MEM_32BIT; + break; + } + } + + if (of_find_property(node, "console-stdin")) + plat->f_caps |= CONSOLE_STDIN; + if (of_find_property(node, "console-stdout")) + plat->f_caps |= CONSOLE_STDOUT; + if (of_find_property(node, "console-stderr")) + plat->f_caps |= CONSOLE_STDERR; + + dev->platform_data = plat; + } else + plat->flags = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK; + dev->priv = dev_request_mem_region(dev, 0); cdev = xzalloc(sizeof(*cdev)); @@ -255,11 +293,20 @@ static int ns16550_probe(struct device_d *dev) return console_register(cdev); } +static struct of_device_id ns16550_serial_dt_ids[] = { + { + .compatible = "ns16550_serial", + }, { + /* sentinel */ + }, +}; + /** * @brief Driver registration structure */ static struct driver_d ns16550_serial_driver = { .name = "ns16550_serial", .probe = ns16550_probe, + .of_compatible = DRV_OF_COMPAT(ns16550_serial_dt_ids), }; console_platform_driver(ns16550_serial_driver); -- 1.8.1.2 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox