forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/tty/serial/8250/8250_fsl.c
....@@ -1,15 +1,12 @@
11 // SPDX-License-Identifier: GPL-2.0
2
-#include <linux/serial_reg.h>
3
-#include <linux/serial_8250.h>
4
-
5
-#include "8250.h"
6
-
72 /*
83 * Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker.
4
+ * Copyright 2020 NXP
5
+ * Copyright 2020 Puresoftware Ltd.
96 *
107 * This isn't a full driver; it just provides an alternate IRQ
11
- * handler to deal with an errata. Everything else is just
12
- * using the bog standard 8250 support.
8
+ * handler to deal with an errata and provide ACPI wrapper.
9
+ * Everything else is just using the bog standard 8250 support.
1310 *
1411 * We follow code flow of serial8250_default_handle_irq() but add
1512 * a check for a break and insert a dummy read on the Rx for the
....@@ -19,6 +16,16 @@
1916 * field to carry the "what we just did" information from the one
2017 * IRQ event to the next one.
2118 */
19
+
20
+#include <linux/acpi.h>
21
+#include <linux/serial_reg.h>
22
+#include <linux/serial_8250.h>
23
+
24
+#include "8250.h"
25
+
26
+struct fsl8250_data {
27
+ int line;
28
+};
2229
2330 int fsl8250_handle_irq(struct uart_port *port)
2431 {
....@@ -53,9 +60,18 @@
5360
5461 /* Stop processing interrupts on input overrun */
5562 if ((orig_lsr & UART_LSR_OE) && (up->overrun_backoff_time_ms > 0)) {
63
+ unsigned int ca_flags;
5664 unsigned long delay;
65
+ bool is_console;
5766
67
+ is_console = uart_console(port);
68
+
69
+ if (is_console)
70
+ console_atomic_lock(&ca_flags);
5871 up->ier = port->serial_in(port, UART_IER);
72
+ if (is_console)
73
+ console_atomic_unlock(ca_flags);
74
+
5975 if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) {
6076 port->ops->stop_rx(port);
6177 } else {
....@@ -71,11 +87,98 @@
7187
7288 serial8250_modem_status(up);
7389
74
- if (lsr & UART_LSR_THRE)
90
+ if ((lsr & UART_LSR_THRE) && (up->ier & UART_IER_THRI))
7591 serial8250_tx_chars(up);
7692
7793 up->lsr_saved_flags = orig_lsr;
78
- spin_unlock_irqrestore(&up->port.lock, flags);
94
+ uart_unlock_and_check_sysrq(&up->port, flags);
7995 return 1;
8096 }
8197 EXPORT_SYMBOL_GPL(fsl8250_handle_irq);
98
+
99
+#ifdef CONFIG_ACPI
100
+static int fsl8250_acpi_probe(struct platform_device *pdev)
101
+{
102
+ struct fsl8250_data *data;
103
+ struct uart_8250_port port8250;
104
+ struct device *dev = &pdev->dev;
105
+ struct resource *regs;
106
+
107
+ int ret, irq;
108
+
109
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
110
+ if (!regs) {
111
+ dev_err(dev, "no registers defined\n");
112
+ return -EINVAL;
113
+ }
114
+
115
+ irq = platform_get_irq(pdev, 0);
116
+ if (irq < 0) {
117
+ if (irq != -EPROBE_DEFER)
118
+ dev_err(dev, "cannot get irq\n");
119
+ return irq;
120
+ }
121
+
122
+ memset(&port8250, 0, sizeof(port8250));
123
+
124
+ ret = device_property_read_u32(dev, "clock-frequency",
125
+ &port8250.port.uartclk);
126
+ if (ret)
127
+ return ret;
128
+
129
+ spin_lock_init(&port8250.port.lock);
130
+
131
+ port8250.port.mapbase = regs->start;
132
+ port8250.port.irq = irq;
133
+ port8250.port.handle_irq = fsl8250_handle_irq;
134
+ port8250.port.type = PORT_16550A;
135
+ port8250.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
136
+ | UPF_FIXED_PORT | UPF_IOREMAP
137
+ | UPF_FIXED_TYPE;
138
+ port8250.port.dev = dev;
139
+ port8250.port.mapsize = resource_size(regs);
140
+ port8250.port.iotype = UPIO_MEM;
141
+ port8250.port.irqflags = IRQF_SHARED;
142
+
143
+ port8250.port.membase = devm_ioremap(dev, port8250.port.mapbase,
144
+ port8250.port.mapsize);
145
+ if (!port8250.port.membase)
146
+ return -ENOMEM;
147
+
148
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
149
+ if (!data)
150
+ return -ENOMEM;
151
+
152
+ data->line = serial8250_register_8250_port(&port8250);
153
+ if (data->line < 0)
154
+ return data->line;
155
+
156
+ platform_set_drvdata(pdev, data);
157
+ return 0;
158
+}
159
+
160
+static int fsl8250_acpi_remove(struct platform_device *pdev)
161
+{
162
+ struct fsl8250_data *data = platform_get_drvdata(pdev);
163
+
164
+ serial8250_unregister_port(data->line);
165
+ return 0;
166
+}
167
+
168
+static const struct acpi_device_id fsl_8250_acpi_id[] = {
169
+ { "NXP0018", 0 },
170
+ { },
171
+};
172
+MODULE_DEVICE_TABLE(acpi, fsl_8250_acpi_id);
173
+
174
+static struct platform_driver fsl8250_platform_driver = {
175
+ .driver = {
176
+ .name = "fsl-16550-uart",
177
+ .acpi_match_table = ACPI_PTR(fsl_8250_acpi_id),
178
+ },
179
+ .probe = fsl8250_acpi_probe,
180
+ .remove = fsl8250_acpi_remove,
181
+};
182
+
183
+module_platform_driver(fsl8250_platform_driver);
184
+#endif