summaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-omap-dmtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-omap-dmtimer.c')
-rw-r--r--drivers/pwm/pwm-omap-dmtimer.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 0083e75d950f..54641e45f45b 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -119,15 +119,13 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
119 fclk = omap->pdata->get_fclk(omap->dm_timer); 119 fclk = omap->pdata->get_fclk(omap->dm_timer);
120 if (!fclk) { 120 if (!fclk) {
121 dev_err(chip->dev, "invalid pmtimer fclk\n"); 121 dev_err(chip->dev, "invalid pmtimer fclk\n");
122 mutex_unlock(&omap->mutex); 122 goto err_einval;
123 return -EINVAL;
124 } 123 }
125 124
126 clk_rate = clk_get_rate(fclk); 125 clk_rate = clk_get_rate(fclk);
127 if (!clk_rate) { 126 if (!clk_rate) {
128 dev_err(chip->dev, "invalid pmtimer fclk rate\n"); 127 dev_err(chip->dev, "invalid pmtimer fclk rate\n");
129 mutex_unlock(&omap->mutex); 128 goto err_einval;
130 return -EINVAL;
131 } 129 }
132 130
133 dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate); 131 dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate);
@@ -142,6 +140,8 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
142 * The non-active time is the remainder: (DM_TIMER_MAX-match_value) 140 * The non-active time is the remainder: (DM_TIMER_MAX-match_value)
143 * clock cycles. 141 * clock cycles.
144 * 142 *
143 * NOTE: It is required that: load_value <= match_value < DM_TIMER_MAX
144 *
145 * References: 145 * References:
146 * OMAP4430/60/70 TRM sections 22.2.4.10 and 22.2.4.11 146 * OMAP4430/60/70 TRM sections 22.2.4.10 and 22.2.4.11
147 * AM335x Sitara TRM sections 20.1.3.5 and 20.1.3.6 147 * AM335x Sitara TRM sections 20.1.3.5 and 20.1.3.6
@@ -149,6 +149,27 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
149 period_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, period_ns); 149 period_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, period_ns);
150 duty_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, duty_ns); 150 duty_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, duty_ns);
151 151
152 if (period_cycles < 2) {
153 dev_info(chip->dev,
154 "period %d ns too short for clock rate %lu Hz\n",
155 period_ns, clk_rate);
156 goto err_einval;
157 }
158
159 if (duty_cycles < 1) {
160 dev_dbg(chip->dev,
161 "duty cycle %d ns is too short for clock rate %lu Hz\n",
162 duty_ns, clk_rate);
163 dev_dbg(chip->dev, "using minimum of 1 clock cycle\n");
164 duty_cycles = 1;
165 } else if (duty_cycles >= period_cycles) {
166 dev_dbg(chip->dev,
167 "duty cycle %d ns is too long for period %d ns at clock rate %lu Hz\n",
168 duty_ns, period_ns, clk_rate);
169 dev_dbg(chip->dev, "using maximum of 1 clock cycle less than period\n");
170 duty_cycles = period_cycles - 1;
171 }
172
152 load_value = (DM_TIMER_MAX - period_cycles) + 1; 173 load_value = (DM_TIMER_MAX - period_cycles) + 1;
153 match_value = load_value + duty_cycles - 1; 174 match_value = load_value + duty_cycles - 1;
154 175
@@ -179,6 +200,11 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
179 mutex_unlock(&omap->mutex); 200 mutex_unlock(&omap->mutex);
180 201
181 return 0; 202 return 0;
203
204err_einval:
205 mutex_unlock(&omap->mutex);
206
207 return -EINVAL;
182} 208}
183 209
184static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip, 210static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip,