On Thu, Jan 22, 2015 at 4:44 PM, Julien Grall <julien.gr...@linaro.org> 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 I will rewrite code to use these callbacks. > > > [..] > > > +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@lists.xen.org http://lists.xen.org/xen-devel