diff options
| -rw-r--r-- | drivers/pwm/pwm-meson.c | 16 | 
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c index defc27d880f3..cb845edfe2b4 100644 --- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -163,7 +163,8 @@ static int meson_pwm_calc(struct meson_pwm *meson,  			  unsigned int duty, unsigned int period)  {  	unsigned int pre_div, cnt, duty_cnt; -	unsigned long fin_freq = -1, fin_ns; +	unsigned long fin_freq = -1; +	u64 fin_ps;  	if (~(meson->inverter_mask >> id) & 0x1)  		duty = period - duty; @@ -179,13 +180,15 @@ static int meson_pwm_calc(struct meson_pwm *meson,  	}  	dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq); -	fin_ns = NSEC_PER_SEC / fin_freq; +	fin_ps = (u64)NSEC_PER_SEC * 1000; +	do_div(fin_ps, fin_freq);  	/* Calc pre_div with the period */  	for (pre_div = 0; pre_div < MISC_CLK_DIV_MASK; pre_div++) { -		cnt = DIV_ROUND_CLOSEST(period, fin_ns * (pre_div + 1)); -		dev_dbg(meson->chip.dev, "fin_ns=%lu pre_div=%u cnt=%u\n", -			fin_ns, pre_div, cnt); +		cnt = DIV_ROUND_CLOSEST_ULL((u64)period * 1000, +					    fin_ps * (pre_div + 1)); +		dev_dbg(meson->chip.dev, "fin_ps=%llu pre_div=%u cnt=%u\n", +			fin_ps, pre_div, cnt);  		if (cnt <= 0xffff)  			break;  	} @@ -208,7 +211,8 @@ static int meson_pwm_calc(struct meson_pwm *meson,  		channel->lo = cnt;  	} else {  		/* Then check is we can have the duty with the same pre_div */ -		duty_cnt = DIV_ROUND_CLOSEST(duty, fin_ns * (pre_div + 1)); +		duty_cnt = DIV_ROUND_CLOSEST_ULL((u64)duty * 1000, +						 fin_ps * (pre_div + 1));  		if (duty_cnt > 0xffff) {  			dev_err(meson->chip.dev, "unable to get duty cycle\n");  			return -EINVAL;  | 

