From: lee.jones@linaro.org (Lee Jones)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 2/5] pinctrl: st: Enhance the controller to manage unavailable registers
Date: Mon, 10 Mar 2014 09:17:07 +0000 [thread overview]
Message-ID: <20140310091707.GD14976@lee--X1> (raw)
In-Reply-To: <1394203251-25361-3-git-send-email-maxime.coquelin@st.com>
> From: Giuseppe Cavallaro <peppe.cavallaro@st.com>
>
> This patch adds a new logic inside the st pinctrl to manage
> an unsupported scenario: some sysconfig are not available!
>
> This is the case of STiH407 where, although documented, the
> following registers from SYSCFG_FLASH have been removed from the SoC.
>
> SYSTEM_CONFIG3040
> Output Enable pad control for all PIO Alternate Functions
> and
> SYSTEM_ CONFIG3050
> Pull Up pad control for all PIO Alternate Functions
>
> Without managing this condition an imprecise external abort
> will be detect.
>
> To do this the patch also reviews the st_parse_syscfgs
> and other routines to manipulate the registers only if
> actually available.
> In any case, for example the st_parse_syscfgs detected
> an error condition but no action was made in the
> st_pctl_probe_dt.
>
> Signed-off-by: Maxime Coquelin <maxime.coquelin@st.com>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
These two SOBs need reordering.
> ---
> drivers/pinctrl/pinctrl-st.c | 106 +++++++++++++++++++++++++------------------
> 1 file changed, 61 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c
> index 9fb66aa..1721611 100644
> --- a/drivers/pinctrl/pinctrl-st.c
> +++ b/drivers/pinctrl/pinctrl-st.c
> @@ -410,25 +410,27 @@ static void st_pinconf_set_config(struct st_pio_control *pc,
> unsigned int oe_value, pu_value, od_value;
> unsigned long mask = BIT(pin);
>
> - regmap_field_read(output_enable, &oe_value);
> - regmap_field_read(pull_up, &pu_value);
> - regmap_field_read(open_drain, &od_value);
> -
> - /* Clear old values */
> - oe_value &= ~mask;
> - pu_value &= ~mask;
> - od_value &= ~mask;
> -
> - if (config & ST_PINCONF_OE)
> - oe_value |= mask;
> - if (config & ST_PINCONF_PU)
> - pu_value |= mask;
> - if (config & ST_PINCONF_OD)
> - od_value |= mask;
> -
> - regmap_field_write(output_enable, oe_value);
> - regmap_field_write(pull_up, pu_value);
> - regmap_field_write(open_drain, od_value);
> + if (output_enable) {
> + regmap_field_read(output_enable, &oe_value);
> + oe_value &= ~mask;
> + if (config & ST_PINCONF_OE)
> + oe_value |= mask;
> + regmap_field_write(output_enable, oe_value);
> + }
> + if (pull_up) {
> + regmap_field_read(pull_up, &pu_value);
> + pu_value &= ~mask;
> + if (config & ST_PINCONF_PU)
> + pu_value |= mask;
> + regmap_field_write(pull_up, pu_value);
> + }
> + if (open_drain) {
> + regmap_field_read(open_drain, &od_value);
> + od_value &= ~mask;
> + if (config & ST_PINCONF_OD)
> + od_value |= mask;
> + regmap_field_write(open_drain, od_value);
> + }
Nice change.
Nit: For consistency with the changes below, please consider placing
new lines between the 3 outer checks.
> }
>
<snip>
> -static void st_pinconf_get_direction(struct st_pio_control *pc,
> - int pin, unsigned long *config)
> +static void st_pinconf_get_direction(struct st_pio_control *pc, int pin,
> + unsigned long *config)
Unrelated change?
> {
> unsigned int oe_value, pu_value, od_value;
Is it worth checking for (!config) here?
> - regmap_field_read(pc->oe, &oe_value);
> - regmap_field_read(pc->pu, &pu_value);
> - regmap_field_read(pc->od, &od_value);
> + if (pc->oe) {
> + regmap_field_read(pc->oe, &oe_value);
> + if (oe_value & BIT(pin))
> + ST_PINCONF_PACK_OE(*config);
> + }
>
> - if (oe_value & BIT(pin))
> - ST_PINCONF_PACK_OE(*config);
> - if (pu_value & BIT(pin))
> - ST_PINCONF_PACK_PU(*config);
> - if (od_value & BIT(pin))
> - ST_PINCONF_PACK_OD(*config);
> + if (pc->pu) {
> + regmap_field_read(pc->pu, &pu_value);
> + if (pu_value & BIT(pin))
> + ST_PINCONF_PACK_PU(*config);
> + }
>
> + if (pc->od) {
> + regmap_field_read(pc->od, &od_value);
> + if (od_value & BIT(pin))
> + ST_PINCONF_PACK_OD(*config);
> + }
> }
Nice.
> static int st_pinconf_get_retime_packed(struct st_pinctrl *info,
> @@ -1105,8 +1116,21 @@ static int st_pctl_dt_setup_retime(struct st_pinctrl *info,
> return -EINVAL;
> }
>
> -static int st_parse_syscfgs(struct st_pinctrl *info,
> - int bank, struct device_node *np)
> +
> +static struct regmap_field *st_pc_get_value(struct device *dev,
> + struct regmap *regmap, int bank,
> + int data, int lsb, int msb)
> +{
> + struct reg_field reg = REG_FIELD((data + bank) * 4, lsb, msb);
> +
> + if (data < 0)
> + return NULL;
What happens is data < 0 and it's used in REG_FIELD?
Would it make more sense to make this check before calling REG_FIELD?
> + return devm_regmap_field_alloc(dev, regmap, reg);
> +}
> +
> +static void st_parse_syscfgs(struct st_pinctrl *info, int bank,
> + struct device_node *np)
> {
> const struct st_pctl_data *data = info->data;
> /**
> @@ -1116,29 +1140,21 @@ static int st_parse_syscfgs(struct st_pinctrl *info,
> */
> int lsb = (bank%4) * ST_GPIO_PINS_PER_BANK;
> int msb = lsb + ST_GPIO_PINS_PER_BANK - 1;
> - struct reg_field alt_reg = REG_FIELD((data->alt + bank) * 4, 0, 31);
> - struct reg_field oe_reg = REG_FIELD((data->oe + bank/4) * 4, lsb, msb);
> - struct reg_field pu_reg = REG_FIELD((data->pu + bank/4) * 4, lsb, msb);
> - struct reg_field od_reg = REG_FIELD((data->od + bank/4) * 4, lsb, msb);
> struct st_pio_control *pc = &info->banks[bank].pc;
> struct device *dev = info->dev;
> struct regmap *regmap = info->regmap;
>
> - pc->alt = devm_regmap_field_alloc(dev, regmap, alt_reg);
> - pc->oe = devm_regmap_field_alloc(dev, regmap, oe_reg);
> - pc->pu = devm_regmap_field_alloc(dev, regmap, pu_reg);
> - pc->od = devm_regmap_field_alloc(dev, regmap, od_reg);
> -
> - if (IS_ERR(pc->alt) || IS_ERR(pc->oe) ||
> - IS_ERR(pc->pu) || IS_ERR(pc->od))
> - return -EINVAL;
> + pc->alt = st_pc_get_value(dev, regmap, bank, data->alt, 0, 31);
> + pc->oe = st_pc_get_value(dev, regmap, bank/4, data->oe, lsb, msb);
> + pc->pu = st_pc_get_value(dev, regmap, bank/4, data->pu, lsb, msb);
> + pc->od = st_pc_get_value(dev, regmap, bank/4, data->od, lsb, msb);
>
> /* retime avaiable for all pins by default */
> pc->rt_pin_mask = 0xff;
> of_property_read_u32(np, "st,retime-pin-mask", &pc->rt_pin_mask);
> st_pctl_dt_setup_retime(info, bank, pc);
>
> - return 0;
> + return;
> }
>
> /*
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
WARNING: multiple messages have this Message-ID (diff)
From: Lee Jones <lee.jones@linaro.org>
To: Maxime COQUELIN <maxime.coquelin@st.com>
Cc: Rob Landley <rob@landley.net>, Rob Herring <robh+dt@kernel.org>,
Pawel Moll <pawel.moll@arm.com>,
Mark Rutland <mark.rutland@arm.com>,
Ian Campbell <ijc+devicetree@hellion.org.uk>,
Kumar Gala <galak@codeaurora.org>,
Russell King <linux@arm.linux.org.uk>,
Srinivas Kandagatla <srinivas.kandagatla@st.com>,
Stuart Menefy <stuart.menefy@st.com>,
Linus Walleij <linus.walleij@linaro.org>,
Giuseppe Cavallaro <peppe.cavallaro@st.com>,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
kernel@stlinux.com
Subject: Re: [PATCH v3 2/5] pinctrl: st: Enhance the controller to manage unavailable registers
Date: Mon, 10 Mar 2014 09:17:07 +0000 [thread overview]
Message-ID: <20140310091707.GD14976@lee--X1> (raw)
In-Reply-To: <1394203251-25361-3-git-send-email-maxime.coquelin@st.com>
> From: Giuseppe Cavallaro <peppe.cavallaro@st.com>
>
> This patch adds a new logic inside the st pinctrl to manage
> an unsupported scenario: some sysconfig are not available!
>
> This is the case of STiH407 where, although documented, the
> following registers from SYSCFG_FLASH have been removed from the SoC.
>
> SYSTEM_CONFIG3040
> Output Enable pad control for all PIO Alternate Functions
> and
> SYSTEM_ CONFIG3050
> Pull Up pad control for all PIO Alternate Functions
>
> Without managing this condition an imprecise external abort
> will be detect.
>
> To do this the patch also reviews the st_parse_syscfgs
> and other routines to manipulate the registers only if
> actually available.
> In any case, for example the st_parse_syscfgs detected
> an error condition but no action was made in the
> st_pctl_probe_dt.
>
> Signed-off-by: Maxime Coquelin <maxime.coquelin@st.com>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
These two SOBs need reordering.
> ---
> drivers/pinctrl/pinctrl-st.c | 106 +++++++++++++++++++++++++------------------
> 1 file changed, 61 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c
> index 9fb66aa..1721611 100644
> --- a/drivers/pinctrl/pinctrl-st.c
> +++ b/drivers/pinctrl/pinctrl-st.c
> @@ -410,25 +410,27 @@ static void st_pinconf_set_config(struct st_pio_control *pc,
> unsigned int oe_value, pu_value, od_value;
> unsigned long mask = BIT(pin);
>
> - regmap_field_read(output_enable, &oe_value);
> - regmap_field_read(pull_up, &pu_value);
> - regmap_field_read(open_drain, &od_value);
> -
> - /* Clear old values */
> - oe_value &= ~mask;
> - pu_value &= ~mask;
> - od_value &= ~mask;
> -
> - if (config & ST_PINCONF_OE)
> - oe_value |= mask;
> - if (config & ST_PINCONF_PU)
> - pu_value |= mask;
> - if (config & ST_PINCONF_OD)
> - od_value |= mask;
> -
> - regmap_field_write(output_enable, oe_value);
> - regmap_field_write(pull_up, pu_value);
> - regmap_field_write(open_drain, od_value);
> + if (output_enable) {
> + regmap_field_read(output_enable, &oe_value);
> + oe_value &= ~mask;
> + if (config & ST_PINCONF_OE)
> + oe_value |= mask;
> + regmap_field_write(output_enable, oe_value);
> + }
> + if (pull_up) {
> + regmap_field_read(pull_up, &pu_value);
> + pu_value &= ~mask;
> + if (config & ST_PINCONF_PU)
> + pu_value |= mask;
> + regmap_field_write(pull_up, pu_value);
> + }
> + if (open_drain) {
> + regmap_field_read(open_drain, &od_value);
> + od_value &= ~mask;
> + if (config & ST_PINCONF_OD)
> + od_value |= mask;
> + regmap_field_write(open_drain, od_value);
> + }
Nice change.
Nit: For consistency with the changes below, please consider placing
new lines between the 3 outer checks.
> }
>
<snip>
> -static void st_pinconf_get_direction(struct st_pio_control *pc,
> - int pin, unsigned long *config)
> +static void st_pinconf_get_direction(struct st_pio_control *pc, int pin,
> + unsigned long *config)
Unrelated change?
> {
> unsigned int oe_value, pu_value, od_value;
Is it worth checking for (!config) here?
> - regmap_field_read(pc->oe, &oe_value);
> - regmap_field_read(pc->pu, &pu_value);
> - regmap_field_read(pc->od, &od_value);
> + if (pc->oe) {
> + regmap_field_read(pc->oe, &oe_value);
> + if (oe_value & BIT(pin))
> + ST_PINCONF_PACK_OE(*config);
> + }
>
> - if (oe_value & BIT(pin))
> - ST_PINCONF_PACK_OE(*config);
> - if (pu_value & BIT(pin))
> - ST_PINCONF_PACK_PU(*config);
> - if (od_value & BIT(pin))
> - ST_PINCONF_PACK_OD(*config);
> + if (pc->pu) {
> + regmap_field_read(pc->pu, &pu_value);
> + if (pu_value & BIT(pin))
> + ST_PINCONF_PACK_PU(*config);
> + }
>
> + if (pc->od) {
> + regmap_field_read(pc->od, &od_value);
> + if (od_value & BIT(pin))
> + ST_PINCONF_PACK_OD(*config);
> + }
> }
Nice.
> static int st_pinconf_get_retime_packed(struct st_pinctrl *info,
> @@ -1105,8 +1116,21 @@ static int st_pctl_dt_setup_retime(struct st_pinctrl *info,
> return -EINVAL;
> }
>
> -static int st_parse_syscfgs(struct st_pinctrl *info,
> - int bank, struct device_node *np)
> +
> +static struct regmap_field *st_pc_get_value(struct device *dev,
> + struct regmap *regmap, int bank,
> + int data, int lsb, int msb)
> +{
> + struct reg_field reg = REG_FIELD((data + bank) * 4, lsb, msb);
> +
> + if (data < 0)
> + return NULL;
What happens is data < 0 and it's used in REG_FIELD?
Would it make more sense to make this check before calling REG_FIELD?
> + return devm_regmap_field_alloc(dev, regmap, reg);
> +}
> +
> +static void st_parse_syscfgs(struct st_pinctrl *info, int bank,
> + struct device_node *np)
> {
> const struct st_pctl_data *data = info->data;
> /**
> @@ -1116,29 +1140,21 @@ static int st_parse_syscfgs(struct st_pinctrl *info,
> */
> int lsb = (bank%4) * ST_GPIO_PINS_PER_BANK;
> int msb = lsb + ST_GPIO_PINS_PER_BANK - 1;
> - struct reg_field alt_reg = REG_FIELD((data->alt + bank) * 4, 0, 31);
> - struct reg_field oe_reg = REG_FIELD((data->oe + bank/4) * 4, lsb, msb);
> - struct reg_field pu_reg = REG_FIELD((data->pu + bank/4) * 4, lsb, msb);
> - struct reg_field od_reg = REG_FIELD((data->od + bank/4) * 4, lsb, msb);
> struct st_pio_control *pc = &info->banks[bank].pc;
> struct device *dev = info->dev;
> struct regmap *regmap = info->regmap;
>
> - pc->alt = devm_regmap_field_alloc(dev, regmap, alt_reg);
> - pc->oe = devm_regmap_field_alloc(dev, regmap, oe_reg);
> - pc->pu = devm_regmap_field_alloc(dev, regmap, pu_reg);
> - pc->od = devm_regmap_field_alloc(dev, regmap, od_reg);
> -
> - if (IS_ERR(pc->alt) || IS_ERR(pc->oe) ||
> - IS_ERR(pc->pu) || IS_ERR(pc->od))
> - return -EINVAL;
> + pc->alt = st_pc_get_value(dev, regmap, bank, data->alt, 0, 31);
> + pc->oe = st_pc_get_value(dev, regmap, bank/4, data->oe, lsb, msb);
> + pc->pu = st_pc_get_value(dev, regmap, bank/4, data->pu, lsb, msb);
> + pc->od = st_pc_get_value(dev, regmap, bank/4, data->od, lsb, msb);
>
> /* retime avaiable for all pins by default */
> pc->rt_pin_mask = 0xff;
> of_property_read_u32(np, "st,retime-pin-mask", &pc->rt_pin_mask);
> st_pctl_dt_setup_retime(info, bank, pc);
>
> - return 0;
> + return;
> }
>
> /*
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
next prev parent reply other threads:[~2014-03-10 9:17 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-07 14:40 [PATCH v3 0/5] Add STiH407 SoC and reference board support Maxime COQUELIN
2014-03-07 14:40 ` Maxime COQUELIN
2014-03-07 14:40 ` Maxime COQUELIN
2014-03-07 14:40 ` [PATCH v3 1/5] ARM: STi: Add STiH407 SoC support Maxime COQUELIN
2014-03-07 14:40 ` Maxime COQUELIN
2014-03-10 12:34 ` Lee Jones
2014-03-10 12:34 ` Lee Jones
2014-03-10 12:34 ` Lee Jones
2014-03-11 13:56 ` Maxime Coquelin
2014-03-11 13:56 ` Maxime Coquelin
2014-03-11 13:56 ` Maxime Coquelin
2014-03-07 14:40 ` [PATCH v3 2/5] pinctrl: st: Enhance the controller to manage unavailable registers Maxime COQUELIN
2014-03-07 14:40 ` Maxime COQUELIN
2014-03-07 15:37 ` srinivas kandagatla
2014-03-07 15:37 ` srinivas kandagatla
2014-03-07 15:37 ` srinivas kandagatla
2014-03-10 9:17 ` Lee Jones [this message]
2014-03-10 9:17 ` Lee Jones
2014-03-11 8:18 ` Maxime Coquelin
2014-03-11 8:18 ` Maxime Coquelin
2014-03-11 8:18 ` Maxime Coquelin
2014-03-11 10:55 ` Maxime Coquelin
2014-03-11 10:55 ` Maxime Coquelin
2014-03-11 10:55 ` Maxime Coquelin
2014-03-11 11:13 ` Lee Jones
2014-03-11 11:13 ` Lee Jones
2014-03-11 11:12 ` Lee Jones
2014-03-11 11:12 ` Lee Jones
2014-03-07 14:40 ` [PATCH v3 3/5] pinctrl: st: add pinctrl support for the STiH407 SoC Maxime COQUELIN
2014-03-07 14:40 ` Maxime COQUELIN
2014-03-07 15:36 ` srinivas kandagatla
2014-03-07 15:36 ` srinivas kandagatla
2014-03-07 15:36 ` srinivas kandagatla
2014-03-10 14:44 ` Lee Jones
2014-03-10 14:44 ` Lee Jones
2014-03-11 8:52 ` Maxime Coquelin
2014-03-11 8:52 ` Maxime Coquelin
2014-03-11 8:52 ` Maxime Coquelin
2014-03-07 14:40 ` [PATCH v3 4/5] ARM: dts: Add STiH407 SoC support Maxime COQUELIN
2014-03-07 14:40 ` Maxime COQUELIN
2014-03-07 14:40 ` Maxime COQUELIN
2014-03-10 12:28 ` Lee Jones
2014-03-10 12:28 ` Lee Jones
2014-03-10 12:28 ` Lee Jones
2014-03-10 16:16 ` Lee Jones
2014-03-10 16:16 ` Lee Jones
2014-03-11 10:09 ` Maxime Coquelin
2014-03-11 10:09 ` Maxime Coquelin
2014-03-11 10:09 ` Maxime Coquelin
2014-03-07 14:40 ` [PATCH v3 5/5] ARM: dts: STiH407: Add B2120 board support Maxime COQUELIN
2014-03-07 14:40 ` Maxime COQUELIN
2014-03-10 12:37 ` Lee Jones
2014-03-10 12:37 ` Lee Jones
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=20140310091707.GD14976@lee--X1 \
--to=lee.jones@linaro.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.