From: David Hsu Date: Tue, 9 Aug 2016 21:57:46 +0000 (-0700) Subject: pwm: Unexport children before chip removal X-Git-Tag: v3.12.68~81 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=82ed23da6bd0a676b236ef085f507a5b78a9fef8;p=thirdparty%2Fkernel%2Fstable.git pwm: Unexport children before chip removal 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 Fixes: 76abbdde2d95 ("pwm: Add sysfs interface") Signed-off-by: Thierry Reding Signed-off-by: Jiri Slaby --- diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 2ca95042a0b93..c244e7dc6d660 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 8c20332d48258..809b5ab9074cc 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 f0feafd184a0d..08b0215128dc5 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 */