aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-atmel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-atmel.c')
-rw-r--r--drivers/pwm/pwm-atmel.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 0e4bd4e8e582..e6b8b1b7e6ba 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -64,7 +64,8 @@ struct atmel_pwm_chip {
void __iomem *base;
unsigned int updated_pwms;
- struct mutex isr_lock; /* ISR is cleared when read, ensure only one thread does that */
+ /* ISR is cleared when read, ensure only one thread does that */
+ struct mutex isr_lock;
void (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long dty, unsigned long prd);
@@ -271,6 +272,16 @@ static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
mutex_unlock(&atmel_pwm->isr_lock);
atmel_pwm_writel(atmel_pwm, PWM_DIS, 1 << pwm->hwpwm);
+ /*
+ * Wait for the PWM channel disable operation to be effective before
+ * stopping the clock.
+ */
+ timeout = jiffies + 2 * HZ;
+
+ while ((atmel_pwm_readl(atmel_pwm, PWM_SR) & (1 << pwm->hwpwm)) &&
+ time_before(jiffies, timeout))
+ usleep_range(10, 100);
+
clk_disable(atmel_pwm->clk);
}
@@ -324,21 +335,14 @@ MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids);
static inline const struct atmel_pwm_data *
atmel_pwm_get_driver_data(struct platform_device *pdev)
{
- if (pdev->dev.of_node) {
- const struct of_device_id *match;
-
- match = of_match_device(atmel_pwm_dt_ids, &pdev->dev);
- if (!match)
- return NULL;
+ const struct platform_device_id *id;
- return match->data;
- } else {
- const struct platform_device_id *id;
+ if (pdev->dev.of_node)
+ return of_device_get_match_data(&pdev->dev);
- id = platform_get_device_id(pdev);
+ id = platform_get_device_id(pdev);
- return (struct atmel_pwm_data *)id->driver_data;
- }
+ return (struct atmel_pwm_data *)id->driver_data;
}
static int atmel_pwm_probe(struct platform_device *pdev)