summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew de los Reyes <adlr@chromium.org>2013-01-05 14:06:32 -0800
committerPeter Wu <lekensteyn@gmail.com>2013-09-04 22:28:55 +0200
commit24c61dcb42484dcc5163ab4127ccd64a91c1e8e4 (patch)
treeade99562fb9d538652b7f291af6feb079ebae1ee
parentd8dfad3876e4386666b759da3c833d62fb8b2267 (diff)
downloadlinux-24c61dcb42484dcc5163ab4127ccd64a91c1e8e4.tar.gz
CHROMEOS: HID: logitech-dj: Delay creation of enumerated devices until connected.
This is necessary because it's impossible to communicate with devices that aren't connected and future patches will need to communicate with devices during probe(). By waiting until the device is connected, we ensure that we only register the device when it's active and ready for use. BUG=chromium-os:39354 TEST=manually tested on Link Signed-off-by: Andrew de los Reyes <adlr@chromium.org> Change-Id: Id5f2ae88839d1c39362cf0f9246a39d1f6e6238a Reviewed-on: https://gerrit.chromium.org/gerrit/46007 Reviewed-by: Yufeng Shen <miletus@chromium.org>
-rw-r--r--drivers/hid/hid-logitech-dj.c35
-rw-r--r--drivers/hid/hid-logitech-dj.h1
2 files changed, 27 insertions, 9 deletions
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index cd33084c7860..a7c0da78b3b8 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -290,17 +290,8 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
djrcv_dev->paired_dj_devices[dj_report->device_index] = dj_dev;
- if (hid_add_device(dj_hiddev)) {
- dev_err(&djrcv_hdev->dev, "%s: failed adding dj_device\n",
- __func__);
- goto hid_add_device_fail;
- }
-
return;
-hid_add_device_fail:
- djrcv_dev->paired_dj_devices[dj_report->device_index] = NULL;
- kfree(dj_dev);
dj_device_allocate_fail:
hid_destroy_device(dj_hiddev);
}
@@ -309,11 +300,15 @@ static void delayedwork_callback(struct work_struct *work)
{
struct dj_receiver_dev *djrcv_dev =
container_of(work, struct dj_receiver_dev, work);
+ struct hid_device *djrcv_hdev = djrcv_dev->hdev;
+ struct dj_device *djdev;
struct dj_report dj_report;
unsigned long flags;
int count;
int retval;
+ u8 param_status;
+ bool connected;
dbg_hid("%s\n", __func__);
@@ -345,6 +340,27 @@ static void delayedwork_callback(struct work_struct *work)
case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
break;
+ case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
+ param_status = dj_report.report_params[
+ CONNECTION_STATUS_PARAM_STATUS];
+ connected = param_status != STATUS_LINKLOSS;
+ djdev = djrcv_dev->paired_dj_devices[dj_report.device_index];
+ dbg_hid("%s: got REPORT_TYPE_NOTIF_CONNECTION_STATUS %d %d\n", __func__, djdev ? djdev->hid_device_started : -1, connected);
+ if (!djdev) {
+ dev_err(&djrcv_dev->hdev->dev, "%s:"
+ "dj_dev null, unexpected device index\n",
+ __func__);
+ return;
+ }
+ if (!djdev->hid_device_started && connected) {
+ if (hid_add_device(djdev->hdev)) {
+ dev_err(&djrcv_hdev->dev,
+ "%s: failed adding dj_device\n",
+ __func__);
+ } else {
+ djdev->hid_device_started = 1;
+ }
+ }
default:
/* A normal report (i. e. not belonging to a pair/unpair notification)
* arriving here, means that the report arrived but we did not have a
@@ -718,6 +734,7 @@ static int logi_dj_raw_event(struct hid_device *hdev,
STATUS_LINKLOSS) {
logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
}
+ logi_dj_recv_queue_notification(djrcv_dev, dj_report);
break;
default:
logi_dj_recv_forward_report(djrcv_dev, dj_report);
diff --git a/drivers/hid/hid-logitech-dj.h b/drivers/hid/hid-logitech-dj.h
index 4a4000340ce1..767decaad964 100644
--- a/drivers/hid/hid-logitech-dj.h
+++ b/drivers/hid/hid-logitech-dj.h
@@ -109,6 +109,7 @@ struct dj_device {
struct dj_receiver_dev *dj_receiver_dev;
u32 reports_supported;
u8 device_index;
+ unsigned hid_device_started:1;
};
/**