linux/drivers/pwm
Patrick Havelange 3479bbd1e1 pwm: fsl-ftm: More relaxed permissions for updating period
The Flextimer has only one period for several channels. The PWM
subsystem doesn't allow to model something like that. The current
implementation simply disallows changing the period once it has
been set, having as a side effect that you need to enable and
disable the PWM if you want to change the period.

The driver should allow as much freedom as possible for configuring
the period and duty cycle. Therefore, this patch reworks the code
to allow the following:

- period and duty_cycle can be set at will when the PWM is disabled;
- when enabling a PWM, verify that the period is either not set yet,
  or the same as the other already enabled PWM(s), and fail if not;
- allow to change the period on the fly when the PWM is the only one
  enabled.

It also allows to have different periods configured for different PWMs.
Only one period can be used at a time, thus the first PWM to be enabled
will set that period, only other PWMs with that same period can be
enabled at the same time. To use another PWM with another period, the
enabled PWMs must be disabled first.

Example scenario :
echo 5000000 > pwm0/period	#OK
echo 1000000 > pwm0/duty_cycle	#OK
echo 1000000 > pwm1/period	#OK
echo 1000000 > pwm1/duty_cycle	#OK
echo 1 > pwm0/enable		#OK
echo 1 > pwm1/enable		#FAIL (pwm0/period != pwm1/period)
echo 0 > pwm0/enable		#OK
echo 1 > pwm1/enable		#OK
echo 1000000 > pwm0/period	#OK
echo 2000000 > pwm0/period	#OK
echo 1 > pwm0/enable		#FAIL (pwm0/period != pwm1/period)
echo 2000000 > pwm1/period	#OK (pwm1 still running, changed on the fly)
echo 1 > pwm0/enable		#OK (now pwm0/period == pwm1/period)
echo 3000000 > pwm1/period	#FAIL (other PWMs running)
echo 0 > pwm0/enable		#OK
echo 3000000 > pwm1/period	#OK (only this PWM running)

Adapting the code to satisfy these constraints turned up a number of
additional issues with the current implementation:
- the prescaler value 0 was not used (when it could have been);
- when setting the period was not possible, the internal state was
  inconsistent;
- the maximal value for configuring the period was never used;

Since all of these interact with each other, rather than trying to fix
each individual issue, this patch reworks how the period and duty cycle
are set entirely, with the following additional improvements:
- implement the new apply() method instead of the individual methods;
- return the exact used period/duty_cycle values;
- more coherent argument types for period, duty_cycle;

Signed-off-by: Patrick Havelange <patrick.havelange@essensium.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2019-06-26 11:39:16 +02:00
..
core.c pwm: Add support referencing PWMs from ACPI 2019-06-26 11:39:11 +02:00
Kconfig pwm: sifive: Add a driver for SiFive SoC PWM 2019-06-25 14:48:12 +02:00
Makefile pwm: sifive: Add a driver for SiFive SoC PWM 2019-06-25 14:48:12 +02:00
pwm-ab8500.c pwm: drop owner assignment from platform_drivers 2014-10-20 16:21:28 +02:00
pwm-atmel-hlcdc.c pwm: atmel-hlcdc: Add compatible for SAM9X60 HLCDC's PWM 2019-06-26 11:39:13 +02:00
pwm-atmel-tcb.c ARM: at91: move SoC specific definitions to SoC folder 2019-05-02 21:55:58 +02:00
pwm-atmel.c pwm: atmel: Remove useless symbolic definitions 2019-03-04 12:52:49 +01:00
pwm-bcm2835.c pwm: bcm2835: Improve precision of PWM 2019-06-26 11:39:12 +02:00
pwm-bcm-iproc.c pwm: Add support for Broadcom iProc PWM controller 2016-07-11 12:49:25 +02:00
pwm-bcm-kona.c pwm: bcm-kona: Update macros to remove braces around numbers 2019-03-04 12:52:49 +01:00
pwm-berlin.c pwm: Clear chip_data in pwm_put() 2019-05-09 17:09:54 +02:00
pwm-brcmstb.c pwm: Remove .can_sleep from struct pwm_chip 2017-01-04 09:40:54 +01:00
pwm-clps711x.c pwm: clps711x: Switch to SPDX identifier 2018-12-24 12:06:56 +01:00
pwm-crc.c pwm: Use pwm_get/set_xxx() helpers where appropriate 2016-05-17 14:44:59 +02:00
pwm-cros-ec.c pwm: cros-ec: Switch to SPDX identifier 2018-07-09 19:02:23 +02:00
pwm-ep93xx.c ARM: ep93xx: move pinctrl interfaces into include/linux/soc 2019-04-28 23:08:40 -07:00
pwm-fsl-ftm.c pwm: fsl-ftm: More relaxed permissions for updating period 2019-06-26 11:39:16 +02:00
pwm-hibvt.c pwm: hibvt: Add hi3559v100 support 2019-03-04 11:38:52 +01:00
pwm-img.c pwm: img: Turn final 'else if' into 'else' in img_pwm_config 2019-03-20 12:29:22 +01:00
pwm-imx1.c pwm: imx: Split into two drivers 2019-01-16 08:45:33 +01:00
pwm-imx27.c pwm: imx27: Use devm_platform_ioremap_resource() to simplify code 2019-05-09 16:53:59 +02:00
pwm-imx-tpm.c pwm: Add i.MX TPM PWM driver support 2019-05-09 17:01:48 +02:00
pwm-jz4740.c pwm: jz4740: Force TCU2 channels to return to their init level 2019-06-26 11:39:05 +02:00
pwm-lp3943.c treewide: devm_kzalloc() -> devm_kcalloc() 2018-06-12 16:19:22 -07:00
pwm-lpc18xx-sct.c pwm: lpc18xx-sct: Don't reconfigure PWM in .request and .free 2018-11-16 11:02:47 +01:00
pwm-lpc32xx.c pwm: lpc32xx: Set PWM_PIN_LEVEL bit to default value 2016-07-11 12:49:29 +02:00
pwm-lpss-pci.c pwm: lpss: Set enable-bit before waiting for update-bit to go low 2017-04-06 14:48:14 +02:00
pwm-lpss-platform.c pwm: lpss: Force runtime-resume on suspend on Cherry Trail 2018-10-16 13:15:57 +02:00
pwm-lpss.c pwm: lpss: Only set update bit if we are actually changing the settings 2018-10-16 13:16:15 +02:00
pwm-lpss.h pwm: lpss: Force runtime-resume on suspend on Cherry Trail 2018-10-16 13:15:57 +02:00
pwm-mediatek.c pwm: mediatek: Add MT7628 support 2018-08-20 11:36:07 +02:00
pwm-meson.c pwm: meson: Add documentation to the driver 2019-06-26 11:39:10 +02:00
pwm-mtk-disp.c pwm: Add MediaTek MT8183 display PWM driver support 2019-03-04 11:45:08 +01:00
pwm-mxs.c pwm: mxs: Switch to SPDX identifier 2018-07-12 09:03:06 +02:00
pwm-omap-dmtimer.c pwm: omap-dmtimer: Return -EPROBE_DEFER if no dmtimer platform data 2018-08-20 11:32:19 +02:00
pwm-pca9685.c pwm: Clear chip_data in pwm_put() 2019-05-09 17:09:54 +02:00
pwm-puv3.c pwm: puv3: Delete an error message for a failed memory allocation 2018-03-27 23:27:05 +02:00
pwm-pxa.c pwm: constify pwm_ops structures 2017-01-19 00:38:17 +01:00
pwm-rcar.c pwm: rcar: Remove suspend/resume support 2019-06-26 11:39:11 +02:00
pwm-renesas-tpu.c pwm: Use SPDX identifier for Renesas drivers 2018-10-12 13:35:45 +02:00
pwm-rockchip.c pwm: rockchip: Add rk3328 support 2017-08-18 17:44:34 +02:00
pwm-samsung.c pwm: samsung: Don't uses devm_*() functions in ->request() 2019-05-09 17:29:15 +02:00
pwm-sifive.c pwm: sifive: Add a driver for SiFive SoC PWM 2019-06-25 14:48:12 +02:00
pwm-spear.c pwm: drop owner assignment from platform_drivers 2014-10-20 16:21:28 +02:00
pwm-sti.c pwm: Remove .can_sleep from struct pwm_chip 2017-01-04 09:40:54 +01:00
pwm-stm32-lp.c pwm: stm32-lp: Add power management support 2019-06-25 14:49:50 +02:00
pwm-stm32.c pwm: stm32: Use 3 cells ->of_xlate() 2019-06-25 14:53:51 +02:00
pwm-stmpe.c pwm: stmpe: Fix wrong register offset for hwpwm=2 case 2017-12-05 09:33:05 +01:00
pwm-sun4i.c pwm: sun4i: Simplify controller mapping 2018-03-28 01:12:12 +02:00
pwm-tegra.c pwm: tegra: Remove gratuituous blank line 2018-09-26 16:01:39 +02:00
pwm-tiecap.c pwm: tiecap: Set driver data before runtime PM enable 2017-08-21 08:31:37 +02:00
pwm-tiehrpwm.c pwm: tiehrpwm: Update shadow register for disabling PWMs 2019-03-20 12:31:07 +01:00
pwm-tipwmss.c pwm: pwm-tipwmss: Remove all runtime PM gets/puts 2016-09-06 10:48:54 +02:00
pwm-twl-led.c mfd: twl: Move header file out of I2C realm 2017-09-04 14:41:02 +01:00
pwm-twl.c mfd: twl: Move header file out of I2C realm 2017-09-04 14:41:02 +01:00
pwm-vt8500.c pwm: vt8500: Undo preparation of a clock source. 2017-07-25 13:43:28 +02:00
pwm-zx.c pwm: Add ZTE ZX PWM device driver 2017-08-21 08:11:24 +02:00
sysfs.c pwm: sysfs: Add suspend/resume support 2019-06-26 11:39:11 +02:00