lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260119-pinctrl_ocelot_extend_support_for_lan9645x-v1-2-1228155ed0ee@microchip.com>
Date: Mon, 19 Jan 2026 16:06:10 +0100
From: Jens Emil Schulz Østergaard
	<jensemil.schulzostergaard@...rochip.com>
To: Linus Walleij <linusw@...nel.org>, Rob Herring <robh@...nel.org>,
	Krzysztof Kozlowski <krzk+dt@...nel.org>, Conor Dooley <conor+dt@...nel.org>,
	Alexandre Belloni <alexandre.belloni@...tlin.com>, Lars Povlsen
	<lars.povlsen@...rochip.com>, Bartosz Golaszewski <brgl@...nel.org>, "Steen
 Hegelund" <Steen.Hegelund@...rochip.com>, Daniel Machon
	<daniel.machon@...rochip.com>
CC: <linux-gpio@...r.kernel.org>, <devicetree@...r.kernel.org>,
	<linux-kernel@...r.kernel.org>, Jens Emil Schulz Østergaard
	<jensemil.schulzostergaard@...rochip.com>
Subject: [PATCH 2/3] pinctrl: ocelot: Update alt mode reg addr calculation

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>
---
 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


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ