Commit 71eec483 authored by Andre Przywara's avatar Andre Przywara Committed by Greg Kroah-Hartman

drivers: PL011: allow avoiding UART enabling/disabling

The SBSA UART should not be enabled or disabled (it is always on),
and consequently the spec lacks the UART_CR register.
Add a vendor specific property to skip disabling or enabling of the
UART. This will be used later by the SBSA UART support.
Signed-off-by: default avatarAndre Przywara <andre.przywara@arm.com>
Tested-by: default avatarMark Langsdorf <mlangsdo@redhat.com>
Tested-by: default avatarNaresh Bhat <nbhat@cavium.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9c4ef4b0
...@@ -78,6 +78,7 @@ struct vendor_data { ...@@ -78,6 +78,7 @@ struct vendor_data {
bool oversampling; bool oversampling;
bool dma_threshold; bool dma_threshold;
bool cts_event_workaround; bool cts_event_workaround;
bool always_enabled;
unsigned int (*get_fifosize)(struct amba_device *dev); unsigned int (*get_fifosize)(struct amba_device *dev);
}; };
...@@ -94,6 +95,7 @@ static struct vendor_data vendor_arm = { ...@@ -94,6 +95,7 @@ static struct vendor_data vendor_arm = {
.oversampling = false, .oversampling = false,
.dma_threshold = false, .dma_threshold = false,
.cts_event_workaround = false, .cts_event_workaround = false,
.always_enabled = false,
.get_fifosize = get_fifosize_arm, .get_fifosize = get_fifosize_arm,
}; };
...@@ -109,6 +111,7 @@ static struct vendor_data vendor_st = { ...@@ -109,6 +111,7 @@ static struct vendor_data vendor_st = {
.oversampling = true, .oversampling = true,
.dma_threshold = true, .dma_threshold = true,
.cts_event_workaround = true, .cts_event_workaround = true,
.always_enabled = false,
.get_fifosize = get_fifosize_st, .get_fifosize = get_fifosize_st,
}; };
...@@ -1958,7 +1961,7 @@ static void ...@@ -1958,7 +1961,7 @@ static void
pl011_console_write(struct console *co, const char *s, unsigned int count) pl011_console_write(struct console *co, const char *s, unsigned int count)
{ {
struct uart_amba_port *uap = amba_ports[co->index]; struct uart_amba_port *uap = amba_ports[co->index];
unsigned int status, old_cr, new_cr; unsigned int status, old_cr = 0, new_cr;
unsigned long flags; unsigned long flags;
int locked = 1; int locked = 1;
...@@ -1975,10 +1978,12 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) ...@@ -1975,10 +1978,12 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
/* /*
* First save the CR then disable the interrupts * First save the CR then disable the interrupts
*/ */
old_cr = readw(uap->port.membase + UART011_CR); if (!uap->vendor->always_enabled) {
new_cr = old_cr & ~UART011_CR_CTSEN; old_cr = readw(uap->port.membase + UART011_CR);
new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; new_cr = old_cr & ~UART011_CR_CTSEN;
writew(new_cr, uap->port.membase + UART011_CR); new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
writew(new_cr, uap->port.membase + UART011_CR);
}
uart_console_write(&uap->port, s, count, pl011_console_putchar); uart_console_write(&uap->port, s, count, pl011_console_putchar);
...@@ -1989,7 +1994,8 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) ...@@ -1989,7 +1994,8 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
do { do {
status = readw(uap->port.membase + UART01x_FR); status = readw(uap->port.membase + UART01x_FR);
} while (status & UART01x_FR_BUSY); } while (status & UART01x_FR_BUSY);
writew(old_cr, uap->port.membase + UART011_CR); if (!uap->vendor->always_enabled)
writew(old_cr, uap->port.membase + UART011_CR);
if (locked) if (locked)
spin_unlock(&uap->port.lock); spin_unlock(&uap->port.lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment