1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker.
4*4882a593Smuzhiyun * Copyright 2020 NXP
5*4882a593Smuzhiyun * Copyright 2020 Puresoftware Ltd.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * This isn't a full driver; it just provides an alternate IRQ
8*4882a593Smuzhiyun * handler to deal with an errata and provide ACPI wrapper.
9*4882a593Smuzhiyun * Everything else is just using the bog standard 8250 support.
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * We follow code flow of serial8250_default_handle_irq() but add
12*4882a593Smuzhiyun * a check for a break and insert a dummy read on the Rx for the
13*4882a593Smuzhiyun * immediately following IRQ event.
14*4882a593Smuzhiyun *
15*4882a593Smuzhiyun * We re-use the already existing "bug handling" lsr_saved_flags
16*4882a593Smuzhiyun * field to carry the "what we just did" information from the one
17*4882a593Smuzhiyun * IRQ event to the next one.
18*4882a593Smuzhiyun */
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #include <linux/acpi.h>
21*4882a593Smuzhiyun #include <linux/serial_reg.h>
22*4882a593Smuzhiyun #include <linux/serial_8250.h>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #include "8250.h"
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun struct fsl8250_data {
27*4882a593Smuzhiyun int line;
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun
fsl8250_handle_irq(struct uart_port * port)30*4882a593Smuzhiyun int fsl8250_handle_irq(struct uart_port *port)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun unsigned char lsr, orig_lsr;
33*4882a593Smuzhiyun unsigned long flags;
34*4882a593Smuzhiyun unsigned int iir;
35*4882a593Smuzhiyun struct uart_8250_port *up = up_to_u8250p(port);
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun spin_lock_irqsave(&up->port.lock, flags);
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun iir = port->serial_in(port, UART_IIR);
40*4882a593Smuzhiyun if (iir & UART_IIR_NO_INT) {
41*4882a593Smuzhiyun spin_unlock_irqrestore(&up->port.lock, flags);
42*4882a593Smuzhiyun return 0;
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun /* This is the WAR; if last event was BRK, then read and return */
46*4882a593Smuzhiyun if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) {
47*4882a593Smuzhiyun up->lsr_saved_flags &= ~UART_LSR_BI;
48*4882a593Smuzhiyun port->serial_in(port, UART_RX);
49*4882a593Smuzhiyun spin_unlock_irqrestore(&up->port.lock, flags);
50*4882a593Smuzhiyun return 1;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR);
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /* Process incoming characters first */
56*4882a593Smuzhiyun if ((lsr & (UART_LSR_DR | UART_LSR_BI)) &&
57*4882a593Smuzhiyun (up->ier & (UART_IER_RLSI | UART_IER_RDI))) {
58*4882a593Smuzhiyun lsr = serial8250_rx_chars(up, lsr);
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* Stop processing interrupts on input overrun */
62*4882a593Smuzhiyun if ((orig_lsr & UART_LSR_OE) && (up->overrun_backoff_time_ms > 0)) {
63*4882a593Smuzhiyun unsigned long delay;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun up->ier = port->serial_in(port, UART_IER);
66*4882a593Smuzhiyun if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) {
67*4882a593Smuzhiyun port->ops->stop_rx(port);
68*4882a593Smuzhiyun } else {
69*4882a593Smuzhiyun /* Keep restarting the timer until
70*4882a593Smuzhiyun * the input overrun subsides.
71*4882a593Smuzhiyun */
72*4882a593Smuzhiyun cancel_delayed_work(&up->overrun_backoff);
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun delay = msecs_to_jiffies(up->overrun_backoff_time_ms);
76*4882a593Smuzhiyun schedule_delayed_work(&up->overrun_backoff, delay);
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun serial8250_modem_status(up);
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun if ((lsr & UART_LSR_THRE) && (up->ier & UART_IER_THRI))
82*4882a593Smuzhiyun serial8250_tx_chars(up);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun up->lsr_saved_flags = orig_lsr;
85*4882a593Smuzhiyun uart_unlock_and_check_sysrq(&up->port, flags);
86*4882a593Smuzhiyun return 1;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(fsl8250_handle_irq);
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun #ifdef CONFIG_ACPI
fsl8250_acpi_probe(struct platform_device * pdev)91*4882a593Smuzhiyun static int fsl8250_acpi_probe(struct platform_device *pdev)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun struct fsl8250_data *data;
94*4882a593Smuzhiyun struct uart_8250_port port8250;
95*4882a593Smuzhiyun struct device *dev = &pdev->dev;
96*4882a593Smuzhiyun struct resource *regs;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun int ret, irq;
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
101*4882a593Smuzhiyun if (!regs) {
102*4882a593Smuzhiyun dev_err(dev, "no registers defined\n");
103*4882a593Smuzhiyun return -EINVAL;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun irq = platform_get_irq(pdev, 0);
107*4882a593Smuzhiyun if (irq < 0) {
108*4882a593Smuzhiyun if (irq != -EPROBE_DEFER)
109*4882a593Smuzhiyun dev_err(dev, "cannot get irq\n");
110*4882a593Smuzhiyun return irq;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun memset(&port8250, 0, sizeof(port8250));
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun ret = device_property_read_u32(dev, "clock-frequency",
116*4882a593Smuzhiyun &port8250.port.uartclk);
117*4882a593Smuzhiyun if (ret)
118*4882a593Smuzhiyun return ret;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun spin_lock_init(&port8250.port.lock);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun port8250.port.mapbase = regs->start;
123*4882a593Smuzhiyun port8250.port.irq = irq;
124*4882a593Smuzhiyun port8250.port.handle_irq = fsl8250_handle_irq;
125*4882a593Smuzhiyun port8250.port.type = PORT_16550A;
126*4882a593Smuzhiyun port8250.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
127*4882a593Smuzhiyun | UPF_FIXED_PORT | UPF_IOREMAP
128*4882a593Smuzhiyun | UPF_FIXED_TYPE;
129*4882a593Smuzhiyun port8250.port.dev = dev;
130*4882a593Smuzhiyun port8250.port.mapsize = resource_size(regs);
131*4882a593Smuzhiyun port8250.port.iotype = UPIO_MEM;
132*4882a593Smuzhiyun port8250.port.irqflags = IRQF_SHARED;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun port8250.port.membase = devm_ioremap(dev, port8250.port.mapbase,
135*4882a593Smuzhiyun port8250.port.mapsize);
136*4882a593Smuzhiyun if (!port8250.port.membase)
137*4882a593Smuzhiyun return -ENOMEM;
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
140*4882a593Smuzhiyun if (!data)
141*4882a593Smuzhiyun return -ENOMEM;
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun data->line = serial8250_register_8250_port(&port8250);
144*4882a593Smuzhiyun if (data->line < 0)
145*4882a593Smuzhiyun return data->line;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun platform_set_drvdata(pdev, data);
148*4882a593Smuzhiyun return 0;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
fsl8250_acpi_remove(struct platform_device * pdev)151*4882a593Smuzhiyun static int fsl8250_acpi_remove(struct platform_device *pdev)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun struct fsl8250_data *data = platform_get_drvdata(pdev);
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun serial8250_unregister_port(data->line);
156*4882a593Smuzhiyun return 0;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun static const struct acpi_device_id fsl_8250_acpi_id[] = {
160*4882a593Smuzhiyun { "NXP0018", 0 },
161*4882a593Smuzhiyun { },
162*4882a593Smuzhiyun };
163*4882a593Smuzhiyun MODULE_DEVICE_TABLE(acpi, fsl_8250_acpi_id);
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun static struct platform_driver fsl8250_platform_driver = {
166*4882a593Smuzhiyun .driver = {
167*4882a593Smuzhiyun .name = "fsl-16550-uart",
168*4882a593Smuzhiyun .acpi_match_table = ACPI_PTR(fsl_8250_acpi_id),
169*4882a593Smuzhiyun },
170*4882a593Smuzhiyun .probe = fsl8250_acpi_probe,
171*4882a593Smuzhiyun .remove = fsl8250_acpi_remove,
172*4882a593Smuzhiyun };
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun module_platform_driver(fsl8250_platform_driver);
175*4882a593Smuzhiyun #endif
176