Message ID | 20200323065318.16533-2-rayagonda.kokatanur@broadcom.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Handle return value and remove unnecessary check | expand |
On Mon, Mar 23, 2020 at 12:23:17PM +0530, Rayagonda Kokatanur wrote: > Handle clk_get_rate() returning <= 0 condition to avoid > possible division by zero. Was this noticed during a review and is more theoretic. Or does this (depending on pre-boot state) result in a kernel crash? > Fixes: daa5abc41c80 ("pwm: Add support for Broadcom iProc PWM controller") > Signed-off-by: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com> > --- > drivers/pwm/pwm-bcm-iproc.c | 32 +++++++++++++++++++------------- > 1 file changed, 19 insertions(+), 13 deletions(-) > > diff --git a/drivers/pwm/pwm-bcm-iproc.c b/drivers/pwm/pwm-bcm-iproc.c > index 1f829edd8ee7..8bbd2a04fead 100644 > --- a/drivers/pwm/pwm-bcm-iproc.c > +++ b/drivers/pwm/pwm-bcm-iproc.c > @@ -99,19 +99,25 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm, > else > state->polarity = PWM_POLARITY_INVERSED; > > - value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET); > - prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm); > - prescale &= IPROC_PWM_PRESCALE_MAX; > - > - multi = NSEC_PER_SEC * (prescale + 1); > - > - value = readl(ip->base + IPROC_PWM_PERIOD_OFFSET(pwm->hwpwm)); > - tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; > - state->period = div64_u64(tmp, rate); > - > - value = readl(ip->base + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm)); > - tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; > - state->duty_cycle = div64_u64(tmp, rate); > + if (rate == 0) { > + state->period = 0; > + state->duty_cycle = 0; > + } else { > + value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET); > + prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm); > + prescale &= IPROC_PWM_PRESCALE_MAX; > + > + multi = NSEC_PER_SEC * (prescale + 1); > + > + value = readl(ip->base + IPROC_PWM_PERIOD_OFFSET(pwm->hwpwm)); > + tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; > + state->period = div64_u64(tmp, rate); > + > + value = readl(ip->base + > + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm)); > + tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; > + state->duty_cycle = div64_u64(tmp, rate); > + } The change looks fine. Best regards Uwe
On Mon, Mar 23, 2020 at 1:55 PM Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote: > > On Mon, Mar 23, 2020 at 12:23:17PM +0530, Rayagonda Kokatanur wrote: > > Handle clk_get_rate() returning <= 0 condition to avoid > > possible division by zero. > > Was this noticed during a review and is more theoretic. Or does this > (depending on pre-boot state) result in a kernel crash? This is reported by internal coverity tool. > > > Fixes: daa5abc41c80 ("pwm: Add support for Broadcom iProc PWM controller") > > Signed-off-by: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com> > > --- > > drivers/pwm/pwm-bcm-iproc.c | 32 +++++++++++++++++++------------- > > 1 file changed, 19 insertions(+), 13 deletions(-) > > > > diff --git a/drivers/pwm/pwm-bcm-iproc.c b/drivers/pwm/pwm-bcm-iproc.c > > index 1f829edd8ee7..8bbd2a04fead 100644 > > --- a/drivers/pwm/pwm-bcm-iproc.c > > +++ b/drivers/pwm/pwm-bcm-iproc.c > > @@ -99,19 +99,25 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm, > > else > > state->polarity = PWM_POLARITY_INVERSED; > > > > - value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET); > > - prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm); > > - prescale &= IPROC_PWM_PRESCALE_MAX; > > - > > - multi = NSEC_PER_SEC * (prescale + 1); > > - > > - value = readl(ip->base + IPROC_PWM_PERIOD_OFFSET(pwm->hwpwm)); > > - tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; > > - state->period = div64_u64(tmp, rate); > > - > > - value = readl(ip->base + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm)); > > - tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; > > - state->duty_cycle = div64_u64(tmp, rate); > > + if (rate == 0) { > > + state->period = 0; > > + state->duty_cycle = 0; > > + } else { > > + value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET); > > + prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm); > > + prescale &= IPROC_PWM_PRESCALE_MAX; > > + > > + multi = NSEC_PER_SEC * (prescale + 1); > > + > > + value = readl(ip->base + IPROC_PWM_PERIOD_OFFSET(pwm->hwpwm)); > > + tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; > > + state->period = div64_u64(tmp, rate); > > + > > + value = readl(ip->base + > > + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm)); > > + tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; > > + state->duty_cycle = div64_u64(tmp, rate); > > + } > > The change looks fine. > > Best regards > Uwe > > -- > Pengutronix e.K. | Uwe Kleine-König | > Industrial Linux Solutions | https://www.pengutronix.de/ |
diff --git a/drivers/pwm/pwm-bcm-iproc.c b/drivers/pwm/pwm-bcm-iproc.c index 1f829edd8ee7..8bbd2a04fead 100644 --- a/drivers/pwm/pwm-bcm-iproc.c +++ b/drivers/pwm/pwm-bcm-iproc.c @@ -99,19 +99,25 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm, else state->polarity = PWM_POLARITY_INVERSED; - value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET); - prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm); - prescale &= IPROC_PWM_PRESCALE_MAX; - - multi = NSEC_PER_SEC * (prescale + 1); - - value = readl(ip->base + IPROC_PWM_PERIOD_OFFSET(pwm->hwpwm)); - tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; - state->period = div64_u64(tmp, rate); - - value = readl(ip->base + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm)); - tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; - state->duty_cycle = div64_u64(tmp, rate); + if (rate == 0) { + state->period = 0; + state->duty_cycle = 0; + } else { + value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET); + prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm); + prescale &= IPROC_PWM_PRESCALE_MAX; + + multi = NSEC_PER_SEC * (prescale + 1); + + value = readl(ip->base + IPROC_PWM_PERIOD_OFFSET(pwm->hwpwm)); + tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; + state->period = div64_u64(tmp, rate); + + value = readl(ip->base + + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm)); + tmp = (value & IPROC_PWM_PERIOD_MAX) * multi; + state->duty_cycle = div64_u64(tmp, rate); + } } static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm,
Handle clk_get_rate() returning <= 0 condition to avoid possible division by zero. Fixes: daa5abc41c80 ("pwm: Add support for Broadcom iProc PWM controller") Signed-off-by: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com> --- drivers/pwm/pwm-bcm-iproc.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-)