aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-12 14:11:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-12 14:11:05 -0400
commitb67be92feb486f800d80d72c67fd87b47b79b18e (patch)
treefcd22ae553cc094be6fcee8f2d3f99661793d165
parent2d2474a194652f55c7af51068db3c1b851f16711 (diff)
parentdc8e6e1e8f2d2719dd396708b0f56d8b73c9ea52 (diff)
Merge tag 'pwm/for-4.9-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 contains support for PWM signal capture in the STi driver as well as support for the PWM controller found on Meson SoCs. There's also support added for the MediaTek MT2701 and SunXi H3 to the existing drivers. Other than that there's a fair set of miscellaneous cleanups and fixes across the board" * tag 'pwm/for-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (24 commits) pwm: meson: Handle unknown ID values pwm: sti: Take the opportunity to conduct a little house keeping pwm: sti: It's now valid for number of PWM channels to be zero pwm: sti: Add PWM capture callback pwm: sti: Add support for PWM capture interrupts pwm: sti: Initialise PWM capture device data pwm: sti: Supply PWM Capture clock handling pwm: sti: Supply PWM capture register addresses and bit locations pwm: sti: Only request clock rate when needed pwm: sti: Reorganise register names in preparation for new functionality pwm: sti: Rename channel => device dt-bindings: pwm: sti: Update DT bindings for capture support pwm: lpc-18xx: use pwm_set_chip_data pwm: sunxi: Add H3 support pwm: Add support for Meson PWM Controller dt-bindings: pwm: Add bindings for Meson PWM Controller pwm: samsung: Fix to use lowest div for large enough modulation bits pwm: pwm-tipwmss: Remove all runtime PM gets/puts pwm: cros-ec: Add __packed to prevent padding pwm: Add MediaTek MT2701 display PWM driver support ...
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-meson.txt23
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt3
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-st.txt8
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-sun4i.txt1
-rw-r--r--drivers/pwm/Kconfig9
-rw-r--r--drivers/pwm/Makefile1
-rw-r--r--drivers/pwm/core.c2
-rw-r--r--drivers/pwm/pwm-berlin.c84
-rw-r--r--drivers/pwm/pwm-cros-ec.c4
-rw-r--r--drivers/pwm/pwm-lpc18xx-sct.c12
-rw-r--r--drivers/pwm/pwm-meson.c529
-rw-r--r--drivers/pwm/pwm-mtk-disp.c87
-rw-r--r--drivers/pwm/pwm-samsung.c15
-rw-r--r--drivers/pwm/pwm-sti.c483
-rw-r--r--drivers/pwm/pwm-sun4i.c9
-rw-r--r--drivers/pwm/pwm-tipwmss.c19
-rw-r--r--drivers/pwm/pwm-twl.c16
-rw-r--r--drivers/pwm/sysfs.c18
-rw-r--r--include/linux/pwm.h5
19 files changed, 1183 insertions, 145 deletions
diff --git a/Documentation/devicetree/bindings/pwm/pwm-meson.txt b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
new file mode 100644
index 000000000000..5376a4468cb6
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
@@ -0,0 +1,23 @@
1Amlogic Meson PWM Controller
2============================
3
4Required properties:
5- compatible: Shall contain "amlogic,meson8b-pwm" or "amlogic,meson-gxbb-pwm".
6- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
7 the cells format.
8
9Optional properties:
10- clocks: Could contain one or two parents clocks phandle for each of the two
11 PWM channels.
12- clock-names: Could contain at least the "clkin0" and/or "clkin1" names.
13
14Example:
15
16 pwm_ab: pwm@8550 {
17 compatible = "amlogic,meson-gxbb-pwm";
18 reg = <0x0 0x08550 0x0 0x10>;
19 #pwm-cells = <3>;
20 status = "disabled";
21 clocks = <&xtal>, <&xtal>;
22 clock-names = "clkin0", "clkin1";
23 }
diff --git a/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt b/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
index f8f59baf6b67..6f8af2bcc7b7 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
@@ -2,8 +2,9 @@ MediaTek display PWM controller
2 2
3Required properties: 3Required properties:
4 - compatible: should be "mediatek,<name>-disp-pwm": 4 - compatible: should be "mediatek,<name>-disp-pwm":
5 - "mediatek,mt8173-disp-pwm": found on mt8173 SoC. 5 - "mediatek,mt2701-disp-pwm": found on mt2701 SoC.
6 - "mediatek,mt6595-disp-pwm": found on mt6595 SoC. 6 - "mediatek,mt6595-disp-pwm": found on mt6595 SoC.
7 - "mediatek,mt8173-disp-pwm": found on mt8173 SoC.
7 - reg: physical base address and length of the controller's registers. 8 - reg: physical base address and length of the controller's registers.
8 - #pwm-cells: must be 2. See pwm.txt in this directory for a description of 9 - #pwm-cells: must be 2. See pwm.txt in this directory for a description of
9 the cell format. 10 the cell format.
diff --git a/Documentation/devicetree/bindings/pwm/pwm-st.txt b/Documentation/devicetree/bindings/pwm/pwm-st.txt
index 84d2fb807d3c..19fce774cafa 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-st.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-st.txt
@@ -13,13 +13,14 @@ Required parameters:
13- pinctrl-0: List of phandles pointing to pin configuration nodes 13- pinctrl-0: List of phandles pointing to pin configuration nodes
14 for PWM module. 14 for PWM module.
15 For Pinctrl properties, please refer to [1]. 15 For Pinctrl properties, please refer to [1].
16- clock-names: Set to "pwm". 16- clock-names: Valid entries are "pwm" and/or "capture".
17- clocks: phandle of the clock used by the PWM module. 17- clocks: phandle of the clock used by the PWM module.
18 For Clk properties, please refer to [2]. 18 For Clk properties, please refer to [2].
19- interrupts: IRQ for the Capture device
19 20
20Optional properties: 21Optional properties:
21- st,pwm-num-chan: Number of available channels. If not passed, the driver 22- st,pwm-num-chan: Number of available PWM channels. Default is 0.
22 will consider single channel by default. 23- st,capture-num-chan: Number of available Capture channels. Default is 0.
23 24
24[1] Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt 25[1] Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
25[2] Documentation/devicetree/bindings/clock/clock-bindings.txt 26[2] Documentation/devicetree/bindings/clock/clock-bindings.txt
@@ -38,4 +39,5 @@ pwm1: pwm@fe510000 {
38 clocks = <&clk_sysin>; 39 clocks = <&clk_sysin>;
39 clock-names = "pwm"; 40 clock-names = "pwm";
40 st,pwm-num-chan = <4>; 41 st,pwm-num-chan = <4>;
42 st,capture-num-chan = <2>;
41}; 43};
diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
index cf6068b8e974..f1cbeefb3087 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
@@ -6,6 +6,7 @@ Required properties:
6 - "allwinner,sun5i-a10s-pwm" 6 - "allwinner,sun5i-a10s-pwm"
7 - "allwinner,sun5i-a13-pwm" 7 - "allwinner,sun5i-a13-pwm"
8 - "allwinner,sun7i-a20-pwm" 8 - "allwinner,sun7i-a20-pwm"
9 - "allwinner,sun8i-h3-pwm"
9 - reg: physical base address and length of the controller's registers 10 - reg: physical base address and length of the controller's registers
10 - #pwm-cells: should be 3. See pwm.txt in this directory for a description of 11 - #pwm-cells: should be 3. See pwm.txt in this directory for a description of
11 the cells format. 12 the cells format.
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 80a566a00d04..bf0128899c09 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -262,6 +262,15 @@ config PWM_LPSS_PLATFORM
262 To compile this driver as a module, choose M here: the module 262 To compile this driver as a module, choose M here: the module
263 will be called pwm-lpss-platform. 263 will be called pwm-lpss-platform.
264 264
265config PWM_MESON
266 tristate "Amlogic Meson PWM driver"
267 depends on ARCH_MESON
268 help
269 The platform driver for Amlogic Meson PWM controller.
270
271 To compile this driver as a module, choose M here: the module
272 will be called pwm-meson.
273
265config PWM_MTK_DISP 274config PWM_MTK_DISP
266 tristate "MediaTek display PWM driver" 275 tristate "MediaTek display PWM driver"
267 depends on ARCH_MEDIATEK || COMPILE_TEST 276 depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index feef1dd29f73..1194c54efcc2 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o
24obj-$(CONFIG_PWM_LPSS) += pwm-lpss.o 24obj-$(CONFIG_PWM_LPSS) += pwm-lpss.o
25obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o 25obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o
26obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o 26obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
27obj-$(CONFIG_PWM_MESON) += pwm-meson.o
27obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o 28obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
28obj-$(CONFIG_PWM_MXS) += pwm-mxs.o 29obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
29obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o 30obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 0dbd29e287db..172ef8245811 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -339,6 +339,8 @@ int pwmchip_remove(struct pwm_chip *chip)
339 unsigned int i; 339 unsigned int i;
340 int ret = 0; 340 int ret = 0;
341 341
342 pwmchip_sysfs_unexport_children(chip);
343
342 mutex_lock(&pwm_lock); 344 mutex_lock(&pwm_lock);
343 345
344 for (i = 0; i < chip->npwm; i++) { 346 for (i = 0; i < chip->npwm; i++) {
diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
index 65108129d505..01339c152ab0 100644
--- a/drivers/pwm/pwm-berlin.c
+++ b/drivers/pwm/pwm-berlin.c
@@ -16,6 +16,7 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/pwm.h> 18#include <linux/pwm.h>
19#include <linux/slab.h>
19 20
20#define BERLIN_PWM_EN 0x0 21#define BERLIN_PWM_EN 0x0
21#define BERLIN_PWM_ENABLE BIT(0) 22#define BERLIN_PWM_ENABLE BIT(0)
@@ -27,6 +28,13 @@
27#define BERLIN_PWM_TCNT 0xc 28#define BERLIN_PWM_TCNT 0xc
28#define BERLIN_PWM_MAX_TCNT 65535 29#define BERLIN_PWM_MAX_TCNT 65535
29 30
31struct berlin_pwm_channel {
32 u32 enable;
33 u32 ctrl;
34 u32 duty;
35 u32 tcnt;
36};
37
30struct berlin_pwm_chip { 38struct berlin_pwm_chip {
31 struct pwm_chip chip; 39 struct pwm_chip chip;
32 struct clk *clk; 40 struct clk *clk;
@@ -55,6 +63,25 @@ static inline void berlin_pwm_writel(struct berlin_pwm_chip *chip,
55 writel_relaxed(value, chip->base + channel * 0x10 + offset); 63 writel_relaxed(value, chip->base + channel * 0x10 + offset);
56} 64}
57 65
66static int berlin_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
67{
68 struct berlin_pwm_channel *channel;
69
70 channel = kzalloc(sizeof(*channel), GFP_KERNEL);
71 if (!channel)
72 return -ENOMEM;
73
74 return pwm_set_chip_data(pwm, channel);
75}
76
77static void berlin_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
78{
79 struct berlin_pwm_channel *channel = pwm_get_chip_data(pwm);
80
81 pwm_set_chip_data(pwm, NULL);
82 kfree(channel);
83}
84
58static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev, 85static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev,
59 int duty_ns, int period_ns) 86 int duty_ns, int period_ns)
60{ 87{
@@ -137,6 +164,8 @@ static void berlin_pwm_disable(struct pwm_chip *chip,
137} 164}
138 165
139static const struct pwm_ops berlin_pwm_ops = { 166static const struct pwm_ops berlin_pwm_ops = {
167 .request = berlin_pwm_request,
168 .free = berlin_pwm_free,
140 .config = berlin_pwm_config, 169 .config = berlin_pwm_config,
141 .set_polarity = berlin_pwm_set_polarity, 170 .set_polarity = berlin_pwm_set_polarity,
142 .enable = berlin_pwm_enable, 171 .enable = berlin_pwm_enable,
@@ -204,12 +233,67 @@ static int berlin_pwm_remove(struct platform_device *pdev)
204 return ret; 233 return ret;
205} 234}
206 235
236#ifdef CONFIG_PM_SLEEP
237static int berlin_pwm_suspend(struct device *dev)
238{
239 struct berlin_pwm_chip *pwm = dev_get_drvdata(dev);
240 unsigned int i;
241
242 for (i = 0; i < pwm->chip.npwm; i++) {
243 struct berlin_pwm_channel *channel;
244
245 channel = pwm_get_chip_data(&pwm->chip.pwms[i]);
246 if (!channel)
247 continue;
248
249 channel->enable = berlin_pwm_readl(pwm, i, BERLIN_PWM_ENABLE);
250 channel->ctrl = berlin_pwm_readl(pwm, i, BERLIN_PWM_CONTROL);
251 channel->duty = berlin_pwm_readl(pwm, i, BERLIN_PWM_DUTY);
252 channel->tcnt = berlin_pwm_readl(pwm, i, BERLIN_PWM_TCNT);
253 }
254
255 clk_disable_unprepare(pwm->clk);
256
257 return 0;
258}
259
260static int berlin_pwm_resume(struct device *dev)
261{
262 struct berlin_pwm_chip *pwm = dev_get_drvdata(dev);
263 unsigned int i;
264 int ret;
265
266 ret = clk_prepare_enable(pwm->clk);
267 if (ret)
268 return ret;
269
270 for (i = 0; i < pwm->chip.npwm; i++) {
271 struct berlin_pwm_channel *channel;
272
273 channel = pwm_get_chip_data(&pwm->chip.pwms[i]);
274 if (!channel)
275 continue;
276
277 berlin_pwm_writel(pwm, i, channel->ctrl, BERLIN_PWM_CONTROL);
278 berlin_pwm_writel(pwm, i, channel->duty, BERLIN_PWM_DUTY);
279 berlin_pwm_writel(pwm, i, channel->tcnt, BERLIN_PWM_TCNT);
280 berlin_pwm_writel(pwm, i, channel->enable, BERLIN_PWM_ENABLE);
281 }
282
283 return 0;
284}
285#endif
286
287static SIMPLE_DEV_PM_OPS(berlin_pwm_pm_ops, berlin_pwm_suspend,
288 berlin_pwm_resume);
289
207static struct platform_driver berlin_pwm_driver = { 290static struct platform_driver berlin_pwm_driver = {
208 .probe = berlin_pwm_probe, 291 .probe = berlin_pwm_probe,
209 .remove = berlin_pwm_remove, 292 .remove = berlin_pwm_remove,
210 .driver = { 293 .driver = {
211 .name = "berlin-pwm", 294 .name = "berlin-pwm",
212 .of_match_table = berlin_pwm_match, 295 .of_match_table = berlin_pwm_match,
296 .pm = &berlin_pwm_pm_ops,
213 }, 297 },
214}; 298};
215module_platform_driver(berlin_pwm_driver); 299module_platform_driver(berlin_pwm_driver);
diff --git a/drivers/pwm/pwm-cros-ec.c b/drivers/pwm/pwm-cros-ec.c
index 99b9acc1a420..f6ca4e8c6253 100644
--- a/drivers/pwm/pwm-cros-ec.c
+++ b/drivers/pwm/pwm-cros-ec.c
@@ -38,7 +38,7 @@ static int cros_ec_pwm_set_duty(struct cros_ec_device *ec, u8 index, u16 duty)
38 struct { 38 struct {
39 struct cros_ec_command msg; 39 struct cros_ec_command msg;
40 struct ec_params_pwm_set_duty params; 40 struct ec_params_pwm_set_duty params;
41 } buf; 41 } __packed buf;
42 struct ec_params_pwm_set_duty *params = &buf.params; 42 struct ec_params_pwm_set_duty *params = &buf.params;
43 struct cros_ec_command *msg = &buf.msg; 43 struct cros_ec_command *msg = &buf.msg;
44 44
@@ -65,7 +65,7 @@ static int __cros_ec_pwm_get_duty(struct cros_ec_device *ec, u8 index,
65 struct ec_params_pwm_get_duty params; 65 struct ec_params_pwm_get_duty params;
66 struct ec_response_pwm_get_duty resp; 66 struct ec_response_pwm_get_duty resp;
67 }; 67 };
68 } buf; 68 } __packed buf;
69 struct ec_params_pwm_get_duty *params = &buf.params; 69 struct ec_params_pwm_get_duty *params = &buf.params;
70 struct ec_response_pwm_get_duty *resp = &buf.resp; 70 struct ec_response_pwm_get_duty *resp = &buf.resp;
71 struct cros_ec_command *msg = &buf.msg; 71 struct cros_ec_command *msg = &buf.msg;
diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
index 19dc64cab2f0..d7f5f7de030d 100644
--- a/drivers/pwm/pwm-lpc18xx-sct.c
+++ b/drivers/pwm/pwm-lpc18xx-sct.c
@@ -413,14 +413,18 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
413 } 413 }
414 414
415 for (i = 0; i < lpc18xx_pwm->chip.npwm; i++) { 415 for (i = 0; i < lpc18xx_pwm->chip.npwm; i++) {
416 struct lpc18xx_pwm_data *data;
417
416 pwm = &lpc18xx_pwm->chip.pwms[i]; 418 pwm = &lpc18xx_pwm->chip.pwms[i];
417 pwm->chip_data = devm_kzalloc(lpc18xx_pwm->dev, 419
418 sizeof(struct lpc18xx_pwm_data), 420 data = devm_kzalloc(lpc18xx_pwm->dev, sizeof(*data),
419 GFP_KERNEL); 421 GFP_KERNEL);
420 if (!pwm->chip_data) { 422 if (!data) {
421 ret = -ENOMEM; 423 ret = -ENOMEM;
422 goto remove_pwmchip; 424 goto remove_pwmchip;
423 } 425 }
426
427 pwm_set_chip_data(pwm, data);
424 } 428 }
425 429
426 platform_set_drvdata(pdev, lpc18xx_pwm); 430 platform_set_drvdata(pdev, lpc18xx_pwm);
diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
new file mode 100644
index 000000000000..381871b2bb46
--- /dev/null
+++ b/drivers/pwm/pwm-meson.c
@@ -0,0 +1,529 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright (c) 2016 BayLibre, SAS.
8 * Author: Neil Armstrong <narmstrong@baylibre.com>
9 * Copyright (C) 2014 Amlogic, Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 * The full GNU General Public License is included in this distribution
23 * in the file called COPYING.
24 *
25 * BSD LICENSE
26 *
27 * Copyright (c) 2016 BayLibre, SAS.
28 * Author: Neil Armstrong <narmstrong@baylibre.com>
29 * Copyright (C) 2014 Amlogic, Inc.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 *
35 * * Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * * Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in
39 * the documentation and/or other materials provided with the
40 * distribution.
41 * * Neither the name of Intel Corporation nor the names of its
42 * contributors may be used to endorse or promote products derived
43 * from this software without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
48 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
49 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
52 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
53 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
55 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 */
57
58#include <linux/clk.h>
59#include <linux/clk-provider.h>
60#include <linux/err.h>
61#include <linux/io.h>
62#include <linux/kernel.h>
63#include <linux/module.h>
64#include <linux/of.h>
65#include <linux/of_device.h>
66#include <linux/platform_device.h>
67#include <linux/pwm.h>
68#include <linux/slab.h>
69#include <linux/spinlock.h>
70
71#define REG_PWM_A 0x0
72#define REG_PWM_B 0x4
73#define PWM_HIGH_SHIFT 16
74
75#define REG_MISC_AB 0x8
76#define MISC_B_CLK_EN BIT(23)
77#define MISC_A_CLK_EN BIT(15)
78#define MISC_CLK_DIV_MASK 0x7f
79#define MISC_B_CLK_DIV_SHIFT 16
80#define MISC_A_CLK_DIV_SHIFT 8
81#define MISC_B_CLK_SEL_SHIFT 6
82#define MISC_A_CLK_SEL_SHIFT 4
83#define MISC_CLK_SEL_WIDTH 2
84#define MISC_B_EN BIT(1)
85#define MISC_A_EN BIT(0)
86
87static const unsigned int mux_reg_shifts[] = {
88 MISC_A_CLK_SEL_SHIFT,
89 MISC_B_CLK_SEL_SHIFT
90};
91
92struct meson_pwm_channel {
93 unsigned int hi;
94 unsigned int lo;
95 u8 pre_div;
96
97 struct pwm_state state;
98
99 struct clk *clk_parent;
100 struct clk_mux mux;
101 struct clk *clk;
102};
103
104struct meson_pwm_data {
105 const char * const *parent_names;
106};
107
108struct meson_pwm {
109 struct pwm_chip chip;
110 const struct meson_pwm_data *data;
111 void __iomem *base;
112 u8 inverter_mask;
113 spinlock_t lock;
114};
115
116static inline struct meson_pwm *to_meson_pwm(struct pwm_chip *chip)
117{
118 return container_of(chip, struct meson_pwm, chip);
119}
120
121static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
122{
123 struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
124 struct device *dev = chip->dev;
125 int err;
126
127 if (!channel)
128 return -ENODEV;
129
130 if (channel->clk_parent) {
131 err = clk_set_parent(channel->clk, channel->clk_parent);
132 if (err < 0) {
133 dev_err(dev, "failed to set parent %s for %s: %d\n",
134 __clk_get_name(channel->clk_parent),
135 __clk_get_name(channel->clk), err);
136 return err;
137 }
138 }
139
140 err = clk_prepare_enable(channel->clk);
141 if (err < 0) {
142 dev_err(dev, "failed to enable clock %s: %d\n",
143 __clk_get_name(channel->clk), err);
144 return err;
145 }
146
147 chip->ops->get_state(chip, pwm, &channel->state);
148
149 return 0;
150}
151
152static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
153{
154 struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
155
156 if (channel)
157 clk_disable_unprepare(channel->clk);
158}
159
160static int meson_pwm_calc(struct meson_pwm *meson,
161 struct meson_pwm_channel *channel, unsigned int id,
162 unsigned int duty, unsigned int period)
163{
164 unsigned int pre_div, cnt, duty_cnt;
165 unsigned long fin_freq = -1, fin_ns;
166
167 if (~(meson->inverter_mask >> id) & 0x1)
168 duty = period - duty;
169
170 if (period == channel->state.period &&
171 duty == channel->state.duty_cycle)
172 return 0;
173
174 fin_freq = clk_get_rate(channel->clk);
175 if (fin_freq == 0) {
176 dev_err(meson->chip.dev, "invalid source clock frequency\n");
177 return -EINVAL;
178 }
179
180 dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq);
181 fin_ns = NSEC_PER_SEC / fin_freq;
182
183 /* Calc pre_div with the period */
184 for (pre_div = 0; pre_div < MISC_CLK_DIV_MASK; pre_div++) {
185 cnt = DIV_ROUND_CLOSEST(period, fin_ns * (pre_div + 1));
186 dev_dbg(meson->chip.dev, "fin_ns=%lu pre_div=%u cnt=%u\n",
187 fin_ns, pre_div, cnt);
188 if (cnt <= 0xffff)
189 break;
190 }
191
192 if (pre_div == MISC_CLK_DIV_MASK) {
193 dev_err(meson->chip.dev, "unable to get period pre_div\n");
194 return -EINVAL;
195 }
196
197 dev_dbg(meson->chip.dev, "period=%u pre_div=%u cnt=%u\n", period,
198 pre_div, cnt);
199
200 if (duty == period) {
201 channel->pre_div = pre_div;
202 channel->hi = cnt;
203 channel->lo = 0;
204 } else if (duty == 0) {
205 channel->pre_div = pre_div;
206 channel->hi = 0;
207 channel->lo = cnt;
208 } else {
209 /* Then check is we can have the duty with the same pre_div */
210 duty_cnt = DIV_ROUND_CLOSEST(duty, fin_ns * (pre_div + 1));
211 if (duty_cnt > 0xffff) {
212 dev_err(meson->chip.dev, "unable to get duty cycle\n");
213 return -EINVAL;
214 }
215
216 dev_dbg(meson->chip.dev, "duty=%u pre_div=%u duty_cnt=%u\n",
217 duty, pre_div, duty_cnt);
218
219 channel->pre_div = pre_div;
220 channel->hi = duty_cnt;
221 channel->lo = cnt - duty_cnt;
222 }
223
224 return 0;
225}
226
227static void meson_pwm_enable(struct meson_pwm *meson,
228 struct meson_pwm_channel *channel,
229 unsigned int id)
230{
231 u32 value, clk_shift, clk_enable, enable;
232 unsigned int offset;
233
234 switch (id) {
235 case 0:
236 clk_shift = MISC_A_CLK_DIV_SHIFT;
237 clk_enable = MISC_A_CLK_EN;
238 enable = MISC_A_EN;
239 offset = REG_PWM_A;
240 break;
241
242 case 1:
243 clk_shift = MISC_B_CLK_DIV_SHIFT;
244 clk_enable = MISC_B_CLK_EN;
245 enable = MISC_B_EN;
246 offset = REG_PWM_B;
247 break;
248
249 default:
250 return;
251 }
252
253 value = readl(meson->base + REG_MISC_AB);
254 value &= ~(MISC_CLK_DIV_MASK << clk_shift);
255 value |= channel->pre_div << clk_shift;
256 value |= clk_enable;
257 writel(value, meson->base + REG_MISC_AB);
258
259 value = (channel->hi << PWM_HIGH_SHIFT) | channel->lo;
260 writel(value, meson->base + offset);
261
262 value = readl(meson->base + REG_MISC_AB);
263 value |= enable;
264 writel(value, meson->base + REG_MISC_AB);
265}
266
267static void meson_pwm_disable(struct meson_pwm *meson, unsigned int id)
268{
269 u32 value, enable;
270
271 switch (id) {
272 case 0:
273 enable = MISC_A_EN;
274 break;
275
276 case 1:
277 enable = MISC_B_EN;
278 break;
279
280 default:
281 return;
282 }
283
284 value = readl(meson->base + REG_MISC_AB);
285 value &= ~enable;
286 writel(value, meson->base + REG_MISC_AB);
287}
288
289static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
290 struct pwm_state *state)
291{
292 struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
293 struct meson_pwm *meson = to_meson_pwm(chip);
294 unsigned long flags;
295 int err = 0;
296
297 if (!state)
298 return -EINVAL;
299
300 spin_lock_irqsave(&meson->lock, flags);
301
302 if (!state->enabled) {
303 meson_pwm_disable(meson, pwm->hwpwm);
304 channel->state.enabled = false;
305
306 goto unlock;
307 }
308
309 if (state->period != channel->state.period ||
310 state->duty_cycle != channel->state.duty_cycle ||
311 state->polarity != channel->state.polarity) {
312 if (channel->state.enabled) {
313 meson_pwm_disable(meson, pwm->hwpwm);
314 channel->state.enabled = false;
315 }
316
317 if (state->polarity != channel->state.polarity) {
318 if (state->polarity == PWM_POLARITY_NORMAL)
319 meson->inverter_mask |= BIT(pwm->hwpwm);
320 else
321 meson->inverter_mask &= ~BIT(pwm->hwpwm);
322 }
323
324 err = meson_pwm_calc(meson, channel, pwm->hwpwm,
325 state->duty_cycle, state->period);
326 if (err < 0)
327 goto unlock;
328
329 channel->state.polarity = state->polarity;
330 channel->state.period = state->period;
331 channel->state.duty_cycle = state->duty_cycle;
332 }
333
334 if (state->enabled && !channel->state.enabled) {
335 meson_pwm_enable(meson, channel, pwm->hwpwm);
336 channel->state.enabled = true;
337 }
338
339unlock:
340 spin_unlock_irqrestore(&meson->lock, flags);
341 return err;
342}
343
344static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
345 struct pwm_state *state)
346{
347 struct meson_pwm *meson = to_meson_pwm(chip);
348 u32 value, mask;
349
350 if (!state)
351 return;
352
353 switch (pwm->hwpwm) {
354 case 0:
355 mask = MISC_A_EN;
356 break;
357
358 case 1:
359 mask = MISC_B_EN;
360 break;
361
362 default:
363 return;
364 }
365
366 value = readl(meson->base + REG_MISC_AB);
367 state->enabled = (value & mask) != 0;
368}
369
370static const struct pwm_ops meson_pwm_ops = {
371 .request = meson_pwm_request,
372 .free = meson_pwm_free,
373 .apply = meson_pwm_apply,
374 .get_state = meson_pwm_get_state,
375 .owner = THIS_MODULE,
376};
377
378static const char * const pwm_meson8b_parent_names[] = {
379 "xtal", "vid_pll", "fclk_div4", "fclk_div3"
380};
381
382static const struct meson_pwm_data pwm_meson8b_data = {
383 .parent_names = pwm_meson8b_parent_names,
384};
385
386static const char * const pwm_gxbb_parent_names[] = {
387 "xtal", "hdmi_pll", "fclk_div4", "fclk_div3"
388};
389
390static const struct meson_pwm_data pwm_gxbb_data = {
391 .parent_names = pwm_gxbb_parent_names,
392};
393
394static const struct of_device_id meson_pwm_matches[] = {
395 { .compatible = "amlogic,meson8b-pwm", .data = &pwm_meson8b_data },
396 { .compatible = "amlogic,meson-gxbb-pwm", .data = &pwm_gxbb_data },
397 {},
398};
399MODULE_DEVICE_TABLE(of, meson_pwm_matches);
400
401static int meson_pwm_init_channels(struct meson_pwm *meson,
402 struct meson_pwm_channel *channels)
403{
404 struct device *dev = meson->chip.dev;
405 struct device_node *np = dev->of_node;
406 struct clk_init_data init;
407 unsigned int i;
408 char name[255];
409 int err;
410
411 for (i = 0; i < meson->chip.npwm; i++) {
412 struct meson_pwm_channel *channel = &channels[i];
413
414 snprintf(name, sizeof(name), "%s#mux%u", np->full_name, i);
415
416 init.name = name;
417 init.ops = &clk_mux_ops;
418 init.flags = CLK_IS_BASIC;
419 init.parent_names = meson->data->parent_names;
420 init.num_parents = 1 << MISC_CLK_SEL_WIDTH;
421
422 channel->mux.reg = meson->base + REG_MISC_AB;
423 channel->mux.shift = mux_reg_shifts[i];
424 channel->mux.mask = BIT(MISC_CLK_SEL_WIDTH) - 1;
425 channel->mux.flags = 0;
426 channel->mux.lock = &meson->lock;
427 channel->mux.table = NULL;
428 channel->mux.hw.init = &init;
429
430 channel->clk = devm_clk_register(dev, &channel->mux.hw);
431 if (IS_ERR(channel->clk)) {
432 err = PTR_ERR(channel->clk);
433 dev_err(dev, "failed to register %s: %d\n", name, err);
434 return err;
435 }
436
437 snprintf(name, sizeof(name), "clkin%u", i);
438
439 channel->clk_parent = devm_clk_get(dev, name);
440 if (IS_ERR(channel->clk_parent)) {
441 err = PTR_ERR(channel->clk_parent);
442 if (err == -EPROBE_DEFER)
443 return err;
444
445 channel->clk_parent = NULL;
446 }
447 }
448
449 return 0;
450}
451
452static void meson_pwm_add_channels(struct meson_pwm *meson,
453 struct meson_pwm_channel *channels)
454{
455 unsigned int i;
456
457 for (i = 0; i < meson->chip.npwm; i++)
458 pwm_set_chip_data(&meson->chip.pwms[i], &channels[i]);
459}
460
461static int meson_pwm_probe(struct platform_device *pdev)
462{
463 struct meson_pwm_channel *channels;
464 struct meson_pwm *meson;
465 struct resource *regs;
466 int err;
467
468 meson = devm_kzalloc(&pdev->dev, sizeof(*meson), GFP_KERNEL);
469 if (!meson)
470 return -ENOMEM;
471
472 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
473 meson->base = devm_ioremap_resource(&pdev->dev, regs);
474 if (IS_ERR(meson->base))
475 return PTR_ERR(meson->base);
476
477 meson->chip.dev = &pdev->dev;
478 meson->chip.ops = &meson_pwm_ops;
479 meson->chip.base = -1;
480 meson->chip.npwm = 2;
481 meson->chip.of_xlate = of_pwm_xlate_with_flags;
482 meson->chip.of_pwm_n_cells = 3;
483
484 meson->data = of_device_get_match_data(&pdev->dev);
485 meson->inverter_mask = BIT(meson->chip.npwm) - 1;
486
487 channels = devm_kcalloc(&pdev->dev, meson->chip.npwm, sizeof(*meson),
488 GFP_KERNEL);
489 if (!channels)
490 return -ENOMEM;
491
492 err = meson_pwm_init_channels(meson, channels);
493 if (err < 0)
494 return err;
495
496 err = pwmchip_add(&meson->chip);
497 if (err < 0) {
498 dev_err(&pdev->dev, "failed to register PWM chip: %d\n", err);
499 return err;
500 }
501
502 meson_pwm_add_channels(meson, channels);
503
504 platform_set_drvdata(pdev, meson);
505
506 return 0;
507}
508
509static int meson_pwm_remove(struct platform_device *pdev)
510{
511 struct meson_pwm *meson = platform_get_drvdata(pdev);
512
513 return pwmchip_remove(&meson->chip);
514}
515
516static struct platform_driver meson_pwm_driver = {
517 .driver = {
518 .name = "meson-pwm",
519 .of_match_table = meson_pwm_matches,
520 },
521 .probe = meson_pwm_probe,
522 .remove = meson_pwm_remove,
523};
524module_platform_driver(meson_pwm_driver);
525
526MODULE_ALIAS("platform:meson-pwm");
527MODULE_DESCRIPTION("Amlogic Meson PWM Generator driver");
528MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
529MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index 0ad3385298c0..893940d45f0d 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -18,30 +18,40 @@
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_device.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/pwm.h> 23#include <linux/pwm.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
24 25
25#define DISP_PWM_EN 0x00 26#define DISP_PWM_EN 0x00
26#define PWM_ENABLE_MASK BIT(0)
27 27
28#define DISP_PWM_COMMIT 0x08
29#define PWM_COMMIT_MASK BIT(0)
30
31#define DISP_PWM_CON_0 0x10
32#define PWM_CLKDIV_SHIFT 16 28#define PWM_CLKDIV_SHIFT 16
33#define PWM_CLKDIV_MAX 0x3ff 29#define PWM_CLKDIV_MAX 0x3ff
34#define PWM_CLKDIV_MASK (PWM_CLKDIV_MAX << PWM_CLKDIV_SHIFT) 30#define PWM_CLKDIV_MASK (PWM_CLKDIV_MAX << PWM_CLKDIV_SHIFT)
35 31
36#define DISP_PWM_CON_1 0x14
37#define PWM_PERIOD_BIT_WIDTH 12 32#define PWM_PERIOD_BIT_WIDTH 12
38#define PWM_PERIOD_MASK ((1 << PWM_PERIOD_BIT_WIDTH) - 1) 33#define PWM_PERIOD_MASK ((1 << PWM_PERIOD_BIT_WIDTH) - 1)
39 34
40#define PWM_HIGH_WIDTH_SHIFT 16 35#define PWM_HIGH_WIDTH_SHIFT 16
41#define PWM_HIGH_WIDTH_MASK (0x1fff << PWM_HIGH_WIDTH_SHIFT) 36#define PWM_HIGH_WIDTH_MASK (0x1fff << PWM_HIGH_WIDTH_SHIFT)
42 37
38struct mtk_pwm_data {
39 u32 enable_mask;
40 unsigned int con0;
41 u32 con0_sel;
42 unsigned int con1;
43
44 bool has_commit;
45 unsigned int commit;
46 unsigned int commit_mask;
47
48 unsigned int bls_debug;
49 u32 bls_debug_mask;
50};
51
43struct mtk_disp_pwm { 52struct mtk_disp_pwm {
44 struct pwm_chip chip; 53 struct pwm_chip chip;
54 const struct mtk_pwm_data *data;
45 struct clk *clk_main; 55 struct clk *clk_main;
46 struct clk *clk_mm; 56 struct clk *clk_mm;
47 void __iomem *base; 57 void __iomem *base;
@@ -106,12 +116,21 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
106 return err; 116 return err;
107 } 117 }
108 118
109 mtk_disp_pwm_update_bits(mdp, DISP_PWM_CON_0, PWM_CLKDIV_MASK, 119 mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
120 PWM_CLKDIV_MASK,
110 clk_div << PWM_CLKDIV_SHIFT); 121 clk_div << PWM_CLKDIV_SHIFT);
111 mtk_disp_pwm_update_bits(mdp, DISP_PWM_CON_1, 122 mtk_disp_pwm_update_bits(mdp, mdp->data->con1,
112 PWM_PERIOD_MASK | PWM_HIGH_WIDTH_MASK, value); 123 PWM_PERIOD_MASK | PWM_HIGH_WIDTH_MASK,
113 mtk_disp_pwm_update_bits(mdp, DISP_PWM_COMMIT, PWM_COMMIT_MASK, 1); 124 value);
114 mtk_disp_pwm_update_bits(mdp, DISP_PWM_COMMIT, PWM_COMMIT_MASK, 0); 125
126 if (mdp->data->has_commit) {
127 mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
128 mdp->data->commit_mask,
129 mdp->data->commit_mask);
130 mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
131 mdp->data->commit_mask,
132 0x0);
133 }
115 134
116 clk_disable(mdp->clk_mm); 135 clk_disable(mdp->clk_mm);
117 clk_disable(mdp->clk_main); 136 clk_disable(mdp->clk_main);
@@ -134,7 +153,8 @@ static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
134 return err; 153 return err;
135 } 154 }
136 155
137 mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, PWM_ENABLE_MASK, 1); 156 mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
157 mdp->data->enable_mask);
138 158
139 return 0; 159 return 0;
140} 160}
@@ -143,7 +163,8 @@ static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
143{ 163{
144 struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip); 164 struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
145 165
146 mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, PWM_ENABLE_MASK, 0); 166 mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
167 0x0);
147 168
148 clk_disable(mdp->clk_mm); 169 clk_disable(mdp->clk_mm);
149 clk_disable(mdp->clk_main); 170 clk_disable(mdp->clk_main);
@@ -166,6 +187,8 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
166 if (!mdp) 187 if (!mdp)
167 return -ENOMEM; 188 return -ENOMEM;
168 189
190 mdp->data = of_device_get_match_data(&pdev->dev);
191
169 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 192 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
170 mdp->base = devm_ioremap_resource(&pdev->dev, r); 193 mdp->base = devm_ioremap_resource(&pdev->dev, r);
171 if (IS_ERR(mdp->base)) 194 if (IS_ERR(mdp->base))
@@ -200,6 +223,19 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
200 223
201 platform_set_drvdata(pdev, mdp); 224 platform_set_drvdata(pdev, mdp);
202 225
226 /*
227 * For MT2701, disable double buffer before writing register
228 * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
229 */
230 if (!mdp->data->has_commit) {
231 mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
232 mdp->data->bls_debug_mask,
233 mdp->data->bls_debug_mask);
234 mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
235 mdp->data->con0_sel,
236 mdp->data->con0_sel);
237 }
238
203 return 0; 239 return 0;
204 240
205disable_clk_mm: 241disable_clk_mm:
@@ -221,9 +257,30 @@ static int mtk_disp_pwm_remove(struct platform_device *pdev)
221 return ret; 257 return ret;
222} 258}
223 259
260static const struct mtk_pwm_data mt2701_pwm_data = {
261 .enable_mask = BIT(16),
262 .con0 = 0xa8,
263 .con0_sel = 0x2,
264 .con1 = 0xac,
265 .has_commit = false,
266 .bls_debug = 0xb0,
267 .bls_debug_mask = 0x3,
268};
269
270static const struct mtk_pwm_data mt8173_pwm_data = {
271 .enable_mask = BIT(0),
272 .con0 = 0x10,
273 .con0_sel = 0x0,
274 .con1 = 0x14,
275 .has_commit = true,
276 .commit = 0x8,
277 .commit_mask = 0x1,
278};
279
224static const struct of_device_id mtk_disp_pwm_of_match[] = { 280static const struct of_device_id mtk_disp_pwm_of_match[] = {
225 { .compatible = "mediatek,mt8173-disp-pwm" }, 281 { .compatible = "mediatek,mt2701-disp-pwm", .data = &mt2701_pwm_data},
226 { .compatible = "mediatek,mt6595-disp-pwm" }, 282 { .compatible = "mediatek,mt6595-disp-pwm", .data = &mt8173_pwm_data},
283 { .compatible = "mediatek,mt8173-disp-pwm", .data = &mt8173_pwm_data},
227 { } 284 { }
228}; 285};
229MODULE_DEVICE_TABLE(of, mtk_disp_pwm_of_match); 286MODULE_DEVICE_TABLE(of, mtk_disp_pwm_of_match);
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index ada2d326dc3e..f113cda47032 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -193,9 +193,18 @@ static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
193 * divider settings and choose the lowest divisor that can generate 193 * divider settings and choose the lowest divisor that can generate
194 * frequencies lower than requested. 194 * frequencies lower than requested.
195 */ 195 */
196 for (div = variant->div_base; div < 4; ++div) 196 if (variant->bits < 32) {
197 if ((rate >> (variant->bits + div)) < freq) 197 /* Only for s3c24xx */
198 break; 198 for (div = variant->div_base; div < 4; ++div)
199 if ((rate >> (variant->bits + div)) < freq)
200 break;
201 } else {
202 /*
203 * Other variants have enough counter bits to generate any
204 * requested rate, so no need to check higher divisors.
205 */
206 div = variant->div_base;
207 }
199 208
200 pwm_samsung_set_divisor(chip, chan, BIT(div)); 209 pwm_samsung_set_divisor(chip, chan, BIT(div));
201 210
diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c
index 92abbd56b9f7..dd82dc840af9 100644
--- a/drivers/pwm/pwm-sti.c
+++ b/drivers/pwm/pwm-sti.c
@@ -1,8 +1,10 @@
1/* 1/*
2 * PWM device driver for ST SoCs. 2 * PWM device driver for ST SoCs
3 * Author: Ajit Pal Singh <ajitpal.singh@st.com> 3 *
4 * Copyright (C) 2013-2016 STMicroelectronics (R&D) Limited
4 * 5 *
5 * Copyright (C) 2013-2014 STMicroelectronics (R&D) Limited 6 * Author: Ajit Pal Singh <ajitpal.singh@st.com>
7 * Lee Jones <lee.jones@linaro.org>
6 * 8 *
7 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -11,6 +13,7 @@
11 */ 13 */
12 14
13#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/interrupt.h>
14#include <linux/math64.h> 17#include <linux/math64.h>
15#include <linux/mfd/syscon.h> 18#include <linux/mfd/syscon.h>
16#include <linux/module.h> 19#include <linux/module.h>
@@ -18,43 +21,82 @@
18#include <linux/platform_device.h> 21#include <linux/platform_device.h>
19#include <linux/pwm.h> 22#include <linux/pwm.h>
20#include <linux/regmap.h> 23#include <linux/regmap.h>
24#include <linux/sched.h>
21#include <linux/slab.h> 25#include <linux/slab.h>
22#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/wait.h>
28
29#define PWM_OUT_VAL(x) (0x00 + (4 * (x))) /* Device's Duty Cycle register */
30#define PWM_CPT_VAL(x) (0x10 + (4 * (x))) /* Capture value */
31#define PWM_CPT_EDGE(x) (0x30 + (4 * (x))) /* Edge to capture on */
23 32
24#define STI_DS_REG(ch) (4 * (ch)) /* Channel's Duty Cycle register */ 33#define STI_PWM_CTRL 0x50 /* Control/Config register */
25#define STI_PWMCR 0x50 /* Control/Config register */ 34#define STI_INT_EN 0x54 /* Interrupt Enable/Disable register */
26#define STI_INTEN 0x54 /* Interrupt Enable/Disable register */ 35#define STI_INT_STA 0x58 /* Interrupt Status register */
27#define PWM_PRESCALE_LOW_MASK 0x0f 36#define PWM_INT_ACK 0x5c
28#define PWM_PRESCALE_HIGH_MASK 0xf0 37#define PWM_PRESCALE_LOW_MASK 0x0f
38#define PWM_PRESCALE_HIGH_MASK 0xf0
39#define PWM_CPT_EDGE_MASK 0x03
40#define PWM_INT_ACK_MASK 0x1ff
41
42#define STI_MAX_CPT_DEVS 4
43#define CPT_DC_MAX 0xff
29 44
30/* Regfield IDs */ 45/* Regfield IDs */
31enum { 46enum {
47 /* Bits in PWM_CTRL*/
32 PWMCLK_PRESCALE_LOW, 48 PWMCLK_PRESCALE_LOW,
33 PWMCLK_PRESCALE_HIGH, 49 PWMCLK_PRESCALE_HIGH,
34 PWM_EN, 50 CPTCLK_PRESCALE,
35 PWM_INT_EN, 51
52 PWM_OUT_EN,
53 PWM_CPT_EN,
54
55 PWM_CPT_INT_EN,
56 PWM_CPT_INT_STAT,
36 57
37 /* Keep last */ 58 /* Keep last */
38 MAX_REGFIELDS 59 MAX_REGFIELDS
39}; 60};
40 61
62/*
63 * Each capture input can be programmed to detect rising-edge, falling-edge,
64 * either edge or neither egde.
65 */
66enum sti_cpt_edge {
67 CPT_EDGE_DISABLED,
68 CPT_EDGE_RISING,
69 CPT_EDGE_FALLING,
70 CPT_EDGE_BOTH,
71};
72
73struct sti_cpt_ddata {
74 u32 snapshot[3];
75 unsigned int index;
76 struct mutex lock;
77 wait_queue_head_t wait;
78};
79
41struct sti_pwm_compat_data { 80struct sti_pwm_compat_data {
42 const struct reg_field *reg_fields; 81 const struct reg_field *reg_fields;
43 unsigned int num_chan; 82 unsigned int pwm_num_devs;
83 unsigned int cpt_num_devs;
44 unsigned int max_pwm_cnt; 84 unsigned int max_pwm_cnt;
45 unsigned int max_prescale; 85 unsigned int max_prescale;
46}; 86};
47 87
48struct sti_pwm_chip { 88struct sti_pwm_chip {
49 struct device *dev; 89 struct device *dev;
50 struct clk *clk; 90 struct clk *pwm_clk;
51 unsigned long clk_rate; 91 struct clk *cpt_clk;
52 struct regmap *regmap; 92 struct regmap *regmap;
53 struct sti_pwm_compat_data *cdata; 93 struct sti_pwm_compat_data *cdata;
54 struct regmap_field *prescale_low; 94 struct regmap_field *prescale_low;
55 struct regmap_field *prescale_high; 95 struct regmap_field *prescale_high;
56 struct regmap_field *pwm_en; 96 struct regmap_field *pwm_out_en;
57 struct regmap_field *pwm_int_en; 97 struct regmap_field *pwm_cpt_en;
98 struct regmap_field *pwm_cpt_int_en;
99 struct regmap_field *pwm_cpt_int_stat;
58 struct pwm_chip chip; 100 struct pwm_chip chip;
59 struct pwm_device *cur; 101 struct pwm_device *cur;
60 unsigned long configured; 102 unsigned long configured;
@@ -64,10 +106,13 @@ struct sti_pwm_chip {
64}; 106};
65 107
66static const struct reg_field sti_pwm_regfields[MAX_REGFIELDS] = { 108static const struct reg_field sti_pwm_regfields[MAX_REGFIELDS] = {
67 [PWMCLK_PRESCALE_LOW] = REG_FIELD(STI_PWMCR, 0, 3), 109 [PWMCLK_PRESCALE_LOW] = REG_FIELD(STI_PWM_CTRL, 0, 3),
68 [PWMCLK_PRESCALE_HIGH] = REG_FIELD(STI_PWMCR, 11, 14), 110 [PWMCLK_PRESCALE_HIGH] = REG_FIELD(STI_PWM_CTRL, 11, 14),
69 [PWM_EN] = REG_FIELD(STI_PWMCR, 9, 9), 111 [CPTCLK_PRESCALE] = REG_FIELD(STI_PWM_CTRL, 4, 8),
70 [PWM_INT_EN] = REG_FIELD(STI_INTEN, 0, 0), 112 [PWM_OUT_EN] = REG_FIELD(STI_PWM_CTRL, 9, 9),
113 [PWM_CPT_EN] = REG_FIELD(STI_PWM_CTRL, 10, 10),
114 [PWM_CPT_INT_EN] = REG_FIELD(STI_INT_EN, 1, 4),
115 [PWM_CPT_INT_STAT] = REG_FIELD(STI_INT_STA, 1, 4),
71}; 116};
72 117
73static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip) 118static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip)
@@ -82,61 +127,68 @@ static int sti_pwm_get_prescale(struct sti_pwm_chip *pc, unsigned long period,
82 unsigned int *prescale) 127 unsigned int *prescale)
83{ 128{
84 struct sti_pwm_compat_data *cdata = pc->cdata; 129 struct sti_pwm_compat_data *cdata = pc->cdata;
85 unsigned long val; 130 unsigned long clk_rate;
131 unsigned long value;
86 unsigned int ps; 132 unsigned int ps;
87 133
134 clk_rate = clk_get_rate(pc->pwm_clk);
135 if (!clk_rate) {
136 dev_err(pc->dev, "failed to get clock rate\n");
137 return -EINVAL;
138 }
139
88 /* 140 /*
89 * prescale = ((period_ns * clk_rate) / (10^9 * (max_pwm_count + 1)) - 1 141 * prescale = ((period_ns * clk_rate) / (10^9 * (max_pwm_cnt + 1)) - 1
90 */ 142 */
91 val = NSEC_PER_SEC / pc->clk_rate; 143 value = NSEC_PER_SEC / clk_rate;
92 val *= cdata->max_pwm_cnt + 1; 144 value *= cdata->max_pwm_cnt + 1;
93 145
94 if (period % val) { 146 if (period % value)
95 return -EINVAL; 147 return -EINVAL;
96 } else { 148
97 ps = period / val - 1; 149 ps = period / value - 1;
98 if (ps > cdata->max_prescale) 150 if (ps > cdata->max_prescale)
99 return -EINVAL; 151 return -EINVAL;
100 } 152
101 *prescale = ps; 153 *prescale = ps;
102 154
103 return 0; 155 return 0;
104} 156}
105 157
106/* 158/*
107 * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. 159 * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. The
108 * The only way to change the period (apart from changing the PWM input clock) 160 * only way to change the period (apart from changing the PWM input clock) is
109 * is to change the PWM clock prescaler. 161 * to change the PWM clock prescaler.
110 * The prescaler is of 8 bits, so 256 prescaler values and hence 162 *
111 * 256 possible period values are supported (for a particular clock rate). 163 * The prescaler is of 8 bits, so 256 prescaler values and hence 256 possible
112 * The requested period will be applied only if it matches one of these 164 * period values are supported (for a particular clock rate). The requested
113 * 256 values. 165 * period will be applied only if it matches one of these 256 values.
114 */ 166 */
115static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 167static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
116 int duty_ns, int period_ns) 168 int duty_ns, int period_ns)
117{ 169{
118 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); 170 struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
119 struct sti_pwm_compat_data *cdata = pc->cdata; 171 struct sti_pwm_compat_data *cdata = pc->cdata;
172 unsigned int ncfg, value, prescale = 0;
120 struct pwm_device *cur = pc->cur; 173 struct pwm_device *cur = pc->cur;
121 struct device *dev = pc->dev; 174 struct device *dev = pc->dev;
122 unsigned int prescale = 0, pwmvalx;
123 int ret;
124 unsigned int ncfg;
125 bool period_same = false; 175 bool period_same = false;
176 int ret;
126 177
127 ncfg = hweight_long(pc->configured); 178 ncfg = hweight_long(pc->configured);
128 if (ncfg) 179 if (ncfg)
129 period_same = (period_ns == pwm_get_period(cur)); 180 period_same = (period_ns == pwm_get_period(cur));
130 181
131 /* Allow configuration changes if one of the 182 /*
132 * following conditions satisfy. 183 * Allow configuration changes if one of the following conditions
133 * 1. No channels have been configured. 184 * satisfy.
134 * 2. Only one channel has been configured and the new request 185 * 1. No devices have been configured.
135 * is for the same channel. 186 * 2. Only one device has been configured and the new request is for
136 * 3. Only one channel has been configured and the new request is 187 * the same device.
137 * for a new channel and period of the new channel is same as 188 * 3. Only one device has been configured and the new request is for
138 * the current configured period. 189 * a new device and period of the new device is same as the current
139 * 4. More than one channels are configured and period of the new 190 * configured period.
191 * 4. More than one devices are configured and period of the new
140 * requestis the same as the current period. 192 * requestis the same as the current period.
141 */ 193 */
142 if (!ncfg || 194 if (!ncfg ||
@@ -144,7 +196,11 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
144 ((ncfg == 1) && (pwm->hwpwm != cur->hwpwm) && period_same) || 196 ((ncfg == 1) && (pwm->hwpwm != cur->hwpwm) && period_same) ||
145 ((ncfg > 1) && period_same)) { 197 ((ncfg > 1) && period_same)) {
146 /* Enable clock before writing to PWM registers. */ 198 /* Enable clock before writing to PWM registers. */
147 ret = clk_enable(pc->clk); 199 ret = clk_enable(pc->pwm_clk);
200 if (ret)
201 return ret;
202
203 ret = clk_enable(pc->cpt_clk);
148 if (ret) 204 if (ret)
149 return ret; 205 return ret;
150 206
@@ -153,15 +209,15 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
153 if (ret) 209 if (ret)
154 goto clk_dis; 210 goto clk_dis;
155 211
156 ret = 212 value = prescale & PWM_PRESCALE_LOW_MASK;
157 regmap_field_write(pc->prescale_low, 213
158 prescale & PWM_PRESCALE_LOW_MASK); 214 ret = regmap_field_write(pc->prescale_low, value);
159 if (ret) 215 if (ret)
160 goto clk_dis; 216 goto clk_dis;
161 217
162 ret = 218 value = (prescale & PWM_PRESCALE_HIGH_MASK) >> 4;
163 regmap_field_write(pc->prescale_high, 219
164 (prescale & PWM_PRESCALE_HIGH_MASK) >> 4); 220 ret = regmap_field_write(pc->prescale_high, value);
165 if (ret) 221 if (ret)
166 goto clk_dis; 222 goto clk_dis;
167 } 223 }
@@ -172,25 +228,26 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
172 * PWM pulse = (max_pwm_count + 1) local cycles, 228 * PWM pulse = (max_pwm_count + 1) local cycles,
173 * that is continuous pulse: signal never goes low. 229 * that is continuous pulse: signal never goes low.
174 */ 230 */
175 pwmvalx = cdata->max_pwm_cnt * duty_ns / period_ns; 231 value = cdata->max_pwm_cnt * duty_ns / period_ns;
176 232
177 ret = regmap_write(pc->regmap, STI_DS_REG(pwm->hwpwm), pwmvalx); 233 ret = regmap_write(pc->regmap, PWM_OUT_VAL(pwm->hwpwm), value);
178 if (ret) 234 if (ret)
179 goto clk_dis; 235 goto clk_dis;
180 236
181 ret = regmap_field_write(pc->pwm_int_en, 0); 237 ret = regmap_field_write(pc->pwm_cpt_int_en, 0);
182 238
183 set_bit(pwm->hwpwm, &pc->configured); 239 set_bit(pwm->hwpwm, &pc->configured);
184 pc->cur = pwm; 240 pc->cur = pwm;
185 241
186 dev_dbg(dev, "prescale:%u, period:%i, duty:%i, pwmvalx:%u\n", 242 dev_dbg(dev, "prescale:%u, period:%i, duty:%i, value:%u\n",
187 prescale, period_ns, duty_ns, pwmvalx); 243 prescale, period_ns, duty_ns, value);
188 } else { 244 } else {
189 return -EINVAL; 245 return -EINVAL;
190 } 246 }
191 247
192clk_dis: 248clk_dis:
193 clk_disable(pc->clk); 249 clk_disable(pc->pwm_clk);
250 clk_disable(pc->cpt_clk);
194 return ret; 251 return ret;
195} 252}
196 253
@@ -201,23 +258,30 @@ static int sti_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
201 int ret = 0; 258 int ret = 0;
202 259
203 /* 260 /*
204 * Since we have a common enable for all PWM channels, 261 * Since we have a common enable for all PWM devices, do not enable if
205 * do not enable if already enabled. 262 * already enabled.
206 */ 263 */
207 mutex_lock(&pc->sti_pwm_lock); 264 mutex_lock(&pc->sti_pwm_lock);
265
208 if (!pc->en_count) { 266 if (!pc->en_count) {
209 ret = clk_enable(pc->clk); 267 ret = clk_enable(pc->pwm_clk);
268 if (ret)
269 goto out;
270
271 ret = clk_enable(pc->cpt_clk);
210 if (ret) 272 if (ret)
211 goto out; 273 goto out;
212 274
213 ret = regmap_field_write(pc->pwm_en, 1); 275 ret = regmap_field_write(pc->pwm_out_en, 1);
214 if (ret) { 276 if (ret) {
215 dev_err(dev, "failed to enable PWM device:%d\n", 277 dev_err(dev, "failed to enable PWM device %u: %d\n",
216 pwm->hwpwm); 278 pwm->hwpwm, ret);
217 goto out; 279 goto out;
218 } 280 }
219 } 281 }
282
220 pc->en_count++; 283 pc->en_count++;
284
221out: 285out:
222 mutex_unlock(&pc->sti_pwm_lock); 286 mutex_unlock(&pc->sti_pwm_lock);
223 return ret; 287 return ret;
@@ -228,13 +292,17 @@ static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
228 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); 292 struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
229 293
230 mutex_lock(&pc->sti_pwm_lock); 294 mutex_lock(&pc->sti_pwm_lock);
295
231 if (--pc->en_count) { 296 if (--pc->en_count) {
232 mutex_unlock(&pc->sti_pwm_lock); 297 mutex_unlock(&pc->sti_pwm_lock);
233 return; 298 return;
234 } 299 }
235 regmap_field_write(pc->pwm_en, 0);
236 300
237 clk_disable(pc->clk); 301 regmap_field_write(pc->pwm_out_en, 0);
302
303 clk_disable(pc->pwm_clk);
304 clk_disable(pc->cpt_clk);
305
238 mutex_unlock(&pc->sti_pwm_lock); 306 mutex_unlock(&pc->sti_pwm_lock);
239} 307}
240 308
@@ -245,7 +313,90 @@ static void sti_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
245 clear_bit(pwm->hwpwm, &pc->configured); 313 clear_bit(pwm->hwpwm, &pc->configured);
246} 314}
247 315
316static int sti_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
317 struct pwm_capture *result, unsigned long timeout)
318{
319 struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
320 struct sti_pwm_compat_data *cdata = pc->cdata;
321 struct sti_cpt_ddata *ddata = pwm_get_chip_data(pwm);
322 struct device *dev = pc->dev;
323 unsigned int effective_ticks;
324 unsigned long long high, low;
325 int ret;
326
327 if (pwm->hwpwm >= cdata->cpt_num_devs) {
328 dev_err(dev, "device %u is not valid\n", pwm->hwpwm);
329 return -EINVAL;
330 }
331
332 mutex_lock(&ddata->lock);
333 ddata->index = 0;
334
335 /* Prepare capture measurement */
336 regmap_write(pc->regmap, PWM_CPT_EDGE(pwm->hwpwm), CPT_EDGE_RISING);
337 regmap_field_write(pc->pwm_cpt_int_en, BIT(pwm->hwpwm));
338
339 /* Enable capture */
340 ret = regmap_field_write(pc->pwm_cpt_en, 1);
341 if (ret) {
342 dev_err(dev, "failed to enable PWM capture %u: %d\n",
343 pwm->hwpwm, ret);
344 goto out;
345 }
346
347 ret = wait_event_interruptible_timeout(ddata->wait, ddata->index > 1,
348 msecs_to_jiffies(timeout));
349
350 regmap_write(pc->regmap, PWM_CPT_EDGE(pwm->hwpwm), CPT_EDGE_DISABLED);
351
352 if (ret == -ERESTARTSYS)
353 goto out;
354
355 switch (ddata->index) {
356 case 0:
357 case 1:
358 /*
359 * Getting here could mean:
360 * - input signal is constant of less than 1 Hz
361 * - there is no input signal at all
362 *
363 * In such case the frequency is rounded down to 0
364 */
365 result->period = 0;
366 result->duty_cycle = 0;
367
368 break;
369
370 case 2:
371 /* We have everying we need */
372 high = ddata->snapshot[1] - ddata->snapshot[0];
373 low = ddata->snapshot[2] - ddata->snapshot[1];
374
375 effective_ticks = clk_get_rate(pc->cpt_clk);
376
377 result->period = (high + low) * NSEC_PER_SEC;
378 result->period /= effective_ticks;
379
380 result->duty_cycle = high * NSEC_PER_SEC;
381 result->duty_cycle /= effective_ticks;
382
383 break;
384
385 default:
386 dev_err(dev, "internal error\n");
387 break;
388 }
389
390out:
391 /* Disable capture */
392 regmap_field_write(pc->pwm_cpt_en, 0);
393
394 mutex_unlock(&ddata->lock);
395 return ret;
396}
397
248static const struct pwm_ops sti_pwm_ops = { 398static const struct pwm_ops sti_pwm_ops = {
399 .capture = sti_pwm_capture,
249 .config = sti_pwm_config, 400 .config = sti_pwm_config,
250 .enable = sti_pwm_enable, 401 .enable = sti_pwm_enable,
251 .disable = sti_pwm_disable, 402 .disable = sti_pwm_disable,
@@ -253,17 +404,98 @@ static const struct pwm_ops sti_pwm_ops = {
253 .owner = THIS_MODULE, 404 .owner = THIS_MODULE,
254}; 405};
255 406
407static irqreturn_t sti_pwm_interrupt(int irq, void *data)
408{
409 struct sti_pwm_chip *pc = data;
410 struct device *dev = pc->dev;
411 struct sti_cpt_ddata *ddata;
412 int devicenum;
413 unsigned int cpt_int_stat;
414 unsigned int reg;
415 int ret = IRQ_NONE;
416
417 ret = regmap_field_read(pc->pwm_cpt_int_stat, &cpt_int_stat);
418 if (ret)
419 return ret;
420
421 while (cpt_int_stat) {
422 devicenum = ffs(cpt_int_stat) - 1;
423
424 ddata = pwm_get_chip_data(&pc->chip.pwms[devicenum]);
425
426 /*
427 * Capture input:
428 * _______ _______
429 * | | | |
430 * __| |_________________| |________
431 * ^0 ^1 ^2
432 *
433 * Capture start by the first available rising edge. When a
434 * capture event occurs, capture value (CPT_VALx) is stored,
435 * index incremented, capture edge changed.
436 *
437 * After the capture, if the index > 1, we have collected the
438 * necessary data so we signal the thread waiting for it and
439 * disable the capture by setting capture edge to none
440 */
441
442 regmap_read(pc->regmap,
443 PWM_CPT_VAL(devicenum),
444 &ddata->snapshot[ddata->index]);
445
446 switch (ddata->index) {
447 case 0:
448 case 1:
449 regmap_read(pc->regmap, PWM_CPT_EDGE(devicenum), &reg);
450 reg ^= PWM_CPT_EDGE_MASK;
451 regmap_write(pc->regmap, PWM_CPT_EDGE(devicenum), reg);
452
453 ddata->index++;
454 break;
455
456 case 2:
457 regmap_write(pc->regmap,
458 PWM_CPT_EDGE(devicenum),
459 CPT_EDGE_DISABLED);
460 wake_up(&ddata->wait);
461 break;
462
463 default:
464 dev_err(dev, "Internal error\n");
465 }
466
467 cpt_int_stat &= ~BIT_MASK(devicenum);
468
469 ret = IRQ_HANDLED;
470 }
471
472 /* Just ACK everything */
473 regmap_write(pc->regmap, PWM_INT_ACK, PWM_INT_ACK_MASK);
474
475 return ret;
476}
477
256static int sti_pwm_probe_dt(struct sti_pwm_chip *pc) 478static int sti_pwm_probe_dt(struct sti_pwm_chip *pc)
257{ 479{
258 struct device *dev = pc->dev; 480 struct device *dev = pc->dev;
259 const struct reg_field *reg_fields; 481 const struct reg_field *reg_fields;
260 struct device_node *np = dev->of_node; 482 struct device_node *np = dev->of_node;
261 struct sti_pwm_compat_data *cdata = pc->cdata; 483 struct sti_pwm_compat_data *cdata = pc->cdata;
262 u32 num_chan; 484 u32 num_devs;
485 int ret;
486
487 ret = of_property_read_u32(np, "st,pwm-num-chan", &num_devs);
488 if (!ret)
489 cdata->pwm_num_devs = num_devs;
490
491 ret = of_property_read_u32(np, "st,capture-num-chan", &num_devs);
492 if (!ret)
493 cdata->cpt_num_devs = num_devs;
263 494
264 of_property_read_u32(np, "st,pwm-num-chan", &num_chan); 495 if (!cdata->pwm_num_devs && !cdata->cpt_num_devs) {
265 if (num_chan) 496 dev_err(dev, "No channels configured\n");
266 cdata->num_chan = num_chan; 497 return -EINVAL;
498 }
267 499
268 reg_fields = cdata->reg_fields; 500 reg_fields = cdata->reg_fields;
269 501
@@ -277,15 +509,26 @@ static int sti_pwm_probe_dt(struct sti_pwm_chip *pc)
277 if (IS_ERR(pc->prescale_high)) 509 if (IS_ERR(pc->prescale_high))
278 return PTR_ERR(pc->prescale_high); 510 return PTR_ERR(pc->prescale_high);
279 511
280 pc->pwm_en = devm_regmap_field_alloc(dev, pc->regmap,
281 reg_fields[PWM_EN]);
282 if (IS_ERR(pc->pwm_en))
283 return PTR_ERR(pc->pwm_en);
284 512
285 pc->pwm_int_en = devm_regmap_field_alloc(dev, pc->regmap, 513 pc->pwm_out_en = devm_regmap_field_alloc(dev, pc->regmap,
286 reg_fields[PWM_INT_EN]); 514 reg_fields[PWM_OUT_EN]);
287 if (IS_ERR(pc->pwm_int_en)) 515 if (IS_ERR(pc->pwm_out_en))
288 return PTR_ERR(pc->pwm_int_en); 516 return PTR_ERR(pc->pwm_out_en);
517
518 pc->pwm_cpt_en = devm_regmap_field_alloc(dev, pc->regmap,
519 reg_fields[PWM_CPT_EN]);
520 if (IS_ERR(pc->pwm_cpt_en))
521 return PTR_ERR(pc->pwm_cpt_en);
522
523 pc->pwm_cpt_int_en = devm_regmap_field_alloc(dev, pc->regmap,
524 reg_fields[PWM_CPT_INT_EN]);
525 if (IS_ERR(pc->pwm_cpt_int_en))
526 return PTR_ERR(pc->pwm_cpt_int_en);
527
528 pc->pwm_cpt_int_stat = devm_regmap_field_alloc(dev, pc->regmap,
529 reg_fields[PWM_CPT_INT_STAT]);
530 if (PTR_ERR_OR_ZERO(pc->pwm_cpt_int_stat))
531 return PTR_ERR(pc->pwm_cpt_int_stat);
289 532
290 return 0; 533 return 0;
291} 534}
@@ -302,7 +545,8 @@ static int sti_pwm_probe(struct platform_device *pdev)
302 struct sti_pwm_compat_data *cdata; 545 struct sti_pwm_compat_data *cdata;
303 struct sti_pwm_chip *pc; 546 struct sti_pwm_chip *pc;
304 struct resource *res; 547 struct resource *res;
305 int ret; 548 unsigned int i;
549 int irq, ret;
306 550
307 pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); 551 pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
308 if (!pc) 552 if (!pc)
@@ -323,14 +567,28 @@ static int sti_pwm_probe(struct platform_device *pdev)
323 if (IS_ERR(pc->regmap)) 567 if (IS_ERR(pc->regmap))
324 return PTR_ERR(pc->regmap); 568 return PTR_ERR(pc->regmap);
325 569
570 irq = platform_get_irq(pdev, 0);
571 if (irq < 0) {
572 dev_err(&pdev->dev, "Failed to obtain IRQ\n");
573 return irq;
574 }
575
576 ret = devm_request_irq(&pdev->dev, irq, sti_pwm_interrupt, 0,
577 pdev->name, pc);
578 if (ret < 0) {
579 dev_err(&pdev->dev, "Failed to request IRQ\n");
580 return ret;
581 }
582
326 /* 583 /*
327 * Setup PWM data with default values: some values could be replaced 584 * Setup PWM data with default values: some values could be replaced
328 * with specific ones provided from Device Tree. 585 * with specific ones provided from Device Tree.
329 */ 586 */
330 cdata->reg_fields = &sti_pwm_regfields[0]; 587 cdata->reg_fields = sti_pwm_regfields;
331 cdata->max_prescale = 0xff; 588 cdata->max_prescale = 0xff;
332 cdata->max_pwm_cnt = 255; 589 cdata->max_pwm_cnt = 255;
333 cdata->num_chan = 1; 590 cdata->pwm_num_devs = 0;
591 cdata->cpt_num_devs = 0;
334 592
335 pc->cdata = cdata; 593 pc->cdata = cdata;
336 pc->dev = dev; 594 pc->dev = dev;
@@ -341,36 +599,64 @@ static int sti_pwm_probe(struct platform_device *pdev)
341 if (ret) 599 if (ret)
342 return ret; 600 return ret;
343 601
344 pc->clk = of_clk_get_by_name(dev->of_node, "pwm"); 602 if (!cdata->pwm_num_devs)
345 if (IS_ERR(pc->clk)) { 603 goto skip_pwm;
604
605 pc->pwm_clk = of_clk_get_by_name(dev->of_node, "pwm");
606 if (IS_ERR(pc->pwm_clk)) {
346 dev_err(dev, "failed to get PWM clock\n"); 607 dev_err(dev, "failed to get PWM clock\n");
347 return PTR_ERR(pc->clk); 608 return PTR_ERR(pc->pwm_clk);
348 } 609 }
349 610
350 pc->clk_rate = clk_get_rate(pc->clk); 611 ret = clk_prepare(pc->pwm_clk);
351 if (!pc->clk_rate) { 612 if (ret) {
352 dev_err(dev, "failed to get clock rate\n"); 613 dev_err(dev, "failed to prepare clock\n");
353 return -EINVAL; 614 return ret;
354 } 615 }
355 616
356 ret = clk_prepare(pc->clk); 617skip_pwm:
618 if (!cdata->cpt_num_devs)
619 goto skip_cpt;
620
621 pc->cpt_clk = of_clk_get_by_name(dev->of_node, "capture");
622 if (IS_ERR(pc->cpt_clk)) {
623 dev_err(dev, "failed to get PWM capture clock\n");
624 return PTR_ERR(pc->cpt_clk);
625 }
626
627 ret = clk_prepare(pc->cpt_clk);
357 if (ret) { 628 if (ret) {
358 dev_err(dev, "failed to prepare clock\n"); 629 dev_err(dev, "failed to prepare clock\n");
359 return ret; 630 return ret;
360 } 631 }
361 632
633skip_cpt:
362 pc->chip.dev = dev; 634 pc->chip.dev = dev;
363 pc->chip.ops = &sti_pwm_ops; 635 pc->chip.ops = &sti_pwm_ops;
364 pc->chip.base = -1; 636 pc->chip.base = -1;
365 pc->chip.npwm = pc->cdata->num_chan; 637 pc->chip.npwm = pc->cdata->pwm_num_devs;
366 pc->chip.can_sleep = true; 638 pc->chip.can_sleep = true;
367 639
368 ret = pwmchip_add(&pc->chip); 640 ret = pwmchip_add(&pc->chip);
369 if (ret < 0) { 641 if (ret < 0) {
370 clk_unprepare(pc->clk); 642 clk_unprepare(pc->pwm_clk);
643 clk_unprepare(pc->cpt_clk);
371 return ret; 644 return ret;
372 } 645 }
373 646
647 for (i = 0; i < cdata->cpt_num_devs; i++) {
648 struct sti_cpt_ddata *ddata;
649
650 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
651 if (!ddata)
652 return -ENOMEM;
653
654 init_waitqueue_head(&ddata->wait);
655 mutex_init(&ddata->lock);
656
657 pwm_set_chip_data(&pc->chip.pwms[i], ddata);
658 }
659
374 platform_set_drvdata(pdev, pc); 660 platform_set_drvdata(pdev, pc);
375 661
376 return 0; 662 return 0;
@@ -381,10 +667,11 @@ static int sti_pwm_remove(struct platform_device *pdev)
381 struct sti_pwm_chip *pc = platform_get_drvdata(pdev); 667 struct sti_pwm_chip *pc = platform_get_drvdata(pdev);
382 unsigned int i; 668 unsigned int i;
383 669
384 for (i = 0; i < pc->cdata->num_chan; i++) 670 for (i = 0; i < pc->cdata->pwm_num_devs; i++)
385 pwm_disable(&pc->chip.pwms[i]); 671 pwm_disable(&pc->chip.pwms[i]);
386 672
387 clk_unprepare(pc->clk); 673 clk_unprepare(pc->pwm_clk);
674 clk_unprepare(pc->cpt_clk);
388 675
389 return pwmchip_remove(&pc->chip); 676 return pwmchip_remove(&pc->chip);
390} 677}
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 03a99a53c39e..b0803f6c64d9 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -284,6 +284,12 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
284 .npwm = 2, 284 .npwm = 2,
285}; 285};
286 286
287static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
288 .has_prescaler_bypass = true,
289 .has_rdy = true,
290 .npwm = 1,
291};
292
287static const struct of_device_id sun4i_pwm_dt_ids[] = { 293static const struct of_device_id sun4i_pwm_dt_ids[] = {
288 { 294 {
289 .compatible = "allwinner,sun4i-a10-pwm", 295 .compatible = "allwinner,sun4i-a10-pwm",
@@ -298,6 +304,9 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
298 .compatible = "allwinner,sun7i-a20-pwm", 304 .compatible = "allwinner,sun7i-a20-pwm",
299 .data = &sun4i_pwm_data_a20, 305 .data = &sun4i_pwm_data_a20,
300 }, { 306 }, {
307 .compatible = "allwinner,sun8i-h3-pwm",
308 .data = &sun4i_pwm_data_h3,
309 }, {
301 /* sentinel */ 310 /* sentinel */
302 }, 311 },
303}; 312};
diff --git a/drivers/pwm/pwm-tipwmss.c b/drivers/pwm/pwm-tipwmss.c
index 829f4991c96f..7fa85a1604da 100644
--- a/drivers/pwm/pwm-tipwmss.c
+++ b/drivers/pwm/pwm-tipwmss.c
@@ -34,7 +34,6 @@ static int pwmss_probe(struct platform_device *pdev)
34 struct device_node *node = pdev->dev.of_node; 34 struct device_node *node = pdev->dev.of_node;
35 35
36 pm_runtime_enable(&pdev->dev); 36 pm_runtime_enable(&pdev->dev);
37 pm_runtime_get_sync(&pdev->dev);
38 37
39 /* Populate all the child nodes here... */ 38 /* Populate all the child nodes here... */
40 ret = of_platform_populate(node, NULL, NULL, &pdev->dev); 39 ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
@@ -46,31 +45,13 @@ static int pwmss_probe(struct platform_device *pdev)
46 45
47static int pwmss_remove(struct platform_device *pdev) 46static int pwmss_remove(struct platform_device *pdev)
48{ 47{
49 pm_runtime_put_sync(&pdev->dev);
50 pm_runtime_disable(&pdev->dev); 48 pm_runtime_disable(&pdev->dev);
51 return 0; 49 return 0;
52} 50}
53 51
54#ifdef CONFIG_PM_SLEEP
55static int pwmss_suspend(struct device *dev)
56{
57 pm_runtime_put_sync(dev);
58 return 0;
59}
60
61static int pwmss_resume(struct device *dev)
62{
63 pm_runtime_get_sync(dev);
64 return 0;
65}
66#endif
67
68static SIMPLE_DEV_PM_OPS(pwmss_pm_ops, pwmss_suspend, pwmss_resume);
69
70static struct platform_driver pwmss_driver = { 52static struct platform_driver pwmss_driver = {
71 .driver = { 53 .driver = {
72 .name = "pwmss", 54 .name = "pwmss",
73 .pm = &pwmss_pm_ops,
74 .of_match_table = pwmss_of_match, 55 .of_match_table = pwmss_of_match,
75 }, 56 },
76 .probe = pwmss_probe, 57 .probe = pwmss_probe,
diff --git a/drivers/pwm/pwm-twl.c b/drivers/pwm/pwm-twl.c
index 04f76725d591..7a993b056638 100644
--- a/drivers/pwm/pwm-twl.c
+++ b/drivers/pwm/pwm-twl.c
@@ -269,6 +269,22 @@ static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
269 goto out; 269 goto out;
270 } 270 }
271 271
272 val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXEN);
273
274 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
275 if (ret < 0) {
276 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
277 goto out;
278 }
279
280 val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXEN);
281
282 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
283 if (ret < 0) {
284 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
285 goto out;
286 }
287
272 twl->twl6030_toggle3 = val; 288 twl->twl6030_toggle3 = val;
273out: 289out:
274 mutex_unlock(&twl->mutex); 290 mutex_unlock(&twl->mutex);
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index 18ed725594c3..0296d8178ae2 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -409,6 +409,24 @@ void pwmchip_sysfs_unexport(struct pwm_chip *chip)
409 } 409 }
410} 410}
411 411
412void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
413{
414 struct device *parent;
415 unsigned int i;
416
417 parent = class_find_device(&pwm_class, NULL, chip,
418 pwmchip_sysfs_match);
419 if (!parent)
420 return;
421
422 for (i = 0; i < chip->npwm; i++) {
423 struct pwm_device *pwm = &chip->pwms[i];
424
425 if (test_bit(PWMF_EXPORTED, &pwm->flags))
426 pwm_unexport_child(parent, pwm);
427 }
428}
429
412static int __init pwm_sysfs_init(void) 430static int __init pwm_sysfs_init(void)
413{ 431{
414 return class_register(&pwm_class); 432 return class_register(&pwm_class);
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index f1bbae014889..2c6c5114c089 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -641,6 +641,7 @@ static inline void pwm_remove_table(struct pwm_lookup *table, size_t num)
641#ifdef CONFIG_PWM_SYSFS 641#ifdef CONFIG_PWM_SYSFS
642void pwmchip_sysfs_export(struct pwm_chip *chip); 642void pwmchip_sysfs_export(struct pwm_chip *chip);
643void pwmchip_sysfs_unexport(struct pwm_chip *chip); 643void pwmchip_sysfs_unexport(struct pwm_chip *chip);
644void pwmchip_sysfs_unexport_children(struct pwm_chip *chip);
644#else 645#else
645static inline void pwmchip_sysfs_export(struct pwm_chip *chip) 646static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
646{ 647{
@@ -649,6 +650,10 @@ static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
649static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip) 650static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip)
650{ 651{
651} 652}
653
654static inline void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
655{
656}
652#endif /* CONFIG_PWM_SYSFS */ 657#endif /* CONFIG_PWM_SYSFS */
653 658
654#endif /* __LINUX_PWM_H */ 659#endif /* __LINUX_PWM_H */