All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lars Poeschel <poeschel@lemonage.de>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Thierry Reding" <thierry.reding@gmail.com>,
	"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
	"Lee Jones" <lee.jones@linaro.org>,
	"open list:PWM SUBSYSTEM" <linux-pwm@vger.kernel.org>,
	"open list" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 1/2] pwm: sysfs: Set class on pwm devices
Date: Fri, 2 Oct 2020 15:08:44 +0200	[thread overview]
Message-ID: <20201002130844.udikqwzspp6zlyhh@lem-wkst-02.lemonage> (raw)
In-Reply-To: <20201002124616.GB3348424@kroah.com>

On Fri, Oct 02, 2020 at 02:46:16PM +0200, Greg Kroah-Hartman wrote:
> On Fri, Oct 02, 2020 at 02:30:47PM +0200, poeschel@lemonage.de wrote:
> > From: Lars Poeschel <poeschel@lemonage.de>
> > 
> > This adds a class to exported pwm devices.
> > Exporting a pwm through sysfs did not yield udev events. The
> > dev_uevent_filter function does filter-out devices without a bus or
> > class.
> > This was already addressed in commit
> > commit 7e5d1fd75c3d ("pwm: Set class for exported channels in sysfs")
> > but this did cause problems and the commit got reverted with
> > commit c289d6625237 ("Revert "pwm: Set class for exported channels in
> > sysfs"")
> > Problem with the previous approach was, that there is a clash if we have
> > multiple pwmchips:
> > 	echo 0 > pwmchip0/export
> > 	echo 0 > pwmchip1/export
> > would both export /sys/class/pwm/pwm0 .
> > 
> > Now this patch changes the sysfs interface. We do include the pwmchip
> > number into the pwm directory that gets exported.
> > With the example above we get:
> > 	/sys/class/pwm/pwm-0-0
> > 	/sys/class/pwm/pwm-1-0
> > We maintain ABI backward compatibility through symlinks.
> > 	/sys/class/pwm/pwmchip0/pwm0
> > 	/sys/class/pwm/pwmchip1/pwm0
> > are now symbolic links to the new names.
> > 
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
> > ---
> >  drivers/pwm/sysfs.c | 57 +++++++++++++++++++++++++++++++++++++--------
> >  1 file changed, 47 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
> > index 449dbc0f49ed..c708da17a857 100644
> > --- a/drivers/pwm/sysfs.c
> > +++ b/drivers/pwm/sysfs.c
> > @@ -240,8 +240,10 @@ static void pwm_export_release(struct device *child)
> >  
> >  static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
> >  {
> > +	struct pwm_chip *chip = dev_get_drvdata(parent);
> >  	struct pwm_export *export;
> >  	char *pwm_prop[2];
> > +	char *link_name;
> >  	int ret;
> >  
> >  	if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
> > @@ -256,25 +258,39 @@ static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
> >  	export->pwm = pwm;
> >  	mutex_init(&export->lock);
> >  
> > +	export->child.class = parent->class;
> >  	export->child.release = pwm_export_release;
> >  	export->child.parent = parent;
> >  	export->child.devt = MKDEV(0, 0);
> >  	export->child.groups = pwm_groups;
> > -	dev_set_name(&export->child, "pwm%u", pwm->hwpwm);
> > +	dev_set_name(&export->child, "pwm-%u-%u", chip->base, pwm->hwpwm);
> >  
> >  	ret = device_register(&export->child);
> > -	if (ret) {
> > -		clear_bit(PWMF_EXPORTED, &pwm->flags);
> > -		put_device(&export->child);
> > -		export = NULL;
> > -		return ret;
> > +	if (ret)
> > +		goto error;
> > +
> > +	link_name = kasprintf(GFP_KERNEL, "pwm%u", pwm->hwpwm);
> > +	if (link_name == NULL) {
> > +		ret = -ENOMEM;
> > +		goto dev_unregister;
> >  	}
> > -	pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm);
> > +
> > +	pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=%s",
> > +			export->child.kobj.name);
> >  	pwm_prop[1] = NULL;
> >  	kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
> 
> Do you still need to do this by hand?  Why can't this uevent field
> belong to the class and have it create this for you automatically when
> the device is added?

I did not add this with my patch, it was there before and I wonder, what
purpose it served, since the uevent was filtered because there was no
class there.
Now we have a class and now it works and this is what happens:

/sys/class/pwm# echo 0 > pwmchip1/export 
KERNEL[2111.952725] add      /devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip1/pwm-1-0 (pwm)
ACTION=add
DEVPATH=/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip1/pwm-1-0
SEQNUM=1546
SUBSYSTEM=pwm

KERNEL[2111.955155] change   /devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip1 (pwm)
ACTION=change
DEVPATH=/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip1
EXPORT=pwm-1-0
SEQNUM=1547
SUBSYSTEM=pwm

The first event is the event from device_register. It informs us that we
now have a new pwm-1-0. Nice.
The second is the event done here "by hand". It informs us, that
pwmchip1 changed. It has a new export now. For me personally this is not
needed, but also I don't think it is wrong.
You decide!

> >  	kfree(pwm_prop[0]);
> >  
> > -	return 0;
> > +	ret = sysfs_create_link(&parent->kobj, &export->child.kobj, link_name);
> 
> You create the link _after_ you told userspace it was there, you raced
> and lost :(

Are you sure ?
We inform userspace that there is a "pwm-1-0" now available. We do not say
anything about "pwm0". "pwm0" is the name of our symlink. This should
not be a problem.

> > +	return ret;
> > +
> > +dev_unregister:
> > +	device_unregister(&export->child);
> > +error:
> > +	clear_bit(PWMF_EXPORTED, &pwm->flags);
> > +	put_device(&export->child);
> > +	export = NULL;
> > +	return ret;
> >  }
> >  
> >  static int pwm_unexport_match(struct device *child, void *data)
> > @@ -286,6 +302,7 @@ static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
> >  {
> >  	struct device *child;
> >  	char *pwm_prop[2];
> > +	char *link_name;
> >  
> >  	if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
> >  		return -ENODEV;
> > @@ -294,7 +311,11 @@ static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
> >  	if (!child)
> >  		return -ENODEV;
> >  
> > -	pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm);
> > +	link_name = kasprintf(GFP_KERNEL, "pwm%u", pwm->hwpwm);
> > +	if (link_name)
> > +		sysfs_delete_link(&parent->kobj, &child->kobj, link_name);
> > +
> > +	pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=%s", child->kobj.name);
> >  	pwm_prop[1] = NULL;
> >  	kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
> 
> Same uevent question here.
> 
> Otherwise, this looks good, nice work in figuring out the is_visable
> stuff and everything.

Thanks! :-)
And thank you for your help so far.

Regards,
Lars

  reply	other threads:[~2020-10-02 13:08 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-02 12:30 [PATCH 1/2] pwm: sysfs: Set class on pwm devices poeschel
2020-10-02 12:32 ` [PATCH 2/2] Documentation: Reflect the changes to pwm sysfs poeschel
2020-10-02 12:44 ` [PATCH 1/2] pwm: sysfs: Set class on pwm devices Greg Kroah-Hartman
2020-10-02 12:46 ` Greg Kroah-Hartman
2020-10-02 13:08   ` Lars Poeschel [this message]
2020-10-02 13:35     ` Greg Kroah-Hartman
2020-10-05 13:42       ` Lars Poeschel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201002130844.udikqwzspp6zlyhh@lem-wkst-02.lemonage \
    --to=poeschel@lemonage.de \
    --cc=gregkh@linuxfoundation.org \
    --cc=lee.jones@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pwm@vger.kernel.org \
    --cc=thierry.reding@gmail.com \
    --cc=u.kleine-koenig@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.