diff options
| -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]; |
