Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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@microchip.com>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Signed-off-by: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>

authored by

Jens Emil Schulz Østergaard and committed by
Linus Walleij
96bfeba8 cb07e60b

+6 -1
+6 -1
drivers/pinctrl/pinctrl-ocelot.c
··· 358 358 const struct ocelot_pincfg_data *pincfg_data; 359 359 struct ocelot_pmx_func func[FUNC_MAX]; 360 360 u8 stride; 361 + u8 altm_stride; 361 362 struct workqueue_struct *wq; 362 363 }; 363 364 364 365 struct ocelot_match_data { 365 366 struct pinctrl_desc desc; 366 367 struct ocelot_pincfg_data pincfg_data; 368 + unsigned int n_alt_modes; 367 369 }; 368 370 369 371 struct ocelot_irq_work { ··· 1364 1362 return -1; 1365 1363 } 1366 1364 1367 - #define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->stride * ((p) / 32)))) 1365 + #define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->altm_stride * ((p) / 32)))) 1368 1366 1369 1367 static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, 1370 1368 unsigned int selector, unsigned int group) ··· 2296 2294 reset_control_reset(reset); 2297 2295 2298 2296 info->stride = 1 + (info->desc->npins - 1) / 32; 2297 + info->altm_stride = info->stride; 2298 + if (data->n_alt_modes) 2299 + info->altm_stride = fls(data->n_alt_modes); 2299 2300 2300 2301 regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4; 2301 2302