Skip to content

Commit

Permalink
pwm: Create device class for pwm channels
Browse files Browse the repository at this point in the history
#https://lkml.org/lkml/2016/6/14/967

Pwm channels don't send uevents when exported, this change adds the
channels to a pwm class and set their device type to pwm_channel so
uevents are sent.

To do this properly, the device names need to change to uniquely
identify a channel.  This change is from pwmN to pwm-(chip->base):N

Signed-off-by: David Hsu <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Robert Nelson <[email protected]>
  • Loading branch information
David Hsu authored and RobertCNelson committed May 15, 2020
1 parent be11c72 commit 0e09cd3
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
6 changes: 4 additions & 2 deletions Documentation/pwm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ will find:

The PWM channels are numbered using a per-chip index from 0 to npwm-1.

When a PWM channel is exported a pwmX directory will be created in the
When a PWM channel is exported a pwm-N:X directory will be created in the
pwmchipN directory it is associated with, where X is the number of the
channel that was exported. The following properties will then be available:
channel that was exported. It will also be exposed at /sys/class/pwm/ and
can be identified by the pwm_channel device type.
The following properties will then be available:

period
The total period of the PWM signal (read/write).
Expand Down
15 changes: 12 additions & 3 deletions drivers/pwm/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <linux/kdev_t.h>
#include <linux/pwm.h>

static struct class pwm_class;

struct pwm_export {
struct device child;
struct pwm_device *pwm;
Expand Down Expand Up @@ -239,6 +241,10 @@ static struct attribute *pwm_attrs[] = {
};
ATTRIBUTE_GROUPS(pwm);

static const struct device_type pwm_channel_type = {
.name = "pwm_channel",
};

static void pwm_export_release(struct device *child)
{
struct pwm_export *export = child_to_pwm_export(child);
Expand All @@ -248,6 +254,7 @@ 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;
int ret;

Expand All @@ -265,9 +272,11 @@ static int pwm_export_child(struct device *parent, struct pwm_device *pwm)

export->child.release = pwm_export_release;
export->child.parent = parent;
export->child.type = &pwm_channel_type;
export->child.devt = MKDEV(0, 0);
export->child.class = &pwm_class;
export->child.groups = pwm_groups;
dev_set_name(&export->child, "pwm%u", pwm->hwpwm);
dev_set_name(&export->child, "pwm-%d:%u", chip->base, pwm->hwpwm);

ret = device_register(&export->child);
if (ret) {
Expand Down Expand Up @@ -372,7 +381,6 @@ ATTRIBUTE_GROUPS(pwm_chip);
static struct class pwm_class = {
.name = "pwm",
.owner = THIS_MODULE,
.dev_groups = pwm_chip_groups,
};

static int pwmchip_sysfs_match(struct device *parent, const void *data)
Expand All @@ -388,7 +396,8 @@ void pwmchip_sysfs_export(struct pwm_chip *chip)
* If device_create() fails the pwm_chip is still usable by
* the kernel its just not exported.
*/
parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
parent = device_create_with_groups(&pwm_class, chip->dev, MKDEV(0, 0),
chip, pwm_chip_groups,
"pwmchip%d", chip->base);
if (IS_ERR(parent)) {
dev_warn(chip->dev,
Expand Down

0 comments on commit 0e09cd3

Please sign in to comment.