|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |