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