dev/uart: Use a linker set to find uart classes

When the uart is configured via the environment we need to find the
uart class with a specified name. Currently to do this with an
incomplete list of uarts. As we may not have included all uarts in the
kernel each class is defined as weak.

Switch to a linker set so the list is always up to date based on what
is included in the kernel, and the class can be static.

Reviewed by:	imp
Sponsored by:	Arm Ltd
Differential Revision:	https://reviews.freebsd.org/D43361
This commit is contained in:
Andrew Turner 2024-01-08 15:02:29 +00:00
parent 202890922e
commit 949670f8f4
4 changed files with 9 additions and 9 deletions

View file

@ -29,6 +29,8 @@
#ifndef _DEV_UART_H_
#define _DEV_UART_H_
#include <sys/linker_set.h>
/*
* Bus access structure. This structure holds the minimum information needed
* to access the UART. The rclk field, although not important to actually
@ -99,6 +101,8 @@ uart_setreg(struct uart_bas *bas, int reg, int value)
*/
struct uart_class;
SET_DECLARE(uart_class_set, struct uart_class);
extern struct uart_class uart_ns8250_class __attribute__((weak));
extern struct uart_class uart_quicc_class __attribute__((weak));
extern struct uart_class uart_z8530_class __attribute__((weak));

View file

@ -451,6 +451,7 @@ struct uart_class uart_ns8250_class = {
.uc_rclk = DEFAULT_RCLK,
.uc_rshift = 0
};
DATA_SET(uart_class_set, uart_ns8250_class);
/*
* XXX -- refactor out ACPI and FDT ifdefs

View file

@ -309,6 +309,7 @@ struct uart_class uart_z8530_class = {
.uc_rclk = DEFAULT_RCLK,
.uc_rshift = 0
};
DATA_SET(uart_class_set, uart_z8530_class);
#define SIGCHG(c, i, s, d) \
if (c) { \

View file

@ -48,11 +48,6 @@
#define UART_TAG_XO 9
#define UART_TAG_BD 10
static struct uart_class *uart_classes[] = {
&uart_ns8250_class,
&uart_z8530_class,
};
static bus_addr_t
uart_parse_addr(const char **p)
{
@ -62,13 +57,12 @@ uart_parse_addr(const char **p)
static struct uart_class *
uart_parse_class(struct uart_class *class, const char **p)
{
struct uart_class *uc;
struct uart_class **puc, *uc;
const char *nm;
size_t len;
u_int i;
for (i = 0; i < nitems(uart_classes); i++) {
uc = uart_classes[i];
SET_FOREACH(puc, uart_class_set) {
uc = *puc;
nm = uart_getname(uc);
if (nm == NULL || *nm == '\0')
continue;