summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/amba-pl011.c
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2015-05-21 18:26:21 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-05-24 22:08:51 +0200
commit71eec4836b834b992e0cefeefc8b85efe4cb185b (patch)
treedaa964b2f0b2ecaa0cc9ac08e4675cc0cc1f6de5 /drivers/tty/serial/amba-pl011.c
parentdrivers: PL011: move cts_event workaround into separate function (diff)
downloadlinux-71eec4836b834b992e0cefeefc8b85efe4cb185b.tar.xz
linux-71eec4836b834b992e0cefeefc8b85efe4cb185b.zip
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: Andre Przywara <andre.przywara@arm.com> Tested-by: Mark Langsdorf <mlangsdo@redhat.com> Tested-by: Naresh Bhat <nbhat@cavium.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/amba-pl011.c')
-rw-r--r--drivers/tty/serial/amba-pl011.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 7ecf3b380132..3f6b9150e575 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -78,6 +78,7 @@ struct vendor_data {
bool oversampling;
bool dma_threshold;
bool cts_event_workaround;
+ bool always_enabled;
unsigned int (*get_fifosize)(struct amba_device *dev);
};
@@ -94,6 +95,7 @@ static struct vendor_data vendor_arm = {
.oversampling = false,
.dma_threshold = false,
.cts_event_workaround = false,
+ .always_enabled = false,
.get_fifosize = get_fifosize_arm,
};
@@ -109,6 +111,7 @@ static struct vendor_data vendor_st = {
.oversampling = true,
.dma_threshold = true,
.cts_event_workaround = true,
+ .always_enabled = false,
.get_fifosize = get_fifosize_st,
};
@@ -1958,7 +1961,7 @@ static void
pl011_console_write(struct console *co, const char *s, unsigned int count)
{
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;
int locked = 1;
@@ -1975,10 +1978,12 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
/*
* First save the CR then disable the interrupts
*/
- old_cr = readw(uap->port.membase + UART011_CR);
- new_cr = old_cr & ~UART011_CR_CTSEN;
- new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
- writew(new_cr, uap->port.membase + UART011_CR);
+ if (!uap->vendor->always_enabled) {
+ old_cr = readw(uap->port.membase + UART011_CR);
+ new_cr = old_cr & ~UART011_CR_CTSEN;
+ 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);
@@ -1989,7 +1994,8 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
do {
status = readw(uap->port.membase + UART01x_FR);
} 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)
spin_unlock(&uap->port.lock);