--- v3
+++ v2
@@ -1,71 +1,26 @@
-A hid device may create several input devices, and a driver may need
-to prepare or finalize the configuration per input device. Currently,
-there is no sane way for a driver to know when a device has been
-configured. This patch adds a callback providing that information.
+Going through the motions of printing the debug message information
+takes a long time; using the keyboard can lead to a 160 us irqsoff
+latency. This patch skips hid_dump_input() when there are no open
+handles, which brings latency down to 100 us.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
---
- drivers/hid/hid-input.c | 11 +++++++++--
- include/linux/hid.h | 3 +++
- 2 files changed, 12 insertions(+), 2 deletions(-)
+ drivers/hid/hid-core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
-diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
-index 811bfad..d917c0d 100644
---- a/drivers/hid/hid-input.c
-+++ b/drivers/hid/hid-input.c
-@@ -1154,6 +1154,7 @@ static void report_features(struct hid_device *hid)
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index 60ea284..5b74e78 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -996,7 +996,8 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field,
+ struct hid_driver *hdrv = hid->driver;
+ int ret;
- int hidinput_connect(struct hid_device *hid, unsigned int force)
- {
-+ struct hid_driver *drv = hid->driver;
- struct hid_report *report;
- struct hid_input *hidinput = NULL;
- struct input_dev *input_dev;
-@@ -1228,6 +1229,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
- * UGCI) cram a lot of unrelated inputs into the
- * same interface. */
- hidinput->report = report;
-+ if (drv->input_configured)
-+ drv->input_configured(hid, hidinput);
- if (input_register_device(hidinput->input))
- goto out_cleanup;
- hidinput = NULL;
-@@ -1235,8 +1238,12 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
- }
- }
+- hid_dump_input(hid, usage, value);
++ if (!list_empty(&hid->debug_list))
++ hid_dump_input(hid, usage, value);
-- if (hidinput && input_register_device(hidinput->input))
-- goto out_cleanup;
-+ if (hidinput) {
-+ if (drv->input_configured)
-+ drv->input_configured(hid, hidinput);
-+ if (input_register_device(hidinput->input))
-+ goto out_cleanup;
-+ }
-
- return 0;
-
-diff --git a/include/linux/hid.h b/include/linux/hid.h
-index 42970de..f37da28 100644
---- a/include/linux/hid.h
-+++ b/include/linux/hid.h
-@@ -626,6 +626,7 @@ struct hid_usage_id {
- * @report_fixup: called before report descriptor parsing (NULL means nop)
- * @input_mapping: invoked on input registering before mapping an usage
- * @input_mapped: invoked on input registering after mapping an usage
-+ * @input_configured: invoked just before the device is registered
- * @feature_mapping: invoked on feature registering
- * @suspend: invoked on suspend (NULL means nop)
- * @resume: invoked on resume if device was not reset (NULL means nop)
-@@ -670,6 +671,8 @@ struct hid_driver {
- int (*input_mapped)(struct hid_device *hdev,
- struct hid_input *hidinput, struct hid_field *field,
- struct hid_usage *usage, unsigned long **bit, int *max);
-+ void (*input_configured)(struct hid_device *hdev,
-+ struct hid_input *hidinput);
- void (*feature_mapping)(struct hid_device *hdev,
- struct hid_field *field,
- struct hid_usage *usage);
+ if (hdrv && hdrv->event && hid_match_usage(hid, usage)) {
+ ret = hdrv->event(hid, field, usage, value);
--
1.7.12
-