From mboxrd@z Thu Jan 1 00:00:00 1970 From: Michal Simek Date: Tue, 1 Sep 2015 17:42:24 +0200 Subject: [U-Boot] [PATCH 13/13] arm: zynq: Move serial driver to driver model In-Reply-To: <1440861022-22674-14-git-send-email-sjg@chromium.org> References: <1440861022-22674-1-git-send-email-sjg@chromium.org> <1440861022-22674-14-git-send-email-sjg@chromium.org> Message-ID: <55E5C760.2050806@monstr.eu> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 08/29/2015 05:10 PM, Simon Glass wrote: > Update this driver to use driver model and change all users. > > Signed-off-by: Simon Glass > --- > > arch/arm/Kconfig | 1 + > drivers/serial/serial_zynq.c | 162 ++++++++++++++++------------------------ > include/configs/zynq_microzed.h | 1 - > include/configs/zynq_picozed.h | 1 - > include/configs/zynq_zc70x.h | 1 - > include/configs/zynq_zc770.h | 6 -- > include/configs/zynq_zed.h | 1 - > include/configs/zynq_zybo.h | 1 - > 8 files changed, 65 insertions(+), 109 deletions(-) > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index a82306e..7705e03 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -687,6 +687,7 @@ config ARCH_ZYNQ > select DM > select SPL_DM > select DM_SPI > + select DM_SERIAL Can you please keep DM_SPI and DM_SPI_FLASH together? > select DM_SPI_FLASH > select SPL_SEPARATE_BSS > > diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c > index c39c1a9..7069afe 100644 > --- a/drivers/serial/serial_zynq.c > +++ b/drivers/serial/serial_zynq.c > @@ -6,6 +6,8 @@ > */ > > #include > +#include > +#include > #include > #include > #include > @@ -18,6 +20,7 @@ > DECLARE_GLOBAL_DATA_PTR; > > #define ZYNQ_UART_SR_TXFULL 0x00000010 /* TX FIFO full */ > +#define ZYNQ_UART_SR_TXACTIVE (1 << 11) /* TX active */ > #define ZYNQ_UART_SR_RXEMPTY 0x00000002 /* RX FIFO empty */ > > #define ZYNQ_UART_CR_TX_EN 0x00000010 /* TX enabled */ > @@ -38,9 +41,8 @@ struct uart_zynq { > u32 baud_rate_divider; /* 0x34 - Baud Rate Divider [7:0] */ > }; > > -static struct uart_zynq *uart_zynq_ports[2] = { > - [0] = (struct uart_zynq *)ZYNQ_SERIAL_BASEADDR0, > - [1] = (struct uart_zynq *)ZYNQ_SERIAL_BASEADDR1, > +struct zynq_uart_priv { > + struct uart_zynq *regs; > }; > > /* Set up the baud rate in gd struct */ > @@ -84,15 +86,6 @@ static void _uart_zynq_serial_setbrg(struct uart_zynq *regs, > writel(bgen, ®s->baud_rate_gen); > } > > -/* Set up the baud rate in gd struct */ > -static void uart_zynq_serial_setbrg(const int port) > -{ > - unsigned long clock = get_uart_clk(port); > - struct uart_zynq *regs = uart_zynq_ports[port]; > - > - return _uart_zynq_serial_setbrg(regs, clock, gd->baudrate); > -} > - > /* Initialize the UART, with...some settings. */ > static void _uart_zynq_serial_init(struct uart_zynq *regs) > { > @@ -102,20 +95,6 @@ static void _uart_zynq_serial_init(struct uart_zynq *regs) > writel(ZYNQ_UART_MR_PARITY_NONE, ®s->mode); /* 8 bit, no parity */ > } > > -/* Initialize the UART, with...some settings. */ > -static int uart_zynq_serial_init(const int port) > -{ > - struct uart_zynq *regs = uart_zynq_ports[port]; > - > - if (!regs) > - return -1; > - > - _uart_zynq_serial_init(regs); > - uart_zynq_serial_setbrg(port); > - > - return 0; > -} > - > static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c) > { > if (readl(®s->channel_sts) & ZYNQ_UART_SR_TXFULL) > @@ -126,103 +105,90 @@ static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c) > return 0; > } > > -static void uart_zynq_serial_putc(const char c, const int port) > +int zynq_serial_setbrg(struct udevice *dev, int baudrate) > { > - struct uart_zynq *regs = uart_zynq_ports[port]; > + struct zynq_uart_priv *priv = dev_get_priv(dev); > + unsigned long clock = get_uart_clk(0); > > - while (_uart_zynq_serial_putc(regs, c) == -EAGAIN) > - WATCHDOG_RESET(); > + _uart_zynq_serial_setbrg(priv->regs, clock, baudrate); > > - if (c == '\n') { > - while (_uart_zynq_serial_putc(regs, '\r') == -EAGAIN) > - WATCHDOG_RESET(); > - } > + return 0; > } > > -static void uart_zynq_serial_puts(const char *s, const int port) > +static int zynq_serial_probe(struct udevice *dev) > { > - while (*s) > - uart_zynq_serial_putc(*s++, port); > -} > + struct zynq_uart_priv *priv = dev_get_priv(dev); > > -static int uart_zynq_serial_tstc(const int port) > -{ > - struct uart_zynq *regs = uart_zynq_ports[port]; > + _uart_zynq_serial_init(priv->regs); > > - return (readl(®s->channel_sts) & ZYNQ_UART_SR_RXEMPTY) == 0; > + return 0; > } > > -static int uart_zynq_serial_getc(const int port) > +static int zynq_serial_getc(struct udevice *dev) > { > - struct uart_zynq *regs = uart_zynq_ports[port]; > + struct zynq_uart_priv *priv = dev_get_priv(dev); > + struct uart_zynq *regs = priv->regs; > + > + if (readl(®s->channel_sts) & ZYNQ_UART_SR_RXEMPTY) > + return -EAGAIN; > > - while (!uart_zynq_serial_tstc(port)) > - WATCHDOG_RESET(); > return readl(®s->tx_rx_fifo); > } > > -/* Multi serial device functions */ > -#define DECLARE_PSSERIAL_FUNCTIONS(port) \ > - static int uart_zynq##port##_init(void) \ > - { return uart_zynq_serial_init(port); } \ > - static void uart_zynq##port##_setbrg(void) \ > - { return uart_zynq_serial_setbrg(port); } \ > - static int uart_zynq##port##_getc(void) \ > - { return uart_zynq_serial_getc(port); } \ > - static int uart_zynq##port##_tstc(void) \ > - { return uart_zynq_serial_tstc(port); } \ > - static void uart_zynq##port##_putc(const char c) \ > - { uart_zynq_serial_putc(c, port); } \ > - static void uart_zynq##port##_puts(const char *s) \ > - { uart_zynq_serial_puts(s, port); } > - > -/* Serial device descriptor */ > -#define INIT_PSSERIAL_STRUCTURE(port, __name) { \ > - .name = __name, \ > - .start = uart_zynq##port##_init, \ > - .stop = NULL, \ > - .setbrg = uart_zynq##port##_setbrg, \ > - .getc = uart_zynq##port##_getc, \ > - .tstc = uart_zynq##port##_tstc, \ > - .putc = uart_zynq##port##_putc, \ > - .puts = uart_zynq##port##_puts, \ > -} > +static int zynq_serial_putc(struct udevice *dev, const char ch) > +{ > + struct zynq_uart_priv *priv = dev_get_priv(dev); > > -DECLARE_PSSERIAL_FUNCTIONS(0); > -static struct serial_device uart_zynq_serial0_device = > - INIT_PSSERIAL_STRUCTURE(0, "ttyPS0"); > -DECLARE_PSSERIAL_FUNCTIONS(1); > -static struct serial_device uart_zynq_serial1_device = > - INIT_PSSERIAL_STRUCTURE(1, "ttyPS1"); > + return _uart_zynq_serial_putc(priv->regs, ch); > +} > > -__weak struct serial_device *default_serial_console(void) > +static int zynq_serial_pending(struct udevice *dev, bool input) > { > - const void *blob = gd->fdt_blob; > - int node; > - unsigned int base_addr; > + struct zynq_uart_priv *priv = dev_get_priv(dev); > + struct uart_zynq *regs = priv->regs; > > - node = fdt_path_offset(blob, "serial0"); > - if (node < 0) > - return NULL; > + if (input) > + return !(readl(®s->channel_sts) & ZYNQ_UART_SR_RXEMPTY); > + else > + return !!(readl(®s->channel_sts) & ZYNQ_UART_SR_TXACTIVE); > +} > > - base_addr = fdtdec_get_addr(blob, node, "reg"); > - if (base_addr == FDT_ADDR_T_NONE) > - return NULL; > +static int zynq_serial_ofdata_to_platdata(struct udevice *dev) > +{ > + struct zynq_uart_priv *priv = dev_get_priv(dev); > + fdt_addr_t addr; > > - if (base_addr == ZYNQ_SERIAL_BASEADDR0) > - return &uart_zynq_serial0_device; > + addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg"); > + if (addr == FDT_ADDR_T_NONE) > + return -EINVAL; > > - if (base_addr == ZYNQ_SERIAL_BASEADDR1) > - return &uart_zynq_serial1_device; > + priv->regs = (struct uart_zynq *)addr; > > - return NULL; > + return 0; > } > > -void zynq_serial_initialize(void) > -{ > - serial_register(&uart_zynq_serial0_device); > - serial_register(&uart_zynq_serial1_device); > -} > +static const struct dm_serial_ops zynq_serial_ops = { > + .putc = zynq_serial_putc, > + .pending = zynq_serial_pending, > + .getc = zynq_serial_getc, > + .setbrg = zynq_serial_setbrg, > +}; > + > +static const struct udevice_id zynq_serial_ids[] = { > + { .compatible = "xlnx,xuartps" }, I would prefer to use { .compatible = "cdns,uart-r1p8" }, instead. Or both. The reason is that xlnx,xuartps compatible string is deprecated. We switch to cadence compatible string. > + { } > +}; > + > +U_BOOT_DRIVER(serial_s5p) = { serial_zynq here Thanks, Michal -- Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91 w: www.monstr.eu p: +42-0-721842854 Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/ Maintainer of Linux kernel - Xilinx Zynq ARM architecture Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: OpenPGP digital signature URL: