Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'pwm/for-5.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm

Pull pwm updates from Thierry Reding:
"This contains a number of nice cleanups and improvements for the core
and various drivers, as well as a minor tweak to the json-schema
device tree bindings"

* tag 'pwm/for-5.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
dt-bindings: pwm: Avoid selecting schema on node name match
pwm: img: Use only a single idiom to get a runtime PM reference
pwm: vt8500: Implement .apply() callback
pwm: img: Implement .apply() callback
pwm: twl: Implement .apply() callback
pwm: Restore initial state if a legacy callback fails
pwm: Prevent a glitch for legacy drivers
pwm: Move legacy driver handling into a dedicated function

+213 -82
+2
Documentation/devicetree/bindings/pwm/pwm.yaml
··· 9 9 maintainers: 10 10 - Thierry Reding <thierry.reding@gmail.com> 11 11 12 + select: false 13 + 12 14 properties: 13 15 $nodename: 14 16 pattern: "^pwm(@.*|-[0-9a-f])*$"
+79 -60
drivers/pwm/core.c
··· 548 548 } 549 549 } 550 550 551 + static int pwm_apply_legacy(struct pwm_chip *chip, struct pwm_device *pwm, 552 + const struct pwm_state *state) 553 + { 554 + int err; 555 + struct pwm_state initial_state = pwm->state; 556 + 557 + if (state->polarity != pwm->state.polarity) { 558 + if (!chip->ops->set_polarity) 559 + return -EINVAL; 560 + 561 + /* 562 + * Changing the polarity of a running PWM is only allowed when 563 + * the PWM driver implements ->apply(). 564 + */ 565 + if (pwm->state.enabled) { 566 + chip->ops->disable(chip, pwm); 567 + 568 + /* 569 + * Update pwm->state already here in case 570 + * .set_polarity() or another callback depend on that. 571 + */ 572 + pwm->state.enabled = false; 573 + } 574 + 575 + err = chip->ops->set_polarity(chip, pwm, state->polarity); 576 + if (err) 577 + goto rollback; 578 + 579 + pwm->state.polarity = state->polarity; 580 + } 581 + 582 + if (!state->enabled) { 583 + if (pwm->state.enabled) 584 + chip->ops->disable(chip, pwm); 585 + 586 + return 0; 587 + } 588 + 589 + /* 590 + * We cannot skip calling ->config even if state->period == 591 + * pwm->state.period && state->duty_cycle == pwm->state.duty_cycle 592 + * because we might have exited early in the last call to 593 + * pwm_apply_state because of !state->enabled and so the two values in 594 + * pwm->state might not be configured in hardware. 595 + */ 596 + err = chip->ops->config(pwm->chip, pwm, 597 + state->duty_cycle, 598 + state->period); 599 + if (err) 600 + goto rollback; 601 + 602 + pwm->state.period = state->period; 603 + pwm->state.duty_cycle = state->duty_cycle; 604 + 605 + if (!pwm->state.enabled) { 606 + err = chip->ops->enable(chip, pwm); 607 + if (err) 608 + goto rollback; 609 + } 610 + 611 + return 0; 612 + 613 + rollback: 614 + pwm->state = initial_state; 615 + return err; 616 + } 617 + 551 618 /** 552 619 * pwm_apply_state() - atomically apply a new state to a PWM device 553 620 * @pwm: PWM device ··· 647 580 state->usage_power == pwm->state.usage_power) 648 581 return 0; 649 582 650 - if (chip->ops->apply) { 583 + if (chip->ops->apply) 651 584 err = chip->ops->apply(chip, pwm, state); 652 - if (err) 653 - return err; 585 + else 586 + err = pwm_apply_legacy(chip, pwm, state); 587 + if (err) 588 + return err; 654 589 655 - trace_pwm_apply(pwm, state); 590 + trace_pwm_apply(pwm, state); 656 591 657 - pwm->state = *state; 592 + pwm->state = *state; 658 593 659 - /* 660 - * only do this after pwm->state was applied as some 661 - * implementations of .get_state depend on this 662 - */ 663 - pwm_apply_state_debug(pwm, state); 664 - } else { 665 - /* 666 - * FIXME: restore the initial state in case of error. 667 - */ 668 - if (state->polarity != pwm->state.polarity) { 669 - if (!chip->ops->set_polarity) 670 - return -EINVAL; 671 - 672 - /* 673 - * Changing the polarity of a running PWM is 674 - * only allowed when the PWM driver implements 675 - * ->apply(). 676 - */ 677 - if (pwm->state.enabled) { 678 - chip->ops->disable(chip, pwm); 679 - pwm->state.enabled = false; 680 - } 681 - 682 - err = chip->ops->set_polarity(chip, pwm, 683 - state->polarity); 684 - if (err) 685 - return err; 686 - 687 - pwm->state.polarity = state->polarity; 688 - } 689 - 690 - if (state->period != pwm->state.period || 691 - state->duty_cycle != pwm->state.duty_cycle) { 692 - err = chip->ops->config(pwm->chip, pwm, 693 - state->duty_cycle, 694 - state->period); 695 - if (err) 696 - return err; 697 - 698 - pwm->state.duty_cycle = state->duty_cycle; 699 - pwm->state.period = state->period; 700 - } 701 - 702 - if (state->enabled != pwm->state.enabled) { 703 - if (state->enabled) { 704 - err = chip->ops->enable(chip, pwm); 705 - if (err) 706 - return err; 707 - } else { 708 - chip->ops->disable(chip, pwm); 709 - } 710 - 711 - pwm->state.enabled = state->enabled; 712 - } 713 - } 594 + /* 595 + * only do this after pwm->state was applied as some 596 + * implementations of .get_state depend on this 597 + */ 598 + pwm_apply_state_debug(pwm, state); 714 599 715 600 return 0; 716 601 }
+28 -7
drivers/pwm/pwm-img.c
··· 128 128 129 129 duty = DIV_ROUND_UP(timebase * duty_ns, period_ns); 130 130 131 - ret = pm_runtime_get_sync(chip->dev); 132 - if (ret < 0) { 133 - pm_runtime_put_autosuspend(chip->dev); 131 + ret = pm_runtime_resume_and_get(chip->dev); 132 + if (ret < 0) 134 133 return ret; 135 - } 136 134 137 135 val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG); 138 136 val &= ~(PWM_CTRL_CFG_DIV_MASK << PWM_CTRL_CFG_DIV_SHIFT(pwm->hwpwm)); ··· 182 184 pm_runtime_put_autosuspend(chip->dev); 183 185 } 184 186 187 + static int img_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 188 + const struct pwm_state *state) 189 + { 190 + int err; 191 + 192 + if (state->polarity != PWM_POLARITY_NORMAL) 193 + return -EINVAL; 194 + 195 + if (!state->enabled) { 196 + if (pwm->state.enabled) 197 + img_pwm_disable(chip, pwm); 198 + 199 + return 0; 200 + } 201 + 202 + err = img_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); 203 + if (err) 204 + return err; 205 + 206 + if (!pwm->state.enabled) 207 + err = img_pwm_enable(chip, pwm); 208 + 209 + return err; 210 + } 211 + 185 212 static const struct pwm_ops img_pwm_ops = { 186 - .config = img_pwm_config, 187 - .enable = img_pwm_enable, 188 - .disable = img_pwm_disable, 213 + .apply = img_pwm_apply, 189 214 .owner = THIS_MODULE, 190 215 }; 191 216
+54 -8
drivers/pwm/pwm-twl.c
··· 58 58 } 59 59 60 60 static int twl_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 61 - int duty_ns, int period_ns) 61 + u64 duty_ns, u64 period_ns) 62 62 { 63 - int duty_cycle = DIV_ROUND_UP(duty_ns * TWL_PWM_MAX, period_ns) + 1; 63 + int duty_cycle = DIV64_U64_ROUND_UP(duty_ns * TWL_PWM_MAX, period_ns) + 1; 64 64 u8 pwm_config[2] = { 1, 0 }; 65 65 int base, ret; 66 66 ··· 279 279 mutex_unlock(&twl->mutex); 280 280 } 281 281 282 + static int twl4030_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 283 + const struct pwm_state *state) 284 + { 285 + int err; 286 + 287 + if (state->polarity != PWM_POLARITY_NORMAL) 288 + return -EINVAL; 289 + 290 + if (!state->enabled) { 291 + if (pwm->state.enabled) 292 + twl4030_pwm_disable(chip, pwm); 293 + 294 + return 0; 295 + } 296 + 297 + err = twl_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); 298 + if (err) 299 + return err; 300 + 301 + if (!pwm->state.enabled) 302 + err = twl4030_pwm_enable(chip, pwm); 303 + 304 + return err; 305 + } 306 + 307 + static int twl6030_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 308 + const struct pwm_state *state) 309 + { 310 + int err; 311 + 312 + if (state->polarity != PWM_POLARITY_NORMAL) 313 + return -EINVAL; 314 + 315 + if (!state->enabled) { 316 + if (pwm->state.enabled) 317 + twl6030_pwm_disable(chip, pwm); 318 + 319 + return 0; 320 + } 321 + 322 + err = twl_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); 323 + if (err) 324 + return err; 325 + 326 + if (!pwm->state.enabled) 327 + err = twl6030_pwm_enable(chip, pwm); 328 + 329 + return err; 330 + } 331 + 282 332 static const struct pwm_ops twl4030_pwm_ops = { 283 - .config = twl_pwm_config, 284 - .enable = twl4030_pwm_enable, 285 - .disable = twl4030_pwm_disable, 333 + .apply = twl4030_pwm_apply, 286 334 .request = twl4030_pwm_request, 287 335 .free = twl4030_pwm_free, 288 336 .owner = THIS_MODULE, 289 337 }; 290 338 291 339 static const struct pwm_ops twl6030_pwm_ops = { 292 - .config = twl_pwm_config, 293 - .enable = twl6030_pwm_enable, 294 - .disable = twl6030_pwm_disable, 340 + .apply = twl6030_pwm_apply, 295 341 .owner = THIS_MODULE, 296 342 }; 297 343
+50 -7
drivers/pwm/pwm-vt8500.c
··· 70 70 } 71 71 72 72 static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 73 - int duty_ns, int period_ns) 73 + u64 duty_ns, u64 period_ns) 74 74 { 75 75 struct vt8500_chip *vt8500 = to_vt8500_chip(chip); 76 76 unsigned long long c; ··· 102 102 } 103 103 104 104 c = (unsigned long long)pv * duty_ns; 105 - do_div(c, period_ns); 106 - dc = c; 105 + 106 + dc = div64_u64(c, period_ns); 107 107 108 108 writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm)); 109 109 vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE); ··· 176 176 return 0; 177 177 } 178 178 179 + static int vt8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 180 + const struct pwm_state *state) 181 + { 182 + int err; 183 + bool enabled = pwm->state.enabled; 184 + 185 + if (state->polarity != pwm->state.polarity) { 186 + /* 187 + * Changing the polarity of a running PWM is only allowed when 188 + * the PWM driver implements ->apply(). 189 + */ 190 + if (enabled) { 191 + vt8500_pwm_disable(chip, pwm); 192 + 193 + enabled = false; 194 + } 195 + 196 + err = vt8500_pwm_set_polarity(chip, pwm, state->polarity); 197 + if (err) 198 + return err; 199 + } 200 + 201 + if (!state->enabled) { 202 + if (enabled) 203 + vt8500_pwm_disable(chip, pwm); 204 + 205 + return 0; 206 + } 207 + 208 + /* 209 + * We cannot skip calling ->config even if state->period == 210 + * pwm->state.period && state->duty_cycle == pwm->state.duty_cycle 211 + * because we might have exited early in the last call to 212 + * pwm_apply_state because of !state->enabled and so the two values in 213 + * pwm->state might not be configured in hardware. 214 + */ 215 + err = vt8500_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); 216 + if (err) 217 + return err; 218 + 219 + if (!enabled) 220 + err = vt8500_pwm_enable(chip, pwm); 221 + 222 + return err; 223 + } 224 + 179 225 static const struct pwm_ops vt8500_pwm_ops = { 180 - .enable = vt8500_pwm_enable, 181 - .disable = vt8500_pwm_disable, 182 - .config = vt8500_pwm_config, 183 - .set_polarity = vt8500_pwm_set_polarity, 226 + .apply = vt8500_pwm_apply, 184 227 .owner = THIS_MODULE, 185 228 }; 186 229