@@ -126,6 +126,7 @@ struct ideapad_rfk_priv {
126
126
127
127
struct ideapad_private {
128
128
struct acpi_device * adev ;
129
+ struct mutex vpc_mutex ; /* protects the VPC calls */
129
130
struct rfkill * rfk [IDEAPAD_RFKILL_DEV_NUM ];
130
131
struct ideapad_rfk_priv rfk_priv [IDEAPAD_RFKILL_DEV_NUM ];
131
132
struct platform_device * platform_device ;
@@ -301,6 +302,8 @@ static int debugfs_status_show(struct seq_file *s, void *data)
301
302
struct ideapad_private * priv = s -> private ;
302
303
unsigned long value ;
303
304
305
+ guard (mutex )(& priv -> vpc_mutex );
306
+
304
307
if (!read_ec_data (priv -> adev -> handle , VPCCMD_R_BL_MAX , & value ))
305
308
seq_printf (s , "Backlight max: %lu\n" , value );
306
309
if (!read_ec_data (priv -> adev -> handle , VPCCMD_R_BL , & value ))
@@ -419,7 +422,8 @@ static ssize_t camera_power_show(struct device *dev,
419
422
unsigned long result ;
420
423
int err ;
421
424
422
- err = read_ec_data (priv -> adev -> handle , VPCCMD_R_CAMERA , & result );
425
+ scoped_guard (mutex , & priv -> vpc_mutex )
426
+ err = read_ec_data (priv -> adev -> handle , VPCCMD_R_CAMERA , & result );
423
427
if (err )
424
428
return err ;
425
429
@@ -438,7 +442,8 @@ static ssize_t camera_power_store(struct device *dev,
438
442
if (err )
439
443
return err ;
440
444
441
- err = write_ec_cmd (priv -> adev -> handle , VPCCMD_W_CAMERA , state );
445
+ scoped_guard (mutex , & priv -> vpc_mutex )
446
+ err = write_ec_cmd (priv -> adev -> handle , VPCCMD_W_CAMERA , state );
442
447
if (err )
443
448
return err ;
444
449
@@ -491,7 +496,8 @@ static ssize_t fan_mode_show(struct device *dev,
491
496
unsigned long result ;
492
497
int err ;
493
498
494
- err = read_ec_data (priv -> adev -> handle , VPCCMD_R_FAN , & result );
499
+ scoped_guard (mutex , & priv -> vpc_mutex )
500
+ err = read_ec_data (priv -> adev -> handle , VPCCMD_R_FAN , & result );
495
501
if (err )
496
502
return err ;
497
503
@@ -513,7 +519,8 @@ static ssize_t fan_mode_store(struct device *dev,
513
519
if (state > 4 || state == 3 )
514
520
return - EINVAL ;
515
521
516
- err = write_ec_cmd (priv -> adev -> handle , VPCCMD_W_FAN , state );
522
+ scoped_guard (mutex , & priv -> vpc_mutex )
523
+ err = write_ec_cmd (priv -> adev -> handle , VPCCMD_W_FAN , state );
517
524
if (err )
518
525
return err ;
519
526
@@ -598,7 +605,8 @@ static ssize_t touchpad_show(struct device *dev,
598
605
unsigned long result ;
599
606
int err ;
600
607
601
- err = read_ec_data (priv -> adev -> handle , VPCCMD_R_TOUCHPAD , & result );
608
+ scoped_guard (mutex , & priv -> vpc_mutex )
609
+ err = read_ec_data (priv -> adev -> handle , VPCCMD_R_TOUCHPAD , & result );
602
610
if (err )
603
611
return err ;
604
612
@@ -619,7 +627,8 @@ static ssize_t touchpad_store(struct device *dev,
619
627
if (err )
620
628
return err ;
621
629
622
- err = write_ec_cmd (priv -> adev -> handle , VPCCMD_W_TOUCHPAD , state );
630
+ scoped_guard (mutex , & priv -> vpc_mutex )
631
+ err = write_ec_cmd (priv -> adev -> handle , VPCCMD_W_TOUCHPAD , state );
623
632
if (err )
624
633
return err ;
625
634
@@ -1012,6 +1021,8 @@ static int ideapad_rfk_set(void *data, bool blocked)
1012
1021
struct ideapad_rfk_priv * priv = data ;
1013
1022
int opcode = ideapad_rfk_data [priv -> dev ].opcode ;
1014
1023
1024
+ guard (mutex )(& priv -> priv -> vpc_mutex );
1025
+
1015
1026
return write_ec_cmd (priv -> priv -> adev -> handle , opcode , !blocked );
1016
1027
}
1017
1028
@@ -1025,6 +1036,8 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv)
1025
1036
int i ;
1026
1037
1027
1038
if (priv -> features .hw_rfkill_switch ) {
1039
+ guard (mutex )(& priv -> vpc_mutex );
1040
+
1028
1041
if (read_ec_data (priv -> adev -> handle , VPCCMD_R_RF , & hw_blocked ))
1029
1042
return ;
1030
1043
hw_blocked = !hw_blocked ;
@@ -1198,8 +1211,9 @@ static void ideapad_input_novokey(struct ideapad_private *priv)
1198
1211
{
1199
1212
unsigned long long_pressed ;
1200
1213
1201
- if (read_ec_data (priv -> adev -> handle , VPCCMD_R_NOVO , & long_pressed ))
1202
- return ;
1214
+ scoped_guard (mutex , & priv -> vpc_mutex )
1215
+ if (read_ec_data (priv -> adev -> handle , VPCCMD_R_NOVO , & long_pressed ))
1216
+ return ;
1203
1217
1204
1218
if (long_pressed )
1205
1219
ideapad_input_report (priv , 17 );
@@ -1211,8 +1225,9 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv)
1211
1225
{
1212
1226
unsigned long bit , value ;
1213
1227
1214
- if (read_ec_data (priv -> adev -> handle , VPCCMD_R_SPECIAL_BUTTONS , & value ))
1215
- return ;
1228
+ scoped_guard (mutex , & priv -> vpc_mutex )
1229
+ if (read_ec_data (priv -> adev -> handle , VPCCMD_R_SPECIAL_BUTTONS , & value ))
1230
+ return ;
1216
1231
1217
1232
for_each_set_bit (bit , & value , 16 ) {
1218
1233
switch (bit ) {
@@ -1245,6 +1260,8 @@ static int ideapad_backlight_get_brightness(struct backlight_device *blightdev)
1245
1260
unsigned long now ;
1246
1261
int err ;
1247
1262
1263
+ guard (mutex )(& priv -> vpc_mutex );
1264
+
1248
1265
err = read_ec_data (priv -> adev -> handle , VPCCMD_R_BL , & now );
1249
1266
if (err )
1250
1267
return err ;
@@ -1257,6 +1274,8 @@ static int ideapad_backlight_update_status(struct backlight_device *blightdev)
1257
1274
struct ideapad_private * priv = bl_get_data (blightdev );
1258
1275
int err ;
1259
1276
1277
+ guard (mutex )(& priv -> vpc_mutex );
1278
+
1260
1279
err = write_ec_cmd (priv -> adev -> handle , VPCCMD_W_BL ,
1261
1280
blightdev -> props .brightness );
1262
1281
if (err )
@@ -1334,6 +1353,8 @@ static void ideapad_backlight_notify_power(struct ideapad_private *priv)
1334
1353
if (!blightdev )
1335
1354
return ;
1336
1355
1356
+ guard (mutex )(& priv -> vpc_mutex );
1357
+
1337
1358
if (read_ec_data (priv -> adev -> handle , VPCCMD_R_BL_POWER , & power ))
1338
1359
return ;
1339
1360
@@ -1346,7 +1367,8 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv)
1346
1367
1347
1368
/* if we control brightness via acpi video driver */
1348
1369
if (!priv -> blightdev )
1349
- read_ec_data (priv -> adev -> handle , VPCCMD_R_BL , & now );
1370
+ scoped_guard (mutex , & priv -> vpc_mutex )
1371
+ read_ec_data (priv -> adev -> handle , VPCCMD_R_BL , & now );
1350
1372
else
1351
1373
backlight_force_update (priv -> blightdev , BACKLIGHT_UPDATE_HOTKEY );
1352
1374
}
@@ -1571,7 +1593,8 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv, bool send_
1571
1593
int ret ;
1572
1594
1573
1595
/* Without reading from EC touchpad LED doesn't switch state */
1574
- ret = read_ec_data (priv -> adev -> handle , VPCCMD_R_TOUCHPAD , & value );
1596
+ scoped_guard (mutex , & priv -> vpc_mutex )
1597
+ ret = read_ec_data (priv -> adev -> handle , VPCCMD_R_TOUCHPAD , & value );
1575
1598
if (ret )
1576
1599
return ;
1577
1600
@@ -1631,7 +1654,8 @@ static void ideapad_laptop_trigger_ec(void)
1631
1654
if (!priv -> features .ymc_ec_trigger )
1632
1655
return ;
1633
1656
1634
- ret = write_ec_cmd (priv -> adev -> handle , VPCCMD_W_YMC , 1 );
1657
+ scoped_guard (mutex , & priv -> vpc_mutex )
1658
+ ret = write_ec_cmd (priv -> adev -> handle , VPCCMD_W_YMC , 1 );
1635
1659
if (ret )
1636
1660
dev_warn (& priv -> platform_device -> dev , "Could not write YMC: %d\n" , ret );
1637
1661
}
@@ -1677,11 +1701,13 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data)
1677
1701
struct ideapad_private * priv = data ;
1678
1702
unsigned long vpc1 , vpc2 , bit ;
1679
1703
1680
- if (read_ec_data (handle , VPCCMD_R_VPC1 , & vpc1 ))
1681
- return ;
1704
+ scoped_guard (mutex , & priv -> vpc_mutex ) {
1705
+ if (read_ec_data (handle , VPCCMD_R_VPC1 , & vpc1 ))
1706
+ return ;
1682
1707
1683
- if (read_ec_data (handle , VPCCMD_R_VPC2 , & vpc2 ))
1684
- return ;
1708
+ if (read_ec_data (handle , VPCCMD_R_VPC2 , & vpc2 ))
1709
+ return ;
1710
+ }
1685
1711
1686
1712
vpc1 = (vpc2 << 8 ) | vpc1 ;
1687
1713
@@ -1988,6 +2014,10 @@ static int ideapad_acpi_add(struct platform_device *pdev)
1988
2014
priv -> adev = adev ;
1989
2015
priv -> platform_device = pdev ;
1990
2016
2017
+ err = devm_mutex_init (& pdev -> dev , & priv -> vpc_mutex );
2018
+ if (err )
2019
+ return err ;
2020
+
1991
2021
ideapad_check_features (priv );
1992
2022
1993
2023
err = ideapad_sysfs_init (priv );
0 commit comments