diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/Kconfig | 4 | ||||
-rw-r--r-- | drivers/char/hvc_console.c | 2 | ||||
-rw-r--r-- | drivers/char/hvcs.c | 2 | ||||
-rw-r--r-- | drivers/char/hw_random/via-rng.c | 14 | ||||
-rw-r--r-- | drivers/char/i8k.c | 7 | ||||
-rw-r--r-- | drivers/char/ip27-rtc.c | 9 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 6 | ||||
-rw-r--r-- | drivers/char/lp.c | 10 | ||||
-rw-r--r-- | drivers/char/mxser.c | 1 | ||||
-rw-r--r-- | drivers/char/mxser_new.c | 1 | ||||
-rw-r--r-- | drivers/char/n_tty.c | 27 | ||||
-rw-r--r-- | drivers/char/pcmcia/synclink_cs.c | 3 | ||||
-rw-r--r-- | drivers/char/random.c | 1 | ||||
-rw-r--r-- | drivers/char/riscom8.c | 147 | ||||
-rw-r--r-- | drivers/char/ser_a2232.c | 2 | ||||
-rw-r--r-- | drivers/char/synclink.c | 3 | ||||
-rw-r--r-- | drivers/char/synclink_gt.c | 71 | ||||
-rw-r--r-- | drivers/char/synclinkmp.c | 3 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.c | 44 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 2 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_infineon.c | 6 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 25 | ||||
-rw-r--r-- | drivers/char/vt.c | 8 |
23 files changed, 240 insertions, 158 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 466629594776..85bf9b2aa74a 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -276,7 +276,7 @@ config N_HDLC config RISCOM8 tristate "SDL RISCom/8 card support" - depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP + depends on SERIAL_NONSTANDARD help This is a driver for the SDL Communications RISCom/8 multiport card, which gives you many serial ports. You would need something like @@ -765,7 +765,7 @@ config JS_RTC config SGI_DS1286 tristate "SGI DS1286 RTC support" - depends on SGI_IP22 + depends on SGI_HAS_DS1286 help If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 480fae29c9b2..44160d5ebca0 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -93,7 +93,7 @@ struct hvc_struct { }; /* dynamic list of hvc_struct instances */ -static struct list_head hvc_structs = LIST_HEAD_INIT(hvc_structs); +static LIST_HEAD(hvc_structs); /* * Protect the list of hvc_struct instances from inserts and removals during diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 3402def22007..786d518e9477 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c @@ -306,7 +306,7 @@ struct hvcs_struct { /* Required to back map a kref to its containing object */ #define from_kref(k) container_of(k, struct hvcs_struct, kref) -static struct list_head hvcs_structs = LIST_HEAD_INIT(hvcs_structs); +static LIST_HEAD(hvcs_structs); static DEFINE_SPINLOCK(hvcs_structs_lock); static void hvcs_unthrottle(struct tty_struct *tty); diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c index 868e39fd42e4..f7feae4ebb5e 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c @@ -42,6 +42,8 @@ enum { VIA_STRFILT_ENABLE = (1 << 14), VIA_RAWBITS_ENABLE = (1 << 13), VIA_RNG_ENABLE = (1 << 6), + VIA_NOISESRC1 = (1 << 8), + VIA_NOISESRC2 = (1 << 9), VIA_XSTORE_CNT_MASK = 0x0F, VIA_RNG_CHUNK_8 = 0x00, /* 64 rand bits, 64 stored bits */ @@ -119,6 +121,7 @@ static int via_rng_data_read(struct hwrng *rng, u32 *data) static int via_rng_init(struct hwrng *rng) { + struct cpuinfo_x86 *c = &cpu_data(0); u32 lo, hi, old_lo; /* Control the RNG via MSR. Tread lightly and pay very close @@ -134,6 +137,17 @@ static int via_rng_init(struct hwrng *rng) lo &= ~VIA_XSTORE_CNT_MASK; lo &= ~(VIA_STRFILT_ENABLE | VIA_STRFILT_FAIL | VIA_RAWBITS_ENABLE); lo |= VIA_RNG_ENABLE; + lo |= VIA_NOISESRC1; + + /* Enable secondary noise source on CPUs where it is present. */ + + /* Nehemiah stepping 8 and higher */ + if ((c->x86_model == 9) && (c->x86_mask > 7)) + lo |= VIA_NOISESRC2; + + /* Esther */ + if (c->x86_model >= 10) + lo |= VIA_NOISESRC2; if (lo != old_lo) wrmsr(MSR_VIA_RNG, lo, hi); diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 30e564516422..179223a17414 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c @@ -439,6 +439,13 @@ static struct dmi_system_id __initdata i8k_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), }, }, + { /* UK Inspiron 6400 */ + .ident = "Dell Inspiron 3", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MM061"), + }, + }, { } }; diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c index 932264a657d0..86e6538a77b0 100644 --- a/drivers/char/ip27-rtc.c +++ b/drivers/char/ip27-rtc.c @@ -46,8 +46,8 @@ #include <asm/sn/sn0/hub.h> #include <asm/sn/sn_private.h> -static int rtc_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); +static long rtc_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data); @@ -75,8 +75,7 @@ static unsigned long epoch = 1970; /* year corresponding to 0x00 */ static const unsigned char days_in_mo[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static long rtc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct rtc_time wtime; @@ -197,7 +196,7 @@ static int rtc_release(struct inode *inode, struct file *file) static const struct file_operations rtc_fops = { .owner = THIS_MODULE, - .ioctl = rtc_ioctl, + .unlocked_ioctl = rtc_ioctl, .open = rtc_open, .release = rtc_release, }; diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 5dc1265ce1d5..32b2b22996dc 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -365,12 +365,12 @@ static struct device_driver ipmidriver = { }; static DEFINE_MUTEX(ipmidriver_mutex); -static struct list_head ipmi_interfaces = LIST_HEAD_INIT(ipmi_interfaces); +static LIST_HEAD(ipmi_interfaces); static DEFINE_MUTEX(ipmi_interfaces_mutex); /* List of watchers that want to know when smi's are added and deleted. */ -static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers); +static LIST_HEAD(smi_watchers); static DEFINE_MUTEX(smi_watchers_mutex); @@ -441,7 +441,7 @@ struct watcher_entry { int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) { ipmi_smi_t intf; - struct list_head to_deliver = LIST_HEAD_INIT(to_deliver); + LIST_HEAD(to_deliver); struct watcher_entry *e, *e2; mutex_lock(&smi_watchers_mutex); diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 81674d7c56c7..60ac642752be 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -312,7 +312,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf, if (copy_size > LP_BUFFER_SIZE) copy_size = LP_BUFFER_SIZE; - if (down_interruptible (&lp_table[minor].port_mutex)) + if (mutex_lock_interruptible(&lp_table[minor].port_mutex)) return -EINTR; if (copy_from_user (kbuf, buf, copy_size)) { @@ -399,7 +399,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf, lp_release_parport (&lp_table[minor]); } out_unlock: - up (&lp_table[minor].port_mutex); + mutex_unlock(&lp_table[minor].port_mutex); return retv; } @@ -421,7 +421,7 @@ static ssize_t lp_read(struct file * file, char __user * buf, if (count > LP_BUFFER_SIZE) count = LP_BUFFER_SIZE; - if (down_interruptible (&lp_table[minor].port_mutex)) + if (mutex_lock_interruptible(&lp_table[minor].port_mutex)) return -EINTR; lp_claim_parport_or_block (&lp_table[minor]); @@ -479,7 +479,7 @@ static ssize_t lp_read(struct file * file, char __user * buf, if (retval > 0 && copy_to_user (buf, kbuf, retval)) retval = -EFAULT; - up (&lp_table[minor].port_mutex); + mutex_unlock(&lp_table[minor].port_mutex); return retval; } @@ -888,7 +888,7 @@ static int __init lp_init (void) lp_table[i].last_error = 0; init_waitqueue_head (&lp_table[i].waitq); init_waitqueue_head (&lp_table[i].dataq); - init_MUTEX (&lp_table[i].port_mutex); + mutex_init(&lp_table[i].port_mutex); lp_table[i].timeout = 10 * HZ; } diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index fd0abef7ee08..47420787a017 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -37,7 +37,6 @@ #include <linux/module.h> -#include <linux/autoconf.h> #include <linux/errno.h> #include <linux/signal.h> #include <linux/sched.h> diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c index 081c84c7b548..bf1bee4e1f5e 100644 --- a/drivers/char/mxser_new.c +++ b/drivers/char/mxser_new.c @@ -20,7 +20,6 @@ */ #include <linux/module.h> -#include <linux/autoconf.h> #include <linux/errno.h> #include <linux/signal.h> #include <linux/sched.h> diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 596c7173997b..90c3969012a3 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -695,17 +695,16 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) return; } - if (tty->stopped && !tty->flow_stopped && - I_IXON(tty) && I_IXANY(tty)) { - start_tty(tty); - return; - } - if (I_ISTRIP(tty)) c &= 0x7f; if (I_IUCLC(tty) && L_IEXTEN(tty)) c=tolower(c); + if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && + ((I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty)) || + c == INTR_CHAR(tty) || c == QUIT_CHAR(tty))) + start_tty(tty); + if (tty->closing) { if (I_IXON(tty)) { if (c == START_CHAR(tty)) @@ -769,7 +768,21 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) signal = SIGTSTP; if (c == SUSP_CHAR(tty)) { send_signal: - isig(signal, tty, 0); + /* + * Echo character, and then send the signal. + * Note that we do not use isig() here because we want + * the order to be: + * 1) flush, 2) echo, 3) signal + */ + if (!L_NOFLSH(tty)) { + n_tty_flush_buffer(tty); + if (tty->driver->flush_buffer) + tty->driver->flush_buffer(tty); + } + if (L_ECHO(tty)) + echo_char(c, tty); + if (tty->pgrp) + kill_pgrp(tty->pgrp, signal, 1); return; } } diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 8caff0ca80ff..279ff5005cec 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -57,6 +57,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/ioctl.h> +#include <linux/synclink.h> #include <asm/system.h> #include <asm/io.h> @@ -87,8 +88,6 @@ #include <asm/uaccess.h> -#include "linux/synclink.h" - static MGSL_PARAMS default_params = { MGSL_MODE_HDLC, /* unsigned long mode */ 0, /* unsigned char loopback; */ diff --git a/drivers/char/random.c b/drivers/char/random.c index c511a831f0c0..f43c89f7c449 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1039,6 +1039,7 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count) p += bytes; add_entropy_words(r, buf, (bytes + 3) / 4); + cond_resched(); } return 0; diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 102ece4c4e0e..d130b87d8ed7 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c @@ -47,6 +47,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/tty_flip.h> +#include <linux/spinlock.h> #include <asm/uaccess.h> @@ -81,6 +82,8 @@ static struct tty_driver *riscom_driver; +static DEFINE_SPINLOCK(riscom_lock); + static struct riscom_board rc_board[RC_NBOARD] = { { .base = RC_IOBASE1, @@ -217,13 +220,14 @@ static void __init rc_init_CD180(struct riscom_board const * bp) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&riscom_lock, flags); + rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ rc_wait_CCR(bp); /* Wait for CCR ready */ rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ - sti(); + spin_unlock_irqrestore(&riscom_lock, flags); msleep(50); /* Delay 0.05 sec */ - cli(); + spin_lock_irqsave(&riscom_lock, flags); rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ rc_out(bp, CD180_GICR, 0); /* Clear all bits */ rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ @@ -234,7 +238,7 @@ static void __init rc_init_CD180(struct riscom_board const * bp) rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); - restore_flags(flags); + spin_unlock_irqrestore(&riscom_lock, flags); } /* Main probing routine, also sets irq. */ @@ -812,9 +816,9 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) } port->xmit_buf = (unsigned char *) tmp; } - - save_flags(flags); cli(); - + + spin_lock_irqsave(&riscom_lock, flags); + if (port->tty) clear_bit(TTY_IO_ERROR, &port->tty->flags); @@ -825,7 +829,7 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) rc_change_speed(bp, port); port->flags |= ASYNC_INITIALIZED; - restore_flags(flags); + spin_unlock_irqrestore(&riscom_lock, flags); return 0; } @@ -901,6 +905,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, int retval; int do_clocal = 0; int CD; + unsigned long flags; /* * If the device is in the middle of being closed, then block @@ -936,19 +941,26 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, */ retval = 0; add_wait_queue(&port->open_wait, &wait); - cli(); + + spin_lock_irqsave(&riscom_lock, flags); + if (!tty_hung_up_p(filp)) port->count--; - sti(); + + spin_unlock_irqrestore(&riscom_lock, flags); + port->blocked_open++; while (1) { - cli(); + spin_lock_irqsave(&riscom_lock, flags); + rc_out(bp, CD180_CAR, port_No(port)); CD = rc_in(bp, CD180_MSVR) & MSVR_CD; rc_out(bp, CD180_MSVR, MSVR_RTS); bp->DTR &= ~(1u << port_No(port)); rc_out(bp, RC_DTR, bp->DTR); - sti(); + + spin_unlock_irqrestore(&riscom_lock, flags); + set_current_state(TASK_INTERRUPTIBLE); if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { @@ -1020,8 +1032,9 @@ static void rc_close(struct tty_struct * tty, struct file * filp) if (!port || rc_paranoia_check(port, tty->name, "close")) return; - - save_flags(flags); cli(); + + spin_lock_irqsave(&riscom_lock, flags); + if (tty_hung_up_p(filp)) goto out; @@ -1088,7 +1101,9 @@ static void rc_close(struct tty_struct * tty, struct file * filp) } port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&port->close_wait); -out: restore_flags(flags); + +out: + spin_unlock_irqrestore(&riscom_lock, flags); } static int rc_write(struct tty_struct * tty, @@ -1107,34 +1122,33 @@ static int rc_write(struct tty_struct * tty, if (!tty || !port->xmit_buf) return 0; - save_flags(flags); while (1) { - cli(); + spin_lock_irqsave(&riscom_lock, flags); + c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, SERIAL_XMIT_SIZE - port->xmit_head)); - if (c <= 0) { - restore_flags(flags); - break; - } + if (c <= 0) + break; /* lock continues to be held */ memcpy(port->xmit_buf + port->xmit_head, buf, c); port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); port->xmit_cnt += c; - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); buf += c; count -= c; total += c; } - cli(); if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && !(port->IER & IER_TXRDY)) { port->IER |= IER_TXRDY; rc_out(bp, CD180_CAR, port_No(port)); rc_out(bp, CD180_IER, port->IER); } - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); return total; } @@ -1150,7 +1164,7 @@ static void rc_put_char(struct tty_struct * tty, unsigned char ch) if (!tty || !port->xmit_buf) return; - save_flags(flags); cli(); + spin_lock_irqsave(&riscom_lock, flags); if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) goto out; @@ -1158,7 +1172,9 @@ static void rc_put_char(struct tty_struct * tty, unsigned char ch) port->xmit_buf[port->xmit_head++] = ch; port->xmit_head &= SERIAL_XMIT_SIZE - 1; port->xmit_cnt++; -out: restore_flags(flags); + +out: + spin_unlock_irqrestore(&riscom_lock, flags); } static void rc_flush_chars(struct tty_struct * tty) @@ -1173,11 +1189,13 @@ static void rc_flush_chars(struct tty_struct * tty) !port->xmit_buf) return; - save_flags(flags); cli(); + spin_lock_irqsave(&riscom_lock, flags); + port->IER |= IER_TXRDY; rc_out(port_Board(port), CD180_CAR, port_No(port)); rc_out(port_Board(port), CD180_IER, port->IER); - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); } static int rc_write_room(struct tty_struct * tty) @@ -1212,9 +1230,11 @@ static void rc_flush_buffer(struct tty_struct *tty) if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) return; - save_flags(flags); cli(); + spin_lock_irqsave(&riscom_lock, flags); + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); tty_wakeup(tty); } @@ -1231,11 +1251,15 @@ static int rc_tiocmget(struct tty_struct *tty, struct file *file) return -ENODEV; bp = port_Board(port); - save_flags(flags); cli(); + + spin_lock_irqsave(&riscom_lock, flags); + rc_out(bp, CD180_CAR, port_No(port)); status = rc_in(bp, CD180_MSVR); result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG; - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); + result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0) | ((status & MSVR_DTR) ? TIOCM_DTR : 0) | ((status & MSVR_CD) ? TIOCM_CAR : 0) @@ -1256,7 +1280,8 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file, bp = port_Board(port); - save_flags(flags); cli(); + spin_lock_irqsave(&riscom_lock, flags); + if (set & TIOCM_RTS) port->MSVR |= MSVR_RTS; if (set & TIOCM_DTR) @@ -1270,7 +1295,9 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file, rc_out(bp, CD180_CAR, port_No(port)); rc_out(bp, CD180_MSVR, port->MSVR); rc_out(bp, RC_DTR, bp->DTR); - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); + return 0; } @@ -1279,7 +1306,8 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length struct riscom_board *bp = port_Board(port); unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&riscom_lock, flags); + port->break_length = RISCOM_TPS / HZ * length; port->COR2 |= COR2_ETC; port->IER |= IER_TXRDY; @@ -1289,7 +1317,8 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length rc_wait_CCR(bp); rc_out(bp, CD180_CCR, CCR_CORCHG2); rc_wait_CCR(bp); - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); } static inline int rc_set_serial_info(struct riscom_port * port, @@ -1298,7 +1327,6 @@ static inline int rc_set_serial_info(struct riscom_port * port, struct serial_struct tmp; struct riscom_board *bp = port_Board(port); int change_speed; - unsigned long flags; if (copy_from_user(&tmp, newinfo, sizeof(tmp))) return -EFAULT; @@ -1332,9 +1360,11 @@ static inline int rc_set_serial_info(struct riscom_port * port, port->closing_wait = tmp.closing_wait; } if (change_speed) { - save_flags(flags); cli(); + unsigned long flags; + + spin_lock_irqsave(&riscom_lock, flags); rc_change_speed(bp, port); - restore_flags(flags); + spin_unlock_irqrestore(&riscom_lock, flags); } return 0; } @@ -1414,17 +1444,19 @@ static void rc_throttle(struct tty_struct * tty) return; bp = port_Board(port); - - save_flags(flags); cli(); + + spin_lock_irqsave(&riscom_lock, flags); + port->MSVR &= ~MSVR_RTS; rc_out(bp, CD180_CAR, port_No(port)); - if (I_IXOFF(tty)) { + if (I_IXOFF(tty)) { rc_wait_CCR(bp); rc_out(bp, CD180_CCR, CCR_SSCH2); rc_wait_CCR(bp); } rc_out(bp, CD180_MSVR, port->MSVR); - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); } static void rc_unthrottle(struct tty_struct * tty) @@ -1438,7 +1470,8 @@ static void rc_unthrottle(struct tty_struct * tty) bp = port_Board(port); - save_flags(flags); cli(); + spin_lock_irqsave(&riscom_lock, flags); + port->MSVR |= MSVR_RTS; rc_out(bp, CD180_CAR, port_No(port)); if (I_IXOFF(tty)) { @@ -1447,7 +1480,8 @@ static void rc_unthrottle(struct tty_struct * tty) rc_wait_CCR(bp); } rc_out(bp, CD180_MSVR, port->MSVR); - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); } static void rc_stop(struct tty_struct * tty) @@ -1461,11 +1495,13 @@ static void rc_stop(struct tty_struct * tty) bp = port_Board(port); - save_flags(flags); cli(); + spin_lock_irqsave(&riscom_lock, flags); + port->IER &= ~IER_TXRDY; rc_out(bp, CD180_CAR, port_No(port)); rc_out(bp, CD180_IER, port->IER); - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); } static void rc_start(struct tty_struct * tty) @@ -1479,13 +1515,15 @@ static void rc_start(struct tty_struct * tty) bp = port_Board(port); - save_flags(flags); cli(); + spin_lock_irqsave(&riscom_lock, flags); + if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { port->IER |= IER_TXRDY; rc_out(bp, CD180_CAR, port_No(port)); rc_out(bp, CD180_IER, port->IER); } - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); } /* @@ -1537,9 +1575,9 @@ static void rc_set_termios(struct tty_struct * tty, struct ktermios * old_termio tty->termios->c_iflag == old_termios->c_iflag) return; - save_flags(flags); cli(); + spin_lock_irqsave(&riscom_lock, flags); rc_change_speed(port_Board(port), port); - restore_flags(flags); + spin_unlock_irqrestore(&riscom_lock, flags); if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { @@ -1627,11 +1665,12 @@ static void rc_release_drivers(void) { unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&riscom_lock, flags); + tty_unregister_driver(riscom_driver); put_tty_driver(riscom_driver); - restore_flags(flags); + + spin_unlock_irqrestore(&riscom_lock, flags); } #ifndef MODULE diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index 3c869145bfdc..4ba3aec9e1cd 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c @@ -653,7 +653,7 @@ static void a2232_init_portstructs(void) port->gs.closing_wait = 30 * HZ; port->gs.rd = &a2232_real_driver; #ifdef NEW_WRITE_LOCKING - init_MUTEX(&(port->gs.port_write_mutex)); + mutex_init(&(port->gs.port_write_mutex)); #endif init_waitqueue_head(&port->gs.open_wait); init_waitqueue_head(&port->gs.close_wait); diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index d010ed95ed3b..ddc74d1f4f1b 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -85,6 +85,7 @@ #include <linux/vmalloc.h> #include <linux/init.h> #include <linux/ioctl.h> +#include <linux/synclink.h> #include <asm/system.h> #include <asm/io.h> @@ -110,8 +111,6 @@ #include <asm/uaccess.h> -#include "linux/synclink.h" - #define RCLRVALUE 0xffff static MGSL_PARAMS default_params = { diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 64e835f62438..1f954acf2bac 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -73,6 +73,7 @@ #include <linux/bitops.h> #include <linux/workqueue.h> #include <linux/hdlc.h> +#include <linux/synclink.h> #include <asm/system.h> #include <asm/io.h> @@ -81,8 +82,6 @@ #include <asm/types.h> #include <asm/uaccess.h> -#include "linux/synclink.h" - #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE)) #define SYNCLINK_GENERIC_HDLC 1 #else @@ -2040,37 +2039,41 @@ static void bh_transmit(struct slgt_info *info) tty_wakeup(tty); } -static void dsr_change(struct slgt_info *info) +static void dsr_change(struct slgt_info *info, unsigned short status) { - get_signals(info); + if (status & BIT3) { + info->signals |= SerialSignal_DSR; + info->input_signal_events.dsr_up++; + } else { + info->signals &= ~SerialSignal_DSR; + info->input_signal_events.dsr_down++; + } DBGISR(("dsr_change %s signals=%04X\n", info->device_name, info->signals)); if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { slgt_irq_off(info, IRQ_DSR); return; } info->icount.dsr++; - if (info->signals & SerialSignal_DSR) - info->input_signal_events.dsr_up++; - else - info->input_signal_events.dsr_down++; wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->event_wait_q); info->pending_bh |= BH_STATUS; } -static void cts_change(struct slgt_info *info) +static void cts_change(struct slgt_info *info, unsigned short status) { - get_signals(info); + if (status & BIT2) { + info->signals |= SerialSignal_CTS; + info->input_signal_events.cts_up++; + } else { + info->signals &= ~SerialSignal_CTS; + info->input_signal_events.cts_down++; + } DBGISR(("cts_change %s signals=%04X\n", info->device_name, info->signals)); if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { slgt_irq_off(info, IRQ_CTS); return; } info->icount.cts++; - if (info->signals & SerialSignal_CTS) - info->input_signal_events.cts_up++; - else - info->input_signal_events.cts_down++; wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->event_wait_q); info->pending_bh |= BH_STATUS; @@ -2091,20 +2094,21 @@ static void cts_change(struct slgt_info *info) } } -static void dcd_change(struct slgt_info *info) +static void dcd_change(struct slgt_info *info, unsigned short status) { - get_signals(info); + if (status & BIT1) { + info->signals |= SerialSignal_DCD; + info->input_signal_events.dcd_up++; + } else { + info->signals &= ~SerialSignal_DCD; + info->input_signal_events.dcd_down++; + } DBGISR(("dcd_change %s signals=%04X\n", info->device_name, info->signals)); if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { slgt_irq_off(info, IRQ_DCD); return; } info->icount.dcd++; - if (info->signals & SerialSignal_DCD) { - info->input_signal_events.dcd_up++; - } else { - info->input_signal_events.dcd_down++; - } #if SYNCLINK_GENERIC_HDLC if (info->netcount) { if (info->signals & SerialSignal_DCD) @@ -2127,20 +2131,21 @@ static void dcd_change(struct slgt_info *info) } } -static void ri_change(struct slgt_info *info) +static void ri_change(struct slgt_info *info, unsigned short status) { - get_signals(info); + if (status & BIT0) { + info->signals |= SerialSignal_RI; + info->input_signal_events.ri_up++; + } else { + info->signals &= ~SerialSignal_RI; + info->input_signal_events.ri_down++; + } DBGISR(("ri_change %s signals=%04X\n", info->device_name, info->signals)); if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { slgt_irq_off(info, IRQ_RI); return; } - info->icount.dcd++; - if (info->signals & SerialSignal_RI) { - info->input_signal_events.ri_up++; - } else { - info->input_signal_events.ri_down++; - } + info->icount.rng++; wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->event_wait_q); info->pending_bh |= BH_STATUS; @@ -2191,13 +2196,13 @@ static void isr_serial(struct slgt_info *info) } if (status & IRQ_DSR) - dsr_change(info); + dsr_change(info, status); if (status & IRQ_CTS) - cts_change(info); + cts_change(info, status); if (status & IRQ_DCD) - dcd_change(info); + dcd_change(info, status); if (status & IRQ_RI) - ri_change(info); + ri_change(info, status); } static void isr_rdma(struct slgt_info *info) diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index c63013b2fc36..f3e7807f78d9 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c @@ -66,6 +66,7 @@ #include <linux/termios.h> #include <linux/workqueue.h> #include <linux/hdlc.h> +#include <linux/synclink.h> #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINKMP_MODULE)) #define SYNCLINK_GENERIC_HDLC 1 @@ -80,8 +81,6 @@ #include <asm/uaccess.h> -#include "linux/synclink.h" - static MGSL_PARAMS default_params = { MGSL_MODE_HDLC, /* unsigned long mode */ 0, /* unsigned char loopback; */ diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index c88424a0c89b..a5d8bcb40000 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -1031,18 +1031,13 @@ void tpm_remove_hardware(struct device *dev) spin_unlock(&driver_lock); - dev_set_drvdata(dev, NULL); misc_deregister(&chip->vendor.miscdev); - kfree(chip->vendor.miscdev.name); sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); tpm_bios_log_teardown(chip->bios_dir); - clear_bit(chip->dev_num, dev_mask); - - kfree(chip); - - put_device(dev); + /* write it this way to be explicit (chip->dev == dev) */ + put_device(chip->dev); } EXPORT_SYMBOL_GPL(tpm_remove_hardware); @@ -1083,6 +1078,26 @@ int tpm_pm_resume(struct device *dev) EXPORT_SYMBOL_GPL(tpm_pm_resume); /* + * Once all references to platform device are down to 0, + * release all allocated structures. + * In case vendor provided release function, + * call it too. + */ +static void tpm_dev_release(struct device *dev) +{ + struct tpm_chip *chip = dev_get_drvdata(dev); + + if (chip->vendor.release) + chip->vendor.release(dev); + + chip->release(dev); + + clear_bit(chip->dev_num, dev_mask); + kfree(chip->vendor.miscdev.name); + kfree(chip); +} + +/* * Called from tpm_<specific>.c probe function only for devices * the driver has determined it should claim. Prior to calling * this function the specific probe function has called pci_enable_device @@ -1136,23 +1151,21 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend chip->vendor.miscdev.parent = dev; chip->dev = get_device(dev); + chip->release = dev->release; + dev->release = tpm_dev_release; + dev_set_drvdata(dev, chip); if (misc_register(&chip->vendor.miscdev)) { dev_err(chip->dev, "unable to misc_register %s, minor %d\n", chip->vendor.miscdev.name, chip->vendor.miscdev.minor); - put_device(dev); - clear_bit(chip->dev_num, dev_mask); - kfree(chip); - kfree(devname); + put_device(chip->dev); return NULL; } spin_lock(&driver_lock); - dev_set_drvdata(dev, chip); - list_add(&chip->list, &tpm_chip_list); spin_unlock(&driver_lock); @@ -1160,10 +1173,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { list_del(&chip->list); misc_deregister(&chip->vendor.miscdev); - put_device(dev); - clear_bit(chip->dev_num, dev_mask); - kfree(chip); - kfree(devname); + put_device(chip->dev); return NULL; } diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index d15ccddc92eb..e885148b4cfb 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -74,6 +74,7 @@ struct tpm_vendor_specific { int (*send) (struct tpm_chip *, u8 *, size_t); void (*cancel) (struct tpm_chip *); u8 (*status) (struct tpm_chip *); + void (*release) (struct device *); struct miscdevice miscdev; struct attribute_group *attr_group; struct list_head list; @@ -106,6 +107,7 @@ struct tpm_chip { struct dentry **bios_dir; struct list_head list; + void (*release) (struct device *); }; #define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 967002a5a1e5..726ee8a0277f 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c @@ -611,7 +611,7 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) } } -static struct pnp_driver tpm_inf_pnp = { +static struct pnp_driver tpm_inf_pnp_driver = { .name = "tpm_inf_pnp", .driver = { .owner = THIS_MODULE, @@ -625,12 +625,12 @@ static struct pnp_driver tpm_inf_pnp = { static int __init init_inf(void) { - return pnp_register_driver(&tpm_inf_pnp); + return pnp_register_driver(&tpm_inf_pnp_driver); } static void __exit cleanup_inf(void) { - pnp_unregister_driver(&tpm_inf_pnp); + pnp_unregister_driver(&tpm_inf_pnp_driver); } module_init(init_inf); diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index f36fecd3fd26..79c86c47947f 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -138,7 +138,7 @@ EXPORT_SYMBOL(tty_mutex); extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ extern int pty_limit; /* Config limit on Unix98 ptys */ static DEFINE_IDR(allocated_ptys); -static DECLARE_MUTEX(allocated_ptys_lock); +static DEFINE_MUTEX(allocated_ptys_lock); static int ptmx_open(struct inode *, struct file *); #endif @@ -2571,9 +2571,9 @@ static void release_dev(struct file * filp) #ifdef CONFIG_UNIX98_PTYS /* Make this pty number available for reallocation */ if (devpts) { - down(&allocated_ptys_lock); + mutex_lock(&allocated_ptys_lock); idr_remove(&allocated_ptys, idx); - up(&allocated_ptys_lock); + mutex_unlock(&allocated_ptys_lock); } #endif @@ -2737,24 +2737,24 @@ static int ptmx_open(struct inode * inode, struct file * filp) nonseekable_open(inode, filp); /* find a device that is not in use. */ - down(&allocated_ptys_lock); + mutex_lock(&allocated_ptys_lock); if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) { - up(&allocated_ptys_lock); + mutex_unlock(&allocated_ptys_lock); return -ENOMEM; } idr_ret = idr_get_new(&allocated_ptys, NULL, &index); if (idr_ret < 0) { - up(&allocated_ptys_lock); + mutex_unlock(&allocated_ptys_lock); if (idr_ret == -EAGAIN) return -ENOMEM; return -EIO; } if (index >= pty_limit) { idr_remove(&allocated_ptys, index); - up(&allocated_ptys_lock); + mutex_unlock(&allocated_ptys_lock); return -EIO; } - up(&allocated_ptys_lock); + mutex_unlock(&allocated_ptys_lock); mutex_lock(&tty_mutex); retval = init_dev(ptm_driver, index, &tty); @@ -2781,9 +2781,9 @@ out1: release_dev(filp); return retval; out: - down(&allocated_ptys_lock); + mutex_lock(&allocated_ptys_lock); idr_remove(&allocated_ptys, index); - up(&allocated_ptys_lock); + mutex_unlock(&allocated_ptys_lock); return retval; } #endif @@ -3721,7 +3721,6 @@ static void initialize_tty_struct(struct tty_struct *tty) tty->buf.head = tty->buf.tail = NULL; tty_buffer_init(tty); INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); - init_MUTEX(&tty->buf.pty_sem); mutex_init(&tty->termios_mutex); init_waitqueue_head(&tty->write_wait); init_waitqueue_head(&tty->read_wait); @@ -4048,10 +4047,6 @@ void __init console_init(void) } } -#ifdef CONFIG_VT -extern int vty_init(void); -#endif - static int __init tty_class_init(void) { tty_class = class_create(THIS_MODULE, "tty"); diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 7a5badfb7d84..367be9175061 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -2400,13 +2400,15 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) { struct vc_data *vc = vc_cons[fg_console].d; unsigned char c; - static unsigned long printing; + static DEFINE_SPINLOCK(printing_lock); const ushort *start; ushort cnt = 0; ushort myx; /* console busy or not yet initialized */ - if (!printable || test_and_set_bit(0, &printing)) + if (!printable) + return; + if (!spin_trylock(&printing_lock)) return; if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1)) @@ -2481,7 +2483,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) notify_update(vc); quit: - clear_bit(0, &printing); + spin_unlock(&printing_lock); } static struct tty_driver *vt_console_device(struct console *c, int *index) |