Skip to content

Commit fcc37f7

Browse files
committed
Merge tag 'pwm/for-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm
Pull pwm updates from Thierry Reding: "This series contains a number of improvements to existing drivers, such as LPSS. Some drivers, such as renesas-tpu and rcar get support for more SoC generations. To round things off this fixes an issue with the sysfs interface" * tag 'pwm/for-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: pwm: lpss: Only set update bit if we are actually changing the settings pwm: lpss: Force runtime-resume on suspend on Cherry Trail pwm: Enable TI ECAP driver for ARCH_K3 dt-bindings: pwm: tiecap: Add TI AM654 SoC specific compatible dt-bindings: pwm: rcar: Add r8a774a1 support pwm: Send a uevent on the pwmchip device upon channel sysfs (un)export Revert "pwm: Set class for exported channels in sysfs" dt-bindings: pwm: renesas-tpu: Document r8a7744 support dt-bindings: pwm: rcar: Add r8a7744 support dt-bindings: pwm: renesas: tpu: Document R8A779{7|8}0 bindings dt-bindings: pwm: renesas: pwm-rcar: Document R8A779{7|8}0 bindings dt-bindings: pwm: renesas: tpu: Fix "compatible" prop description pwm: Use SPDX identifier for Renesas drivers pwm: lpss: Add get_state callback pwm: lpss: Release runtime-pm reference from the driver's remove callback pwm: lpss: Check PWM powerstate after resume on Cherry Trail devices pwm: lpss: Move struct pwm_lpss_chip definition to the header file pwm: lpss: Add ACPI HID for second PWM controller on Cherry Trail devices ACPI / PM: Export acpi_device_get_power() for use by modular build drivers pwm: tegra: Remove gratuituous blank line
2 parents 0b21f21 + 2153bbc commit fcc37f7

File tree

12 files changed

+110
-38
lines changed

12 files changed

+110
-38
lines changed

Documentation/devicetree/bindings/pwm/pwm-tiecap.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Required properties:
77
for da850 - compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap";
88
for dra746 - compatible = "ti,dra746-ecap", "ti,am3352-ecap";
99
for 66ak2g - compatible = "ti,k2g-ecap", "ti,am3352-ecap";
10+
for am654 - compatible = "ti,am654-ecap", "ti,am3352-ecap";
1011
- #pwm-cells: should be 3. See pwm.txt in this directory for a description of
1112
the cells format. The PWM channel index ranges from 0 to 4. The only third
1213
cell flag supported by this binding is PWM_POLARITY_INVERTED.

Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
Required Properties:
44
- compatible: should be "renesas,pwm-rcar" and one of the following.
55
- "renesas,pwm-r8a7743": for RZ/G1M
6+
- "renesas,pwm-r8a7744": for RZ/G1N
67
- "renesas,pwm-r8a7745": for RZ/G1E
8+
- "renesas,pwm-r8a774a1": for RZ/G2M
79
- "renesas,pwm-r8a7778": for R-Car M1A
810
- "renesas,pwm-r8a7779": for R-Car H1
911
- "renesas,pwm-r8a7790": for R-Car H2
@@ -12,6 +14,8 @@ Required Properties:
1214
- "renesas,pwm-r8a7795": for R-Car H3
1315
- "renesas,pwm-r8a7796": for R-Car M3-W
1416
- "renesas,pwm-r8a77965": for R-Car M3-N
17+
- "renesas,pwm-r8a77970": for R-Car V3M
18+
- "renesas,pwm-r8a77980": for R-Car V3H
1519
- "renesas,pwm-r8a77990": for R-Car E3
1620
- "renesas,pwm-r8a77995": for R-Car D3
1721
- reg: base address and length of the registers block for the PWM.

Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22

33
Required Properties:
44

5-
- compatible: should be one of the following.
5+
- compatible: must contain one or more of the following:
66
- "renesas,tpu-r8a73a4": for R8A73A4 (R-Mobile APE6) compatible PWM controller.
77
- "renesas,tpu-r8a7740": for R8A7740 (R-Mobile A1) compatible PWM controller.
88
- "renesas,tpu-r8a7743": for R8A7743 (RZ/G1M) compatible PWM controller.
9+
- "renesas,tpu-r8a7744": for R8A7744 (RZ/G1N) compatible PWM controller.
910
- "renesas,tpu-r8a7745": for R8A7745 (RZ/G1E) compatible PWM controller.
1011
- "renesas,tpu-r8a7790": for R8A7790 (R-Car H2) compatible PWM controller.
11-
- "renesas,tpu": for generic R-Car and RZ/G1 TPU PWM controller.
12+
- "renesas,tpu-r8a77970": for R8A77970 (R-Car V3M) compatible PWM
13+
controller.
14+
- "renesas,tpu-r8a77980": for R8A77980 (R-Car V3H) compatible PWM
15+
controller.
16+
- "renesas,tpu": for the generic TPU PWM controller; this is a fallback for
17+
the entries listed above.
1218

1319
- reg: Base address and length of each memory resource used by the PWM
1420
controller hardware module.

drivers/acpi/device_pm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ int acpi_device_get_power(struct acpi_device *device, int *state)
126126

127127
return 0;
128128
}
129+
EXPORT_SYMBOL(acpi_device_get_power);
129130

130131
static int acpi_dev_pm_explicit_set(struct acpi_device *adev, int state)
131132
{

drivers/pwm/Kconfig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,10 +447,9 @@ config PWM_TEGRA
447447

448448
config PWM_TIECAP
449449
tristate "ECAP PWM support"
450-
depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_KEYSTONE
450+
depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_KEYSTONE || ARCH_K3
451451
help
452-
PWM driver support for the ECAP APWM controller found on AM33XX
453-
TI SOC
452+
PWM driver support for the ECAP APWM controller found on TI SOCs
454453

455454
To compile this driver as a module, choose M here: the module
456455
will be called pwm-tiecap.

drivers/pwm/pwm-lpss-platform.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
3030
.clk_rate = 19200000,
3131
.npwm = 1,
3232
.base_unit_bits = 16,
33+
.other_devices_aml_touches_pwm_regs = true,
3334
};
3435

3536
/* Broxton */
@@ -60,6 +61,7 @@ static int pwm_lpss_probe_platform(struct platform_device *pdev)
6061

6162
platform_set_drvdata(pdev, lpwm);
6263

64+
dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_SMART_PREPARE);
6365
pm_runtime_set_active(&pdev->dev);
6466
pm_runtime_enable(&pdev->dev);
6567

@@ -74,13 +76,29 @@ static int pwm_lpss_remove_platform(struct platform_device *pdev)
7476
return pwm_lpss_remove(lpwm);
7577
}
7678

77-
static SIMPLE_DEV_PM_OPS(pwm_lpss_platform_pm_ops,
78-
pwm_lpss_suspend,
79-
pwm_lpss_resume);
79+
static int pwm_lpss_prepare(struct device *dev)
80+
{
81+
struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev);
82+
83+
/*
84+
* If other device's AML code touches the PWM regs on suspend/resume
85+
* force runtime-resume the PWM controller to allow this.
86+
*/
87+
if (lpwm->info->other_devices_aml_touches_pwm_regs)
88+
return 0; /* Force runtime-resume */
89+
90+
return 1; /* If runtime-suspended leave as is */
91+
}
92+
93+
static const struct dev_pm_ops pwm_lpss_platform_pm_ops = {
94+
.prepare = pwm_lpss_prepare,
95+
SET_SYSTEM_SLEEP_PM_OPS(pwm_lpss_suspend, pwm_lpss_resume)
96+
};
8097

8198
static const struct acpi_device_id pwm_lpss_acpi_match[] = {
8299
{ "80860F09", (unsigned long)&pwm_lpss_byt_info },
83100
{ "80862288", (unsigned long)&pwm_lpss_bsw_info },
101+
{ "80862289", (unsigned long)&pwm_lpss_bsw_info },
84102
{ "80865AC8", (unsigned long)&pwm_lpss_bxt_info },
85103
{ },
86104
};

drivers/pwm/pwm-lpss.c

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,6 @@
3232
/* Size of each PWM register space if multiple */
3333
#define PWM_SIZE 0x400
3434

35-
#define MAX_PWMS 4
36-
37-
struct pwm_lpss_chip {
38-
struct pwm_chip chip;
39-
void __iomem *regs;
40-
const struct pwm_lpss_boardinfo *info;
41-
u32 saved_ctrl[MAX_PWMS];
42-
};
43-
4435
static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
4536
{
4637
return container_of(chip, struct pwm_lpss_chip, chip);
@@ -97,7 +88,7 @@ static void pwm_lpss_prepare(struct pwm_lpss_chip *lpwm, struct pwm_device *pwm,
9788
unsigned long long on_time_div;
9889
unsigned long c = lpwm->info->clk_rate, base_unit_range;
9990
unsigned long long base_unit, freq = NSEC_PER_SEC;
100-
u32 ctrl;
91+
u32 orig_ctrl, ctrl;
10192

10293
do_div(freq, period_ns);
10394

@@ -114,13 +105,17 @@ static void pwm_lpss_prepare(struct pwm_lpss_chip *lpwm, struct pwm_device *pwm,
114105
do_div(on_time_div, period_ns);
115106
on_time_div = 255ULL - on_time_div;
116107

117-
ctrl = pwm_lpss_read(pwm);
108+
orig_ctrl = ctrl = pwm_lpss_read(pwm);
118109
ctrl &= ~PWM_ON_TIME_DIV_MASK;
119110
ctrl &= ~(base_unit_range << PWM_BASE_UNIT_SHIFT);
120111
base_unit &= base_unit_range;
121112
ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT;
122113
ctrl |= on_time_div;
123-
pwm_lpss_write(pwm, ctrl);
114+
115+
if (orig_ctrl != ctrl) {
116+
pwm_lpss_write(pwm, ctrl);
117+
pwm_lpss_write(pwm, ctrl | PWM_SW_UPDATE);
118+
}
124119
}
125120

126121
static inline void pwm_lpss_cond_enable(struct pwm_device *pwm, bool cond)
@@ -144,7 +139,6 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
144139
return ret;
145140
}
146141
pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
147-
pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
148142
pwm_lpss_cond_enable(pwm, lpwm->info->bypass == false);
149143
ret = pwm_lpss_wait_for_update(pwm);
150144
if (ret) {
@@ -157,7 +151,6 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
157151
if (ret)
158152
return ret;
159153
pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
160-
pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
161154
return pwm_lpss_wait_for_update(pwm);
162155
}
163156
} else if (pwm_is_enabled(pwm)) {
@@ -168,8 +161,42 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
168161
return 0;
169162
}
170163

164+
/* This function gets called once from pwmchip_add to get the initial state */
165+
static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
166+
struct pwm_state *state)
167+
{
168+
struct pwm_lpss_chip *lpwm = to_lpwm(chip);
169+
unsigned long base_unit_range;
170+
unsigned long long base_unit, freq, on_time_div;
171+
u32 ctrl;
172+
173+
base_unit_range = BIT(lpwm->info->base_unit_bits);
174+
175+
ctrl = pwm_lpss_read(pwm);
176+
on_time_div = 255 - (ctrl & PWM_ON_TIME_DIV_MASK);
177+
base_unit = (ctrl >> PWM_BASE_UNIT_SHIFT) & (base_unit_range - 1);
178+
179+
freq = base_unit * lpwm->info->clk_rate;
180+
do_div(freq, base_unit_range);
181+
if (freq == 0)
182+
state->period = NSEC_PER_SEC;
183+
else
184+
state->period = NSEC_PER_SEC / (unsigned long)freq;
185+
186+
on_time_div *= state->period;
187+
do_div(on_time_div, 255);
188+
state->duty_cycle = on_time_div;
189+
190+
state->polarity = PWM_POLARITY_NORMAL;
191+
state->enabled = !!(ctrl & PWM_ENABLE);
192+
193+
if (state->enabled)
194+
pm_runtime_get(chip->dev);
195+
}
196+
171197
static const struct pwm_ops pwm_lpss_ops = {
172198
.apply = pwm_lpss_apply,
199+
.get_state = pwm_lpss_get_state,
173200
.owner = THIS_MODULE,
174201
};
175202

@@ -214,6 +241,12 @@ EXPORT_SYMBOL_GPL(pwm_lpss_probe);
214241

215242
int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
216243
{
244+
int i;
245+
246+
for (i = 0; i < lpwm->info->npwm; i++) {
247+
if (pwm_is_enabled(&lpwm->chip.pwms[i]))
248+
pm_runtime_put(lpwm->chip.dev);
249+
}
217250
return pwmchip_remove(&lpwm->chip);
218251
}
219252
EXPORT_SYMBOL_GPL(pwm_lpss_remove);

drivers/pwm/pwm-lpss.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,25 @@
1616
#include <linux/device.h>
1717
#include <linux/pwm.h>
1818

19-
struct pwm_lpss_chip;
19+
#define MAX_PWMS 4
20+
21+
struct pwm_lpss_chip {
22+
struct pwm_chip chip;
23+
void __iomem *regs;
24+
const struct pwm_lpss_boardinfo *info;
25+
u32 saved_ctrl[MAX_PWMS];
26+
};
2027

2128
struct pwm_lpss_boardinfo {
2229
unsigned long clk_rate;
2330
unsigned int npwm;
2431
unsigned long base_unit_bits;
2532
bool bypass;
33+
/*
34+
* On some devices the _PS0/_PS3 AML code of the GPU (GFX0) device
35+
* messes with the PWM0 controllers state,
36+
*/
37+
bool other_devices_aml_touches_pwm_regs;
2638
};
2739

2840
struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,

drivers/pwm/pwm-rcar.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1+
// SPDX-License-Identifier: GPL-2.0
12
/*
23
* R-Car PWM Timer driver
34
*
45
* Copyright (C) 2015 Renesas Electronics Corporation
5-
*
6-
* This is free software; you can redistribute it and/or modify
7-
* it under the terms of version 2 of the GNU General Public License as
8-
* published by the Free Software Foundation.
96
*/
107

118
#include <linux/clk.h>

drivers/pwm/pwm-renesas-tpu.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,8 @@
1+
// SPDX-License-Identifier: GPL-2.0
12
/*
23
* R-Mobile TPU PWM driver
34
*
45
* Copyright (C) 2012 Renesas Solutions Corp.
5-
*
6-
* This program is free software; you can redistribute it and/or modify
7-
* it under the terms of the GNU General Public License as published by
8-
* the Free Software Foundation; either version 2 of the License
9-
*
10-
* This program is distributed in the hope that it will be useful,
11-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13-
* GNU General Public License for more details.
146
*/
157

168
#include <linux/clk.h>

drivers/pwm/pwm-tegra.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ static const struct of_device_id tegra_pwm_of_match[] = {
300300
{ .compatible = "nvidia,tegra186-pwm", .data = &tegra186_pwm_soc },
301301
{ }
302302
};
303-
304303
MODULE_DEVICE_TABLE(of, tegra_pwm_of_match);
305304

306305
static const struct dev_pm_ops tegra_pwm_pm_ops = {

drivers/pwm/sysfs.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ static void pwm_export_release(struct device *child)
249249
static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
250250
{
251251
struct pwm_export *export;
252+
char *pwm_prop[2];
252253
int ret;
253254

254255
if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
@@ -263,7 +264,6 @@ static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
263264
export->pwm = pwm;
264265
mutex_init(&export->lock);
265266

266-
export->child.class = parent->class;
267267
export->child.release = pwm_export_release;
268268
export->child.parent = parent;
269269
export->child.devt = MKDEV(0, 0);
@@ -277,6 +277,10 @@ static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
277277
export = NULL;
278278
return ret;
279279
}
280+
pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm);
281+
pwm_prop[1] = NULL;
282+
kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
283+
kfree(pwm_prop[0]);
280284

281285
return 0;
282286
}
@@ -289,6 +293,7 @@ static int pwm_unexport_match(struct device *child, void *data)
289293
static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
290294
{
291295
struct device *child;
296+
char *pwm_prop[2];
292297

293298
if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
294299
return -ENODEV;
@@ -297,6 +302,11 @@ static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
297302
if (!child)
298303
return -ENODEV;
299304

305+
pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm);
306+
pwm_prop[1] = NULL;
307+
kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
308+
kfree(pwm_prop[0]);
309+
300310
/* for device_find_child() */
301311
put_device(child);
302312
device_unregister(child);

0 commit comments

Comments
 (0)