diff mbox

Found bug in pwm-mxs.c

Message ID 54C794A6.3040805@induct.be
State Superseded
Headers show

Commit Message

Gaetan Hug Jan. 27, 2015, 1:37 p.m. UTC
Hello folks,

   I found a bug in the pwm-mxs.c driver for the i.MX28 platform.

   The driver computes from the desired period which clock divider it 
should be using. This computation assumes that the link between the 
register value and the actual divider value is raising 2 to the power of 
the registry value.

    div = 1 << regvalue

   This is true only for the first 5 values out of 8. Next values are 
64, 256 and, 1024.
   This affects only the user only if he requests a period > 0.04369s.
   I solved this by replacing the computation of the divider value with 
a lookup table.

   If I should provide it in a different manner for it to be included in 
the kernel, please let me know.

Best regards

Gaetan Hug

------

         }



--
To unsubscribe from this list: send the line "unsubscribe linux-pwm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git i/drivers/pwm/pwm-mxs.c w/drivers/pwm/pwm-mxs.c
index c2c5a4f..cb89f7e 100644
--- i/drivers/pwm/pwm-mxs.c
+++ w/drivers/pwm/pwm-mxs.c
@@ -51,16 +51,17 @@  static int mxs_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
         unsigned int period_cycles, duty_cycles;
         unsigned long rate;
         unsigned long long c;
+       unsigned const int cdiv[PERIOD_CDIV_MAX] = {1, 2, 4, 8, 16, 64, 
256, 1024};

         rate = clk_get_rate(mxs->clk);
         while (1) {
-               c = rate / (1 << div);
+               c = rate / cdiv[div];
                 c = c * period_ns;
                 do_div(c, 1000000000);
                 if (c < PERIOD_PERIOD_MAX)
                         break;
                 div++;
-               if (div > PERIOD_CDIV_MAX)
+               if (div >= PERIOD_CDIV_MAX)
                         return -EINVAL;