unsigned char prev_status;
#ifdef CONFIG_SERIO
- struct serio serio;
+ struct serio *serio;
int serio_open;
#endif
};
/* Stop-A is handled by drivers/char/keyboard.c now. */
#ifdef CONFIG_SERIO
if (up->serio_open)
- serio_interrupt(&up->serio, ch, 0, regs);
+ serio_interrupt(up->serio, ch, 0, regs);
#endif
} else if (ZS_IS_MOUSE(up)) {
int ret = suncore_mouse_baud_detection(ch, is_break);
case 0:
#ifdef CONFIG_SERIO
if (up->serio_open)
- serio_interrupt(&up->serio, ch, 0, regs);
+ serio_interrupt(up->serio, ch, 0, regs);
#endif
break;
};
static int sunzilog_serio_write(struct serio *serio, unsigned char ch)
{
- struct uart_sunzilog_port *up = serio->driver;
+ struct uart_sunzilog_port *up = serio->port_data;
unsigned long flags;
spin_lock_irqsave(&sunzilog_serio_lock, flags);
static int sunzilog_serio_open(struct serio *serio)
{
- struct uart_sunzilog_port *up = serio->driver;
+ struct uart_sunzilog_port *up = serio->port_data;
unsigned long flags;
int ret;
static void sunzilog_serio_close(struct serio *serio)
{
- struct uart_sunzilog_port *up = serio->driver;
+ struct uart_sunzilog_port *up = serio->port_data;
unsigned long flags;
spin_lock_irqsave(&sunzilog_serio_lock, flags);
up->curregs[R15] = BRKIE;
brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
sunzilog_convert_to_zs(up, up->cflag, 0, brg);
+ sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
+ __sunzilog_startup(up);
+}
#ifdef CONFIG_SERIO
- memset(&up->serio, 0, sizeof(up->serio));
+static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel)
+{
+ struct serio *serio;
- up->serio.driver = up;
+ up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+ if (serio) {
+ memset(serio, 0, sizeof(*serio));
- up->serio.type = SERIO_RS232;
- if (channel == KEYBOARD_LINE) {
- up->serio.type |= SERIO_SUNKBD;
- up->serio.name = "zskbd";
- } else {
- up->serio.type |= (SERIO_SUN | (1 << 16));
- up->serio.name = "zsms";
- }
- up->serio.phys = (channel == KEYBOARD_LINE ?
- "zs/serio0" : "zs/serio1");
+ serio->port_data = up;
- up->serio.write = sunzilog_serio_write;
- up->serio.open = sunzilog_serio_open;
- up->serio.close = sunzilog_serio_close;
+ serio->type = SERIO_RS232;
+ if (channel == KEYBOARD_LINE) {
+ serio->type |= SERIO_SUNKBD;
+ strlcpy(serio->name, "zskbd", sizeof(serio->name));
+ } else {
+ serio->type |= (SERIO_SUN | (1 << 16));
+ strlcpy(serio->name, "zsms", sizeof(serio->name));
+ }
+ strlcpy(serio->phys,
+ (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"),
+ sizeof(serio->phys));
- serio_register_port(&up->serio);
-#endif
+ serio->write = sunzilog_serio_write;
+ serio->open = sunzilog_serio_open;
+ serio->close = sunzilog_serio_close;
- sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
- __sunzilog_startup(up);
+ serio_register_port(serio);
+ } else {
+ printk(KERN_WARNING "zs%d: not enough memory for serio port\n",
+ channel);
+ }
}
+#endif
static void __init sunzilog_init_hw(void)
{
}
spin_unlock_irqrestore(&up->port.lock, flags);
+
+#ifdef CONFIG_SERIO
+ if (i == KEYBOARD_LINE || i == MOUSE_LINE)
+ sunzilog_register_serio(up, i);
+#endif
}
}
for (i = 0; i < NUM_CHANNELS; i++) {
struct uart_sunzilog_port *up = &sunzilog_port_table[i];
- if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up))
- continue;
-
- uart_remove_one_port(&sunzilog_reg, &up->port);
+ if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
+#ifdef CONFIG_SERIO
+ if (up->serio) {
+ serio_unregister_port(up->serio);
+ up->serio = NULL;
+ }
+#endif
+ } else
+ uart_remove_one_port(&sunzilog_reg, &up->port);
}
uart_unregister_driver(&sunzilog_reg);