Skip to content

Commit

Permalink
pwm: Unexport children before chip removal
Browse files Browse the repository at this point in the history
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: 76abbdd ("pwm: Add sysfs interface")
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
  • Loading branch information
David Hsu authored and thierryreding committed Sep 5, 2016
1 parent 29b4817 commit 0733424
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/pwm/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down
18 changes: 18 additions & 0 deletions drivers/pwm/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions include/linux/pwm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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 */

0 comments on commit 0733424

Please sign in to comment.