HID: sony: Refactor the output report sending functions
authorFrank Praznik <frank.praznik@gmail.com>
Wed, 11 Nov 2015 14:49:37 +0000 (09:49 -0500)
committerJiri Kosina <jkosina@suse.cz>
Thu, 19 Nov 2015 10:16:13 +0000 (11:16 +0100)
Refactor the output report sending functions to allow for the sending of output
reports without enqueuing a work item.  Output reports for any device can now be
sent via the send_output_report function pointer in the sony_sc struct which
points to the appropriate output function.  The individual state worker
functions have been replaced with a universal sony_state_worker function which
uses this function pointer.

Signed-off-by: Frank Praznik <frank.praznik@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/hid-sony.c

index 774cd221056659f5bacd480b8b07744c1a5a138f..4ba904b02bc26b3cca424df91aaaa88bc74dfa76 100644 (file)
@@ -1028,6 +1028,7 @@ struct sony_sc {
        struct led_classdev *leds[MAX_LEDS];
        unsigned long quirks;
        struct work_struct state_worker;
+       void(*send_output_report)(struct sony_sc*);
        struct power_supply *battery;
        struct power_supply_desc battery_desc;
        int device_id;
@@ -1789,7 +1790,7 @@ error_leds:
        return ret;
 }
 
-static void sixaxis_state_worker(struct work_struct *work)
+static void sixaxis_send_output_report(struct sony_sc *sc)
 {
        static const union sixaxis_output_report_01 default_report = {
                .buf = {
@@ -1803,7 +1804,6 @@ static void sixaxis_state_worker(struct work_struct *work)
                        0x00, 0x00, 0x00, 0x00, 0x00
                }
        };
-       struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
        struct sixaxis_output_report *report =
                (struct sixaxis_output_report *)sc->output_report_dmabuf;
        int n;
@@ -1846,9 +1846,8 @@ static void sixaxis_state_worker(struct work_struct *work)
                        HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
 }
 
-static void dualshock4_state_worker(struct work_struct *work)
+static void dualshock4_send_output_report(struct sony_sc *sc)
 {
-       struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
        struct hid_device *hdev = sc->hdev;
        __u8 *buf = sc->output_report_dmabuf;
        int offset;
@@ -1893,9 +1892,8 @@ static void dualshock4_state_worker(struct work_struct *work)
                                HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
 }
 
-static void motion_state_worker(struct work_struct *work)
+static void motion_send_output_report(struct sony_sc *sc)
 {
-       struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
        struct hid_device *hdev = sc->hdev;
        struct motion_output_report_02 *report =
                (struct motion_output_report_02 *)sc->output_report_dmabuf;
@@ -1914,6 +1912,12 @@ static void motion_state_worker(struct work_struct *work)
        hid_hw_output_report(hdev, (__u8 *)report, MOTION_REPORT_0x02_SIZE);
 }
 
+static void sony_state_worker(struct work_struct *work)
+{
+       struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
+       sc->send_output_report(sc);
+}
+
 static int sony_allocate_output_report(struct sony_sc *sc)
 {
        if ((sc->quirks & SIXAXIS_CONTROLLER) ||
@@ -2241,11 +2245,13 @@ static void sony_release_device_id(struct sony_sc *sc)
        }
 }
 
-static inline void sony_init_work(struct sony_sc *sc,
-                                       void (*worker)(struct work_struct *))
+static inline void sony_init_output_report(struct sony_sc *sc,
+                               void(*send_output_report)(struct sony_sc*))
 {
+       sc->send_output_report = send_output_report;
+
        if (!sc->worker_initialized)
-               INIT_WORK(&sc->state_worker, worker);
+               INIT_WORK(&sc->state_worker, sony_state_worker);
 
        sc->worker_initialized = 1;
 }
@@ -2319,7 +2325,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
                hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
                hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
                ret = sixaxis_set_operational_usb(hdev);
-               sony_init_work(sc, sixaxis_state_worker);
+               sony_init_output_report(sc, sixaxis_send_output_report);
        } else if ((sc->quirks & SIXAXIS_CONTROLLER_BT) ||
                        (sc->quirks & NAVIGATION_CONTROLLER_BT)) {
                /*
@@ -2328,7 +2334,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
                 */
                hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
                ret = sixaxis_set_operational_bt(hdev);
-               sony_init_work(sc, sixaxis_state_worker);
+               sony_init_output_report(sc, sixaxis_send_output_report);
        } else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
                if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
                        /*
@@ -2343,9 +2349,9 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
                        }
                }
 
-               sony_init_work(sc, dualshock4_state_worker);
+               sony_init_output_report(sc, dualshock4_send_output_report);
        } else if (sc->quirks & MOTION_CONTROLLER) {
-               sony_init_work(sc, motion_state_worker);
+               sony_init_output_report(sc, motion_send_output_report);
        } else {
                ret = 0;
        }