aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-sensor-hub.c
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2014-01-31 15:04:10 -0500
committerJiri Kosina <jkosina@suse.cz>2014-02-17 11:12:47 -0500
commitca2ed12f163bf430a425ec725ef76df5254b9f45 (patch)
tree06fbeca9113d06fccb6bebad133e460facacee38 /drivers/hid/hid-sensor-hub.c
parent1a214ae5d1a66ead18c5e8c3a8d03b969b0ee647 (diff)
HID: hid-sensor-hub: Processing for duplicate physical ids
In HID sensor hub, HID physical ids are used to represent different sensors. For example physical id of 0x73 in usage page = 0x20, represents an accelerometer. The HID sensor hub driver uses this physical ids to create platform devices using MFD. There is 1:1 correspondence between an phy id and a client driver. But in some cases these physical ids are reused. There is a phy id 0xe1, which specifies a custom sensor, which can exist multiple times to represent various custom sensors. In this case there can be multiple instances of client MFD drivers, processing specific custom sensor. In this case when client driver looks for report id or a field index, it should still get the report id specific to its own type. This is also true for reports, they should be directed towards correct instance. This change introduce a way to parse and tie physical devices to their correct instance. Summary of changes: - To get physical ids, use collections. If a collection of type=physical exist then use usage id as in the name of platform device name - As part of the platform data, we assign a hdsev instance, which has start and end of collection indexes. Using these indexes attributes can be tied to correct MFD client instances - When a report is received, call callback with correct hsdev instance. In this way using its private data stored as part of its registry, it can distinguish different sensors even when they have same physical and logical ids. This patch is co-authored with Archana Patni <archna.patni@intel.com>. Reported-by: Archana Patni <archana.patni@intel.com> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Archana Patni <archana.patni@intel.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-sensor-hub.c')
-rw-r--r--drivers/hid/hid-sensor-hub.c188
1 files changed, 102 insertions, 86 deletions
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index ad2b8692ad77..5ab93cb18b88 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -56,9 +56,9 @@ struct sensor_hub_pending {
56 * @dyn_callback_lock: spin lock to protect callback list 56 * @dyn_callback_lock: spin lock to protect callback list
57 * @hid_sensor_hub_client_devs: Stores all MFD cells for a hub instance. 57 * @hid_sensor_hub_client_devs: Stores all MFD cells for a hub instance.
58 * @hid_sensor_client_cnt: Number of MFD cells, (no of sensors attached). 58 * @hid_sensor_client_cnt: Number of MFD cells, (no of sensors attached).
59 * @ref_cnt: Number of MFD clients have opened this device
59 */ 60 */
60struct sensor_hub_data { 61struct sensor_hub_data {
61 struct hid_sensor_hub_device *hsdev;
62 struct mutex mutex; 62 struct mutex mutex;
63 spinlock_t lock; 63 spinlock_t lock;
64 struct sensor_hub_pending pending; 64 struct sensor_hub_pending pending;
@@ -67,6 +67,7 @@ struct sensor_hub_data {
67 struct mfd_cell *hid_sensor_hub_client_devs; 67 struct mfd_cell *hid_sensor_hub_client_devs;
68 int hid_sensor_client_cnt; 68 int hid_sensor_client_cnt;
69 unsigned long quirks; 69 unsigned long quirks;
70 int ref_cnt;
70}; 71};
71 72
72/** 73/**
@@ -79,6 +80,7 @@ struct sensor_hub_data {
79struct hid_sensor_hub_callbacks_list { 80struct hid_sensor_hub_callbacks_list {
80 struct list_head list; 81 struct list_head list;
81 u32 usage_id; 82 u32 usage_id;
83 struct hid_sensor_hub_device *hsdev;
82 struct hid_sensor_hub_callbacks *usage_callback; 84 struct hid_sensor_hub_callbacks *usage_callback;
83 void *priv; 85 void *priv;
84}; 86};
@@ -97,20 +99,18 @@ static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev,
97 return NULL; 99 return NULL;
98} 100}
99 101
100static int sensor_hub_get_physical_device_count( 102static int sensor_hub_get_physical_device_count(struct hid_device *hdev)
101 struct hid_report_enum *report_enum)
102{ 103{
103 struct hid_report *report; 104 int i;
104 struct hid_field *field; 105 int count = 0;
105 int cnt = 0;
106 106
107 list_for_each_entry(report, &report_enum->report_list, list) { 107 for (i = 0; i < hdev->maxcollection; ++i) {
108 field = report->field[0]; 108 struct hid_collection *collection = &hdev->collection[i];
109 if (report->maxfield && field && field->physical) 109 if (collection->type == HID_COLLECTION_PHYSICAL)
110 cnt++; 110 ++count;
111 } 111 }
112 112
113 return cnt; 113 return count;
114} 114}
115 115
116static void sensor_hub_fill_attr_info( 116static void sensor_hub_fill_attr_info(
@@ -128,15 +128,23 @@ static void sensor_hub_fill_attr_info(
128 128
129static struct hid_sensor_hub_callbacks *sensor_hub_get_callback( 129static struct hid_sensor_hub_callbacks *sensor_hub_get_callback(
130 struct hid_device *hdev, 130 struct hid_device *hdev,
131 u32 usage_id, void **priv) 131 u32 usage_id,
132 int collection_index,
133 struct hid_sensor_hub_device **hsdev,
134 void **priv)
132{ 135{
133 struct hid_sensor_hub_callbacks_list *callback; 136 struct hid_sensor_hub_callbacks_list *callback;
134 struct sensor_hub_data *pdata = hid_get_drvdata(hdev); 137 struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
135 138
136 spin_lock(&pdata->dyn_callback_lock); 139 spin_lock(&pdata->dyn_callback_lock);
137 list_for_each_entry(callback, &pdata->dyn_callback_list, list) 140 list_for_each_entry(callback, &pdata->dyn_callback_list, list)
138 if (callback->usage_id == usage_id) { 141 if (callback->usage_id == usage_id &&
142 (collection_index >=
143 callback->hsdev->start_collection_index) &&
144 (collection_index <
145 callback->hsdev->end_collection_index)) {
139 *priv = callback->priv; 146 *priv = callback->priv;
147 *hsdev = callback->hsdev;
140 spin_unlock(&pdata->dyn_callback_lock); 148 spin_unlock(&pdata->dyn_callback_lock);
141 return callback->usage_callback; 149 return callback->usage_callback;
142 } 150 }
@@ -154,7 +162,8 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
154 162
155 spin_lock(&pdata->dyn_callback_lock); 163 spin_lock(&pdata->dyn_callback_lock);
156 list_for_each_entry(callback, &pdata->dyn_callback_list, list) 164 list_for_each_entry(callback, &pdata->dyn_callback_list, list)
157 if (callback->usage_id == usage_id) { 165 if (callback->usage_id == usage_id &&
166 callback->hsdev == hsdev) {
158 spin_unlock(&pdata->dyn_callback_lock); 167 spin_unlock(&pdata->dyn_callback_lock);
159 return -EINVAL; 168 return -EINVAL;
160 } 169 }
@@ -163,6 +172,7 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
163 spin_unlock(&pdata->dyn_callback_lock); 172 spin_unlock(&pdata->dyn_callback_lock);
164 return -ENOMEM; 173 return -ENOMEM;
165 } 174 }
175 callback->hsdev = hsdev;
166 callback->usage_callback = usage_callback; 176 callback->usage_callback = usage_callback;
167 callback->usage_id = usage_id; 177 callback->usage_id = usage_id;
168 callback->priv = NULL; 178 callback->priv = NULL;
@@ -181,7 +191,8 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
181 191
182 spin_lock(&pdata->dyn_callback_lock); 192 spin_lock(&pdata->dyn_callback_lock);
183 list_for_each_entry(callback, &pdata->dyn_callback_list, list) 193 list_for_each_entry(callback, &pdata->dyn_callback_list, list)
184 if (callback->usage_id == usage_id) { 194 if (callback->usage_id == usage_id &&
195 callback->hsdev == hsdev) {
185 list_del(&callback->list); 196 list_del(&callback->list);
186 kfree(callback); 197 kfree(callback);
187 break; 198 break;
@@ -320,8 +331,7 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
320 struct hid_sensor_hub_attribute_info *info) 331 struct hid_sensor_hub_attribute_info *info)
321{ 332{
322 int ret = -1; 333 int ret = -1;
323 int i, j; 334 int i;
324 int collection_index = -1;
325 struct hid_report *report; 335 struct hid_report *report;
326 struct hid_field *field; 336 struct hid_field *field;
327 struct hid_report_enum *report_enum; 337 struct hid_report_enum *report_enum;
@@ -335,44 +345,31 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
335 info->units = -1; 345 info->units = -1;
336 info->unit_expo = -1; 346 info->unit_expo = -1;
337 347
338 for (i = 0; i < hdev->maxcollection; ++i) {
339 struct hid_collection *collection = &hdev->collection[i];
340 if (usage_id == collection->usage) {
341 collection_index = i;
342 break;
343 }
344 }
345 if (collection_index == -1)
346 goto err_ret;
347
348 report_enum = &hdev->report_enum[type]; 348 report_enum = &hdev->report_enum[type];
349 list_for_each_entry(report, &report_enum->report_list, list) { 349 list_for_each_entry(report, &report_enum->report_list, list) {
350 for (i = 0; i < report->maxfield; ++i) { 350 for (i = 0; i < report->maxfield; ++i) {
351 field = report->field[i]; 351 field = report->field[i];
352 if (field->physical == usage_id && 352 if (field->maxusage) {
353 field->logical == attr_usage_id) { 353 if (field->physical == usage_id &&
354 sensor_hub_fill_attr_info(info, i, report->id, 354 (field->logical == attr_usage_id ||
355 field); 355 field->usage[0].hid ==
356 ret = 0; 356 attr_usage_id) &&
357 } else { 357 (field->usage[0].collection_index >=
358 for (j = 0; j < field->maxusage; ++j) { 358 hsdev->start_collection_index) &&
359 if (field->usage[j].hid == 359 (field->usage[0].collection_index <
360 attr_usage_id && 360 hsdev->end_collection_index)) {
361 field->usage[j].collection_index == 361
362 collection_index) { 362 sensor_hub_fill_attr_info(info, i,
363 sensor_hub_fill_attr_info(info, 363 report->id,
364 i, report->id, field); 364 field);
365 ret = 0; 365 ret = 0;
366 break; 366 break;
367 }
368 } 367 }
369 } 368 }
370 if (ret == 0)
371 break;
372 } 369 }
370
373 } 371 }
374 372
375err_ret:
376 return ret; 373 return ret;
377} 374}
378EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info); 375EXPORT_SYMBOL_GPL(sensor_hub_input_get_attribute_info);
@@ -388,7 +385,7 @@ static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)
388 list_for_each_entry(callback, &pdata->dyn_callback_list, list) { 385 list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
389 if (callback->usage_callback->suspend) 386 if (callback->usage_callback->suspend)
390 callback->usage_callback->suspend( 387 callback->usage_callback->suspend(
391 pdata->hsdev, callback->priv); 388 callback->hsdev, callback->priv);
392 } 389 }
393 spin_unlock(&pdata->dyn_callback_lock); 390 spin_unlock(&pdata->dyn_callback_lock);
394 391
@@ -405,7 +402,7 @@ static int sensor_hub_resume(struct hid_device *hdev)
405 list_for_each_entry(callback, &pdata->dyn_callback_list, list) { 402 list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
406 if (callback->usage_callback->resume) 403 if (callback->usage_callback->resume)
407 callback->usage_callback->resume( 404 callback->usage_callback->resume(
408 pdata->hsdev, callback->priv); 405 callback->hsdev, callback->priv);
409 } 406 }
410 spin_unlock(&pdata->dyn_callback_lock); 407 spin_unlock(&pdata->dyn_callback_lock);
411 408
@@ -432,6 +429,7 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
432 struct hid_sensor_hub_callbacks *callback = NULL; 429 struct hid_sensor_hub_callbacks *callback = NULL;
433 struct hid_collection *collection = NULL; 430 struct hid_collection *collection = NULL;
434 void *priv = NULL; 431 void *priv = NULL;
432 struct hid_sensor_hub_device *hsdev = NULL;
435 433
436 hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n", 434 hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n",
437 report->id, size, report->type); 435 report->id, size, report->type);
@@ -466,23 +464,26 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
466 report->field[i]->usage->collection_index]; 464 report->field[i]->usage->collection_index];
467 hid_dbg(hdev, "collection->usage %x\n", 465 hid_dbg(hdev, "collection->usage %x\n",
468 collection->usage); 466 collection->usage);
469 callback = sensor_hub_get_callback(pdata->hsdev->hdev, 467
470 report->field[i]->physical, 468 callback = sensor_hub_get_callback(hdev,
471 &priv); 469 report->field[i]->physical,
470 report->field[i]->usage[0].collection_index,
471 &hsdev, &priv);
472
472 if (callback && callback->capture_sample) { 473 if (callback && callback->capture_sample) {
473 if (report->field[i]->logical) 474 if (report->field[i]->logical)
474 callback->capture_sample(pdata->hsdev, 475 callback->capture_sample(hsdev,
475 report->field[i]->logical, sz, ptr, 476 report->field[i]->logical, sz, ptr,
476 callback->pdev); 477 callback->pdev);
477 else 478 else
478 callback->capture_sample(pdata->hsdev, 479 callback->capture_sample(hsdev,
479 report->field[i]->usage->hid, sz, ptr, 480 report->field[i]->usage->hid, sz, ptr,
480 callback->pdev); 481 callback->pdev);
481 } 482 }
482 ptr += sz; 483 ptr += sz;
483 } 484 }
484 if (callback && collection && callback->send_event) 485 if (callback && collection && callback->send_event)
485 callback->send_event(pdata->hsdev, collection->usage, 486 callback->send_event(hsdev, collection->usage,
486 callback->pdev); 487 callback->pdev);
487 spin_unlock_irqrestore(&pdata->lock, flags); 488 spin_unlock_irqrestore(&pdata->lock, flags);
488 489
@@ -495,7 +496,7 @@ int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev)
495 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); 496 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
496 497
497 mutex_lock(&data->mutex); 498 mutex_lock(&data->mutex);
498 if (!hsdev->ref_cnt) { 499 if (!data->ref_cnt) {
499 ret = hid_hw_open(hsdev->hdev); 500 ret = hid_hw_open(hsdev->hdev);
500 if (ret) { 501 if (ret) {
501 hid_err(hsdev->hdev, "failed to open hid device\n"); 502 hid_err(hsdev->hdev, "failed to open hid device\n");
@@ -503,7 +504,7 @@ int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev)
503 return ret; 504 return ret;
504 } 505 }
505 } 506 }
506 hsdev->ref_cnt++; 507 data->ref_cnt++;
507 mutex_unlock(&data->mutex); 508 mutex_unlock(&data->mutex);
508 509
509 return ret; 510 return ret;
@@ -515,8 +516,8 @@ void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev)
515 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); 516 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
516 517
517 mutex_lock(&data->mutex); 518 mutex_lock(&data->mutex);
518 hsdev->ref_cnt--; 519 data->ref_cnt--;
519 if (!hsdev->ref_cnt) 520 if (!data->ref_cnt)
520 hid_hw_close(hsdev->hdev); 521 hid_hw_close(hsdev->hdev);
521 mutex_unlock(&data->mutex); 522 mutex_unlock(&data->mutex);
522} 523}
@@ -563,26 +564,19 @@ static int sensor_hub_probe(struct hid_device *hdev,
563 struct sensor_hub_data *sd; 564 struct sensor_hub_data *sd;
564 int i; 565 int i;
565 char *name; 566 char *name;
566 struct hid_report *report;
567 struct hid_report_enum *report_enum;
568 struct hid_field *field;
569 int dev_cnt; 567 int dev_cnt;
568 struct hid_sensor_hub_device *hsdev;
569 struct hid_sensor_hub_device *last_hsdev = NULL;
570 570
571 sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL); 571 sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL);
572 if (!sd) { 572 if (!sd) {
573 hid_err(hdev, "cannot allocate Sensor data\n"); 573 hid_err(hdev, "cannot allocate Sensor data\n");
574 return -ENOMEM; 574 return -ENOMEM;
575 } 575 }
576 sd->hsdev = devm_kzalloc(&hdev->dev, sizeof(*sd->hsdev), GFP_KERNEL); 576
577 if (!sd->hsdev) {
578 hid_err(hdev, "cannot allocate hid_sensor_hub_device\n");
579 return -ENOMEM;
580 }
581 hid_set_drvdata(hdev, sd); 577 hid_set_drvdata(hdev, sd);
582 sd->quirks = id->driver_data; 578 sd->quirks = id->driver_data;
583 sd->hsdev->hdev = hdev; 579
584 sd->hsdev->vendor_id = hdev->vendor;
585 sd->hsdev->product_id = hdev->product;
586 spin_lock_init(&sd->lock); 580 spin_lock_init(&sd->lock);
587 spin_lock_init(&sd->dyn_callback_lock); 581 spin_lock_init(&sd->dyn_callback_lock);
588 mutex_init(&sd->mutex); 582 mutex_init(&sd->mutex);
@@ -600,9 +594,8 @@ static int sensor_hub_probe(struct hid_device *hdev,
600 } 594 }
601 INIT_LIST_HEAD(&sd->dyn_callback_list); 595 INIT_LIST_HEAD(&sd->dyn_callback_list);
602 sd->hid_sensor_client_cnt = 0; 596 sd->hid_sensor_client_cnt = 0;
603 report_enum = &hdev->report_enum[HID_INPUT_REPORT];
604 597
605 dev_cnt = sensor_hub_get_physical_device_count(report_enum); 598 dev_cnt = sensor_hub_get_physical_device_count(hdev);
606 if (dev_cnt > HID_MAX_PHY_DEVICES) { 599 if (dev_cnt > HID_MAX_PHY_DEVICES) {
607 hid_err(hdev, "Invalid Physical device count\n"); 600 hid_err(hdev, "Invalid Physical device count\n");
608 ret = -EINVAL; 601 ret = -EINVAL;
@@ -616,42 +609,63 @@ static int sensor_hub_probe(struct hid_device *hdev,
616 ret = -ENOMEM; 609 ret = -ENOMEM;
617 goto err_stop_hw; 610 goto err_stop_hw;
618 } 611 }
619 list_for_each_entry(report, &report_enum->report_list, list) { 612
620 hid_dbg(hdev, "Report id:%x\n", report->id); 613 for (i = 0; i < hdev->maxcollection; ++i) {
621 field = report->field[0]; 614 struct hid_collection *collection = &hdev->collection[i];
622 if (report->maxfield && field && 615
623 field->physical) { 616 if (collection->type == HID_COLLECTION_PHYSICAL) {
617
618 hsdev = kzalloc(sizeof(*hsdev), GFP_KERNEL);
619 if (!hsdev) {
620 hid_err(hdev, "cannot allocate hid_sensor_hub_device\n");
621 ret = -ENOMEM;
622 goto err_no_mem;
623 }
624 hsdev->hdev = hdev;
625 hsdev->vendor_id = hdev->vendor;
626 hsdev->product_id = hdev->product;
627 hsdev->start_collection_index = i;
628 if (last_hsdev)
629 last_hsdev->end_collection_index = i;
630 last_hsdev = hsdev;
624 name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x", 631 name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x",
625 field->physical); 632 collection->usage);
626 if (name == NULL) { 633 if (name == NULL) {
627 hid_err(hdev, "Failed MFD device name\n"); 634 hid_err(hdev, "Failed MFD device name\n");
628 ret = -ENOMEM; 635 ret = -ENOMEM;
629 goto err_free_names; 636 goto err_no_mem;
630 } 637 }
631 sd->hid_sensor_hub_client_devs[ 638 sd->hid_sensor_hub_client_devs[
632 sd->hid_sensor_client_cnt].id = PLATFORM_DEVID_AUTO; 639 sd->hid_sensor_client_cnt].id =
640 PLATFORM_DEVID_AUTO;
633 sd->hid_sensor_hub_client_devs[ 641 sd->hid_sensor_hub_client_devs[
634 sd->hid_sensor_client_cnt].name = name; 642 sd->hid_sensor_client_cnt].name = name;
635 sd->hid_sensor_hub_client_devs[ 643 sd->hid_sensor_hub_client_devs[
636 sd->hid_sensor_client_cnt].platform_data = 644 sd->hid_sensor_client_cnt].platform_data =
637 sd->hsdev; 645 hsdev;
638 sd->hid_sensor_hub_client_devs[ 646 sd->hid_sensor_hub_client_devs[
639 sd->hid_sensor_client_cnt].pdata_size = 647 sd->hid_sensor_client_cnt].pdata_size =
640 sizeof(*sd->hsdev); 648 sizeof(*hsdev);
641 hid_dbg(hdev, "Adding %s:%p\n", name, sd); 649 hid_dbg(hdev, "Adding %s:%d\n", name,
650 hsdev->start_collection_index);
642 sd->hid_sensor_client_cnt++; 651 sd->hid_sensor_client_cnt++;
643 } 652 }
644 } 653 }
654 if (last_hsdev)
655 last_hsdev->end_collection_index = i;
656
645 ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, 657 ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs,
646 sd->hid_sensor_client_cnt, NULL, 0, NULL); 658 sd->hid_sensor_client_cnt, NULL, 0, NULL);
647 if (ret < 0) 659 if (ret < 0)
648 goto err_free_names; 660 goto err_no_mem;
649 661
650 return ret; 662 return ret;
651 663
652err_free_names: 664err_no_mem:
653 for (i = 0; i < sd->hid_sensor_client_cnt ; ++i) 665 for (i = 0; i < sd->hid_sensor_client_cnt; ++i) {
654 kfree(sd->hid_sensor_hub_client_devs[i].name); 666 kfree(sd->hid_sensor_hub_client_devs[i].name);
667 kfree(sd->hid_sensor_hub_client_devs[i].platform_data);
668 }
655 kfree(sd->hid_sensor_hub_client_devs); 669 kfree(sd->hid_sensor_hub_client_devs);
656err_stop_hw: 670err_stop_hw:
657 hid_hw_stop(hdev); 671 hid_hw_stop(hdev);
@@ -673,8 +687,10 @@ static void sensor_hub_remove(struct hid_device *hdev)
673 complete(&data->pending.ready); 687 complete(&data->pending.ready);
674 spin_unlock_irqrestore(&data->lock, flags); 688 spin_unlock_irqrestore(&data->lock, flags);
675 mfd_remove_devices(&hdev->dev); 689 mfd_remove_devices(&hdev->dev);
676 for (i = 0; i < data->hid_sensor_client_cnt ; ++i) 690 for (i = 0; i < data->hid_sensor_client_cnt; ++i) {
677 kfree(data->hid_sensor_hub_client_devs[i].name); 691 kfree(data->hid_sensor_hub_client_devs[i].name);
692 kfree(data->hid_sensor_hub_client_devs[i].platform_data);
693 }
678 kfree(data->hid_sensor_hub_client_devs); 694 kfree(data->hid_sensor_hub_client_devs);
679 hid_set_drvdata(hdev, NULL); 695 hid_set_drvdata(hdev, NULL);
680 mutex_destroy(&data->mutex); 696 mutex_destroy(&data->mutex);