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 | ||
