pwm: Unexport children before chip removal
authorDavid Hsu <davidhsu@google.com>
Tue, 9 Aug 2016 21:57:46 +0000 (14:57 -0700)
committerThierry Reding <thierry.reding@gmail.com>
Mon, 5 Sep 2016 14:45:39 +0000 (16:45 +0200)
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>
drivers/pwm/core.c
drivers/pwm/sysfs.c
include/linux/pwm.h

index 0dbd29e287dbbf495a28fa4b142fb407773b2f0d..172ef82458112c268782d24f55cd882904340ea8 100644 (file)
@@ -339,6 +339,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 18ed725594c316ab71edafdafb5e1912714de7f1..0296d8178ae29d509306670c9bb85147c50f0633 100644 (file)
@@ -409,6 +409,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 f1bbae014889b67a219a73c1e76156aa53229024..2c6c5114c089456cf0d3bac380a922132b077b7d 100644 (file)
@@ -641,6 +641,7 @@ static inline void pwm_remove_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)
 {
@@ -649,6 +650,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 */