Commit 36ac1d2f authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (32 commits)
  Input: wm97xx - update email address for Liam Girdwood
  Input: i8042 - add Thinkpad R31 to nomux list
  Input: move map_to_7segment.h to include/linux
  Input: ads7846 - fix cache line sharing issue
  Input: cm109 - add missing newlines to messages
  Input: document i8042.debug in kernel-parameters.txt
  Input: keyboard - fix potential out of bound access to key_map
  Input: psmouse - add OLPC touchpad driver
  Input: psmouse - tweak PSMOUSE_DEFINE_ATTR to support raw set callbacks
  Input: psmouse - add psmouse_queue_work() for ps/2 extension to make use of
  Input: psmouse - export psmouse_set_state for ps/2 extensions to use
  Input: ads7846 - introduce .gpio_pendown to get pendown state
  Input: ALPS - add signature for DualPoint found in Dell Latitude E6500
  Input: serio_raw - allow attaching to translated (SERIO_I8042XL) ports
  Input: cm109 - don't use obsolete logging macros
  Input: atkbd - expand Latitude's force release quirk to other Dells
  Input: bf54x-keys - add power management support
  Input: atmel_tsadcc - improve accuracy
  Input: convert drivers to use strict_strtoul()
  Input: appletouch - handle geyser 3/4 status bits
  ...
parents d7a6119f 4c0e799a
......@@ -796,6 +796,7 @@ and is between 256 and 4096 characters. It is defined in the file
Defaults to the default architecture's huge page size
if not specified.
i8042.debug [HW] Toggle i8042 debug mode
i8042.direct [HW] Put keyboard port into non-translated mode
i8042.dumbkbd [HW] Pretend that controller can only read data from
keyboard and cannot control its state
......
......@@ -4618,7 +4618,7 @@ WM97XX TOUCHSCREEN DRIVERS
P: Mark Brown
M: broonie@opensource.wolfsonmicro.com
P: Liam Girdwood
M: liam.girdwood@wolfsonmicro.com
M: lrg@slimlogic.co.uk
L: linux-input@vger.kernel.org
T: git git://opensource.wolfsonmicro.com/linux-2.6-touch
W: http://opensource.wolfsonmicro.com/node/7
......
......@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
return;
}
if (keycode > NR_KEYS)
if (keycode >= NR_KEYS)
if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
else
......
......@@ -231,6 +231,7 @@ static void gameport_find_driver(struct gameport *gameport)
enum gameport_event_type {
GAMEPORT_REGISTER_PORT,
GAMEPORT_REGISTER_DRIVER,
GAMEPORT_ATTACH_DRIVER,
};
struct gameport_event {
......@@ -245,11 +246,12 @@ static LIST_HEAD(gameport_event_list);
static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
static struct task_struct *gameport_task;
static void gameport_queue_event(void *object, struct module *owner,
enum gameport_event_type event_type)
static int gameport_queue_event(void *object, struct module *owner,
enum gameport_event_type event_type)
{
unsigned long flags;
struct gameport_event *event;
int retval = 0;
spin_lock_irqsave(&gameport_event_lock, flags);
......@@ -268,24 +270,34 @@ static void gameport_queue_event(void *object, struct module *owner,
}
}
if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) {
if (!try_module_get(owner)) {
printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type);
kfree(event);
goto out;
}
event->type = event_type;
event->object = object;
event->owner = owner;
event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
if (!event) {
printk(KERN_ERR
"gameport: Not enough memory to queue event %d\n",
event_type);
retval = -ENOMEM;
goto out;
}
list_add_tail(&event->node, &gameport_event_list);
wake_up(&gameport_wait);
} else {
printk(KERN_ERR "gameport: Not enough memory to queue event %d\n", event_type);
if (!try_module_get(owner)) {
printk(KERN_WARNING
"gameport: Can't get module reference, dropping event %d\n",
event_type);
kfree(event);
retval = -EINVAL;
goto out;
}
event->type = event_type;
event->object = object;
event->owner = owner;
list_add_tail(&event->node, &gameport_event_list);
wake_up(&gameport_wait);
out:
spin_unlock_irqrestore(&gameport_event_lock, flags);
return retval;
}
static void gameport_free_event(struct gameport_event *event)
......@@ -378,9 +390,10 @@ static void gameport_handle_event(void)
}
/*
* Remove all events that have been submitted for a given gameport port.
* Remove all events that have been submitted for a given object,
* be it a gameport port or a driver.
*/
static void gameport_remove_pending_events(struct gameport *gameport)
static void gameport_remove_pending_events(void *object)
{
struct list_head *node, *next;
struct gameport_event *event;
......@@ -390,7 +403,7 @@ static void gameport_remove_pending_events(struct gameport *gameport)
list_for_each_safe(node, next, &gameport_event_list) {
event = list_entry(node, struct gameport_event, node);
if (event->object == gameport) {
if (event->object == object) {
list_del_init(node);
gameport_free_event(event);
}
......@@ -705,10 +718,40 @@ static void gameport_add_driver(struct gameport_driver *drv)
drv->driver.name, error);
}
void __gameport_register_driver(struct gameport_driver *drv, struct module *owner)
int __gameport_register_driver(struct gameport_driver *drv, struct module *owner,
const char *mod_name)
{
int error;
drv->driver.bus = &gameport_bus;
gameport_queue_event(drv, owner, GAMEPORT_REGISTER_DRIVER);
drv->driver.owner = owner;
drv->driver.mod_name = mod_name;
/*
* Temporarily disable automatic binding because probing
* takes long time and we are better off doing it in kgameportd
*/
drv->ignore = 1;
error = driver_register(&drv->driver);
if (error) {
printk(KERN_ERR
"gameport: driver_register() failed for %s, error: %d\n",
drv->driver.name, error);
return error;
}
/*
* Reset ignore flag and let kgameportd bind the driver to free ports
*/
drv->ignore = 0;
error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER);
if (error) {
driver_unregister(&drv->driver);
return error;
}
return 0;
}
void gameport_unregister_driver(struct gameport_driver *drv)
......@@ -716,7 +759,9 @@ void gameport_unregister_driver(struct gameport_driver *drv)
struct gameport *gameport;
mutex_lock(&gameport_mutex);
drv->ignore = 1; /* so gameport_find_driver ignores it */
gameport_remove_pending_events(drv);
start_over:
list_for_each_entry(gameport, &gameport_list, node) {
......@@ -729,6 +774,7 @@ start_over:
}
driver_unregister(&drv->driver);
mutex_unlock(&gameport_mutex);
}
......
......@@ -414,8 +414,7 @@ static struct gameport_driver a3d_drv = {
static int __init a3d_init(void)
{
gameport_register_driver(&a3d_drv);
return 0;
return gameport_register_driver(&a3d_drv);
}
static void __exit a3d_exit(void)
......
......@@ -572,8 +572,7 @@ static struct gameport_driver adi_drv = {
static int __init adi_init(void)
{
gameport_register_driver(&adi_drv);
return 0;
return gameport_register_driver(&adi_drv);
}
static void __exit adi_exit(void)
......
......@@ -761,9 +761,7 @@ static struct gameport_driver analog_drv = {
static int __init analog_init(void)
{
analog_parse_options();
gameport_register_driver(&analog_drv);
return 0;
return gameport_register_driver(&analog_drv);
}
static void __exit analog_exit(void)
......
......@@ -263,8 +263,7 @@ static struct gameport_driver cobra_drv = {
static int __init cobra_init(void)
{
gameport_register_driver(&cobra_drv);
return 0;
return gameport_register_driver(&cobra_drv);
}
static void __exit cobra_exit(void)
......
......@@ -375,8 +375,7 @@ static struct gameport_driver gf2k_drv = {
static int __init gf2k_init(void)
{
gameport_register_driver(&gf2k_drv);
return 0;
return gameport_register_driver(&gf2k_drv);
}
static void __exit gf2k_exit(void)
......
......@@ -426,8 +426,7 @@ static struct gameport_driver grip_drv = {
static int __init grip_init(void)
{
gameport_register_driver(&grip_drv);
return 0;
return gameport_register_driver(&grip_drv);
}
static void __exit grip_exit(void)
......
......@@ -689,8 +689,7 @@ static struct gameport_driver grip_drv = {
static int __init grip_init(void)
{
gameport_register_driver(&grip_drv);
return 0;
return gameport_register_driver(&grip_drv);
}
static void __exit grip_exit(void)
......
......@@ -283,8 +283,7 @@ static struct gameport_driver guillemot_drv = {
static int __init guillemot_init(void)
{
gameport_register_driver(&guillemot_drv);
return 0;
return gameport_register_driver(&guillemot_drv);
}
static void __exit guillemot_exit(void)
......
......@@ -317,8 +317,7 @@ static struct gameport_driver interact_drv = {
static int __init interact_init(void)
{
gameport_register_driver(&interact_drv);
return 0;
return gameport_register_driver(&interact_drv);
}
static void __exit interact_exit(void)
......
......@@ -161,8 +161,7 @@ static struct gameport_driver joydump_drv = {
static int __init joydump_init(void)
{
gameport_register_driver(&joydump_drv);
return 0;
return gameport_register_driver(&joydump_drv);
}
static void __exit joydump_exit(void)
......
......@@ -818,8 +818,7 @@ static struct gameport_driver sw_drv = {
static int __init sw_init(void)
{
gameport_register_driver(&sw_drv);
return 0;
return gameport_register_driver(&sw_drv);
}
static void __exit sw_exit(void)
......
......@@ -438,8 +438,7 @@ static struct gameport_driver tmdc_drv = {
static int __init tmdc_init(void)
{
gameport_register_driver(&tmdc_drv);
return 0;
return gameport_register_driver(&tmdc_drv);
}
static void __exit tmdc_exit(void)
......
......@@ -834,10 +834,10 @@ static void atkbd_disconnect(struct serio *serio)
}
/*
* Most special keys (Fn+F?) on Dell Latitudes do not generate release
* Most special keys (Fn+F?) on Dell laptops do not generate release
* events so we have to do it ourselves.
*/
static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd)
static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
{
const unsigned int forced_release_keys[] = {
0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
......@@ -1207,15 +1207,13 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
int err;
unsigned char old_extra, old_set;
if (!atkbd->write)
return -EIO;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->extra != value) {
......@@ -1264,12 +1262,10 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
int err;
unsigned char old_scroll;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->scroll != value) {
......@@ -1310,15 +1306,13 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
int err;
unsigned char old_set, old_extra;
if (!atkbd->write)
return -EIO;
value = simple_strtoul(buf, &rest, 10);
if (*rest || (value != 2 && value != 3))
if (strict_strtoul(buf, 10, &value) || (value != 2 && value != 3))
return -EINVAL;
if (atkbd->set != value) {
......@@ -1361,15 +1355,13 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
int err;
unsigned char old_softrepeat, old_softraw;
if (!atkbd->write)
return -EIO;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->softrepeat != value) {
......@@ -1413,12 +1405,10 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
int err;
unsigned char old_softraw;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->softraw != value) {
......@@ -1461,13 +1451,13 @@ static int __init atkbd_setup_fixup(const struct dmi_system_id *id)
static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
{
.ident = "Dell Latitude series",
.ident = "Dell Laptop",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
},
.callback = atkbd_setup_fixup,
.driver_data = atkbd_latitude_keymap_fixup,
.driver_data = atkbd_dell_laptop_keymap_fixup,
},
{
.ident = "HP 2133",
......
......@@ -8,7 +8,7 @@
*
*
* Modified:
* Copyright 2007 Analog Devices Inc.
* Copyright 2007-2008 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
......@@ -81,6 +81,9 @@ struct bf54x_kpad {
unsigned short *keycode;
struct timer_list timer;
unsigned int keyup_test_jiffies;
unsigned short kpad_msel;
unsigned short kpad_prescale;
unsigned short kpad_ctl;
};
static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad,
......@@ -360,6 +363,10 @@ static int bfin_kpad_suspend(struct platform_device *pdev, pm_message_t state)
{
struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
bf54x_kpad->kpad_msel = bfin_read_KPAD_MSEL();
bf54x_kpad->kpad_prescale = bfin_read_KPAD_PRESCALE();
bf54x_kpad->kpad_ctl = bfin_read_KPAD_CTL();
if (device_may_wakeup(&pdev->dev))
enable_irq_wake(bf54x_kpad->irq);
......@@ -370,6 +377,10 @@ static int bfin_kpad_resume(struct platform_device *pdev)
{
struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
bfin_write_KPAD_MSEL(bf54x_kpad->kpad_msel);
bfin_write_KPAD_PRESCALE(bf54x_kpad->kpad_prescale);
bfin_write_KPAD_CTL(bf54x_kpad->kpad_ctl);
if (device_may_wakeup(&pdev->dev))
disable_irq_wake(bf54x_kpad->irq);
......
......@@ -36,9 +36,10 @@ struct gpio_keys_drvdata {
struct gpio_button_data data[0];
};
static void gpio_keys_report_event(struct gpio_keys_button *button,
struct input_dev *input)
static void gpio_keys_report_event(struct gpio_button_data *bdata)
{
struct gpio_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned int type = button->type ?: EV_KEY;
int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
......@@ -50,34 +51,23 @@ static void gpio_check_button(unsigned long _data)
{
struct gpio_button_data *data = (struct gpio_button_data *)_data;
gpio_keys_report_event(data->button, data->input);
gpio_keys_report_event(data);
}
static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
{
struct platform_device *pdev = dev_id;
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
int i;
struct gpio_button_data *bdata = dev_id;
struct gpio_keys_button *button = bdata->button;
for (i = 0; i < pdata->nbuttons; i++) {
struct gpio_keys_button *button = &pdata->buttons[i];
BUG_ON(irq != gpio_to_irq(button->gpio));
if (irq == gpio_to_irq(button->gpio)) {
struct gpio_button_data *bdata = &ddata->data[i];
if (button->debounce_interval)
mod_timer(&bdata->timer,
jiffies +
msecs_to_jiffies(button->debounce_interval));
else
gpio_keys_report_event(button, bdata->input);
return IRQ_HANDLED;
}
}
if (button->debounce_interval)
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(button->debounce_interval));
else
gpio_keys_report_event(bdata);
return IRQ_NONE;
return IRQ_HANDLED;
}
static int __devinit gpio_keys_probe(struct platform_device *pdev)
......@@ -151,7 +141,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING,
button->desc ? button->desc : "gpio_keys",
pdev);
bdata);
if (error) {
pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
irq, error);
......@@ -178,7 +168,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
fail2:
while (--i >= 0) {
free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);
free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
if (pdata->buttons[i].debounce_interval)
del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio);
......@@ -203,7 +193,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
for (i = 0; i < pdata->nbuttons; i++) {
int irq = gpio_to_irq(pdata->buttons[i].gpio);
free_irq(irq, pdev);
free_irq(irq, &ddata->data[i]);
if (pdata->buttons[i].debounce_interval)
del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio);
......
......@@ -180,6 +180,19 @@ config INPUT_YEALINK
To compile this driver as a module, choose M here: the module will be
called yealink.
config INPUT_CM109
tristate "C-Media CM109 USB I/O Controller"
depends on EXPERIMENTAL
depends on USB_ARCH_HAS_HCD
select USB
help
Say Y here if you want to enable keyboard and buzzer functions of the
C-Media CM109 usb phones. The audio part is enabled by the generic
usb sound driver, so you might want to enable that as well.
To compile this driver as a module, choose M here: the module will be
called cm109.
config INPUT_UINPUT
tristate "User level driver support"
help
......
......@@ -16,6 +16,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
obj-$(CONFIG_INPUT_CM109) += cm109.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_APANEL) += apanel.o
......
/*
* ati_remote2 - ATI/Philips USB RF remote driver
*
* Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi>
* Copyright (C) 2007 Peter Stokes <linux@dadeos.freeserve.co.uk>
* Copyright (C) 2005-2008 Ville Syrjala <syrjala@sci.fi>
* Copyright (C) 2007-2008 Peter Stokes <linux@dadeos.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
......@@ -12,7 +12,7 @@
#include <linux/usb/input.h>
#define DRIVER_DESC "ATI/Philips USB RF remote driver"
#define DRIVER_VERSION "0.2"
#define DRIVER_VERSION "0.3"
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_VERSION(DRIVER_VERSION);
......@@ -27,7 +27,7 @@ MODULE_LICENSE("GPL");
* A remote's "channel" may be altered by pressing and holding the "PC" button for
* approximately 3 seconds, after which the button will slowly flash the count of the
* currently configured "channel", using the numeric keypad enter a number between 1 and
* 16 and then the "PC" button again, the button will slowly flash the count of the
* 16 and then press the "PC" button again, the button will slowly flash the count of the
* newly configured "channel".
*/
......@@ -45,9 +45,25 @@ static struct usb_device_id ati_remote2_id_table[] = {
};