[PATCH] ns16550: add device tree support

NISHIMOTO Hiroki hiroki.nishimoto.if at gmail.com
Mon Jun 24 08:18:49 EDT 2013


This patch adds device tree support for serial_ns16550 driver.

Tested with pcduino (allwinner a10).

Signed-off-by: NISHIMOTO Hiroki <hiroki.nishimoto.if at gmail.com>
---
 .../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 at 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




More information about the barebox mailing list