This will be pushed out in the -28 kernel a bit later today. I'll also spin up a new disk image for you that includes this kernel. If it works well for you/us in testing then I'll push it out with the monthly images.
On 05/09/2016 10:50 AM, Christopher Covington wrote:
Hi Jim,
On 05/09/2016 10:14 AM, Jim Perrin wrote:
Excellent, thanks! Does this patch include everything needed to boot the dev platform?
Yes this enables basic boot and shell prompt, including GIC, secondary CPUs, UART, SATA and PCI (using legacy interrupts).
The remaining failures in dmesg are as follows.
KVM: cause to be determined mlx4_core: peripheral firmware update needed PCI MSIs: familiar problem, might need another ACPI PCI backport
Thanks, Cov
On 05/09/2016 09:09 AM, Christopher Covington wrote:
Backport UART and GIC related patches, enabling the CentOS 7.2 AltArch kernel to run on the Qualcomm Technologies QDF2432 server development platform.
Signed-off-by: Christopher Covington cov@codeaurora.org
...mba-pl011-add-register-accessor-functions.patch | 718 +++++++++++++++++++++ ...011-convert-accessor-functions-to-take-ua.patch | 709 ++++++++++++++++++++ ...011-add-support-for-32-bit-register-acces.patch | 79 +++ ...011-use-iotype-instead-of-access_32b-to-t.patch | 119 ++++ ...a-pl011-Use-32-bit-accesses-for-SBSA-UART.patch | 29 + ...4006-irqchip-Fully-support-ACPI-GICv3-ITS.patch | 49 ++ ...-add-support-for-extended-IRQ-to-PCI-link.patch | 113 ++++ ...-v3-ACPI-Add-redistributor-support-via-GI.patch | 68 ++ SPECS/kernel-aarch64.spec | 25 +- 9 files changed, 1908 insertions(+), 1 deletion(-) create mode 100644 SOURCES/4001-tty-amba-pl011-add-register-accessor-functions.patch create mode 100644 SOURCES/4002-tty-amba-pl011-convert-accessor-functions-to-take-ua.patch create mode 100644 SOURCES/4003-tty-amba-pl011-add-support-for-32-bit-register-acces.patch create mode 100644 SOURCES/4004-tty-amba-pl011-use-iotype-instead-of-access_32b-to-t.patch create mode 100644 SOURCES/4005-tty-amba-pl011-Use-32-bit-accesses-for-SBSA-UART.patch create mode 100644 SOURCES/4006-irqchip-Fully-support-ACPI-GICv3-ITS.patch create mode 100644 SOURCES/4007-acpi-add-support-for-extended-IRQ-to-PCI-link.patch create mode 100644 SOURCES/4008-irqchip-gic-v3-ACPI-Add-redistributor-support-via-GI.patch
diff --git a/SOURCES/4001-tty-amba-pl011-add-register-accessor-functions.patch b/SOURCES/4001-tty-amba-pl011-add-register-accessor-functions.patch new file mode 100644 index 0000000..6fb4d0e --- /dev/null +++ b/SOURCES/4001-tty-amba-pl011-add-register-accessor-functions.patch @@ -0,0 +1,718 @@ +From: Russell King rmk+kernel@arm.linux.org.uk +Date: Tue, 3 Nov 2015 14:50:58 +0000 +Subject: tty: amba-pl011: add register accessor functions
+Add register accessor functions to amba-pl011. Much of this +transformation was done using the sed expression below, with any +left-overs fixed up manually afterwards, and code formatted to remain +within coding style.
+s/readw((uap->port.membase|regs|port->membase) +/pl011_read(\1,/g +s/writew((.*) +/pl011_write(\1,/g
+Signed-off-by: Russell King rmk+kernel@arm.linux.org.uk +Reviewed-by: Peter Hurley peter@hurleysoftware.com +Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
+Git-commit: 7583633921d54f33e96b65569a0c980ae1d05dba +Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git +---
- drivers/tty/serial/amba-pl011.c | 210 +++++++++++++++++++++-------------------
- 1 file changed, 112 insertions(+), 98 deletions(-)
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index fd27e98..b75f750 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -184,6 +184,16 @@ struct uart_amba_port {
- #endif
- };
++static unsigned int pl011_read(void __iomem *base, unsigned int reg) ++{ ++ return readw(base + reg); ++} ++ ++static void pl011_write(unsigned int val, void __iomem *base, unsigned int reg) ++{ ++ writew(val, base + reg); ++} ++
- /*
- Reads up to 256 characters from the FIFO or until it's empty and
- inserts them into the TTY layer. Returns the number of characters
+@@ -196,12 +206,12 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap)
- int fifotaken = 0;
- while (max_count--) {
+- status = readw(uap->port.membase + UART01x_FR); ++ status = pl011_read(uap->port.membase, UART01x_FR);
if (status & UART01x_FR_RXFE)
break;
/* Take chars from the FIFO and update status */
+- ch = readw(uap->port.membase + UART01x_DR) | ++ ch = pl011_read(uap->port.membase, UART01x_DR) |
UART_DUMMY_DR_RX;
flag = TTY_NORMAL;
uap->port.icount.rx++;
+@@ -438,7 +448,7 @@ static void pl011_dma_tx_callback(void *data)
- dmacr = uap->dmacr;
- uap->dmacr = dmacr & ~UART011_TXDMAE;
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
- /*
* If TX DMA was disabled, it means that we've stopped the DMA for
+@@ -552,7 +562,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap)
- dma_dev->device_issue_pending(chan);
- uap->dmacr |= UART011_TXDMAE;
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
- uap->dmatx.queued = true;
- /*
+@@ -588,9 +598,9 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap)
*/
- if (uap->dmatx.queued) {
uap->dmacr |= UART011_TXDMAE;
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
uap->im &= ~UART011_TXIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
return true;
- }
+@@ -600,7 +610,7 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap)
*/
- if (pl011_dma_tx_refill(uap) > 0) {
uap->im &= ~UART011_TXIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
return true;
- }
- return false;
+@@ -614,7 +624,7 @@ static inline void pl011_dma_tx_stop(struct uart_amba_port *uap)
- {
- if (uap->dmatx.queued) {
uap->dmacr &= ~UART011_TXDMAE;
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
- }
- }
+@@ -640,14 +650,14 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
if (!uap->dmatx.queued) {
if (pl011_dma_tx_refill(uap) > 0) {
uap->im &= ~UART011_TXIM;
+- writew(uap->im, uap->port.membase + +- UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, ++ UART011_IMSC);
} else
ret = false;
} else if (!(uap->dmacr & UART011_TXDMAE)) {
uap->dmacr |= UART011_TXDMAE;
+- writew(uap->dmacr, +- uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, ++ UART011_DMACR);
}
return ret;
- }
+@@ -658,9 +668,9 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
*/
- dmacr = uap->dmacr;
- uap->dmacr &= ~UART011_TXDMAE;
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
+- if (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) { ++ if (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) {
/*
* No space in the FIFO, so enable the transmit interrupt
* so we know when there is space. Note that once we've
+@@ -669,13 +679,13 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
return false;
- }
+- writew(uap->port.x_char, uap->port.membase + UART01x_DR); ++ pl011_write(uap->port.x_char, uap->port.membase, UART01x_DR);
- uap->port.icount.tx++;
- uap->port.x_char = 0;
- /* Success - restore the DMA state */
- uap->dmacr = dmacr;
+- writew(dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(dmacr, uap->port.membase, UART011_DMACR);
- return true;
- }
+@@ -703,7 +713,7 @@ __acquires(&uap->port.lock)
DMA_TO_DEVICE);
uap->dmatx.queued = false;
uap->dmacr &= ~UART011_TXDMAE;
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
- }
- }
+@@ -743,11 +753,11 @@ static int pl011_dma_rx_trigger_dma(struct uart_amba_port *uap)
- dma_async_issue_pending(rxchan);
- uap->dmacr |= UART011_RXDMAE;
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
- uap->dmarx.running = true;
- uap->im &= ~UART011_RXIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
- return 0;
- }
+@@ -805,8 +815,8 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap,
*/
- if (dma_count == pending && readfifo) {
/* Clear any error flags */
+- writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS, +- uap->port.membase + UART011_ICR); ++ pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | ++ UART011_FEIS, uap->port.membase, UART011_ICR);
/*
* If we read all the DMA'd characters, and we had an
+@@ -854,7 +864,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap)
- /* Disable RX DMA - incoming data will wait in the FIFO */
- uap->dmacr &= ~UART011_RXDMAE;
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
- uap->dmarx.running = false;
- pending = sgbuf->sg.length - state.residue;
+@@ -874,7 +884,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap)
dev_dbg(uap->port.dev, "could not retrigger RX DMA job "
"fall back to interrupt mode\n");
uap->im |= UART011_RXIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
- }
- }
+@@ -922,7 +932,7 @@ static void pl011_dma_rx_callback(void *data)
dev_dbg(uap->port.dev, "could not retrigger RX DMA job "
"fall back to interrupt mode\n");
uap->im |= UART011_RXIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
- }
- }
+@@ -935,7 +945,7 @@ static inline void pl011_dma_rx_stop(struct uart_amba_port *uap)
- {
- /* FIXME. Just disable the DMA enable */
- uap->dmacr &= ~UART011_RXDMAE;
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
- }
- /*
+@@ -979,7 +989,7 @@ static void pl011_dma_rx_poll(unsigned long args)
spin_lock_irqsave(&uap->port.lock, flags);
pl011_dma_rx_stop(uap);
uap->im |= UART011_RXIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
spin_unlock_irqrestore(&uap->port.lock, flags);
uap->dmarx.running = false;
+@@ -1041,7 +1051,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap)
- skip_rx:
- /* Turn on DMA error (RX/TX will be enabled on demand) */
- uap->dmacr |= UART011_DMAONERR;
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
- /*
* ST Micro variants has some specific dma burst threshold
+@@ -1049,8 +1059,8 @@ skip_rx:
* be issued above/below 16 bytes.
*/
- if (uap->vendor->dma_threshold)
+- writew(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16, +- uap->port.membase + ST_UART011_DMAWM); ++ pl011_write(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16, ++ uap->port.membase, ST_UART011_DMAWM);
- if (uap->using_rx_dma) {
if (pl011_dma_rx_trigger_dma(uap))
+@@ -1075,12 +1085,12 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap)
return;
- /* Disable RX and TX DMA */
+- while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) ++ while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_BUSY)
barrier();
- spin_lock_irq(&uap->port.lock);
- uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE);
+- writew(uap->dmacr, uap->port.membase + UART011_DMACR); ++ pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR);
- spin_unlock_irq(&uap->port.lock);
- if (uap->using_tx_dma) {
+@@ -1181,7 +1191,7 @@ static void pl011_stop_tx(struct uart_port *port)
container_of(port, struct uart_amba_port, port);
- uap->im &= ~UART011_TXIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
- pl011_dma_tx_stop(uap);
- }
+@@ -1191,7 +1201,7 @@ static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq);
- static void pl011_start_tx_pio(struct uart_amba_port *uap)
- {
- uap->im |= UART011_TXIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
- pl011_tx_chars(uap, false);
- }
+@@ -1211,7 +1221,7 @@ static void pl011_stop_rx(struct uart_port *port)
- uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM|
UART011_PEIM|UART011_BEIM|UART011_OEIM);
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
- pl011_dma_rx_stop(uap);
- }
+@@ -1222,7 +1232,7 @@ static void pl011_enable_ms(struct uart_port *port)
container_of(port, struct uart_amba_port, port);
- uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
- }
- static void pl011_rx_chars(struct uart_amba_port *uap)
+@@ -1242,7 +1252,7 @@ __acquires(&uap->port.lock)
dev_dbg(uap->port.dev, "could not trigger RX DMA job "
"fall back to interrupt mode again\n");
uap->im |= UART011_RXIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
} else {
- #ifdef CONFIG_DMA_ENGINE
/* Start Rx DMA poll */
+@@ -1263,10 +1273,10 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c,
bool from_irq)
- {
- if (unlikely(!from_irq) &&
+- readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) ++ pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF)
return false; /* unable to transmit character */
+- writew(c, uap->port.membase + UART01x_DR); ++ pl011_write(c, uap->port.membase, UART01x_DR);
- uap->port.icount.tx++;
- return true;
+@@ -1313,7 +1323,8 @@ static void pl011_modem_status(struct uart_amba_port *uap)
- {
- unsigned int status, delta;
+- status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; ++ status = pl011_read(uap->port.membase, UART01x_FR); ++ status &= UART01x_FR_MODEM_ANY;
- delta = status ^ uap->old_status;
- uap->old_status = status;
+@@ -1341,15 +1352,15 @@ static void check_apply_cts_event_workaround(struct uart_amba_port *uap)
return;
- /* workaround to make sure that all bits are unlocked.. */
+- writew(0x00, uap->port.membase + UART011_ICR); ++ pl011_write(0x00, uap->port.membase, UART011_ICR);
- /*
* WA: introduce 26ns(1 uart clk) delay before W1C;
* single apb access will incur 2 pclk(133.12Mhz) delay,
* so add 2 dummy reads
*/
+- dummy_read = readw(uap->port.membase + UART011_ICR); +- dummy_read = readw(uap->port.membase + UART011_ICR); ++ dummy_read = pl011_read(uap->port.membase, UART011_ICR); ++ dummy_read = pl011_read(uap->port.membase, UART011_ICR);
- }
- static irqreturn_t pl011_int(int irq, void *dev_id)
+@@ -1361,15 +1372,15 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
- int handled = 0;
- spin_lock_irqsave(&uap->port.lock, flags);
+- imsc = readw(uap->port.membase + UART011_IMSC); +- status = readw(uap->port.membase + UART011_RIS) & imsc; ++ imsc = pl011_read(uap->port.membase, UART011_IMSC); ++ status = pl011_read(uap->port.membase, UART011_RIS) & imsc;
- if (status) {
do {
check_apply_cts_event_workaround(uap);
+- writew(status & ~(UART011_TXIS|UART011_RTIS| +- UART011_RXIS), +- uap->port.membase + UART011_ICR); ++ pl011_write(status & ~(UART011_TXIS|UART011_RTIS| ++ UART011_RXIS), ++ uap->port.membase, UART011_ICR);
if (status & (UART011_RTIS|UART011_RXIS)) {
if (pl011_dma_rx_running(uap))
+@@ -1386,7 +1397,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
if (pass_counter-- == 0)
break;
+- status = readw(uap->port.membase + UART011_RIS) & imsc; ++ status = pl011_read(uap->port.membase, UART011_RIS) & imsc;
} while (status != 0);
handled = 1;
- }
+@@ -1400,7 +1411,7 @@ static unsigned int pl011_tx_empty(struct uart_port *port)
- {
- struct uart_amba_port *uap =
container_of(port, struct uart_amba_port, port);
+- unsigned int status = readw(uap->port.membase + UART01x_FR); ++ unsigned int status = pl011_read(uap->port.membase, UART01x_FR);
- return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT;
- }
+@@ -1409,7 +1420,7 @@ static unsigned int pl011_get_mctrl(struct uart_port *port)
- struct uart_amba_port *uap =
container_of(port, struct uart_amba_port, port);
- unsigned int result = 0;
+- unsigned int status = readw(uap->port.membase + UART01x_FR); ++ unsigned int status = pl011_read(uap->port.membase, UART01x_FR);
- #define TIOCMBIT(uartbit, tiocmbit) \
- if (status & uartbit) \
+@@ -1429,7 +1440,7 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl)
container_of(port, struct uart_amba_port, port);
- unsigned int cr;
+- cr = readw(uap->port.membase + UART011_CR); ++ cr = pl011_read(uap->port.membase, UART011_CR);
- #define TIOCMBIT(tiocmbit, uartbit) \
- if (mctrl & tiocmbit) \
+@@ -1449,7 +1460,7 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl)
- }
- #undef TIOCMBIT
+- writew(cr, uap->port.membase + UART011_CR); ++ pl011_write(cr, uap->port.membase, UART011_CR);
- }
- static void pl011_break_ctl(struct uart_port *port, int break_state)
+@@ -1460,12 +1471,12 @@ static void pl011_break_ctl(struct uart_port *port, int break_state)
- unsigned int lcr_h;
- spin_lock_irqsave(&uap->port.lock, flags);
+- lcr_h = readw(uap->port.membase + uap->lcrh_tx); ++ lcr_h = pl011_read(uap->port.membase, uap->lcrh_tx);
- if (break_state == -1)
lcr_h |= UART01x_LCRH_BRK;
- else
lcr_h &= ~UART01x_LCRH_BRK;
+- writew(lcr_h, uap->port.membase + uap->lcrh_tx); ++ pl011_write(lcr_h, uap->port.membase, uap->lcrh_tx);
- spin_unlock_irqrestore(&uap->port.lock, flags);
- }
+@@ -1477,7 +1488,7 @@ static void pl011_quiesce_irqs(struct uart_port *port)
container_of(port, struct uart_amba_port, port);
- unsigned char __iomem *regs = uap->port.membase;
+- writew(readw(regs + UART011_MIS), regs + UART011_ICR); ++ pl011_write(pl011_read(regs, UART011_MIS), regs, UART011_ICR);
- /*
* There is no way to clear TXIM as this is "ready to transmit IRQ", so
* we simply mask it. start_tx() will unmask it.
+@@ -1491,7 +1502,8 @@ static void pl011_quiesce_irqs(struct uart_port *port)
* (including tx queue), so we're also fine with start_tx()'s caller
* side.
*/
+- writew(readw(regs + UART011_IMSC) & ~UART011_TXIM, regs + UART011_IMSC); ++ pl011_write(pl011_read(regs, UART011_IMSC) & ~UART011_TXIM, ++ regs, UART011_IMSC);
- }
- static int pl011_get_poll_char(struct uart_port *port)
+@@ -1506,11 +1518,11 @@ static int pl011_get_poll_char(struct uart_port *port)
*/
- pl011_quiesce_irqs(port);
+- status = readw(uap->port.membase + UART01x_FR); ++ status = pl011_read(uap->port.membase, UART01x_FR);
- if (status & UART01x_FR_RXFE)
return NO_POLL_CHAR;
+- return readw(uap->port.membase + UART01x_DR); ++ return pl011_read(uap->port.membase, UART01x_DR);
- }
- static void pl011_put_poll_char(struct uart_port *port,
+@@ -1519,10 +1531,10 @@ static void pl011_put_poll_char(struct uart_port *port,
- struct uart_amba_port *uap =
container_of(port, struct uart_amba_port, port);
+- while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) ++ while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF)
barrier();
+- writew(ch, uap->port.membase + UART01x_DR); ++ pl011_write(ch, uap->port.membase, UART01x_DR);
- }
- #endif /* CONFIG_CONSOLE_POLL */
+@@ -1546,15 +1558,17 @@ static int pl011_hwinit(struct uart_port *port)
- uap->port.uartclk = clk_get_rate(uap->clk);
- /* Clear pending error and receive interrupts */
+- writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS | +- UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR); ++ pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | ++ UART011_FEIS | UART011_RTIS | UART011_RXIS, ++ uap->port.membase, UART011_ICR);
- /*
* Save interrupts enable mask, and enable RX interrupts in case if
* the interrupt is used for NMI entry.
*/
+- uap->im = readw(uap->port.membase + UART011_IMSC); +- writew(UART011_RTIM | UART011_RXIM, uap->port.membase + UART011_IMSC); ++ uap->im = pl011_read(uap->port.membase, UART011_IMSC); ++ pl011_write(UART011_RTIM | UART011_RXIM, uap->port.membase, ++ UART011_IMSC);
- if (dev_get_platdata(uap->port.dev)) {
struct amba_pl011_data *plat;
+@@ -1568,7 +1582,7 @@ static int pl011_hwinit(struct uart_port *port)
- static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h)
- {
+- writew(lcr_h, uap->port.membase + uap->lcrh_rx); ++ pl011_write(lcr_h, uap->port.membase, uap->lcrh_rx);
- if (uap->lcrh_rx != uap->lcrh_tx) {
int i;
/*
+@@ -1576,14 +1590,14 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h)
* to get this delay write read only register 10 times
*/
for (i = 0; i < 10; ++i)
+- writew(0xff, uap->port.membase + UART011_MIS); +- writew(lcr_h, uap->port.membase + uap->lcrh_tx); ++ pl011_write(0xff, uap->port.membase, UART011_MIS); ++ pl011_write(lcr_h, uap->port.membase, uap->lcrh_tx);
- }
- }
- static int pl011_allocate_irq(struct uart_amba_port *uap)
- {
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
- return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
- }
+@@ -1598,12 +1612,12 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
- spin_lock_irq(&uap->port.lock);
- /* Clear out any spuriously appearing RX interrupts */
+- writew(UART011_RTIS | UART011_RXIS, +- uap->port.membase + UART011_ICR); ++ pl011_write(UART011_RTIS | UART011_RXIS, uap->port.membase, ++ UART011_ICR);
- uap->im = UART011_RTIM;
- if (!pl011_dma_rx_running(uap))
uap->im |= UART011_RXIM;
+- writew(uap->im, uap->port.membase + UART011_IMSC); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC);
- spin_unlock_irq(&uap->port.lock);
- }
+@@ -1622,21 +1636,21 @@ static int pl011_startup(struct uart_port *port)
- if (retval)
goto clk_dis;
+- writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); ++ pl011_write(uap->vendor->ifls, uap->port.membase, UART011_IFLS);
- spin_lock_irq(&uap->port.lock);
- /* restore RTS and DTR */
- cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR);
- cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
+- writew(cr, uap->port.membase + UART011_CR); ++ pl011_write(cr, uap->port.membase, UART011_CR);
- spin_unlock_irq(&uap->port.lock);
- /*
* initialise the old status of the modem signals
*/
+- uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; ++ uap->old_status = pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_MODEM_ANY;
- /* Startup DMA */
- pl011_dma_startup(uap);
+@@ -1677,9 +1691,9 @@ static void pl011_shutdown_channel(struct uart_amba_port *uap,
- {
unsigned long val;
+- val = readw(uap->port.membase + lcrh); ++ val = pl011_read(uap->port.membase, lcrh);
val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN);
+- writew(val, uap->port.membase + lcrh); ++ pl011_write(val, uap->port.membase, lcrh);
- }
- /*
+@@ -1693,11 +1707,11 @@ static void pl011_disable_uart(struct uart_amba_port *uap)
- uap->autorts = false;
- spin_lock_irq(&uap->port.lock);
+- cr = readw(uap->port.membase + UART011_CR); ++ cr = pl011_read(uap->port.membase, UART011_CR);
- uap->old_cr = cr;
- cr &= UART011_CR_RTS | UART011_CR_DTR;
- cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
+- writew(cr, uap->port.membase + UART011_CR); ++ pl011_write(cr, uap->port.membase, UART011_CR);
- spin_unlock_irq(&uap->port.lock);
- /*
+@@ -1714,8 +1728,8 @@ static void pl011_disable_interrupts(struct uart_amba_port *uap)
- /* mask all interrupts and clear all pending ones */
- uap->im = 0;
+- writew(uap->im, uap->port.membase + UART011_IMSC); +- writew(0xffff, uap->port.membase + UART011_ICR); ++ pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(0xffff, uap->port.membase, UART011_ICR);
- spin_unlock_irq(&uap->port.lock);
- }
+@@ -1867,8 +1881,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
pl011_enable_ms(port);
- /* first, disable everything */
+- old_cr = readw(port->membase + UART011_CR); +- writew(0, port->membase + UART011_CR); ++ old_cr = pl011_read(port->membase, UART011_CR); ++ pl011_write(0, port->membase, UART011_CR);
- if (termios->c_cflag & CRTSCTS) {
if (old_cr & UART011_CR_RTS)
+@@ -1901,8 +1915,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
quot -= 2;
- }
- /* Set baud rate */
+- writew(quot & 0x3f, port->membase + UART011_FBRD); +- writew(quot >> 6, port->membase + UART011_IBRD); ++ pl011_write(quot & 0x3f, port->membase, UART011_FBRD); ++ pl011_write(quot >> 6, port->membase, UART011_IBRD);
- /*
* ----------v----------v----------v----------v-----
+@@ -1911,7 +1925,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
* ----------^----------^----------^----------^-----
*/
- pl011_write_lcr_h(uap, lcr_h);
+- writew(old_cr, port->membase + UART011_CR); ++ pl011_write(old_cr, port->membase, UART011_CR);
- spin_unlock_irqrestore(&port->lock, flags);
- }
+@@ -2052,9 +2066,9 @@ static void pl011_console_putchar(struct uart_port *port, int ch)
- struct uart_amba_port *uap =
container_of(port, struct uart_amba_port, port);
+- while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) ++ while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF)
barrier();
+- writew(ch, uap->port.membase + UART01x_DR); ++ pl011_write(ch, uap->port.membase, UART01x_DR);
- }
- static void
+@@ -2079,10 +2093,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
* First save the CR then disable the interrupts
*/
- if (!uap->vendor->always_enabled) {
+- old_cr = readw(uap->port.membase + UART011_CR); ++ old_cr = pl011_read(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); ++ pl011_write(new_cr, uap->port.membase, UART011_CR);
- }
- uart_console_write(&uap->port, s, count, pl011_console_putchar);
+@@ -2092,10 +2106,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
* and restore the TCR
*/
- do {
+- status = readw(uap->port.membase + UART01x_FR); ++ status = pl011_read(uap->port.membase, UART01x_FR);
- } while (status & UART01x_FR_BUSY);
- if (!uap->vendor->always_enabled)
+- writew(old_cr, uap->port.membase + UART011_CR); ++ pl011_write(old_cr, uap->port.membase, UART011_CR);
- if (locked)
spin_unlock(&uap->port.lock);
+@@ -2108,10 +2122,10 @@ static void __init
- pl011_console_get_options(struct uart_amba_port *uap, int *baud,
int *parity, int *bits)
- {
+- if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) { ++ if (pl011_read(uap->port.membase, UART011_CR) & UART01x_CR_UARTEN) {
unsigned int lcr_h, ibrd, fbrd;
+- lcr_h = readw(uap->port.membase + uap->lcrh_tx); ++ lcr_h = pl011_read(uap->port.membase, uap->lcrh_tx);
*parity = 'n';
if (lcr_h & UART01x_LCRH_PEN) {
+@@ -2126,13 +2140,13 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud,
else
*bits = 8;
+- ibrd = readw(uap->port.membase + UART011_IBRD); +- fbrd = readw(uap->port.membase + UART011_FBRD); ++ ibrd = pl011_read(uap->port.membase, UART011_IBRD); ++ fbrd = pl011_read(uap->port.membase, UART011_FBRD);
*baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd);
if (uap->vendor->oversampling) {
+- if (readw(uap->port.membase + UART011_CR) ++ if (pl011_read(uap->port.membase, UART011_CR)
& ST_UART011_CR_OVSFACT)
*baud *= 2;
}
+@@ -2334,8 +2348,8 @@ static int pl011_register_port(struct uart_amba_port *uap)
- int ret;
- /* Ensure interrupts from this UART are masked and cleared */
+- writew(0, uap->port.membase + UART011_IMSC); +- writew(0xffff, uap->port.membase + UART011_ICR); ++ pl011_write(0, uap->port.membase, UART011_IMSC); ++ pl011_write(0xffff, uap->port.membase, UART011_ICR);
- if (!amba_reg.state) {
ret = uart_register_driver(&amba_reg);
diff --git a/SOURCES/4002-tty-amba-pl011-convert-accessor-functions-to-take-ua.patch b/SOURCES/4002-tty-amba-pl011-convert-accessor-functions-to-take-ua.patch new file mode 100644 index 0000000..6524bda --- /dev/null +++ b/SOURCES/4002-tty-amba-pl011-convert-accessor-functions-to-take-ua.patch @@ -0,0 +1,709 @@ +From: Russell King rmk+kernel@arm.linux.org.uk +Date: Tue, 3 Nov 2015 14:51:03 +0000 +Subject: tty: amba-pl011: convert accessor functions to take uart_amba_port
+Convert the new accessor functions to take the uart_amba_port instead +of the port base address.
+Signed-off-by: Russell King rmk+kernel@arm.linux.org.uk +Reviewed-by: Peter Hurley peter@hurleysoftware.com +Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
+Git-commit: b2a4e24c2efd76a2c25478836fb35951e00d5b52 +Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git +---
- drivers/tty/serial/amba-pl011.c | 199 ++++++++++++++++++++--------------------
- 1 file changed, 97 insertions(+), 102 deletions(-)
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index b75f750..61512af 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -184,14 +184,16 @@ struct uart_amba_port {
- #endif
- };
+-static unsigned int pl011_read(void __iomem *base, unsigned int reg) ++static unsigned int pl011_read(const struct uart_amba_port *uap, ++ unsigned int reg)
- {
+- return readw(base + reg); ++ return readw(uap->port.membase + reg);
- }
+-static void pl011_write(unsigned int val, void __iomem *base, unsigned int reg) ++static void pl011_write(unsigned int val, const struct uart_amba_port *uap, ++ unsigned int reg)
- {
+- writew(val, base + reg); ++ writew(val, uap->port.membase + reg);
- }
- /*
+@@ -206,13 +208,12 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap)
- int fifotaken = 0;
- while (max_count--) {
+- status = pl011_read(uap->port.membase, UART01x_FR); ++ status = pl011_read(uap, UART01x_FR);
if (status & UART01x_FR_RXFE)
break;
/* Take chars from the FIFO and update status */
+- ch = pl011_read(uap->port.membase, UART01x_DR) | +- UART_DUMMY_DR_RX; ++ ch = pl011_read(uap, UART01x_DR) | UART_DUMMY_DR_RX;
flag = TTY_NORMAL;
uap->port.icount.rx++;
fifotaken++;
+@@ -448,7 +449,7 @@ static void pl011_dma_tx_callback(void *data)
- dmacr = uap->dmacr;
- uap->dmacr = dmacr & ~UART011_TXDMAE;
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
- /*
* If TX DMA was disabled, it means that we've stopped the DMA for
+@@ -562,7 +563,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap)
- dma_dev->device_issue_pending(chan);
- uap->dmacr |= UART011_TXDMAE;
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
- uap->dmatx.queued = true;
- /*
+@@ -598,9 +599,9 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap)
*/
- if (uap->dmatx.queued) {
uap->dmacr |= UART011_TXDMAE;
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
uap->im &= ~UART011_TXIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
return true;
- }
+@@ -610,7 +611,7 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap)
*/
- if (pl011_dma_tx_refill(uap) > 0) {
uap->im &= ~UART011_TXIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
return true;
- }
- return false;
+@@ -624,7 +625,7 @@ static inline void pl011_dma_tx_stop(struct uart_amba_port *uap)
- {
- if (uap->dmatx.queued) {
uap->dmacr &= ~UART011_TXDMAE;
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
- }
- }
+@@ -650,14 +651,12 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
if (!uap->dmatx.queued) {
if (pl011_dma_tx_refill(uap) > 0) {
uap->im &= ~UART011_TXIM;
+- pl011_write(uap->im, uap->port.membase, +- UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
} else
ret = false;
} else if (!(uap->dmacr & UART011_TXDMAE)) {
uap->dmacr |= UART011_TXDMAE;
+- pl011_write(uap->dmacr, uap->port.membase, +- UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
}
return ret;
- }
+@@ -668,9 +667,9 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
*/
- dmacr = uap->dmacr;
- uap->dmacr &= ~UART011_TXDMAE;
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
+- if (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) { ++ if (pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF) {
/*
* No space in the FIFO, so enable the transmit interrupt
* so we know when there is space. Note that once we've
+@@ -679,13 +678,13 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
return false;
- }
+- pl011_write(uap->port.x_char, uap->port.membase, UART01x_DR); ++ pl011_write(uap->port.x_char, uap, UART01x_DR);
- uap->port.icount.tx++;
- uap->port.x_char = 0;
- /* Success - restore the DMA state */
- uap->dmacr = dmacr;
+- pl011_write(dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(dmacr, uap, UART011_DMACR);
- return true;
- }
+@@ -713,7 +712,7 @@ __acquires(&uap->port.lock)
DMA_TO_DEVICE);
uap->dmatx.queued = false;
uap->dmacr &= ~UART011_TXDMAE;
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
- }
- }
+@@ -753,11 +752,11 @@ static int pl011_dma_rx_trigger_dma(struct uart_amba_port *uap)
- dma_async_issue_pending(rxchan);
- uap->dmacr |= UART011_RXDMAE;
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
- uap->dmarx.running = true;
- uap->im &= ~UART011_RXIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
- return 0;
- }
+@@ -816,7 +815,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap,
- if (dma_count == pending && readfifo) {
/* Clear any error flags */
pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS |
+- UART011_FEIS, uap->port.membase, UART011_ICR); ++ UART011_FEIS, uap, UART011_ICR);
/*
* If we read all the DMA'd characters, and we had an
+@@ -864,7 +863,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap)
- /* Disable RX DMA - incoming data will wait in the FIFO */
- uap->dmacr &= ~UART011_RXDMAE;
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
- uap->dmarx.running = false;
- pending = sgbuf->sg.length - state.residue;
+@@ -884,7 +883,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap)
dev_dbg(uap->port.dev, "could not retrigger RX DMA job "
"fall back to interrupt mode\n");
uap->im |= UART011_RXIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
- }
- }
+@@ -932,7 +931,7 @@ static void pl011_dma_rx_callback(void *data)
dev_dbg(uap->port.dev, "could not retrigger RX DMA job "
"fall back to interrupt mode\n");
uap->im |= UART011_RXIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
- }
- }
+@@ -945,7 +944,7 @@ static inline void pl011_dma_rx_stop(struct uart_amba_port *uap)
- {
- /* FIXME. Just disable the DMA enable */
- uap->dmacr &= ~UART011_RXDMAE;
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
- }
- /*
+@@ -989,7 +988,7 @@ static void pl011_dma_rx_poll(unsigned long args)
spin_lock_irqsave(&uap->port.lock, flags);
pl011_dma_rx_stop(uap);
uap->im |= UART011_RXIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
spin_unlock_irqrestore(&uap->port.lock, flags);
uap->dmarx.running = false;
+@@ -1051,7 +1050,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap)
- skip_rx:
- /* Turn on DMA error (RX/TX will be enabled on demand) */
- uap->dmacr |= UART011_DMAONERR;
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
- /*
* ST Micro variants has some specific dma burst threshold
+@@ -1060,7 +1059,7 @@ skip_rx:
*/
- if (uap->vendor->dma_threshold)
pl011_write(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16,
+- uap->port.membase, ST_UART011_DMAWM); ++ uap, ST_UART011_DMAWM);
- if (uap->using_rx_dma) {
if (pl011_dma_rx_trigger_dma(uap))
+@@ -1085,12 +1084,12 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap)
return;
- /* Disable RX and TX DMA */
+- while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_BUSY) ++ while (pl011_read(uap, UART01x_FR) & UART01x_FR_BUSY)
barrier();
- spin_lock_irq(&uap->port.lock);
- uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE);
+- pl011_write(uap->dmacr, uap->port.membase, UART011_DMACR); ++ pl011_write(uap->dmacr, uap, UART011_DMACR);
- spin_unlock_irq(&uap->port.lock);
- if (uap->using_tx_dma) {
+@@ -1191,7 +1190,7 @@ static void pl011_stop_tx(struct uart_port *port)
container_of(port, struct uart_amba_port, port);
- uap->im &= ~UART011_TXIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
- pl011_dma_tx_stop(uap);
- }
+@@ -1201,7 +1200,7 @@ static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq);
- static void pl011_start_tx_pio(struct uart_amba_port *uap)
- {
- uap->im |= UART011_TXIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
- pl011_tx_chars(uap, false);
- }
+@@ -1221,7 +1220,7 @@ static void pl011_stop_rx(struct uart_port *port)
- uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM|
UART011_PEIM|UART011_BEIM|UART011_OEIM);
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
- pl011_dma_rx_stop(uap);
- }
+@@ -1232,7 +1231,7 @@ static void pl011_enable_ms(struct uart_port *port)
container_of(port, struct uart_amba_port, port);
- uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
- }
- static void pl011_rx_chars(struct uart_amba_port *uap)
+@@ -1252,7 +1251,7 @@ __acquires(&uap->port.lock)
dev_dbg(uap->port.dev, "could not trigger RX DMA job "
"fall back to interrupt mode again\n");
uap->im |= UART011_RXIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
} else {
- #ifdef CONFIG_DMA_ENGINE
/* Start Rx DMA poll */
+@@ -1273,10 +1272,10 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c,
bool from_irq)
- {
- if (unlikely(!from_irq) &&
+- pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) ++ pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF)
return false; /* unable to transmit character */
+- pl011_write(c, uap->port.membase, UART01x_DR); ++ pl011_write(c, uap, UART01x_DR);
- uap->port.icount.tx++;
- return true;
+@@ -1323,8 +1322,7 @@ static void pl011_modem_status(struct uart_amba_port *uap)
- {
- unsigned int status, delta;
+- status = pl011_read(uap->port.membase, UART01x_FR); +- status &= UART01x_FR_MODEM_ANY; ++ status = pl011_read(uap, UART01x_FR) & UART01x_FR_MODEM_ANY;
- delta = status ^ uap->old_status;
- uap->old_status = status;
+@@ -1352,15 +1350,15 @@ static void check_apply_cts_event_workaround(struct uart_amba_port *uap)
return;
- /* workaround to make sure that all bits are unlocked.. */
+- pl011_write(0x00, uap->port.membase, UART011_ICR); ++ pl011_write(0x00, uap, UART011_ICR);
- /*
* WA: introduce 26ns(1 uart clk) delay before W1C;
* single apb access will incur 2 pclk(133.12Mhz) delay,
* so add 2 dummy reads
*/
+- dummy_read = pl011_read(uap->port.membase, UART011_ICR); +- dummy_read = pl011_read(uap->port.membase, UART011_ICR); ++ dummy_read = pl011_read(uap, UART011_ICR); ++ dummy_read = pl011_read(uap, UART011_ICR);
- }
- static irqreturn_t pl011_int(int irq, void *dev_id)
+@@ -1372,15 +1370,15 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
- int handled = 0;
- spin_lock_irqsave(&uap->port.lock, flags);
+- imsc = pl011_read(uap->port.membase, UART011_IMSC); +- status = pl011_read(uap->port.membase, UART011_RIS) & imsc; ++ imsc = pl011_read(uap, UART011_IMSC); ++ status = pl011_read(uap, UART011_RIS) & imsc;
- if (status) {
do {
check_apply_cts_event_workaround(uap);
pl011_write(status & ~(UART011_TXIS|UART011_RTIS|
UART011_RXIS),
+- uap->port.membase, UART011_ICR); ++ uap, UART011_ICR);
if (status & (UART011_RTIS|UART011_RXIS)) {
if (pl011_dma_rx_running(uap))
+@@ -1397,7 +1395,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
if (pass_counter-- == 0)
break;
+- status = pl011_read(uap->port.membase, UART011_RIS) & imsc; ++ status = pl011_read(uap, UART011_RIS) & imsc;
} while (status != 0);
handled = 1;
- }
+@@ -1411,7 +1409,7 @@ static unsigned int pl011_tx_empty(struct uart_port *port)
- {
- struct uart_amba_port *uap =
container_of(port, struct uart_amba_port, port);
+- unsigned int status = pl011_read(uap->port.membase, UART01x_FR); ++ unsigned int status = pl011_read(uap, UART01x_FR);
- return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT;
- }
+@@ -1420,7 +1418,7 @@ static unsigned int pl011_get_mctrl(struct uart_port *port)
- struct uart_amba_port *uap =
container_of(port, struct uart_amba_port, port);
- unsigned int result = 0;
+- unsigned int status = pl011_read(uap->port.membase, UART01x_FR); ++ unsigned int status = pl011_read(uap, UART01x_FR);
- #define TIOCMBIT(uartbit, tiocmbit) \
- if (status & uartbit) \
+@@ -1440,7 +1438,7 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl)
container_of(port, struct uart_amba_port, port);
- unsigned int cr;
+- cr = pl011_read(uap->port.membase, UART011_CR); ++ cr = pl011_read(uap, UART011_CR);
- #define TIOCMBIT(tiocmbit, uartbit) \
- if (mctrl & tiocmbit) \
+@@ -1460,7 +1458,7 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl)
- }
- #undef TIOCMBIT
+- pl011_write(cr, uap->port.membase, UART011_CR); ++ pl011_write(cr, uap, UART011_CR);
- }
- static void pl011_break_ctl(struct uart_port *port, int break_state)
+@@ -1471,12 +1469,12 @@ static void pl011_break_ctl(struct uart_port *port, int break_state)
- unsigned int lcr_h;
- spin_lock_irqsave(&uap->port.lock, flags);
+- lcr_h = pl011_read(uap->port.membase, uap->lcrh_tx); ++ lcr_h = pl011_read(uap, uap->lcrh_tx);
- if (break_state == -1)
lcr_h |= UART01x_LCRH_BRK;
- else
lcr_h &= ~UART01x_LCRH_BRK;
+- pl011_write(lcr_h, uap->port.membase, uap->lcrh_tx); ++ pl011_write(lcr_h, uap, uap->lcrh_tx);
- spin_unlock_irqrestore(&uap->port.lock, flags);
- }
+@@ -1486,9 +1484,8 @@ static void pl011_quiesce_irqs(struct uart_port *port)
- {
- struct uart_amba_port *uap =
container_of(port, struct uart_amba_port, port);
+- unsigned char __iomem *regs = uap->port.membase;
+- pl011_write(pl011_read(regs, UART011_MIS), regs, UART011_ICR); ++ pl011_write(pl011_read(uap, UART011_MIS), uap, UART011_ICR);
- /*
* There is no way to clear TXIM as this is "ready to transmit IRQ", so
* we simply mask it. start_tx() will unmask it.
+@@ -1502,8 +1499,8 @@ static void pl011_quiesce_irqs(struct uart_port *port)
* (including tx queue), so we're also fine with start_tx()'s caller
* side.
*/
+- pl011_write(pl011_read(regs, UART011_IMSC) & ~UART011_TXIM, +- regs, UART011_IMSC); ++ pl011_write(pl011_read(uap, UART011_IMSC) & ~UART011_TXIM, uap, ++ UART011_IMSC);
- }
- static int pl011_get_poll_char(struct uart_port *port)
+@@ -1518,11 +1515,11 @@ static int pl011_get_poll_char(struct uart_port *port)
*/
- pl011_quiesce_irqs(port);
+- status = pl011_read(uap->port.membase, UART01x_FR); ++ status = pl011_read(uap, UART01x_FR);
- if (status & UART01x_FR_RXFE)
return NO_POLL_CHAR;
+- return pl011_read(uap->port.membase, UART01x_DR); ++ return pl011_read(uap, UART01x_DR);
- }
- static void pl011_put_poll_char(struct uart_port *port,
+@@ -1531,10 +1528,10 @@ static void pl011_put_poll_char(struct uart_port *port,
- struct uart_amba_port *uap =
container_of(port, struct uart_amba_port, port);
+- while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) ++ while (pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF)
barrier();
+- pl011_write(ch, uap->port.membase, UART01x_DR); ++ pl011_write(ch, uap, UART01x_DR);
- }
- #endif /* CONFIG_CONSOLE_POLL */
+@@ -1560,15 +1557,14 @@ static int pl011_hwinit(struct uart_port *port)
- /* Clear pending error and receive interrupts */
- pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS |
UART011_FEIS | UART011_RTIS | UART011_RXIS,
+- uap->port.membase, UART011_ICR); ++ uap, UART011_ICR);
- /*
* Save interrupts enable mask, and enable RX interrupts in case if
* the interrupt is used for NMI entry.
*/
+- uap->im = pl011_read(uap->port.membase, UART011_IMSC); +- pl011_write(UART011_RTIM | UART011_RXIM, uap->port.membase, +- UART011_IMSC); ++ uap->im = pl011_read(uap, UART011_IMSC); ++ pl011_write(UART011_RTIM | UART011_RXIM, uap, UART011_IMSC);
- if (dev_get_platdata(uap->port.dev)) {
struct amba_pl011_data *plat;
+@@ -1582,7 +1578,7 @@ static int pl011_hwinit(struct uart_port *port)
- static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h)
- {
+- pl011_write(lcr_h, uap->port.membase, uap->lcrh_rx); ++ pl011_write(lcr_h, uap, uap->lcrh_rx);
- if (uap->lcrh_rx != uap->lcrh_tx) {
int i;
/*
+@@ -1590,14 +1586,14 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h)
* to get this delay write read only register 10 times
*/
for (i = 0; i < 10; ++i)
+- pl011_write(0xff, uap->port.membase, UART011_MIS); +- pl011_write(lcr_h, uap->port.membase, uap->lcrh_tx); ++ pl011_write(0xff, uap, UART011_MIS); ++ pl011_write(lcr_h, uap, uap->lcrh_tx);
- }
- }
- static int pl011_allocate_irq(struct uart_amba_port *uap)
- {
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
- return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
- }
+@@ -1612,12 +1608,11 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
- spin_lock_irq(&uap->port.lock);
- /* Clear out any spuriously appearing RX interrupts */
+- pl011_write(UART011_RTIS | UART011_RXIS, uap->port.membase, +- UART011_ICR); ++ pl011_write(UART011_RTIS | UART011_RXIS, uap, UART011_ICR);
- uap->im = UART011_RTIM;
- if (!pl011_dma_rx_running(uap))
uap->im |= UART011_RXIM;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); ++ pl011_write(uap->im, uap, UART011_IMSC);
- spin_unlock_irq(&uap->port.lock);
- }
+@@ -1636,21 +1631,21 @@ static int pl011_startup(struct uart_port *port)
- if (retval)
goto clk_dis;
+- pl011_write(uap->vendor->ifls, uap->port.membase, UART011_IFLS); ++ pl011_write(uap->vendor->ifls, uap, UART011_IFLS);
- spin_lock_irq(&uap->port.lock);
- /* restore RTS and DTR */
- cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR);
- cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
+- pl011_write(cr, uap->port.membase, UART011_CR); ++ pl011_write(cr, uap, UART011_CR);
- spin_unlock_irq(&uap->port.lock);
- /*
* initialise the old status of the modem signals
*/
+- uap->old_status = pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_MODEM_ANY; ++ uap->old_status = pl011_read(uap, UART01x_FR) & UART01x_FR_MODEM_ANY;
- /* Startup DMA */
- pl011_dma_startup(uap);
+@@ -1691,9 +1686,9 @@ static void pl011_shutdown_channel(struct uart_amba_port *uap,
- {
unsigned long val;
+- val = pl011_read(uap->port.membase, lcrh); ++ val = pl011_read(uap, lcrh);
val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN);
+- pl011_write(val, uap->port.membase, lcrh); ++ pl011_write(val, uap, lcrh);
- }
- /*
+@@ -1707,11 +1702,11 @@ static void pl011_disable_uart(struct uart_amba_port *uap)
- uap->autorts = false;
- spin_lock_irq(&uap->port.lock);
+- cr = pl011_read(uap->port.membase, UART011_CR); ++ cr = pl011_read(uap, UART011_CR);
- uap->old_cr = cr;
- cr &= UART011_CR_RTS | UART011_CR_DTR;
- cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
+- pl011_write(cr, uap->port.membase, UART011_CR); ++ pl011_write(cr, uap, UART011_CR);
- spin_unlock_irq(&uap->port.lock);
- /*
+@@ -1728,8 +1723,8 @@ static void pl011_disable_interrupts(struct uart_amba_port *uap)
- /* mask all interrupts and clear all pending ones */
- uap->im = 0;
+- pl011_write(uap->im, uap->port.membase, UART011_IMSC); +- pl011_write(0xffff, uap->port.membase, UART011_ICR); ++ pl011_write(uap->im, uap, UART011_IMSC); ++ pl011_write(0xffff, uap, UART011_ICR);
- spin_unlock_irq(&uap->port.lock);
- }
+@@ -1881,8 +1876,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
pl011_enable_ms(port);
- /* first, disable everything */
+- old_cr = pl011_read(port->membase, UART011_CR); +- pl011_write(0, port->membase, UART011_CR); ++ old_cr = pl011_read(uap, UART011_CR); ++ pl011_write(0, uap, UART011_CR);
- if (termios->c_cflag & CRTSCTS) {
if (old_cr & UART011_CR_RTS)
+@@ -1915,8 +1910,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
quot -= 2;
- }
- /* Set baud rate */
+- pl011_write(quot & 0x3f, port->membase, UART011_FBRD); +- pl011_write(quot >> 6, port->membase, UART011_IBRD); ++ pl011_write(quot & 0x3f, uap, UART011_FBRD); ++ pl011_write(quot >> 6, uap, UART011_IBRD);
- /*
* ----------v----------v----------v----------v-----
+@@ -1925,7 +1920,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
* ----------^----------^----------^----------^-----
*/
- pl011_write_lcr_h(uap, lcr_h);
+- pl011_write(old_cr, port->membase, UART011_CR); ++ pl011_write(old_cr, uap, UART011_CR);
- spin_unlock_irqrestore(&port->lock, flags);
- }
+@@ -2066,9 +2061,9 @@ static void pl011_console_putchar(struct uart_port *port, int ch)
- struct uart_amba_port *uap =
container_of(port, struct uart_amba_port, port);
+- while (pl011_read(uap->port.membase, UART01x_FR) & UART01x_FR_TXFF) ++ while (pl011_read(uap, UART01x_FR) & UART01x_FR_TXFF)
barrier();
+- pl011_write(ch, uap->port.membase, UART01x_DR); ++ pl011_write(ch, uap, UART01x_DR);
- }
- static void
+@@ -2093,10 +2088,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
* First save the CR then disable the interrupts
*/
- if (!uap->vendor->always_enabled) {
+- old_cr = pl011_read(uap->port.membase, UART011_CR); ++ old_cr = pl011_read(uap, UART011_CR);
new_cr = old_cr & ~UART011_CR_CTSEN;
new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
+- pl011_write(new_cr, uap->port.membase, UART011_CR); ++ pl011_write(new_cr, uap, UART011_CR);
- }
- uart_console_write(&uap->port, s, count, pl011_console_putchar);
+@@ -2106,10 +2101,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
* and restore the TCR
*/
- do {
+- status = pl011_read(uap->port.membase, UART01x_FR); ++ status = pl011_read(uap, UART01x_FR);
- } while (status & UART01x_FR_BUSY);
- if (!uap->vendor->always_enabled)
+- pl011_write(old_cr, uap->port.membase, UART011_CR); ++ pl011_write(old_cr, uap, UART011_CR);
- if (locked)
spin_unlock(&uap->port.lock);
+@@ -2122,10 +2117,10 @@ static void __init
- pl011_console_get_options(struct uart_amba_port *uap, int *baud,
int *parity, int *bits)
- {
+- if (pl011_read(uap->port.membase, UART011_CR) & UART01x_CR_UARTEN) { ++ if (pl011_read(uap, UART011_CR) & UART01x_CR_UARTEN) {
unsigned int lcr_h, ibrd, fbrd;
+- lcr_h = pl011_read(uap->port.membase, uap->lcrh_tx); ++ lcr_h = pl011_read(uap, uap->lcrh_tx);
*parity = 'n';
if (lcr_h & UART01x_LCRH_PEN) {
+@@ -2140,13 +2135,13 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud,
else
*bits = 8;
+- ibrd = pl011_read(uap->port.membase, UART011_IBRD); +- fbrd = pl011_read(uap->port.membase, UART011_FBRD); ++ ibrd = pl011_read(uap, UART011_IBRD); ++ fbrd = pl011_read(uap, UART011_FBRD);
*baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd);
if (uap->vendor->oversampling) {
+- if (pl011_read(uap->port.membase, UART011_CR) ++ if (pl011_read(uap, UART011_CR)
& ST_UART011_CR_OVSFACT)
*baud *= 2;
}
+@@ -2348,8 +2343,8 @@ static int pl011_register_port(struct uart_amba_port *uap)
- int ret;
- /* Ensure interrupts from this UART are masked and cleared */
+- pl011_write(0, uap->port.membase, UART011_IMSC); +- pl011_write(0xffff, uap->port.membase, UART011_ICR); ++ pl011_write(0, uap, UART011_IMSC); ++ pl011_write(0xffff, uap, UART011_ICR);
- if (!amba_reg.state) {
ret = uart_register_driver(&amba_reg);
diff --git a/SOURCES/4003-tty-amba-pl011-add-support-for-32-bit-register-acces.patch b/SOURCES/4003-tty-amba-pl011-add-support-for-32-bit-register-acces.patch new file mode 100644 index 0000000..c2fdb4b --- /dev/null +++ b/SOURCES/4003-tty-amba-pl011-add-support-for-32-bit-register-acces.patch @@ -0,0 +1,79 @@ +From: Russell King rmk+kernel@arm.linux.org.uk +Date: Mon, 16 Nov 2015 17:40:52 +0000 +Subject: tty: amba-pl011: add support for 32-bit register access
+Add support for 32-bit register accesses to the AMBA PL011 UART. This +is needed for ZTE UARTs, which require 32-bit accesses as opposed to +the more normal 16-bit accesses.
+Signed-off-by: Russell King rmk+kernel@arm.linux.org.uk +Reviewed-by: Peter Hurley peter@hurleysoftware.com +Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
+Git-commit: 84c3e03bdd1146191b7222ed62a08512199a45c7 +Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git +[cov@codeaurora.org: Backport to CentOS 7.2] +Signed-off-by: Christopher Covington cov@codeaurora.org +---
- drivers/tty/serial/amba-pl011.c | 15 +++++++++++++--
- 1 file changed, 13 insertions(+), 2 deletions(-)
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 61512af..bb49704 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -74,6 +74,7 @@
- /* There is by now at least one vendor with differing details, so handle it */
- struct vendor_data {
- unsigned int ifls;
++ bool access_32b;
- unsigned int lcrh_tx;
- unsigned int lcrh_rx;
- bool oversampling;
+@@ -172,6 +173,7 @@ struct uart_amba_port {
- unsigned int lcrh_rx; /* vendor-specific */
- unsigned int old_cr; /* state during shutdown */
- bool autorts;
++ bool access_32b;
- unsigned int fixed_baud; /* vendor-set fixed baud rate */
- char type[12];
- #ifdef CONFIG_DMA_ENGINE
+@@ -187,13 +189,20 @@ struct uart_amba_port {
- static unsigned int pl011_read(const struct uart_amba_port *uap,
- unsigned int reg)
- {
+- return readw(uap->port.membase + reg); ++ void __iomem *addr = uap->port.membase + reg; ++ ++ return uap->access_32b ? readl(addr) : readw(addr);
- }
- static void pl011_write(unsigned int val, const struct uart_amba_port *uap,
- unsigned int reg)
- {
+- writew(val, uap->port.membase + reg); ++ void __iomem *addr = uap->port.membase + reg; ++ ++ if (uap->access_32b) ++ writel(val, addr); ++ else ++ writew(val, addr);
- }
- /*
+@@ -2381,6 +2390,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
- if (IS_ERR(uap->clk))
return PTR_ERR(uap->clk);
++ uap->access_32b = vendor->access_32b;
- uap->vendor = vendor;
- uap->lcrh_rx = vendor->lcrh_rx;
- uap->lcrh_tx = vendor->lcrh_tx;
+@@ -2462,6 +2472,7 @@ static int sbsa_uart_probe(struct platform_device *pdev)
- if (!uap)
return -ENOMEM;
++ uap->access_32b = vendor_sbsa.access_32b;
- uap->vendor = &vendor_sbsa;
- uap->fifosize = 32;
- uap->port.irq = platform_get_irq(pdev, 0);
diff --git a/SOURCES/4004-tty-amba-pl011-use-iotype-instead-of-access_32b-to-t.patch b/SOURCES/4004-tty-amba-pl011-use-iotype-instead-of-access_32b-to-t.patch new file mode 100644 index 0000000..c8250c4 --- /dev/null +++ b/SOURCES/4004-tty-amba-pl011-use-iotype-instead-of-access_32b-to-t.patch @@ -0,0 +1,119 @@ +From: Timur Tabi timur@codeaurora.org +Date: Mon, 4 Jan 2016 15:37:42 -0600 +Subject: tty: amba-pl011: use iotype instead of access_32b to track 32-bit I/O
+Instead of defining a new field in the uart_amba_port structure, use the +existing iotype field of the uart_port structure, which is intended for +this purpose. If we need to use 32-bit register access, we set iotype +to UPIO_MEM32, otherwise we set it to UPIO_MEM.
+For early console, specify the "mmio32" option on the kernel command-line. +Example:
earlycon=pl011,mmio32,0x3ced1000
+Signed-off-by: Timur Tabi timur@codeaurora.org +Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
+Git-commit: 3b78fae793c027140cfe635ef216bf60aa6498f4 +Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git +[cov@codeaurora.org: Backport to CentOS 7.2] +Signed-off-by: Christopher Covington cov@codeaurora.org +---
- Documentation/kernel-parameters.txt | 5 ++++-
- drivers/tty/serial/amba-pl011.c | 15 ++++++++-------
- 2 files changed, 12 insertions(+), 8 deletions(-)
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index 1d6f045..59bebdd 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -990,10 +990,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
unspecified, the h/w is not initialized.
pl011,<addr>
++ pl011,mmio32,<addr>
Start an early, polled-mode console on a pl011 serial
port at the specified address. The pl011 serial port
must already be setup and configured. Options are not
+- yet supported. ++ yet supported. If 'mmio32' is specified, then only ++ the driver will use only 32-bit accessors to read/write ++ the device registers.
msm_serial,<addr>
Start an early, polled-mode console on an msm serial
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index bb49704..85cf7d0 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -173,7 +173,6 @@ struct uart_amba_port {
- unsigned int lcrh_rx; /* vendor-specific */
- unsigned int old_cr; /* state during shutdown */
- bool autorts;
+- bool access_32b;
- unsigned int fixed_baud; /* vendor-set fixed baud rate */
- char type[12];
- #ifdef CONFIG_DMA_ENGINE
+@@ -191,7 +190,7 @@ static unsigned int pl011_read(const struct uart_amba_port *uap,
- {
- void __iomem *addr = uap->port.membase + reg;
+- return uap->access_32b ? readl(addr) : readw(addr); ++ return (uap->port.iotype == UPIO_MEM32) ? readl(addr) : readw(addr);
- }
- static void pl011_write(unsigned int val, const struct uart_amba_port *uap,
+@@ -199,7 +198,7 @@ static void pl011_write(unsigned int val, const struct uart_amba_port *uap,
- {
- void __iomem *addr = uap->port.membase + reg;
+- if (uap->access_32b) ++ if (uap->port.iotype == UPIO_MEM32)
writel(val, addr);
- else
writew(val, addr);
+@@ -2224,7 +2223,10 @@ static void pl011_putc(struct uart_port *port, int c)
- {
- while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
;
+- writeb(c, port->membase + UART01x_DR); ++ if (port->iotype == UPIO_MEM32) ++ writel(c, port->membase + UART01x_DR); ++ else ++ writeb(c, port->membase + UART01x_DR);
- while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
;
- }
+@@ -2337,7 +2339,6 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap,
- uap->port.dev = dev;
- uap->port.mapbase = mmiobase->start;
- uap->port.membase = base;
+- uap->port.iotype = UPIO_MEM;
- uap->port.fifosize = uap->fifosize;
- uap->port.flags = UPF_BOOT_AUTOCONF;
- uap->port.line = index;
+@@ -2390,11 +2391,11 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
- if (IS_ERR(uap->clk))
return PTR_ERR(uap->clk);
+- uap->access_32b = vendor->access_32b;
- uap->vendor = vendor;
- uap->lcrh_rx = vendor->lcrh_rx;
- uap->lcrh_tx = vendor->lcrh_tx;
- uap->fifosize = vendor->get_fifosize(dev);
++ uap->port.iotype = vendor->access_32b ? UPIO_MEM32 : UPIO_MEM;
- uap->port.irq = dev->irq[0];
- uap->port.ops = &amba_pl011_pops;
+@@ -2472,9 +2473,9 @@ static int sbsa_uart_probe(struct platform_device *pdev)
- if (!uap)
return -ENOMEM;
+- uap->access_32b = vendor_sbsa.access_32b;
- uap->vendor = &vendor_sbsa;
- uap->fifosize = 32;
++ uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM;
- uap->port.irq = platform_get_irq(pdev, 0);
- uap->port.ops = &sbsa_uart_pops;
- uap->fixed_baud = baudrate;
diff --git a/SOURCES/4005-tty-amba-pl011-Use-32-bit-accesses-for-SBSA-UART.patch b/SOURCES/4005-tty-amba-pl011-Use-32-bit-accesses-for-SBSA-UART.patch new file mode 100644 index 0000000..1d5e226 --- /dev/null +++ b/SOURCES/4005-tty-amba-pl011-Use-32-bit-accesses-for-SBSA-UART.patch @@ -0,0 +1,29 @@ +From: Christopher Covington cov@codeaurora.org +Date: Tue, 19 Apr 2016 13:52:25 -0400 +Subject: tty: amba-pl011: Use 32-bit accesses for SBSA UART
+Version 2 of the Server Base System Architecture (SBSAv2) describes UART +hardware registers as 32 bits wide, giving no guidance on access sizes. The +SBSA UART driver previously assumed partial-length 16 and 8 bit accesses would +work. But the SBSAv2 UART hardware on the Qualcomm Technologies QDF2432 only +supports full-length 32 bit register accesses, so use those exclusively. This +is compatible with SBSAv3, which explicitly requires UART hardware support 32 +(and 16 and sometimes 8) bit accesses.
+Signed-off-by: Christopher Covington cov@codeaurora +---
- drivers/tty/serial/amba-pl011.c | 1 +
- 1 file changed, 1 insertion(+)
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 85cf7d0..7127ae0 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -104,6 +104,7 @@ static struct vendor_data vendor_arm = {
- };
- static struct vendor_data vendor_sbsa = {
++ .access_32b = true,
- .oversampling = false,
- .dma_threshold = false,
- .cts_event_workaround = false,
diff --git a/SOURCES/4006-irqchip-Fully-support-ACPI-GICv3-ITS.patch b/SOURCES/4006-irqchip-Fully-support-ACPI-GICv3-ITS.patch new file mode 100644 index 0000000..555fe45 --- /dev/null +++ b/SOURCES/4006-irqchip-Fully-support-ACPI-GICv3-ITS.patch @@ -0,0 +1,49 @@ +From: Christopher Covington cov@codeaurora.org +Date: Fri, 29 Apr 2016 16:06:41 -0400 +Subject: irqchip: Fully support ACPI GICv3 ITS
+Remove stray references to device-tree-specific strings.
+Signed-off-by: Christopher Covington cov@codeaurora.org +---
- drivers/irqchip/irq-gic-v3-its.c | 13 ++++++-------
- 1 file changed, 6 insertions(+), 7 deletions(-)
+diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c +index 3da7a09..2989634 100644 +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -887,8 +887,8 @@ static int its_alloc_tables(struct its_node *its)
order);
if (order >= MAX_ORDER) {
order = MAX_ORDER - 1;
+- pr_warn("%s: Device Table too large, reduce its page order to %u\n", +- its->domain->of_node->full_name, order); ++ pr_warn("ITS: Device Table too large, reduce its page order to %u\n", ++ order);
}
}
+@@ -897,8 +897,8 @@ static int its_alloc_tables(struct its_node *its)
if (alloc_pages > GITS_BASER_PAGES_MAX) {
alloc_pages = GITS_BASER_PAGES_MAX;
order = get_order(GITS_BASER_PAGES_MAX * psz);
+- pr_warn("%s: Device Table too large, reduce its page order to %u (%u pages)\n", +- its->domain->of_node->full_name, order, alloc_pages); ++ pr_warn("ITS: Device Table too large, reduce its page order to %u (%u pages)\n", ++ order, alloc_pages);
}
base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
+@@ -965,9 +965,8 @@ retry_baser:
}
if (val != tmp) {
+- pr_err("ITS: %s: GITS_BASER%d doesn't stick: %lx %lx\n", +- its->domain->of_node->full_name, i, +- (unsigned long) val, (unsigned long) tmp); ++ pr_err("ITS: GITS_BASER%d doesn't stick: %lx %lx\n", ++ i, (unsigned long) val, (unsigned long) tmp);
err = -ENXIO;
goto out_free;
}
diff --git a/SOURCES/4007-acpi-add-support-for-extended-IRQ-to-PCI-link.patch b/SOURCES/4007-acpi-add-support-for-extended-IRQ-to-PCI-link.patch new file mode 100644 index 0000000..2bbb6ad --- /dev/null +++ b/SOURCES/4007-acpi-add-support-for-extended-IRQ-to-PCI-link.patch @@ -0,0 +1,113 @@ +From: Sinan Kaya okaya@codeaurora.org +Date: Mon, 14 Apr 2014 17:48:54 -0500 +Subject: acpi: add support for extended IRQ to PCI link
+The ACPI compiler uses the extended format when +used interrupt numbers are greater than 256. +The PCI link code currently only supports simple +interrupt format. The IRQ numbers are represented +using 32 bits when extended IRQ syntax. This patch +changes the interrupt number type to 32 bits and +places an upper limit of 512 as possible interrupt +id. Additional checks have been placed to prevent +out of bounds writes.
+Signed-off-by: Sinan Kaya okaya@codeaurora.org +---
- drivers/acpi/pci_link.c | 39 +++++++++++++++++++++++++--------------
- 1 file changed, 25 insertions(+), 14 deletions(-)
+diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c +index cfd7581..422f5d2 100644 +--- a/drivers/acpi/pci_link.c ++++ b/drivers/acpi/pci_link.c +@@ -1,6 +1,7 @@
- /*
- pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $)
++ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
- Copyright (C) 2001, 2002 Andy Grover andrew.grover@intel.com
- Copyright (C) 2001, 2002 Paul Diefenbaugh paul.s.diefenbaugh@intel.com
- Copyright (C) 2002 Dominik Brodowski devel@brodo.de
+@@ -71,12 +72,12 @@ static struct acpi_scan_handler pci_link_handler = {
- later even the link is disable. Instead, we just repick the active irq
- */
- struct acpi_pci_link_irq {
+- u8 active; /* Current IRQ */ ++ u32 active; /* Current IRQ */
- u8 triggering; /* All IRQs */
- u8 polarity; /* All IRQs */
- u8 resource_type;
- u8 possible_count;
+- u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; ++ u32 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
- u8 initialized:1;
- u8 reserved:7;
- };
+@@ -441,7 +442,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
- enabled system.
- */
+-#define ACPI_MAX_IRQS 256 ++#define ACPI_MAX_IRQS 512
- #define ACPI_MAX_ISA_IRQ 16
- #define PIRQ_PENALTY_PCI_AVAILABLE (0)
+@@ -497,13 +498,16 @@ int __init acpi_irq_penalty_init(void)
penalty;
}
+- } else if (link->irq.active) { ++ } else if (link->irq.active && ++ (link->irq.active < ACPI_MAX_IRQS)) {
acpi_irq_penalty[link->irq.active] +=
PIRQ_PENALTY_PCI_POSSIBLE;
}
- }
- /* Add a penalty for the SCI */
+- acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING; ++ if (acpi_gbl_FADT.sci_interrupt < ACPI_MAX_IRQS) ++ acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += ++ PIRQ_PENALTY_PCI_USING;
- return 0;
- }
+@@ -547,14 +551,19 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
irq = link->irq.possible[link->irq.possible_count - 1];
- if (acpi_irq_balance || !link->irq.active) {
+- /* +- * Select the best IRQ. This is done in reverse to promote +- * the use of IRQs 9, 10, 11, and >15. +- */ +- for (i = (link->irq.possible_count - 1); i >= 0; i--) { +- if (acpi_irq_penalty[irq] > +- acpi_irq_penalty[link->irq.possible[i]]) +- irq = link->irq.possible[i]; ++ ++ if (irq < ACPI_MAX_IRQS) { ++ /* ++ * Select the best IRQ. This is done in reverse to ++ * promote the use of IRQs 9, 10, 11, and >15. ++ */ ++ for (i = (link->irq.possible_count - 1); i >= 0; ++ i--) { ++ if ((link->irq.possible[i] < ACPI_MAX_IRQS) && ++ (acpi_irq_penalty[irq] > ++ acpi_irq_penalty[link->irq.possible[i]])) ++ irq = link->irq.possible[i]; ++ }
}
- }
+@@ -566,7 +575,9 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
acpi_device_bid(link->device));
return -ENODEV;
- } else {
+- acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING; ++ if (link->irq.active < ACPI_MAX_IRQS) ++ acpi_irq_penalty[link->irq.active] += ++ PIRQ_PENALTY_PCI_USING;
printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
acpi_device_name(link->device),
acpi_device_bid(link->device), link->irq.active);
diff --git a/SOURCES/4008-irqchip-gic-v3-ACPI-Add-redistributor-support-via-GI.patch b/SOURCES/4008-irqchip-gic-v3-ACPI-Add-redistributor-support-via-GI.patch new file mode 100644 index 0000000..f6b8c2c --- /dev/null +++ b/SOURCES/4008-irqchip-gic-v3-ACPI-Add-redistributor-support-via-GI.patch @@ -0,0 +1,68 @@ +From: Tomasz Nowicki tn@semihalf.com +Date: Tue, 19 Jan 2016 14:11:16 +0100 +Subject: irqchip/gic-v3: ACPI: Add redistributor support via GICC structures
+Following ACPI spec: +On systems supporting GICv3 and above, GICR Base Address in MADT GICC +structure holds the 64-bit physical address of the associated Redistributor. +If all of the GIC Redistributors are in the always-on power domain, +GICR structures should be used to describe the Redistributors instead, +and this field must be set to 0.
+It means that we have two ways to initialize registirbutors map. +1. via GICD structure which can accommodate many redistributors as a region +2. via GICC which is able to describe single redistributor
+This patch is going to add support for second option. +Considering redistributors, GICD and GICC subtables have be mutually +exclusive. While discovering and mapping redistributor, we need to know +its size in advance. For the GICC case, redistributor can be in +a power-domain that is off, thus we cannot relay on GICR TYPER register. +Therefore, we get GIC version from distributor register and map 2xSZ_64K +for GICv3. [While the upstream version of this patch includes support for +GICv4, this backport omits it for simplicity.]
+Acked-by: Marc Zyngier marc.zyngier@arm.com +Signed-off-by: Hanjun Guo hanjun.guo@linaro.org +Signed-off-by: Tomasz Nowicki tn@semihalf.com +Signed-off-by: Marc Zyngier marc.zyngier@arm.com
+Git-commit: b70fb7af67158250bf16db467926e6e105d8bc49 +Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git +[cov@codeaurora.org: Backport GICv3 essentials to CentOS 7.2] +Signed-off-by: Christopher Covington cov@codeaurora.org +---
- drivers/irqchip/irq-gic-v3.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
+diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c +index f729b97..cf75d81 100644 +--- a/drivers/irqchip/irq-gic-v3.c ++++ b/drivers/irqchip/irq-gic-v3.c +@@ -49,6 +49,7 @@ struct gic_chip_data {
- u64 redist_stride;
- u32 nr_redist_regions;
- unsigned int irq_nr;
++ bool single_redist;
- };
- static struct gic_chip_data gic_data __read_mostly;
+@@ -453,6 +454,9 @@ static int gic_populate_rdist(void)
return 0;
}
++ if (gic_data.single_redist) ++ break; ++
if (gic_data.redist_stride) {
ptr += gic_data.redist_stride;
} else {
+@@ -1092,7 +1096,7 @@ gic_v3_acpi_init(struct acpi_table_header *table, struct irq_domain **domain)
gic_acpi_parse_madt_redist, table,
ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
- if (!count)
+- pr_info("No valid GICR entries exist\n"); ++ gic_data.single_redist = true;
- else if (count < 0) {
pr_err("Error during GICR entries parsing\n");
err = -EINVAL;
diff --git a/SPECS/kernel-aarch64.spec b/SPECS/kernel-aarch64.spec index ad66cd6..52ee2d1 100644 --- a/SPECS/kernel-aarch64.spec +++ b/SPECS/kernel-aarch64.spec @@ -12,7 +12,7 @@ Summary: The Linux kernel
%define rpmversion 4.2.0 %define pkgrelease 0.21.el7 -%define centupdate 0.27.el7 +%define centupdate 0.28.el7
# allow pkg_release to have configurable %{?dist} tag %define specrelease %%SPECRELEASE%% @@ -344,6 +344,16 @@ Patch2000: KEYS-Fix-keyring-ref-leak-in-join_session_keyring.patch # NXP Patches Patch3001: NXP-Layerscape-support.patch
+# QDF2432 Patches +Patch4001: 4001-tty-amba-pl011-add-register-accessor-functions.patch +Patch4002: 4002-tty-amba-pl011-convert-accessor-functions-to-take-ua.patch +Patch4003: 4003-tty-amba-pl011-add-support-for-32-bit-register-acces.patch +Patch4004: 4004-tty-amba-pl011-use-iotype-instead-of-access_32b-to-t.patch +Patch4005: 4005-tty-amba-pl011-Use-32-bit-accesses-for-SBSA-UART.patch +Patch4006: 4006-irqchip-Fully-support-ACPI-GICv3-ITS.patch +Patch4007: 4007-acpi-add-support-for-extended-IRQ-to-PCI-link.patch +Patch4008: 4008-irqchip-gic-v3-ACPI-Add-redistributor-support-via-GI.patch
# empty final patch to facilitate testing of kernel patches Patch999999: linux-kernel-test.patch
@@ -693,6 +703,16 @@ git am %{PATCH2000} # Apply NXP patches git am %{PATCH3001}
+# Apply QDF2432 patches +git am %{PATCH4001} +git am %{PATCH4002} +git am %{PATCH4003} +git am %{PATCH4004} +git am %{PATCH4005} +git am %{PATCH4006} +git am %{PATCH4007} +git am %{PATCH4008}
# Any further pre-build tree manipulations happen here.
chmod +x scripts/checkpatch.pl @@ -1458,6 +1478,9 @@ fi %kernel_variant_files %{with_debug} kernel-debug debug
%changelog +* Mon May 09 2016 Christopher Covington cov@codeaurora.org [4.2.0-0.28.el7] +- Initial QDF2432 support
- Tue Mar 22 2016 Jim Perrin jperrin@centos.org [4.2.0-0.27.el7]
- Initial NXP support