Commit c0e1aa60 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Greg Kroah-Hartman

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: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20240506140308.4040735-2-andriy.shevchenko@linux.intel.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3093f180
...@@ -111,6 +111,7 @@ struct serial8250_config { ...@@ -111,6 +111,7 @@ struct serial8250_config {
#define SERIAL8250_PORT(_base, _irq) SERIAL8250_PORT_FLAGS(_base, _irq, 0) #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) 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; } ...@@ -301,6 +302,12 @@ static inline int serial8250_pnp_init(void) { return 0; }
static inline void serial8250_pnp_exit(void) { } static inline void serial8250_pnp_exit(void) { }
#endif #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 #ifdef CONFIG_SERIAL_8250_FINTEK
int fintek_8250_probe(struct uart_8250_port *uart); int fintek_8250_probe(struct uart_8250_port *uart);
#else #else
......
...@@ -77,13 +77,6 @@ static const struct old_serial_port old_serial_port[] = { ...@@ -77,13 +77,6 @@ static const struct old_serial_port old_serial_port[] = {
#define UART_NR CONFIG_SERIAL_8250_NR_UARTS #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 irq_info {
struct hlist_node node; struct hlist_node node;
int irq; int irq;
...@@ -348,44 +341,7 @@ static void univ8250_release_irq(struct uart_8250_port *up) ...@@ -348,44 +341,7 @@ static void univ8250_release_irq(struct uart_8250_port *up)
serial_unlink_irq_chain(up); serial_unlink_irq_chain(up);
} }
#ifdef CONFIG_SERIAL_8250_RSA const struct uart_ops *univ8250_port_base_ops = NULL;
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;
static struct uart_ops univ8250_port_ops; static struct uart_ops univ8250_port_ops;
static const struct uart_8250_ops univ8250_driver_ops = { static const struct uart_8250_ops univ8250_driver_ops = {
...@@ -424,69 +380,6 @@ void serial8250_set_isa_configurator( ...@@ -424,69 +380,6 @@ void serial8250_set_isa_configurator(
} }
EXPORT_SYMBOL(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) static inline void serial8250_apply_quirks(struct uart_8250_port *up)
{ {
up->port.quirks |= skip_txen_test ? UPQ_NO_TXEN_TEST : 0; 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) ...@@ -504,8 +397,8 @@ static struct uart_8250_port *serial8250_setup_port(int index)
up->port.port_id = index; up->port.port_id = index;
serial8250_init_port(up); serial8250_init_port(up);
if (!base_ops) if (!univ8250_port_base_ops)
base_ops = up->port.ops; univ8250_port_base_ops = up->port.ops;
up->port.ops = &univ8250_port_ops; up->port.ops = &univ8250_port_ops;
timer_setup(&up->timer, serial8250_timeout, 0); timer_setup(&up->timer, serial8250_timeout, 0);
...@@ -539,7 +432,7 @@ static void __init serial8250_isa_init_ports(void) ...@@ -539,7 +432,7 @@ static void __init serial8250_isa_init_ports(void)
serial8250_setup_port(i); serial8250_setup_port(i);
/* chain base port ops to support Remote Supervisor Adapter */ /* 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); univ8250_rsa_support(&univ8250_port_ops);
if (share_irqs) if (share_irqs)
...@@ -1312,10 +1205,6 @@ MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STR ...@@ -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_param(skip_txen_test, uint, 0644);
MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time"); 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); MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
#ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS #ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS
...@@ -1338,11 +1227,6 @@ static void __used s8250_options(void) ...@@ -1338,11 +1227,6 @@ static void __used s8250_options(void)
module_param_cb(share_irqs, &param_ops_uint, &share_irqs, 0644); module_param_cb(share_irqs, &param_ops_uint, &share_irqs, 0644);
module_param_cb(nr_uarts, &param_ops_uint, &nr_uarts, 0644); module_param_cb(nr_uarts, &param_ops_uint, &nr_uarts, 0644);
module_param_cb(skip_txen_test, &param_ops_uint, &skip_txen_test, 0644); module_param_cb(skip_txen_test, &param_ops_uint, &skip_txen_test, 0644);
#ifdef CONFIG_SERIAL_8250_RSA
__module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
&param_array_ops, .arr = &__param_arr_probe_rsa,
0444, -1, 0);
#endif
} }
#else #else
MODULE_ALIAS("8250_core"); MODULE_ALIAS("8250_core");
......
// 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,
&param_array_ops, .arr = &__param_arr_probe_rsa,
0444, -1, 0);
}
#endif
#endif
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o
8250-y := 8250_core.o 8250-y := 8250_core.o
8250-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.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-y := 8250_port.o
8250_base-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o 8250_base-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o
8250_base-$(CONFIG_SERIAL_8250_DWLIB) += 8250_dwlib.o 8250_base-$(CONFIG_SERIAL_8250_DWLIB) += 8250_dwlib.o
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment