From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/tty/serial/amba-pl011.c | 114 +++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 79 insertions(+), 35 deletions(-)
diff --git a/kernel/drivers/tty/serial/amba-pl011.c b/kernel/drivers/tty/serial/amba-pl011.c
index 9666a20..348d4b2 100644
--- a/kernel/drivers/tty/serial/amba-pl011.c
+++ b/kernel/drivers/tty/serial/amba-pl011.c
@@ -16,11 +16,6 @@
* and hooked into this driver.
*/
-
-#if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/init.h>
@@ -417,7 +412,7 @@
dma_cap_mask_t mask;
uap->dma_probed = true;
- chan = dma_request_slave_channel_reason(dev, "tx");
+ chan = dma_request_chan(dev, "tx");
if (IS_ERR(chan)) {
if (PTR_ERR(chan) == -EPROBE_DEFER) {
uap->dma_probed = false;
@@ -1053,6 +1048,9 @@
*/
static inline void pl011_dma_rx_stop(struct uart_amba_port *uap)
{
+ if (!uap->using_rx_dma)
+ return;
+
/* FIXME. Just disable the DMA enable */
uap->dmacr &= ~UART011_RXDMAE;
pl011_write(uap->dmacr, uap, REG_DMACR);
@@ -1237,10 +1235,6 @@
#else
/* Blank functions if the DMA engine is not available */
-static inline void pl011_dma_probe(struct uart_amba_port *uap)
-{
-}
-
static inline void pl011_dma_remove(struct uart_amba_port *uap)
{
}
@@ -1333,6 +1327,15 @@
pl011_write(uap->im, uap, REG_IMSC);
pl011_dma_rx_stop(uap);
+}
+
+static void pl011_throttle_rx(struct uart_port *port)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ pl011_stop_rx(port);
+ spin_unlock_irqrestore(&port->lock, flags);
}
static void pl011_enable_ms(struct uart_port *port)
@@ -1459,8 +1462,6 @@
static void check_apply_cts_event_workaround(struct uart_amba_port *uap)
{
- unsigned int dummy_read;
-
if (!uap->vendor->cts_event_workaround)
return;
@@ -1472,8 +1473,8 @@
* single apb access will incur 2 pclk(133.12Mhz) delay,
* so add 2 dummy reads
*/
- dummy_read = pl011_read(uap, REG_ICR);
- dummy_read = pl011_read(uap, REG_ICR);
+ pl011_read(uap, REG_ICR);
+ pl011_read(uap, REG_ICR);
}
static irqreturn_t pl011_int(int irq, void *dev_id)
@@ -1718,7 +1719,7 @@
{
pl011_write(uap->im, uap, REG_IMSC);
- return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
+ return request_irq(uap->port.irq, pl011_int, IRQF_SHARED, "uart-pl011", uap);
}
/*
@@ -1728,9 +1729,10 @@
*/
static void pl011_enable_interrupts(struct uart_amba_port *uap)
{
+ unsigned long flags;
unsigned int i;
- spin_lock_irq(&uap->port.lock);
+ spin_lock_irqsave(&uap->port.lock, flags);
/* Clear out any spuriously appearing RX interrupts */
pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
@@ -1752,7 +1754,23 @@
if (!pl011_dma_rx_running(uap))
uap->im |= UART011_RXIM;
pl011_write(uap->im, uap, REG_IMSC);
- spin_unlock_irq(&uap->port.lock);
+ spin_unlock_irqrestore(&uap->port.lock, flags);
+}
+
+static void pl011_unthrottle_rx(struct uart_port *port)
+{
+ struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port);
+ unsigned long flags;
+
+ spin_lock_irqsave(&uap->port.lock, flags);
+
+ uap->im = UART011_RTIM;
+ if (!pl011_dma_rx_running(uap))
+ uap->im |= UART011_RXIM;
+
+ pl011_write(uap->im, uap, REG_IMSC);
+
+ spin_unlock_irqrestore(&uap->port.lock, flags);
}
static int pl011_startup(struct uart_port *port)
@@ -2127,6 +2145,8 @@
.stop_tx = pl011_stop_tx,
.start_tx = pl011_start_tx,
.stop_rx = pl011_stop_rx,
+ .throttle = pl011_throttle_rx,
+ .unthrottle = pl011_unthrottle_rx,
.enable_ms = pl011_enable_ms,
.break_ctl = pl011_break_ctl,
.startup = pl011_startup,
@@ -2191,24 +2211,18 @@
{
struct uart_amba_port *uap = amba_ports[co->index];
unsigned int old_cr = 0, new_cr;
- unsigned long flags = 0;
+ unsigned long flags;
int locked = 1;
clk_enable(uap->clk);
- /*
- * local_irq_save(flags);
- *
- * This local_irq_save() is nonsense. If we come in via sysrq
- * handling then interrupts are already disabled. Aside of
- * that the port.sysrq check is racy on SMP regardless.
- */
+ local_irq_save(flags);
if (uap->port.sysrq)
locked = 0;
else if (oops_in_progress)
- locked = spin_trylock_irqsave(&uap->port.lock, flags);
+ locked = spin_trylock(&uap->port.lock);
else
- spin_lock_irqsave(&uap->port.lock, flags);
+ spin_lock(&uap->port.lock);
/*
* First save the CR then disable the interrupts
@@ -2234,7 +2248,8 @@
pl011_write(old_cr, uap, REG_CR);
if (locked)
- spin_unlock_irqrestore(&uap->port.lock, flags);
+ spin_unlock(&uap->port.lock);
+ local_irq_restore(flags);
clk_disable(uap->clk);
}
@@ -2432,6 +2447,37 @@
uart_console_write(&dev->port, s, n, pl011_putc);
}
+#ifdef CONFIG_CONSOLE_POLL
+static int pl011_getc(struct uart_port *port)
+{
+ if (readl(port->membase + UART01x_FR) & UART01x_FR_RXFE)
+ return NO_POLL_CHAR;
+
+ if (port->iotype == UPIO_MEM32)
+ return readl(port->membase + UART01x_DR);
+ else
+ return readb(port->membase + UART01x_DR);
+}
+
+static int pl011_early_read(struct console *con, char *s, unsigned int n)
+{
+ struct earlycon_device *dev = con->data;
+ int ch, num_read = 0;
+
+ while (num_read < n) {
+ ch = pl011_getc(&dev->port);
+ if (ch == NO_POLL_CHAR)
+ break;
+
+ s[num_read++] = ch;
+ }
+
+ return num_read;
+}
+#else
+#define pl011_early_read NULL
+#endif
+
/*
* On non-ACPI systems, earlycon is enabled by specifying
* "earlycon=pl011,<address>" on the kernel command line.
@@ -2451,6 +2497,7 @@
return -ENODEV;
device->con->write = pl011_early_write;
+ device->con->read = pl011_early_read;
return 0;
}
@@ -2569,9 +2616,9 @@
uap->port.mapbase = mmiobase->start;
uap->port.membase = base;
uap->port.fifosize = uap->fifosize;
+ uap->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_AMBA_PL011_CONSOLE);
uap->port.flags = UPF_BOOT_AUTOCONF;
uap->port.line = index;
- spin_lock_init(&uap->port.lock);
amba_ports[index] = uap;
@@ -2642,13 +2689,12 @@
return pl011_register_port(uap);
}
-static int pl011_remove(struct amba_device *dev)
+static void pl011_remove(struct amba_device *dev)
{
struct uart_amba_port *uap = amba_get_drvdata(dev);
uart_remove_one_port(&amba_reg, &uap->port);
pl011_unregister_port(uap);
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -2706,11 +2752,8 @@
return -ENOMEM;
ret = platform_get_irq(pdev, 0);
- if (ret < 0) {
- if (ret != -EPROBE_DEFER)
- dev_err(&pdev->dev, "cannot obtain irq\n");
+ if (ret < 0)
return ret;
- }
uap->port.irq = ret;
#ifdef CONFIG_ACPI_SPCR_TABLE
@@ -2767,6 +2810,7 @@
.remove = sbsa_uart_remove,
.driver = {
.name = "sbsa-uart",
+ .pm = &pl011_dev_pm_ops,
.of_match_table = of_match_ptr(sbsa_uart_of_match),
.acpi_match_table = ACPI_PTR(sbsa_uart_acpi_match),
.suppress_bind_attrs = IS_BUILTIN(CONFIG_SERIAL_AMBA_PL011),
--
Gitblit v1.6.2