From: Drew Fustini <drew@beagleboard.org>
To: Geert Uytterhoeven <geert@linux-m68k.org>
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>,
Andy Shevchenko <andy.shevchenko@gmail.com>,
Alexandre Belloni <alexandre.belloni@bootlin.com>
Subject: Re: [PATCH] pinctrl: pinmux: Add pinmux-select debugfs file
Date: Fri, 29 Jan 2021 08:59:41 -0800 [thread overview]
Message-ID: <20210129165941.GB384703@x1> (raw)
In-Reply-To: <CAMuHMdVnCmUSn5AgjqJr1TAvGtAAVR=K=ZeM3+GagHueXmZeeQ@mail.gmail.com>
On Fri, Jan 29, 2021 at 12:02:43PM +0100, Geert Uytterhoeven wrote:
> Hi Drew,
>
> Thanks for your patch!
>
> On Fri, Jan 29, 2021 at 9:49 AM Drew Fustini <drew@beagleboard.org> wrote:
> > Add "pinmux-select" to debugfs which will activate a function and group
> > when 2 integers "<function-selector> <group-selector>" are written to
> > the file. The write operation pinmux_select() handles this by checking
> > if fsel and gsel are valid selectors and then calling ops->set_mux().
> >
> > The existing "pinmux-functions" debugfs file lists the pin functions
> > registered for the pin controller. For example:
> >
> > function: pinmux-uart0, groups = [ pinmux-uart0-pins ]
> > function: pinmux-mmc0, groups = [ pinmux-mmc0-pins ]
> > function: pinmux-mmc1, groups = [ pinmux-mmc1-pins ]
> > function: pinmux-i2c0, groups = [ pinmux-i2c0-pins ]
> > function: pinmux-i2c1, groups = [ pinmux-i2c1-pins ]
> > function: pinmux-spi1, groups = [ pinmux-spi1-pins ]
> >
> > To activate function pinmux-i2c1 (fsel 4) and group pinmux-i2c1-pins
> > (gsel 4):
> >
> > echo '4 4' > pinmux-select
>
> Shouldn't gsel be "0" in your example, as "pinmux-i2c1-pins" is the
> first entry in the groups array?
>
> [ /me actually tries this]
>
> Oh, gsel is not the index inside the groups array, but the global index?
>
> On R-Car M2-W, which does not use pinctrl-single, I have:
>
> function 0: audio_clk, groups = [ audio_clk_a audio_clk_b
> audio_clk_b_b audio_clk_c audio_clkout ]
> function 1: avb, groups = [ avb_link avb_magic avb_phy_int
> avb_mdio avb_mii avb_gmii ]
> function 2: can0, groups = [ can0_data can0_data_b can0_data_c
> can0_data_d can0_data_e can0_data_f can_clk can_clk_b can_clk_c
> can_clk_d ]
> function 3: can1, groups = [ can1_data can1_data_b can1_data_c
> can1_data_d can_clk can_clk_b can_clk_c can_clk_d ]
> function 4: can_clk, groups = [ can_clk can_clk_b can_clk_c can_clk_d ]
> function 5: du, groups = [ du_rgb666 du_rgb888 du_clk_out_0
> du_clk_out_1 du_sync du_oddf du_cde du_disp ]
> function 6: du0, groups = [ du0_clk_in ]
> function 7: du1, groups = [ du1_clk_in du1_clk_in_b du1_clk_in_c ]
> function 8: eth, groups = [ eth_link eth_magic eth_mdio eth_rmii ]
> function 9: hscif0, groups = [ hscif0_data hscif0_clk hscif0_ctrl
> hscif0_data_b hscif0_ctrl_b hscif0_data_c hscif0_clk_c ]
> function 10: hscif1, groups = [ hscif1_data hscif1_clk hscif1_ctrl
> hscif1_data_b hscif1_data_c hscif1_clk_c hscif1_ctrl_c hscif1_data_d
> hscif1_data_e hscif1_clk_e hscif1_ctrl_e ]
> function 11: hscif2, groups = [ hscif2_data hscif2_clk hscif2_ctrl
> hscif2_data_b hscif2_ctrl_b hscif2_data_c hscif2_clk_c hscif2_data_d ]
> function 12: i2c0, groups = [ i2c0 i2c0_b i2c0_c ]
> function 13: i2c1, groups = [ i2c1 i2c1_b i2c1_c i2c1_d i2c1_e ]
> function 14: i2c2, groups = [ i2c2 i2c2_b i2c2_c i2c2_d ]
> [...]
>
> Took me a few tries, crashes, and debug prints, to discover that I did
> not count wrong, but that names were de-duplicated (the "can_clk*" in
> functions 2 and 3 are not accessible by gsel), and that "75" not "83" is
> the right number to configure i2c2.
>
> But then it works (on the Koelsch board):
>
> # cd /sys/kernel/debug/pinctrl/e6060000.pinctrl-sh-pfc/
> # echo 14 289 > pinmux-select # Configure i2c2 pins for ssi2_ctrl
> # i2cdetect -y -a 2 # Fails
> # echo 14 75 > pinmux-select # Restore i2c2
> # i2cdetect -y -a 2 # Works again
>
> Nice!
>
> So we definitely want to use the actual names, not error-prone numbers,
> at least for pinctrl drivers that use the concept of names.
> As we do specify the names in DT, cfr.
> arch/arm/boot/dts/r8a7791-koelsch.dts:
>
> i2c2_pins: i2c2 {
> groups = "i2c2";
> function = "i2c2";
> };
>
> the pinmux core already knows how to look them up.
> See pinmux_map_to_setting().
>
> > --- a/drivers/pinctrl/pinmux.c
> > +++ b/drivers/pinctrl/pinmux.c
> > @@ -673,6 +673,65 @@ void pinmux_show_setting(struct seq_file *s,
> > DEFINE_SHOW_ATTRIBUTE(pinmux_functions);
> > DEFINE_SHOW_ATTRIBUTE(pinmux_pins);
> >
> > +static ssize_t pinmux_select(struct file *file, const char __user *user_buf,
> > + size_t len, loff_t *ppos)
> > +{
> > + struct seq_file *sfile = file->private_data;
> > + struct pinctrl_dev *pctldev = sfile->private;
> > + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
> > + const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
> > + int fsel, gsel, ret;
> > + char buf[16];
> > +
> > + if (len > sizeof(buf)) {
> > + dev_err(pctldev->dev, "write too big for buffer");
> > + return -EINVAL;
> > + }
> > +
> > + ret = strncpy_from_user(buf, user_buf, sizeof(buf));
> > + if (ret < 0)
> > + return ret;
> > + buf[len-1] = '\0';
> > +
> > + ret = sscanf(buf, "%d %d", &fsel, &gsel);
> > + if (ret != 2) {
> > + dev_err(pctldev->dev, "expected format: <function#> <group#>");
> > + return -EINVAL;
> > + }
> > +
> > + if (!pmxops->get_function_name(pctldev, fsel)) {
>
> At least for the Renesas pinctrl driver, get_function_name() happily
> iterates beyond the end of the internal array, which may crash.
> Using pinmux_func_name_to_selector() would avoid that.
>
> > + dev_err(pctldev->dev, "function selector %u not valid\n", fsel);
> > + return -EINVAL;
> > + }
> > +
> > + if (!pctlops->get_group_name(pctldev, gsel)) {
>
> Likewise.
>
> Use pmxops->get_function_groups() and match_string() instead?
>
> > + dev_err(pctldev->dev, "group selector %u not valid\n", gsel);
> > + return -EINVAL;
> > + }
> > +
> > + ret = pmxops->set_mux(pctldev, fsel, gsel);
> > + if (ret) {
> > + dev_err(pctldev->dev, "set_mux() failed: %d", ret);
> > + return -EINVAL;
> > + }
> > +
> > + return len;
> > +}
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
Thanks very much for the comments, Geert. It is great to get feedback on
how it behaves on other pin control hardware.
I agree the selectors get confusing, and it does make more sense to use
the function and group names in 'pinmux-select'. I was initially
discouraged when I didn't see an efficient way to do a lookup in the
radix trees based on name. I'll take a look at the functions that you
mentioned as they look promising.
thanks,
drew
prev parent reply other threads:[~2021-01-29 17:03 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20210129084759.372658-1-drew@beagleboard.org>
[not found] ` <CAHp75VcpqbFjHX9PtC=EWafacrWMP=c0KXyDDdJJRjAuh7Xcsg@mail.gmail.com>
2021-01-29 16:55 ` [PATCH] pinctrl: pinmux: Add pinmux-select debugfs file Drew Fustini
[not found] ` <CAMuHMdVnCmUSn5AgjqJr1TAvGtAAVR=K=ZeM3+GagHueXmZeeQ@mail.gmail.com>
2021-01-29 16:59 ` Drew Fustini [this message]
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=20210129165941.GB384703@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.