summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pwm/pwm-atmel.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 6e700a541ca3..d3c22de9ee47 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -102,7 +102,7 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
102 int duty_ns, int period_ns) 102 int duty_ns, int period_ns)
103{ 103{
104 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip); 104 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
105 unsigned long clk_rate, prd, dty; 105 unsigned long prd, dty;
106 unsigned long long div; 106 unsigned long long div;
107 unsigned int pres = 0; 107 unsigned int pres = 0;
108 u32 val; 108 u32 val;
@@ -113,20 +113,18 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
113 return -EBUSY; 113 return -EBUSY;
114 } 114 }
115 115
116 clk_rate = clk_get_rate(atmel_pwm->clk); 116 /* Calculate the period cycles and prescale value */
117 div = clk_rate; 117 div = (unsigned long long)clk_get_rate(atmel_pwm->clk) * period_ns;
118 do_div(div, NSEC_PER_SEC);
118 119
119 /* Calculate the period cycles */
120 while (div > PWM_MAX_PRD) { 120 while (div > PWM_MAX_PRD) {
121 div = clk_rate / (1 << pres); 121 div >>= 1;
122 div = div * period_ns; 122 pres++;
123 /* 1/Hz = 100000000 ns */ 123 }
124 do_div(div, 1000000000); 124
125 125 if (pres > PRD_MAX_PRES) {
126 if (pres++ > PRD_MAX_PRES) { 126 dev_err(chip->dev, "pres exceeds the maximum value\n");
127 dev_err(chip->dev, "pres exceeds the maximum value\n"); 127 return -EINVAL;
128 return -EINVAL;
129 }
130 } 128 }
131 129
132 /* Calculate the duty cycles */ 130 /* Calculate the duty cycles */