@@ -195,6 +195,8 @@ struct aspeed_pwm_tacho_data {
195
195
u8 fan_tach_ch_source [MAX_ASPEED_FAN_TACH_CHANNELS ];
196
196
struct aspeed_cooling_device * cdev [8 ];
197
197
const struct attribute_group * groups [3 ];
198
+ /* protects access to shared ASPEED_PTCR_RESULT */
199
+ struct mutex tach_lock ;
198
200
};
199
201
200
202
enum type { TYPEM , TYPEN , TYPEO };
@@ -529,6 +531,8 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv,
529
531
u8 fan_tach_ch_source , type , mode , both ;
530
532
int ret ;
531
533
534
+ mutex_lock (& priv -> tach_lock );
535
+
532
536
regmap_write (priv -> regmap , ASPEED_PTCR_TRIGGER , 0 );
533
537
regmap_write (priv -> regmap , ASPEED_PTCR_TRIGGER , 0x1 << fan_tach_ch );
534
538
@@ -546,6 +550,8 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv,
546
550
ASPEED_RPM_STATUS_SLEEP_USEC ,
547
551
usec );
548
552
553
+ mutex_unlock (& priv -> tach_lock );
554
+
549
555
/* return -ETIMEDOUT if we didn't get an answer. */
550
556
if (ret )
551
557
return ret ;
@@ -915,6 +921,7 @@ static int aspeed_pwm_tacho_probe(struct platform_device *pdev)
915
921
priv = devm_kzalloc (dev , sizeof (* priv ), GFP_KERNEL );
916
922
if (!priv )
917
923
return - ENOMEM ;
924
+ mutex_init (& priv -> tach_lock );
918
925
priv -> regmap = devm_regmap_init (dev , NULL , (__force void * )regs ,
919
926
& aspeed_pwm_tacho_regmap_config );
920
927
if (IS_ERR (priv -> regmap ))
0 commit comments