Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932232AbdDPLTt (ORCPT ); Sun, 16 Apr 2017 07:19:49 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:59108 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756609AbdDPKwh (ORCPT ); Sun, 16 Apr 2017 06:52:37 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, David Hsu , Thierry Reding Subject: [PATCH 3.18 030/145] pwm: Unexport children before chip removal Date: Sun, 16 Apr 2017 12:48:43 +0200 Message-Id: <20170416080201.904663428@linuxfoundation.org> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20170416080200.205458595@linuxfoundation.org> References: <20170416080200.205458595@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2245 Lines: 83 3.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: David Hsu 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: Greg Kroah-Hartman --- drivers/pwm/core.c | 2 ++ drivers/pwm/sysfs.c | 18 ++++++++++++++++++ include/linux/pwm.h | 5 +++++ 3 files changed, 25 insertions(+) --- 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++) { --- a/drivers/pwm/sysfs.c +++ b/drivers/pwm/sysfs.c @@ -340,6 +340,24 @@ void pwmchip_sysfs_unexport(struct pwm_c } } +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); --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -299,6 +299,7 @@ static inline void pwm_add_table(struct #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( 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 */