[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
Hi Iurii, 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). [..] > +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? [..] > + 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? [..] > +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. [..] > +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 ) ... Regards, -- Julien Grall _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |