mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04: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
16 changed files with 132 additions and 42 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue