diff options
-rw-r--r-- | drivers/pwm/pwm-atmel.c | 24 |
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 */ |