| .. | .. |
|---|
| 16 | 16 | * and hooked into this driver. |
|---|
| 17 | 17 | */ |
|---|
| 18 | 18 | |
|---|
| 19 | | - |
|---|
| 20 | | -#if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
|---|
| 21 | | -#define SUPPORT_SYSRQ |
|---|
| 22 | | -#endif |
|---|
| 23 | | - |
|---|
| 24 | 19 | #include <linux/module.h> |
|---|
| 25 | 20 | #include <linux/ioport.h> |
|---|
| 26 | 21 | #include <linux/init.h> |
|---|
| .. | .. |
|---|
| 417 | 412 | dma_cap_mask_t mask; |
|---|
| 418 | 413 | |
|---|
| 419 | 414 | uap->dma_probed = true; |
|---|
| 420 | | - chan = dma_request_slave_channel_reason(dev, "tx"); |
|---|
| 415 | + chan = dma_request_chan(dev, "tx"); |
|---|
| 421 | 416 | if (IS_ERR(chan)) { |
|---|
| 422 | 417 | if (PTR_ERR(chan) == -EPROBE_DEFER) { |
|---|
| 423 | 418 | uap->dma_probed = false; |
|---|
| .. | .. |
|---|
| 1237 | 1232 | |
|---|
| 1238 | 1233 | #else |
|---|
| 1239 | 1234 | /* Blank functions if the DMA engine is not available */ |
|---|
| 1240 | | -static inline void pl011_dma_probe(struct uart_amba_port *uap) |
|---|
| 1241 | | -{ |
|---|
| 1242 | | -} |
|---|
| 1243 | | - |
|---|
| 1244 | 1235 | static inline void pl011_dma_remove(struct uart_amba_port *uap) |
|---|
| 1245 | 1236 | { |
|---|
| 1246 | 1237 | } |
|---|
| .. | .. |
|---|
| 1333 | 1324 | pl011_write(uap->im, uap, REG_IMSC); |
|---|
| 1334 | 1325 | |
|---|
| 1335 | 1326 | pl011_dma_rx_stop(uap); |
|---|
| 1327 | +} |
|---|
| 1328 | + |
|---|
| 1329 | +static void pl011_throttle_rx(struct uart_port *port) |
|---|
| 1330 | +{ |
|---|
| 1331 | + unsigned long flags; |
|---|
| 1332 | + |
|---|
| 1333 | + spin_lock_irqsave(&port->lock, flags); |
|---|
| 1334 | + pl011_stop_rx(port); |
|---|
| 1335 | + spin_unlock_irqrestore(&port->lock, flags); |
|---|
| 1336 | 1336 | } |
|---|
| 1337 | 1337 | |
|---|
| 1338 | 1338 | static void pl011_enable_ms(struct uart_port *port) |
|---|
| .. | .. |
|---|
| 1459 | 1459 | |
|---|
| 1460 | 1460 | static void check_apply_cts_event_workaround(struct uart_amba_port *uap) |
|---|
| 1461 | 1461 | { |
|---|
| 1462 | | - unsigned int dummy_read; |
|---|
| 1463 | | - |
|---|
| 1464 | 1462 | if (!uap->vendor->cts_event_workaround) |
|---|
| 1465 | 1463 | return; |
|---|
| 1466 | 1464 | |
|---|
| .. | .. |
|---|
| 1472 | 1470 | * single apb access will incur 2 pclk(133.12Mhz) delay, |
|---|
| 1473 | 1471 | * so add 2 dummy reads |
|---|
| 1474 | 1472 | */ |
|---|
| 1475 | | - dummy_read = pl011_read(uap, REG_ICR); |
|---|
| 1476 | | - dummy_read = pl011_read(uap, REG_ICR); |
|---|
| 1473 | + pl011_read(uap, REG_ICR); |
|---|
| 1474 | + pl011_read(uap, REG_ICR); |
|---|
| 1477 | 1475 | } |
|---|
| 1478 | 1476 | |
|---|
| 1479 | 1477 | static irqreturn_t pl011_int(int irq, void *dev_id) |
|---|
| .. | .. |
|---|
| 1718 | 1716 | { |
|---|
| 1719 | 1717 | pl011_write(uap->im, uap, REG_IMSC); |
|---|
| 1720 | 1718 | |
|---|
| 1721 | | - return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); |
|---|
| 1719 | + return request_irq(uap->port.irq, pl011_int, IRQF_SHARED, "uart-pl011", uap); |
|---|
| 1722 | 1720 | } |
|---|
| 1723 | 1721 | |
|---|
| 1724 | 1722 | /* |
|---|
| .. | .. |
|---|
| 1728 | 1726 | */ |
|---|
| 1729 | 1727 | static void pl011_enable_interrupts(struct uart_amba_port *uap) |
|---|
| 1730 | 1728 | { |
|---|
| 1729 | + unsigned long flags; |
|---|
| 1731 | 1730 | unsigned int i; |
|---|
| 1732 | 1731 | |
|---|
| 1733 | | - spin_lock_irq(&uap->port.lock); |
|---|
| 1732 | + spin_lock_irqsave(&uap->port.lock, flags); |
|---|
| 1734 | 1733 | |
|---|
| 1735 | 1734 | /* Clear out any spuriously appearing RX interrupts */ |
|---|
| 1736 | 1735 | pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR); |
|---|
| .. | .. |
|---|
| 1752 | 1751 | if (!pl011_dma_rx_running(uap)) |
|---|
| 1753 | 1752 | uap->im |= UART011_RXIM; |
|---|
| 1754 | 1753 | pl011_write(uap->im, uap, REG_IMSC); |
|---|
| 1755 | | - spin_unlock_irq(&uap->port.lock); |
|---|
| 1754 | + spin_unlock_irqrestore(&uap->port.lock, flags); |
|---|
| 1755 | +} |
|---|
| 1756 | + |
|---|
| 1757 | +static void pl011_unthrottle_rx(struct uart_port *port) |
|---|
| 1758 | +{ |
|---|
| 1759 | + struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); |
|---|
| 1760 | + |
|---|
| 1761 | + pl011_enable_interrupts(uap); |
|---|
| 1756 | 1762 | } |
|---|
| 1757 | 1763 | |
|---|
| 1758 | 1764 | static int pl011_startup(struct uart_port *port) |
|---|
| .. | .. |
|---|
| 2127 | 2133 | .stop_tx = pl011_stop_tx, |
|---|
| 2128 | 2134 | .start_tx = pl011_start_tx, |
|---|
| 2129 | 2135 | .stop_rx = pl011_stop_rx, |
|---|
| 2136 | + .throttle = pl011_throttle_rx, |
|---|
| 2137 | + .unthrottle = pl011_unthrottle_rx, |
|---|
| 2130 | 2138 | .enable_ms = pl011_enable_ms, |
|---|
| 2131 | 2139 | .break_ctl = pl011_break_ctl, |
|---|
| 2132 | 2140 | .startup = pl011_startup, |
|---|
| .. | .. |
|---|
| 2191 | 2199 | { |
|---|
| 2192 | 2200 | struct uart_amba_port *uap = amba_ports[co->index]; |
|---|
| 2193 | 2201 | unsigned int old_cr = 0, new_cr; |
|---|
| 2194 | | - unsigned long flags; |
|---|
| 2202 | + unsigned long flags = 0; |
|---|
| 2195 | 2203 | int locked = 1; |
|---|
| 2196 | 2204 | |
|---|
| 2197 | 2205 | clk_enable(uap->clk); |
|---|
| 2198 | 2206 | |
|---|
| 2199 | | - local_irq_save(flags); |
|---|
| 2207 | + /* |
|---|
| 2208 | + * local_irq_save(flags); |
|---|
| 2209 | + * |
|---|
| 2210 | + * This local_irq_save() is nonsense. If we come in via sysrq |
|---|
| 2211 | + * handling then interrupts are already disabled. Aside of |
|---|
| 2212 | + * that the port.sysrq check is racy on SMP regardless. |
|---|
| 2213 | + */ |
|---|
| 2200 | 2214 | if (uap->port.sysrq) |
|---|
| 2201 | 2215 | locked = 0; |
|---|
| 2202 | 2216 | else if (oops_in_progress) |
|---|
| 2203 | | - locked = spin_trylock(&uap->port.lock); |
|---|
| 2217 | + locked = spin_trylock_irqsave(&uap->port.lock, flags); |
|---|
| 2204 | 2218 | else |
|---|
| 2205 | | - spin_lock(&uap->port.lock); |
|---|
| 2219 | + spin_lock_irqsave(&uap->port.lock, flags); |
|---|
| 2206 | 2220 | |
|---|
| 2207 | 2221 | /* |
|---|
| 2208 | 2222 | * First save the CR then disable the interrupts |
|---|
| .. | .. |
|---|
| 2228 | 2242 | pl011_write(old_cr, uap, REG_CR); |
|---|
| 2229 | 2243 | |
|---|
| 2230 | 2244 | if (locked) |
|---|
| 2231 | | - spin_unlock(&uap->port.lock); |
|---|
| 2232 | | - local_irq_restore(flags); |
|---|
| 2245 | + spin_unlock_irqrestore(&uap->port.lock, flags); |
|---|
| 2233 | 2246 | |
|---|
| 2234 | 2247 | clk_disable(uap->clk); |
|---|
| 2235 | 2248 | } |
|---|
| .. | .. |
|---|
| 2427 | 2440 | uart_console_write(&dev->port, s, n, pl011_putc); |
|---|
| 2428 | 2441 | } |
|---|
| 2429 | 2442 | |
|---|
| 2443 | +#ifdef CONFIG_CONSOLE_POLL |
|---|
| 2444 | +static int pl011_getc(struct uart_port *port) |
|---|
| 2445 | +{ |
|---|
| 2446 | + if (readl(port->membase + UART01x_FR) & UART01x_FR_RXFE) |
|---|
| 2447 | + return NO_POLL_CHAR; |
|---|
| 2448 | + |
|---|
| 2449 | + if (port->iotype == UPIO_MEM32) |
|---|
| 2450 | + return readl(port->membase + UART01x_DR); |
|---|
| 2451 | + else |
|---|
| 2452 | + return readb(port->membase + UART01x_DR); |
|---|
| 2453 | +} |
|---|
| 2454 | + |
|---|
| 2455 | +static int pl011_early_read(struct console *con, char *s, unsigned int n) |
|---|
| 2456 | +{ |
|---|
| 2457 | + struct earlycon_device *dev = con->data; |
|---|
| 2458 | + int ch, num_read = 0; |
|---|
| 2459 | + |
|---|
| 2460 | + while (num_read < n) { |
|---|
| 2461 | + ch = pl011_getc(&dev->port); |
|---|
| 2462 | + if (ch == NO_POLL_CHAR) |
|---|
| 2463 | + break; |
|---|
| 2464 | + |
|---|
| 2465 | + s[num_read++] = ch; |
|---|
| 2466 | + } |
|---|
| 2467 | + |
|---|
| 2468 | + return num_read; |
|---|
| 2469 | +} |
|---|
| 2470 | +#else |
|---|
| 2471 | +#define pl011_early_read NULL |
|---|
| 2472 | +#endif |
|---|
| 2473 | + |
|---|
| 2430 | 2474 | /* |
|---|
| 2431 | 2475 | * On non-ACPI systems, earlycon is enabled by specifying |
|---|
| 2432 | 2476 | * "earlycon=pl011,<address>" on the kernel command line. |
|---|
| .. | .. |
|---|
| 2446 | 2490 | return -ENODEV; |
|---|
| 2447 | 2491 | |
|---|
| 2448 | 2492 | device->con->write = pl011_early_write; |
|---|
| 2493 | + device->con->read = pl011_early_read; |
|---|
| 2449 | 2494 | |
|---|
| 2450 | 2495 | return 0; |
|---|
| 2451 | 2496 | } |
|---|
| .. | .. |
|---|
| 2564 | 2609 | uap->port.mapbase = mmiobase->start; |
|---|
| 2565 | 2610 | uap->port.membase = base; |
|---|
| 2566 | 2611 | uap->port.fifosize = uap->fifosize; |
|---|
| 2612 | + uap->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_AMBA_PL011_CONSOLE); |
|---|
| 2567 | 2613 | uap->port.flags = UPF_BOOT_AUTOCONF; |
|---|
| 2568 | 2614 | uap->port.line = index; |
|---|
| 2569 | | - spin_lock_init(&uap->port.lock); |
|---|
| 2570 | 2615 | |
|---|
| 2571 | 2616 | amba_ports[index] = uap; |
|---|
| 2572 | 2617 | |
|---|
| .. | .. |
|---|
| 2637 | 2682 | return pl011_register_port(uap); |
|---|
| 2638 | 2683 | } |
|---|
| 2639 | 2684 | |
|---|
| 2640 | | -static int pl011_remove(struct amba_device *dev) |
|---|
| 2685 | +static void pl011_remove(struct amba_device *dev) |
|---|
| 2641 | 2686 | { |
|---|
| 2642 | 2687 | struct uart_amba_port *uap = amba_get_drvdata(dev); |
|---|
| 2643 | 2688 | |
|---|
| 2644 | 2689 | uart_remove_one_port(&amba_reg, &uap->port); |
|---|
| 2645 | 2690 | pl011_unregister_port(uap); |
|---|
| 2646 | | - return 0; |
|---|
| 2647 | 2691 | } |
|---|
| 2648 | 2692 | |
|---|
| 2649 | 2693 | #ifdef CONFIG_PM_SLEEP |
|---|
| .. | .. |
|---|
| 2701 | 2745 | return -ENOMEM; |
|---|
| 2702 | 2746 | |
|---|
| 2703 | 2747 | ret = platform_get_irq(pdev, 0); |
|---|
| 2704 | | - if (ret < 0) { |
|---|
| 2705 | | - if (ret != -EPROBE_DEFER) |
|---|
| 2706 | | - dev_err(&pdev->dev, "cannot obtain irq\n"); |
|---|
| 2748 | + if (ret < 0) |
|---|
| 2707 | 2749 | return ret; |
|---|
| 2708 | | - } |
|---|
| 2709 | 2750 | uap->port.irq = ret; |
|---|
| 2710 | 2751 | |
|---|
| 2711 | 2752 | #ifdef CONFIG_ACPI_SPCR_TABLE |
|---|
| .. | .. |
|---|
| 2762 | 2803 | .remove = sbsa_uart_remove, |
|---|
| 2763 | 2804 | .driver = { |
|---|
| 2764 | 2805 | .name = "sbsa-uart", |
|---|
| 2806 | + .pm = &pl011_dev_pm_ops, |
|---|
| 2765 | 2807 | .of_match_table = of_match_ptr(sbsa_uart_of_match), |
|---|
| 2766 | 2808 | .acpi_match_table = ACPI_PTR(sbsa_uart_acpi_match), |
|---|
| 2767 | 2809 | .suppress_bind_attrs = IS_BUILTIN(CONFIG_SERIAL_AMBA_PL011), |
|---|