@@ -126,6 +126,7 @@ struct ideapad_rfk_priv {
126126
127127struct ideapad_private {
128128 struct acpi_device * adev ;
129+ struct mutex vpc_mutex ; /* protects the VPC calls */
129130 struct rfkill * rfk [IDEAPAD_RFKILL_DEV_NUM ];
130131 struct ideapad_rfk_priv rfk_priv [IDEAPAD_RFKILL_DEV_NUM ];
131132 struct platform_device * platform_device ;
@@ -301,6 +302,8 @@ static int debugfs_status_show(struct seq_file *s, void *data)
301302 struct ideapad_private * priv = s -> private ;
302303 unsigned long value ;
303304
305+ guard (mutex )(& priv -> vpc_mutex );
306+
304307 if (!read_ec_data (priv -> adev -> handle , VPCCMD_R_BL_MAX , & value ))
305308 seq_printf (s , "Backlight max: %lu\n" , value );
306309 if (!read_ec_data (priv -> adev -> handle , VPCCMD_R_BL , & value ))
@@ -419,7 +422,8 @@ static ssize_t camera_power_show(struct device *dev,
419422 unsigned long result ;
420423 int err ;
421424
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 );
423427 if (err )
424428 return err ;
425429
@@ -438,7 +442,8 @@ static ssize_t camera_power_store(struct device *dev,
438442 if (err )
439443 return err ;
440444
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 );
442447 if (err )
443448 return err ;
444449
@@ -491,7 +496,8 @@ static ssize_t fan_mode_show(struct device *dev,
491496 unsigned long result ;
492497 int err ;
493498
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 );
495501 if (err )
496502 return err ;
497503
@@ -513,7 +519,8 @@ static ssize_t fan_mode_store(struct device *dev,
513519 if (state > 4 || state == 3 )
514520 return - EINVAL ;
515521
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 );
517524 if (err )
518525 return err ;
519526
@@ -598,7 +605,8 @@ static ssize_t touchpad_show(struct device *dev,
598605 unsigned long result ;
599606 int err ;
600607
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 );
602610 if (err )
603611 return err ;
604612
@@ -619,7 +627,8 @@ static ssize_t touchpad_store(struct device *dev,
619627 if (err )
620628 return err ;
621629
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 );
623632 if (err )
624633 return err ;
625634
@@ -1012,6 +1021,8 @@ static int ideapad_rfk_set(void *data, bool blocked)
10121021 struct ideapad_rfk_priv * priv = data ;
10131022 int opcode = ideapad_rfk_data [priv -> dev ].opcode ;
10141023
1024+ guard (mutex )(& priv -> priv -> vpc_mutex );
1025+
10151026 return write_ec_cmd (priv -> priv -> adev -> handle , opcode , !blocked );
10161027}
10171028
@@ -1025,6 +1036,8 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv)
10251036 int i ;
10261037
10271038 if (priv -> features .hw_rfkill_switch ) {
1039+ guard (mutex )(& priv -> vpc_mutex );
1040+
10281041 if (read_ec_data (priv -> adev -> handle , VPCCMD_R_RF , & hw_blocked ))
10291042 return ;
10301043 hw_blocked = !hw_blocked ;
@@ -1198,8 +1211,9 @@ static void ideapad_input_novokey(struct ideapad_private *priv)
11981211{
11991212 unsigned long long_pressed ;
12001213
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 ;
12031217
12041218 if (long_pressed )
12051219 ideapad_input_report (priv , 17 );
@@ -1211,8 +1225,9 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv)
12111225{
12121226 unsigned long bit , value ;
12131227
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 ;
12161231
12171232 for_each_set_bit (bit , & value , 16 ) {
12181233 switch (bit ) {
@@ -1245,6 +1260,8 @@ static int ideapad_backlight_get_brightness(struct backlight_device *blightdev)
12451260 unsigned long now ;
12461261 int err ;
12471262
1263+ guard (mutex )(& priv -> vpc_mutex );
1264+
12481265 err = read_ec_data (priv -> adev -> handle , VPCCMD_R_BL , & now );
12491266 if (err )
12501267 return err ;
@@ -1257,6 +1274,8 @@ static int ideapad_backlight_update_status(struct backlight_device *blightdev)
12571274 struct ideapad_private * priv = bl_get_data (blightdev );
12581275 int err ;
12591276
1277+ guard (mutex )(& priv -> vpc_mutex );
1278+
12601279 err = write_ec_cmd (priv -> adev -> handle , VPCCMD_W_BL ,
12611280 blightdev -> props .brightness );
12621281 if (err )
@@ -1334,6 +1353,8 @@ static void ideapad_backlight_notify_power(struct ideapad_private *priv)
13341353 if (!blightdev )
13351354 return ;
13361355
1356+ guard (mutex )(& priv -> vpc_mutex );
1357+
13371358 if (read_ec_data (priv -> adev -> handle , VPCCMD_R_BL_POWER , & power ))
13381359 return ;
13391360
@@ -1346,7 +1367,8 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv)
13461367
13471368 /* if we control brightness via acpi video driver */
13481369 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 );
13501372 else
13511373 backlight_force_update (priv -> blightdev , BACKLIGHT_UPDATE_HOTKEY );
13521374}
@@ -1571,7 +1593,8 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv, bool send_
15711593 int ret ;
15721594
15731595 /* 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 );
15751598 if (ret )
15761599 return ;
15771600
@@ -1631,7 +1654,8 @@ static void ideapad_laptop_trigger_ec(void)
16311654 if (!priv -> features .ymc_ec_trigger )
16321655 return ;
16331656
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 );
16351659 if (ret )
16361660 dev_warn (& priv -> platform_device -> dev , "Could not write YMC: %d\n" , ret );
16371661}
@@ -1677,11 +1701,13 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data)
16771701 struct ideapad_private * priv = data ;
16781702 unsigned long vpc1 , vpc2 , bit ;
16791703
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 ;
16821707
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+ }
16851711
16861712 vpc1 = (vpc2 << 8 ) | vpc1 ;
16871713
@@ -1988,6 +2014,10 @@ static int ideapad_acpi_add(struct platform_device *pdev)
19882014 priv -> adev = adev ;
19892015 priv -> platform_device = pdev ;
19902016
2017+ err = devm_mutex_init (& pdev -> dev , & priv -> vpc_mutex );
2018+ if (err )
2019+ return err ;
2020+
19912021 ideapad_check_features (priv );
19922022
19932023 err = ideapad_sysfs_init (priv );
0 commit comments