enum su_type su_type;
unsigned int type_probed; /* XXX Stupid */
int port_node;
- unsigned int irq;
#ifdef CONFIG_SERIO
- struct serio serio;
+ struct serio *serio;
int serio_open;
#endif
};
/* Stop-A is handled by drivers/char/keyboard.c now. */
if (up->su_type == SU_PORT_KBD) {
#ifdef CONFIG_SERIO
- serio_interrupt(&up->serio, ch, 0, regs);
+ serio_interrupt(up->serio, ch, 0, regs);
#endif
} else if (up->su_type == SU_PORT_MS) {
int ret = suncore_mouse_baud_detection(ch, is_break);
case 0:
#ifdef CONFIG_SERIO
- serio_interrupt(&up->serio, ch, 0, regs);
+ serio_interrupt(up->serio, ch, 0, regs);
#endif
break;
};
}
if (up->su_type != SU_PORT_PORT) {
- retval = request_irq(up->irq, sunsu_kbd_ms_interrupt,
+ retval = request_irq(up->port.irq, sunsu_kbd_ms_interrupt,
SA_SHIRQ, su_typev[up->su_type], up);
} else {
- retval = request_irq(up->irq, sunsu_serial_interrupt,
+ retval = request_irq(up->port.irq, sunsu_serial_interrupt,
SA_SHIRQ, su_typev[up->su_type], up);
}
if (retval) {
- printk("su: Cannot register IRQ %d\n", up->irq);
+ printk("su: Cannot register IRQ %d\n", up->port.irq);
return retval;
}
*/
(void) serial_in(up, UART_RX);
- free_irq(up->irq, up);
+ free_irq(up->port.irq, up);
}
static void
#ifdef CONFIG_SERIO
-static spinlock_t sunsu_serio_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sunsu_serio_lock);
static int sunsu_serio_write(struct serio *serio, unsigned char ch)
{
- struct uart_sunsu_port *up = serio->driver;
+ struct uart_sunsu_port *up = serio->port_data;
unsigned long flags;
int lsr;
static int sunsu_serio_open(struct serio *serio)
{
- struct uart_sunsu_port *up = serio->driver;
+ struct uart_sunsu_port *up = serio->port_data;
unsigned long flags;
int ret;
static void sunsu_serio_close(struct serio *serio)
{
- struct uart_sunsu_port *up = serio->driver;
+ struct uart_sunsu_port *up = serio->port_data;
unsigned long flags;
spin_lock_irqsave(&sunsu_serio_lock, flags);
{
unsigned char status1, status2, scratch, scratch2, scratch3;
unsigned char save_lcr, save_mcr;
- struct linux_ebus_device *dev = 0;
+ struct linux_ebus_device *dev = NULL;
struct linux_ebus *ebus;
#ifdef CONFIG_SPARC64
struct sparc_isa_bridge *isa_br;
* This is correct on both architectures.
*/
up->port.mapbase = dev->resource[0].start;
- up->irq = dev->irqs[0];
+ up->port.irq = dev->irqs[0];
goto ebus_done;
}
}
/* Same on sparc64. Cool architecure... */
up->port.membase = (char *) isa_dev->resource.start;
up->port.mapbase = isa_dev->resource.start;
- up->irq = isa_dev->irq;
+ up->port.irq = isa_dev->irq;
goto ebus_done;
}
}
/*
* There is no intr property on MrCoffee, so hardwire it.
*/
- up->irq = IRQ_4M(13);
+ up->port.irq = IRQ_4M(13);
#endif
ebus_done:
.major = TTY_MAJOR,
};
-static int __init sunsu_kbd_ms_init(void)
+static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel)
{
- struct uart_sunsu_port *up;
- int i;
+#ifdef CONFIG_SERIO
+ struct serio *serio;
+#endif
- for (i = 0, up = sunsu_ports; i < 2; i++, up++) {
- up->port.line = i;
- up->port.type = PORT_UNKNOWN;
- up->port.uartclk = (SU_BASE_BAUD * 16);
+ up->port.line = channel;
+ up->port.type = PORT_UNKNOWN;
+ up->port.uartclk = (SU_BASE_BAUD * 16);
- if (up->su_type == SU_PORT_KBD)
- up->cflag = B1200 | CS8 | CLOCAL | CREAD;
- else
- up->cflag = B4800 | CS8 | CLOCAL | CREAD;
+ if (up->su_type == SU_PORT_KBD)
+ up->cflag = B1200 | CS8 | CLOCAL | CREAD;
+ else
+ up->cflag = B4800 | CS8 | CLOCAL | CREAD;
- sunsu_autoconfig(up);
- if (up->port.type == PORT_UNKNOWN)
- continue;
+ sunsu_autoconfig(up);
+ if (up->port.type == PORT_UNKNOWN)
+ return -1;
- printk(KERN_INFO "su%d at 0x%p (irq = %s) is a %s\n",
- i,
- up->port.membase, __irq_itoa(up->irq),
- sunsu_type(&up->port));
+ printk(KERN_INFO "su%d at 0x%p (irq = %s) is a %s\n",
+ channel,
+ up->port.membase, __irq_itoa(up->port.irq),
+ sunsu_type(&up->port));
#ifdef CONFIG_SERIO
- memset(&up->serio, 0, sizeof(up->serio));
+ up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ memset(serio, 0, sizeof(*serio));
- up->serio.driver = up;
+ serio->port_data = up;
- up->serio.type = SERIO_RS232;
+ serio->type = SERIO_RS232;
if (up->su_type == SU_PORT_KBD) {
- up->serio.type |= SERIO_SUNKBD;
- up->serio.name = "sukbd";
+ serio->type |= SERIO_SUNKBD;
+ strlcpy(serio->name, "sukbd", sizeof(serio->name));
} else {
- up->serio.type |= (SERIO_SUN | (1 << 16));
- up->serio.name = "sums";
+ serio->type |= (SERIO_SUN | (1 << 16));
+ strlcpy(serio->name, "sums", sizeof(serio->name));
}
- up->serio.phys = (i == 0 ? "su/serio0" : "su/serio1");
+ strlcpy(serio->phys, (channel == 0 ? "su/serio0" : "su/serio1"),
+ sizeof(serio->phys));
- up->serio.write = sunsu_serio_write;
- up->serio.open = sunsu_serio_open;
- up->serio.close = sunsu_serio_close;
+ serio->write = sunsu_serio_write;
+ serio->open = sunsu_serio_open;
+ serio->close = sunsu_serio_close;
- serio_register_port(&up->serio);
+ serio_register_port(serio);
+ } else {
+ printk(KERN_WARNING "su%d: not enough memory for serio port\n",
+ channel);
+ }
#endif
- sunsu_startup(&up->port);
- }
+ sunsu_startup(&up->port);
return 0;
}
if (ret < 0)
return ret;
+ sunsu_serial_console_init();
for (i = 0; i < UART_NR; i++) {
struct uart_sunsu_port *up = &sunsu_ports[i];
if (scan.msx != -1 && scan.kbx != -1) {
sunsu_ports[0].su_type = SU_PORT_MS;
sunsu_ports[0].port_node = scan.msnode;
+ sunsu_kbd_ms_init(&sunsu_ports[0], 0);
+
sunsu_ports[1].su_type = SU_PORT_KBD;
sunsu_ports[1].port_node = scan.kbnode;
+ sunsu_kbd_ms_init(&sunsu_ports[1], 1);
- sunsu_kbd_ms_init();
return 0;
}
* Console must be initiated after the generic initialization.
*/
sunsu_serial_init();
- sunsu_serial_console_init();
return 0;
}
if (up->su_type == SU_PORT_MS ||
up->su_type == SU_PORT_KBD) {
#ifdef CONFIG_SERIO
- serio_unregister_port(&up->serio);
+ if (up->serio) {
+ serio_unregister_port(up->serio);
+ up->serio = NULL;
+ }
#endif
} else if (up->port.type != PORT_UNKNOWN) {
uart_remove_one_port(&sunsu_reg, &up->port);