aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabrice Gasnier <fabrice.gasnier@st.com>2018-10-01 09:23:57 -0400
committerThierry Reding <thierry.reding@gmail.com>2018-10-12 07:51:33 -0400
commit552c02e3e7cfe2744b59de285aaea70021ae95c9 (patch)
tree53a28e6dca26ab1e000c1ae4e6ed1ad8c72e665e
parentc289d6625237aa785b484b4e94c23b3b91ea7e60 (diff)
pwm: Send a uevent on the pwmchip device upon channel sysfs (un)export
This patch sends a uevent (KOBJ_CHANGE) on the pwmchipN device, everytime a pwmX channel has been exported/unexported via sysfs. This allows udev to implement rules on such events, like: SUBSYSTEM=="pwm*", PROGRAM="/bin/sh -c '\ chown -R root:gpio /sys/class/pwm && chmod -R 770 /sys/class/pwm;\ chown -R root:gpio /sys/devices/platform/soc/*.pwm/pwm/pwmchip* && chmod -R 770 /sys/devices/platform/soc/*.pwm/pwm/pwmchip*\ '" This is a replacement patch for commit 7e5d1fd75c3d ("pwm: Set class for exported channels in sysfs"), see [1]. basic testing: $ udevadm monitor --environment & $ echo 0 > /sys/class/pwm/pwmchip0/export KERNEL[197.321736] change /devices/.../pwm/pwmchip0 (pwm) ACTION=change DEVPATH=/devices/.../pwm/pwmchip0 EXPORT=pwm0 SEQNUM=2045 SUBSYSTEM=pwm [1] https://lkml.org/lkml/2018/9/25/713 Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> Tested-by: Gottfried Haider <gottfried.haider@gmail.com> Tested-by: Michal Vokáč <michal.vokac@ysoft.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
-rw-r--r--drivers/pwm/sysfs.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index 4726d43aaa0c..ceb233dd6048 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -249,6 +249,7 @@ static void pwm_export_release(struct device *child)
249static int pwm_export_child(struct device *parent, struct pwm_device *pwm) 249static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
250{ 250{
251 struct pwm_export *export; 251 struct pwm_export *export;
252 char *pwm_prop[2];
252 int ret; 253 int ret;
253 254
254 if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags)) 255 if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
@@ -276,6 +277,10 @@ static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
276 export = NULL; 277 export = NULL;
277 return ret; 278 return ret;
278 } 279 }
280 pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm);
281 pwm_prop[1] = NULL;
282 kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
283 kfree(pwm_prop[0]);
279 284
280 return 0; 285 return 0;
281} 286}
@@ -288,6 +293,7 @@ static int pwm_unexport_match(struct device *child, void *data)
288static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm) 293static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
289{ 294{
290 struct device *child; 295 struct device *child;
296 char *pwm_prop[2];
291 297
292 if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags)) 298 if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
293 return -ENODEV; 299 return -ENODEV;
@@ -296,6 +302,11 @@ static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
296 if (!child) 302 if (!child)
297 return -ENODEV; 303 return -ENODEV;
298 304
305 pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm);
306 pwm_prop[1] = NULL;
307 kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
308 kfree(pwm_prop[0]);
309
299 /* for device_find_child() */ 310 /* for device_find_child() */
300 put_device(child); 311 put_device(child);
301 device_unregister(child); 312 device_unregister(child);