mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-25 07:14:36 +08:00
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:
commit
43f82216f0
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user