From: swarren@wwwdotorg.org (Stephen Warren)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] pinctrl/pinconfig: add debug interface
Date: Mon, 11 Feb 2013 13:53:55 -0700 [thread overview]
Message-ID: <51195A63.7080706@wwwdotorg.org> (raw)
In-Reply-To: <1360527070-18430-1-git-send-email-linus.walleij@stericsson.com>
On 02/10/2013 01:11 PM, Linus Walleij wrote:
> From: Laurent Meunier <laurent.meunier@st.com>
>
> This update adds a debugfs interface to modify a pin configuration
> for a given state in the pinctrl map. This allows to modify the
> configuration for a non-active state, typically sleep state.
> This configuration is not applied right away, but only when the state
> will be entered.
>
> This solution is mandated for us by HW validation: in order
> to test and verify several pin configurations during sleep without
> recompiling the software.
I never understood why HW engineers can't just recompile the kernel.
Besides, it's just a device tree change these days - no recompile even
required, right?
> diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c
To be worth including, hadn't this feature also better also allow
editing of pin mux settings too, and even addition/removal of entries,
so some more core file would be a better place?
> +/* 32bit read/write ressources */
> +#define MAX_NAME_LEN 16
> +char dbg_pinname[MAX_NAME_LEN]; /* shared: name of the state of the pin*/
> +char dbg_state_name[MAX_NAME_LEN]; /* shared: state of the pin*/
> +static u32 dbg_config; /* shared: config to be read/set for the pin & state*/
Rather than setting pin name, state name, and config separately,
wouldn't it be better to accept a single write() with all those
parameters contained in it at once, so no persistent state was required.
Say something like:
modify configs_pin devicename state pinname newvalue
That would allow "add", "delete" to be implemented in addition to modify
later if desired.
> +static int pinconf_dbg_pinname_write(struct file *file,
> + const char __user *user_buf, size_t count, loff_t *ppos)
> +{
> + int err;
> +
> + if (count > MAX_NAME_LEN)
> + return -EINVAL;
> +
> + err = sscanf(user_buf, "%15s", dbg_pinname);
That %15 had better somehow be related to MAX_NAME_LEN.
I'd suggest making MAX_NAME_LEN 15, and the variable declarations above
use MAX_NAME_LEN + 1, so that MAX_NAME_LEN can be used as part of the
scanf parameter here.
> +/**
> + * pinconf_dbg_config_write() - overwrite the pinctrl config in thepinctrl
> + * map, of a pin/state pair based on pinname and state that have been
> + * selected with the debugfs entries pinconf-name and pinconf-state
> + */
> +static int pinconf_dbg_config_write(struct file *file,
> + const char __user *user_buf, size_t count, loff_t *ppos)
> +{
> + int err;
> + unsigned long config;
> + struct pinctrl_maps *maps_node;
> + struct pinctrl_map const *map;
> + int i, j;
> +
> + err = kstrtoul_from_user(user_buf, count, 0, &config);
> +
> + if (err)
> + return err;
> +
> + dbg_config = config;
That assumes that pin config values are a plain u32. While this is
commonly true in existing pinctrl drivers, it certainly isn't something
that the pinctrl core mandates; that's the whole point of
dt_node_to_map() for example, to allow the individual pinctrl drivers to
use whatever type (scalar, pointer-to-struct, ...) they want to
represent their config values.
> +
> + mutex_lock(&pinctrl_mutex);
> +
> + /* Parse the pinctrl map and look for the selected pin/state */
> + for_each_maps(maps_node, i, map) {
> + if (map->type != PIN_MAP_TYPE_CONFIGS_PIN)
> + continue;
> +
> + if (strncmp(map->name, dbg_state_name, MAX_NAME_LEN) > 0)
> + continue;
What about the device name; this changes that state in every device's
map table entry.
> +
> + /* we found the right pin / state, so overwrite config */
> + for (j = 0; j < map->data.configs.num_configs; j++) {
> + if (strncmp(map->data.configs.group_or_pin, dbg_pinname,
> + MAX_NAME_LEN) == 0)
Why compare this inside the per-config loop;
map->data.configs.group_or_pin is something "global" to the entire
struct, and not specific to each configs[] entry.
> + map->data.configs.configs[j] = dbg_config;
Given that dbg_config is written to by this function, then used by this
function, why even make it a global? The only other use is
pinconf_dbg_config_print(), which can also make it a local variable.
Overall, I'm not convinced of the utility of this patch upstream. Sorry.
WARNING: multiple messages have this Message-ID (diff)
From: Stephen Warren <swarren@wwwdotorg.org>
To: Linus Walleij <linus.walleij@stericsson.com>
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
Stephen Warren <swarren@nvidia.com>,
Anmar Oueja <anmar.oueja@linaro.org>,
Laurent Meunier <laurent.meunier@st.com>,
Linus Walleij <linus.walleij@linaro.org>
Subject: Re: [PATCH] pinctrl/pinconfig: add debug interface
Date: Mon, 11 Feb 2013 13:53:55 -0700 [thread overview]
Message-ID: <51195A63.7080706@wwwdotorg.org> (raw)
In-Reply-To: <1360527070-18430-1-git-send-email-linus.walleij@stericsson.com>
On 02/10/2013 01:11 PM, Linus Walleij wrote:
> From: Laurent Meunier <laurent.meunier@st.com>
>
> This update adds a debugfs interface to modify a pin configuration
> for a given state in the pinctrl map. This allows to modify the
> configuration for a non-active state, typically sleep state.
> This configuration is not applied right away, but only when the state
> will be entered.
>
> This solution is mandated for us by HW validation: in order
> to test and verify several pin configurations during sleep without
> recompiling the software.
I never understood why HW engineers can't just recompile the kernel.
Besides, it's just a device tree change these days - no recompile even
required, right?
> diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c
To be worth including, hadn't this feature also better also allow
editing of pin mux settings too, and even addition/removal of entries,
so some more core file would be a better place?
> +/* 32bit read/write ressources */
> +#define MAX_NAME_LEN 16
> +char dbg_pinname[MAX_NAME_LEN]; /* shared: name of the state of the pin*/
> +char dbg_state_name[MAX_NAME_LEN]; /* shared: state of the pin*/
> +static u32 dbg_config; /* shared: config to be read/set for the pin & state*/
Rather than setting pin name, state name, and config separately,
wouldn't it be better to accept a single write() with all those
parameters contained in it at once, so no persistent state was required.
Say something like:
modify configs_pin devicename state pinname newvalue
That would allow "add", "delete" to be implemented in addition to modify
later if desired.
> +static int pinconf_dbg_pinname_write(struct file *file,
> + const char __user *user_buf, size_t count, loff_t *ppos)
> +{
> + int err;
> +
> + if (count > MAX_NAME_LEN)
> + return -EINVAL;
> +
> + err = sscanf(user_buf, "%15s", dbg_pinname);
That %15 had better somehow be related to MAX_NAME_LEN.
I'd suggest making MAX_NAME_LEN 15, and the variable declarations above
use MAX_NAME_LEN + 1, so that MAX_NAME_LEN can be used as part of the
scanf parameter here.
> +/**
> + * pinconf_dbg_config_write() - overwrite the pinctrl config in thepinctrl
> + * map, of a pin/state pair based on pinname and state that have been
> + * selected with the debugfs entries pinconf-name and pinconf-state
> + */
> +static int pinconf_dbg_config_write(struct file *file,
> + const char __user *user_buf, size_t count, loff_t *ppos)
> +{
> + int err;
> + unsigned long config;
> + struct pinctrl_maps *maps_node;
> + struct pinctrl_map const *map;
> + int i, j;
> +
> + err = kstrtoul_from_user(user_buf, count, 0, &config);
> +
> + if (err)
> + return err;
> +
> + dbg_config = config;
That assumes that pin config values are a plain u32. While this is
commonly true in existing pinctrl drivers, it certainly isn't something
that the pinctrl core mandates; that's the whole point of
dt_node_to_map() for example, to allow the individual pinctrl drivers to
use whatever type (scalar, pointer-to-struct, ...) they want to
represent their config values.
> +
> + mutex_lock(&pinctrl_mutex);
> +
> + /* Parse the pinctrl map and look for the selected pin/state */
> + for_each_maps(maps_node, i, map) {
> + if (map->type != PIN_MAP_TYPE_CONFIGS_PIN)
> + continue;
> +
> + if (strncmp(map->name, dbg_state_name, MAX_NAME_LEN) > 0)
> + continue;
What about the device name; this changes that state in every device's
map table entry.
> +
> + /* we found the right pin / state, so overwrite config */
> + for (j = 0; j < map->data.configs.num_configs; j++) {
> + if (strncmp(map->data.configs.group_or_pin, dbg_pinname,
> + MAX_NAME_LEN) == 0)
Why compare this inside the per-config loop;
map->data.configs.group_or_pin is something "global" to the entire
struct, and not specific to each configs[] entry.
> + map->data.configs.configs[j] = dbg_config;
Given that dbg_config is written to by this function, then used by this
function, why even make it a global? The only other use is
pinconf_dbg_config_print(), which can also make it a local variable.
Overall, I'm not convinced of the utility of this patch upstream. Sorry.
next prev parent reply other threads:[~2013-02-11 20:53 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-10 20:11 [PATCH] pinctrl/pinconfig: add debug interface Linus Walleij
2013-02-10 20:11 ` Linus Walleij
2013-02-11 20:53 ` Stephen Warren [this message]
2013-02-11 20:53 ` Stephen Warren
2013-02-11 21:00 ` Tony Lindgren
2013-02-11 21:00 ` Tony Lindgren
2013-02-11 21:13 ` Stephen Warren
2013-02-11 21:13 ` Stephen Warren
2013-02-11 21:21 ` Tony Lindgren
2013-02-11 21:21 ` Tony Lindgren
2013-02-11 21:23 ` Stephen Warren
2013-02-11 21:23 ` Stephen Warren
2013-02-11 21:33 ` Tony Lindgren
2013-02-11 21:33 ` Tony Lindgren
2013-02-12 12:54 ` Linus Walleij
2013-02-12 12:54 ` Linus Walleij
2013-02-12 15:32 ` Haojian Zhuang
2013-02-12 15:32 ` Haojian Zhuang
2013-02-12 16:57 ` Stephen Warren
2013-02-12 16:57 ` Stephen Warren
2013-02-15 19:32 ` Linus Walleij
2013-02-15 19:32 ` Linus Walleij
-- strict thread matches above, loose matches on Subject: below --
2013-04-03 19:31 Linus Walleij
2013-04-03 19:31 ` Linus Walleij
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=51195A63.7080706@wwwdotorg.org \
--to=swarren@wwwdotorg.org \
--cc=linux-arm-kernel@lists.infradead.org \
/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.