File Index
Files and directories
Sign in
FILE

8250_rsa.c

File preview with syntax highlighting.

linux-6.19.14/drivers/tty/serial/8250/8250_rsa.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2
  3#include <linux/errno.h>
  4#include <linux/ioport.h>
  5#include <linux/module.h>
  6#include <linux/moduleparam.h>
  7
  8#include <linux/serial.h>
  9#include <linux/serial_8250.h>
 10
 11#include "8250.h"
 12
 13#define PORT_RSA_MAX 4
 14static unsigned long probe_rsa[PORT_RSA_MAX];
 15static unsigned int probe_rsa_count;
 16
 17static const struct uart_ops *core_port_base_ops;
 18
 19static int rsa8250_request_resource(struct uart_8250_port *up)
 20{
 21	struct uart_port *port = &up->port;
 22	unsigned long start = UART_RSA_BASE << port->regshift;
 23	unsigned int size = 8 << port->regshift;
 24
 25	switch (port->iotype) {
 26	case UPIO_HUB6:
 27	case UPIO_PORT:
 28		start += port->iobase;
 29		if (!request_region(start, size, "serial-rsa"))
 30			return -EBUSY;
 31		return 0;
 32	default:
 33		return -EINVAL;
 34	}
 35}
 36
 37static void rsa8250_release_resource(struct uart_8250_port *up)
 38{
 39	struct uart_port *port = &up->port;
 40	unsigned long offset = UART_RSA_BASE << port->regshift;
 41	unsigned int size = 8 << port->regshift;
 42
 43	switch (port->iotype) {
 44	case UPIO_HUB6:
 45	case UPIO_PORT:
 46		release_region(port->iobase + offset, size);
 47		break;
 48	default:
 49		break;
 50	}
 51}
 52
 53static void univ8250_config_port(struct uart_port *port, int flags)
 54{
 55	struct uart_8250_port *up = up_to_u8250p(port);
 56	unsigned int i;
 57
 58	up->probe &= ~UART_PROBE_RSA;
 59	if (port->type == PORT_RSA) {
 60		if (rsa8250_request_resource(up) == 0)
 61			up->probe |= UART_PROBE_RSA;
 62	} else if (flags & UART_CONFIG_TYPE) {
 63		for (i = 0; i < probe_rsa_count; i++) {
 64			if (probe_rsa[i] == up->port.iobase) {
 65				if (rsa8250_request_resource(up) == 0)
 66					up->probe |= UART_PROBE_RSA;
 67				break;
 68			}
 69		}
 70	}
 71
 72	core_port_base_ops->config_port(port, flags);
 73
 74	if (port->type != PORT_RSA && up->probe & UART_PROBE_RSA)
 75		rsa8250_release_resource(up);
 76}
 77
 78static int univ8250_request_port(struct uart_port *port)
 79{
 80	struct uart_8250_port *up = up_to_u8250p(port);
 81	int ret;
 82
 83	ret = core_port_base_ops->request_port(port);
 84	if (ret == 0 && port->type == PORT_RSA) {
 85		ret = rsa8250_request_resource(up);
 86		if (ret < 0)
 87			core_port_base_ops->release_port(port);
 88	}
 89
 90	return ret;
 91}
 92
 93static void univ8250_release_port(struct uart_port *port)
 94{
 95	struct uart_8250_port *up = up_to_u8250p(port);
 96
 97	if (port->type == PORT_RSA)
 98		rsa8250_release_resource(up);
 99	core_port_base_ops->release_port(port);
100}
101
102/*
103 * It is not allowed to directly reference any symbols from 8250.ko here as
104 * that would result in a dependency loop between the 8250.ko and
105 * 8250_base.ko modules. This function is called from 8250.ko and is used to
106 * break the symbolic dependency cycle. Anything that is needed from 8250.ko
107 * has to be passed as pointers to this function which then can adjust those
108 * variables on 8250.ko side or store them locally as needed.
109 */
110void univ8250_rsa_support(struct uart_ops *ops, const struct uart_ops *core_ops)
111{
112	core_port_base_ops = core_ops;
113	ops->config_port  = univ8250_config_port;
114	ops->request_port = univ8250_request_port;
115	ops->release_port = univ8250_release_port;
116}
117EXPORT_SYMBOL_FOR_MODULES(univ8250_rsa_support, "8250");
118
119module_param_hw_array(probe_rsa, ulong, ioport, &probe_rsa_count, 0444);
120MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
121
122/*
123 * Attempts to turn on the RSA FIFO.  Returns zero on failure.
124 * We set the port uart clock rate if we succeed.
125 */
126static int __rsa_enable(struct uart_8250_port *up)
127{
128	unsigned char mode;
129	int result;
130
131	mode = serial_in(up, UART_RSA_MSR);
132	result = mode & UART_RSA_MSR_FIFO;
133
134	if (!result) {
135		serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
136		mode = serial_in(up, UART_RSA_MSR);
137		result = mode & UART_RSA_MSR_FIFO;
138	}
139
140	if (result)
141		up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
142
143	return result;
144}
145
146/*
147 * If this is an RSA port, see if we can kick it up to the higher speed clock.
148 */
149void rsa_enable(struct uart_8250_port *up)
150{
151	if (up->port.type != PORT_RSA)
152		return;
153
154	if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
155		guard(uart_port_lock_irq)(&up->port);
156		__rsa_enable(up);
157	}
158	if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
159		serial_out(up, UART_RSA_FRR, 0);
160}
161
162/*
163 * Attempts to turn off the RSA FIFO and resets the RSA board back to 115kbps compat mode. It is
164 * unknown why interrupts were disabled in here. However, the caller is expected to preserve this
165 * behaviour by grabbing the spinlock before calling this function.
166 */
167void rsa_disable(struct uart_8250_port *up)
168{
169	unsigned char mode;
170	int result;
171
172	if (up->port.type != PORT_RSA)
173		return;
174
175	if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16)
176		return;
177
178	guard(uart_port_lock_irq)(&up->port);
179
180	mode = serial_in(up, UART_RSA_MSR);
181	result = !(mode & UART_RSA_MSR_FIFO);
182
183	if (!result) {
184		serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
185		mode = serial_in(up, UART_RSA_MSR);
186		result = !(mode & UART_RSA_MSR_FIFO);
187	}
188
189	if (result)
190		up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
191}
192
193void rsa_autoconfig(struct uart_8250_port *up)
194{
195	/* Only probe for RSA ports if we got the region. */
196	if (up->port.type != PORT_16550A)
197		return;
198	if (!(up->probe & UART_PROBE_RSA))
199		return;
200
201	if (__rsa_enable(up))
202		up->port.type = PORT_RSA;
203}
204
205void rsa_reset(struct uart_8250_port *up)
206{
207	if (up->port.type != PORT_RSA)
208		return;
209
210	serial_out(up, UART_RSA_FRR, 0);
211}
~/ Read-only file preview.