serial: uartlite: Move driver to DM
authorMichal Simek <michal.simek@xilinx.com>
Tue, 1 Dec 2015 13:24:20 +0000 (14:24 +0100)
committerMichal Simek <michal.simek@xilinx.com>
Wed, 27 Jan 2016 14:55:49 +0000 (15:55 +0100)
Enable SPL DM too.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Reviewed-by: Thomas Chou <thomas@wytron.com.tw>
arch/microblaze/Kconfig
configs/microblaze-generic_defconfig
doc/device-tree-bindings/serial/xilinx_uartlite.txt [new file with mode: 0644]
doc/driver-model/serial-howto.txt
drivers/serial/serial_xuartlite.c

index 604f6815af5b460a775557ecf4be19d5753fb4cf..30ea484f48aafe00d536634722d0b31bddc50c26 100644 (file)
@@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC
        select SUPPORT_SPL
        select OF_CONTROL
        select DM
+       select DM_SERIAL
 
 endchoice
 
index ed336e6bc4412dd7bf9c4063c6d057139fdfa977..6b038b884f0af7400d0fb5089f84b26477846837 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_MICROBLAZE=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_DM=y
 CONFIG_TARGET_MICROBLAZE_GENERIC=y
 CONFIG_SYS_TEXT_BASE=0x29000000
 CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic"
@@ -7,4 +8,5 @@ CONFIG_SPL=y
 CONFIG_SYS_PROMPT="U-Boot-mONStR> "
 CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt
new file mode 100644 (file)
index 0000000..d15753c
--- /dev/null
@@ -0,0 +1,13 @@
+Binding for Xilinx Uartlite Controller
+
+Required properties:
+- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b"
+- reg: Should contain UART controller registers location and length.
+- interrupts: Should contain UART controller interrupts.
+
+Example:
+       serial@40600000 {
+               compatible = "xlnx,xps-uartlite-1.00.a";
+               interrupts = <1 0>;
+               reg = <0x40600000 0x10000>;
+       };
index c933b9081be1aba9079dee8f916a2696d219286b..e5e482e30bc297ad6f5b957b6ed65cf068009a76 100644 (file)
@@ -15,7 +15,6 @@ is time for maintainers to start converting over the remaining serial drivers:
    serial_pxa.c
    serial_s3c24x0.c
    serial_sa1100.c
-   serial_xuartlite.c
    usbtty.c
 
 You should complete this by the end of January 2016.
index 988438e75471a37f2643328c910ff13b0fe753e5..157e14dedc4fb1c356bf54836351d57cc7488cdd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2008-2011 Michal Simek <monstr@monstr.eu>
+ * (C) Copyright 2008 - 2015 Michal Simek <monstr@monstr.eu>
  * Clean driver and add xilinx constant from header file
  *
  * (C) Copyright 2004 Atmark Techno, Inc.
 
 #include <config.h>
 #include <common.h>
+#include <dm.h>
 #include <asm/io.h>
 #include <linux/compiler.h>
 #include <serial.h>
 
-#define SR_TX_FIFO_FULL                0x08 /* transmit FIFO full */
-#define SR_RX_FIFO_VALID_DATA  0x01 /* data in receive FIFO */
-#define SR_RX_FIFO_FULL                0x02 /* receive FIFO full */
+DECLARE_GLOBAL_DATA_PTR;
+
+#define SR_TX_FIFO_FULL                BIT(3) /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY       BIT(2) /* transmit FIFO empty */
+#define SR_RX_FIFO_VALID_DATA  BIT(0) /* data in receive FIFO */
+#define SR_RX_FIFO_FULL                BIT(1) /* receive FIFO full */
 
 #define ULITE_CONTROL_RST_TX   0x01
 #define ULITE_CONTROL_RST_RX   0x02
@@ -28,135 +32,85 @@ struct uartlite {
        unsigned int control;
 };
 
-static struct uartlite *userial_ports[4] = {
-#ifdef XILINX_UARTLITE_BASEADDR
-       [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif
-#ifdef XILINX_UARTLITE_BASEADDR1
-       [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif
-#ifdef XILINX_UARTLITE_BASEADDR2
-       [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif
-#ifdef XILINX_UARTLITE_BASEADDR3
-       [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif
+struct uartlite_platdata {
+       struct uartlite *regs;
 };
 
-static void uartlite_serial_putc(const char c, const int port)
+static int uartlite_serial_putc(struct udevice *dev, const char ch)
 {
-       struct uartlite *regs = userial_ports[port];
+       struct uartlite_platdata *plat = dev_get_platdata(dev);
+       struct uartlite *regs = plat->regs;
 
-       if (c == '\n')
-               uartlite_serial_putc('\r', port);
+       if (in_be32(&regs->status) & SR_TX_FIFO_FULL)
+               return -EAGAIN;
 
-       while (in_be32(&regs->status) & SR_TX_FIFO_FULL)
-               ;
-       out_be32(&regs->tx_fifo, c & 0xff);
-}
+       out_be32(&regs->tx_fifo, ch & 0xff);
 
-static void uartlite_serial_puts(const char *s, const int port)
-{
-       while (*s)
-               uartlite_serial_putc(*s++, port);
+       return 0;
 }
 
-static int uartlite_serial_getc(const int port)
+static int uartlite_serial_getc(struct udevice *dev)
 {
-       struct uartlite *regs = userial_ports[port];
+       struct uartlite_platdata *plat = dev_get_platdata(dev);
+       struct uartlite *regs = plat->regs;
+
+       if (!(in_be32(&regs->status) & SR_RX_FIFO_VALID_DATA))
+               return -EAGAIN;
 
-       while (!(in_be32(&regs->status) & SR_RX_FIFO_VALID_DATA))
-               ;
        return in_be32(&regs->rx_fifo) & 0xff;
 }
 
-static int uartlite_serial_tstc(const int port)
+static int uartlite_serial_pending(struct udevice *dev, bool input)
 {
-       struct uartlite *regs = userial_ports[port];
+       struct uartlite_platdata *plat = dev_get_platdata(dev);
+       struct uartlite *regs = plat->regs;
 
-       return in_be32(&regs->status) & SR_RX_FIFO_VALID_DATA;
+       if (input)
+               return in_be32(&regs->status) & SR_RX_FIFO_VALID_DATA;
+
+       return !(in_be32(&regs->status) & SR_TX_FIFO_EMPTY);
 }
 
-static int uartlite_serial_init(const int port)
+static int uartlite_serial_probe(struct udevice *dev)
 {
-       struct uartlite *regs = userial_ports[port];
-
-       if (regs) {
-               out_be32(&regs->control, 0);
-               out_be32(&regs->control,
-                        ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
-               in_be32(&regs->control);
-               return 0;
-       }
+       struct uartlite_platdata *plat = dev_get_platdata(dev);
+       struct uartlite *regs = plat->regs;
 
-       return -1;
-}
+       out_be32(&regs->control, 0);
+       out_be32(&regs->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
+       in_be32(&regs->control);
 
-/* Multi serial device functions */
-#define DECLARE_ESERIAL_FUNCTIONS(port) \
-       static int userial##port##_init(void) \
-                               { return uartlite_serial_init(port); } \
-       static void userial##port##_setbrg(void) {} \
-       static int userial##port##_getc(void) \
-                               { return uartlite_serial_getc(port); } \
-       static int userial##port##_tstc(void) \
-                               { return uartlite_serial_tstc(port); } \
-       static void userial##port##_putc(const char c) \
-                               { uartlite_serial_putc(c, port); } \
-       static void userial##port##_puts(const char *s) \
-                               { uartlite_serial_puts(s, port); }
-
-/* Serial device descriptor */
-#define INIT_ESERIAL_STRUCTURE(port, __name) { \
-       .name   = __name,                       \
-       .start  = userial##port##_init,         \
-       .stop   = NULL,                         \
-       .setbrg = userial##port##_setbrg,       \
-       .getc   = userial##port##_getc,         \
-       .tstc   = userial##port##_tstc,         \
-       .putc   = userial##port##_putc,         \
-       .puts   = userial##port##_puts,         \
+       return 0;
 }
 
-DECLARE_ESERIAL_FUNCTIONS(0);
-struct serial_device uartlite_serial0_device =
-       INIT_ESERIAL_STRUCTURE(0, "ttyUL0");
-DECLARE_ESERIAL_FUNCTIONS(1);
-struct serial_device uartlite_serial1_device =
-       INIT_ESERIAL_STRUCTURE(1, "ttyUL1");
-DECLARE_ESERIAL_FUNCTIONS(2);
-struct serial_device uartlite_serial2_device =
-       INIT_ESERIAL_STRUCTURE(2, "ttyUL2");
-DECLARE_ESERIAL_FUNCTIONS(3);
-struct serial_device uartlite_serial3_device =
-       INIT_ESERIAL_STRUCTURE(3, "ttyUL3");
-
-__weak struct serial_device *default_serial_console(void)
+static int uartlite_serial_ofdata_to_platdata(struct udevice *dev)
 {
-       if (userial_ports[0])
-               return &uartlite_serial0_device;
-       if (userial_ports[1])
-               return &uartlite_serial1_device;
-       if (userial_ports[2])
-               return &uartlite_serial2_device;
-       if (userial_ports[3])
-               return &uartlite_serial3_device;
-
-       return NULL;
-}
+       struct uartlite_platdata *plat = dev_get_platdata(dev);
 
-void uartlite_serial_initialize(void)
-{
-#ifdef XILINX_UARTLITE_BASEADDR
-       serial_register(&uartlite_serial0_device);
-#endif /* XILINX_UARTLITE_BASEADDR */
-#ifdef XILINX_UARTLITE_BASEADDR1
-       serial_register(&uartlite_serial1_device);
-#endif /* XILINX_UARTLITE_BASEADDR1 */
-#ifdef XILINX_UARTLITE_BASEADDR2
-       serial_register(&uartlite_serial2_device);
-#endif /* XILINX_UARTLITE_BASEADDR2 */
-#ifdef XILINX_UARTLITE_BASEADDR3
-       serial_register(&uartlite_serial3_device);
-#endif /* XILINX_UARTLITE_BASEADDR3 */
+       plat->regs = (struct uartlite *)dev_get_addr(dev);
+
+       return 0;
 }
+
+static const struct dm_serial_ops uartlite_serial_ops = {
+       .putc = uartlite_serial_putc,
+       .pending = uartlite_serial_pending,
+       .getc = uartlite_serial_getc,
+};
+
+static const struct udevice_id uartlite_serial_ids[] = {
+       { .compatible = "xlnx,opb-uartlite-1.00.b", },
+       { .compatible = "xlnx,xps-uartlite-1.00.a" },
+       { }
+};
+
+U_BOOT_DRIVER(serial_uartlite) = {
+       .name   = "serial_uartlite",
+       .id     = UCLASS_SERIAL,
+       .of_match = uartlite_serial_ids,
+       .ofdata_to_platdata = uartlite_serial_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct uartlite_platdata),
+       .probe = uartlite_serial_probe,
+       .ops    = &uartlite_serial_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};