Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43f82216 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 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
parents 20f85957 b435fdcd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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)
{
+15 −7
Original line number Diff line number Diff line
@@ -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)
+16 −2
Original line number Diff line number Diff line
@@ -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,7 +200,19 @@ static void gameport_bind_driver(struct gameport *gameport, struct gameport_driv
		gameport->dev.driver = NULL;
		goto out;
	}
	device_bind_driver(&gameport->dev);

	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);
}
+41 −13
Original line number Diff line number Diff line
@@ -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)
{
+11 −2
Original line number Diff line number Diff line
@@ -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;
Loading