[parisc-linux] RFC on superio serial patch
Randolph Chung
Randolph Chung <randolph@tausq.org>
Sun, 19 Jan 2003 23:27:00 -0800
The attached patch uses a slightly different mechanism to address the
circular dependency between SuperIO PCI init and serial init.
this is not particularly clean, but hopefully it will be more
acceptable for submission upstream. Any comments?
Index: drivers/parisc/superio.c
===================================================================
RCS file: /var/cvs/linux-2.5/drivers/parisc/superio.c,v
retrieving revision 1.7
diff -u -p -r1.7 superio.c
--- drivers/parisc/superio.c 17 Dec 2002 19:53:29 -0000 1.7
+++ drivers/parisc/superio.c 20 Jan 2003 07:33:54 -0000
@@ -391,7 +391,7 @@ void __devinit
superio_serial_init(void)
{
#ifdef CONFIG_SERIAL_8250
- struct serial_struct *serial;
+ struct serial_struct serial;
int retval;
if (!sio_dev.irq_region)
@@ -400,47 +400,39 @@ superio_serial_init(void)
if (!sio_dev.iosapic_irq_enabled)
superio_init(&sio_dev);
- serial = kmalloc(2 * sizeof (struct serial_struct), GFP_KERNEL);
+ memset(&serial, 0, sizeof (struct serial_struct));
- if (!serial) {
- printk(KERN_WARNING "SuperIO: Could not get memory for serial struct.\n");
- return;
- }
-
- memset(serial, 0, 2 * sizeof (struct serial_struct));
-
- serial->type = PORT_16550A;
- serial->line = 0;
- serial->port = sio_dev.sp1_base;
- serial->port_high = 0;
- serial->irq = sio_dev.irq_region->data.irqbase + SP1_IRQ;
- serial->io_type = SERIAL_IO_PORT;
- serial->flags = 0;
- serial->xmit_fifo_size = 16;
- serial->custom_divisor = 0;
- serial->baud_base = 115200;
+ serial.type = PORT_16550A;
+ serial.line = 0;
+ serial.port = sio_dev.sp1_base;
+ serial.port_high = 0;
+ serial.irq = sio_dev.irq_region->data.irqbase + SP1_IRQ;
+ serial.io_type = SERIAL_IO_PORT;
+ serial.flags = 0;
+ serial.xmit_fifo_size = 16;
+ serial.custom_divisor = 0;
+ serial.baud_base = 115200;
- retval = register_serial(serial);
+ retval = register_serial(&serial);
if (retval < 0) {
printk(KERN_WARNING "SuperIO: Register Serial #0 failed.\n");
- kfree (serial);
return;
}
- serial++;
+ memset(&serial, 0, sizeof (struct serial_struct));
- serial->type = PORT_16550A;
- serial->line = 1;
- serial->port = sio_dev.sp2_base;
- serial->port_high = 0;
- serial->irq = sio_dev.irq_region->data.irqbase + SP2_IRQ;
- serial->io_type = SERIAL_IO_PORT;
- serial->flags = 0;
- serial->xmit_fifo_size = 16;
- serial->custom_divisor = 0;
- serial->baud_base = 115200;
+ serial.type = PORT_16550A;
+ serial.line = 1;
+ serial.port = sio_dev.sp2_base;
+ serial.port_high = 0;
+ serial.irq = sio_dev.irq_region->data.irqbase + SP2_IRQ;
+ serial.io_type = SERIAL_IO_PORT;
+ serial.flags = 0;
+ serial.xmit_fifo_size = 16;
+ serial.custom_divisor = 0;
+ serial.baud_base = 115200;
- retval = register_serial(serial);
+ retval = register_serial(&serial);
if (retval < 0)
printk(KERN_WARNING "SuperIO: Register Serial #1 failed.\n");
#endif /* CONFIG_SERIAL_8250 */
@@ -504,9 +496,6 @@ static int __devinit superio_probe(struc
#ifdef CONFIG_PARPORT_PC
superio_parport_init();
#endif
-#ifdef CONFIG_SERIAL_8250
- superio_serial_init();
-#endif
/* REVISIT : superio_fdc_init() ? */
return 0;
} else {
@@ -530,11 +519,6 @@ static struct pci_driver superio_driver
static int __init superio_modinit(void)
{
-#ifdef CONFIG_SERIAL_8250
- extern int serial8250_init(void);
- serial8250_init();
-#endif
-
return pci_module_init(&superio_driver);
}
Index: drivers/serial/8250.c
===================================================================
RCS file: /var/cvs/linux-2.5/drivers/serial/8250.c,v
retrieving revision 1.9
diff -u -p -r1.9 8250.c
--- drivers/serial/8250.c 11 Jan 2003 23:05:10 -0000 1.9
+++ drivers/serial/8250.c 20 Jan 2003 07:33:56 -0000
@@ -2032,12 +2032,9 @@ void serial8250_get_irq_map(unsigned int
}
}
-int __init serial8250_init(void)
+static int __init serial8250_init(void)
{
int ret, i;
-/* GROSS HACK for now -PB */
-static int beenhere = 0;
-if (beenhere++) return 1;
printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
"IRQ sharing %sabled\n", share_irqs ? "en" : "dis");
Index: drivers/serial/Makefile
===================================================================
RCS file: /var/cvs/linux-2.5/drivers/serial/Makefile,v
retrieving revision 1.9
diff -u -p -r1.9 Makefile
--- drivers/serial/Makefile 24 Dec 2002 22:43:16 -0000 1.9
+++ drivers/serial/Makefile 20 Jan 2003 07:33:56 -0000
@@ -29,3 +29,4 @@ obj-$(CONFIG_SERIAL_68328) += 68328seria
obj-$(CONFIG_SERIAL_68360) += 68360serial.o
obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o
obj-$(CONFIG_V850E_NB85E_UART) += nb85e_uart.o
+obj-$(CONFIG_PARISC) += parisc.o
--- /dev/null 2002-08-24 10:36:34.000000000 -0700
+++ drivers/serial/parisc.c 2003-01-19 23:33:34.000000000 -0800
@@ -0,0 +1,36 @@
+/*
+ * serial hooks for parisc-based serial drivers
+ *
+ * Copyright (C) 2003 Randolph Chung <tausq@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Right now this is here just for SuperIO based serial devices
+ * used on some parisc workstations. In the future it may also be
+ * used to implement other parisc-specific serial behavior.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/superio.h>
+
+static int __init parisc_serial_init(void)
+{
+#ifdef CONFIG_SUPERIO
+ /* The serial function on SuperIO is part of the LIO function;
+ * as such, superio cannot be written as a generic serial driver.
+ * The PCI portion of SuperIO is initialized first by
+ * drivers/parisc/superio.c. Only after the core serial
+ * functionalities are initialized, this driver is called to
+ * actually register the serial device with the generic 8250
+ * serial driver.
+ */
+ superio_serial_init();
+#endif
+}
+
+module_init(parisc_serial_init);
+
--
Randolph Chung
Debian GNU/Linux Developer, hppa/ia64 ports
http://www.tausq.org/