[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <2026011915101544cfdc14@mail.local>
Date: Mon, 19 Jan 2026 16:10:15 +0100
From: Alexandre Belloni <alexandre.belloni@...tlin.com>
To: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@...rochip.com>
Cc: Linus Walleij <linusw@...nel.org>, Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>,
Conor Dooley <conor+dt@...nel.org>,
Lars Povlsen <lars.povlsen@...rochip.com>,
Bartosz Golaszewski <brgl@...nel.org>,
Steen Hegelund <Steen.Hegelund@...rochip.com>,
Daniel Machon <daniel.machon@...rochip.com>,
linux-gpio@...r.kernel.org, devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2/3] pinctrl: ocelot: Update alt mode reg addr calculation
On 19/01/2026 16:06:10+0100, Jens Emil Schulz Østergaard wrote:
> Lan9645x is the first chip supported by this driver where the pin stride
> is different from the alt mode stride. With 51 pins and up to 7 alt
> modes, we have stride = 2 and alt_mode_stride = 3.
>
> The current REG_ALT macro has the implicit assumption that these numbers
> are equal, so it does not work for lan9645x.
>
> The pin stride is the 'stride' variable in the driver. It is the size
> of certain register groups which depends on the number of pins supported
> by the device. Generally we have stride = DIV_ROUND_UP(npins, 32). E.g:
>
> GPIO_OUT_SET0
> GPIO_OUT_SET1
> ...
> GPIO_OUT_SETn
>
> The alt mode registers are further replicated by the number of bits
> necessary to represent the alt mode. For instance if we need 3 bits to
> represent the alt mode:
>
> GPIO_ALT0[0-2]
> GPIO_ALT1[0-2]
>
> To set alt mode 3 on pin 12, it is necessary to perform writes
>
> GPIO_ALT0[0] |= BIT(12)
> GPIO_ALT0[1] |= BIT(12)
> GPIO_ALT0[2] &= ~BIT(12)
>
> The stride and alt mode stride are used by the REG_ALT macro to
> calculate the alt mode register address for a given pin.
>
> This adds the option to specify n_alt_modes, which is used to set
> info->altm_stride. The default value is info->stride, to make sure
> existing devices are unaffected by this change.
>
> Reviewed-by: Steen Hegelund <Steen.Hegelund@...rochip.com>
> Reviewed-by: Daniel Machon <daniel.machon@...rochip.com>
> Signed-off-by: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@...rochip.com>
Reviewed-by: Alexandre Belloni <alexandre.belloni@...tlin.com>
> ---
> drivers/pinctrl/pinctrl-ocelot.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
> index 70da3f37567a..4db0439ca8c4 100644
> --- a/drivers/pinctrl/pinctrl-ocelot.c
> +++ b/drivers/pinctrl/pinctrl-ocelot.c
> @@ -358,12 +358,14 @@ struct ocelot_pinctrl {
> const struct ocelot_pincfg_data *pincfg_data;
> struct ocelot_pmx_func func[FUNC_MAX];
> u8 stride;
> + u8 altm_stride;
> struct workqueue_struct *wq;
> };
>
> struct ocelot_match_data {
> struct pinctrl_desc desc;
> struct ocelot_pincfg_data pincfg_data;
> + unsigned int n_alt_modes;
> };
>
> struct ocelot_irq_work {
> @@ -1362,7 +1364,7 @@ static int ocelot_pin_function_idx(struct ocelot_pinctrl *info,
> return -1;
> }
>
> -#define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->stride * ((p) / 32))))
> +#define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->altm_stride * ((p) / 32))))
>
> static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev,
> unsigned int selector, unsigned int group)
> @@ -2294,6 +2296,9 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
> reset_control_reset(reset);
>
> info->stride = 1 + (info->desc->npins - 1) / 32;
> + info->altm_stride = info->stride;
> + if (data->n_alt_modes)
> + info->altm_stride = fls(data->n_alt_modes);
>
> regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4;
>
>
> --
> 2.34.1
>
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Powered by blists - more mailing lists