[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 2/3] xen/arm: Add new driver for R-Car Gen2 UART
On Thu, Jan 22, 2015 at 4:44 PM, Julien Grall <julien.grall@xxxxxxxxxx> wrote: > > Hi Iurii, Hi Julien, It's Oleksandr. Thank you for your comments. > > > On 21/01/15 14:16, Iurii Konovalenko wrote: > > diff --git a/xen/drivers/char/rcar2-uart.c b/xen/drivers/char/rcar2-uart.c > > +static void rcar2_uart_interrupt(int irq, void *data, struct cpu_user_regs *regs) > > +{ > > +  Âstruct serial_port *port = data; > > +  Âstruct rcar2_uart *uart = port->uart; > > +  Âuint16_t status, ctrl; > > + > > +  Âctrl = rcar2_readw(uart, SCIF_SCSCR); > > +  Âstatus = rcar2_readw(uart, SCIF_SCFSR) & ~SCFSR_TEND; > > +  Â/* Ignore next flag if TX Interrupt is disabled */ > > +  Âif ( !(ctrl & SCSCR_TIE) ) > > +    Âstatus &= ~SCFSR_TDFE; > > + > > +  Âwhile ( status != 0 ) > > +  Â{ > > +    Â/* TX Interrupt */ > > +    Âif ( status & SCFSR_TDFE ) > > +    Â{ > > +      Âserial_tx_interrupt(port, regs); > > + > > +      Âif ( port->txbufc == port->txbufp ) > > +      Â{ > > +        Â/* > > +         * There is no data bytes to send. We have to disable > > +         * TX Interrupt to prevent us from getting stuck in the > > +         * interrupt handler > > +         */ > > +        Âctrl = rcar2_readw(uart, SCIF_SCSCR); > > +        Âctrl &= ~SCSCR_TIE; > > +        Ârcar2_writew(uart, SCIF_SCSCR, ctrl); > > +      Â} > > serial_start_tx and serial_stop_tx callback have been recently > introduced to start/stop transmission. > > I think you could use them to replace this if (and maybe some others). Am I right that you are speaking about this patch "[PATCH v1] xen/arm: Manage pl011 uart TX interrupt correctly"? http://www.gossamer-threads.com/lists/xen/devel/359033 > > > [..] > > > +static void __init rcar2_uart_init_preirq(struct serial_port *port) > > +{ > > +  Âstruct rcar2_uart *uart = port->uart; > > +  Âunsigned int divisor; > > +  Âuint16_t val; > > + > > +  Â/* > > +   * Wait until last bit has been transmitted. This is needed for a smooth > > +   * transition when we come from early printk > > +   */ > > +  Âwhile ( !(rcar2_readw(uart, SCIF_SCFSR) & SCFSR_TEND) ); > > Would it be possible that it get stucks forever? I don't think so. We just waiting for transmission to end. But anyway, I can break this loop by timeout. > > [..] > > > +  ÂASSERT( uart->clock_hz > 0 ); > > +  Âif ( uart->baud != BAUD_AUTO ) > > +  Â{ > > +    Â/* Setup desired Baud rate */ > > +    Âdivisor = uart->clock_hz / (uart->baud << 4); > > +    ÂASSERT( divisor >= 1 && divisor <= (uint16_t)UINT_MAX ); > > +    Ârcar2_writew(uart, SCIF_DL, (uint16_t)divisor); > > +    Â/* Selects the frequency divided clock (SC_CLK external input) */ > > +    Ârcar2_writew(uart, SCIF_CKS, 0); > > +    Â/* > > +     * TODO: should be uncommented > > +     * udelay(1000000 / uart->baud + 1); > > +     */ > > Why didn't you uncommented? Ah, I just recollected about this. This is due to driver get stucks in udelay(). http://lists.xen.org/archives/html/xen-devel/2014-10/msg01935.html Now, we come from U-Boot with arch timer enabled. I will try your suggestion (about moving init_xen_time() before console_init_preirq()) again. I hope that we can uncomment this call. > > [..] > > > +static int rcar2_uart_tx_ready(struct serial_port *port) > > +{ > > +  Âstruct rcar2_uart *uart = port->uart; > > +  Âuint16_t cnt; > > + > > +  Â/* Check for empty space in TX FIFO */ > > +  Âif ( !(rcar2_readw(uart, SCIF_SCFSR) & SCFSR_TDFE) ) > > +    Âreturn 0; > > + > > +  Â/* > > +   * It seems that the Framework has a data bytes to send. > > +   * Enable TX Interrupt disabled from interrupt handler before > > +   */ > > +  Âif ( uart->irq_en ) > > +    Ârcar2_writew(uart, SCIF_SCSCR, rcar2_readw(uart, SCIF_SCSCR) | > > +           SCSCR_TIE); > > I think you can replace it by implementing the callback start_tx. ok. > > [..] > > > +static int __init rcar2_uart_init(struct dt_device_node *dev, > > +                 const void *data) > > +{ > > +  Âconst char *config = data; > > +  Âstruct rcar2_uart *uart; > > +  Âint res; > > +  Âu64 addr, size; > > + > > +  Âif ( strcmp(config, "") ) > > +    Âprintk("WARNING: UART configuration is not supported\n"); > > + > > +  Âuart = &rcar2_com; > > + > > +  Âuart->clock_hz Â= SCIF_CLK_FREQ; > > +  Âuart->baud   Â= BAUD_AUTO; > > +  Âuart->data_bits = 8; > > +  Âuart->parity  Â= PARITY_NONE; > > +  Âuart->stop_bits = 1; > > + > > +  Âres = dt_device_get_address(dev, 0, &addr, &size); > > +  Âif ( res ) > > +  Â{ > > +    Âprintk("rcar2-uart: Unable to retrieve the base" > > +           " address of the UART\n"); > > +    Âreturn res; > > +  Â} > > + > > +  Âuart->regs = ioremap_nocache(addr, size); > > +  Âif ( !uart->regs ) > > +  Â{ > > +    Âprintk("rcar2-uart: Unable to map the UART memory\n"); > > +    Âreturn -ENOMEM; > > +  Â} > > + > > +  Âres = platform_get_irq(dev, 0); > > +  Âif ( res < 0 ) > > +  Â{ > > +    Âprintk("rcar2-uart: Unable to retrieve the IRQ\n"); > > +    Âreturn res; > > if platform_get_irq fails, the driver will leak the mapping made with > ioremap_cache. I would invert the 2 call: > > res = platform_get_irq(dev, 0); > if ( res < 0 ) >     ... > > uart->regs = ioremap_nocache(addr, size); > if ( !uart->regs ) Sounds reasonable. ok. >     ... > > Regards, > > -- > Julien Grall -- Oleksandr Tyshchenko | Embedded Dev GlobalLogic www.globallogic.com _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |