@@ -84,9 +84,19 @@ struct atmel_pwm_chip {
8484 void __iomem * base ;
8585 const struct atmel_pwm_data * data ;
8686
87- unsigned int updated_pwms ;
88- /* ISR is cleared when read, ensure only one thread does that */
89- struct mutex isr_lock ;
87+ /*
88+ * The hardware supports a mechanism to update a channel's duty cycle at
89+ * the end of the currently running period. When such an update is
90+ * pending we delay disabling the PWM until the new configuration is
91+ * active because otherwise pmw_config(duty_cycle=0); pwm_disable();
92+ * might not result in an inactive output.
93+ * This bitmask tracks for which channels an update is pending in
94+ * hardware.
95+ */
96+ u32 update_pending ;
97+
98+ /* Protects .update_pending */
99+ spinlock_t lock ;
90100};
91101
92102static inline struct atmel_pwm_chip * to_atmel_pwm_chip (struct pwm_chip * chip )
@@ -123,6 +133,64 @@ static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip,
123133 atmel_pwm_writel (chip , base + offset , val );
124134}
125135
136+ static void atmel_pwm_update_pending (struct atmel_pwm_chip * chip )
137+ {
138+ /*
139+ * Each channel that has its bit in ISR set started a new period since
140+ * ISR was cleared and so there is no more update pending. Note that
141+ * reading ISR clears it, so this needs to handle all channels to not
142+ * loose information.
143+ */
144+ u32 isr = atmel_pwm_readl (chip , PWM_ISR );
145+
146+ chip -> update_pending &= ~isr ;
147+ }
148+
149+ static void atmel_pwm_set_pending (struct atmel_pwm_chip * chip , unsigned int ch )
150+ {
151+ spin_lock (& chip -> lock );
152+
153+ /*
154+ * Clear pending flags in hardware because otherwise there might still
155+ * be a stale flag in ISR.
156+ */
157+ atmel_pwm_update_pending (chip );
158+
159+ chip -> update_pending |= (1 << ch );
160+
161+ spin_unlock (& chip -> lock );
162+ }
163+
164+ static int atmel_pwm_test_pending (struct atmel_pwm_chip * chip , unsigned int ch )
165+ {
166+ int ret = 0 ;
167+
168+ spin_lock (& chip -> lock );
169+
170+ if (chip -> update_pending & (1 << ch )) {
171+ atmel_pwm_update_pending (chip );
172+
173+ if (chip -> update_pending & (1 << ch ))
174+ ret = 1 ;
175+ }
176+
177+ spin_unlock (& chip -> lock );
178+
179+ return ret ;
180+ }
181+
182+ static int atmel_pwm_wait_nonpending (struct atmel_pwm_chip * chip , unsigned int ch )
183+ {
184+ unsigned long timeout = jiffies + 2 * HZ ;
185+ int ret ;
186+
187+ while ((ret = atmel_pwm_test_pending (chip , ch )) &&
188+ time_before (jiffies , timeout ))
189+ usleep_range (10 , 100 );
190+
191+ return ret ? - ETIMEDOUT : 0 ;
192+ }
193+
126194static int atmel_pwm_calculate_cprd_and_pres (struct pwm_chip * chip ,
127195 unsigned long clkrate ,
128196 const struct pwm_state * state ,
@@ -185,6 +253,7 @@ static void atmel_pwm_update_cdty(struct pwm_chip *chip, struct pwm_device *pwm,
185253
186254 atmel_pwm_ch_writel (atmel_pwm , pwm -> hwpwm ,
187255 atmel_pwm -> data -> regs .duty_upd , cdty );
256+ atmel_pwm_set_pending (atmel_pwm , pwm -> hwpwm );
188257}
189258
190259static void atmel_pwm_set_cprd_cdty (struct pwm_chip * chip ,
@@ -205,20 +274,8 @@ static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm,
205274 struct atmel_pwm_chip * atmel_pwm = to_atmel_pwm_chip (chip );
206275 unsigned long timeout = jiffies + 2 * HZ ;
207276
208- /*
209- * Wait for at least a complete period to have passed before disabling a
210- * channel to be sure that CDTY has been updated
211- */
212- mutex_lock (& atmel_pwm -> isr_lock );
213- atmel_pwm -> updated_pwms |= atmel_pwm_readl (atmel_pwm , PWM_ISR );
214-
215- while (!(atmel_pwm -> updated_pwms & (1 << pwm -> hwpwm )) &&
216- time_before (jiffies , timeout )) {
217- usleep_range (10 , 100 );
218- atmel_pwm -> updated_pwms |= atmel_pwm_readl (atmel_pwm , PWM_ISR );
219- }
277+ atmel_pwm_wait_nonpending (atmel_pwm , pwm -> hwpwm );
220278
221- mutex_unlock (& atmel_pwm -> isr_lock );
222279 atmel_pwm_writel (atmel_pwm , PWM_DIS , 1 << pwm -> hwpwm );
223280
224281 /*
@@ -292,10 +349,6 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
292349 val |= PWM_CMR_CPOL ;
293350 atmel_pwm_ch_writel (atmel_pwm , pwm -> hwpwm , PWM_CMR , val );
294351 atmel_pwm_set_cprd_cdty (chip , pwm , cprd , cdty );
295- mutex_lock (& atmel_pwm -> isr_lock );
296- atmel_pwm -> updated_pwms |= atmel_pwm_readl (atmel_pwm , PWM_ISR );
297- atmel_pwm -> updated_pwms &= ~(1 << pwm -> hwpwm );
298- mutex_unlock (& atmel_pwm -> isr_lock );
299352 atmel_pwm_writel (atmel_pwm , PWM_ENA , 1 << pwm -> hwpwm );
300353 } else if (cstate .enabled ) {
301354 atmel_pwm_disable (chip , pwm , true);
@@ -326,6 +379,9 @@ static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
326379 tmp <<= pres ;
327380 state -> period = DIV64_U64_ROUND_UP (tmp , rate );
328381
382+ /* Wait for an updated duty_cycle queued in hardware */
383+ atmel_pwm_wait_nonpending (atmel_pwm , pwm -> hwpwm );
384+
329385 cdty = atmel_pwm_ch_readl (atmel_pwm , pwm -> hwpwm ,
330386 atmel_pwm -> data -> regs .duty );
331387 tmp = (u64 )(cprd - cdty ) * NSEC_PER_SEC ;
@@ -416,9 +472,10 @@ static int atmel_pwm_probe(struct platform_device *pdev)
416472 if (!atmel_pwm )
417473 return - ENOMEM ;
418474
419- mutex_init (& atmel_pwm -> isr_lock );
420475 atmel_pwm -> data = of_device_get_match_data (& pdev -> dev );
421- atmel_pwm -> updated_pwms = 0 ;
476+
477+ atmel_pwm -> update_pending = 0 ;
478+ spin_lock_init (& atmel_pwm -> lock );
422479
423480 atmel_pwm -> base = devm_platform_ioremap_resource (pdev , 0 );
424481 if (IS_ERR (atmel_pwm -> base ))
@@ -460,7 +517,6 @@ static int atmel_pwm_remove(struct platform_device *pdev)
460517 pwmchip_remove (& atmel_pwm -> chip );
461518
462519 clk_unprepare (atmel_pwm -> clk );
463- mutex_destroy (& atmel_pwm -> isr_lock );
464520
465521 return 0 ;
466522}
0 commit comments