71
71
72
72
#include <linux/bitfield.h>
73
73
#include <linux/bitops.h>
74
- #include <linux/cleanup.h>
75
74
#include <linux/device.h>
76
75
#include <linux/hid.h>
77
76
#include <linux/module.h>
78
- #include <linux/mutex.h>
79
77
#include <linux/power_supply.h>
80
78
#include <linux/usb.h>
81
79
#include <linux/workqueue.h>
@@ -120,6 +118,12 @@ enum {
120
118
CORSAIR_VOID_BATTERY_CHARGING = 5 ,
121
119
};
122
120
121
+ enum {
122
+ CORSAIR_VOID_ADD_BATTERY = 0 ,
123
+ CORSAIR_VOID_REMOVE_BATTERY = 1 ,
124
+ CORSAIR_VOID_UPDATE_BATTERY = 2 ,
125
+ };
126
+
123
127
static enum power_supply_property corsair_void_battery_props [] = {
124
128
POWER_SUPPLY_PROP_STATUS ,
125
129
POWER_SUPPLY_PROP_PRESENT ,
@@ -155,12 +159,12 @@ struct corsair_void_drvdata {
155
159
156
160
struct power_supply * battery ;
157
161
struct power_supply_desc battery_desc ;
158
- struct mutex battery_mutex ;
159
162
160
163
struct delayed_work delayed_status_work ;
161
164
struct delayed_work delayed_firmware_work ;
162
- struct work_struct battery_remove_work ;
163
- struct work_struct battery_add_work ;
165
+
166
+ unsigned long battery_work_flags ;
167
+ struct work_struct battery_work ;
164
168
};
165
169
166
170
/*
@@ -260,11 +264,9 @@ static void corsair_void_process_receiver(struct corsair_void_drvdata *drvdata,
260
264
261
265
/* Inform power supply if battery values changed */
262
266
if (memcmp (& orig_battery_data , battery_data , sizeof (* battery_data ))) {
263
- scoped_guard (mutex , & drvdata -> battery_mutex ) {
264
- if (drvdata -> battery ) {
265
- power_supply_changed (drvdata -> battery );
266
- }
267
- }
267
+ set_bit (CORSAIR_VOID_UPDATE_BATTERY ,
268
+ & drvdata -> battery_work_flags );
269
+ schedule_work (& drvdata -> battery_work );
268
270
}
269
271
}
270
272
@@ -536,29 +538,11 @@ static void corsair_void_firmware_work_handler(struct work_struct *work)
536
538
537
539
}
538
540
539
- static void corsair_void_battery_remove_work_handler (struct work_struct * work )
540
- {
541
- struct corsair_void_drvdata * drvdata ;
542
-
543
- drvdata = container_of (work , struct corsair_void_drvdata ,
544
- battery_remove_work );
545
- scoped_guard (mutex , & drvdata -> battery_mutex ) {
546
- if (drvdata -> battery ) {
547
- power_supply_unregister (drvdata -> battery );
548
- drvdata -> battery = NULL ;
549
- }
550
- }
551
- }
552
-
553
- static void corsair_void_battery_add_work_handler (struct work_struct * work )
541
+ static void corsair_void_add_battery (struct corsair_void_drvdata * drvdata )
554
542
{
555
- struct corsair_void_drvdata * drvdata ;
556
543
struct power_supply_config psy_cfg = {};
557
544
struct power_supply * new_supply ;
558
545
559
- drvdata = container_of (work , struct corsair_void_drvdata ,
560
- battery_add_work );
561
- guard (mutex )(& drvdata -> battery_mutex );
562
546
if (drvdata -> battery )
563
547
return ;
564
548
@@ -583,16 +567,42 @@ static void corsair_void_battery_add_work_handler(struct work_struct *work)
583
567
drvdata -> battery = new_supply ;
584
568
}
585
569
570
+ static void corsair_void_battery_work_handler (struct work_struct * work )
571
+ {
572
+ struct corsair_void_drvdata * drvdata = container_of (work ,
573
+ struct corsair_void_drvdata , battery_work );
574
+
575
+ bool add_battery = test_and_clear_bit (CORSAIR_VOID_ADD_BATTERY ,
576
+ & drvdata -> battery_work_flags );
577
+ bool remove_battery = test_and_clear_bit (CORSAIR_VOID_REMOVE_BATTERY ,
578
+ & drvdata -> battery_work_flags );
579
+ bool update_battery = test_and_clear_bit (CORSAIR_VOID_UPDATE_BATTERY ,
580
+ & drvdata -> battery_work_flags );
581
+
582
+ if (add_battery && !remove_battery ) {
583
+ corsair_void_add_battery (drvdata );
584
+ } else if (remove_battery && !add_battery && drvdata -> battery ) {
585
+ power_supply_unregister (drvdata -> battery );
586
+ drvdata -> battery = NULL ;
587
+ }
588
+
589
+ if (update_battery && drvdata -> battery )
590
+ power_supply_changed (drvdata -> battery );
591
+
592
+ }
593
+
586
594
static void corsair_void_headset_connected (struct corsair_void_drvdata * drvdata )
587
595
{
588
- schedule_work (& drvdata -> battery_add_work );
596
+ set_bit (CORSAIR_VOID_ADD_BATTERY , & drvdata -> battery_work_flags );
597
+ schedule_work (& drvdata -> battery_work );
589
598
schedule_delayed_work (& drvdata -> delayed_firmware_work ,
590
599
msecs_to_jiffies (100 ));
591
600
}
592
601
593
602
static void corsair_void_headset_disconnected (struct corsair_void_drvdata * drvdata )
594
603
{
595
- schedule_work (& drvdata -> battery_remove_work );
604
+ set_bit (CORSAIR_VOID_REMOVE_BATTERY , & drvdata -> battery_work_flags );
605
+ schedule_work (& drvdata -> battery_work );
596
606
597
607
corsair_void_set_unknown_wireless_data (drvdata );
598
608
corsair_void_set_unknown_batt (drvdata );
@@ -678,13 +688,7 @@ static int corsair_void_probe(struct hid_device *hid_dev,
678
688
drvdata -> battery_desc .get_property = corsair_void_battery_get_property ;
679
689
680
690
drvdata -> battery = NULL ;
681
- INIT_WORK (& drvdata -> battery_remove_work ,
682
- corsair_void_battery_remove_work_handler );
683
- INIT_WORK (& drvdata -> battery_add_work ,
684
- corsair_void_battery_add_work_handler );
685
- ret = devm_mutex_init (drvdata -> dev , & drvdata -> battery_mutex );
686
- if (ret )
687
- return ret ;
691
+ INIT_WORK (& drvdata -> battery_work , corsair_void_battery_work_handler );
688
692
689
693
ret = sysfs_create_group (& hid_dev -> dev .kobj , & corsair_void_attr_group );
690
694
if (ret )
@@ -721,8 +725,7 @@ static void corsair_void_remove(struct hid_device *hid_dev)
721
725
struct corsair_void_drvdata * drvdata = hid_get_drvdata (hid_dev );
722
726
723
727
hid_hw_stop (hid_dev );
724
- cancel_work_sync (& drvdata -> battery_remove_work );
725
- cancel_work_sync (& drvdata -> battery_add_work );
728
+ cancel_work_sync (& drvdata -> battery_work );
726
729
if (drvdata -> battery )
727
730
power_supply_unregister (drvdata -> battery );
728
731
0 commit comments