summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/hvc_console.c2
-rw-r--r--drivers/char/hvcs.c2
-rw-r--r--drivers/char/hw_random/via-rng.c14
-rw-r--r--drivers/char/i8k.c7
-rw-r--r--drivers/char/ip27-rtc.c9
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c6
-rw-r--r--drivers/char/lp.c10
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/mxser_new.c1
-rw-r--r--drivers/char/n_tty.c27
-rw-r--r--drivers/char/pcmcia/synclink_cs.c3
-rw-r--r--drivers/char/random.c1
-rw-r--r--drivers/char/riscom8.c147
-rw-r--r--drivers/char/ser_a2232.c2
-rw-r--r--drivers/char/synclink.c3
-rw-r--r--drivers/char/synclink_gt.c71
-rw-r--r--drivers/char/synclinkmp.c3
-rw-r--r--drivers/char/tpm/tpm.c44
-rw-r--r--drivers/char/tpm/tpm.h2
-rw-r--r--drivers/char/tpm/tpm_infineon.c6
-rw-r--r--drivers/char/tty_io.c25
-rw-r--r--drivers/char/vt.c8
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)
OpenPOWER on IntegriCloud