diff options
author | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2019-06-20 14:30:37 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2019-06-25 09:42:31 -0400 |
commit | 4b36082e2e09c2769710756390d54cfca563ed96 (patch) | |
tree | 22bdf79cd7ffdbc51ad283e704929c4dab384265 | |
parent | f2818ba3a0125670cb9999bb5a65ebb631a8da2f (diff) |
pinctrl: ocelot: fix pinmuxing for pins after 31
The actual layout for OCELOT_GPIO_ALT[01] when there are more than 32 pins
is interleaved, i.e. OCELOT_GPIO_ALT0[0], OCELOT_GPIO_ALT1[0],
OCELOT_GPIO_ALT0[1], OCELOT_GPIO_ALT1[1]. Introduce a new REG_ALT macro to
facilitate the register offset calculation and use it where necessary.
Fixes: da801ab56ad8 pinctrl: ocelot: add MSCC Jaguar2 support
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/pinctrl/pinctrl-ocelot.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c index d2478db975bd..fb76fb2e9ea5 100644 --- a/drivers/pinctrl/pinctrl-ocelot.c +++ b/drivers/pinctrl/pinctrl-ocelot.c | |||
@@ -396,7 +396,7 @@ static int ocelot_pin_function_idx(struct ocelot_pinctrl *info, | |||
396 | return -1; | 396 | return -1; |
397 | } | 397 | } |
398 | 398 | ||
399 | #define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32))) | 399 | #define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->stride * ((p) / 32)))) |
400 | 400 | ||
401 | static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, | 401 | static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, |
402 | unsigned int selector, unsigned int group) | 402 | unsigned int selector, unsigned int group) |
@@ -412,19 +412,21 @@ static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, | |||
412 | 412 | ||
413 | /* | 413 | /* |
414 | * f is encoded on two bits. | 414 | * f is encoded on two bits. |
415 | * bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of | 415 | * bit 0 of f goes in BIT(pin) of ALT[0], bit 1 of f goes in BIT(pin) of |
416 | * ALT1 | 416 | * ALT[1] |
417 | * This is racy because both registers can't be updated at the same time | 417 | * This is racy because both registers can't be updated at the same time |
418 | * but it doesn't matter much for now. | 418 | * but it doesn't matter much for now. |
419 | */ | 419 | */ |
420 | regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT0, info, pin->pin), | 420 | regmap_update_bits(info->map, REG_ALT(0, info, pin->pin), |
421 | BIT(p), f << p); | 421 | BIT(p), f << p); |
422 | regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT1, info, pin->pin), | 422 | regmap_update_bits(info->map, REG_ALT(1, info, pin->pin), |
423 | BIT(p), f << (p - 1)); | 423 | BIT(p), f << (p - 1)); |
424 | 424 | ||
425 | return 0; | 425 | return 0; |
426 | } | 426 | } |
427 | 427 | ||
428 | #define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32))) | ||
429 | |||
428 | static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, | 430 | static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, |
429 | struct pinctrl_gpio_range *range, | 431 | struct pinctrl_gpio_range *range, |
430 | unsigned int pin, bool input) | 432 | unsigned int pin, bool input) |
@@ -445,9 +447,9 @@ static int ocelot_gpio_request_enable(struct pinctrl_dev *pctldev, | |||
445 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | 447 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); |
446 | unsigned int p = offset % 32; | 448 | unsigned int p = offset % 32; |
447 | 449 | ||
448 | regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT0, info, offset), | 450 | regmap_update_bits(info->map, REG_ALT(0, info, offset), |
449 | BIT(p), 0); | 451 | BIT(p), 0); |
450 | regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT1, info, offset), | 452 | regmap_update_bits(info->map, REG_ALT(1, info, offset), |
451 | BIT(p), 0); | 453 | BIT(p), 0); |
452 | 454 | ||
453 | return 0; | 455 | return 0; |