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

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

Pull pwm updates from Thierry Reding:
"This set of changes introduces an atomic API to the PWM subsystem.
This is influenced by the DRM atomic API that was introduced a while
back, though it is obviously a lot simpler. The fundamental idea
remains the same, though: drivers provide a single callback to
implement the atomic configuration of a PWM channel.

As a side-effect the PWM subsystem gains the ability for initial state
retrieval, so that the logical state mirrors that of the hardware.
Many use-cases don't care about this, but for others it is essential.

These new features require changes in all users, which these patches
take care of. The core is transitioned to use the atomic callback if
available and provides a fallback mechanism for other drivers.

Changes to transition users and drivers to the atomic API are
postponed to v4.8"

* tag 'pwm/for-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (30 commits)
pwm: Add information about polarity, duty cycle and period to debugfs
pwm: Switch to the atomic API
pwm: Update documentation
pwm: Add core infrastructure to allow atomic updates
pwm: Add hardware readout infrastructure
pwm: Move the enabled/disabled info into pwm_state
pwm: Introduce the pwm_state concept
pwm: Keep PWM state in sync with hardware state
ARM: Explicitly apply PWM config extracted from pwm_args
drm: i915: Explicitly apply PWM config extracted from pwm_args
input: misc: pwm-beeper: Explicitly apply PWM config extracted from pwm_args
input: misc: max8997: Explicitly apply PWM config extracted from pwm_args
backlight: lm3630a: explicitly apply PWM config extracted from pwm_args
backlight: lp855x: Explicitly apply PWM config extracted from pwm_args
backlight: lp8788: Explicitly apply PWM config extracted from pwm_args
backlight: pwm_bl: Use pwm_get_args() where appropriate
fbdev: ssd1307fb: Use pwm_get_args() where appropriate
regulator: pwm: Use pwm_get_args() where appropriate
leds: pwm: Use pwm_get_args() where appropriate
input: misc: max77693: Use pwm_get_args() where appropriate
...

+596 -221
+28 -2
Documentation/pwm.txt
··· 42 42 43 43 After being requested, a PWM has to be configured using: 44 44 45 - int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns); 45 + int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state); 46 46 47 - To start/stop toggling the PWM output use pwm_enable()/pwm_disable(). 47 + This API controls both the PWM period/duty_cycle config and the 48 + enable/disable state. 49 + 50 + The pwm_config(), pwm_enable() and pwm_disable() functions are just wrappers 51 + around pwm_apply_state() and should not be used if the user wants to change 52 + several parameter at once. For example, if you see pwm_config() and 53 + pwm_{enable,disable}() calls in the same function, this probably means you 54 + should switch to pwm_apply_state(). 55 + 56 + The PWM user API also allows one to query the PWM state with pwm_get_state(). 57 + 58 + In addition to the PWM state, the PWM API also exposes PWM arguments, which 59 + are the reference PWM config one should use on this PWM. 60 + PWM arguments are usually platform-specific and allows the PWM user to only 61 + care about dutycycle relatively to the full period (like, duty = 50% of the 62 + period). struct pwm_args contains 2 fields (period and polarity) and should 63 + be used to set the initial PWM config (usually done in the probe function 64 + of the PWM user). PWM arguments are retrieved with pwm_get_args(). 48 65 49 66 Using PWMs with the sysfs interface 50 67 ----------------------------------- ··· 121 104 goes low for the remainder of the period. Conversely, a signal with inversed 122 105 polarity starts low for the duration of the duty cycle and goes high for the 123 106 remainder of the period. 107 + 108 + Drivers are encouraged to implement ->apply() instead of the legacy 109 + ->enable(), ->disable() and ->config() methods. Doing that should provide 110 + atomicity in the PWM config workflow, which is required when the PWM controls 111 + a critical device (like a regulator). 112 + 113 + The implementation of ->get_state() (a method used to retrieve initial PWM 114 + state) is also encouraged for the same reason: letting the PWM user know 115 + about the current PWM state would allow him to avoid glitches. 124 116 125 117 Locking 126 118 -------
+6
arch/arm/mach-s3c24xx/mach-rx1950.c
··· 496 496 return PTR_ERR(lcd_pwm); 497 497 } 498 498 499 + /* 500 + * FIXME: pwm_apply_args() should be removed when switching to 501 + * the atomic PWM API. 502 + */ 503 + pwm_apply_args(lcd_pwm); 504 + 499 505 rx1950_lcd_power(1); 500 506 rx1950_bl_power(1); 501 507
+12 -5
drivers/clk/clk-pwm.c
··· 59 59 struct clk_init_data init; 60 60 struct clk_pwm *clk_pwm; 61 61 struct pwm_device *pwm; 62 + struct pwm_args pargs; 62 63 const char *clk_name; 63 64 struct clk *clk; 64 65 int ret; ··· 72 71 if (IS_ERR(pwm)) 73 72 return PTR_ERR(pwm); 74 73 75 - if (!pwm->period) { 74 + pwm_get_args(pwm, &pargs); 75 + if (!pargs.period) { 76 76 dev_err(&pdev->dev, "invalid PWM period\n"); 77 77 return -EINVAL; 78 78 } 79 79 80 80 if (of_property_read_u32(node, "clock-frequency", &clk_pwm->fixed_rate)) 81 - clk_pwm->fixed_rate = NSEC_PER_SEC / pwm->period; 81 + clk_pwm->fixed_rate = NSEC_PER_SEC / pargs.period; 82 82 83 - if (pwm->period != NSEC_PER_SEC / clk_pwm->fixed_rate && 84 - pwm->period != DIV_ROUND_UP(NSEC_PER_SEC, clk_pwm->fixed_rate)) { 83 + if (pargs.period != NSEC_PER_SEC / clk_pwm->fixed_rate && 84 + pargs.period != DIV_ROUND_UP(NSEC_PER_SEC, clk_pwm->fixed_rate)) { 85 85 dev_err(&pdev->dev, 86 86 "clock-frequency does not match PWM period\n"); 87 87 return -EINVAL; 88 88 } 89 89 90 - ret = pwm_config(pwm, (pwm->period + 1) >> 1, pwm->period); 90 + /* 91 + * FIXME: pwm_apply_args() should be removed when switching to the 92 + * atomic PWM API. 93 + */ 94 + pwm_apply_args(pwm); 95 + ret = pwm_config(pwm, (pargs.period + 1) >> 1, pargs.period); 91 96 if (ret < 0) 92 97 return ret; 93 98
+6
drivers/gpu/drm/i915/intel_panel.c
··· 1638 1638 return -ENODEV; 1639 1639 } 1640 1640 1641 + /* 1642 + * FIXME: pwm_apply_args() should be removed when switching to 1643 + * the atomic PWM API. 1644 + */ 1645 + pwm_apply_args(panel->backlight.pwm); 1646 + 1641 1647 retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS, 1642 1648 CRC_PMIC_PWM_PERIOD_NS); 1643 1649 if (retval < 0) {
+20 -6
drivers/hwmon/pwm-fan.c
··· 40 40 41 41 static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) 42 42 { 43 + struct pwm_args pargs; 43 44 unsigned long duty; 44 45 int ret = 0; 46 + 47 + pwm_get_args(ctx->pwm, &pargs); 45 48 46 49 mutex_lock(&ctx->lock); 47 50 if (ctx->pwm_value == pwm) 48 51 goto exit_set_pwm_err; 49 52 50 - duty = DIV_ROUND_UP(pwm * (ctx->pwm->period - 1), MAX_PWM); 51 - ret = pwm_config(ctx->pwm, duty, ctx->pwm->period); 53 + duty = DIV_ROUND_UP(pwm * (pargs.period - 1), MAX_PWM); 54 + ret = pwm_config(ctx->pwm, duty, pargs.period); 52 55 if (ret) 53 56 goto exit_set_pwm_err; 54 57 ··· 218 215 { 219 216 struct thermal_cooling_device *cdev; 220 217 struct pwm_fan_ctx *ctx; 218 + struct pwm_args pargs; 221 219 struct device *hwmon; 222 220 int duty_cycle; 223 221 int ret; ··· 237 233 238 234 platform_set_drvdata(pdev, ctx); 239 235 236 + /* 237 + * FIXME: pwm_apply_args() should be removed when switching to the 238 + * atomic PWM API. 239 + */ 240 + pwm_apply_args(ctx->pwm); 241 + 240 242 /* Set duty cycle to maximum allowed */ 241 - duty_cycle = ctx->pwm->period - 1; 243 + pwm_get_args(ctx->pwm, &pargs); 244 + 245 + duty_cycle = pargs.period - 1; 242 246 ctx->pwm_value = MAX_PWM; 243 247 244 - ret = pwm_config(ctx->pwm, duty_cycle, ctx->pwm->period); 248 + ret = pwm_config(ctx->pwm, duty_cycle, pargs.period); 245 249 if (ret) { 246 250 dev_err(&pdev->dev, "Failed to configure PWM\n"); 247 251 return ret; ··· 315 303 static int pwm_fan_resume(struct device *dev) 316 304 { 317 305 struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); 306 + struct pwm_args pargs; 318 307 unsigned long duty; 319 308 int ret; 320 309 321 310 if (ctx->pwm_value == 0) 322 311 return 0; 323 312 324 - duty = DIV_ROUND_UP(ctx->pwm_value * (ctx->pwm->period - 1), MAX_PWM); 325 - ret = pwm_config(ctx->pwm, duty, ctx->pwm->period); 313 + pwm_get_args(ctx->pwm, &pargs); 314 + duty = DIV_ROUND_UP(ctx->pwm_value * (pargs.period - 1), MAX_PWM); 315 + ret = pwm_config(ctx->pwm, duty, pargs.period); 326 316 if (ret) 327 317 return ret; 328 318 return pwm_enable(ctx->pwm);
+14 -3
drivers/input/misc/max77693-haptic.c
··· 70 70 71 71 static int max77693_haptic_set_duty_cycle(struct max77693_haptic *haptic) 72 72 { 73 - int delta = (haptic->pwm_dev->period + haptic->pwm_duty) / 2; 73 + struct pwm_args pargs; 74 + int delta; 74 75 int error; 75 76 76 - error = pwm_config(haptic->pwm_dev, delta, haptic->pwm_dev->period); 77 + pwm_get_args(haptic->pwm_dev, &pargs); 78 + delta = (pargs.period + haptic->pwm_duty) / 2; 79 + error = pwm_config(haptic->pwm_dev, delta, pargs.period); 77 80 if (error) { 78 81 dev_err(haptic->dev, "failed to configure pwm: %d\n", error); 79 82 return error; ··· 237 234 struct ff_effect *effect) 238 235 { 239 236 struct max77693_haptic *haptic = input_get_drvdata(dev); 237 + struct pwm_args pargs; 240 238 u64 period_mag_multi; 241 239 242 240 haptic->magnitude = effect->u.rumble.strong_magnitude; ··· 249 245 * The formula to convert magnitude to pwm_duty as follows: 250 246 * - pwm_duty = (magnitude * pwm_period) / MAX_MAGNITUDE(0xFFFF) 251 247 */ 252 - period_mag_multi = (u64)haptic->pwm_dev->period * haptic->magnitude; 248 + pwm_get_args(haptic->pwm_dev, &pargs); 249 + period_mag_multi = (u64)pargs.period * haptic->magnitude; 253 250 haptic->pwm_duty = (unsigned int)(period_mag_multi >> 254 251 MAX_MAGNITUDE_SHIFT); 255 252 ··· 333 328 dev_err(&pdev->dev, "failed to get pwm device\n"); 334 329 return PTR_ERR(haptic->pwm_dev); 335 330 } 331 + 332 + /* 333 + * FIXME: pwm_apply_args() should be removed when switching to the 334 + * atomic PWM API. 335 + */ 336 + pwm_apply_args(haptic->pwm_dev); 336 337 337 338 haptic->motor_reg = devm_regulator_get(&pdev->dev, "haptic"); 338 339 if (IS_ERR(haptic->motor_reg)) {
+6
drivers/input/misc/max8997_haptic.c
··· 306 306 error); 307 307 goto err_free_mem; 308 308 } 309 + 310 + /* 311 + * FIXME: pwm_apply_args() should be removed when switching to 312 + * the atomic PWM API. 313 + */ 314 + pwm_apply_args(chip->pwm); 309 315 break; 310 316 311 317 default:
+6
drivers/input/misc/pwm-beeper.c
··· 87 87 goto err_free; 88 88 } 89 89 90 + /* 91 + * FIXME: pwm_apply_args() should be removed when switching to 92 + * the atomic PWM API. 93 + */ 94 + pwm_apply_args(beeper->pwm); 95 + 90 96 beeper->input = input_allocate_device(); 91 97 if (!beeper->input) { 92 98 dev_err(&pdev->dev, "Failed to allocate input device\n");
+10 -1
drivers/leds/leds-pwm.c
··· 91 91 struct led_pwm *led, struct device_node *child) 92 92 { 93 93 struct led_pwm_data *led_data = &priv->leds[priv->num_leds]; 94 + struct pwm_args pargs; 94 95 int ret; 95 96 96 97 led_data->active_low = led->active_low; ··· 118 117 else 119 118 led_data->cdev.brightness_set_blocking = led_pwm_set_blocking; 120 119 121 - led_data->period = pwm_get_period(led_data->pwm); 120 + /* 121 + * FIXME: pwm_apply_args() should be removed when switching to the 122 + * atomic PWM API. 123 + */ 124 + pwm_apply_args(led_data->pwm); 125 + 126 + pwm_get_args(led_data->pwm, &pargs); 127 + 128 + led_data->period = pargs.period; 122 129 if (!led_data->period && (led->pwm_period_ns > 0)) 123 130 led_data->period = led->pwm_period_ns; 124 131
+148 -98
drivers/pwm/core.c
··· 75 75 76 76 for (i = 0; i < chip->npwm; i++) { 77 77 struct pwm_device *pwm = &chip->pwms[i]; 78 + 78 79 radix_tree_delete(&pwm_tree, pwm->pwm); 79 80 } 80 81 ··· 128 127 129 128 set_bit(PWMF_REQUESTED, &pwm->flags); 130 129 pwm->label = label; 131 - 132 - /* 133 - * FIXME: This should be removed once all PWM users properly make use 134 - * of struct pwm_args to initialize the PWM device. As long as this is 135 - * here, the PWM state and hardware state can get out of sync. 136 - */ 137 - pwm_apply_args(pwm); 138 130 139 131 return 0; 140 132 } ··· 227 233 } 228 234 EXPORT_SYMBOL_GPL(pwm_get_chip_data); 229 235 236 + static bool pwm_ops_check(const struct pwm_ops *ops) 237 + { 238 + /* driver supports legacy, non-atomic operation */ 239 + if (ops->config && ops->enable && ops->disable) 240 + return true; 241 + 242 + /* driver supports atomic operation */ 243 + if (ops->apply) 244 + return true; 245 + 246 + return false; 247 + } 248 + 230 249 /** 231 250 * pwmchip_add_with_polarity() - register a new PWM chip 232 251 * @chip: the PWM chip to add ··· 258 251 unsigned int i; 259 252 int ret; 260 253 261 - if (!chip || !chip->dev || !chip->ops || !chip->ops->config || 262 - !chip->ops->enable || !chip->ops->disable || !chip->npwm) 254 + if (!chip || !chip->dev || !chip->ops || !chip->npwm) 255 + return -EINVAL; 256 + 257 + if (!pwm_ops_check(chip->ops)) 263 258 return -EINVAL; 264 259 265 260 mutex_lock(&pwm_lock); ··· 270 261 if (ret < 0) 271 262 goto out; 272 263 273 - chip->pwms = kzalloc(chip->npwm * sizeof(*pwm), GFP_KERNEL); 264 + chip->pwms = kcalloc(chip->npwm, sizeof(*pwm), GFP_KERNEL); 274 265 if (!chip->pwms) { 275 266 ret = -ENOMEM; 276 267 goto out; ··· 284 275 pwm->chip = chip; 285 276 pwm->pwm = chip->base + i; 286 277 pwm->hwpwm = i; 287 - pwm->polarity = polarity; 288 - mutex_init(&pwm->lock); 278 + pwm->state.polarity = polarity; 279 + 280 + if (chip->ops->get_state) 281 + chip->ops->get_state(chip, pwm, &pwm->state); 289 282 290 283 radix_tree_insert(&pwm_tree, pwm->pwm, pwm); 291 284 } ··· 447 436 EXPORT_SYMBOL_GPL(pwm_free); 448 437 449 438 /** 450 - * pwm_config() - change a PWM device configuration 439 + * pwm_apply_state() - atomically apply a new state to a PWM device 451 440 * @pwm: PWM device 452 - * @duty_ns: "on" time (in nanoseconds) 453 - * @period_ns: duration (in nanoseconds) of one cycle 454 - * 455 - * Returns: 0 on success or a negative error code on failure. 441 + * @state: new state to apply. This can be adjusted by the PWM driver 442 + * if the requested config is not achievable, for example, 443 + * ->duty_cycle and ->period might be approximated. 456 444 */ 457 - int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) 445 + int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state) 458 446 { 459 447 int err; 460 - 461 - if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns) 462 - return -EINVAL; 463 - 464 - err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns); 465 - if (err) 466 - return err; 467 - 468 - pwm->duty_cycle = duty_ns; 469 - pwm->period = period_ns; 470 - 471 - return 0; 472 - } 473 - EXPORT_SYMBOL_GPL(pwm_config); 474 - 475 - /** 476 - * pwm_set_polarity() - configure the polarity of a PWM signal 477 - * @pwm: PWM device 478 - * @polarity: new polarity of the PWM signal 479 - * 480 - * Note that the polarity cannot be configured while the PWM device is 481 - * enabled. 482 - * 483 - * Returns: 0 on success or a negative error code on failure. 484 - */ 485 - int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity) 486 - { 487 - int err; 488 - 489 - if (!pwm || !pwm->chip->ops) 490 - return -EINVAL; 491 - 492 - if (!pwm->chip->ops->set_polarity) 493 - return -ENOSYS; 494 - 495 - mutex_lock(&pwm->lock); 496 - 497 - if (pwm_is_enabled(pwm)) { 498 - err = -EBUSY; 499 - goto unlock; 500 - } 501 - 502 - err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity); 503 - if (err) 504 - goto unlock; 505 - 506 - pwm->polarity = polarity; 507 - 508 - unlock: 509 - mutex_unlock(&pwm->lock); 510 - return err; 511 - } 512 - EXPORT_SYMBOL_GPL(pwm_set_polarity); 513 - 514 - /** 515 - * pwm_enable() - start a PWM output toggling 516 - * @pwm: PWM device 517 - * 518 - * Returns: 0 on success or a negative error code on failure. 519 - */ 520 - int pwm_enable(struct pwm_device *pwm) 521 - { 522 - int err = 0; 523 448 524 449 if (!pwm) 525 450 return -EINVAL; 526 451 527 - mutex_lock(&pwm->lock); 452 + if (!memcmp(state, &pwm->state, sizeof(*state))) 453 + return 0; 528 454 529 - if (!test_and_set_bit(PWMF_ENABLED, &pwm->flags)) { 530 - err = pwm->chip->ops->enable(pwm->chip, pwm); 455 + if (pwm->chip->ops->apply) { 456 + err = pwm->chip->ops->apply(pwm->chip, pwm, state); 531 457 if (err) 532 - clear_bit(PWMF_ENABLED, &pwm->flags); 458 + return err; 459 + 460 + pwm->state = *state; 461 + } else { 462 + /* 463 + * FIXME: restore the initial state in case of error. 464 + */ 465 + if (state->polarity != pwm->state.polarity) { 466 + if (!pwm->chip->ops->set_polarity) 467 + return -ENOTSUPP; 468 + 469 + /* 470 + * Changing the polarity of a running PWM is 471 + * only allowed when the PWM driver implements 472 + * ->apply(). 473 + */ 474 + if (pwm->state.enabled) { 475 + pwm->chip->ops->disable(pwm->chip, pwm); 476 + pwm->state.enabled = false; 477 + } 478 + 479 + err = pwm->chip->ops->set_polarity(pwm->chip, pwm, 480 + state->polarity); 481 + if (err) 482 + return err; 483 + 484 + pwm->state.polarity = state->polarity; 485 + } 486 + 487 + if (state->period != pwm->state.period || 488 + state->duty_cycle != pwm->state.duty_cycle) { 489 + err = pwm->chip->ops->config(pwm->chip, pwm, 490 + state->duty_cycle, 491 + state->period); 492 + if (err) 493 + return err; 494 + 495 + pwm->state.duty_cycle = state->duty_cycle; 496 + pwm->state.period = state->period; 497 + } 498 + 499 + if (state->enabled != pwm->state.enabled) { 500 + if (state->enabled) { 501 + err = pwm->chip->ops->enable(pwm->chip, pwm); 502 + if (err) 503 + return err; 504 + } else { 505 + pwm->chip->ops->disable(pwm->chip, pwm); 506 + } 507 + 508 + pwm->state.enabled = state->enabled; 509 + } 533 510 } 534 511 535 - mutex_unlock(&pwm->lock); 536 - 537 - return err; 512 + return 0; 538 513 } 539 - EXPORT_SYMBOL_GPL(pwm_enable); 514 + EXPORT_SYMBOL_GPL(pwm_apply_state); 540 515 541 516 /** 542 - * pwm_disable() - stop a PWM output toggling 517 + * pwm_adjust_config() - adjust the current PWM config to the PWM arguments 543 518 * @pwm: PWM device 519 + * 520 + * This function will adjust the PWM config to the PWM arguments provided 521 + * by the DT or PWM lookup table. This is particularly useful to adapt 522 + * the bootloader config to the Linux one. 544 523 */ 545 - void pwm_disable(struct pwm_device *pwm) 524 + int pwm_adjust_config(struct pwm_device *pwm) 546 525 { 547 - if (pwm && test_and_clear_bit(PWMF_ENABLED, &pwm->flags)) 548 - pwm->chip->ops->disable(pwm->chip, pwm); 526 + struct pwm_state state; 527 + struct pwm_args pargs; 528 + 529 + pwm_get_args(pwm, &pargs); 530 + pwm_get_state(pwm, &state); 531 + 532 + /* 533 + * If the current period is zero it means that either the PWM driver 534 + * does not support initial state retrieval or the PWM has not yet 535 + * been configured. 536 + * 537 + * In either case, we setup the new period and polarity, and assign a 538 + * duty cycle of 0. 539 + */ 540 + if (!state.period) { 541 + state.duty_cycle = 0; 542 + state.period = pargs.period; 543 + state.polarity = pargs.polarity; 544 + 545 + return pwm_apply_state(pwm, &state); 546 + } 547 + 548 + /* 549 + * Adjust the PWM duty cycle/period based on the period value provided 550 + * in PWM args. 551 + */ 552 + if (pargs.period != state.period) { 553 + u64 dutycycle = (u64)state.duty_cycle * pargs.period; 554 + 555 + do_div(dutycycle, state.period); 556 + state.duty_cycle = dutycycle; 557 + state.period = pargs.period; 558 + } 559 + 560 + /* 561 + * If the polarity changed, we should also change the duty cycle. 562 + */ 563 + if (pargs.polarity != state.polarity) { 564 + state.polarity = pargs.polarity; 565 + state.duty_cycle = state.period - state.duty_cycle; 566 + } 567 + 568 + return pwm_apply_state(pwm, &state); 549 569 } 550 - EXPORT_SYMBOL_GPL(pwm_disable); 570 + EXPORT_SYMBOL_GPL(pwm_adjust_config); 551 571 552 572 static struct pwm_chip *of_node_to_pwmchip(struct device_node *np) 553 573 { ··· 796 754 if (!chip) 797 755 goto out; 798 756 799 - pwm->args.period = chosen->period; 800 - pwm->args.polarity = chosen->polarity; 801 - 802 757 pwm = pwm_request_from_chip(chip, chosen->index, con_id ?: dev_id); 803 758 if (IS_ERR(pwm)) 804 759 goto out; 760 + 761 + pwm->args.period = chosen->period; 762 + pwm->args.polarity = chosen->polarity; 805 763 806 764 out: 807 765 mutex_unlock(&pwm_lookup_lock); ··· 949 907 950 908 for (i = 0; i < chip->npwm; i++) { 951 909 struct pwm_device *pwm = &chip->pwms[i]; 910 + struct pwm_state state; 911 + 912 + pwm_get_state(pwm, &state); 952 913 953 914 seq_printf(s, " pwm-%-3d (%-20.20s):", i, pwm->label); 954 915 955 916 if (test_bit(PWMF_REQUESTED, &pwm->flags)) 956 917 seq_puts(s, " requested"); 957 918 958 - if (pwm_is_enabled(pwm)) 919 + if (state.enabled) 959 920 seq_puts(s, " enabled"); 921 + 922 + seq_printf(s, " period: %u ns", state.period); 923 + seq_printf(s, " duty: %u ns", state.duty_cycle); 924 + seq_printf(s, " polarity: %s", 925 + state.polarity ? "inverse" : "normal"); 960 926 961 927 seq_puts(s, "\n"); 962 928 }
+1 -1
drivers/pwm/pwm-crc.c
··· 75 75 return -EINVAL; 76 76 } 77 77 78 - if (pwm->period != period_ns) { 78 + if (pwm_get_period(pwm) != period_ns) { 79 79 int clk_div; 80 80 81 81 /* changing the clk divisor, need to disable fisrt */
+1 -1
drivers/pwm/pwm-lpc18xx-sct.c
··· 249 249 LPC18XX_PWM_EVSTATEMSK(lpc18xx_data->duty_event), 250 250 LPC18XX_PWM_EVSTATEMSK_ALL); 251 251 252 - if (pwm->polarity == PWM_POLARITY_NORMAL) { 252 + if (pwm_get_polarity(pwm) == PWM_POLARITY_NORMAL) { 253 253 set_event = lpc18xx_pwm->period_event; 254 254 clear_event = lpc18xx_data->duty_event; 255 255 res_action = LPC18XX_PWM_RES_SET;
+1 -1
drivers/pwm/pwm-omap-dmtimer.c
··· 192 192 load_value, load_value, match_value, match_value); 193 193 194 194 omap->pdata->set_pwm(omap->dm_timer, 195 - pwm->polarity == PWM_POLARITY_INVERSED, 195 + pwm_get_polarity(pwm) == PWM_POLARITY_INVERSED, 196 196 true, 197 197 PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE); 198 198
+1 -1
drivers/pwm/pwm-rcar.c
··· 157 157 return div; 158 158 159 159 /* Let the core driver set pwm->period if disabled and duty_ns == 0 */ 160 - if (!test_bit(PWMF_ENABLED, &pwm->flags) && !duty_ns) 160 + if (!pwm_is_enabled(pwm) && !duty_ns) 161 161 return 0; 162 162 163 163 rcar_pwm_update(rp, RCAR_PWMCR_SYNC, RCAR_PWMCR_SYNC, RCAR_PWMCR);
+2 -1
drivers/pwm/pwm-sun4i.c
··· 354 354 val = sun4i_pwm_readl(pwm, PWM_CTRL_REG); 355 355 for (i = 0; i < pwm->chip.npwm; i++) 356 356 if (!(val & BIT_CH(PWM_ACT_STATE, i))) 357 - pwm->chip.pwms[i].polarity = PWM_POLARITY_INVERSED; 357 + pwm_set_polarity(&pwm->chip.pwms[i], 358 + PWM_POLARITY_INVERSED); 358 359 clk_disable_unprepare(pwm->clk); 359 360 360 361 return 0;
+56 -14
drivers/pwm/sysfs.c
··· 26 26 struct pwm_export { 27 27 struct device child; 28 28 struct pwm_device *pwm; 29 + struct mutex lock; 29 30 }; 30 31 31 32 static struct pwm_export *child_to_pwm_export(struct device *child) ··· 46 45 char *buf) 47 46 { 48 47 const struct pwm_device *pwm = child_to_pwm_device(child); 48 + struct pwm_state state; 49 49 50 - return sprintf(buf, "%u\n", pwm_get_period(pwm)); 50 + pwm_get_state(pwm, &state); 51 + 52 + return sprintf(buf, "%u\n", state.period); 51 53 } 52 54 53 55 static ssize_t period_store(struct device *child, 54 56 struct device_attribute *attr, 55 57 const char *buf, size_t size) 56 58 { 57 - struct pwm_device *pwm = child_to_pwm_device(child); 59 + struct pwm_export *export = child_to_pwm_export(child); 60 + struct pwm_device *pwm = export->pwm; 61 + struct pwm_state state; 58 62 unsigned int val; 59 63 int ret; 60 64 ··· 67 61 if (ret) 68 62 return ret; 69 63 70 - ret = pwm_config(pwm, pwm_get_duty_cycle(pwm), val); 64 + mutex_lock(&export->lock); 65 + pwm_get_state(pwm, &state); 66 + state.period = val; 67 + ret = pwm_apply_state(pwm, &state); 68 + mutex_unlock(&export->lock); 71 69 72 70 return ret ? : size; 73 71 } ··· 81 71 char *buf) 82 72 { 83 73 const struct pwm_device *pwm = child_to_pwm_device(child); 74 + struct pwm_state state; 84 75 85 - return sprintf(buf, "%u\n", pwm_get_duty_cycle(pwm)); 76 + pwm_get_state(pwm, &state); 77 + 78 + return sprintf(buf, "%u\n", state.duty_cycle); 86 79 } 87 80 88 81 static ssize_t duty_cycle_store(struct device *child, 89 82 struct device_attribute *attr, 90 83 const char *buf, size_t size) 91 84 { 92 - struct pwm_device *pwm = child_to_pwm_device(child); 85 + struct pwm_export *export = child_to_pwm_export(child); 86 + struct pwm_device *pwm = export->pwm; 87 + struct pwm_state state; 93 88 unsigned int val; 94 89 int ret; 95 90 ··· 102 87 if (ret) 103 88 return ret; 104 89 105 - ret = pwm_config(pwm, val, pwm_get_period(pwm)); 90 + mutex_lock(&export->lock); 91 + pwm_get_state(pwm, &state); 92 + state.duty_cycle = val; 93 + ret = pwm_apply_state(pwm, &state); 94 + mutex_unlock(&export->lock); 106 95 107 96 return ret ? : size; 108 97 } ··· 116 97 char *buf) 117 98 { 118 99 const struct pwm_device *pwm = child_to_pwm_device(child); 100 + struct pwm_state state; 119 101 120 - return sprintf(buf, "%d\n", pwm_is_enabled(pwm)); 102 + pwm_get_state(pwm, &state); 103 + 104 + return sprintf(buf, "%d\n", state.enabled); 121 105 } 122 106 123 107 static ssize_t enable_store(struct device *child, 124 108 struct device_attribute *attr, 125 109 const char *buf, size_t size) 126 110 { 127 - struct pwm_device *pwm = child_to_pwm_device(child); 111 + struct pwm_export *export = child_to_pwm_export(child); 112 + struct pwm_device *pwm = export->pwm; 113 + struct pwm_state state; 128 114 int val, ret; 129 115 130 116 ret = kstrtoint(buf, 0, &val); 131 117 if (ret) 132 118 return ret; 133 119 120 + mutex_lock(&export->lock); 121 + 122 + pwm_get_state(pwm, &state); 123 + 134 124 switch (val) { 135 125 case 0: 136 - pwm_disable(pwm); 126 + state.enabled = false; 137 127 break; 138 128 case 1: 139 - ret = pwm_enable(pwm); 129 + state.enabled = true; 140 130 break; 141 131 default: 142 132 ret = -EINVAL; 143 - break; 133 + goto unlock; 144 134 } 145 135 136 + pwm_apply_state(pwm, &state); 137 + 138 + unlock: 139 + mutex_unlock(&export->lock); 146 140 return ret ? : size; 147 141 } 148 142 ··· 165 133 { 166 134 const struct pwm_device *pwm = child_to_pwm_device(child); 167 135 const char *polarity = "unknown"; 136 + struct pwm_state state; 168 137 169 - switch (pwm_get_polarity(pwm)) { 138 + pwm_get_state(pwm, &state); 139 + 140 + switch (state.polarity) { 170 141 case PWM_POLARITY_NORMAL: 171 142 polarity = "normal"; 172 143 break; ··· 186 151 struct device_attribute *attr, 187 152 const char *buf, size_t size) 188 153 { 189 - struct pwm_device *pwm = child_to_pwm_device(child); 154 + struct pwm_export *export = child_to_pwm_export(child); 155 + struct pwm_device *pwm = export->pwm; 190 156 enum pwm_polarity polarity; 157 + struct pwm_state state; 191 158 int ret; 192 159 193 160 if (sysfs_streq(buf, "normal")) ··· 199 162 else 200 163 return -EINVAL; 201 164 202 - ret = pwm_set_polarity(pwm, polarity); 165 + mutex_lock(&export->lock); 166 + pwm_get_state(pwm, &state); 167 + state.polarity = polarity; 168 + ret = pwm_apply_state(pwm, &state); 169 + mutex_unlock(&export->lock); 203 170 204 171 return ret ? : size; 205 172 } ··· 244 203 } 245 204 246 205 export->pwm = pwm; 206 + mutex_init(&export->lock); 247 207 248 208 export->child.release = pwm_export_release; 249 209 export->child.parent = parent;
+7 -2
drivers/video/backlight/lm3630a_bl.c
··· 162 162 163 163 static void lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max) 164 164 { 165 - unsigned int period = pwm_get_period(pchip->pwmd); 165 + unsigned int period = pchip->pdata->pwm_period; 166 166 unsigned int duty = br * period / br_max; 167 167 168 168 pwm_config(pchip->pwmd, duty, period); ··· 424 424 dev_err(&client->dev, "fail : get pwm device\n"); 425 425 return PTR_ERR(pchip->pwmd); 426 426 } 427 + 428 + /* 429 + * FIXME: pwm_apply_args() should be removed when switching to 430 + * the atomic PWM API. 431 + */ 432 + pwm_apply_args(pchip->pwmd); 427 433 } 428 - pchip->pwmd->period = pdata->pwm_period; 429 434 430 435 /* interrupt enable : irq 0 is not allowed */ 431 436 pchip->irq = client->irq;
+6
drivers/video/backlight/lp855x_bl.c
··· 246 246 return; 247 247 248 248 lp->pwm = pwm; 249 + 250 + /* 251 + * FIXME: pwm_apply_args() should be removed when switching to 252 + * the atomic PWM API. 253 + */ 254 + pwm_apply_args(pwm); 249 255 } 250 256 251 257 pwm_config(lp->pwm, duty, period);
+6
drivers/video/backlight/lp8788_bl.c
··· 145 145 } 146 146 147 147 bl->pwm = pwm; 148 + 149 + /* 150 + * FIXME: pwm_apply_args() should be removed when switching to 151 + * the atomic PWM API. 152 + */ 153 + pwm_apply_args(pwm); 148 154 } 149 155 150 156 pwm_config(bl->pwm, duty, period);
+10 -4
drivers/video/backlight/pwm_bl.c
··· 201 201 struct device_node *node = pdev->dev.of_node; 202 202 struct pwm_bl_data *pb; 203 203 int initial_blank = FB_BLANK_UNBLANK; 204 + struct pwm_args pargs; 204 205 int ret; 205 206 206 207 if (!data) { ··· 308 307 dev_dbg(&pdev->dev, "got pwm for backlight\n"); 309 308 310 309 /* 310 + * FIXME: pwm_apply_args() should be removed when switching to 311 + * the atomic PWM API. 312 + */ 313 + pwm_apply_args(pb->pwm); 314 + 315 + /* 311 316 * The DT case will set the pwm_period_ns field to 0 and store the 312 317 * period, parsed from the DT, in the PWM device. For the non-DT case, 313 318 * set the period from platform data if it has not already been set 314 319 * via the PWM lookup table. 315 320 */ 316 - pb->period = pwm_get_period(pb->pwm); 317 - if (!pb->period && (data->pwm_period_ns > 0)) { 321 + pwm_get_args(pb->pwm, &pargs); 322 + pb->period = pargs.period; 323 + if (!pb->period && (data->pwm_period_ns > 0)) 318 324 pb->period = data->pwm_period_ns; 319 - pwm_set_period(pb->pwm, data->pwm_period_ns); 320 - } 321 325 322 326 pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale); 323 327
+10 -1
drivers/video/fbdev/ssd1307fb.c
··· 286 286 { 287 287 int ret; 288 288 u32 precharge, dclk, com_invdir, compins; 289 + struct pwm_args pargs; 289 290 290 291 if (par->device_info->need_pwm) { 291 292 par->pwm = pwm_get(&par->client->dev, NULL); ··· 295 294 return PTR_ERR(par->pwm); 296 295 } 297 296 298 - par->pwm_period = pwm_get_period(par->pwm); 297 + /* 298 + * FIXME: pwm_apply_args() should be removed when switching to 299 + * the atomic PWM API. 300 + */ 301 + pwm_apply_args(par->pwm); 302 + 303 + pwm_get_args(par->pwm, &pargs); 304 + 305 + par->pwm_period = pargs.period; 299 306 /* Enable the PWM */ 300 307 pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period); 301 308 pwm_enable(par->pwm);
+239 -80
include/linux/pwm.h
··· 5 5 #include <linux/mutex.h> 6 6 #include <linux/of.h> 7 7 8 - struct pwm_device; 9 8 struct seq_file; 10 - 11 - #if IS_ENABLED(CONFIG_PWM) 12 - /* 13 - * pwm_request - request a PWM device 14 - */ 15 - struct pwm_device *pwm_request(int pwm_id, const char *label); 16 - 17 - /* 18 - * pwm_free - free a PWM device 19 - */ 20 - void pwm_free(struct pwm_device *pwm); 21 - 22 - /* 23 - * pwm_config - change a PWM device configuration 24 - */ 25 - int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns); 26 - 27 - /* 28 - * pwm_enable - start a PWM output toggling 29 - */ 30 - int pwm_enable(struct pwm_device *pwm); 31 - 32 - /* 33 - * pwm_disable - stop a PWM output toggling 34 - */ 35 - void pwm_disable(struct pwm_device *pwm); 36 - #else 37 - static inline struct pwm_device *pwm_request(int pwm_id, const char *label) 38 - { 39 - return ERR_PTR(-ENODEV); 40 - } 41 - 42 - static inline void pwm_free(struct pwm_device *pwm) 43 - { 44 - } 45 - 46 - static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) 47 - { 48 - return -EINVAL; 49 - } 50 - 51 - static inline int pwm_enable(struct pwm_device *pwm) 52 - { 53 - return -EINVAL; 54 - } 55 - 56 - static inline void pwm_disable(struct pwm_device *pwm) 57 - { 58 - } 59 - #endif 60 - 61 9 struct pwm_chip; 62 10 63 11 /** ··· 42 94 43 95 enum { 44 96 PWMF_REQUESTED = 1 << 0, 45 - PWMF_ENABLED = 1 << 1, 46 - PWMF_EXPORTED = 1 << 2, 97 + PWMF_EXPORTED = 1 << 1, 98 + }; 99 + 100 + /* 101 + * struct pwm_state - state of a PWM channel 102 + * @period: PWM period (in nanoseconds) 103 + * @duty_cycle: PWM duty cycle (in nanoseconds) 104 + * @polarity: PWM polarity 105 + * @enabled: PWM enabled status 106 + */ 107 + struct pwm_state { 108 + unsigned int period; 109 + unsigned int duty_cycle; 110 + enum pwm_polarity polarity; 111 + bool enabled; 47 112 }; 48 113 49 114 /** ··· 67 106 * @pwm: global index of the PWM device 68 107 * @chip: PWM chip providing this PWM device 69 108 * @chip_data: chip-private data associated with the PWM device 70 - * @lock: used to serialize accesses to the PWM device where necessary 71 - * @period: period of the PWM signal (in nanoseconds) 72 - * @duty_cycle: duty cycle of the PWM signal (in nanoseconds) 73 - * @polarity: polarity of the PWM signal 74 109 * @args: PWM arguments 110 + * @state: curent PWM channel state 75 111 */ 76 112 struct pwm_device { 77 113 const char *label; ··· 77 119 unsigned int pwm; 78 120 struct pwm_chip *chip; 79 121 void *chip_data; 80 - struct mutex lock; 81 - 82 - unsigned int period; 83 - unsigned int duty_cycle; 84 - enum pwm_polarity polarity; 85 122 86 123 struct pwm_args args; 124 + struct pwm_state state; 87 125 }; 126 + 127 + /** 128 + * pwm_get_state() - retrieve the current PWM state 129 + * @pwm: PWM device 130 + * @state: state to fill with the current PWM state 131 + */ 132 + static inline void pwm_get_state(const struct pwm_device *pwm, 133 + struct pwm_state *state) 134 + { 135 + *state = pwm->state; 136 + } 88 137 89 138 static inline bool pwm_is_enabled(const struct pwm_device *pwm) 90 139 { 91 - return test_bit(PWMF_ENABLED, &pwm->flags); 140 + struct pwm_state state; 141 + 142 + pwm_get_state(pwm, &state); 143 + 144 + return state.enabled; 92 145 } 93 146 94 147 static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period) 95 148 { 96 149 if (pwm) 97 - pwm->period = period; 150 + pwm->state.period = period; 98 151 } 99 152 100 153 static inline unsigned int pwm_get_period(const struct pwm_device *pwm) 101 154 { 102 - return pwm ? pwm->period : 0; 155 + struct pwm_state state; 156 + 157 + pwm_get_state(pwm, &state); 158 + 159 + return state.period; 103 160 } 104 161 105 162 static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty) 106 163 { 107 164 if (pwm) 108 - pwm->duty_cycle = duty; 165 + pwm->state.duty_cycle = duty; 109 166 } 110 167 111 168 static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm) 112 169 { 113 - return pwm ? pwm->duty_cycle : 0; 114 - } 170 + struct pwm_state state; 115 171 116 - /* 117 - * pwm_set_polarity - configure the polarity of a PWM signal 118 - */ 119 - int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity); 172 + pwm_get_state(pwm, &state); 173 + 174 + return state.duty_cycle; 175 + } 120 176 121 177 static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm) 122 178 { 123 - return pwm ? pwm->polarity : PWM_POLARITY_NORMAL; 179 + struct pwm_state state; 180 + 181 + pwm_get_state(pwm, &state); 182 + 183 + return state.polarity; 124 184 } 125 185 126 186 static inline void pwm_get_args(const struct pwm_device *pwm, 127 187 struct pwm_args *args) 128 188 { 129 189 *args = pwm->args; 130 - } 131 - 132 - static inline void pwm_apply_args(struct pwm_device *pwm) 133 - { 134 - pwm_set_period(pwm, pwm->args.period); 135 - pwm_set_polarity(pwm, pwm->args.polarity); 136 190 } 137 191 138 192 /** ··· 155 185 * @set_polarity: configure the polarity of this PWM 156 186 * @enable: enable PWM output toggling 157 187 * @disable: disable PWM output toggling 188 + * @apply: atomically apply a new PWM config. The state argument 189 + * should be adjusted with the real hardware config (if the 190 + * approximate the period or duty_cycle value, state should 191 + * reflect it) 192 + * @get_state: get the current PWM state. This function is only 193 + * called once per PWM device when the PWM chip is 194 + * registered. 158 195 * @dbg_show: optional routine to show contents in debugfs 159 196 * @owner: helps prevent removal of modules exporting active PWMs 160 197 */ ··· 174 197 enum pwm_polarity polarity); 175 198 int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm); 176 199 void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm); 200 + int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm, 201 + struct pwm_state *state); 202 + void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm, 203 + struct pwm_state *state); 177 204 #ifdef CONFIG_DEBUG_FS 178 205 void (*dbg_show)(struct pwm_chip *chip, struct seq_file *s); 179 206 #endif ··· 213 232 }; 214 233 215 234 #if IS_ENABLED(CONFIG_PWM) 235 + /* PWM user APIs */ 236 + struct pwm_device *pwm_request(int pwm_id, const char *label); 237 + void pwm_free(struct pwm_device *pwm); 238 + int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state); 239 + int pwm_adjust_config(struct pwm_device *pwm); 240 + 241 + /** 242 + * pwm_config() - change a PWM device configuration 243 + * @pwm: PWM device 244 + * @duty_ns: "on" time (in nanoseconds) 245 + * @period_ns: duration (in nanoseconds) of one cycle 246 + * 247 + * Returns: 0 on success or a negative error code on failure. 248 + */ 249 + static inline int pwm_config(struct pwm_device *pwm, int duty_ns, 250 + int period_ns) 251 + { 252 + struct pwm_state state; 253 + 254 + if (!pwm) 255 + return -EINVAL; 256 + 257 + pwm_get_state(pwm, &state); 258 + if (state.duty_cycle == duty_ns && state.period == period_ns) 259 + return 0; 260 + 261 + state.duty_cycle = duty_ns; 262 + state.period = period_ns; 263 + return pwm_apply_state(pwm, &state); 264 + } 265 + 266 + /** 267 + * pwm_set_polarity() - configure the polarity of a PWM signal 268 + * @pwm: PWM device 269 + * @polarity: new polarity of the PWM signal 270 + * 271 + * Note that the polarity cannot be configured while the PWM device is 272 + * enabled. 273 + * 274 + * Returns: 0 on success or a negative error code on failure. 275 + */ 276 + static inline int pwm_set_polarity(struct pwm_device *pwm, 277 + enum pwm_polarity polarity) 278 + { 279 + struct pwm_state state; 280 + 281 + if (!pwm) 282 + return -EINVAL; 283 + 284 + pwm_get_state(pwm, &state); 285 + if (state.polarity == polarity) 286 + return 0; 287 + 288 + /* 289 + * Changing the polarity of a running PWM without adjusting the 290 + * dutycycle/period value is a bit risky (can introduce glitches). 291 + * Return -EBUSY in this case. 292 + * Note that this is allowed when using pwm_apply_state() because 293 + * the user specifies all the parameters. 294 + */ 295 + if (state.enabled) 296 + return -EBUSY; 297 + 298 + state.polarity = polarity; 299 + return pwm_apply_state(pwm, &state); 300 + } 301 + 302 + /** 303 + * pwm_enable() - start a PWM output toggling 304 + * @pwm: PWM device 305 + * 306 + * Returns: 0 on success or a negative error code on failure. 307 + */ 308 + static inline int pwm_enable(struct pwm_device *pwm) 309 + { 310 + struct pwm_state state; 311 + 312 + if (!pwm) 313 + return -EINVAL; 314 + 315 + pwm_get_state(pwm, &state); 316 + if (state.enabled) 317 + return 0; 318 + 319 + state.enabled = true; 320 + return pwm_apply_state(pwm, &state); 321 + } 322 + 323 + /** 324 + * pwm_disable() - stop a PWM output toggling 325 + * @pwm: PWM device 326 + */ 327 + static inline void pwm_disable(struct pwm_device *pwm) 328 + { 329 + struct pwm_state state; 330 + 331 + if (!pwm) 332 + return; 333 + 334 + pwm_get_state(pwm, &state); 335 + if (!state.enabled) 336 + return; 337 + 338 + state.enabled = false; 339 + pwm_apply_state(pwm, &state); 340 + } 341 + 342 + 343 + /* PWM provider APIs */ 216 344 int pwm_set_chip_data(struct pwm_device *pwm, void *data); 217 345 void *pwm_get_chip_data(struct pwm_device *pwm); 218 346 ··· 347 257 348 258 bool pwm_can_sleep(struct pwm_device *pwm); 349 259 #else 260 + static inline struct pwm_device *pwm_request(int pwm_id, const char *label) 261 + { 262 + return ERR_PTR(-ENODEV); 263 + } 264 + 265 + static inline void pwm_free(struct pwm_device *pwm) 266 + { 267 + } 268 + 269 + static inline int pwm_apply_state(struct pwm_device *pwm, 270 + const struct pwm_state *state) 271 + { 272 + return -ENOTSUPP; 273 + } 274 + 275 + static inline int pwm_adjust_config(struct pwm_device *pwm) 276 + { 277 + return -ENOTSUPP; 278 + } 279 + 280 + static inline int pwm_config(struct pwm_device *pwm, int duty_ns, 281 + int period_ns) 282 + { 283 + return -EINVAL; 284 + } 285 + 286 + static inline int pwm_set_polarity(struct pwm_device *pwm, 287 + enum pwm_polarity polarity) 288 + { 289 + return -ENOTSUPP; 290 + } 291 + 292 + static inline int pwm_enable(struct pwm_device *pwm) 293 + { 294 + return -EINVAL; 295 + } 296 + 297 + static inline void pwm_disable(struct pwm_device *pwm) 298 + { 299 + } 300 + 350 301 static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data) 351 302 { 352 303 return -EINVAL; ··· 458 327 return false; 459 328 } 460 329 #endif 330 + 331 + static inline void pwm_apply_args(struct pwm_device *pwm) 332 + { 333 + /* 334 + * PWM users calling pwm_apply_args() expect to have a fresh config 335 + * where the polarity and period are set according to pwm_args info. 336 + * The problem is, polarity can only be changed when the PWM is 337 + * disabled. 338 + * 339 + * PWM drivers supporting hardware readout may declare the PWM device 340 + * as enabled, and prevent polarity setting, which changes from the 341 + * existing behavior, where all PWM devices are declared as disabled 342 + * at startup (even if they are actually enabled), thus authorizing 343 + * polarity setting. 344 + * 345 + * Instead of setting ->enabled to false, we call pwm_disable() 346 + * before pwm_set_polarity() to ensure that everything is configured 347 + * as expected, and the PWM is really disabled when the user request 348 + * it. 349 + * 350 + * Note that PWM users requiring a smooth handover between the 351 + * bootloader and the kernel (like critical regulators controlled by 352 + * PWM devices) will have to switch to the atomic API and avoid calling 353 + * pwm_apply_args(). 354 + */ 355 + pwm_disable(pwm); 356 + pwm_set_polarity(pwm, pwm->args.polarity); 357 + } 461 358 462 359 struct pwm_lookup { 463 360 struct list_head list;