/* struct timer timer; */
/* unsigned int timeout_ms; */
/* bool_t probing, intr_works; */
+ bool sbsa; /* ARM SBSA generic interface */
} pl011_com = {0};
/* These parity settings can be ORed directly into the LCR. */
#define PARITY_MARK (PEN|SPS)
#define PARITY_SPACE (PEN|EPS|SPS)
+/* SBSA v2.x document requires, all reads/writes must be 32-bit accesses */
#define pl011_read(uart, off) readl((uart)->regs + (off))
#define pl011_write(uart, off,val) writel((val), (uart)->regs + (off))
/* No interrupts, please. */
pl011_write(uart, IMSC, 0);
- /* Definitely no DMA */
- pl011_write(uart, DMACR, 0x0);
-
- /* This write must follow FBRD and IBRD writes. */
- pl011_write(uart, LCR_H, (uart->data_bits - 5) << 5
- | FEN
- | ((uart->stop_bits - 1) << 3)
- | uart->parity);
+ if ( !uart->sbsa )
+ {
+ /* Definitely no DMA */
+ pl011_write(uart, DMACR, 0x0);
+
+ /* This write must follow FBRD and IBRD writes. */
+ pl011_write(uart, LCR_H, (uart->data_bits - 5) << 5
+ | FEN
+ | ((uart->stop_bits - 1) << 3)
+ | uart->parity);
+ }
/* Clear errors */
pl011_write(uart, RSR, 0);
pl011_write(uart, IMSC, 0);
pl011_write(uart, ICR, ALLI);
- /* Enable the UART for RX and TX; keep RTS and DTR */
- cr = pl011_read(uart, CR);
- cr &= RTS | DTR;
- pl011_write(uart, CR, cr | RXE | TXE | UARTEN);
+ if ( !uart->sbsa )
+ {
+ /* Enable the UART for RX and TX; keep RTS and DTR */
+ cr = pl011_read(uart, CR);
+ cr &= RTS | DTR;
+ pl011_write(uart, CR, cr | RXE | TXE | UARTEN);
+ }
}
static void __init pl011_init_postirq(struct serial_port *port)
.vuart_info = pl011_vuart,
};
-static int __init pl011_uart_init(int irq, u64 addr, u64 size)
+static int __init pl011_uart_init(int irq, u64 addr, u64 size, bool sbsa)
{
struct pl011 *uart;
uart->data_bits = 8;
uart->parity = PARITY_NONE;
uart->stop_bits = 1;
+ uart->sbsa = sbsa;
uart->regs = ioremap_nocache(addr, size);
if ( !uart->regs )
return -EINVAL;
}
- res = pl011_uart_init(res, addr, size);
+ res = pl011_uart_init(res, addr, size, false);
if ( res < 0 )
{
printk("pl011: Unable to initialize\n");
acpi_status status;
struct acpi_table_spcr *spcr = NULL;
int res;
+ bool sbsa;
status = acpi_get_table(ACPI_SIG_SPCR, 0,
(struct acpi_table_header **)&spcr);
return -EINVAL;
}
+ sbsa = (spcr->interface_type == ACPI_DBG2_SBSA ||
+ spcr->interface_type == ACPI_DBG2_SBSA_32);
+
/* trigger/polarity information is not available in spcr */
irq_set_type(spcr->interrupt, IRQ_TYPE_LEVEL_HIGH);
res = pl011_uart_init(spcr->interrupt, spcr->serial_port.address,
- PAGE_SIZE);
+ PAGE_SIZE, sbsa);
if ( res < 0 )
{
printk("pl011: Unable to initialize\n");
.class_type = ACPI_DBG2_PL011,
.init = pl011_acpi_uart_init,
ACPI_DEVICE_END
+
+ACPI_DEVICE_START(asbsa_uart, "SBSA UART", DEVICE_SERIAL)
+ .class_type = ACPI_DBG2_SBSA,
+ .init = pl011_acpi_uart_init,
+ACPI_DEVICE_END
+
+ACPI_DEVICE_START(asbsa32_uart, "SBSA32 UART", DEVICE_SERIAL)
+ .class_type = ACPI_DBG2_SBSA_32,
+ .init = pl011_acpi_uart_init,
+ACPI_DEVICE_END
+
#endif
/*