[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