--- /dev/null
+From 0ae43810976bc969ee158510c4acbe70ed136e61 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Fri, 11 Mar 2011 00:27:34 -0800
+Subject: HID: ACRUX - activate the device immediately after binding
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 0ae43810976bc969ee158510c4acbe70ed136e61 upstream.
+
+This device does not tolerate delayed opening and goes into a coma if
+we try to that. Ubuntu even has a crutch for udev that opened the device
+upon seeing it for the first time, but it did not work if we happened to
+boot with the device attached, since by the time userspace got around
+opening the device it was too late. Let's start the device immediately
+to deal with this issue.
+
+Reported-by: Sergei Kolzun <x0r@dv-life.ru>
+Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hid/Kconfig | 10 ++++++++--
+ drivers/hid/Makefile | 2 +-
+ drivers/hid/hid-axff.c | 31 ++++++++++++++++++++++++++++---
+ drivers/hid/hid-core.c | 2 --
+ 4 files changed, 37 insertions(+), 8 deletions(-)
+
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -68,9 +68,15 @@ config HID_A4TECH
+ ---help---
+ Support for A4 tech X5 and WOP-35 / Trust 450L mice.
+
+-config HID_ACRUX_FF
+- tristate "ACRUX force feedback"
++config HID_ACRUX
++ tristate "ACRUX game controller support"
+ depends on USB_HID
++ ---help---
++ Say Y here if you want to enable support for ACRUX game controllers.
++
++config HID_ACRUX_FF
++ tristate "ACRUX force feedback support"
++ depends on HID_ACRUX
+ select INPUT_FF_MEMLESS
+ ---help---
+ Say Y here if you want to enable force feedback support for ACRUX
+--- a/drivers/hid/Makefile
++++ b/drivers/hid/Makefile
+@@ -27,7 +27,7 @@ endif
+
+ obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o
+ obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
+-obj-$(CONFIG_HID_ACRUX_FF) += hid-axff.o
++obj-$(CONFIG_HID_ACRUX) += hid-axff.o
+ obj-$(CONFIG_HID_APPLE) += hid-apple.o
+ obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
+ obj-$(CONFIG_HID_CANDO) += hid-cando.o
+--- a/drivers/hid/hid-axff.c
++++ b/drivers/hid/hid-axff.c
+@@ -33,6 +33,8 @@
+ #include <linux/hid.h>
+
+ #include "hid-ids.h"
++
++#ifdef CONFIG_HID_ACRUX_FF
+ #include "usbhid/usbhid.h"
+
+ struct axff_device {
+@@ -109,6 +111,12 @@ err_free_mem:
+ kfree(axff);
+ return error;
+ }
++#else
++static inline int axff_init(struct hid_device *hid)
++{
++ return 0;
++}
++#endif
+
+ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ {
+@@ -139,9 +147,25 @@ static int ax_probe(struct hid_device *h
+ error);
+ }
+
++ /*
++ * We need to start polling device right away, otherwise
++ * it will go into a coma.
++ */
++ error = hid_hw_open(hdev);
++ if (error) {
++ dev_err(&hdev->dev, "hw open failed\n");
++ return error;
++ }
++
+ return 0;
+ }
+
++static void ax_remove(struct hid_device *hdev)
++{
++ hid_hw_close(hdev);
++ hid_hw_stop(hdev);
++}
++
+ static const struct hid_device_id ax_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802), },
+ { }
+@@ -149,9 +173,10 @@ static const struct hid_device_id ax_dev
+ MODULE_DEVICE_TABLE(hid, ax_devices);
+
+ static struct hid_driver ax_driver = {
+- .name = "acrux",
+- .id_table = ax_devices,
+- .probe = ax_probe,
++ .name = "acrux",
++ .id_table = ax_devices,
++ .probe = ax_probe,
++ .remove = ax_remove,
+ };
+
+ static int __init ax_init(void)
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1256,9 +1256,7 @@ static const struct hid_device_id hid_ha
+ { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
+-#if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE)
+ { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
+-#endif
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
--- /dev/null
+From f635bd11c8d332d917fb9a4cad3071b2357d5b2a Mon Sep 17 00:00:00 2001
+From: Henrik Rydberg <rydberg@euromail.se>
+Date: Thu, 24 Feb 2011 19:30:59 +0100
+Subject: HID: Do not create input devices for feature reports
+
+From: Henrik Rydberg <rydberg@euromail.se>
+
+commit f635bd11c8d332d917fb9a4cad3071b2357d5b2a upstream.
+
+When the multi input quirk is set, there is a new input device
+created for every feature report. Since the idea is to present
+features per hid device, not per input device, revert back to
+the original report loop and change the feature_mapping() callback
+to not take the input device as argument.
+
+Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
+Tested-by: Benjamin Tissoires <benjmain.tissoires@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hid/hid-input.c | 30 +++++++++++++++++++++---------
+ drivers/hid/hid-multitouch.c | 2 +-
+ include/linux/hid.h | 2 +-
+ 3 files changed, 23 insertions(+), 11 deletions(-)
+
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -290,14 +290,6 @@ static void hidinput_configure_usage(str
+ goto ignore;
+ }
+
+- if (field->report_type == HID_FEATURE_REPORT) {
+- if (device->driver->feature_mapping) {
+- device->driver->feature_mapping(device, hidinput, field,
+- usage);
+- }
+- goto ignore;
+- }
+-
+ if (device->driver->input_mapping) {
+ int ret = device->driver->input_mapping(device, hidinput, field,
+ usage, &bit, &max);
+@@ -835,6 +827,24 @@ static void hidinput_close(struct input_
+ hid_hw_close(hid);
+ }
+
++static void report_features(struct hid_device *hid)
++{
++ struct hid_driver *drv = hid->driver;
++ struct hid_report_enum *rep_enum;
++ struct hid_report *rep;
++ int i, j;
++
++ if (!drv->feature_mapping)
++ return;
++
++ rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
++ list_for_each_entry(rep, &rep_enum->report_list, list)
++ for (i = 0; i < rep->maxfield; i++)
++ for (j = 0; j < rep->field[i]->maxusage; j++)
++ drv->feature_mapping(hid, rep->field[i],
++ rep->field[i]->usage + j);
++}
++
+ /*
+ * Register the input device; print a message.
+ * Configure the input layer interface
+@@ -863,7 +873,9 @@ int hidinput_connect(struct hid_device *
+ return -1;
+ }
+
+- for (k = HID_INPUT_REPORT; k <= HID_FEATURE_REPORT; k++) {
++ report_features(hid);
++
++ for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
+ if (k == HID_OUTPUT_REPORT &&
+ hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
+ continue;
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -122,7 +122,7 @@ struct mt_class mt_classes[] = {
+ { }
+ };
+
+-static void mt_feature_mapping(struct hid_device *hdev, struct hid_input *hi,
++static void mt_feature_mapping(struct hid_device *hdev,
+ struct hid_field *field, struct hid_usage *usage)
+ {
+ if (usage->hid == HID_DG_INPUTMODE) {
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -638,7 +638,7 @@ struct hid_driver {
+ struct hid_input *hidinput, struct hid_field *field,
+ struct hid_usage *usage, unsigned long **bit, int *max);
+ void (*feature_mapping)(struct hid_device *hdev,
+- struct hid_input *hidinput, struct hid_field *field,
++ struct hid_field *field,
+ struct hid_usage *usage);
+ #ifdef CONFIG_PM
+ int (*suspend)(struct hid_device *hdev, pm_message_t message);