From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thomas Chou Date: Thu, 17 Dec 2015 21:37:11 +0800 Subject: [U-Boot] [PATCH v2 1/3] serial: uartlite: Move driver to DM In-Reply-To: References: Message-ID: <5672BA87.6020605@wytron.com.tw> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Michal, On 2015?12?17? 20:00, Michal Simek wrote: > Enable SPL DM too. > > Signed-off-by: Michal Simek > --- > > Changes in v2: > - Remove unneeded headers > - Use get_dev_addr instead of fdtdec_get_addr > - Use platdata instead of private data > - Add opb compatible string to be in sync with Linux > - Add binding documentation > > arch/microblaze/Kconfig | 1 + > configs/microblaze-generic_defconfig | 2 + > .../serial/xilinx_uartlite.txt | 13 ++ > doc/driver-model/serial-howto.txt | 1 - > drivers/serial/serial_xuartlite.c | 170 ++++++++------------- > 5 files changed, 78 insertions(+), 109 deletions(-) > create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt > > diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig > index 604f6815af5b..30ea484f48aa 100644 > --- a/arch/microblaze/Kconfig > +++ b/arch/microblaze/Kconfig > @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC > select SUPPORT_SPL > select OF_CONTROL > select DM > + select DM_SERIAL > > endchoice > > diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig > index 54aa3ef3d26f..5df080b6a87c 100644 > --- a/configs/microblaze-generic_defconfig > +++ b/configs/microblaze-generic_defconfig > @@ -1,9 +1,11 @@ > CONFIG_MICROBLAZE=y > CONFIG_SPL_SYS_MALLOC_SIMPLE=y > +CONFIG_SPL_DM=y > CONFIG_TARGET_MICROBLAZE_GENERIC=y > CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" > 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 > index 000000000000..d15753c8c380 > --- /dev/null > +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt > @@ -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 at 40600000 { > + compatible = "xlnx,xps-uartlite-1.00.a"; > + interrupts = <1 0>; > + reg = <0x40600000 0x10000>; > + }; > diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt > index 76ad629ef9cb..381a2a084562 100644 > --- a/doc/driver-model/serial-howto.txt > +++ b/doc/driver-model/serial-howto.txt > @@ -18,7 +18,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. > diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c > index 988438e75471..8225d9a320a5 100644 > --- a/drivers/serial/serial_xuartlite.c > +++ b/drivers/serial/serial_xuartlite.c > @@ -1,5 +1,5 @@ > /* > - * (C) Copyright 2008-2011 Michal Simek > + * (C) Copyright 2008 - 2015 Michal Simek > * Clean driver and add xilinx constant from header file > * > * (C) Copyright 2004 Atmark Techno, Inc. > @@ -10,11 +10,15 @@ > > #include > #include > +#include > #include > #include > #include > > +DECLARE_GLOBAL_DATA_PTR; > + > #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */ > +#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ > #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ > #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */ > > @@ -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(®s->status) & SR_TX_FIFO_FULL) > + return -EAGAIN; > > - while (in_be32(®s->status) & SR_TX_FIFO_FULL) > - ; > - out_be32(®s->tx_fifo, c & 0xff); > -} > + out_be32(®s->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(®s->status) & SR_RX_FIFO_VALID_DATA)) > + return -EAGAIN; > > - while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA)) > - ; > return in_be32(®s->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(®s->status) & SR_RX_FIFO_VALID_DATA; > + if (input) > + return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA; > + > + return in_be32(®s->status) & SR_TX_FIFO_EMPTY; Should be inversed. Otherwise, Reviewed-by: Thomas Chou > } > > -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(®s->control, 0); > - out_be32(®s->control, > - ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); > - in_be32(®s->control); > - return 0; > - } > + struct uartlite_platdata *plat = dev_get_platdata(dev); > + struct uartlite *regs = plat->regs; > > - return -1; > -} > + out_be32(®s->control, 0); > + out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); > + in_be32(®s->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, > +}; > Best regards, Thomas