aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/ioc4_serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/ioc4_serial.c')
-rw-r--r--drivers/serial/ioc4_serial.c92
1 files changed, 44 insertions, 48 deletions
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 0c5c96a582b3..771676abee60 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -308,6 +308,8 @@ struct ioc4_serial {
308typedef void ioc4_intr_func_f(void *, uint32_t); 308typedef void ioc4_intr_func_f(void *, uint32_t);
309typedef ioc4_intr_func_f *ioc4_intr_func_t; 309typedef ioc4_intr_func_f *ioc4_intr_func_t;
310 310
311static unsigned int Num_of_ioc4_cards;
312
311/* defining this will get you LOTS of great debug info */ 313/* defining this will get you LOTS of great debug info */
312//#define DEBUG_INTERRUPTS 314//#define DEBUG_INTERRUPTS
313#define DPRINT_CONFIG(_x...) ; 315#define DPRINT_CONFIG(_x...) ;
@@ -317,7 +319,8 @@ typedef ioc4_intr_func_f *ioc4_intr_func_t;
317#define WAKEUP_CHARS 256 319#define WAKEUP_CHARS 256
318 320
319/* number of characters we want to transmit to the lower level at a time */ 321/* number of characters we want to transmit to the lower level at a time */
320#define IOC4_MAX_CHARS 128 322#define IOC4_MAX_CHARS 256
323#define IOC4_FIFO_CHARS 255
321 324
322/* Device name we're using */ 325/* Device name we're using */
323#define DEVICE_NAME "ttyIOC" 326#define DEVICE_NAME "ttyIOC"
@@ -973,18 +976,6 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs)
973 this_ir &= ~this_mir; 976 this_ir &= ~this_mir;
974 } 977 }
975 } 978 }
976 if (this_ir) {
977 printk(KERN_ERR
978 "unknown IOC4 %s interrupt 0x%x, sio_ir = 0x%x,"
979 " sio_ies = 0x%x, other_ir = 0x%x :"
980 "other_ies = 0x%x\n",
981 (intr_type == IOC4_SIO_INTR_TYPE) ? "sio" :
982 "other", this_ir,
983 readl(&soft->is_ioc4_misc_addr->sio_ir.raw),
984 readl(&soft->is_ioc4_misc_addr->sio_ies.raw),
985 readl(&soft->is_ioc4_misc_addr->other_ir.raw),
986 readl(&soft->is_ioc4_misc_addr->other_ies.raw));
987 }
988 } 979 }
989#ifdef DEBUG_INTERRUPTS 980#ifdef DEBUG_INTERRUPTS
990 { 981 {
@@ -1050,6 +1041,7 @@ static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
1050 return -ENOMEM; 1041 return -ENOMEM;
1051 } 1042 }
1052 memset(port, 0, sizeof(struct ioc4_port)); 1043 memset(port, 0, sizeof(struct ioc4_port));
1044 spin_lock_init(&port->ip_lock);
1053 1045
1054 /* we need to remember the previous ones, to point back to 1046 /* we need to remember the previous ones, to point back to
1055 * them farther down - setting up the ring buffers. 1047 * them farther down - setting up the ring buffers.
@@ -1703,12 +1695,14 @@ ioc4_change_speed(struct uart_port *the_port,
1703 baud = 9600; 1695 baud = 9600;
1704 1696
1705 if (!the_port->fifosize) 1697 if (!the_port->fifosize)
1706 the_port->fifosize = IOC4_MAX_CHARS; 1698 the_port->fifosize = IOC4_FIFO_CHARS;
1707 the_port->timeout = ((the_port->fifosize * HZ * bits) / (baud / 10)); 1699 the_port->timeout = ((the_port->fifosize * HZ * bits) / (baud / 10));
1708 the_port->timeout += HZ / 50; /* Add .02 seconds of slop */ 1700 the_port->timeout += HZ / 50; /* Add .02 seconds of slop */
1709 1701
1710 the_port->ignore_status_mask = N_ALL_INPUT; 1702 the_port->ignore_status_mask = N_ALL_INPUT;
1711 1703
1704 info->tty->low_latency = 1;
1705
1712 if (I_IGNPAR(info->tty)) 1706 if (I_IGNPAR(info->tty))
1713 the_port->ignore_status_mask &= ~(N_PARITY_ERROR 1707 the_port->ignore_status_mask &= ~(N_PARITY_ERROR
1714 | N_FRAMING_ERROR); 1708 | N_FRAMING_ERROR);
@@ -1754,7 +1748,6 @@ ioc4_change_speed(struct uart_port *the_port,
1754 */ 1748 */
1755static inline int ic4_startup_local(struct uart_port *the_port) 1749static inline int ic4_startup_local(struct uart_port *the_port)
1756{ 1750{
1757 int retval = 0;
1758 struct ioc4_port *port; 1751 struct ioc4_port *port;
1759 struct uart_info *info; 1752 struct uart_info *info;
1760 1753
@@ -1766,9 +1759,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
1766 return -1; 1759 return -1;
1767 1760
1768 info = the_port->info; 1761 info = the_port->info;
1769 if (info->flags & UIF_INITIALIZED) {
1770 return retval;
1771 }
1772 1762
1773 if (info->tty) { 1763 if (info->tty) {
1774 set_bit(TTY_IO_ERROR, &info->tty->flags); 1764 set_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -1787,7 +1777,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
1787 /* set the speed of the serial port */ 1777 /* set the speed of the serial port */
1788 ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0); 1778 ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0);
1789 1779
1790 info->flags |= UIF_INITIALIZED;
1791 return 0; 1780 return 0;
1792} 1781}
1793 1782
@@ -1797,9 +1786,13 @@ static inline int ic4_startup_local(struct uart_port *the_port)
1797 */ 1786 */
1798static void ioc4_cb_output_lowat(struct ioc4_port *port) 1787static void ioc4_cb_output_lowat(struct ioc4_port *port)
1799{ 1788{
1789 unsigned long pflags;
1790
1800 /* ip_lock is set on the call here */ 1791 /* ip_lock is set on the call here */
1801 if (port->ip_port) { 1792 if (port->ip_port) {
1793 spin_lock_irqsave(&port->ip_port->lock, pflags);
1802 transmit_chars(port->ip_port); 1794 transmit_chars(port->ip_port);
1795 spin_unlock_irqrestore(&port->ip_port->lock, pflags);
1803 } 1796 }
1804} 1797}
1805 1798
@@ -2076,8 +2069,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
2076 * available data as long as it returns some. 2069 * available data as long as it returns some.
2077 */ 2070 */
2078 /* Re-arm the timer */ 2071 /* Re-arm the timer */
2079 writel(port->ip_rx_cons | IOC4_SRCIR_ARM, 2072 writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
2080 &port->ip_serial_regs->srcir);
2081 2073
2082 prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK; 2074 prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
2083 cons_ptr = port->ip_rx_cons; 2075 cons_ptr = port->ip_rx_cons;
@@ -2311,6 +2303,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
2311 } 2303 }
2312 return total; 2304 return total;
2313} 2305}
2306
2314/** 2307/**
2315 * receive_chars - upper level read. Called with ip_lock. 2308 * receive_chars - upper level read. Called with ip_lock.
2316 * @the_port: port to read from 2309 * @the_port: port to read from
@@ -2319,9 +2312,11 @@ static void receive_chars(struct uart_port *the_port)
2319{ 2312{
2320 struct tty_struct *tty; 2313 struct tty_struct *tty;
2321 unsigned char ch[IOC4_MAX_CHARS]; 2314 unsigned char ch[IOC4_MAX_CHARS];
2322 int read_count, request_count; 2315 int read_count, request_count = IOC4_MAX_CHARS;
2323 struct uart_icount *icount; 2316 struct uart_icount *icount;
2324 struct uart_info *info = the_port->info; 2317 struct uart_info *info = the_port->info;
2318 int flip = 0;
2319 unsigned long pflags;
2325 2320
2326 /* Make sure all the pointers are "good" ones */ 2321 /* Make sure all the pointers are "good" ones */
2327 if (!info) 2322 if (!info)
@@ -2329,16 +2324,17 @@ static void receive_chars(struct uart_port *the_port)
2329 if (!info->tty) 2324 if (!info->tty)
2330 return; 2325 return;
2331 2326
2327 spin_lock_irqsave(&the_port->lock, pflags);
2332 tty = info->tty; 2328 tty = info->tty;
2333 2329
2334 request_count = TTY_FLIPBUF_SIZE - tty->flip.count - 1; 2330 if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count)
2331 request_count = TTY_FLIPBUF_SIZE - tty->flip.count;
2335 2332
2336 if (request_count > 0) { 2333 if (request_count > 0) {
2337 if (request_count > IOC4_MAX_CHARS - 2)
2338 request_count = IOC4_MAX_CHARS - 2;
2339 icount = &the_port->icount; 2334 icount = &the_port->icount;
2340 read_count = do_read(the_port, ch, request_count); 2335 read_count = do_read(the_port, ch, request_count);
2341 if (read_count > 0) { 2336 if (read_count > 0) {
2337 flip = 1;
2342 memcpy(tty->flip.char_buf_ptr, ch, read_count); 2338 memcpy(tty->flip.char_buf_ptr, ch, read_count);
2343 memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count); 2339 memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count);
2344 tty->flip.char_buf_ptr += read_count; 2340 tty->flip.char_buf_ptr += read_count;
@@ -2347,7 +2343,11 @@ static void receive_chars(struct uart_port *the_port)
2347 icount->rx += read_count; 2343 icount->rx += read_count;
2348 } 2344 }
2349 } 2345 }
2350 tty_flip_buffer_push(tty); 2346
2347 spin_unlock_irqrestore(&the_port->lock, pflags);
2348
2349 if (flip)
2350 tty_flip_buffer_push(tty);
2351} 2351}
2352 2352
2353/** 2353/**
@@ -2405,18 +2405,14 @@ static void ic4_shutdown(struct uart_port *the_port)
2405 2405
2406 info = the_port->info; 2406 info = the_port->info;
2407 2407
2408 if (!(info->flags & UIF_INITIALIZED))
2409 return;
2410
2411 wake_up_interruptible(&info->delta_msr_wait); 2408 wake_up_interruptible(&info->delta_msr_wait);
2412 2409
2413 if (info->tty) 2410 if (info->tty)
2414 set_bit(TTY_IO_ERROR, &info->tty->flags); 2411 set_bit(TTY_IO_ERROR, &info->tty->flags);
2415 2412
2416 spin_lock_irqsave(&port->ip_lock, port_flags); 2413 spin_lock_irqsave(&the_port->lock, port_flags);
2417 set_notification(port, N_ALL, 0); 2414 set_notification(port, N_ALL, 0);
2418 info->flags &= ~UIF_INITIALIZED; 2415 spin_unlock_irqrestore(&the_port->lock, port_flags);
2419 spin_unlock_irqrestore(&port->ip_lock, port_flags);
2420} 2416}
2421 2417
2422/** 2418/**
@@ -2475,12 +2471,10 @@ static unsigned int ic4_get_mctrl(struct uart_port *the_port)
2475static void ic4_start_tx(struct uart_port *the_port) 2471static void ic4_start_tx(struct uart_port *the_port)
2476{ 2472{
2477 struct ioc4_port *port = get_ioc4_port(the_port); 2473 struct ioc4_port *port = get_ioc4_port(the_port);
2478 unsigned long flags;
2479 2474
2480 if (port) { 2475 if (port) {
2481 spin_lock_irqsave(&port->ip_lock, flags); 2476 set_notification(port, N_OUTPUT_LOWAT, 1);
2482 transmit_chars(the_port); 2477 enable_intrs(port, port->ip_hooks->intr_tx_mt);
2483 spin_unlock_irqrestore(&port->ip_lock, flags);
2484 } 2478 }
2485} 2479}
2486 2480
@@ -2522,9 +2516,9 @@ static int ic4_startup(struct uart_port *the_port)
2522 } 2516 }
2523 2517
2524 /* Start up the serial port */ 2518 /* Start up the serial port */
2525 spin_lock_irqsave(&port->ip_lock, port_flags); 2519 spin_lock_irqsave(&the_port->lock, port_flags);
2526 retval = ic4_startup_local(the_port); 2520 retval = ic4_startup_local(the_port);
2527 spin_unlock_irqrestore(&port->ip_lock, port_flags); 2521 spin_unlock_irqrestore(&the_port->lock, port_flags);
2528 return retval; 2522 return retval;
2529} 2523}
2530 2524
@@ -2539,12 +2533,11 @@ static void
2539ic4_set_termios(struct uart_port *the_port, 2533ic4_set_termios(struct uart_port *the_port,
2540 struct termios *termios, struct termios *old_termios) 2534 struct termios *termios, struct termios *old_termios)
2541{ 2535{
2542 struct ioc4_port *port = get_ioc4_port(the_port);
2543 unsigned long port_flags; 2536 unsigned long port_flags;
2544 2537
2545 spin_lock_irqsave(&port->ip_lock, port_flags); 2538 spin_lock_irqsave(&the_port->lock, port_flags);
2546 ioc4_change_speed(the_port, termios, old_termios); 2539 ioc4_change_speed(the_port, termios, old_termios);
2547 spin_unlock_irqrestore(&port->ip_lock, port_flags); 2540 spin_unlock_irqrestore(&the_port->lock, port_flags);
2548} 2541}
2549 2542
2550/** 2543/**
@@ -2619,24 +2612,25 @@ ioc4_serial_core_attach(struct pci_dev *pdev)
2619 __FUNCTION__, (void *)the_port, 2612 __FUNCTION__, (void *)the_port,
2620 (void *)port)); 2613 (void *)port));
2621 2614
2622 spin_lock_init(&the_port->lock);
2623 /* membase, iobase and mapbase just need to be non-0 */ 2615 /* membase, iobase and mapbase just need to be non-0 */
2624 the_port->membase = (unsigned char __iomem *)1; 2616 the_port->membase = (unsigned char __iomem *)1;
2625 the_port->line = the_port->iobase = ii; 2617 the_port->iobase = (pdev->bus->number << 16) | ii;
2618 the_port->line = (Num_of_ioc4_cards << 2) | ii;
2626 the_port->mapbase = 1; 2619 the_port->mapbase = 1;
2627 the_port->type = PORT_16550A; 2620 the_port->type = PORT_16550A;
2628 the_port->fifosize = IOC4_MAX_CHARS; 2621 the_port->fifosize = IOC4_FIFO_CHARS;
2629 the_port->ops = &ioc4_ops; 2622 the_port->ops = &ioc4_ops;
2630 the_port->irq = control->ic_irq; 2623 the_port->irq = control->ic_irq;
2631 the_port->dev = &pdev->dev; 2624 the_port->dev = &pdev->dev;
2625 spin_lock_init(&the_port->lock);
2632 if (uart_add_one_port(&ioc4_uart, the_port) < 0) { 2626 if (uart_add_one_port(&ioc4_uart, the_port) < 0) {
2633 printk(KERN_WARNING 2627 printk(KERN_WARNING
2634 "%s: unable to add port %d\n", 2628 "%s: unable to add port %d bus %d\n",
2635 __FUNCTION__, the_port->line); 2629 __FUNCTION__, the_port->line, pdev->bus->number);
2636 } else { 2630 } else {
2637 DPRINT_CONFIG( 2631 DPRINT_CONFIG(
2638 ("IOC4 serial driver port %d irq = %d\n", 2632 ("IOC4 serial port %d irq = %d, bus %d\n",
2639 the_port->line, the_port->irq)); 2633 the_port->line, the_port->irq, pdev->bus->number));
2640 } 2634 }
2641 /* all ports are rs232 for now */ 2635 /* all ports are rs232 for now */
2642 ioc4_set_proto(port, PROTO_RS232); 2636 ioc4_set_proto(port, PROTO_RS232);
@@ -2746,6 +2740,8 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
2746 if ((ret = ioc4_serial_core_attach(idd->idd_pdev))) 2740 if ((ret = ioc4_serial_core_attach(idd->idd_pdev)))
2747 goto out4; 2741 goto out4;
2748 2742
2743 Num_of_ioc4_cards++;
2744
2749 return ret; 2745 return ret;
2750 2746
2751 /* error exits that give back resources */ 2747 /* error exits that give back resources */