]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
pwm: Unexport children before chip removal
authorDavid Hsu <davidhsu@google.com>
Tue, 9 Aug 2016 21:57:46 +0000 (14:57 -0700)
committerBen Hutchings <ben@decadent.org.uk>
Thu, 23 Feb 2017 03:53:57 +0000 (03:53 +0000)
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@google.com>
Fixes: 76abbdde2d95 ("pwm: Add sysfs interface")
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/pwm/core.c
drivers/pwm/sysfs.c
include/linux/pwm.h

index d2c35920ff08e7e84e4f1a6be3ce1c15454b2a4b..825b5e48be0835b5bb31c9d0424e40f1c4cd9250 100644 (file)
@@ -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++) {
index 4bd0c639e16da9d49598f637c5473ae37e419def..6c88e1adf63742f3b635defaaa84a965104f753f 100644 (file)
@@ -340,6 +340,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);
index e90628cac8fae57e8a88ecd9f93d2a2f1342b9d5..84e526a12defff85698b2cf01ba37d2abc16d05b 100644 (file)
@@ -299,6 +299,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)
 {
@@ -307,6 +308,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 */