Commit d43a338e authored by Linus Torvalds's avatar Linus Torvalds

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

* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input:
  Input: remove obsolete setup parameters from input drivers
  Input: HIL - fix improper call to release_region()
  Input: hid-lgff - treat devices as joysticks unless told otherwise
  Input: HID - add support for Logitech Formula Force EX
  Input: gpio-keys - switch to common GPIO API
  Input: do not lock device when showing name, phys and uniq
  Input: i8042 - let serio bus suspend ports
  Input: psmouse - properly reset mouse on shutdown/suspend
parents cb4aaf46 62b529a7
...@@ -588,18 +588,9 @@ static inline void input_proc_exit(void) { } ...@@ -588,18 +588,9 @@ static inline void input_proc_exit(void) { }
static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \ static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \
{ \ { \
struct input_dev *input_dev = to_input_dev(dev); \ struct input_dev *input_dev = to_input_dev(dev); \
int retval; \
\ \
retval = mutex_lock_interruptible(&input_dev->mutex); \ return scnprintf(buf, PAGE_SIZE, "%s\n", \
if (retval) \ input_dev->name ? input_dev->name : ""); \
return retval; \
\
retval = scnprintf(buf, PAGE_SIZE, \
"%s\n", input_dev->name ? input_dev->name : ""); \
\
mutex_unlock(&input_dev->mutex); \
\
return retval; \
} \ } \
static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL); static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
...@@ -1049,10 +1040,6 @@ void input_unregister_device(struct input_dev *dev) ...@@ -1049,10 +1040,6 @@ void input_unregister_device(struct input_dev *dev)
sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
mutex_lock(&dev->mutex);
dev->name = dev->phys = dev->uniq = NULL;
mutex_unlock(&dev->mutex);
class_device_unregister(&dev->cdev); class_device_unregister(&dev->cdev);
input_wakeup_procfs_readers(); input_wakeup_procfs_readers();
......
...@@ -50,8 +50,6 @@ static int amijoy[2] = { 0, 1 }; ...@@ -50,8 +50,6 @@ static int amijoy[2] = { 0, 1 };
module_param_array_named(map, amijoy, uint, NULL, 0); module_param_array_named(map, amijoy, uint, NULL, 0);
MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is 0,1)"); MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is 0,1)");
__obsolete_setup("amijoy=");
static int amijoy_used; static int amijoy_used;
static DEFINE_MUTEX(amijoy_mutex); static DEFINE_MUTEX(amijoy_mutex);
static struct input_dev *amijoy_dev[2]; static struct input_dev *amijoy_dev[2];
......
...@@ -58,8 +58,6 @@ static int analog_options[ANALOG_PORTS]; ...@@ -58,8 +58,6 @@ static int analog_options[ANALOG_PORTS];
module_param_array_named(map, js, charp, &js_nargs, 0); module_param_array_named(map, js, charp, &js_nargs, 0);
MODULE_PARM_DESC(map, "Describes analog joysticks type/capabilities"); MODULE_PARM_DESC(map, "Describes analog joysticks type/capabilities");
__obsolete_setup("js=");
/* /*
* Times, feature definitions. * Times, feature definitions.
*/ */
......
...@@ -59,10 +59,6 @@ MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)"); ...@@ -59,10 +59,6 @@ MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0); module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0);
MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)"); MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
__obsolete_setup("db9=");
__obsolete_setup("db9_2=");
__obsolete_setup("db9_3=");
#define DB9_ARG_PARPORT 0 #define DB9_ARG_PARPORT 0
#define DB9_ARG_MODE 1 #define DB9_ARG_MODE 1
......
...@@ -60,10 +60,6 @@ MODULE_PARM_DESC(map2, "Describes second set of devices"); ...@@ -60,10 +60,6 @@ MODULE_PARM_DESC(map2, "Describes second set of devices");
module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0); module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices"); MODULE_PARM_DESC(map3, "Describes third set of devices");
__obsolete_setup("gc=");
__obsolete_setup("gc_2=");
__obsolete_setup("gc_3=");
/* see also gs_psx_delay parameter in PSX support section */ /* see also gs_psx_delay parameter in PSX support section */
#define GC_SNES 1 #define GC_SNES 1
...@@ -403,8 +399,6 @@ static int gc_psx_delay = GC_PSX_DELAY; ...@@ -403,8 +399,6 @@ static int gc_psx_delay = GC_PSX_DELAY;
module_param_named(psx_delay, gc_psx_delay, uint, 0); module_param_named(psx_delay, gc_psx_delay, uint, 0);
MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)"); MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)");
__obsolete_setup("gc_psx_delay=");
static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y }; static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y };
static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y, static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y,
BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR }; BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR };
......
...@@ -60,10 +60,6 @@ MODULE_PARM_DESC(map2, "Describes second set of devices"); ...@@ -60,10 +60,6 @@ MODULE_PARM_DESC(map2, "Describes second set of devices");
module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0); module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices"); MODULE_PARM_DESC(map3, "Describes third set of devices");
__obsolete_setup("tgfx=");
__obsolete_setup("tgfx_2=");
__obsolete_setup("tgfx_3=");
#define TGFX_REFRESH_TIME HZ/100 /* 10 ms */ #define TGFX_REFRESH_TIME HZ/100 /* 10 ms */
#define TGFX_TRIGGER 0x08 #define TGFX_TRIGGER 0x08
......
...@@ -215,11 +215,11 @@ config KEYBOARD_AAED2000 ...@@ -215,11 +215,11 @@ config KEYBOARD_AAED2000
module will be called aaed2000_kbd. module will be called aaed2000_kbd.
config KEYBOARD_GPIO config KEYBOARD_GPIO
tristate "Buttons on CPU GPIOs (PXA)" tristate "Buttons on CPU GPIOs (PXA)"
depends on ARCH_PXA depends on (ARCH_SA1100 || ARCH_PXA || ARCH_S3C2410)
help help
This driver implements support for buttons connected This driver implements support for buttons connected
directly to GPIO pins of PXA CPUs. directly to GPIO pins of SA1100, PXA or S3C24xx CPUs.
Say Y here if your device has buttons connected Say Y here if your device has buttons connected
directly to GPIO pins of the CPU. directly to GPIO pins of the CPU.
......
...@@ -63,10 +63,6 @@ static int atkbd_extra; ...@@ -63,10 +63,6 @@ static int atkbd_extra;
module_param_named(extra, atkbd_extra, bool, 0); module_param_named(extra, atkbd_extra, bool, 0);
MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards");
__obsolete_setup("atkbd_set=");
__obsolete_setup("atkbd_reset");
__obsolete_setup("atkbd_softrepeat=");
/* /*
* Scancode to keycode tables. These are just the default setting, and * Scancode to keycode tables. These are just the default setting, and
* are loadable via an userland utility. * are loadable via an userland utility.
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <asm/arch/pxa-regs.h> #include <asm/gpio.h>
#include <asm/arch/hardware.h> #include <asm/arch/hardware.h>
#include <asm/hardware/gpio_keys.h> #include <asm/hardware/gpio_keys.h>
...@@ -38,8 +38,8 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) ...@@ -38,8 +38,8 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
for (i = 0; i < pdata->nbuttons; i++) { for (i = 0; i < pdata->nbuttons; i++) {
int gpio = pdata->buttons[i].gpio; int gpio = pdata->buttons[i].gpio;
if (irq == IRQ_GPIO(gpio)) { if (irq == gpio_to_irq(gpio)) {
int state = ((GPLR(gpio) & GPIO_bit(gpio)) ? 1 : 0) ^ (pdata->buttons[i].active_low); int state = (gpio_get_value(gpio) ? 1 : 0) ^ (pdata->buttons[i].active_low);
input_report_key(input, pdata->buttons[i].keycode, state); input_report_key(input, pdata->buttons[i].keycode, state);
input_sync(input); input_sync(input);
...@@ -75,14 +75,15 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) ...@@ -75,14 +75,15 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
for (i = 0; i < pdata->nbuttons; i++) { for (i = 0; i < pdata->nbuttons; i++) {
int code = pdata->buttons[i].keycode; int code = pdata->buttons[i].keycode;
int irq = IRQ_GPIO(pdata->buttons[i].gpio); int irq = gpio_to_irq(pdata->buttons[i].gpio);
set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM, error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM,
pdata->buttons[i].desc ? pdata->buttons[i].desc : "gpio_keys", pdata->buttons[i].desc ? pdata->buttons[i].desc : "gpio_keys",
pdev); pdev);
if (error) { if (error) {
printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", irq, ret); printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n",
irq, error);
goto fail; goto fail;
} }
set_bit(code, input->keybit); set_bit(code, input->keybit);
...@@ -98,7 +99,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) ...@@ -98,7 +99,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
fail: fail:
for (i = i - 1; i >= 0; i--) for (i = i - 1; i >= 0; i--)
free_irq(IRQ_GPIO(pdata->buttons[i].gpio), pdev); free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);
input_free_device(input); input_free_device(input);
...@@ -112,7 +113,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) ...@@ -112,7 +113,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
int i; int i;
for (i = 0; i < pdata->nbuttons; i++) { for (i = 0; i < pdata->nbuttons; i++) {
int irq = IRQ_GPIO(pdata->buttons[i].gpio); int irq = gpio_to_irq(pdata->buttons[i].gpio);
free_irq(irq, pdev); free_irq(irq, pdev);
} }
......
...@@ -294,8 +294,10 @@ hil_keyb_init(void) ...@@ -294,8 +294,10 @@ hil_keyb_init(void)
disable_irq(HIL_IRQ); disable_irq(HIL_IRQ);
free_irq(HIL_IRQ, hil_dev.dev_id); free_irq(HIL_IRQ, hil_dev.dev_id);
err2: err2:
#if defined(CONFIG_HP300)
release_region(HILBASE + HIL_DATA, 2); release_region(HILBASE + HIL_DATA, 2);
err1: err1:
#endif
input_free_device(hil_dev.dev); input_free_device(hil_dev.dev);
hil_dev.dev = NULL; hil_dev.dev = NULL;
return err; return err;
......
...@@ -84,8 +84,6 @@ static int inport_irq = INPORT_IRQ; ...@@ -84,8 +84,6 @@ static int inport_irq = INPORT_IRQ;
module_param_named(irq, inport_irq, uint, 0); module_param_named(irq, inport_irq, uint, 0);
MODULE_PARM_DESC(irq, "IRQ number (5=default)"); MODULE_PARM_DESC(irq, "IRQ number (5=default)");
__obsolete_setup("inport_irq=");
static struct input_dev *inport_dev; static struct input_dev *inport_dev;
static irqreturn_t inport_interrupt(int irq, void *dev_id) static irqreturn_t inport_interrupt(int irq, void *dev_id)
......
...@@ -75,8 +75,6 @@ static int logibm_irq = LOGIBM_IRQ; ...@@ -75,8 +75,6 @@ static int logibm_irq = LOGIBM_IRQ;
module_param_named(irq, logibm_irq, uint, 0); module_param_named(irq, logibm_irq, uint, 0);
MODULE_PARM_DESC(irq, "IRQ number (5=default)"); MODULE_PARM_DESC(irq, "IRQ number (5=default)");
__obsolete_setup("logibm_irq=");
static struct input_dev *logibm_dev; static struct input_dev *logibm_dev;
static irqreturn_t logibm_interrupt(int irq, void *dev_id) static irqreturn_t logibm_interrupt(int irq, void *dev_id)
......
...@@ -93,12 +93,6 @@ static struct attribute_group psmouse_attribute_group = { ...@@ -93,12 +93,6 @@ static struct attribute_group psmouse_attribute_group = {
.attrs = psmouse_attributes, .attrs = psmouse_attributes,
}; };
__obsolete_setup("psmouse_noext");
__obsolete_setup("psmouse_resolution=");
__obsolete_setup("psmouse_smartscroll=");
__obsolete_setup("psmouse_resetafter=");
__obsolete_setup("psmouse_rate=");
/* /*
* psmouse_mutex protects all operations changing state of mouse * psmouse_mutex protects all operations changing state of mouse
* (connecting, disconnecting, changing rate or resolution via * (connecting, disconnecting, changing rate or resolution via
...@@ -987,8 +981,36 @@ static void psmouse_resync(struct work_struct *work) ...@@ -987,8 +981,36 @@ static void psmouse_resync(struct work_struct *work)
static void psmouse_cleanup(struct serio *serio) static void psmouse_cleanup(struct serio *serio)
{ {
struct psmouse *psmouse = serio_get_drvdata(serio); struct psmouse *psmouse = serio_get_drvdata(serio);
struct psmouse *parent = NULL;
mutex_lock(&psmouse_mutex);
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
parent = serio_get_drvdata(serio->parent);
psmouse_deactivate(parent);
}
psmouse_deactivate(psmouse);
if (psmouse->cleanup)
psmouse->cleanup(psmouse);
psmouse_reset(psmouse); psmouse_reset(psmouse);
/*
* Some boxes, such as HP nx7400, get terribly confused if mouse
* is not fully enabled before suspending/shutting down.
*/
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
if (parent) {
if (parent->pt_deactivate)
parent->pt_deactivate(parent);
psmouse_activate(parent);
}
mutex_unlock(&psmouse_mutex);
} }
/* /*
......
...@@ -68,6 +68,7 @@ struct psmouse { ...@@ -68,6 +68,7 @@ struct psmouse {
int (*reconnect)(struct psmouse *psmouse); int (*reconnect)(struct psmouse *psmouse);
void (*disconnect)(struct psmouse *psmouse); void (*disconnect)(struct psmouse *psmouse);
void (*cleanup)(struct psmouse *psmouse);
int (*poll)(struct psmouse *psmouse); int (*poll)(struct psmouse *psmouse);
void (*pt_activate)(struct psmouse *psmouse); void (*pt_activate)(struct psmouse *psmouse);
......
...@@ -652,6 +652,7 @@ int synaptics_init(struct psmouse *psmouse) ...@@ -652,6 +652,7 @@ int synaptics_init(struct psmouse *psmouse)
psmouse->set_rate = synaptics_set_rate; psmouse->set_rate = synaptics_set_rate;
psmouse->disconnect = synaptics_disconnect; psmouse->disconnect = synaptics_disconnect;
psmouse->reconnect = synaptics_reconnect; psmouse->reconnect = synaptics_reconnect;
psmouse->cleanup = synaptics_reset;
psmouse->pktsize = 6; psmouse->pktsize = 6;
/* Synaptics can usually stay in sync without extra help */ /* Synaptics can usually stay in sync without extra help */
psmouse->resync_time = 0; psmouse->resync_time = 0;
......
...@@ -76,13 +76,6 @@ module_param_named(debug, i8042_debug, bool, 0600); ...@@ -76,13 +76,6 @@ module_param_named(debug, i8042_debug, bool, 0600);
MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off"); MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off");
#endif #endif
__obsolete_setup("i8042_noaux");
__obsolete_setup("i8042_nomux");
__obsolete_setup("i8042_unlock");
__obsolete_setup("i8042_reset");
__obsolete_setup("i8042_direct");
__obsolete_setup("i8042_dumbkbd");
#include "i8042.h" #include "i8042.h"
static DEFINE_SPINLOCK(i8042_lock); static DEFINE_SPINLOCK(i8042_lock);
...@@ -724,7 +717,7 @@ static int i8042_controller_init(void) ...@@ -724,7 +717,7 @@ static int i8042_controller_init(void)
if (~i8042_read_status() & I8042_STR_KEYLOCK) { if (~i8042_read_status() & I8042_STR_KEYLOCK) {
if (i8042_unlock) if (i8042_unlock)
i8042_ctr |= I8042_CTR_IGNKEYLOCK; i8042_ctr |= I8042_CTR_IGNKEYLOCK;
else else
printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n"); printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
} }
spin_unlock_irqrestore(&i8042_lock, flags); spin_unlock_irqrestore(&i8042_lock, flags);
...@@ -790,27 +783,6 @@ static void i8042_controller_reset(void) ...@@ -790,27 +783,6 @@ static void i8042_controller_reset(void)
} }
/*
* Here we try to reset everything back to a state in which the BIOS will be
* able to talk to the hardware when rebooting.
*/
static void i8042_controller_cleanup(void)
{
int i;
/*
* Reset anything that is connected to the ports.
*/
for (i = 0; i < I8042_NUM_PORTS; i++)
if (i8042_ports[i].serio)
serio_cleanup(i8042_ports[i].serio);
i8042_controller_reset();
}
/* /*
* i8042_panic_blink() will flash the keyboard LEDs and is called when * i8042_panic_blink() will flash the keyboard LEDs and is called when
* kernel panics. Flashing LEDs is useful for users running X who may * kernel panics. Flashing LEDs is useful for users running X who may
...@@ -857,13 +829,22 @@ static long i8042_panic_blink(long count) ...@@ -857,13 +829,22 @@ static long i8042_panic_blink(long count)
#undef DELAY #undef DELAY
#ifdef CONFIG_PM
/* /*
* Here we try to restore the original BIOS settings * Here we try to restore the original BIOS settings. We only want to
* do that once, when we really suspend, not when we taking memory
* snapshot for swsusp (in this case we'll perform required cleanup
* as part of shutdown process).
*/ */
static int i8042_suspend(struct platform_device *dev, pm_message_t state) static int i8042_suspend(struct platform_device *dev, pm_message_t state)
{ {
i8042_controller_cleanup(); if (dev->dev.power.power_state.event != state.event) {
if (state.event == PM_EVENT_SUSPEND)
i8042_controller_reset();
dev->dev.power.power_state = state;
}
return 0; return 0;
} }
...@@ -877,6 +858,12 @@ static int i8042_resume(struct platform_device *dev) ...@@ -877,6 +858,12 @@ static int i8042_resume(struct platform_device *dev)
{ {
int error; int error;
/*
* Do not bother with restoring state if we haven't suspened yet
*/
if (dev->dev.power.power_state.event == PM_EVENT_ON)
return 0;
error = i8042_controller_check(); error = i8042_controller_check();
if (error) if (error)
return error; return error;
...@@ -886,9 +873,12 @@ static int i8042_resume(struct platform_device *dev) ...@@ -886,9 +873,12 @@ static int i8042_resume(struct platform_device *dev)
return error; return error;
/* /*
* Restore pre-resume CTR value and disable all ports * Restore original CTR value and disable all ports
*/ */
i8042_ctr = i8042_initial_ctr;
if (i8042_direct)
i8042_ctr &= ~I8042_CTR_XLATE;
i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS; i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS;
i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT); i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT);
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
...@@ -909,8 +899,11 @@ static int i8042_resume(struct platform_device *dev) ...@@ -909,8 +899,11 @@ static int i8042_resume(struct platform_device *dev)
i8042_interrupt(0, NULL); i8042_interrupt(0, NULL);
dev->dev.power.power_state = PMSG_ON;
return 0; return 0;
} }
#endif /* CONFIG_PM */
/* /*
* We need to reset the 8042 back to original mode on system shutdown, * We need to reset the 8042 back to original mode on system shutdown,
...@@ -919,7 +912,7 @@ static int i8042_resume(struct platform_device *dev) ...@@ -919,7 +912,7 @@ static int i8042_resume(struct platform_device *dev)
static void i8042_shutdown(struct platform_device *dev) static void i8042_shutdown(struct platform_device *dev)
{ {
i8042_controller_cleanup(); i8042_controller_reset();
} }
static int __devinit i8042_create_kbd_port(void) static int __devinit i8042_create_kbd_port(void)
...@@ -1154,9 +1147,11 @@ static struct platform_driver i8042_driver = { ...@@ -1154,9 +1147,11 @@ static struct platform_driver i8042_driver = {
}, },
.probe = i8042_probe, .probe = i8042_probe,
.remove = __devexit_p(i8042_remove), .remove = __devexit_p(i8042_remove),
.shutdown = i8042_shutdown,
#ifdef CONFIG_PM
.suspend = i8042_suspend, .suspend = i8042_suspend,
.resume = i8042_resume, .resume = i8042_resume,
.shutdown = i8042_shutdown, #endif
}; };
static int __init i8042_init(void) static int __init i8042_init(void)
......
...@@ -778,6 +778,19 @@ static int serio_driver_remove(struct device *dev) ...@@ -778,6 +778,19 @@ static int serio_driver_remove(struct device *dev)
return 0; return 0;
} }
static void serio_cleanup(struct serio *serio)
{
if (serio->drv && serio->drv->cleanup)
serio->drv->cleanup(serio);
}
static void serio_shutdown(struct device *dev)
{
struct serio *serio = to_serio_port(dev);
serio_cleanup(serio);
}
static void serio_attach_driver(struct serio_driver *drv) static void serio_attach_driver(struct serio_driver *drv)
{ {
int error; int error;
...@@ -910,11 +923,25 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf ...@@ -910,11 +923,25 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf
#endif /* CONFIG_HOTPLUG */ #endif /* CONFIG_HOTPLUG */
#ifdef CONFIG_PM
static int serio_suspend(struct device *dev, pm_message_t state)
{
if (dev->power.power_state.event != state.event) {
if (state.event == PM_EVENT_SUSPEND)
serio_cleanup(to_serio_port(dev));
dev->power.power_state = state;
}
return 0;
}
static int serio_resume(struct device *dev) static int serio_resume(struct device *dev)
{ {
struct serio *serio = to_serio_port(dev); struct serio *serio = to_serio_port(dev);
if (serio_reconnect_driver(serio)) { if (dev->power.power_state.event != PM_EVENT_ON &&
serio_reconnect_driver(serio)) {
/* /*
* Driver re-probing can take a while, so better let kseriod * Driver re-probing can take a while, so better let kseriod
* deal with it. * deal with it.
...@@ -922,8 +949,11 @@ static int serio_resume(struct device *dev) ...@@ -922,8 +949,11 @@ static int serio_resume(struct device *dev)
serio_rescan(serio); serio_rescan(serio);
} }
dev->power.power_state = PMSG_ON;
return 0; return 0;
} }
#endif /* CONFIG_PM */
/* called from serio_driver->connect/disconnect methods under serio_mutex */ /* called from serio_driver->connect/disconnect methods under serio_mutex */
int serio_open(struct serio *serio, struct serio_driver *drv) int serio_open(struct serio *serio, struct serio_driver *drv)
...@@ -974,7 +1004,11 @@ static struct bus_type serio_bus = { ...@@ -974,7 +1004,11 @@ static struct bus_type serio_bus = {
.uevent = serio_uevent, .uevent = serio_uevent,
.probe = serio_driver_probe, .probe = serio_driver_probe,
.remove = serio_driver_remove, .remove = serio_driver_remove,
.shutdown = serio_shutdown,
#ifdef CONFIG_PM
.suspend = serio_suspend,
.resume = serio_resume, .resume = serio_resume,
#endif
}; };
static int __init serio_init(void) static int __init serio_init(void)
......
...@@ -58,13 +58,17 @@ config HID_PID ...@@ -58,13 +58,17 @@ config HID_PID
devices. devices.
config LOGITECH_FF config LOGITECH_FF
bool "Logitech WingMan *3D support" bool "Logitech devices support"
depends on HID_FF depends on HID_FF
select INPUT_FF_MEMLESS if USB_HID select INPUT_FF_MEMLESS if USB_HID
help help
Say Y here if you have one of these devices: Say Y here if you have one of these devices:
- Logitech WingMan Cordless RumblePad - Logitech WingMan Cordless RumblePad
- Logitech WingMan Cordless RumblePad 2
- Logitech WingMan Force 3D - Logitech WingMan Force 3D
- Logitech Formula Force EX
- Logitech MOMO Force wheel
and if you want to enable force feedback for them. and if you want to enable force feedback for them.
Note: if you say N here, this device will still be supported, but without Note: if you say N here, this device will still be supported, but without
force feedback. force feedback.
......
...@@ -54,9 +54,10 @@ struct hid_ff_initializer { ...@@ -54,9 +54,10 @@ struct hid_ff_initializer {
static struct hid_ff_initializer inits[] = { static struct hid_ff_initializer inits[] = {
#ifdef CONFIG_LOGITECH_FF #ifdef CONFIG_LOGITECH_FF
{ 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */ { 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */
{ 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
{ 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */ { 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
{ 0x46d, 0xc294, hid_lgff_init }, /* Logitech Formula Force EX */
{ 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */ { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
{ 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
{ 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */ { 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */
#endif #endif
#ifdef CONFIG_PANTHERLORD_FF #ifdef CONFIG_PANTHERLORD_FF
......
...@@ -52,8 +52,9 @@ static const struct dev_type devices[] = { ...@@ -52,8 +52,9 @@ static const struct dev_type devices[] = {
{ 0x046d, 0xc211, ff_rumble }, { 0x046d, 0xc211, ff_rumble },
{ 0x046d, 0xc219, ff_rumble }, { 0x046d, 0xc219, ff_rumble },
{ 0x046d, 0xc283, ff_joystick }, { 0x046d, 0xc283, ff_joystick },
{ 0x046d, 0xc294, ff_joystick },
{ 0x046d, 0xc295, ff_joystick },
{ 0x046d, 0xca03, ff_joystick }, { 0x046d, 0xca03, ff_joystick },
{ 0x0000, 0x0000, ff_joystick }
}; };
static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect) static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
...@@ -105,8 +106,9 @@ int hid_lgff_init(struct hid_device* hid) ...@@ -105,8 +106,9 @@ int hid_lgff_init(struct hid_device* hid)
struct input_dev *dev = hidinput->input; struct input_dev *dev = hidinput->input;
struct hid_report *report; struct hid_report *report;
struct hid_field *field; struct hid_field *field;
const signed short *ff_bits = ff_joystick;
int error; int error;
int i, j; int i;
/* Find the report to use */ /* Find the report to use */
if (list_empty(report_list)) { if (list_empty(report_list)) {
...@@ -130,12 +132,14 @@ int hid_lgff_init(struct hid_device* hid) ...@@ -130,12 +132,14 @@ int hid_lgff_init(struct hid_device* hid)
for (i = 0; i < ARRAY_SIZE(devices); i++) { for (i = 0; i < ARRAY_SIZE(devices); i++) {
if (dev->id.vendor == devices[i].idVendor && if (dev->id.vendor == devices[i].idVendor &&
dev->id.product == devices[i].idProduct) { dev->id.product == devices[i].idProduct) {
for (j = 0; devices[i].ff[j] >= 0; j++) ff_bits = devices[i].ff;
set_bit(devices[i].ff[j], dev->ffbit);
break; break;
} }
} }
for (i = 0; ff_bits[i] >= 0; i++)
set_bit(ff_bits[i], dev->ffbit);
error = input_ff_create_memless(dev, NULL, hid_lgff_play); error = input_ff_create_memless(dev, NULL, hid_lgff_play);
if (error) if (error)
return error; return error;
......
...@@ -108,12 +108,6 @@ static inline void serio_drv_write_wakeup(struct serio *serio) ...@@ -108,12 +108,6 @@ static inline void serio_drv_write_wakeup(struct serio *serio)
serio->drv->write_wakeup(serio); serio->drv->write_wakeup(serio);
} }
static inline void serio_cleanup(struct serio *serio)
{
if (serio->drv && serio->drv->cleanup)
serio->drv->cleanup(serio);
}
/* /*
* Use the following functions to manipulate serio's per-port * Use the following functions to manipulate serio's per-port
* driver-specific data. * driver-specific data.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment