DORMANTno replies

[PATCH] HID: hid-sensor-hub: Fix kernel warning and failure

From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Date: 2013-12-05 19:58:14
Subsystem: hid core layer, hid sensor hub drivers, the rest · Maintainers: Jiri Kosina, Benjamin Tissoires, Jonathan Cameron, Srinivas Pandruvada, Linus Torvalds

Fix kernel warning and failure to register sensor hub devices with MFD.
Now many devices has in-built sensor hubs. So by default this HID hub,
is properly parsed and register individual sensors as platform device
using MFD framework. But if a second sensor hub is attached via USB,
which has same sensors, it will result in kernel warning and failure
to register MFD cell as the platform device sysfs file name will be
same as created by in-built sensor hubs. This patch uses MFD cell id
to genarate unique platform device name. In this way there will never
be duplicate sysfs file names.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 drivers/hid/hid-sensor-hub.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index a184e19..4cead68 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/mfd/core.h>
 #include <linux/list.h>
+#include <linux/idr.h>
 #include <linux/hid-sensor-ids.h>
 #include <linux/hid-sensor-hub.h>
 #include "hid-ids.h"
@@ -80,6 +81,8 @@ struct hid_sensor_hub_callbacks_list {
 	void *priv;
 };
 
+static DEFINE_IDR(hid_sensor_hub_idr);
+
 static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev,
 						int dir)
 {
@@ -512,6 +515,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
 	struct hid_report_enum *report_enum;
 	struct hid_field *field;
 	int dev_cnt;
+	int cell_id;
 
 	sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL);
 	if (!sd) {
@@ -565,6 +569,11 @@ static int sensor_hub_probe(struct hid_device *hdev,
 		field = report->field[0];
 		if (report->maxfield && field &&
 					field->physical) {
+			cell_id = idr_alloc(&hid_sensor_hub_idr,
+							NULL, 0, 0,
+							GFP_KERNEL);
+			if (cell_id < 0)
+					goto err_free_names;
 			name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x",
 						field->physical);
 			if (name == NULL) {
@@ -573,6 +582,8 @@ static int sensor_hub_probe(struct hid_device *hdev,
 					goto err_free_names;
 			}
 			sd->hid_sensor_hub_client_devs[
+				sd->hid_sensor_client_cnt].id = cell_id;
+			sd->hid_sensor_hub_client_devs[
 				sd->hid_sensor_client_cnt].name = name;
 			sd->hid_sensor_hub_client_devs[
 				sd->hid_sensor_client_cnt].platform_data =
@@ -592,8 +603,11 @@ static int sensor_hub_probe(struct hid_device *hdev,
 	return ret;
 
 err_free_names:
-	for (i = 0; i < sd->hid_sensor_client_cnt ; ++i)
+	for (i = 0; i < sd->hid_sensor_client_cnt; ++i) {
 		kfree(sd->hid_sensor_hub_client_devs[i].name);
+		idr_remove(&hid_sensor_hub_idr,
+			sd->hid_sensor_hub_client_devs[i].id);
+	}
 	kfree(sd->hid_sensor_hub_client_devs);
 err_stop_hw:
 	hid_hw_stop(hdev);
@@ -615,8 +629,11 @@ static void sensor_hub_remove(struct hid_device *hdev)
 		complete(&data->pending.ready);
 	spin_unlock_irqrestore(&data->lock, flags);
 	mfd_remove_devices(&hdev->dev);
-	for (i = 0; i < data->hid_sensor_client_cnt ; ++i)
+	for (i = 0; i < data->hid_sensor_client_cnt; ++i) {
 		kfree(data->hid_sensor_hub_client_devs[i].name);
+		idr_remove(&hid_sensor_hub_idr,
+			data->hid_sensor_hub_client_devs[i].id);
+	}
 	kfree(data->hid_sensor_hub_client_devs);
 	hid_set_drvdata(hdev, NULL);
 	mutex_destroy(&data->mutex);
-- 
1.8.1.2
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help