summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/8250
diff options
context:
space:
mode:
authorRodríguez Barbarin, José Javier <JoseJavier.Rodriguez@duagon.com>2023-07-05 16:15:14 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-07-25 21:21:26 +0300
commitc563831ba879480ea16afb56fb2f81a0a0eb17a6 (patch)
tree4803f168ba2674096a13f9f1a67fce0a72a5d4dd /drivers/tty/serial/8250
parent2554e6ba28a25f00cf1258d984a695e7ae391af2 (diff)
downloadlinux-c563831ba879480ea16afb56fb2f81a0a0eb17a6.tar.xz
8250_men_mcb: Make UART config auto configurable
The UART ports created by this driver were not usable out of the box, so let the configuration be handled by the 8250 UART subsystem. This makes the implementation simpler and the UART port more usable. The 8250 UART subsystem will take care of requesting the memory resources, but the driver needs to first read the register where the num ports is set, so a request of the resource is needed before registering the UART port. Co-developed-by: Jorge Sanjuan Garcia <jorge.sanjuangarcia@duagon.com> Signed-off-by: Jorge Sanjuan Garcia <jorge.sanjuangarcia@duagon.com> Signed-off-by: Javier Rodriguez <josejavier.rodriguez@duagon.com> Link: https://lore.kernel.org/r/20230705131423.30552-4-josejavier.rodriguez@duagon.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r--drivers/tty/serial/8250/8250_men_mcb.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c
index d6cfebb3ee8f..c3143ffddea0 100644
--- a/drivers/tty/serial/8250/8250_men_mcb.c
+++ b/drivers/tty/serial/8250/8250_men_mcb.c
@@ -81,15 +81,28 @@ static u32 men_lookup_uartclk(struct mcb_device *mdev)
return clkval;
}
-static int read_uarts_available_from_register(void __iomem *membase,
+static int read_uarts_available_from_register(struct resource *mem_res,
u8 *uarts_available)
{
void __iomem *mem;
int reg_value;
- mem = membase + MEN_Z025_REGISTER_OFFSET;
+ if (!request_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
+ MEM_UART_REGISTER_SIZE, KBUILD_MODNAME)) {
+ return -EBUSY;
+ }
+
+ mem = ioremap(mem_res->start + MEN_Z025_REGISTER_OFFSET,
+ MEM_UART_REGISTER_SIZE);
+ if (IS_ERR(mem))
+ return -ENOMEM;
+
+ reg_value = MEN_READ_REGISTER(mem);
+
+ iounmap(mem);
- reg_value = MEN_READ_REGISTER(membase);
+ release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
+ MEM_UART_REGISTER_SIZE);
*uarts_available = reg_value >> 4;
@@ -97,7 +110,7 @@ static int read_uarts_available_from_register(void __iomem *membase,
}
static int read_serial_data(struct mcb_device *mdev,
- void __iomem *membase,
+ struct resource *mem_res,
struct serial_8250_men_mcb_data *serial_data)
{
u8 uarts_available;
@@ -106,7 +119,7 @@ static int read_serial_data(struct mcb_device *mdev,
int res;
int i;
- res = read_uarts_available_from_register(membase, &uarts_available);
+ res = read_uarts_available_from_register(mem_res, &uarts_available);
if (res < 0)
return res;
@@ -146,7 +159,7 @@ static int read_serial_data(struct mcb_device *mdev,
}
static int init_serial_data(struct mcb_device *mdev,
- void __iomem *membase,
+ struct resource *mem_res,
struct serial_8250_men_mcb_data *serial_data)
{
switch (mdev->id) {
@@ -156,7 +169,7 @@ static int init_serial_data(struct mcb_device *mdev,
return 0;
case MEN_UART_ID_Z025:
case MEN_UART_ID_Z057:
- return read_serial_data(mdev, membase, serial_data);
+ return read_serial_data(mdev, mem_res, serial_data);
default:
dev_err(&mdev->dev, "no supported device!\n");
return -ENODEV;
@@ -170,15 +183,11 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
struct serial_8250_men_mcb_data *data;
struct resource *mem;
int i;
- void __iomem *membase;
int res;
mem = mcb_get_resource(mdev, IORESOURCE_MEM);
if (mem == NULL)
return -ENXIO;
- membase = devm_ioremap_resource(&mdev->dev, mem);
- if (IS_ERR(membase))
- return PTR_ERR_OR_ZERO(membase);
data = devm_kzalloc(&mdev->dev,
sizeof(struct serial_8250_men_mcb_data),
@@ -186,7 +195,7 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
if (!data)
return -ENOMEM;
- res = init_serial_data(mdev, membase, data);
+ res = init_serial_data(mdev, mem, data);
if (res < 0)
return res;
@@ -196,22 +205,18 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
mcb_set_drvdata(mdev, data);
for (i = 0; i < data->num_ports; i++) {
- uart.port.dev = mdev->dma_dev;
+ memset(&uart, 0, sizeof(struct uart_8250_port));
spin_lock_init(&uart.port.lock);
- uart.port.type = PORT_16550;
uart.port.flags = UPF_SKIP_TEST |
UPF_SHARE_IRQ |
- UPF_FIXED_TYPE;
+ UPF_BOOT_AUTOCONF |
+ UPF_IOREMAP;
uart.port.iotype = UPIO_MEM;
uart.port.uartclk = men_lookup_uartclk(mdev);
- uart.port.regshift = 0;
uart.port.irq = mcb_get_irq(mdev);
- uart.port.membase = membase;
- uart.port.fifosize = 60;
uart.port.mapbase = (unsigned long) mem->start
+ data->offset[i];
- uart.port.iobase = uart.port.mapbase;
/* ok, register the port */
data->line[i] = serial8250_register_8250_port(&uart);