HID: add hidraw interface

hidraw is an interface that is going to obsolete hiddev one
day.

Many userland applications are using libusb instead of using
kernel-provided hiddev interface. This is caused by various
reasons - the HID parser in kernel doesn't handle all the
HID hardware on the planet properly, some devices might require
its own specific quirks/drivers, etc.

hiddev interface tries to do its best to parse all the received
reports properly, and presents only parsed usages into userspace.
This is however often not enough, and that's the reason why
many userland applications just don't use hiddev at all, and
rather use libusb to read raw USB events and process them on
their own.

Another drawback of hiddev is that it is USB-specific.

hidraw interface provides userspace readers with really raw HID
reports, no matter what the low-level transport layer is (USB/BT),
and gives the userland applications all the freedom to process
the HID reports in a way they wish to.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 317cf8a..2884b03 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -30,6 +30,7 @@
 #include <linux/hid.h>
 #include <linux/hiddev.h>
 #include <linux/hid-debug.h>
+#include <linux/hidraw.h>
 
 /*
  * Version Information
@@ -979,6 +980,8 @@
 
 	if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
 		hid->hiddev_report_event(hid, report);
+	if (hid->claimed & HID_CLAIMED_HIDRAW)
+		hidraw_report_event(hid, data, size);
 
 	for (n = 0; n < report->maxfield; n++)
 		hid_input_field(hid, report->field[n], data, interrupt);
@@ -990,5 +993,18 @@
 }
 EXPORT_SYMBOL_GPL(hid_input_report);
 
+static int __init hid_init(void)
+{
+	return hidraw_init();
+}
+
+static void __exit hid_exit(void)
+{
+	hidraw_exit();
+}
+
+module_init(hid_init);
+module_exit(hid_exit);
+
 MODULE_LICENSE(DRIVER_LICENSE);