diff options
-rw-r--r-- | drivers/pwm/pwm-sti.c | 30 |
1 files changed, 11 insertions, 19 deletions
diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c index b95115cdaea7..92abbd56b9f7 100644 --- a/drivers/pwm/pwm-sti.c +++ b/drivers/pwm/pwm-sti.c | |||
@@ -57,6 +57,7 @@ struct sti_pwm_chip { | |||
57 | struct regmap_field *pwm_int_en; | 57 | struct regmap_field *pwm_int_en; |
58 | struct pwm_chip chip; | 58 | struct pwm_chip chip; |
59 | struct pwm_device *cur; | 59 | struct pwm_device *cur; |
60 | unsigned long configured; | ||
60 | unsigned int en_count; | 61 | unsigned int en_count; |
61 | struct mutex sti_pwm_lock; /* To sync between enable/disable calls */ | 62 | struct mutex sti_pwm_lock; /* To sync between enable/disable calls */ |
62 | void __iomem *mmio; | 63 | void __iomem *mmio; |
@@ -102,24 +103,6 @@ static int sti_pwm_get_prescale(struct sti_pwm_chip *pc, unsigned long period, | |||
102 | return 0; | 103 | return 0; |
103 | } | 104 | } |
104 | 105 | ||
105 | /* Calculate the number of PWM devices configured with a period. */ | ||
106 | static unsigned int sti_pwm_count_configured(struct pwm_chip *chip) | ||
107 | { | ||
108 | struct pwm_device *pwm; | ||
109 | unsigned int ncfg = 0; | ||
110 | unsigned int i; | ||
111 | |||
112 | for (i = 0; i < chip->npwm; i++) { | ||
113 | pwm = &chip->pwms[i]; | ||
114 | if (test_bit(PWMF_REQUESTED, &pwm->flags)) { | ||
115 | if (pwm_get_period(pwm)) | ||
116 | ncfg++; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | return ncfg; | ||
121 | } | ||
122 | |||
123 | /* | 106 | /* |
124 | * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. | 107 | * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. |
125 | * The only way to change the period (apart from changing the PWM input clock) | 108 | * The only way to change the period (apart from changing the PWM input clock) |
@@ -141,7 +124,7 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
141 | unsigned int ncfg; | 124 | unsigned int ncfg; |
142 | bool period_same = false; | 125 | bool period_same = false; |
143 | 126 | ||
144 | ncfg = sti_pwm_count_configured(chip); | 127 | ncfg = hweight_long(pc->configured); |
145 | if (ncfg) | 128 | if (ncfg) |
146 | period_same = (period_ns == pwm_get_period(cur)); | 129 | period_same = (period_ns == pwm_get_period(cur)); |
147 | 130 | ||
@@ -197,6 +180,7 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
197 | 180 | ||
198 | ret = regmap_field_write(pc->pwm_int_en, 0); | 181 | ret = regmap_field_write(pc->pwm_int_en, 0); |
199 | 182 | ||
183 | set_bit(pwm->hwpwm, &pc->configured); | ||
200 | pc->cur = pwm; | 184 | pc->cur = pwm; |
201 | 185 | ||
202 | dev_dbg(dev, "prescale:%u, period:%i, duty:%i, pwmvalx:%u\n", | 186 | dev_dbg(dev, "prescale:%u, period:%i, duty:%i, pwmvalx:%u\n", |
@@ -254,10 +238,18 @@ static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
254 | mutex_unlock(&pc->sti_pwm_lock); | 238 | mutex_unlock(&pc->sti_pwm_lock); |
255 | } | 239 | } |
256 | 240 | ||
241 | static void sti_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) | ||
242 | { | ||
243 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); | ||
244 | |||
245 | clear_bit(pwm->hwpwm, &pc->configured); | ||
246 | } | ||
247 | |||
257 | static const struct pwm_ops sti_pwm_ops = { | 248 | static const struct pwm_ops sti_pwm_ops = { |
258 | .config = sti_pwm_config, | 249 | .config = sti_pwm_config, |
259 | .enable = sti_pwm_enable, | 250 | .enable = sti_pwm_enable, |
260 | .disable = sti_pwm_disable, | 251 | .disable = sti_pwm_disable, |
252 | .free = sti_pwm_free, | ||
261 | .owner = THIS_MODULE, | 253 | .owner = THIS_MODULE, |
262 | }; | 254 | }; |
263 | 255 | ||