Merge git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

* git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: fm801-gp - handle errors from pci_enable_device()
  Input: gameport core - handle errors returned by device_bind_driver()
  Input: serio core - handle errors returned by device_bind_driver()
  Lockdep: fix compile error in drivers/input/serio/serio.c
  Input: serio - add lockdep annotations
  Lockdep: add lockdep_set_class_and_subclass() and lockdep_set_subclass()
  Input: atkbd - supress "too many keys" error message
  Input: i8042 - supress ACK/NAKs when blinking during panic
  Input: add missing exports to fix modular build
This commit is contained in:
Linus Torvalds 2006-10-17 08:56:43 -07:00
commit 43f82216f0
16 changed files with 132 additions and 42 deletions

View File

@ -645,6 +645,7 @@ void add_input_randomness(unsigned int type, unsigned int code,
add_timer_randomness(&input_timer_state,
(type << 4) ^ code ^ (code >> 4) ^ value);
}
EXPORT_SYMBOL_GPL(add_input_randomness);
void add_interrupt_randomness(int irq)
{

View File

@ -82,17 +82,19 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
{
struct fm801_gp *gp;
struct gameport *port;
int error;
gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL);
port = gameport_allocate_port();
if (!gp || !port) {
printk(KERN_ERR "fm801-gp: Memory allocation failed\n");
kfree(gp);
gameport_free_port(port);
return -ENOMEM;
error = -ENOMEM;
goto err_out_free;
}
pci_enable_device(pci);
error = pci_enable_device(pci);
if (error)
goto err_out_free;
port->open = fm801_gp_open;
#ifdef HAVE_COOKED
@ -108,9 +110,8 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
if (!gp->res_port) {
printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n",
port->io, port->io + 0x0f);
gameport_free_port(port);
kfree(gp);
return -EBUSY;
error = -EBUSY;
goto err_out_disable_dev;
}
pci_set_drvdata(pci, gp);
@ -119,6 +120,13 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
gameport_register_port(port);
return 0;
err_out_disable_dev:
pci_disable_device(pci);
err_out_free:
gameport_free_port(port);
kfree(gp);
return error;
}
static void __devexit fm801_gp_remove(struct pci_dev *pci)

View File

@ -191,6 +191,8 @@ static void gameport_run_poll_handler(unsigned long d)
static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv)
{
int error;
down_write(&gameport_bus.subsys.rwsem);
gameport->dev.driver = &drv->driver;
@ -198,8 +200,20 @@ static void gameport_bind_driver(struct gameport *gameport, struct gameport_driv
gameport->dev.driver = NULL;
goto out;
}
device_bind_driver(&gameport->dev);
out:
error = device_bind_driver(&gameport->dev);
if (error) {
printk(KERN_WARNING
"gameport: device_bind_driver() failed "
"for %s (%s) and %s, error: %d\n",
gameport->phys, gameport->name,
drv->description, error);
drv->disconnect(gameport);
gameport->dev.driver = NULL;
goto out;
}
out:
up_write(&gameport_bus.subsys.rwsem);
}

View File

@ -221,6 +221,7 @@ struct atkbd {
unsigned long xl_bit;
unsigned int last;
unsigned long time;
unsigned long err_count;
struct work_struct event_work;
struct mutex event_mutex;
@ -234,11 +235,13 @@ static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t
#define ATKBD_DEFINE_ATTR(_name) \
static ssize_t atkbd_show_##_name(struct atkbd *, char *); \
static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \
static ssize_t atkbd_do_show_##_name(struct device *d, struct device_attribute *attr, char *b) \
static ssize_t atkbd_do_show_##_name(struct device *d, \
struct device_attribute *attr, char *b) \
{ \
return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \
} \
static ssize_t atkbd_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s) \
static ssize_t atkbd_do_set_##_name(struct device *d, \
struct device_attribute *attr, const char *b, size_t s) \
{ \
return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \
} \
@ -251,6 +254,32 @@ ATKBD_DEFINE_ATTR(set);
ATKBD_DEFINE_ATTR(softrepeat);
ATKBD_DEFINE_ATTR(softraw);
#define ATKBD_DEFINE_RO_ATTR(_name) \
static ssize_t atkbd_show_##_name(struct atkbd *, char *); \
static ssize_t atkbd_do_show_##_name(struct device *d, \
struct device_attribute *attr, char *b) \
{ \
return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \
} \
static struct device_attribute atkbd_attr_##_name = \
__ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL);
ATKBD_DEFINE_RO_ATTR(err_count);
static struct attribute *atkbd_attributes[] = {
&atkbd_attr_extra.attr,
&atkbd_attr_scroll.attr,
&atkbd_attr_set.attr,
&atkbd_attr_softrepeat.attr,
&atkbd_attr_softraw.attr,
&atkbd_attr_err_count.attr,
NULL
};
static struct attribute_group atkbd_attribute_group = {
.attrs = atkbd_attributes,
};
static const unsigned int xl_table[] = {
ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK,
ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL,
@ -396,7 +425,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
add_release_event = 1;
break;
case ATKBD_RET_ERR:
atkbd->err_count++;
#ifdef ATKBD_DEBUG
printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
#endif
goto out;
}
@ -786,12 +818,7 @@ static void atkbd_disconnect(struct serio *serio)
synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */
flush_scheduled_work();
device_remove_file(&serio->dev, &atkbd_attr_extra);
device_remove_file(&serio->dev, &atkbd_attr_scroll);
device_remove_file(&serio->dev, &atkbd_attr_set);
device_remove_file(&serio->dev, &atkbd_attr_softrepeat);
device_remove_file(&serio->dev, &atkbd_attr_softraw);
sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
input_unregister_device(atkbd->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
@ -961,11 +988,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
device_create_file(&serio->dev, &atkbd_attr_extra);
device_create_file(&serio->dev, &atkbd_attr_scroll);
device_create_file(&serio->dev, &atkbd_attr_set);
device_create_file(&serio->dev, &atkbd_attr_softrepeat);
device_create_file(&serio->dev, &atkbd_attr_softraw);
sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group);
atkbd_enable(atkbd);
@ -1259,6 +1282,11 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
return count;
}
static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf)
{
return sprintf(buf, "%lu\n", atkbd->err_count);
}
static int __init atkbd_init(void)
{

View File

@ -106,6 +106,7 @@ static unsigned char i8042_ctr;
static unsigned char i8042_mux_present;
static unsigned char i8042_kbd_irq_registered;
static unsigned char i8042_aux_irq_registered;
static unsigned char i8042_suppress_kbd_ack;
static struct platform_device *i8042_platform_device;
static irqreturn_t i8042_interrupt(int irq, void *dev_id);
@ -316,7 +317,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
unsigned char str, data;
unsigned int dfl;
unsigned int port_no;
int ret;
int ret = 1;
spin_lock_irqsave(&i8042_lock, flags);
str = i8042_read_status();
@ -378,10 +379,16 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : "");
if (unlikely(i8042_suppress_kbd_ack))
if (port_no == I8042_KBD_PORT_NO &&
(data == 0xfa || data == 0xfe)) {
i8042_suppress_kbd_ack = 0;
goto out;
}
if (likely(port->exists))
serio_interrupt(port->serio, data, dfl);
ret = 1;
out:
return IRQ_RETVAL(ret);
}
@ -842,11 +849,13 @@ static long i8042_panic_blink(long count)
led ^= 0x01 | 0x04;
while (i8042_read_status() & I8042_STR_IBF)
DELAY;
i8042_suppress_kbd_ack = 1;
i8042_write_data(0xed); /* set leds */
DELAY;
while (i8042_read_status() & I8042_STR_IBF)
DELAY;
DELAY;
i8042_suppress_kbd_ack = 1;
i8042_write_data(led);
DELAY;
last_blink = count;

View File

@ -189,7 +189,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
return -1;
}
mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING);
mutex_lock(&ps2dev->cmd_mutex);
serio_pause_rx(ps2dev->serio);
ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
@ -296,6 +296,7 @@ EXPORT_SYMBOL(ps2_schedule_command);
void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
{
mutex_init(&ps2dev->cmd_mutex);
lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth);
init_waitqueue_head(&ps2dev->wait);
ps2dev->serio = serio;
}

View File

@ -118,6 +118,8 @@ static int serio_match_port(const struct serio_device_id *ids, struct serio *ser
static void serio_bind_driver(struct serio *serio, struct serio_driver *drv)
{
int error;
down_write(&serio_bus.subsys.rwsem);
if (serio_match_port(drv->id_table, serio)) {
@ -126,9 +128,19 @@ static void serio_bind_driver(struct serio *serio, struct serio_driver *drv)
serio->dev.driver = NULL;
goto out;
}
device_bind_driver(&serio->dev);
error = device_bind_driver(&serio->dev);
if (error) {
printk(KERN_WARNING
"serio: device_bind_driver() failed "
"for %s (%s) and %s, error: %d\n",
serio->phys, serio->name,
drv->description, error);
serio_disconnect_driver(serio);
serio->dev.driver = NULL;
goto out;
}
}
out:
out:
up_write(&serio_bus.subsys.rwsem);
}
@ -538,8 +550,12 @@ static void serio_init_port(struct serio *serio)
"serio%ld", (long)atomic_inc_return(&serio_no) - 1);
serio->dev.bus = &serio_bus;
serio->dev.release = serio_release_port;
if (serio->parent)
if (serio->parent) {
serio->dev.parent = &serio->parent->dev;
serio->depth = serio->parent->depth + 1;
} else
serio->depth = 0;
lockdep_set_subclass(&serio->lock, serio->depth);
}
/*

View File

@ -202,7 +202,7 @@ extern int lockdep_internal(void);
*/
extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
struct lock_class_key *key);
struct lock_class_key *key, int subclass);
/*
* Reinitialize a lock key - for cases where there is special locking or
@ -211,9 +211,14 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
* or they are too narrow (they suffer from a false class-split):
*/
#define lockdep_set_class(lock, key) \
lockdep_init_map(&(lock)->dep_map, #key, key)
lockdep_init_map(&(lock)->dep_map, #key, key, 0)
#define lockdep_set_class_and_name(lock, key, name) \
lockdep_init_map(&(lock)->dep_map, name, key)
lockdep_init_map(&(lock)->dep_map, name, key, 0)
#define lockdep_set_class_and_subclass(lock, key, sub) \
lockdep_init_map(&(lock)->dep_map, #key, key, sub)
#define lockdep_set_subclass(lock, sub) \
lockdep_init_map(&(lock)->dep_map, #lock, \
(lock)->dep_map.key, sub)
/*
* Acquire a lock.
@ -257,10 +262,14 @@ static inline int lockdep_internal(void)
# define lock_release(l, n, i) do { } while (0)
# define lockdep_init() do { } while (0)
# define lockdep_info() do { } while (0)
# define lockdep_init_map(lock, name, key) do { (void)(key); } while (0)
# define lockdep_init_map(lock, name, key, sub) do { (void)(key); } while (0)
# define lockdep_set_class(lock, key) do { (void)(key); } while (0)
# define lockdep_set_class_and_name(lock, key, name) \
do { (void)(key); } while (0)
#define lockdep_set_class_and_subclass(lock, key, sub) \
do { (void)(key); } while (0)
#define lockdep_set_subclass(lock, sub) do { } while (0)
# define INIT_LOCKDEP
# define lockdep_reset() do { debug_locks = 1; } while (0)
# define lockdep_free_key_range(start, size) do { } while (0)

View File

@ -41,6 +41,7 @@ struct serio {
void (*stop)(struct serio *);
struct serio *parent, *child;
unsigned int depth; /* level of nesting in serio hierarchy */
struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock and serio->sem */
struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */

View File

@ -1176,7 +1176,7 @@ look_up_lock_class(struct lockdep_map *lock, unsigned int subclass)
* itself, so actual lookup of the hash should be once per lock object.
*/
static inline struct lock_class *
register_lock_class(struct lockdep_map *lock, unsigned int subclass)
register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
{
struct lockdep_subclass_key *key;
struct list_head *hash_head;
@ -1248,7 +1248,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass)
out_unlock_set:
__raw_spin_unlock(&hash_lock);
if (!subclass)
if (!subclass || force)
lock->class_cache = class;
DEBUG_LOCKS_WARN_ON(class->subclass != subclass);
@ -1936,7 +1936,7 @@ void trace_softirqs_off(unsigned long ip)
* Initialize a lock instance's lock-class mapping info:
*/
void lockdep_init_map(struct lockdep_map *lock, const char *name,
struct lock_class_key *key)
struct lock_class_key *key, int subclass)
{
if (unlikely(!debug_locks))
return;
@ -1956,6 +1956,8 @@ void lockdep_init_map(struct lockdep_map *lock, const char *name,
lock->name = name;
lock->key = key;
lock->class_cache = NULL;
if (subclass)
register_lock_class(lock, subclass, 1);
}
EXPORT_SYMBOL_GPL(lockdep_init_map);
@ -1994,7 +1996,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
* Not cached yet or subclass?
*/
if (unlikely(!class)) {
class = register_lock_class(lock, subclass);
class = register_lock_class(lock, subclass, 0);
if (!class)
return 0;
}

View File

@ -91,7 +91,7 @@ void debug_mutex_init(struct mutex *lock, const char *name,
* Make sure we are not reinitializing a held lock:
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
lockdep_init_map(&lock->dep_map, name, key);
lockdep_init_map(&lock->dep_map, name, key, 0);
#endif
lock->owner = NULL;
lock->magic = lock;

View File

@ -119,6 +119,7 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
return path;
}
EXPORT_SYMBOL_GPL(kobject_get_path);
/**
* kobject_init - initialize object.

View File

@ -28,7 +28,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name,
* Make sure we are not reinitializing a held semaphore:
*/
debug_check_no_locks_freed((void *)sem, sizeof(*sem));
lockdep_init_map(&sem->dep_map, name, key);
lockdep_init_map(&sem->dep_map, name, key, 0);
#endif
sem->activity = 0;
spin_lock_init(&sem->wait_lock);

View File

@ -19,7 +19,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name,
* Make sure we are not reinitializing a held semaphore:
*/
debug_check_no_locks_freed((void *)sem, sizeof(*sem));
lockdep_init_map(&sem->dep_map, name, key);
lockdep_init_map(&sem->dep_map, name, key, 0);
#endif
sem->count = RWSEM_UNLOCKED_VALUE;
spin_lock_init(&sem->wait_lock);

View File

@ -20,7 +20,7 @@ void __spin_lock_init(spinlock_t *lock, const char *name,
* Make sure we are not reinitializing a held lock:
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
lockdep_init_map(&lock->dep_map, name, key);
lockdep_init_map(&lock->dep_map, name, key, 0);
#endif
lock->raw_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
lock->magic = SPINLOCK_MAGIC;
@ -38,7 +38,7 @@ void __rwlock_init(rwlock_t *lock, const char *name,
* Make sure we are not reinitializing a held lock:
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
lockdep_init_map(&lock->dep_map, name, key);
lockdep_init_map(&lock->dep_map, name, key, 0);
#endif
lock->raw_lock = (raw_rwlock_t) __RAW_RW_LOCK_UNLOCKED;
lock->magic = RWLOCK_MAGIC;

View File

@ -823,7 +823,7 @@ static void inline sock_lock_init(struct sock *sk)
af_family_slock_key_strings[sk->sk_family]);
lockdep_init_map(&sk->sk_lock.dep_map,
af_family_key_strings[sk->sk_family],
af_family_keys + sk->sk_family);
af_family_keys + sk->sk_family, 0);
}
/**