[PATCH] ioc4 serial support - mostly cleanup
Various small mods for the Altix ioc4 serial driver - mostly cleanup: - remove UIF_INITIALIZED usage - use the 'lock' from uart_port - better multiple card support Signed-off-by: Patrick Gefre <pfg@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Родитель
5b11687924
Коммит
396dc44bca
|
@ -308,6 +308,8 @@ struct ioc4_serial {
|
|||
typedef void ioc4_intr_func_f(void *, uint32_t);
|
||||
typedef ioc4_intr_func_f *ioc4_intr_func_t;
|
||||
|
||||
static unsigned int Num_of_ioc4_cards;
|
||||
|
||||
/* defining this will get you LOTS of great debug info */
|
||||
//#define DEBUG_INTERRUPTS
|
||||
#define DPRINT_CONFIG(_x...) ;
|
||||
|
@ -317,7 +319,8 @@ typedef ioc4_intr_func_f *ioc4_intr_func_t;
|
|||
#define WAKEUP_CHARS 256
|
||||
|
||||
/* number of characters we want to transmit to the lower level at a time */
|
||||
#define IOC4_MAX_CHARS 128
|
||||
#define IOC4_MAX_CHARS 256
|
||||
#define IOC4_FIFO_CHARS 255
|
||||
|
||||
/* Device name we're using */
|
||||
#define DEVICE_NAME "ttyIOC"
|
||||
|
@ -1038,6 +1041,7 @@ static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
|
|||
return -ENOMEM;
|
||||
}
|
||||
memset(port, 0, sizeof(struct ioc4_port));
|
||||
spin_lock_init(&port->ip_lock);
|
||||
|
||||
/* we need to remember the previous ones, to point back to
|
||||
* them farther down - setting up the ring buffers.
|
||||
|
@ -1691,12 +1695,14 @@ ioc4_change_speed(struct uart_port *the_port,
|
|||
baud = 9600;
|
||||
|
||||
if (!the_port->fifosize)
|
||||
the_port->fifosize = IOC4_MAX_CHARS;
|
||||
the_port->fifosize = IOC4_FIFO_CHARS;
|
||||
the_port->timeout = ((the_port->fifosize * HZ * bits) / (baud / 10));
|
||||
the_port->timeout += HZ / 50; /* Add .02 seconds of slop */
|
||||
|
||||
the_port->ignore_status_mask = N_ALL_INPUT;
|
||||
|
||||
info->tty->low_latency = 1;
|
||||
|
||||
if (I_IGNPAR(info->tty))
|
||||
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
|
||||
| N_FRAMING_ERROR);
|
||||
|
@ -1742,7 +1748,6 @@ ioc4_change_speed(struct uart_port *the_port,
|
|||
*/
|
||||
static inline int ic4_startup_local(struct uart_port *the_port)
|
||||
{
|
||||
int retval = 0;
|
||||
struct ioc4_port *port;
|
||||
struct uart_info *info;
|
||||
|
||||
|
@ -1754,9 +1759,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
|
|||
return -1;
|
||||
|
||||
info = the_port->info;
|
||||
if (info->flags & UIF_INITIALIZED) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (info->tty) {
|
||||
set_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
|
@ -1775,7 +1777,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
|
|||
/* set the speed of the serial port */
|
||||
ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0);
|
||||
|
||||
info->flags |= UIF_INITIALIZED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1785,9 +1786,13 @@ static inline int ic4_startup_local(struct uart_port *the_port)
|
|||
*/
|
||||
static void ioc4_cb_output_lowat(struct ioc4_port *port)
|
||||
{
|
||||
unsigned long pflags;
|
||||
|
||||
/* ip_lock is set on the call here */
|
||||
if (port->ip_port) {
|
||||
spin_lock_irqsave(&port->ip_port->lock, pflags);
|
||||
transmit_chars(port->ip_port);
|
||||
spin_unlock_irqrestore(&port->ip_port->lock, pflags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2064,8 +2069,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
|
|||
* available data as long as it returns some.
|
||||
*/
|
||||
/* Re-arm the timer */
|
||||
writel(port->ip_rx_cons | IOC4_SRCIR_ARM,
|
||||
&port->ip_serial_regs->srcir);
|
||||
writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
|
||||
|
||||
prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
|
||||
cons_ptr = port->ip_rx_cons;
|
||||
|
@ -2299,6 +2303,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
|
|||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* receive_chars - upper level read. Called with ip_lock.
|
||||
* @the_port: port to read from
|
||||
|
@ -2307,9 +2312,11 @@ static void receive_chars(struct uart_port *the_port)
|
|||
{
|
||||
struct tty_struct *tty;
|
||||
unsigned char ch[IOC4_MAX_CHARS];
|
||||
int read_count, request_count;
|
||||
int read_count, request_count = IOC4_MAX_CHARS;
|
||||
struct uart_icount *icount;
|
||||
struct uart_info *info = the_port->info;
|
||||
int flip = 0;
|
||||
unsigned long pflags;
|
||||
|
||||
/* Make sure all the pointers are "good" ones */
|
||||
if (!info)
|
||||
|
@ -2317,16 +2324,17 @@ static void receive_chars(struct uart_port *the_port)
|
|||
if (!info->tty)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&the_port->lock, pflags);
|
||||
tty = info->tty;
|
||||
|
||||
request_count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
|
||||
if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count)
|
||||
request_count = TTY_FLIPBUF_SIZE - tty->flip.count;
|
||||
|
||||
if (request_count > 0) {
|
||||
if (request_count > IOC4_MAX_CHARS - 2)
|
||||
request_count = IOC4_MAX_CHARS - 2;
|
||||
icount = &the_port->icount;
|
||||
read_count = do_read(the_port, ch, request_count);
|
||||
if (read_count > 0) {
|
||||
flip = 1;
|
||||
memcpy(tty->flip.char_buf_ptr, ch, read_count);
|
||||
memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count);
|
||||
tty->flip.char_buf_ptr += read_count;
|
||||
|
@ -2335,7 +2343,11 @@ static void receive_chars(struct uart_port *the_port)
|
|||
icount->rx += read_count;
|
||||
}
|
||||
}
|
||||
tty_flip_buffer_push(tty);
|
||||
|
||||
spin_unlock_irqrestore(&the_port->lock, pflags);
|
||||
|
||||
if (flip)
|
||||
tty_flip_buffer_push(tty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2393,18 +2405,14 @@ static void ic4_shutdown(struct uart_port *the_port)
|
|||
|
||||
info = the_port->info;
|
||||
|
||||
if (!(info->flags & UIF_INITIALIZED))
|
||||
return;
|
||||
|
||||
wake_up_interruptible(&info->delta_msr_wait);
|
||||
|
||||
if (info->tty)
|
||||
set_bit(TTY_IO_ERROR, &info->tty->flags);
|
||||
|
||||
spin_lock_irqsave(&port->ip_lock, port_flags);
|
||||
spin_lock_irqsave(&the_port->lock, port_flags);
|
||||
set_notification(port, N_ALL, 0);
|
||||
info->flags &= ~UIF_INITIALIZED;
|
||||
spin_unlock_irqrestore(&port->ip_lock, port_flags);
|
||||
spin_unlock_irqrestore(&the_port->lock, port_flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2463,12 +2471,10 @@ static unsigned int ic4_get_mctrl(struct uart_port *the_port)
|
|||
static void ic4_start_tx(struct uart_port *the_port)
|
||||
{
|
||||
struct ioc4_port *port = get_ioc4_port(the_port);
|
||||
unsigned long flags;
|
||||
|
||||
if (port) {
|
||||
spin_lock_irqsave(&port->ip_lock, flags);
|
||||
transmit_chars(the_port);
|
||||
spin_unlock_irqrestore(&port->ip_lock, flags);
|
||||
set_notification(port, N_OUTPUT_LOWAT, 1);
|
||||
enable_intrs(port, port->ip_hooks->intr_tx_mt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2510,9 +2516,9 @@ static int ic4_startup(struct uart_port *the_port)
|
|||
}
|
||||
|
||||
/* Start up the serial port */
|
||||
spin_lock_irqsave(&port->ip_lock, port_flags);
|
||||
spin_lock_irqsave(&the_port->lock, port_flags);
|
||||
retval = ic4_startup_local(the_port);
|
||||
spin_unlock_irqrestore(&port->ip_lock, port_flags);
|
||||
spin_unlock_irqrestore(&the_port->lock, port_flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -2527,12 +2533,11 @@ static void
|
|||
ic4_set_termios(struct uart_port *the_port,
|
||||
struct termios *termios, struct termios *old_termios)
|
||||
{
|
||||
struct ioc4_port *port = get_ioc4_port(the_port);
|
||||
unsigned long port_flags;
|
||||
|
||||
spin_lock_irqsave(&port->ip_lock, port_flags);
|
||||
spin_lock_irqsave(&the_port->lock, port_flags);
|
||||
ioc4_change_speed(the_port, termios, old_termios);
|
||||
spin_unlock_irqrestore(&port->ip_lock, port_flags);
|
||||
spin_unlock_irqrestore(&the_port->lock, port_flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2607,24 +2612,25 @@ ioc4_serial_core_attach(struct pci_dev *pdev)
|
|||
__FUNCTION__, (void *)the_port,
|
||||
(void *)port));
|
||||
|
||||
spin_lock_init(&the_port->lock);
|
||||
/* membase, iobase and mapbase just need to be non-0 */
|
||||
the_port->membase = (unsigned char __iomem *)1;
|
||||
the_port->line = the_port->iobase = ii;
|
||||
the_port->iobase = (pdev->bus->number << 16) | ii;
|
||||
the_port->line = (Num_of_ioc4_cards << 2) | ii;
|
||||
the_port->mapbase = 1;
|
||||
the_port->type = PORT_16550A;
|
||||
the_port->fifosize = IOC4_MAX_CHARS;
|
||||
the_port->fifosize = IOC4_FIFO_CHARS;
|
||||
the_port->ops = &ioc4_ops;
|
||||
the_port->irq = control->ic_irq;
|
||||
the_port->dev = &pdev->dev;
|
||||
spin_lock_init(&the_port->lock);
|
||||
if (uart_add_one_port(&ioc4_uart, the_port) < 0) {
|
||||
printk(KERN_WARNING
|
||||
"%s: unable to add port %d\n",
|
||||
__FUNCTION__, the_port->line);
|
||||
"%s: unable to add port %d bus %d\n",
|
||||
__FUNCTION__, the_port->line, pdev->bus->number);
|
||||
} else {
|
||||
DPRINT_CONFIG(
|
||||
("IOC4 serial driver port %d irq = %d\n",
|
||||
the_port->line, the_port->irq));
|
||||
("IOC4 serial port %d irq = %d, bus %d\n",
|
||||
the_port->line, the_port->irq, pdev->bus->number));
|
||||
}
|
||||
/* all ports are rs232 for now */
|
||||
ioc4_set_proto(port, PROTO_RS232);
|
||||
|
@ -2734,6 +2740,8 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
|
|||
if ((ret = ioc4_serial_core_attach(idd->idd_pdev)))
|
||||
goto out4;
|
||||
|
||||
Num_of_ioc4_cards++;
|
||||
|
||||
return ret;
|
||||
|
||||
/* error exits that give back resources */
|
||||
|
|
Загрузка…
Ссылка в новой задаче