mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-06 05:06:29 +00:00
serial: 8250: Extract RSA bits
Extract RSA bits to a separate module for better maintenance and to reduce a churn on 8250_core part changes when it's solely related to the former. No functional changes intended. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://lore.kernel.org/r/20240506140308.4040735-2-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
3093f180bc
commit
c0e1aa60d6
@ -111,6 +111,7 @@ struct serial8250_config {
|
||||
|
||||
#define SERIAL8250_PORT(_base, _irq) SERIAL8250_PORT_FLAGS(_base, _irq, 0)
|
||||
|
||||
extern const struct uart_ops *univ8250_port_base_ops;
|
||||
|
||||
static inline int serial_in(struct uart_8250_port *up, int offset)
|
||||
{
|
||||
@ -301,6 +302,12 @@ static inline int serial8250_pnp_init(void) { return 0; }
|
||||
static inline void serial8250_pnp_exit(void) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_RSA
|
||||
void univ8250_rsa_support(struct uart_ops *ops);
|
||||
#else
|
||||
static inline void univ8250_rsa_support(struct uart_ops *ops) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_FINTEK
|
||||
int fintek_8250_probe(struct uart_8250_port *uart);
|
||||
#else
|
||||
|
@ -77,13 +77,6 @@ static const struct old_serial_port old_serial_port[] = {
|
||||
|
||||
#define UART_NR CONFIG_SERIAL_8250_NR_UARTS
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_RSA
|
||||
|
||||
#define PORT_RSA_MAX 4
|
||||
static unsigned long probe_rsa[PORT_RSA_MAX];
|
||||
static unsigned int probe_rsa_count;
|
||||
#endif /* CONFIG_SERIAL_8250_RSA */
|
||||
|
||||
struct irq_info {
|
||||
struct hlist_node node;
|
||||
int irq;
|
||||
@ -348,44 +341,7 @@ static void univ8250_release_irq(struct uart_8250_port *up)
|
||||
serial_unlink_irq_chain(up);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_RSA
|
||||
static int serial8250_request_rsa_resource(struct uart_8250_port *up)
|
||||
{
|
||||
unsigned long start = UART_RSA_BASE << up->port.regshift;
|
||||
unsigned int size = 8 << up->port.regshift;
|
||||
struct uart_port *port = &up->port;
|
||||
int ret = -EINVAL;
|
||||
|
||||
switch (port->iotype) {
|
||||
case UPIO_HUB6:
|
||||
case UPIO_PORT:
|
||||
start += port->iobase;
|
||||
if (request_region(start, size, "serial-rsa"))
|
||||
ret = 0;
|
||||
else
|
||||
ret = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void serial8250_release_rsa_resource(struct uart_8250_port *up)
|
||||
{
|
||||
unsigned long offset = UART_RSA_BASE << up->port.regshift;
|
||||
unsigned int size = 8 << up->port.regshift;
|
||||
struct uart_port *port = &up->port;
|
||||
|
||||
switch (port->iotype) {
|
||||
case UPIO_HUB6:
|
||||
case UPIO_PORT:
|
||||
release_region(port->iobase + offset, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct uart_ops *base_ops;
|
||||
const struct uart_ops *univ8250_port_base_ops = NULL;
|
||||
static struct uart_ops univ8250_port_ops;
|
||||
|
||||
static const struct uart_8250_ops univ8250_driver_ops = {
|
||||
@ -424,69 +380,6 @@ void serial8250_set_isa_configurator(
|
||||
}
|
||||
EXPORT_SYMBOL(serial8250_set_isa_configurator);
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_RSA
|
||||
|
||||
static void univ8250_config_port(struct uart_port *port, int flags)
|
||||
{
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
|
||||
up->probe &= ~UART_PROBE_RSA;
|
||||
if (port->type == PORT_RSA) {
|
||||
if (serial8250_request_rsa_resource(up) == 0)
|
||||
up->probe |= UART_PROBE_RSA;
|
||||
} else if (flags & UART_CONFIG_TYPE) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < probe_rsa_count; i++) {
|
||||
if (probe_rsa[i] == up->port.iobase) {
|
||||
if (serial8250_request_rsa_resource(up) == 0)
|
||||
up->probe |= UART_PROBE_RSA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base_ops->config_port(port, flags);
|
||||
|
||||
if (port->type != PORT_RSA && up->probe & UART_PROBE_RSA)
|
||||
serial8250_release_rsa_resource(up);
|
||||
}
|
||||
|
||||
static int univ8250_request_port(struct uart_port *port)
|
||||
{
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
int ret;
|
||||
|
||||
ret = base_ops->request_port(port);
|
||||
if (ret == 0 && port->type == PORT_RSA) {
|
||||
ret = serial8250_request_rsa_resource(up);
|
||||
if (ret < 0)
|
||||
base_ops->release_port(port);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void univ8250_release_port(struct uart_port *port)
|
||||
{
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
|
||||
if (port->type == PORT_RSA)
|
||||
serial8250_release_rsa_resource(up);
|
||||
base_ops->release_port(port);
|
||||
}
|
||||
|
||||
static void univ8250_rsa_support(struct uart_ops *ops)
|
||||
{
|
||||
ops->config_port = univ8250_config_port;
|
||||
ops->request_port = univ8250_request_port;
|
||||
ops->release_port = univ8250_release_port;
|
||||
}
|
||||
|
||||
#else
|
||||
#define univ8250_rsa_support(x) do { } while (0)
|
||||
#endif /* CONFIG_SERIAL_8250_RSA */
|
||||
|
||||
static inline void serial8250_apply_quirks(struct uart_8250_port *up)
|
||||
{
|
||||
up->port.quirks |= skip_txen_test ? UPQ_NO_TXEN_TEST : 0;
|
||||
@ -504,8 +397,8 @@ static struct uart_8250_port *serial8250_setup_port(int index)
|
||||
up->port.port_id = index;
|
||||
|
||||
serial8250_init_port(up);
|
||||
if (!base_ops)
|
||||
base_ops = up->port.ops;
|
||||
if (!univ8250_port_base_ops)
|
||||
univ8250_port_base_ops = up->port.ops;
|
||||
up->port.ops = &univ8250_port_ops;
|
||||
|
||||
timer_setup(&up->timer, serial8250_timeout, 0);
|
||||
@ -539,7 +432,7 @@ static void __init serial8250_isa_init_ports(void)
|
||||
serial8250_setup_port(i);
|
||||
|
||||
/* chain base port ops to support Remote Supervisor Adapter */
|
||||
univ8250_port_ops = *base_ops;
|
||||
univ8250_port_ops = *univ8250_port_base_ops;
|
||||
univ8250_rsa_support(&univ8250_port_ops);
|
||||
|
||||
if (share_irqs)
|
||||
@ -1312,10 +1205,6 @@ MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STR
|
||||
module_param(skip_txen_test, uint, 0644);
|
||||
MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_RSA
|
||||
module_param_hw_array(probe_rsa, ulong, ioport, &probe_rsa_count, 0444);
|
||||
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
|
||||
#endif
|
||||
MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS
|
||||
@ -1338,11 +1227,6 @@ static void __used s8250_options(void)
|
||||
module_param_cb(share_irqs, ¶m_ops_uint, &share_irqs, 0644);
|
||||
module_param_cb(nr_uarts, ¶m_ops_uint, &nr_uarts, 0644);
|
||||
module_param_cb(skip_txen_test, ¶m_ops_uint, &skip_txen_test, 0644);
|
||||
#ifdef CONFIG_SERIAL_8250_RSA
|
||||
__module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
|
||||
¶m_array_ops, .arr = &__param_arr_probe_rsa,
|
||||
0444, -1, 0);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
MODULE_ALIAS("8250_core");
|
||||
|
133
drivers/tty/serial/8250/8250_rsa.c
Normal file
133
drivers/tty/serial/8250/8250_rsa.c
Normal file
@ -0,0 +1,133 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_8250.h>
|
||||
|
||||
#include "8250.h"
|
||||
|
||||
#define PORT_RSA_MAX 4
|
||||
static unsigned long probe_rsa[PORT_RSA_MAX];
|
||||
static unsigned int probe_rsa_count;
|
||||
|
||||
static int rsa8250_request_resource(struct uart_8250_port *up)
|
||||
{
|
||||
unsigned long start = UART_RSA_BASE << up->port.regshift;
|
||||
unsigned int size = 8 << up->port.regshift;
|
||||
struct uart_port *port = &up->port;
|
||||
int ret = -EINVAL;
|
||||
|
||||
switch (port->iotype) {
|
||||
case UPIO_HUB6:
|
||||
case UPIO_PORT:
|
||||
start += port->iobase;
|
||||
if (request_region(start, size, "serial-rsa"))
|
||||
ret = 0;
|
||||
else
|
||||
ret = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rsa8250_release_resource(struct uart_8250_port *up)
|
||||
{
|
||||
unsigned long offset = UART_RSA_BASE << up->port.regshift;
|
||||
unsigned int size = 8 << up->port.regshift;
|
||||
struct uart_port *port = &up->port;
|
||||
|
||||
switch (port->iotype) {
|
||||
case UPIO_HUB6:
|
||||
case UPIO_PORT:
|
||||
release_region(port->iobase + offset, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void univ8250_config_port(struct uart_port *port, int flags)
|
||||
{
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
unsigned int i;
|
||||
|
||||
up->probe &= ~UART_PROBE_RSA;
|
||||
if (port->type == PORT_RSA) {
|
||||
if (rsa8250_request_resource(up) == 0)
|
||||
up->probe |= UART_PROBE_RSA;
|
||||
} else if (flags & UART_CONFIG_TYPE) {
|
||||
for (i = 0; i < probe_rsa_count; i++) {
|
||||
if (probe_rsa[i] == up->port.iobase) {
|
||||
if (rsa8250_request_resource(up) == 0)
|
||||
up->probe |= UART_PROBE_RSA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
univ8250_port_base_ops->config_port(port, flags);
|
||||
|
||||
if (port->type != PORT_RSA && up->probe & UART_PROBE_RSA)
|
||||
rsa8250_release_resource(up);
|
||||
}
|
||||
|
||||
static int univ8250_request_port(struct uart_port *port)
|
||||
{
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
int ret;
|
||||
|
||||
ret = univ8250_port_base_ops->request_port(port);
|
||||
if (ret == 0 && port->type == PORT_RSA) {
|
||||
ret = rsa8250_request_resource(up);
|
||||
if (ret < 0)
|
||||
univ8250_port_base_ops->release_port(port);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void univ8250_release_port(struct uart_port *port)
|
||||
{
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
|
||||
if (port->type == PORT_RSA)
|
||||
rsa8250_release_resource(up);
|
||||
univ8250_port_base_ops->release_port(port);
|
||||
}
|
||||
|
||||
void univ8250_rsa_support(struct uart_ops *ops)
|
||||
{
|
||||
ops->config_port = univ8250_config_port;
|
||||
ops->request_port = univ8250_request_port;
|
||||
ops->release_port = univ8250_release_port;
|
||||
}
|
||||
|
||||
module_param_hw_array(probe_rsa, ulong, ioport, &probe_rsa_count, 0444);
|
||||
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS
|
||||
#ifndef MODULE
|
||||
/*
|
||||
* Keep the old "8250" name working as well for the module options so we don't
|
||||
* break people. We need to keep the names identical and the convenient macros
|
||||
* will happily refuse to let us do that by failing the build with redefinition
|
||||
* errors of global variables. So we stick them inside a dummy function to
|
||||
* avoid those conflicts. The options still get parsed, and the redefined
|
||||
* MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive.
|
||||
*
|
||||
* This is hacky. I'm sorry.
|
||||
*/
|
||||
static void __used rsa8250_options(void)
|
||||
{
|
||||
#undef MODULE_PARAM_PREFIX
|
||||
#define MODULE_PARAM_PREFIX "8250_core."
|
||||
|
||||
__module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
|
||||
¶m_array_ops, .arr = &__param_arr_probe_rsa,
|
||||
0444, -1, 0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -6,6 +6,7 @@
|
||||
obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o
|
||||
8250-y := 8250_core.o
|
||||
8250-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
|
||||
8250-$(CONFIG_SERIAL_8250_RSA) += 8250_rsa.o
|
||||
8250_base-y := 8250_port.o
|
||||
8250_base-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o
|
||||
8250_base-$(CONFIG_SERIAL_8250_DWLIB) += 8250_dwlib.o
|
||||
|
Loading…
Reference in New Issue
Block a user