From: James S. <jsi...@us...> - 2001-12-25 06:50:54
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/serial In directory usw-pr-cvs1:/tmp/cvs-serv30082/drivers/serial Modified Files: ChangeLog serial_21285.c serial_8250.c serial_8250.h serial_8250_pci.c serial_8250_pnp.c serial_amba.c serial_anakin.c serial_clps711x.c serial_core.c serial_sa1100.c serial_uart00.c Log Message: Synced to RMK work. See ChangeLg for comments. Index: ChangeLog =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/ChangeLog,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- ChangeLog 2001/12/25 04:29:59 1.3 +++ ChangeLog 2001/12/25 06:50:51 1.4 @@ -9,3 +9,10 @@ 2001-12-24 James Simmons <jsi...@us...> * Removed ops field in uart_info. Instead use in in uart_port instead. +2001-12-24 James Simmons <jsi...@us...> + * Synced to RMK latest changes. He removed the awful table, termios + stuff from struct uart_driver. This makes life easier for us :-) + He also implemented a struct uart_xxx_port that wraps around the + default struct uart_port. From my experience with the fbdev layer + this is a bad idea and will lead to really bad code. This must + change. Index: serial_21285.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_21285.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- serial_21285.c 2001/12/25 04:29:59 1.8 +++ serial_21285.c 2001/12/25 06:50:51 1.9 @@ -54,9 +54,6 @@ #define H_UBRLCR_FIFO (1 << 4) static struct tty_driver normal, callout; -static struct tty_struct *serial21285_table[1]; -static struct termios *serial21285_termios[1]; -static struct termios *serial21285_termios_locked[1]; static const char serial21285_name[] = "Footbridge UART"; /* @@ -471,9 +468,6 @@ normal_driver: &normal, callout_major: SERIAL_21285_AUXMAJOR, callout_driver: &callout, - table: serial21285_table, - termios: serial21285_termios, - termios_locked: serial21285_termios_locked, minor: SERIAL_21285_MINOR, nr: 1, port: &serial21285_port, Index: serial_8250.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- serial_8250.c 2001/12/25 04:29:59 1.13 +++ serial_8250.c 2001/12/25 06:50:51 1.14 @@ -75,10 +75,7 @@ #define UART_NR ARRAY_SIZE(old_serial_port) static struct tty_driver normal, callout; -static struct tty_struct *serial8250_table[UART_NR]; -static struct termios *serial8250_termios[UART_NR], *serial8250_termios_locked[UART_NR]; #ifdef CONFIG_SERIAL_8250_CONSOLE -static struct console serial8250_console; static unsigned int lsr_break_flag; #endif static struct uart_info *IRQ_ports[NR_IRQS]; @@ -95,10 +92,13 @@ MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA"); #endif /* CONFIG_SERIAL_RSA */ -#define port_acr unused[0] /* 8bit */ -#define port_ier unused[1] /* 8bit */ -#define port_rev unused[2] /* 8bit */ -#define port_lcr unused[3] /* 8bit */ +struct uart_8250_port { + struct uart_port port; + u_char acr; + u_char ier; + u_char rev; + u_char lcr; +}; /* * Here we define the default xmit fifo size used for each type of UART. @@ -182,12 +182,13 @@ static unsigned int serial_icr_read(struct uart_port *port, int offset) { + struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned int value; - serial_icr_write(port, UART_ACR, port->port_acr | UART_ACR_ICRRD); + serial_icr_write(port, UART_ACR, up->acr | UART_ACR_ICRRD); serial_out(port, UART_SCR, offset); value = serial_in(port, UART_ICR); - serial_icr_write(port, UART_ACR, port->port_acr); + serial_icr_write(port, UART_ACR, up->acr); return value; } @@ -284,6 +285,7 @@ static void autoconfig_startech_uarts(struct uart_port *port) { + struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned char scratch, scratch2, scratch3, scratch4; /* @@ -301,7 +303,7 @@ * (Ex...@is...) claims that it's needed for 952 * dual UART's (which are not recommended for new designs). */ - port->port_acr = 0; + up->acr = 0; serial_out(port, UART_LCR, 0xBF); serial_out(port, UART_EFR, 0x10); serial_out(port, UART_LCR, 0x00); @@ -314,8 +316,8 @@ (scratch3 == 0x50 || scratch3 == 0x52 || scratch3 == 0x54)) { port->type = PORT_16C950; - port->port_rev = serial_icr_read(port, UART_REV) | - (scratch3 << 8); + up->rev = serial_icr_read(port, UART_REV) | + (scratch3 << 8); return; } } @@ -343,7 +345,7 @@ if (scratch == 0x10 || scratch == 0x12 || scratch == 0x14) { if (scratch == 0x10) - port->port_rev = scratch2; + up->rev = scratch2; port->type = PORT_16850; return; } @@ -624,42 +626,50 @@ static void serial8250_stop_tx(struct uart_port *port, u_int from_tty) { - if (port->port_ier & UART_IER_THRI) { - port->port_ier &= ~UART_IER_THRI; - serial_out(port, UART_IER, port->port_ier); + struct uart_8250_port *up = (struct uart_8250_port *)port; + + if (up->ier & UART_IER_THRI) { + up->ier &= ~UART_IER_THRI; + serial_out(port, UART_IER, up->ier); } if (port->type == PORT_16C950) { - port->port_acr |= UART_ACR_TXDIS; - serial_icr_write(port, UART_ACR, port->port_acr); + up->acr |= UART_ACR_TXDIS; + serial_icr_write(port, UART_ACR, up->acr); } } static void serial8250_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty) { - if (nonempty && !(port->port_ier & UART_IER_THRI)) { - port->port_ier |= UART_IER_THRI; - serial_out(port, UART_IER, port->port_ier); + struct uart_8250_port *up = (struct uart_8250_port *)port; + + if (nonempty && !(up->ier & UART_IER_THRI)) { + up->ier |= UART_IER_THRI; + serial_out(port, UART_IER, up->ier); } /* * We only do this from uart_start */ if (from_tty && port->type == PORT_16C950) { - port->port_acr &= ~UART_ACR_TXDIS; - serial_icr_write(port, UART_ACR, port->port_acr); + up->acr &= ~UART_ACR_TXDIS; + serial_icr_write(port, UART_ACR, up->acr); } } static void serial8250_stop_rx(struct uart_port *port) { - port->port_ier &= ~UART_IER_RLSI; + struct uart_8250_port *up = (struct uart_8250_port *)port; + + up->ier &= ~UART_IER_RLSI; port->read_status_mask &= ~UART_LSR_DR; - serial_out(port, UART_IER, port->port_ier); + serial_out(port, UART_IER, up->ier); } static void serial8250_enable_ms(struct uart_port *port) { - port->port_ier |= UART_IER_MSI; - serial_out(port, UART_IER, port->port_ier); + struct uart_8250_port *up = (struct uart_8250_port *)port; + + up->ier |= UART_IER_MSI; + serial_out(port, UART_IER, up->ier); } static _INLINE_ void @@ -695,7 +705,7 @@ * may get masked by ignore_status_mask * or read_status_mask. */ - uart_handle_break(info, &serial8250_console); + uart_handle_break(info, port->cons); } else if (*status & UART_LSR_PE) port->icount.parity++; else if (*status & UART_LSR_FE) @@ -709,7 +719,7 @@ *status &= port->read_status_mask; #ifdef CONFIG_SERIAL_8250_CONSOLE - if (port->line == serial8250_console.index) { + if (port->line == port->cons->index) { /* Recover the break flag from console xmit */ *status |= lsr_break_flag; lsr_break_flag = 0; @@ -1085,21 +1095,24 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) { + struct uart_8250_port *up = (struct uart_8250_port *)port; + if (break_state == -1) - port->port_lcr |= UART_LCR_SBC; + up->lcr |= UART_LCR_SBC; else - port->port_lcr &= ~UART_LCR_SBC; - serial_out(port, UART_LCR, port->port_lcr); + up->lcr &= ~UART_LCR_SBC; + serial_out(port, UART_LCR, up->lcr); } static int serial8250_startup(struct uart_port *port, struct uart_info *info) { + struct uart_8250_port *up = (struct uart_8250_port *)port; void (*handler)(int, void *, struct pt_regs *); int retval; if (port->type == PORT_16C950) { /* Wake up and initialize UART */ - port->port_acr = 0; + up->acr = 0; serial_outp(port, UART_LCR, 0xBF); serial_outp(port, UART_EFR, UART_EFR_ECB); serial_outp(port, UART_IER, 0); @@ -1197,8 +1210,8 @@ * are set via change_speed(), which will be occuring imminently * anyway, so we don't enable them here. */ - port->port_ier = UART_IER_RLSI | UART_IER_RDI; - serial_outp(port, UART_IER, port->port_ier); + up->ier = UART_IER_RLSI | UART_IER_RDI; + serial_outp(port, UART_IER, up->ier); #ifdef CONFIG_SERIAL_MANY_PORTS if (port->flags & ASYNC_FOURPORT) { @@ -1225,6 +1238,7 @@ static void serial8250_shutdown(struct uart_port *port, struct uart_info *info) { + struct uart_8250_port *up = (struct uart_8250_port *)port; struct uart_info **infop; int retval; @@ -1256,7 +1270,7 @@ /* * Disable all intrs */ - port->port_ier = 0; + up->ier = 0; serial_outp(port, UART_IER, 0); /* @@ -1286,6 +1300,7 @@ static void serial8250_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot) { + struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned char cval, fcr = 0; unsigned long flags; @@ -1314,7 +1329,7 @@ * when DLL is 0. */ if ((quot & 0xff) == 0 && port->type == PORT_16C950 && - port->port_rev == 0x5201) + up->rev == 0x5201) quot ++; if (uart_config[port->type].flags & UART_USE_FIFO) { @@ -1361,17 +1376,17 @@ /* * CTS flow control flag and modem status interrupts */ - port->port_ier &= ~UART_IER_MSI; + up->ier &= ~UART_IER_MSI; if (port->flags & ASYNC_HARDPPS_CD || cflag & CRTSCTS || !(cflag & CLOCAL)) - port->port_ier |= UART_IER_MSI; + up->ier |= UART_IER_MSI; /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ save_flags(flags); cli(); - serial_out(port, UART_IER, port->port_ier); + serial_out(port, UART_IER, up->ier); if (uart_config[port->type].flags & UART_STARTECH) { serial_outp(port, UART_LCR, 0xBF); @@ -1383,7 +1398,7 @@ if (port->type == PORT_16750) serial_outp(port, UART_FCR, fcr); /* set fcr */ serial_outp(port, UART_LCR, cval); /* reset DLAB */ - port->port_lcr = cval; /* Save LCR */ + up->lcr = cval; /* Save LCR */ if (port->type != PORT_16750) { if (fcr & UART_FCR_ENABLE_FIFO) { /* emulated UARTs (Lucent Venus 167x) need two steps */ @@ -1655,7 +1670,7 @@ verify_port: serial8250_verify_port, }; -static struct uart_port serial8250_ports[UART_NR]; +static struct uart_8250_port serial8250_ports[UART_NR]; static void __init serial8250_isa_init_ports(void) { @@ -1667,14 +1682,26 @@ first = 0; for (i = 0; i < ARRAY_SIZE(old_serial_port); i++) { - serial8250_ports[i].iobase = old_serial_port[i].port; - serial8250_ports[i].irq = irq_cannonicalize(old_serial_port[i].irq); - serial8250_ports[i].uartclk = old_serial_port[i].base_baud * 16; - serial8250_ports[i].flags = old_serial_port[i].flags; - serial8250_ports[i].ops = &serial8250_pops; + serial8250_ports[i].port.iobase = old_serial_port[i].port; + serial8250_ports[i].port.irq = irq_cannonicalize(old_serial_port[i].irq); + serial8250_ports[i].port.uartclk = old_serial_port[i].base_baud * 16; + serial8250_ports[i].port.flags = old_serial_port[i].flags; + serial8250_ports[i].port.ops = &serial8250_pops; } } +static void __init serial8250_register_ports(struct uart_driver *drv) +{ + int i; + + serial8250_isa_init_ports(); + + for (i = 0; i < UART_NR; i++) { + serial8250_ports[i].port.line = i; + uart_add_one_port(drv, &serial8250_ports[i].port); + } +} + #ifdef CONFIG_SERIAL_8250_CONSOLE #ifdef used_and_not_const_char_pointer static int serial8250_console_read(struct uart_port *port, char *s, u_int count) @@ -1717,7 +1744,7 @@ */ static void serial8250_console_write(struct console *co, const char *s, u_int count) { - struct uart_port *port = serial8250_ports + co->index; + struct uart_port *port = &serial8250_ports[co->index].port; unsigned int ier; int i; @@ -1759,7 +1786,7 @@ static int serial8250_console_wait_key(struct console *co) { - struct uart_port *port = serial8250_ports + co->index; + struct uart_port *port = &serial8250_ports[co->index].port; int ier, c; /* @@ -1794,11 +1821,15 @@ * if so, search for the first available port that does have * console support. */ +#if 0 port = uart_get_console(serial8250_ports, UART_NR, co); - +#else + if (co->index >= UART_NR) + co->index = 0; + port = &serial8250_ports[co->index].port; +#endif if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); - return uart_set_options(port, co, baud, parity, bits, flow); } @@ -1839,12 +1870,8 @@ callout_major: TTYAUX_MAJOR, normal_driver: &normal, callout_driver: &callout, - table: serial8250_table, - termios: serial8250_termios, - termios_locked: serial8250_termios_locked, minor: 64, - nr: ARRAY_SIZE(old_serial_port), - port: serial8250_ports, + nr: UART_NR, cons: SERIAL8250_CONSOLE, }; @@ -1883,6 +1910,7 @@ port->regshift = req->iomem_reg_shift; port->iotype = req->io_type; port->flags = req->flags | ASYNC_BOOT_AUTOCONF; + port->line = -1; if (HIGH_BITS_OFFSET) port->iobase |= req->port_high << HIGH_BITS_OFFSET; @@ -1910,14 +1938,37 @@ uart_unregister_port(&serial8250_reg, line); } +/* + * This is for ISAPNP only. + */ +void serial8250_get_irq_map(int *map) +{ + int i; + + for (i = 0; i < UART_NR; i++) { + if (serial8250_ports[i].port.type != PORT_UNKNOWN) + clear_bit(serial8250_ports[i].port.irq, map); + } +} + static int __init serial8250_init(void) { - serial8250_isa_init_ports(); - return uart_register_driver(&serial8250_reg); + int ret; + + ret = uart_register_driver(&serial8250_reg); + if (ret) + return ret; + + serial8250_register_ports(&serial8250_reg); + return 0; } static void __exit serial8250_exit(void) { + int i; + + for (i = 0; i < UART_NR; i++) + uart_remove_one_port(&serial8250_reg,&serial8250_ports[i].port); uart_unregister_driver(&serial8250_reg); } @@ -1926,7 +1977,7 @@ EXPORT_SYMBOL(register_serial); EXPORT_SYMBOL(unregister_serial); +EXPORT_SYMBOL(serial8250_get_irq_map); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Generic 8250/16x50 serial driver"); - Index: serial_8250.h =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- serial_8250.h 2001/12/13 04:46:52 1.5 +++ serial_8250.h 2001/12/25 06:50:51 1.6 @@ -24,6 +24,7 @@ int serial8250_register_probe(struct serial8250_probe *probe); void serial8250_unregister_probe(struct serial8250_probe *probe); +void serial8250_get_irq_map(int *map); struct old_serial_port { unsigned int uart; @@ -46,7 +47,7 @@ #endif #endif -#if defined(CONFIG_ISAPNP)|| (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE)) +#ifdef __ISAPNP__ #ifndef ENABLE_SERIAL_PNP #define ENABLE_SERIAL_PNP #endif Index: serial_8250_pci.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250_pci.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- serial_8250_pci.c 2001/12/25 04:29:59 1.13 +++ serial_8250_pci.c 2001/12/25 06:50:51 1.14 @@ -1078,4 +1078,4 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module"); -//MODULE_GENERIC_TABLE(pci, serial_pci_tbl); +MODULE_DEVICE_TABLE(pci, serial_pci_tbl); Index: serial_8250_pnp.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250_pnp.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- serial_8250_pnp.c 2001/12/25 04:29:59 1.8 +++ serial_8250_pnp.c 2001/12/25 06:50:51 1.9 @@ -29,9 +29,6 @@ #include "serial_8250.h" -static struct serial_state rs_table[] = { }; -#define NR_PORTS 0 - struct pnpbios_device_id { char id[8]; @@ -312,16 +309,11 @@ static void inline avoid_irq_share(struct pci_dev *dev) { - int i, map = 0x1FF8; - struct serial_state *state = rs_table; struct isapnp_irq *irq; struct isapnp_resources *res = dev->sysdata; + int map = 0x1FF8; - for (i = 0; i < NR_PORTS; i++) { - if (state->type != PORT_UNKNOWN) - clear_bit(state->irq, &map); - state++; - } + serial8250_get_irq_map(&map); for ( ; res; res = res->alt) for(irq = res->irq; irq; irq = irq->next) @@ -549,5 +541,4 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Generic 8250/16x50 PNPBIOS serial probe module"); -//MODULE_GENERIC_TABLE(pnp, pnp_dev_table); - +MODULE_DEVICE_TABLE(pnpbios, pnp_dev_table); Index: serial_amba.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_amba.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- serial_amba.c 2001/12/25 04:29:59 1.11 +++ serial_amba.c 2001/12/25 06:50:51 1.12 @@ -78,11 +78,6 @@ #define CALLOUT_AMBA_NR UART_NR static struct tty_driver normal, callout; -static struct tty_struct *amba_table[UART_NR]; -static struct termios *amba_termios[UART_NR], *amba_termios_locked[UART_NR]; -#ifdef SUPPORT_SYSRQ -static struct console amba_console; -#endif #define AMBA_ISR_PASS_LIMIT 256 @@ -120,17 +115,18 @@ * We encode this bit information into port->driver_priv using the * following macros. */ -//#define PORT_CTRLS(dtrbit,rtsbit) ((1 << dtrbit) | (1 << (16 + rtsbit))) -#define PORT_CTRLS_DTR(port) (1 << (port)->unused[1]) -#define PORT_CTRLS_RTS(port) (1 << (port)->unused[0]) - #define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET) #define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET) /* - * Our private driver data mappings. + * We wrap our port structure around the generic uart_port. */ -#define drv_old_status driver_priv +struct uart_amba_port { + struct uart_port port; + u_int dtr_mask; + u_int rts_mask; + u_int old_status; +}; static void ambauart_stop_tx(struct uart_port *port, u_int from_tty) { @@ -206,7 +202,7 @@ if (rsr & AMBA_UARTRSR_BE) { rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE); port->icount.brk++; - if (uart_handle_break(info, &amba_console)) + if (uart_handle_break(info, port->cons)) goto ignore_char; } else if (rsr & AMBA_UARTRSR_PE) port->icount.parity++; @@ -288,15 +284,16 @@ static void ambauart_modem_status(struct uart_info *info) { + struct uart_amba_port *uap = (struct uart_amba_port *)info->port; struct uart_port *port = info->port; unsigned int status, delta; - UART_PUT_ICR(port, 0); + UART_PUT_ICR(&uap->port, 0); - status = UART_GET_FR(port) & AMBA_UARTFR_MODEM_ANY; + status = UART_GET_FR(&uap->port) & AMBA_UARTFR_MODEM_ANY; - delta = status ^ info->drv_old_status; - info->drv_old_status = status; + delta = status ^ uap->old_status; + uap->old_status = status; if (!delta) return; @@ -362,17 +359,18 @@ static void ambauart_set_mctrl(struct uart_port *port, u_int mctrl) { + struct uart_amba_port *uap = (struct uart_amba_port *)port; u_int ctrls = 0, ctrlc = 0; if (mctrl & TIOCM_RTS) - ctrlc |= PORT_CTRLS_RTS(port); + ctrlc |= uap->rts_mask; else - ctrls |= PORT_CTRLS_RTS(port); + ctrls |= uap->rts_mask; if (mctrl & TIOCM_DTR) - ctrlc |= PORT_CTRLS_DTR(port); + ctrlc |= uap->dtr_mask; else - ctrls |= PORT_CTRLS_DTR(port); + ctrls |= uap->dtr_mask; __raw_writel(ctrls, SC_CTRLS); __raw_writel(ctrlc, SC_CTRLC); @@ -392,6 +390,7 @@ static int ambauart_startup(struct uart_port *port, struct uart_info *info) { + struct uart_amba_port *uap = (struct uart_amba_port *)port; int retval; /* @@ -404,7 +403,7 @@ /* * initialise the old status of the modem signals */ - info->drv_old_status = UART_GET_FR(port) & AMBA_UARTFR_MODEM_ANY; + uap->old_status = UART_GET_FR(port) & AMBA_UARTFR_MODEM_ANY; /* * Finally, enable interrupts @@ -578,28 +577,36 @@ verify_port: ambauart_verify_port, }; -static struct uart_port amba_ports[UART_NR] = { +static struct uart_amba_port amba_ports[UART_NR] = { { - membase: (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), - mapbase: INTEGRATOR_UART0_BASE, - iotype: SERIAL_IO_MEM, - irq: IRQ_UARTINT0, - uartclk: 14745600, - fifosize: 16, - unused: { 4, 5 }, /*driver_priv: PORT_CTRLS(5, 4), */ - ops: &amba_pops, - flags: ASYNC_BOOT_AUTOCONF, + port: { + membase: (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), + mapbase: INTEGRATOR_UART0_BASE, + iotype: SERIAL_IO_MEM, + irq: IRQ_UARTINT0, + uartclk: 14745600, + fifosize: 16, + unused: { 4, 5 }, /*driver_priv: PORT_CTRLS(5, 4), */ + ops: &amba_pops, + flags: ASYNC_BOOT_AUTOCONF, + }, + dtr_mask: 1 << 5, + rts_mask: 1 << 4, }, { - membase: (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), - mapbase: INTEGRATOR_UART1_BASE, - iotype: SERIAL_IO_MEM, - irq: IRQ_UARTINT1, - uartclk: 14745600, - fifosize: 16, - unused: { 6, 7 }, /*driver_priv: PORT_CTRLS(7, 6), */ - ops: &amba_pops, - flags: ASYNC_BOOT_AUTOCONF, + port: { + membase: (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), + mapbase: INTEGRATOR_UART1_BASE, + iotype: SERIAL_IO_MEM, + irq: IRQ_UARTINT1, + uartclk: 14745600, + fifosize: 16, + unused: { 6, 7 }, /*driver_priv: PORT_CTRLS(7, 6), */ + ops: &amba_pops, + flags: ASYNC_BOOT_AUTOCONF, + }, + dtr_mask: 1 << 7, + rts_mask: 1 << 6, } }; @@ -631,7 +638,7 @@ static void ambauart_console_write(struct console *co, const char *s, u_int count) { - struct uart_port *port = amba_ports + co->index; + struct uart_port *port = &amba_ports[co->index].port; unsigned int status, old_cr; int i; @@ -674,7 +681,7 @@ static int ambauart_console_wait_key(struct console *co) { - struct uart_port *port = amba_ports + co->index; + struct uart_port *port = &amba_ports[co->index].port; unsigned int status; do { @@ -721,8 +728,14 @@ * if so, search for the first available port that does have * console support. */ +#if 0 port = uart_get_console(amba_ports, UART_NR, co); - +#else + if (co->index >= UART_NR) + co->index = 0; + port = &amba_ports[co->index].port; +#endif + if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); else @@ -767,22 +780,32 @@ normal_driver: &normal, callout_major: CALLOUT_AMBA_MAJOR, callout_driver: &callout, - table: amba_table, - termios: amba_termios, - termios_locked: amba_termios_locked, minor: SERIAL_AMBA_MINOR, nr: UART_NR, - port: amba_ports, cons: AMBA_CONSOLE, }; static int __init ambauart_init(void) { - return uart_register_driver(&amba_reg); + int ret; + + ret = uart_register_driver(&amba_reg); + if (ret == 0) { + int i; + + for (i = 0; i < UART_NR; i++) + uart_add_one_port(&amba_reg, &amba_ports[i].port); + } + return ret; } static void __exit ambauart_exit(void) { + int i; + + for (i = 0; i < UART_NR; i++) + uart_remove_one_port(&amba_reg, &amba_ports[i].port); + uart_unregister_driver(&amba_reg); } Index: serial_anakin.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_anakin.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- serial_anakin.c 2001/12/25 04:29:59 1.4 +++ serial_anakin.c 2001/12/25 06:50:51 1.5 @@ -64,11 +64,13 @@ #define CALLOUT_ANAKIN_MINOR 32 static struct tty_driver normal, callout; -static struct tty_struct *anakin_table[UART_NR]; -static struct termios *anakin_termios[UART_NR], *anakin_termios_locked[UART_NR]; -static struct uart_state anakin_state[UART_NR]; static u_int txenable[NR_IRQS]; /* Software interrupt register */ +struct uart_anakin_port { + struct uart_port port; + struct uart_info *info; +}; + static inline unsigned int anakin_in(struct uart_port *port, u_int offset) { @@ -112,6 +114,7 @@ static void anakin_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty) { + struct uart_anakin_port *up = (struct uart_anakin_port *)port; unsigned int flags; save_flags_cli(flags); @@ -121,7 +124,7 @@ txenable[port->irq] = TXENABLE; if ((anakin_in(port, 0x10) & TXEMPTY) && nonempty) { - anakin_transmit_buffer(port); + anakin_transmit_buffer(up->port); } } restore_flags(flags); @@ -273,8 +276,9 @@ static int anakin_startup(struct uart_port *port, struct uart_info *info) { - int retval; + struct uart_anakin_port *up = (struct uart_anakin_port *)port; unsigned int read,write; + int retval; /* * Allocate the IRQ @@ -300,8 +304,7 @@ /* Store the uart_info pointer so we can reference it in * anakin_start_tx() */ - port->unused = (u_int)info; - + up->info = info; return 0; } @@ -354,41 +357,51 @@ type: anakin_type, }; -static struct uart_port anakin_ports[UART_NR] = { +static struct uart_anakin_port anakin_ports[UART_NR] = { { - base: IO_BASE + UART0, - irq: IRQ_UART0, - uartclk: 3686400, - fifosize: 0, - ops: &anakin_pops, + port: { + base: IO_BASE + UART0, + irq: IRQ_UART0, + uartclk: 3686400, + fifosize: 0, + ops: &anakin_pops, + }, }, { - base: IO_BASE + UART1, - irq: IRQ_UART1, - uartclk: 3686400, - fifosize: 0, - ops: &anakin_pops, + port: { + base: IO_BASE + UART1, + irq: IRQ_UART1, + uartclk: 3686400, + fifosize: 0, + ops: &anakin_pops, + }, }, { - base: IO_BASE + UART2, - irq: IRQ_UART2, - uartclk: 3686400, - fifosize: 0, - ops: &anakin_pops, + port: { + base: IO_BASE + UART2, + irq: IRQ_UART2, + uartclk: 3686400, + fifosize: 0, + ops: &anakin_pops, + }, }, { - base: IO_BASE + UART3, - irq: IRQ_UART3, - uartclk: 3686400, - fifosize: 0, - ops: &anakin_pops, + port: { + base: IO_BASE + UART3, + irq: IRQ_UART3, + uartclk: 3686400, + fifosize: 0, + ops: &anakin_pops, + }, }, { - base: IO_BASE + UART4, - irq: IRQ_UART4, - uartclk: 3686400, - fifosize: 0, - ops: &anakin_pops, + port: { + base: IO_BASE + UART4, + irq: IRQ_UART4, + uartclk: 3686400, + fifosize: 0, + ops: &anakin_pops, + }, }, }; @@ -398,7 +411,7 @@ static void anakin_console_write(struct console *co, const char *s, u_int count) { - struct uart_port *port = anakin_ports + co->index; + struct uart_port *port = &anakin_ports[co->index].port; unsigned int flags, status, i; /* @@ -436,10 +449,11 @@ */ while (!(anakin_in(port, 0x10) & TXEMPTY)); - if (status & IRQENABLE) + if (status & IRQENABLE) { save_flags_cli(flags); anakin_out(port, 0x18, anakin_in(port, 0x18) | IRQENABLE); restore_flags(flags); + } } static kdev_t @@ -451,7 +465,7 @@ static int anakin_console_wait_key(struct console *co) { - struct uart_port *port = anakin_ports + co->index; + struct uart_port *port = &anakin_ports[co->index].port; unsigned int flags, status, ch; save_flags_cli(flags); @@ -501,7 +515,13 @@ * if so, search for the first available port that does have * console support. */ +#if 0 port = uart_get_console(anakin_ports, UART_NR, co); +#else + if (co->index >= UART_NR) + co->index = 0; + port = &anakin_ports[co->index].port; +#endif if (options) uart_parse_options(options, &baud, &parity, &bits); @@ -539,20 +559,24 @@ callout_major: CALLOUT_ANAKIN_MAJOR, callout_name: CALLOUT_ANAKIN_NAME, callout_driver: &callout, - table: anakin_table, - termios: anakin_termios, - termios_locked: anakin_termios_locked, minor: SERIAL_ANAKIN_MINOR, nr: UART_NR, - state: anakin_state, - port: anakin_ports, cons: ANAKIN_CONSOLE, }; static int __init anakin_init(void) { - return uart_register_port(&anakin_reg); + int ret; + + ret = uart_register_driver(&anakin_reg); + if (ret == 0) { + int i; + + for (i = 0; i < UART_NR; i++) + uart_add_one_port(&anakin_reg, &anakin_ports[i].port); + } + return ret; } __initcall(anakin_init); Index: serial_clps711x.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_clps711x.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- serial_clps711x.c 2001/12/25 04:29:59 1.11 +++ serial_clps711x.c 2001/12/25 06:50:51 1.12 @@ -59,19 +59,17 @@ #define UART_NR 2 -#define SERIAL_CLPS711X_NAME "ttyAM" +#define SERIAL_CLPS711X_NAME "ttyCL" #define SERIAL_CLPS711X_MAJOR 204 -#define SERIAL_CLPS711X_MINOR 16 +#define SERIAL_CLPS711X_MINOR 40 #define SERIAL_CLPS711X_NR UART_NR -#define CALLOUT_CLPS711X_NAME "cuaam" +#define CALLOUT_CLPS711X_NAME "cuacl" #define CALLOUT_CLPS711X_MAJOR 205 -#define CALLOUT_CLPS711X_MINOR 16 +#define CALLOUT_CLPS711X_MINOR 40 #define CALLOUT_CLPS711X_NR UART_NR static struct tty_driver normal, callout; -static struct tty_struct *clps711x_table[UART_NR]; -static struct termios *clps711x_termios[UART_NR], *clps711x_termios_locked[UART_NR]; /* * We use the relevant SYSCON register as a base address for these ports. @@ -661,10 +659,6 @@ normal_driver: &normal, callout_major: CALLOUT_CLPS711X_MAJOR, callout_driver: &callout, - - table: clps711x_table, - termios: clps711x_termios, - termios_locked: clps711x_termios_locked, minor: SERIAL_CLPS711X_MINOR, nr: UART_NR, Index: serial_core.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_core.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- serial_core.c 2001/12/25 04:29:59 1.18 +++ serial_core.c 2001/12/25 06:50:51 1.19 @@ -831,7 +831,8 @@ * from incrementing, and hence any extra opens * of the port while we're auto-configging. */ - down(&info->state->count_sem); + if (down_interruptible(&info->state->count_sem)) + return -ERESTARTSYS; ret = -EBUSY; if (info->state->count == 1) { @@ -1348,38 +1349,38 @@ static struct uart_info *uart_get(struct uart_driver *drv, int line) { struct uart_state *state = drv->state + line; - struct uart_info *info; + struct uart_info *info = NULL; down(&state->count_sem); - state->count++; - if (state->info) + if (!state->port) goto out; - info = kmalloc(sizeof(struct uart_info), GFP_KERNEL); - if (info) { - memset(info, 0, sizeof(struct uart_info)); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->delta_msr_wait); - info->port = state->port; - info->flags = info->port->flags; - info->state = state; - tasklet_init(&info->tlet, uart_tasklet_action, - (unsigned long)info); + state->count++; + info = state->info; + + if (!info) { + info = kmalloc(sizeof(struct uart_info), GFP_KERNEL); + if (info) { + memset(info, 0, sizeof(struct uart_info)); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); + info->port = state->port; + info->flags = info->port->flags; + info->state = state; + tasklet_init(&info->tlet, uart_tasklet_action, + (unsigned long)info); + state->info = info; + } else + state->count--; } - if (state->info) - kfree(info); - else - state->info = info; out: up(&state->count_sem); - return state->info; + return info; } /* - * Make sure we have the temporary buffer allocated. Note - * that we set retval appropriately above, and we rely on - * this. + * Make sure we have the temporary buffer allocated. */ static inline int uart_alloc_tmpbuf(void) { @@ -1411,23 +1412,44 @@ printk("uart_open(%d) called\n", line); #endif + /* + * tty->driver.num won't change, so we won't fail here with + * tty->driver_data set to something non-NULL (and therefore + * we won't get caught by uart_close()). + */ retval = -ENODEV; if (line >= tty->driver.num) goto fail; - if (!try_inc_mod_count(drv->owner)) + /* + * If we fail to increment the module use count, we can't have + * any other users of this tty (since this implies that the module + * is about to be unloaded). Therefore, it is safe to set + * tty->driver_data to be NULL, so uart_close() doesn't bite us. + */ + if (!try_inc_mod_count(drv->owner)) { + tty->driver_data = NULL; goto fail; + } + /* + * FIXME: This one isn't fun. We can't guarantee that the tty isn't + * already in open, nor can we guarantee the state of tty->driver_data + */ info = uart_get(drv, line); retval = -ENOMEM; - if (!info) - goto out; + if (!info) { + if (tty->driver_data) + goto out; + else + goto fail; + } /* - * Set the tty driver_data. If we fail from this point on, - * the generic tty layer will cause uart_close(), which will - * decrement the module use count. - */ + * Once we set tty->driver_data here, we are guaranteed that + * uart_close() will decrement the driver module use count. + * Any failures from here onwards should not touch the count. + */ tty->driver_data = info; info->tty = tty; info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; @@ -1485,7 +1507,7 @@ * Copy across the serial console cflag setting */ { - struct console *c = drv->cons; + struct console *c = info->port->cons; if (c && c->cflag && c->index == line) { tty->termios->c_cflag = c->cflag; c->cflag = 0; @@ -1767,7 +1789,7 @@ int running = state->info && state->info->flags & ASYNC_INITIALIZED; - if (port->type == PORT_UNKNOWN) + if (!port || port->type == PORT_UNKNOWN) return 0; //printk("pm: %08x: %d -> %d, %srunning\n", port->iobase, dev->state, pm_state, running ? "" : "not "); @@ -1785,8 +1807,8 @@ /* * Re-enable the console device after suspending. */ - if (state->cons && state->cons->index == port->line) - state->cons->flags |= CON_ENABLED; + if (port->cons && port->cons->index == port->line) + port->cons->flags |= CON_ENABLED; } else if (pm_state == 1) { if (ops->pm) ops->pm(port, pm_state, oldstate); @@ -1794,8 +1816,8 @@ /* * Disable the console device before suspending. */ - if (state->cons && state->cons->index == port->line) - state->cons->flags &= ~CON_ENABLED; + if (port->cons && port->cons->index == port->line) + port->cons->flags &= ~CON_ENABLED; if (running) { ops->stop_tx(port, 0); @@ -1860,24 +1882,15 @@ } static void -uart_setup_port(struct uart_driver *drv, struct uart_state *state) +__uart_register_port(struct uart_driver *drv, struct uart_state *state, + struct uart_port *port) { - struct uart_port *port = state->port; - int flags = UART_CONFIG_TYPE; - - init_MUTEX(&state->count_sem); - - state->close_delay = 5 * HZ / 10; - state->closing_wait = 30 * HZ; + u_int flags; + state->port = port; + port->type = PORT_UNKNOWN; - -#ifdef CONFIG_PM - state->cons = drv->cons; - state->pm = pm_register(PM_SYS_DEV, PM_SYS_COM, uart_pm); - if (state->pm) - state->pm->data = state; -#endif + port->cons = drv->cons; /* * If there isn't a port here, don't do anything further. @@ -1889,39 +1902,80 @@ * Now do the auto configuration stuff. Note that config_port * is expected to claim the resources and map the port for us. */ + flags = UART_CONFIG_TYPE; if (port->flags & ASYNC_AUTO_IRQ) flags |= UART_CONFIG_IRQ; if (port->flags & ASYNC_BOOT_AUTOCONF) port->ops->config_port(port, flags); /* - * Only register this port if it is detected. + * Register the port whether it's detected or not. This allows + * setserial to be used to alter this ports parameters. */ + tty_register_devfs(drv->normal_driver, 0, drv->minor + port->line); + tty_register_devfs(drv->callout_driver, 0, drv->minor + port->line); + if (port->type != PORT_UNKNOWN) { - tty_register_devfs(drv->normal_driver, 0, drv->minor + - state->port->line); - tty_register_devfs(drv->callout_driver, 0, drv->minor + - state->port->line); uart_report_port(drv, port); - } #ifdef CONFIG_PM + /* + * Power down all ports by default, except + * the console if we have one. + */ + if (state->pm && (!drv->cons || port->line != drv->cons->index)) + pm_send(state->pm, PM_SUSPEND, (void *)3); +#endif + } +} + +/* + * This reverses the affects of __uart_register_port. + */ +static void +__uart_unregister_port(struct uart_driver *drv, struct uart_state *state) +{ + struct uart_port *port = state->port; + /* - * Power down all ports by default, except the console if we have one. + * Hang up the line to kill all usage of this port. + */ + if (state->info && state->info->tty) + tty_hangup(state->info->tty); + + /* + * Remove the devices from devfs */ - if (state->pm && (!drv->cons || port->line != drv->cons->index)) - pm_send(state->pm, PM_SUSPEND, (void *)3); -#endif + tty_unregister_devfs(drv->normal_driver, drv->minor + port->line); + tty_unregister_devfs(drv->callout_driver, drv->minor + port->line); + + /* + * Free the ports resources, if any. + */ + if (port->type != PORT_UNKNOWN) + port->ops->release_port(port); + + /* + * Indicate that there isn't a port here anymore. + */ + port->type = PORT_UNKNOWN; + + /* + * Kill the tasklet, and free resources. + */ + if (state->info) { + tasklet_kill(&state->info->tlet); + kfree(state->info); + } } /* - * Register a set of ports with the core driver. Note that we don't - * printk any information about the ports; that is up to the low level - * driver to do if they so wish. + * Register a set of ports with the core driver. */ int uart_register_driver(struct uart_driver *drv) { struct tty_driver *normal, *callout; + struct termios **termios; int i, retval; if (drv->state) @@ -1941,6 +1995,11 @@ memset(drv->state, 0, sizeof(struct uart_state) * drv->nr + sizeof(int)); + termios = kmalloc(sizeof(struct termios *) * drv->nr * 2 + + sizeof(struct tty_struct *) * drv->nr, GFP_KERNEL); + if (!termios) + goto out; + normal = drv->normal_driver; callout = drv->callout_driver; @@ -1956,9 +2015,9 @@ normal->init_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; normal->refcount = (int *)(drv->state + drv->nr); - normal->table = drv->table; - normal->termios = drv->termios; - normal->termios_locked = drv->termios_locked; + normal->termios = termios; + normal->termios_locked = termios + drv->nr; + normal->table = (struct tty_struct **)(termios + drv->nr * 2); normal->driver_state = drv; normal->open = uart_open; @@ -1992,27 +2051,53 @@ callout->major = drv->callout_major; callout->subtype = SERIAL_TYPE_CALLOUT; callout->read_proc = NULL; - callout->proc_entry = NULL; + /* + * Initialise the UART state(s). + */ for (i = 0; i < drv->nr; i++) { struct uart_state *state = drv->state + i; + init_MUTEX(&state->count_sem); state->callout_termios = callout->init_termios; state->normal_termios = normal->init_termios; - state->port = drv->port + i; - state->port->line = i; - - uart_setup_port(drv, state); - } + state->close_delay = 5 * HZ / 10; + state->closing_wait = 30 * HZ; +#ifdef CONFIG_PM + state->pm = pm_register(PM_SYS_DEV, PM_SYS_COM, uart_pm); + if (state->pm) + state->pm->data = state; +#endif + } retval = tty_register_driver(normal); - if (retval) + if (retval) goto out; retval = tty_register_driver(callout); - if (retval) + if (retval) { tty_unregister_driver(normal); + goto out; + } + /* + * And finally the port(s). This part will eventually + * become the responsibility of the low level drivers - + * and will allow the low level drivers to extend the + * uart_port structure in any way they see fit. + * + * Any drivers using this method should not set drv->port. + */ + if (drv->port) { + printk("serial_core: driver %s uses obsolete registration\n", + drv->normal_name); + for (i = 0; i < drv->nr; i++) { + struct uart_port *port = drv->port + i; + + port->line = i; + __uart_register_port(drv, drv->state + i, port); + } + } out: if (retval && drv->state) kfree(drv->state); @@ -2022,33 +2107,60 @@ void uart_unregister_driver(struct uart_driver *drv) { int i; - - for (i = 0; i < drv->nr; i++) { - struct uart_state *state = drv->state + i; - if (state->info && state->info->tty) - tty_hangup(state->info->tty); - - pm_unregister(state->pm); + /* + * First, remove all ports. We only do this if the driver + * isn't using the new API (and therefore registering its own + * port structures). + */ + if (drv->port) { + for (i = 0; i < drv->nr; i++) { + struct uart_state *state = drv->state + i; + + __uart_unregister_port(drv, state); + } + } - if (state->port->type != PORT_UNKNOWN) - state->port->ops->release_port(state->port); - if (state->info) { - tasklet_kill(&state->info->tlet); - kfree(state->info); - } - } + for (i = 0; i < drv->nr; i++) + pm_unregister(drv->state[i].pm); tty_unregister_driver(drv->normal_driver); tty_unregister_driver(drv->callout_driver); kfree(drv->state); + kfree(drv->normal_driver->termios); } +int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) +{ + struct uart_state *state = drv->state + port->line; + + down(&state->count_sem); + __uart_register_port(drv, state, port); + up(&state->count_sem); + + return 0; +} + +int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) +{ + struct uart_state *state = drv->state + port->line; + + if (state->port != port) + printk(KERN_ALERT "Removing wrong port: %p != %p\n", + state->port, port); + + down(&state->count_sem); + __uart_unregister_port(drv, state); + up(&state->count_sem); + return 0; +} + static int uart_match_port(struct uart_port *port1, struct uart_port *port2) { if (port1->iotype != port2->iotype) return 0; + switch (port1->iotype) { case SERIAL_IO_PORT: return (port1->iobase == port2->iobase); case SERIAL_IO_MEM: return (port1->membase == port2->membase); @@ -2065,19 +2177,23 @@ * type of the port if ASYNC_BOOT_AUTOCONF is set, and detect the IRQ * if ASYNC_AUTO_IRQ is set. * + * We try to pick the same port for the same IO base address, so that + * when a modem is plugged in, unplugged and plugged back in, it gets + * allocated the same port. + * * Returns negative error, or positive line number. */ int uart_register_port(struct uart_driver *drv, struct uart_port *port) { struct uart_state *state = NULL; - int i, flags = UART_CONFIG_TYPE; + int i; + down(&port_sem); /* * First, find a port entry which matches. Note: if we do * find a matching entry, and it has a non-zero use count, * then we can't register the port. */ - down(&port_sem); for (i = 0; i < drv->nr; i++) { if (uart_match_port(drv->state[i].port, port)) { down(&drv->state[i].count_sem); @@ -2120,6 +2236,11 @@ } } + /* + * Ok, we've found a line that we can use. We have taken the + * per-port semaphore, so we can release the global port + * semaphore now. + */ up(&port_sem); if (!state) @@ -2149,34 +2270,9 @@ state->port->regshift = port->regshift; state->port->iotype = port->iotype; state->port->flags = port->flags; - -#if 0 //def CONFIG_PM - /* we have already registered the power management handlers */ - state->pm = pm_register(PM_SYS_DEV, PM_SYS_COM, uart_pm); - if (state->pm) { - state->pm->data = state; - - /* - * Power down all ports by default, except - * the console if we have one. - */ - if (!drv->cons || state->port->line != drv->cons->index) - pm_send(state->pm, PM_SUSPEND, (void *)3); - } -#endif - - if (state->port->flags & ASYNC_AUTO_IRQ) - flags |= UART_CONFIG_IRQ; - if (state->port->flags & ASYNC_BOOT_AUTOCONF) - state->port->ops->config_port(state->port, flags); - - tty_register_devfs(drv->normal_driver, 0, drv->minor + - state->port->line); - tty_register_devfs(drv->callout_driver, 0, drv->minor + - state->port->line); - - uart_report_port(drv, state->port); + state->port->line = drv->state - state; + __uart_register_port(drv, state, state->port); up(&state->count_sem); return i; } @@ -2197,36 +2293,7 @@ state = drv->state + line; down(&state->count_sem); - /* - * The port has already gone. We have to hang up the line - * to kill all usage of this port. - */ - if (state->info && state->info->tty) - tty_hangup(state->info->tty); - - /* - * Free the ports resources, if any. - */ - state->port->ops->release_port(state->port); - - /* - * Indicate that there isn't a port here anymore. - */ - state->port->type = PORT_UNKNOWN; - -#if 0 // not yet - /* - * No point in doing power management for hardware that - * isn't present. - */ - pm_unregister(state->pm); -#endif - - /* - * Remove the devices from devfs - */ - tty_unregister_devfs(drv->normal_driver, drv->minor + line); - tty_unregister_devfs(drv->callout_driver, drv->minor + line); + __uart_unregister_port(drv, state); up(&state->count_sem); } Index: serial_sa1100.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_sa1100.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- serial_sa1100.c 2001/12/25 04:29:59 1.16 +++ serial_sa1100.c 2001/12/25 06:50:51 1.17 @@ -98,13 +98,8 @@ #define UART_PORT_SIZE 0x24 static struct tty_driver normal, callout; -static struct tty_struct *sa1100_table[NR_PORTS]; -static struct termios *sa1100_termios[NR_PORTS], *sa1100_termios_locked[NR_PORTS]; static int (*sa1100_open)(struct uart_port *, struct uart_info *); static void (*sa1100_close)(struct uart_port *, struct uart_info *); -#ifdef SUPPORT_SYSRQ -static struct console sa1100_console; -#endif /* * interrupts disabled on entry @@ -289,7 +284,7 @@ if (status & UTSR0_REB) { #ifdef SUPPORT_SYSRQ - if (port->line == sa1100_console.index && + if (port->line == port->cons->index && !info->sysrq) { info->sysrq = jiffies + HZ*5; } @@ -787,9 +782,6 @@ normal_driver: &normal, callout_major: CALLOUT_SA1100_MAJOR, callout_driver: &callout, - table: sa1100_table, - termios: sa1100_termios, - termios_locked: sa1100_termios_locked, minor: MINOR_START, nr: NR_PORTS, port: sa1100_ports, Index: serial_uart00.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_uart00.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- serial_uart00.c 2001/12/25 04:29:59 1.4 +++ serial_uart00.c 2001/12/25 06:50:51 1.5 @@ -81,13 +81,8 @@ #define CALLOUT_UART00_MINOR 16 /* Temporary - will change in future */ #define CALLOUT_UART00_NR UART_NR - - static struct tty_driver normal, callout; -static struct tty_struct *uart00_table[UART_NR]; -static struct termios *uart00_termios[UART_NR], *uart00_termios_locked[UART_NR]; //static struct uart_state uart00_state[UART_NR]; -static struct console uart00_console; #define UART00_ISR_PASS_LIMIT 256 @@ -187,7 +182,7 @@ port->icount.brk++; #ifdef SUPPORT_SYSRQ - if (uart_handle_break(info, &uart00_console)) + if (uart_handle_break(info, port->cons)) goto ignore_char; #endif } else if (rds & UART_RDS_PE_MSK) @@ -782,9 +777,6 @@ callout_major: CALLOUT_UART00_MAJOR, callout_name: CALLOUT_UART00_NAME, callout_driver: &callout, - table: uart00_table, - termios: uart00_termios, - termios_locked: uart00_termios_locked, minor: SERIAL_UART00_MINOR, nr: UART_NR, state: NULL, |