Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (axi-fan-control) Handle irqs in natural order

The core will now start out of reset at boot as soon as clocking is
available. Hence, by the time we unmask the interrupts we already might
have some of them set. Thus, it's important to handle them in the
natural order the core generates them. Otherwise, we could process
'ADI_IRQ_SRC_PWM_CHANGED' before 'ADI_IRQ_SRC_TEMP_INCREASE' and
erroneously set 'update_tacho_params' to true.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20210811114853.159298-3-nuno.sa@analog.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Nuno Sá and committed by
Guenter Roeck
e66705de a3933625

+15 -15
+15 -15
drivers/hwmon/axi-fan-control.c
··· 283 283 u32 irq_pending = axi_ioread(ADI_REG_IRQ_PENDING, ctl); 284 284 u32 clear_mask; 285 285 286 - if (irq_pending & ADI_IRQ_SRC_NEW_MEASUR) { 287 - if (ctl->update_tacho_params) { 288 - u32 new_tach = axi_ioread(ADI_REG_TACH_MEASUR, ctl); 289 - 290 - /* get 25% tolerance */ 291 - u32 tach_tol = DIV_ROUND_CLOSEST(new_tach * 25, 100); 292 - /* set new tacho parameters */ 293 - axi_iowrite(new_tach, ADI_REG_TACH_PERIOD, ctl); 294 - axi_iowrite(tach_tol, ADI_REG_TACH_TOLERANCE, ctl); 295 - ctl->update_tacho_params = false; 296 - } 297 - } 286 + if (irq_pending & ADI_IRQ_SRC_TEMP_INCREASE) 287 + /* hardware requested a new pwm */ 288 + ctl->hw_pwm_req = true; 298 289 299 290 if (irq_pending & ADI_IRQ_SRC_PWM_CHANGED) { 300 291 /* ··· 301 310 } 302 311 } 303 312 304 - if (irq_pending & ADI_IRQ_SRC_TEMP_INCREASE) 305 - /* hardware requested a new pwm */ 306 - ctl->hw_pwm_req = true; 313 + if (irq_pending & ADI_IRQ_SRC_NEW_MEASUR) { 314 + if (ctl->update_tacho_params) { 315 + u32 new_tach = axi_ioread(ADI_REG_TACH_MEASUR, ctl); 316 + /* get 25% tolerance */ 317 + u32 tach_tol = DIV_ROUND_CLOSEST(new_tach * 25, 100); 318 + 319 + /* set new tacho parameters */ 320 + axi_iowrite(new_tach, ADI_REG_TACH_PERIOD, ctl); 321 + axi_iowrite(tach_tol, ADI_REG_TACH_TOLERANCE, ctl); 322 + ctl->update_tacho_params = false; 323 + } 324 + } 307 325 308 326 if (irq_pending & ADI_IRQ_SRC_TACH_ERR) 309 327 ctl->fan_fault = 1;