From: Drew Fustini <drew@beagleboard.org>
To: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: "open list:GPIO SUBSYSTEM" <linux-gpio@vger.kernel.org>,
Pantelis Antoniou <pantelis.antoniou@konsulko.com>,
Jason Kridner <jkridner@beagleboard.org>,
Robert Nelson <robertcnelson@beagleboard.org>,
Linus Walleij <linus.walleij@linaro.org>,
Tony Lindgren <tony@atomide.com>,
Alexandre Belloni <alexandre.belloni@bootlin.com>,
Geert Uytterhoeven <geert@linux-m68k.org>
Subject: Re: [RFC PATCH] pinctrl: pinmux: Add pinmux-set debugfs file
Date: Thu, 21 Jan 2021 15:26:53 -0800 [thread overview]
Message-ID: <20210121232653.GA672978@x1> (raw)
In-Reply-To: <CAHp75Vd5M0kyNzq+5gcZEd=6hK_7Y5_dEJ39-yQO7WuYRM4KWw@mail.gmail.com>
On Thu, Jan 21, 2021 at 01:18:58PM +0200, Andy Shevchenko wrote:
> On Thu, Jan 21, 2021 at 7:18 AM Drew Fustini <drew@beagleboard.org> wrote:
> >
> > This RFC is a change in approach from my previous RFC patch [1]. It adds
> > "pinnux-set" to debugfs. A function and group on the pin control device
> > will be activated when 2 integers "<function-selector> <group-selector>"
> > are written to the file. The debugfs write operation pinmux_set_write()
> > handles this by calling ops->set_mux() with fsel and gsel.
>
> s/ops//
Ok, thanks.
>
> > RFC question: should pinmux-set take function name and group name
> > instead of the selector numbers?
>
> I would prefer names and integers (but from user p.o.v. names are
> easier to understand, while numbers are good for scripting).
I don't actually see any example of looking up the function name in the
existing pinctrl code. There is pin_function_tree in struct pinctrl_dev.
pinmux_generic_get_function_name() does radix_tree_lookup() with the
selector integer as the key, but there is no corresponding "get function
selector by name" function.
I think I would need to go through all the nodes in the radix tree to
find the name that matches. Although, I am just learning now about the
radix implementation in Linux so there might be a simpler way that I am
missing.
>
> The following is better to include in documentation and remove from
> the commit message.
>
> > The following is an example on the PocketBeagle [2] which has the AM3358
> > SoC and binds to pinctrl-single. I added this to the device tree [3] to
> > represent two of the pins on the expansion header as an example: P1.36
> > and P2.01. Both of these header pins are designed to be set to PWM mode
> > by default [4] but can now be set back to gpio mode through pinmux-set.
>
> ...
>
> > The following shows the pin functions registered for the pin controller:
> >
> > root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single# cat pinmux-functions
>
> Shorter is better, what about simply
>
> # cat /sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single/pinmux-functions
> ?
>
> Btw in reST format you may create a nice citation of this. And yes,
> this should also go to the documentation.
Good point, I'll shorten the example lines in v2.
> > function: pinmux_P1_36_default_pin, groups = [ pinmux_P1_36_default_pin ]
> > function: pinmux_P2_01_default_pin, groups = [ pinmux_P2_01_default_pin ]
> > function: pinmux_P1_36_gpio_pin, groups = [ pinmux_P1_36_gpio_pin ]
> > function: pinmux_P1_36_gpio_pu_pin, groups = [ pinmux_P1_36_gpio_pu_pin ]
> > function: pinmux_P1_36_gpio_pd_pin, groups = [ pinmux_P1_36_gpio_pd_pin ]
> > function: pinmux_P1_36_gpio_input_pin, groups = [ pinmux_P1_36_gpio_input_pin ]
> > function: pinmux_P1_36_pwm_pin, groups = [ pinmux_P1_36_pwm_pin ]
> > function: pinmux_P2_01_gpio_pin, groups = [ pinmux_P2_01_gpio_pin ]
> > function: pinmux_P2_01_gpio_pu_pin, groups = [ pinmux_P2_01_gpio_pu_pin ]
> > function: pinmux_P2_01_gpio_pd_pin, groups = [ pinmux_P2_01_gpio_pd_pin ]
> > function: pinmux_P2_01_gpio_input_pin, groups = [ pinmux_P2_01_gpio_input_pin ]
> > function: pinmux_P2_01_pwm_pin, groups = [ pinmux_P2_01_pwm_pin ]
> > function: pinmux-uart0-pins, groups = [ pinmux-uart0-pins ]
> > function: pinmux-mmc0-pins, groups = [ pinmux-mmc0-pins ]
> > function: pinmux-i2c0-pins, groups = [ pinmux-i2c0-pins ]
> >
> > Activate the pinmux_P1_36_gpio_pin function (fsel 2):
> >
> > root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single# echo '2 2' > pinmux-set
> >
> > Extra debug output that I added shows that pinctrl-single's set_mux()
> > has set the register correctly for gpio mode:
> >
> > pinmux core: DEBUG pinmux_set_write(): returned 0
> > pinmux core: DEBUG pinmux_set_write(): buf=[2 2]
> > pinmux core: DEBUG pinmux_set_write(): sscanf(2,2)
> > pinmux core: DEBUG pinmux_set_write(): call ops->set_mux(fsel=2, gsel=2)
> > pinctrl-single 44e10800.pinmux: DEBUG pcs_set_mux(): call pinmux_generic_get_function() on fselector=2
> > pinctrl-single 44e10800.pinmux: enabling (null) function2
> > pinctrl-single 44e10800.pinmux: DEBUG pcs_set_mux(): func->nvals=1
> > pinctrl-single 44e10800.pinmux: DEBUG pcs_set_mux(): offset=0x190 old_val=0x21 val=0x2f
> >
> > Activate the pinmux_P1_36_pwm_pin function (fsel 6):
> >
> > root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single# echo '6 6' > pinmux-set
> >
> > pinctrl-single set_mux() is able to set register correctly for pwm mode:
> >
> > pinmux core: DEBUG pinmux_set_write(): returned 0
> > pinmux core: DEBUG pinmux_set_write(): buf=[6 6]
> > pinmux core: DEBUG pinmux_set_write(): sscanf(6,6)
> > pinmux core: DEBUG pinmux_set_write(): call ops->set_mux(fsel=6, gsel=6)
> > pinctrl-single 44e10800.pinmux: DEBUG pcs_set_mux(): call pinmux_generic_get_function() on fselector=6
> > pinctrl-single 44e10800.pinmux: enabling (null) function6
> > pinctrl-single 44e10800.pinmux: DEBUG pcs_set_mux(): func->nvals=1
> > pinctrl-single 44e10800.pinmux: DEBUG pcs_set_mux(): offset=0x190 old_val=0x2f val=0x21
>
> This and above is still part of documentation, and not a commit message thingy.
Is something I should add to Documentation/driver-api/pinctl.rst in a
seperate patch?
>
> ...
>
> > +static ssize_t pinmux_set_write(struct file *file, const char __user *user_buf,
> > + size_t cnt, loff_t *ppos)
> > +{
> > + int err;
> > + int fsel;
> > + int gsel;
> > + int ret;
> > + char *buf;
> > + struct seq_file *sfile;
> > + struct pinctrl_dev *pctldev;
> > + const struct pinmux_ops *ops;
>
> Reversed xmas tree order please, and you may group some of them, like
>
> int fsel, gsel;
>
Ok, understood.
> > + if (*ppos != 0)
> > + return -EINVAL;
>
> > + if (cnt == 0)
> > + return 0;
>
> Has it ever happened here?
Good point, I guess there is no reason for userspace to write 0 bytes.
> > + buf = memdup_user_nul(user_buf, cnt);
> > + if (IS_ERR(buf))
> > + return PTR_ERR(buf);
> > +
> > + if (buf[cnt - 1] == '\n')
> > + buf[cnt - 1] = '\0';
>
> Shouldn't you rather use strndup_from_user() (or how is it called?)
>
> > + ret = sscanf(buf, "%d %d", &fsel, &gsel);
> > + if (ret != 2) {
> > + pr_warn("%s: sscanf() expects '<fsel> <gsel>'", __func__);
>
> No __func__ and instead use dev_err() (it is strange you are using
> warn level for errors).
>
Ok, that makes sense. I used warn because I wasn't sure if bad format in
a write to a debugfs file rises to the level of error.
> > + err = -EINVAL;
> > + goto err_freebuf;
> > + }
>
> > + sfile = file->private_data;
> > + pctldev = sfile->private;
>
> These can be applied directly in the definition block above.
I'll clean that up.
>
> > + ops = pctldev->desc->pmxops;
> > + ret = ops->set_mux(pctldev, fsel, gsel);
>
> > + if (ret != 0) {
>
> if (ret)
>
> > + pr_warn("%s(): set_mux() failed: %d", __func__, ret);
>
> As above.
>
> > + err = -EINVAL;
> > + goto err_freebuf;
> > + }
>
> > + kfree(buf);
> > + return cnt;
> > +
> > +err_freebuf:
> > + kfree(buf);
> > + return err;
>
> Can be simply
>
> err_freebuf:
> kfree(buf);
> return err ?: cnt;
Thanks, I didn't really like the duplication but was having trouble
thinking of a cleaner way to write it. That is good to know it is ok to
use the ternary operator in a return statement.
>
> > +}
> > +
>
> ...
>
> > + debugfs_create_file("pinmux-set", S_IFREG | S_IWUSR,
> > + devroot, pctldev, &pinmux_set_ops);
>
> I would rather call it 'pinmux-select'.
I think that makes sense, too.
>
> Overall since it's a debugfs I do not much care about interfaces and
> particular implementation details, but in general looks good to me,
> thanks for doing this!
Thanks for the review. I'll get a v2 posted.
-Drew
next prev parent reply other threads:[~2021-01-21 23:28 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-21 5:18 [RFC PATCH] pinctrl: pinmux: Add pinmux-set debugfs file Drew Fustini
2021-01-21 11:18 ` Andy Shevchenko
2021-01-21 23:26 ` Drew Fustini [this message]
2021-01-22 9:50 ` Andy Shevchenko
2021-01-22 23:16 ` Drew Fustini
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=20210121232653.GA672978@x1 \
--to=drew@beagleboard.org \
--cc=alexandre.belloni@bootlin.com \
--cc=andy.shevchenko@gmail.com \
--cc=geert@linux-m68k.org \
--cc=jkridner@beagleboard.org \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=pantelis.antoniou@konsulko.com \
--cc=robertcnelson@beagleboard.org \
--cc=tony@atomide.com \
/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.