diff options
Diffstat (limited to 'drivers/hwmon/aspeed-pwm-tacho.c')
-rw-r--r-- | drivers/hwmon/aspeed-pwm-tacho.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c index b2ab5612d8a4..ddfe66bdff86 100644 --- a/drivers/hwmon/aspeed-pwm-tacho.c +++ b/drivers/hwmon/aspeed-pwm-tacho.c | |||
@@ -163,6 +163,9 @@ | |||
163 | #define M_TACH_UNIT 0x00c0 | 163 | #define M_TACH_UNIT 0x00c0 |
164 | #define INIT_FAN_CTRL 0xFF | 164 | #define INIT_FAN_CTRL 0xFF |
165 | 165 | ||
166 | /* How long we sleep in us while waiting for an RPM result. */ | ||
167 | #define ASPEED_RPM_STATUS_SLEEP_USEC 500 | ||
168 | |||
166 | struct aspeed_pwm_tacho_data { | 169 | struct aspeed_pwm_tacho_data { |
167 | struct regmap *regmap; | 170 | struct regmap *regmap; |
168 | unsigned long clk_freq; | 171 | unsigned long clk_freq; |
@@ -508,8 +511,9 @@ static u32 aspeed_get_fan_tach_ch_measure_period(struct aspeed_pwm_tacho_data | |||
508 | static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv, | 511 | static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv, |
509 | u8 fan_tach_ch) | 512 | u8 fan_tach_ch) |
510 | { | 513 | { |
511 | u32 raw_data, tach_div, clk_source, sec, val; | 514 | u32 raw_data, tach_div, clk_source, msec, usec, val; |
512 | u8 fan_tach_ch_source, type, mode, both; | 515 | u8 fan_tach_ch_source, type, mode, both; |
516 | int ret; | ||
513 | 517 | ||
514 | regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0); | 518 | regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0); |
515 | regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch); | 519 | regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch); |
@@ -517,12 +521,20 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv, | |||
517 | fan_tach_ch_source = priv->fan_tach_ch_source[fan_tach_ch]; | 521 | fan_tach_ch_source = priv->fan_tach_ch_source[fan_tach_ch]; |
518 | type = priv->pwm_port_type[fan_tach_ch_source]; | 522 | type = priv->pwm_port_type[fan_tach_ch_source]; |
519 | 523 | ||
520 | sec = (1000 / aspeed_get_fan_tach_ch_measure_period(priv, type)); | 524 | msec = (1000 / aspeed_get_fan_tach_ch_measure_period(priv, type)); |
521 | msleep(sec); | 525 | usec = msec * 1000; |
526 | |||
527 | ret = regmap_read_poll_timeout( | ||
528 | priv->regmap, | ||
529 | ASPEED_PTCR_RESULT, | ||
530 | val, | ||
531 | (val & RESULT_STATUS_MASK), | ||
532 | ASPEED_RPM_STATUS_SLEEP_USEC, | ||
533 | usec); | ||
522 | 534 | ||
523 | regmap_read(priv->regmap, ASPEED_PTCR_RESULT, &val); | 535 | /* return -ETIMEDOUT if we didn't get an answer. */ |
524 | if (!(val & RESULT_STATUS_MASK)) | 536 | if (ret) |
525 | return -ETIMEDOUT; | 537 | return ret; |
526 | 538 | ||
527 | raw_data = val & RESULT_VALUE_MASK; | 539 | raw_data = val & RESULT_VALUE_MASK; |
528 | tach_div = priv->type_fan_tach_clock_division[type]; | 540 | tach_div = priv->type_fan_tach_clock_division[type]; |