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

Commit 7803c054 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: do not pass injected events back to the originating handler
  Input: pcf8574_keypad - fix error handling in pcf8574_kp_probe
  Input: acecad - fix a memory leak in usb_acecad_probe error path
  Input: atkbd - add 'terminal' parameter for IBM Terminal keyboards
  Input: i8042 - add Sony VAIOs to MUX blacklist
  kgdboc: reset input devices (keyboards) when exiting debugger
  Input: export input_reset_device() for use in KGDB
  Input: adp5588-keys - unify common header defines
parents 522a9914 5fdbe44d
Loading
Loading
Loading
Loading
+61 −26
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
 * dev->event_lock held and interrupts disabled.
 */
static void input_pass_event(struct input_dev *dev,
			     struct input_handler *src_handler,
			     unsigned int type, unsigned int code, int value)
{
	struct input_handler *handler;
@@ -92,6 +93,15 @@ static void input_pass_event(struct input_dev *dev,
				continue;

			handler = handle->handler;

			/*
			 * If this is the handler that injected this
			 * particular event we want to skip it to avoid
			 * filters firing again and again.
			 */
			if (handler == src_handler)
				continue;

			if (!handler->filter) {
				if (filtered)
					break;
@@ -121,7 +131,7 @@ static void input_repeat_key(unsigned long data)
	if (test_bit(dev->repeat_key, dev->key) &&
	    is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {

		input_pass_event(dev, EV_KEY, dev->repeat_key, 2);
		input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2);

		if (dev->sync) {
			/*
@@ -130,7 +140,7 @@ static void input_repeat_key(unsigned long data)
			 * Otherwise assume that the driver will send
			 * SYN_REPORT once it's done.
			 */
			input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
			input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
		}

		if (dev->rep[REP_PERIOD])
@@ -163,6 +173,7 @@ static void input_stop_autorepeat(struct input_dev *dev)
#define INPUT_PASS_TO_ALL	(INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)

static int input_handle_abs_event(struct input_dev *dev,
				  struct input_handler *src_handler,
				  unsigned int code, int *pval)
{
	bool is_mt_event;
@@ -206,13 +217,15 @@ static int input_handle_abs_event(struct input_dev *dev,
	/* Flush pending "slot" event */
	if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
		input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
		input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
		input_pass_event(dev, src_handler,
				 EV_ABS, ABS_MT_SLOT, dev->slot);
	}

	return INPUT_PASS_TO_HANDLERS;
}

static void input_handle_event(struct input_dev *dev,
			       struct input_handler *src_handler,
			       unsigned int type, unsigned int code, int value)
{
	int disposition = INPUT_IGNORE_EVENT;
@@ -265,7 +278,8 @@ static void input_handle_event(struct input_dev *dev,

	case EV_ABS:
		if (is_event_supported(code, dev->absbit, ABS_MAX))
			disposition = input_handle_abs_event(dev, code, &value);
			disposition = input_handle_abs_event(dev, src_handler,
							     code, &value);

		break;

@@ -323,7 +337,7 @@ static void input_handle_event(struct input_dev *dev,
		dev->event(dev, type, code, value);

	if (disposition & INPUT_PASS_TO_HANDLERS)
		input_pass_event(dev, type, code, value);
		input_pass_event(dev, src_handler, type, code, value);
}

/**
@@ -352,7 +366,7 @@ void input_event(struct input_dev *dev,

		spin_lock_irqsave(&dev->event_lock, flags);
		add_input_randomness(type, code, value);
		input_handle_event(dev, type, code, value);
		input_handle_event(dev, NULL, type, code, value);
		spin_unlock_irqrestore(&dev->event_lock, flags);
	}
}
@@ -382,7 +396,8 @@ void input_inject_event(struct input_handle *handle,
		rcu_read_lock();
		grab = rcu_dereference(dev->grab);
		if (!grab || grab == handle)
			input_handle_event(dev, type, code, value);
			input_handle_event(dev, handle->handler,
					   type, code, value);
		rcu_read_unlock();

		spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -595,10 +610,10 @@ static void input_dev_release_keys(struct input_dev *dev)
		for (code = 0; code <= KEY_MAX; code++) {
			if (is_event_supported(code, dev->keybit, KEY_MAX) &&
			    __test_and_clear_bit(code, dev->key)) {
				input_pass_event(dev, EV_KEY, code, 0);
				input_pass_event(dev, NULL, EV_KEY, code, 0);
			}
		}
		input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
		input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
	}
}

@@ -873,9 +888,9 @@ int input_set_keycode(struct input_dev *dev,
	    !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
	    __test_and_clear_bit(old_keycode, dev->key)) {

		input_pass_event(dev, EV_KEY, old_keycode, 0);
		input_pass_event(dev, NULL, EV_KEY, old_keycode, 0);
		if (dev->sync)
			input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
			input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
	}

 out:
@@ -1565,8 +1580,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
		}							\
	} while (0)

#ifdef CONFIG_PM
static void input_dev_reset(struct input_dev *dev, bool activate)
static void input_dev_toggle(struct input_dev *dev, bool activate)
{
	if (!dev->event)
		return;
@@ -1580,12 +1594,44 @@ static void input_dev_reset(struct input_dev *dev, bool activate)
	}
}

/**
 * input_reset_device() - reset/restore the state of input device
 * @dev: input device whose state needs to be reset
 *
 * This function tries to reset the state of an opened input device and
 * bring internal state and state if the hardware in sync with each other.
 * We mark all keys as released, restore LED state, repeat rate, etc.
 */
void input_reset_device(struct input_dev *dev)
{
	mutex_lock(&dev->mutex);

	if (dev->users) {
		input_dev_toggle(dev, true);

		/*
		 * Keys that have been pressed at suspend time are unlikely
		 * to be still pressed when we resume.
		 */
		spin_lock_irq(&dev->event_lock);
		input_dev_release_keys(dev);
		spin_unlock_irq(&dev->event_lock);
	}

	mutex_unlock(&dev->mutex);
}
EXPORT_SYMBOL(input_reset_device);

#ifdef CONFIG_PM
static int input_dev_suspend(struct device *dev)
{
	struct input_dev *input_dev = to_input_dev(dev);

	mutex_lock(&input_dev->mutex);
	input_dev_reset(input_dev, false);

	if (input_dev->users)
		input_dev_toggle(input_dev, false);

	mutex_unlock(&input_dev->mutex);

	return 0;
@@ -1595,18 +1641,7 @@ static int input_dev_resume(struct device *dev)
{
	struct input_dev *input_dev = to_input_dev(dev);

	mutex_lock(&input_dev->mutex);
	input_dev_reset(input_dev, true);

	/*
	 * Keys that have been pressed at suspend time are unlikely
	 * to be still pressed when we resume.
	 */
	spin_lock_irq(&input_dev->event_lock);
	input_dev_release_keys(input_dev);
	spin_unlock_irq(&input_dev->event_lock);

	mutex_unlock(&input_dev->mutex);
	input_reset_device(input_dev);

	return 0;
}
+25 −49
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
 *		 I2C QWERTY Keypad and IO Expander
 * Bugs: Enter bugs at http://blackfin.uclinux.org/
 *
 * Copyright (C) 2008-2009 Analog Devices Inc.
 * Copyright (C) 2008-2010 Analog Devices Inc.
 * Licensed under the GPL-2 or later.
 */

@@ -24,29 +24,6 @@

#include <linux/i2c/adp5588.h>

 /* Configuration Register1 */
#define AUTO_INC	(1 << 7)
#define GPIEM_CFG	(1 << 6)
#define OVR_FLOW_M	(1 << 5)
#define INT_CFG		(1 << 4)
#define OVR_FLOW_IEN	(1 << 3)
#define K_LCK_IM	(1 << 2)
#define GPI_IEN		(1 << 1)
#define KE_IEN		(1 << 0)

/* Interrupt Status Register */
#define CMP2_INT	(1 << 5)
#define CMP1_INT	(1 << 4)
#define OVR_FLOW_INT	(1 << 3)
#define K_LCK_INT	(1 << 2)
#define GPI_INT		(1 << 1)
#define KE_INT		(1 << 0)

/* Key Lock and Event Counter Register */
#define K_LCK_EN	(1 << 6)
#define LCK21		0x30
#define KEC		0xF

/* Key Event Register xy */
#define KEY_EV_PRESSED		(1 << 7)
#define KEY_EV_MASK		(0x7F)
@@ -55,10 +32,6 @@

#define KEYP_MAX_EVENT		10

#define MAXGPIO			18
#define ADP_BANK(offs)		((offs) >> 3)
#define ADP_BIT(offs)		(1u << ((offs) & 0x7))

/*
 * Early pre 4.0 Silicon required to delay readout by at least 25ms,
 * since the Event Counter Register updated 25ms after the interrupt
@@ -75,7 +48,7 @@ struct adp5588_kpad {
	const struct adp5588_gpi_map *gpimap;
	unsigned short gpimapsize;
#ifdef CONFIG_GPIOLIB
	unsigned char gpiomap[MAXGPIO];
	unsigned char gpiomap[ADP5588_MAXGPIO];
	bool export_gpio;
	struct gpio_chip gc;
	struct mutex gpio_lock;	/* Protect cached dir, dat_out */
@@ -103,8 +76,8 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val)
static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
{
	struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
	unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
	unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);

	return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit);
}
@@ -113,8 +86,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip,
				   unsigned off, int val)
{
	struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
	unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
	unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);

	mutex_lock(&kpad->gpio_lock);

@@ -132,8 +105,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip,
static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off)
{
	struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
	unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
	unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
	int ret;

	mutex_lock(&kpad->gpio_lock);
@@ -150,8 +123,8 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip,
					 unsigned off, int val)
{
	struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
	unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
	unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
	int ret;

	mutex_lock(&kpad->gpio_lock);
@@ -176,7 +149,7 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip,
static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad,
				const struct adp5588_kpad_platform_data *pdata)
{
	bool pin_used[MAXGPIO];
	bool pin_used[ADP5588_MAXGPIO];
	int n_unused = 0;
	int i;

@@ -191,7 +164,7 @@ static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad,
	for (i = 0; i < kpad->gpimapsize; i++)
		pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true;

	for (i = 0; i < MAXGPIO; i++)
	for (i = 0; i < ADP5588_MAXGPIO; i++)
		if (!pin_used[i])
			kpad->gpiomap[n_unused++] = i;

@@ -234,7 +207,7 @@ static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad)
		return error;
	}

	for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
	for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
		kpad->dat_out[i] = adp5588_read(kpad->client,
						GPIO_DAT_OUT1 + i);
		kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i);
@@ -318,11 +291,11 @@ static void adp5588_work(struct work_struct *work)

	status = adp5588_read(client, INT_STAT);

	if (status & OVR_FLOW_INT)	/* Unlikely and should never happen */
	if (status & ADP5588_OVR_FLOW_INT)	/* Unlikely and should never happen */
		dev_err(&client->dev, "Event Overflow Error\n");

	if (status & KE_INT) {
		ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC;
	if (status & ADP5588_KE_INT) {
		ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & ADP5588_KEC;
		if (ev_cnt) {
			adp5588_report_events(kpad, ev_cnt);
			input_sync(kpad->input);
@@ -360,7 +333,7 @@ static int __devinit adp5588_setup(struct i2c_client *client)
	if (pdata->en_keylock) {
		ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1);
		ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2);
		ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN);
		ret |= adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN);
	}

	for (i = 0; i < KEYP_MAX_EVENT; i++)
@@ -384,7 +357,7 @@ static int __devinit adp5588_setup(struct i2c_client *client)
	}

	if (gpio_data) {
		for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
		for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
			int pull_mask = gpio_data->pullup_dis_mask;

			ret |= adp5588_write(client, GPIO_PULL1 + i,
@@ -392,11 +365,14 @@ static int __devinit adp5588_setup(struct i2c_client *client)
		}
	}

	ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT |
					OVR_FLOW_INT | K_LCK_INT |
					GPI_INT | KE_INT); /* Status is W1C */
	ret |= adp5588_write(client, INT_STAT,
				ADP5588_CMP2_INT | ADP5588_CMP1_INT |
				ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT |
				ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */

	ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN);
	ret |= adp5588_write(client, CFG, ADP5588_INT_CFG |
					  ADP5588_OVR_FLOW_IEN |
					  ADP5588_KE_IEN);

	if (ret < 0) {
		dev_err(&client->dev, "Write Error\n");
+11 −1
Original line number Diff line number Diff line
@@ -63,6 +63,10 @@ static bool atkbd_extra;
module_param_named(extra, atkbd_extra, bool, 0);
MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards");

static bool atkbd_terminal;
module_param_named(terminal, atkbd_terminal, bool, 0);
MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2");

/*
 * Scancode to keycode tables. These are just the default setting, and
 * are loadable via a userland utility.
@@ -136,7 +140,8 @@ static const unsigned short atkbd_unxlate_table[128] = {
#define ATKBD_CMD_ENABLE	0x00f4
#define ATKBD_CMD_RESET_DIS	0x00f5	/* Reset to defaults and disable */
#define ATKBD_CMD_RESET_DEF	0x00f6	/* Reset to defaults */
#define ATKBD_CMD_SETALL_MBR	0x00fa
#define ATKBD_CMD_SETALL_MB	0x00f8	/* Set all keys to give break codes */
#define ATKBD_CMD_SETALL_MBR	0x00fa  /* ... and repeat */
#define ATKBD_CMD_RESET_BAT	0x02ff
#define ATKBD_CMD_RESEND	0x00fe
#define ATKBD_CMD_EX_ENABLE	0x10ea
@@ -764,6 +769,11 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra
		}
	}

	if (atkbd_terminal) {
		ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MB);
		return 3;
	}

	if (target_set != 3)
		return 2;

+10 −13
Original line number Diff line number Diff line
@@ -127,14 +127,6 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2
	idev->id.product = 0x0001;
	idev->id.version = 0x0100;

	input_set_drvdata(idev, lp);

	ret = input_register_device(idev);
	if (ret) {
		dev_err(&client->dev, "input_register_device() failed\n");
		goto fail_register;
	}

	lp->laststate = read_state(lp);

	ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler,
@@ -142,16 +134,21 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2
				   DRV_NAME, lp);
	if (ret) {
		dev_err(&client->dev, "IRQ %d is not free\n", client->irq);
		goto fail_irq;
		goto fail_free_device;
	}

	ret = input_register_device(idev);
	if (ret) {
		dev_err(&client->dev, "input_register_device() failed\n");
		goto fail_free_irq;
	}

	i2c_set_clientdata(client, lp);
	return 0;

 fail_irq:
	input_unregister_device(idev);
 fail_register:
	input_set_drvdata(idev, NULL);
 fail_free_irq:
	free_irq(client->irq, lp);
 fail_free_device:
	input_free_device(idev);
 fail_allocate:
	kfree(lp);
+11 −0
Original line number Diff line number Diff line
@@ -350,6 +350,17 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
		},
	},
	{
		/*
		 * Most (all?) VAIOs do not have external PS/2 ports nor
		 * they implement active multiplexing properly, and
		 * MUX discovery usually messes up keyboard/touchpad.
		 */
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
			DMI_MATCH(DMI_BOARD_NAME, "VAIO"),
		},
	},
	{
		/* Amoi M636/A737 */
		.matches = {
Loading