aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2015-05-21 12:26:21 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-05-24 16:08:51 -0400
commit71eec4836b834b992e0cefeefc8b85efe4cb185b (patch)
treedaa964b2f0b2ecaa0cc9ac08e4675cc0cc1f6de5
parent9c4ef4b0301673c6fa48b5ad138b6ce94e34c841 (diff)
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>
-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 {
78 bool oversampling; 78 bool oversampling;
79 bool dma_threshold; 79 bool dma_threshold;
80 bool cts_event_workaround; 80 bool cts_event_workaround;
81 bool always_enabled;
81 82
82 unsigned int (*get_fifosize)(struct amba_device *dev); 83 unsigned int (*get_fifosize)(struct amba_device *dev);
83}; 84};
@@ -94,6 +95,7 @@ static struct vendor_data vendor_arm = {
94 .oversampling = false, 95 .oversampling = false,
95 .dma_threshold = false, 96 .dma_threshold = false,
96 .cts_event_workaround = false, 97 .cts_event_workaround = false,
98 .always_enabled = false,
97 .get_fifosize = get_fifosize_arm, 99 .get_fifosize = get_fifosize_arm,
98}; 100};
99 101
@@ -109,6 +111,7 @@ static struct vendor_data vendor_st = {
109 .oversampling = true, 111 .oversampling = true,
110 .dma_threshold = true, 112 .dma_threshold = true,
111 .cts_event_workaround = true, 113 .cts_event_workaround = true,
114 .always_enabled = false,
112 .get_fifosize = get_fifosize_st, 115 .get_fifosize = get_fifosize_st,
113}; 116};
114 117
@@ -1958,7 +1961,7 @@ static void
1958pl011_console_write(struct console *co, const char *s, unsigned int count) 1961pl011_console_write(struct console *co, const char *s, unsigned int count)
1959{ 1962{
1960 struct uart_amba_port *uap = amba_ports[co->index]; 1963 struct uart_amba_port *uap = amba_ports[co->index];
1961 unsigned int status, old_cr, new_cr; 1964 unsigned int status, old_cr = 0, new_cr;
1962 unsigned long flags; 1965 unsigned long flags;
1963 int locked = 1; 1966 int locked = 1;
1964 1967
@@ -1975,10 +1978,12 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
1975 /* 1978 /*
1976 * First save the CR then disable the interrupts 1979 * First save the CR then disable the interrupts
1977 */ 1980 */
1978 old_cr = readw(uap->port.membase + UART011_CR); 1981 if (!uap->vendor->always_enabled) {
1979 new_cr = old_cr & ~UART011_CR_CTSEN; 1982 old_cr = readw(uap->port.membase + UART011_CR);
1980 new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; 1983 new_cr = old_cr & ~UART011_CR_CTSEN;
1981 writew(new_cr, uap->port.membase + UART011_CR); 1984 new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
1985 writew(new_cr, uap->port.membase + UART011_CR);
1986 }
1982 1987
1983 uart_console_write(&uap->port, s, count, pl011_console_putchar); 1988 uart_console_write(&uap->port, s, count, pl011_console_putchar);
1984 1989
@@ -1989,7 +1994,8 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
1989 do { 1994 do {
1990 status = readw(uap->port.membase + UART01x_FR); 1995 status = readw(uap->port.membase + UART01x_FR);
1991 } while (status & UART01x_FR_BUSY); 1996 } while (status & UART01x_FR_BUSY);
1992 writew(old_cr, uap->port.membase + UART011_CR); 1997 if (!uap->vendor->always_enabled)
1998 writew(old_cr, uap->port.membase + UART011_CR);
1993 1999
1994 if (locked) 2000 if (locked)
1995 spin_unlock(&uap->port.lock); 2001 spin_unlock(&uap->port.lock);