writeb(value, p->membase + offset);
}
-/* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */
-static inline void dwapb_save_out_value(struct uart_port *p, int offset,
- int value)
-{
- struct uart_8250_port *up =
- container_of(p, struct uart_8250_port, port);
-
- if (offset == UART_LCR)
- up->lcr = value;
-}
-
-/* Read the IER to ensure any interrupt is cleared before returning from ISR. */
-static inline void dwapb_check_clear_ier(struct uart_port *p, int offset)
-{
- if (offset == UART_TX || offset == UART_IER)
- p->serial_in(p, UART_IER);
-}
-
-static void dwapb_serial_out(struct uart_port *p, int offset, int value)
-{
- int save_offset = offset;
- offset = map_8250_out_reg(p, offset) << p->regshift;
- dwapb_save_out_value(p, save_offset, value);
- writeb(value, p->membase + offset);
- dwapb_check_clear_ier(p, save_offset);
-}
-
-static void dwapb32_serial_out(struct uart_port *p, int offset, int value)
-{
- int save_offset = offset;
- offset = map_8250_out_reg(p, offset) << p->regshift;
- dwapb_save_out_value(p, save_offset, value);
- writel(value, p->membase + offset);
- dwapb_check_clear_ier(p, save_offset);
-}
-
static unsigned int io_serial_in(struct uart_port *p, int offset)
{
offset = map_8250_in_reg(p, offset) << p->regshift;
p->serial_out = tsi_serial_out;
break;
- case UPIO_DWAPB:
- p->serial_in = mem_serial_in;
- p->serial_out = dwapb_serial_out;
- break;
-
- case UPIO_DWAPB32:
- p->serial_in = mem32_serial_in;
- p->serial_out = dwapb32_serial_out;
- break;
-
default:
p->serial_in = io_serial_in;
p->serial_out = io_serial_out;
case UPIO_MEM:
case UPIO_MEM32:
case UPIO_AU:
- case UPIO_DWAPB:
- case UPIO_DWAPB32:
p->serial_out(p, offset, value);
p->serial_in(p, UART_LCR); /* safe, no side-effects */
break;
port = &up->port;
if (port->handle_irq(port)) {
-
handled = 1;
-
- end = NULL;
- } else if ((up->port.iotype == UPIO_DWAPB ||
- up->port.iotype == UPIO_DWAPB32) &&
- (iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
- /* The DesignWare APB UART has an Busy Detect (0x07)
- * interrupt meaning an LCR write attempt occurred while the
- * UART was busy. The interrupt must be cleared by reading
- * the UART status register (USR) and the LCR re-written. */
- unsigned int status;
- status = *(volatile u32 *)up->port.private_data;
- serial_out(up, UART_LCR, up->lcr);
-
- handled = 1;
-
end = NULL;
} else if (end == NULL)
end = l;
case UPIO_TSI:
case UPIO_MEM32:
case UPIO_MEM:
- case UPIO_DWAPB:
- case UPIO_DWAPB32:
if (!up->port.mapbase)
break;
case UPIO_TSI:
case UPIO_MEM32:
case UPIO_MEM:
- case UPIO_DWAPB:
- case UPIO_DWAPB32:
if (!up->port.mapbase)
break;