[PATCH 3.12 046/127] pwm: Unexport children before chip removal

From: Jiri Slaby
Date: Fri Nov 25 2016 - 03:31:59 EST


From: David Hsu <davidhsu@xxxxxxxxxx>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 0733424c9ba9f42242409d1ece780777272f7ea1 upstream.

Exported pwm channels aren't removed before the pwmchip and are
leaked. This results in invalid sysfs files. This fix removes
all exported pwm channels before chip removal.

Signed-off-by: David Hsu <davidhsu@xxxxxxxxxx>
Fixes: 76abbdde2d95 ("pwm: Add sysfs interface")
Signed-off-by: Thierry Reding <thierry.reding@xxxxxxxxx>
Signed-off-by: Jiri Slaby <jslaby@xxxxxxx>
---
drivers/pwm/core.c | 2 ++
drivers/pwm/sysfs.c | 18 ++++++++++++++++++
include/linux/pwm.h | 5 +++++
3 files changed, 25 insertions(+)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 2ca95042a0b9..c244e7dc6d66 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -293,6 +293,8 @@ int pwmchip_remove(struct pwm_chip *chip)
unsigned int i;
int ret = 0;

+ pwmchip_sysfs_unexport_children(chip);
+
mutex_lock(&pwm_lock);

for (i = 0; i < chip->npwm; i++) {
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index 8c20332d4825..809b5ab9074c 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -348,6 +348,24 @@ void pwmchip_sysfs_unexport(struct pwm_chip *chip)
}
}

+void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
+{
+ struct device *parent;
+ unsigned int i;
+
+ parent = class_find_device(&pwm_class, NULL, chip,
+ pwmchip_sysfs_match);
+ if (!parent)
+ return;
+
+ for (i = 0; i < chip->npwm; i++) {
+ struct pwm_device *pwm = &chip->pwms[i];
+
+ if (test_bit(PWMF_EXPORTED, &pwm->flags))
+ pwm_unexport_child(parent, pwm);
+ }
+}
+
static int __init pwm_sysfs_init(void)
{
return class_register(&pwm_class);
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index f0feafd184a0..08b0215128dc 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -295,6 +295,7 @@ static inline void pwm_add_table(struct pwm_lookup *table, size_t num)
#ifdef CONFIG_PWM_SYSFS
void pwmchip_sysfs_export(struct pwm_chip *chip);
void pwmchip_sysfs_unexport(struct pwm_chip *chip);
+void pwmchip_sysfs_unexport_children(struct pwm_chip *chip);
#else
static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
{
@@ -303,6 +304,10 @@ static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip)
{
}
+
+static inline void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
+{
+}
#endif /* CONFIG_PWM_SYSFS */

#endif /* __LINUX_PWM_H */
--
2.10.2