aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-tiecap.txt1
-rw-r--r--Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt4
-rw-r--r--Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt10
-rw-r--r--drivers/acpi/device_pm.c1
-rw-r--r--drivers/pwm/Kconfig5
-rw-r--r--drivers/pwm/pwm-lpss-platform.c24
-rw-r--r--drivers/pwm/pwm-lpss.c61
-rw-r--r--drivers/pwm/pwm-lpss.h14
-rw-r--r--drivers/pwm/pwm-rcar.c5
-rw-r--r--drivers/pwm/pwm-renesas-tpu.c10
-rw-r--r--drivers/pwm/pwm-tegra.c1
-rw-r--r--drivers/pwm/sysfs.c12
12 files changed, 110 insertions, 38 deletions
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
index 06a363d9ccef..b9a1d7402128 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
@@ -7,6 +7,7 @@ Required properties:
7 for da850 - compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; 7 for da850 - compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap";
8 for dra746 - compatible = "ti,dra746-ecap", "ti,am3352-ecap"; 8 for dra746 - compatible = "ti,dra746-ecap", "ti,am3352-ecap";
9 for 66ak2g - compatible = "ti,k2g-ecap", "ti,am3352-ecap"; 9 for 66ak2g - compatible = "ti,k2g-ecap", "ti,am3352-ecap";
10 for am654 - compatible = "ti,am654-ecap", "ti,am3352-ecap";
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. The PWM channel index ranges from 0 to 4. The only third 12 the cells format. The PWM channel index ranges from 0 to 4. The only third
12 cell flag supported by this binding is PWM_POLARITY_INVERTED. 13 cell flag supported by this binding is PWM_POLARITY_INVERTED.
diff --git a/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt b/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt
index e1ef6afbe3a7..7f31fe7e2093 100644
--- a/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt
+++ b/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt
@@ -3,7 +3,9 @@
3Required Properties: 3Required Properties:
4- compatible: should be "renesas,pwm-rcar" and one of the following. 4- compatible: should be "renesas,pwm-rcar" and one of the following.
5 - "renesas,pwm-r8a7743": for RZ/G1M 5 - "renesas,pwm-r8a7743": for RZ/G1M
6 - "renesas,pwm-r8a7744": for RZ/G1N
6 - "renesas,pwm-r8a7745": for RZ/G1E 7 - "renesas,pwm-r8a7745": for RZ/G1E
8 - "renesas,pwm-r8a774a1": for RZ/G2M
7 - "renesas,pwm-r8a7778": for R-Car M1A 9 - "renesas,pwm-r8a7778": for R-Car M1A
8 - "renesas,pwm-r8a7779": for R-Car H1 10 - "renesas,pwm-r8a7779": for R-Car H1
9 - "renesas,pwm-r8a7790": for R-Car H2 11 - "renesas,pwm-r8a7790": for R-Car H2
@@ -12,6 +14,8 @@ Required Properties:
12 - "renesas,pwm-r8a7795": for R-Car H3 14 - "renesas,pwm-r8a7795": for R-Car H3
13 - "renesas,pwm-r8a7796": for R-Car M3-W 15 - "renesas,pwm-r8a7796": for R-Car M3-W
14 - "renesas,pwm-r8a77965": for R-Car M3-N 16 - "renesas,pwm-r8a77965": for R-Car M3-N
17 - "renesas,pwm-r8a77970": for R-Car V3M
18 - "renesas,pwm-r8a77980": for R-Car V3H
15 - "renesas,pwm-r8a77990": for R-Car E3 19 - "renesas,pwm-r8a77990": for R-Car E3
16 - "renesas,pwm-r8a77995": for R-Car D3 20 - "renesas,pwm-r8a77995": for R-Car D3
17- reg: base address and length of the registers block for the PWM. 21- reg: base address and length of the registers block for the PWM.
diff --git a/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt b/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt
index d53a16715da6..848a92b53d81 100644
--- a/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt
@@ -2,13 +2,19 @@
2 2
3Required Properties: 3Required Properties:
4 4
5 - compatible: should be one of the following. 5 - compatible: must contain one or more of the following:
6 - "renesas,tpu-r8a73a4": for R8A73A4 (R-Mobile APE6) compatible PWM controller. 6 - "renesas,tpu-r8a73a4": for R8A73A4 (R-Mobile APE6) compatible PWM controller.
7 - "renesas,tpu-r8a7740": for R8A7740 (R-Mobile A1) compatible PWM controller. 7 - "renesas,tpu-r8a7740": for R8A7740 (R-Mobile A1) compatible PWM controller.
8 - "renesas,tpu-r8a7743": for R8A7743 (RZ/G1M) compatible PWM controller. 8 - "renesas,tpu-r8a7743": for R8A7743 (RZ/G1M) compatible PWM controller.
9 - "renesas,tpu-r8a7744": for R8A7744 (RZ/G1N) compatible PWM controller.
9 - "renesas,tpu-r8a7745": for R8A7745 (RZ/G1E) compatible PWM controller. 10 - "renesas,tpu-r8a7745": for R8A7745 (RZ/G1E) compatible PWM controller.
10 - "renesas,tpu-r8a7790": for R8A7790 (R-Car H2) compatible PWM controller. 11 - "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.
12 18
13 - reg: Base address and length of each memory resource used by the PWM 19 - reg: Base address and length of each memory resource used by the PWM
14 controller hardware module. 20 controller hardware module.
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index a7c2673ffd36..824ae985ad93 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -126,6 +126,7 @@ int acpi_device_get_power(struct acpi_device *device, int *state)
126 126
127 return 0; 127 return 0;
128} 128}
129EXPORT_SYMBOL(acpi_device_get_power);
129 130
130static int acpi_dev_pm_explicit_set(struct acpi_device *adev, int state) 131static int acpi_dev_pm_explicit_set(struct acpi_device *adev, int state)
131{ 132{
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 504d252716f2..27e5dd47a01f 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -447,10 +447,9 @@ config PWM_TEGRA
447 447
448config PWM_TIECAP 448config PWM_TIECAP
449 tristate "ECAP PWM support" 449 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
451 help 451 help
452 PWM driver support for the ECAP APWM controller found on AM33XX 452 PWM driver support for the ECAP APWM controller found on TI SOCs
453 TI SOC
454 453
455 To compile this driver as a module, choose M here: the module 454 To compile this driver as a module, choose M here: the module
456 will be called pwm-tiecap. 455 will be called pwm-tiecap.
diff --git a/drivers/pwm/pwm-lpss-platform.c b/drivers/pwm/pwm-lpss-platform.c
index 5561b9e190f8..757230e1f575 100644
--- a/drivers/pwm/pwm-lpss-platform.c
+++ b/drivers/pwm/pwm-lpss-platform.c
@@ -30,6 +30,7 @@ static const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
30 .clk_rate = 19200000, 30 .clk_rate = 19200000,
31 .npwm = 1, 31 .npwm = 1,
32 .base_unit_bits = 16, 32 .base_unit_bits = 16,
33 .other_devices_aml_touches_pwm_regs = true,
33}; 34};
34 35
35/* Broxton */ 36/* Broxton */
@@ -60,6 +61,7 @@ static int pwm_lpss_probe_platform(struct platform_device *pdev)
60 61
61 platform_set_drvdata(pdev, lpwm); 62 platform_set_drvdata(pdev, lpwm);
62 63
64 dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_SMART_PREPARE);
63 pm_runtime_set_active(&pdev->dev); 65 pm_runtime_set_active(&pdev->dev);
64 pm_runtime_enable(&pdev->dev); 66 pm_runtime_enable(&pdev->dev);
65 67
@@ -74,13 +76,29 @@ static int pwm_lpss_remove_platform(struct platform_device *pdev)
74 return pwm_lpss_remove(lpwm); 76 return pwm_lpss_remove(lpwm);
75} 77}
76 78
77static SIMPLE_DEV_PM_OPS(pwm_lpss_platform_pm_ops, 79static int pwm_lpss_prepare(struct device *dev)
78 pwm_lpss_suspend, 80{
79 pwm_lpss_resume); 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
93static 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};
80 97
81static const struct acpi_device_id pwm_lpss_acpi_match[] = { 98static const struct acpi_device_id pwm_lpss_acpi_match[] = {
82 { "80860F09", (unsigned long)&pwm_lpss_byt_info }, 99 { "80860F09", (unsigned long)&pwm_lpss_byt_info },
83 { "80862288", (unsigned long)&pwm_lpss_bsw_info }, 100 { "80862288", (unsigned long)&pwm_lpss_bsw_info },
101 { "80862289", (unsigned long)&pwm_lpss_bsw_info },
84 { "80865AC8", (unsigned long)&pwm_lpss_bxt_info }, 102 { "80865AC8", (unsigned long)&pwm_lpss_bxt_info },
85 { }, 103 { },
86}; 104};
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index 4721a264bac2..2ac3a2aa9e53 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -32,15 +32,6 @@
32/* Size of each PWM register space if multiple */ 32/* Size of each PWM register space if multiple */
33#define PWM_SIZE 0x400 33#define PWM_SIZE 0x400
34 34
35#define MAX_PWMS 4
36
37struct 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
44static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip) 35static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
45{ 36{
46 return container_of(chip, struct pwm_lpss_chip, chip); 37 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,
97 unsigned long long on_time_div; 88 unsigned long long on_time_div;
98 unsigned long c = lpwm->info->clk_rate, base_unit_range; 89 unsigned long c = lpwm->info->clk_rate, base_unit_range;
99 unsigned long long base_unit, freq = NSEC_PER_SEC; 90 unsigned long long base_unit, freq = NSEC_PER_SEC;
100 u32 ctrl; 91 u32 orig_ctrl, ctrl;
101 92
102 do_div(freq, period_ns); 93 do_div(freq, period_ns);
103 94
@@ -114,13 +105,17 @@ static void pwm_lpss_prepare(struct pwm_lpss_chip *lpwm, struct pwm_device *pwm,
114 do_div(on_time_div, period_ns); 105 do_div(on_time_div, period_ns);
115 on_time_div = 255ULL - on_time_div; 106 on_time_div = 255ULL - on_time_div;
116 107
117 ctrl = pwm_lpss_read(pwm); 108 orig_ctrl = ctrl = pwm_lpss_read(pwm);
118 ctrl &= ~PWM_ON_TIME_DIV_MASK; 109 ctrl &= ~PWM_ON_TIME_DIV_MASK;
119 ctrl &= ~(base_unit_range << PWM_BASE_UNIT_SHIFT); 110 ctrl &= ~(base_unit_range << PWM_BASE_UNIT_SHIFT);
120 base_unit &= base_unit_range; 111 base_unit &= base_unit_range;
121 ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT; 112 ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT;
122 ctrl |= on_time_div; 113 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 }
124} 119}
125 120
126static inline void pwm_lpss_cond_enable(struct pwm_device *pwm, bool cond) 121static 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,
144 return ret; 139 return ret;
145 } 140 }
146 pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period); 141 pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
147 pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
148 pwm_lpss_cond_enable(pwm, lpwm->info->bypass == false); 142 pwm_lpss_cond_enable(pwm, lpwm->info->bypass == false);
149 ret = pwm_lpss_wait_for_update(pwm); 143 ret = pwm_lpss_wait_for_update(pwm);
150 if (ret) { 144 if (ret) {
@@ -157,7 +151,6 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
157 if (ret) 151 if (ret)
158 return ret; 152 return ret;
159 pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period); 153 pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
160 pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
161 return pwm_lpss_wait_for_update(pwm); 154 return pwm_lpss_wait_for_update(pwm);
162 } 155 }
163 } else if (pwm_is_enabled(pwm)) { 156 } else if (pwm_is_enabled(pwm)) {
@@ -168,8 +161,42 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
168 return 0; 161 return 0;
169} 162}
170 163
164/* This function gets called once from pwmchip_add to get the initial state */
165static 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
171static const struct pwm_ops pwm_lpss_ops = { 197static const struct pwm_ops pwm_lpss_ops = {
172 .apply = pwm_lpss_apply, 198 .apply = pwm_lpss_apply,
199 .get_state = pwm_lpss_get_state,
173 .owner = THIS_MODULE, 200 .owner = THIS_MODULE,
174}; 201};
175 202
@@ -214,6 +241,12 @@ EXPORT_SYMBOL_GPL(pwm_lpss_probe);
214 241
215int pwm_lpss_remove(struct pwm_lpss_chip *lpwm) 242int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
216{ 243{
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 }
217 return pwmchip_remove(&lpwm->chip); 250 return pwmchip_remove(&lpwm->chip);
218} 251}
219EXPORT_SYMBOL_GPL(pwm_lpss_remove); 252EXPORT_SYMBOL_GPL(pwm_lpss_remove);
diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h
index 7a4238ad1fcb..3236be835bd9 100644
--- a/drivers/pwm/pwm-lpss.h
+++ b/drivers/pwm/pwm-lpss.h
@@ -16,13 +16,25 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/pwm.h> 17#include <linux/pwm.h>
18 18
19struct pwm_lpss_chip; 19#define MAX_PWMS 4
20
21struct 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};
20 27
21struct pwm_lpss_boardinfo { 28struct pwm_lpss_boardinfo {
22 unsigned long clk_rate; 29 unsigned long clk_rate;
23 unsigned int npwm; 30 unsigned int npwm;
24 unsigned long base_unit_bits; 31 unsigned long base_unit_bits;
25 bool bypass; 32 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;
26}; 38};
27 39
28struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r, 40struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c
index 748f614d5375..a41812fc6f95 100644
--- a/drivers/pwm/pwm-rcar.c
+++ b/drivers/pwm/pwm-rcar.c
@@ -1,11 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * R-Car PWM Timer driver 3 * R-Car PWM Timer driver
3 * 4 *
4 * Copyright (C) 2015 Renesas Electronics Corporation 5 * 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.
9 */ 6 */
10 7
11#include <linux/clk.h> 8#include <linux/clk.h>
diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c
index 29267d12fb4c..4a855a21b782 100644
--- a/drivers/pwm/pwm-renesas-tpu.c
+++ b/drivers/pwm/pwm-renesas-tpu.c
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * R-Mobile TPU PWM driver 3 * R-Mobile TPU PWM driver
3 * 4 *
4 * Copyright (C) 2012 Renesas Solutions Corp. 5 * 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.
14 */ 6 */
15 7
16#include <linux/clk.h> 8#include <linux/clk.h>
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index f8ebbece57b7..48c4595a0ffc 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -300,7 +300,6 @@ static const struct of_device_id tegra_pwm_of_match[] = {
300 { .compatible = "nvidia,tegra186-pwm", .data = &tegra186_pwm_soc }, 300 { .compatible = "nvidia,tegra186-pwm", .data = &tegra186_pwm_soc },
301 { } 301 { }
302}; 302};
303
304MODULE_DEVICE_TABLE(of, tegra_pwm_of_match); 303MODULE_DEVICE_TABLE(of, tegra_pwm_of_match);
305 304
306static const struct dev_pm_ops tegra_pwm_pm_ops = { 305static const struct dev_pm_ops tegra_pwm_pm_ops = {
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index 7c71cdb8a9d8..ceb233dd6048 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -249,6 +249,7 @@ static void pwm_export_release(struct device *child)
249static int pwm_export_child(struct device *parent, struct pwm_device *pwm) 249static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
250{ 250{
251 struct pwm_export *export; 251 struct pwm_export *export;
252 char *pwm_prop[2];
252 int ret; 253 int ret;
253 254
254 if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags)) 255 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)
263 export->pwm = pwm; 264 export->pwm = pwm;
264 mutex_init(&export->lock); 265 mutex_init(&export->lock);
265 266
266 export->child.class = parent->class;
267 export->child.release = pwm_export_release; 267 export->child.release = pwm_export_release;
268 export->child.parent = parent; 268 export->child.parent = parent;
269 export->child.devt = MKDEV(0, 0); 269 export->child.devt = MKDEV(0, 0);
@@ -277,6 +277,10 @@ static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
277 export = NULL; 277 export = NULL;
278 return ret; 278 return ret;
279 } 279 }
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]);
280 284
281 return 0; 285 return 0;
282} 286}
@@ -289,6 +293,7 @@ static int pwm_unexport_match(struct device *child, void *data)
289static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm) 293static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
290{ 294{
291 struct device *child; 295 struct device *child;
296 char *pwm_prop[2];
292 297
293 if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags)) 298 if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
294 return -ENODEV; 299 return -ENODEV;
@@ -297,6 +302,11 @@ static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
297 if (!child) 302 if (!child)
298 return -ENODEV; 303 return -ENODEV;
299 304
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
300 /* for device_find_child() */ 310 /* for device_find_child() */
301 put_device(child); 311 put_device(child);
302 device_unregister(child); 312 device_unregister(child);