From cde9070d9970eef1f7ec2360586c802a16230ad8 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 10 May 2024 07:43:50 +0000 Subject: [PATCH] rtl88x2CE_WiFi_linux driver --- kernel/drivers/tty/serial/8250/8250_port.c | 114 ++++++++++++++++++++++++++------------------------------ 1 files changed, 53 insertions(+), 61 deletions(-) diff --git a/kernel/drivers/tty/serial/8250/8250_port.c b/kernel/drivers/tty/serial/8250/8250_port.c index e619eaf..9eadc7f 100644 --- a/kernel/drivers/tty/serial/8250/8250_port.c +++ b/kernel/drivers/tty/serial/8250/8250_port.c @@ -15,6 +15,7 @@ #include <linux/moduleparam.h> #include <linux/ioport.h> #include <linux/init.h> +#include <linux/irq.h> #include <linux/console.h> #include <linux/gpio/consumer.h> #include <linux/sysrq.h> @@ -737,7 +738,7 @@ serial_out(p, UART_EFR, UART_EFR_ECB); serial_out(p, UART_LCR, 0); } - serial8250_set_IER(p, sleep ? UART_IERX_SLEEP : 0); + serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); if (p->capabilities & UART_CAP_EFR) { serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(p, UART_EFR, efr); @@ -1411,7 +1412,7 @@ up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); up->port.read_status_mask &= ~UART_LSR_DR; - serial8250_set_IER(up, up->ier); + serial_port_out(port, UART_IER, up->ier); serial8250_rpm_put(up); } @@ -1441,7 +1442,7 @@ serial8250_clear_and_reinit_fifos(p); p->ier |= UART_IER_RLSI | UART_IER_RDI; - serial8250_set_IER(p, p->ier); + serial_port_out(&p->port, UART_IER, p->ier); } } EXPORT_SYMBOL_GPL(serial8250_em485_stop_tx); @@ -1688,7 +1689,7 @@ mctrl_gpio_disable_ms(up->gpios); up->ier &= ~UART_IER_MSI; - serial8250_set_IER(up, up->ier); + serial_port_out(port, UART_IER, up->ier); } static void serial8250_enable_ms(struct uart_port *port) @@ -1704,7 +1705,7 @@ up->ier |= UART_IER_MSI; serial8250_rpm_get(up); - serial8250_set_IER(up, up->ier); + serial_port_out(port, UART_IER, up->ier); serial8250_rpm_put(up); } @@ -1909,6 +1910,7 @@ unsigned long flags; struct uart_8250_port *up = up_to_u8250p(port); #ifndef CONFIG_ARCH_ROCKCHIP + struct tty_port *tport = &port->state->port; bool skip_rx = false; #endif @@ -1944,6 +1946,11 @@ skip_rx = true; if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { + struct irq_data *d; + + d = irq_get_irq_data(port->irq); + if (d && irqd_is_wakeup_set(d)) + pm_wakeup_event(tport->tty->dev, 0); if (!up->dma || handle_rx_dma(up, iir)) status = serial8250_rx_chars(up, status); } @@ -2022,19 +2029,25 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); + unsigned int result = 0; unsigned long flags; unsigned int lsr; serial8250_rpm_get(up); spin_lock_irqsave(&port->lock, flags); - lsr = serial_port_in(port, UART_LSR); - up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + if (!serial8250_tx_dma_running(up)) { + lsr = serial_port_in(port, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + + if ((lsr & BOTH_EMPTY) == BOTH_EMPTY) + result = TIOCSER_TEMT; + } spin_unlock_irqrestore(&port->lock, flags); serial8250_rpm_put(up); - return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; + return result; } unsigned int serial8250_do_get_mctrl(struct uart_port *port) @@ -2171,7 +2184,14 @@ struct uart_8250_port *up = up_to_u8250p(port); serial8250_rpm_get(up); - ier = serial8250_clear_IER(up); + /* + * First save the IER then disable the interrupts + */ + ier = serial_port_in(port, UART_IER); + if (up->capabilities & UART_CAP_UUE) + serial_port_out(port, UART_IER, UART_IER_UUE); + else + serial_port_out(port, UART_IER, 0); wait_for_xmitr(up, BOTH_EMPTY); /* @@ -2184,7 +2204,7 @@ * and restore the IER */ wait_for_xmitr(up, BOTH_EMPTY); - serial8250_set_IER(up, ier); + serial_port_out(port, UART_IER, ier); serial8250_rpm_put(up); } @@ -2491,7 +2511,7 @@ */ spin_lock_irqsave(&port->lock, flags); up->ier = 0; - serial8250_set_IER(up, 0); + serial_port_out(port, UART_IER, 0); spin_unlock_irqrestore(&port->lock, flags); synchronize_irq(port->irq); @@ -2863,7 +2883,7 @@ if (up->capabilities & UART_CAP_RTOIE) up->ier |= UART_IER_RTOIE; - serial8250_set_IER(up, up->ier); + serial_port_out(port, UART_IER, up->ier); #endif if (up->capabilities & UART_CAP_EFR) { @@ -2923,7 +2943,7 @@ if (up->capabilities & UART_CAP_RTOIE) up->ier |= UART_IER_RTOIE; - serial8250_set_IER(up, up->ier); + serial_port_out(port, UART_IER, up->ier); #endif spin_unlock_irqrestore(&port->lock, flags); @@ -3319,6 +3339,7 @@ struct uart_port *port = &up->port; spin_lock_init(&port->lock); + port->pm = NULL; port->ops = &serial8250_pops; port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE); @@ -3355,24 +3376,12 @@ #ifdef CONFIG_SERIAL_8250_CONSOLE -static void serial8250_console_putchar_locked(struct uart_port *port, int ch) +static void serial8250_console_putchar(struct uart_port *port, int ch) { struct uart_8250_port *up = up_to_u8250p(port); wait_for_xmitr(up, UART_LSR_THRE); serial_port_out(port, UART_TX, ch); -} - -static void serial8250_console_putchar(struct uart_port *port, int ch) -{ - struct uart_8250_port *up = up_to_u8250p(port); - unsigned int flags; - - wait_for_xmitr(up, UART_LSR_THRE); - - console_atomic_lock(&flags); - serial8250_console_putchar_locked(port, ch); - console_atomic_unlock(flags); } /* @@ -3396,32 +3405,6 @@ serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS); } -void serial8250_console_write_atomic(struct uart_8250_port *up, - const char *s, unsigned int count) -{ - struct uart_port *port = &up->port; - unsigned int flags; - unsigned int ier; - - console_atomic_lock(&flags); - - touch_nmi_watchdog(); - - ier = serial8250_clear_IER(up); - - if (atomic_fetch_inc(&up->console_printing)) { - uart_console_write(port, "\n", 1, - serial8250_console_putchar_locked); - } - uart_console_write(port, s, count, serial8250_console_putchar_locked); - atomic_dec(&up->console_printing); - - wait_for_xmitr(up, BOTH_EMPTY); - serial8250_set_IER(up, ier); - - console_atomic_unlock(flags); -} - /* * Print a string to the serial port trying not to disturb * any possible real use of the port... @@ -3438,12 +3421,24 @@ struct uart_port *port = &up->port; unsigned long flags; unsigned int ier; + int locked = 1; touch_nmi_watchdog(); - spin_lock_irqsave(&port->lock, flags); + if (oops_in_progress) + locked = spin_trylock_irqsave(&port->lock, flags); + else + spin_lock_irqsave(&port->lock, flags); - ier = serial8250_clear_IER(up); + /* + * First save the IER then disable the interrupts + */ + ier = serial_port_in(port, UART_IER); + + if (up->capabilities & UART_CAP_UUE) + serial_port_out(port, UART_IER, UART_IER_UUE); + else + serial_port_out(port, UART_IER, 0); /* check scratch reg to see if port powered off during system sleep */ if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { @@ -3457,9 +3452,7 @@ mdelay(port->rs485.delay_rts_before_send); } - atomic_inc(&up->console_printing); uart_console_write(port, s, count, serial8250_console_putchar); - atomic_dec(&up->console_printing); /* * Finally, wait for transmitter to become empty @@ -3472,7 +3465,8 @@ if (em485->tx_stopped) up->rs485_stop_tx(up); } - serial8250_set_IER(up, ier); + + serial_port_out(port, UART_IER, ier); /* * The receive handling will happen properly because the @@ -3484,7 +3478,8 @@ if (up->msr_saved_flags) serial8250_modem_status(up); - spin_unlock_irqrestore(&port->lock, flags); + if (locked) + spin_unlock_irqrestore(&port->lock, flags); } static unsigned int probe_baud(struct uart_port *port) @@ -3504,7 +3499,6 @@ int serial8250_console_setup(struct uart_port *port, char *options, bool probe) { - struct uart_8250_port *up = up_to_u8250p(port); int baud = 9600; int bits = 8; int parity = 'n'; @@ -3513,8 +3507,6 @@ if (!port->iobase && !port->membase) return -ENODEV; - - atomic_set(&up->console_printing, 0); if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); -- Gitblit v1.6.2