[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [RFC PATCH] xen/arm: Add MVEBU UART driver for Armada 3700 SoC



Hi

Thanks for the comments.

> OOI, do you have any plan for adding earlyprintk support for that platform?

I didn't think about it but I would look into it.

> Please give a link to the Linux driver. This would help me for reviewing and
> also for future reference.

Ok.

> This is part of xen/drivers/char/* so even if the driver if only for ARM
> hardware, you likely want to CC "THE REST" maintainers as this is under
> drivers/char. scripts/get_maintainers.pl can help you to find relevant
> maintainers to CC on each patch.

Ok.

 <xen/*> include should be first, then <asm/*>.

Ok, I was under the impression that it should be sorted in alphabetical order.

>
>> +#include <xen/console.h>
>> +#include <xen/errno.h>
>> +#include <xen/init.h>
>> +#include <xen/irq.h>
>> +#include <xen/mm.h>
>> +#include <xen/serial.h>
>> +#include <xen/serial.h>
>
>
> xen/serial.h is mentioned twice.
Ok.

>
>> +#include <xen/vmap.h>
>> +
>> +#define UART_RX_REG             0x00
>> +#define RBR_BRK_DET             BIT(15)
>> +#define RBR_FRM_ERR_DET         BIT(14)
>> +#define RBR_PAR_ERR_DET         BIT(13)
>> +#define RBR_OVR_ERR_DET         BIT(12)
>> +
>> +#define UART_TX_REG             0x04
>> +
>> +#define UART_CTRL_REG           0x08
>> +#define CTRL_SOFT_RST           BIT(31)
>> +#define CTRL_TXFIFO_RST         BIT(15)
>> +#define CTRL_RXFIFO_RST         BIT(14)
>> +#define CTRL_ST_MIRR_EN         BIT(13)
>> +#define CTRL_LPBK_EN            BIT(12)
>> +#define CTRL_SND_BRK_SEQ        BIT(11)
>> +#define CTRL_PAR_EN             BIT(10)
>> +#define CTRL_TWO_STOP           BIT(9)
>> +#define CTRL_TX_HFL_INT         BIT(8)
>> +#define CTRL_RX_HFL_INT         BIT(7)
>> +#define CTRL_TX_EMP_INT         BIT(6)
>> +#define CTRL_TX_RDY_INT         BIT(5)
>> +#define CTRL_RX_RDY_INT         BIT(4)
>> +#define CTRL_BRK_DET_INT        BIT(3)
>> +#define CTRL_FRM_ERR_INT        BIT(2)
>> +#define CTRL_PAR_ERR_INT        BIT(1)
>> +#define CTRL_OVR_ERR_INT        BIT(0)
>> +#define CTRL_RX_INT             (CTRL_BRK_DET_INT | CTRL_FRM_ERR_INT | \
>> +                                 CTRL_PAR_ERR_INT | CTRL_OVR_ERR_INT)
>> +
>> +#define UART_STATUS_REG         0x0c
>> +#define STATUS_TXFIFO_EMP       BIT(13)
>> +#define STATUS_RXFIFO_EMP       BIT(12)
>> +#define STATUS_TXFIFO_FUL       BIT(11)
>> +#define STATUS_TXFIFO_HFL       BIT(10)
>> +#define STATUS_RX_TOGL          BIT(9)
>> +#define STATUS_RXFIFO_FUL       BIT(8)
>> +#define STATUS_RXFIFO_HFL       BIT(7)
>> +#define STATUS_TX_EMP           BIT(6)
>> +#define STATUS_TX_RDY           BIT(5)
>> +#define STATUS_RX_RDY           BIT(4)
>> +#define STATUS_BRK_DET          BIT(3)
>> +#define STATUS_FRM_ERR          BIT(2)
>> +#define STATUS_PAR_ERR          BIT(1)
>> +#define STATUS_OVR_ERR          BIT(0)
>> +#define STATUS_BRK_ERR          (STATUS_BRK_DET | STATUS_FRM_ERR | \
>> +                                STATUS_PAR_ERR | STATUS_OVR_ERR)
>> +
>> +#define UART_BAUD_REG           0x10
>> +#define UART_POSSR_REG          0x14
>
>
> Can you please only define only registers/bits used in the code?

Ok.

>> +
>> +#define TX_FIFO_SIZE            32
>> +#define RX_FIFO_SIZE            64
>> +
>> +static struct mvebu3700_uart {
>> +    unsigned int baud, data_bits, parity, stop_bits;
>
>
> Are all those fields necessary? For instance, you always set baud but never
> read it.

Not sure about this as I don't know if these fields are used by XEN
serial infrastructure later on.

>> +    unsigned int irq;
>> +    void __iomem *regs;
>> +    struct irqaction irqaction;
>> +    struct vuart_info vuart;
>> +} mvebu3700_com = {0};
>> +
>> +#define PARITY_NONE  (0)
>> +
>> +#define mvebu3700_read(uart, off)           readl((uart)->regs + off)
>> +#define mvebu3700_write(uart, off, val)     writel(val, (uart->regs) +
>> off)
>> +
>> +static void mvebu3700_uart_interrupt(int irq, void *data, struct
>> +cpu_user_regs *regs)
>
>
> The indentation looks wrong here.
>
>> +{
>> +    struct serial_port *port = data;
>> +    struct mvebu3700_uart *uart = port->uart;
>> +    unsigned int st = mvebu3700_read(uart, UART_STATUS_REG);
>> +
>> +    if ( st & STATUS_TX_RDY )
>> +        serial_tx_interrupt(port, regs);
>> +
>> +    if ( st & (STATUS_RX_RDY | STATUS_OVR_ERR | STATUS_FRM_ERR |
>> STATUS_BRK_DET) )
>> +        serial_rx_interrupt(port, regs);
>> +}
>> +
>> +static void __init mvebu3700_uart_init_preirq(struct serial_port *port)
>> +{
>> +    struct mvebu3700_uart *uart = port->uart;
>> +    unsigned ret;
>
>
> 'ret' is a bit confusion. I would expect to be the return value of the
> function but it is used a temporary variable for reading/write reg. You
> might want to rename to 'reg' for more clarity.
Ok.

> But as this is a register value (i.e specific size), please use uint32_t.
>
>> +
>> +    ret = mvebu3700_read(uart, UART_CTRL_REG);
>> +    ret |= (CTRL_TXFIFO_RST | CTRL_RXFIFO_RST);
>> +    mvebu3700_write(uart, UART_CTRL_REG, ret);
>> +
>> +    /* Before we make IRQ request, Clear the error bits of state register
>> */
>
>
> s/Clear/clear/ and missing full stop.

Ok.
>
>
>> +    ret = mvebu3700_read(uart, UART_STATUS_REG);
>> +    ret |= STATUS_BRK_ERR;
>> +    mvebu3700_write(uart, UART_STATUS_REG, ret);
>> +
>> +    /* Clear error interrupts */
>> +    mvebu3700_write(uart, UART_CTRL_REG, CTRL_RX_INT);
>> +
>> +    /* Disable Rx/Tx interrupts */
>> +    ret = mvebu3700_read(uart, UART_CTRL_REG);
>> +    ret &= ~(CTRL_RX_RDY_INT | CTRL_TX_RDY_INT);
>> +    mvebu3700_write(uart, UART_CTRL_REG, ret);
>> +}
>> +
>> +        dprintk(XENLOG_ERR, "Failed to allocated mvebu3700_uart IRQ
>> %d\n",
>> +                uart->irq);
>
>
> dprintk will only be used in debug build. I think this should be printk
> here.

Ok.

>> +
>> +    /* Make sure Rx/Tx interrupts are enabled now */
>> +    ret = mvebu3700_read(uart, UART_CTRL_REG);
>
>
> ret is an int. This is usually a pretty bad idea to use signed value for
> register. Furthermore, I would highly recommend to specific the size in the
> variable type (e.g uint32_t).

Ok.
>
>> +    ret |= (CTRL_RX_RDY_INT | CTRL_TX_RDY_INT);
>> +    mvebu3700_write(uart, UART_CTRL_REG, ret);
>> +}
>> +
>> +static void mvebu3700_uart_suspend(struct serial_port *port)
>> +{
>> +    BUG();
>> +}
>> +
>> +static void mvebu3700_uart_resume(struct serial_port *port)
>> +{
>> +    BUG();
>> +}
>> +
>> +static void mvebu3700_uart_putc(struct serial_port *port, char c)
>> +{
>> +    struct mvebu3700_uart *uart = port->uart;
>> +
>> +    mvebu3700_write(uart, UART_TX_REG, c);
>> +}
>> +
>> +static int mvebu3700_uart_getc(struct serial_port *port, char *c)
>> +{
>> +    struct mvebu3700_uart *uart = port->uart;
>> +
>> +    if ( !(mvebu3700_read(uart, UART_STATUS_REG) & STATUS_RX_RDY) )
>> +        return 0;
>> +
>> +    *c = mvebu3700_read(uart, UART_RX_REG) & 0xff;
>> +
>> +    return 1;
>> +}
>> +
>> +static int __init mvebu3700_irq(struct serial_port *port)
>> +{
>> +    struct mvebu3700_uart *uart = port->uart;
>> +
>> +    return ( (uart->irq > 0) ? uart->irq : -1 );
>> +}
>> +
>> +static const struct vuart_info *mvebu3700_vuart_info(struct serial_port
>> *port)
>> +{
>> +    struct mvebu3700_uart *uart = port->uart;
>> +
>> +    return &uart->vuart;
>> +}
>> +
>> +static void mvebu3700_uart_stop_tx(struct serial_port *port)
>> +{
>> +    struct mvebu3700_uart *uart = port->uart;
>> +    unsigned int ctl;
>
>
> s/unsigned int/uint32_t/.

Ok.
>
>> +
>> +    ctl = mvebu3700_read(uart, UART_CTRL_REG);
>> +    ctl &= ~CTRL_TX_RDY_INT;
>> +    mvebu3700_write(uart, UART_CTRL_REG, ctl);
>> +}
>> +
>> +static void mvebu3700_uart_start_tx(struct serial_port *port)
>> +{
>> +    struct mvebu3700_uart *uart = port->uart;
>> +    unsigned int ctl;
>> +
>> +    ctl = mvebu3700_read(uart, UART_CTRL_REG);
>> +    ctl |= CTRL_TX_RDY_INT;
>> +    mvebu3700_write(uart, UART_CTRL_REG, ctl);
>> +}
>> +
>> +static int mvebu3700_uart_tx_ready(struct serial_port *port)
>> +{
>> +    struct mvebu3700_uart *uart = port->uart;
>> +
>> +    return ( mvebu3700_read(uart, UART_STATUS_REG) & STATUS_TXFIFO_EMP ?
>> +             TX_FIFO_SIZE : 0 );
>
>
> This is not so nice to read. Can you introduce a temporary variable to read
> the register?

Ok.

>> +    {
>> +        printk("mvebu3700: Unable to retrieve the base"
>> +               " address of the UART\n");
>
>
> Please don't split message (unless there are a newline in it). This is more
> difficult to grep in the code. This is one place where we accept line
> greater than 80 characters.

Ok.

Thanks
Amit

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.