Commit 8e9734fd authored by Alexandre Belloni's avatar Alexandre Belloni Committed by Greg Kroah-Hartman

pinctrl: ocelot: fix pinmuxing for pins after 31

[ Upstream commit 4b36082e ]

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: da801ab5 pinctrl: ocelot: add MSCC Jaguar2 support
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent fc8f20ce
...@@ -396,7 +396,7 @@ static int ocelot_pin_function_idx(struct ocelot_pinctrl *info, ...@@ -396,7 +396,7 @@ static int ocelot_pin_function_idx(struct ocelot_pinctrl *info,
return -1; return -1;
} }
#define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32))) #define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->stride * ((p) / 32))))
static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int selector, unsigned int group) unsigned int selector, unsigned int group)
...@@ -412,19 +412,21 @@ static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, ...@@ -412,19 +412,21 @@ static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev,
/* /*
* f is encoded on two bits. * f is encoded on two bits.
* bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of * bit 0 of f goes in BIT(pin) of ALT[0], bit 1 of f goes in BIT(pin) of
* ALT1 * ALT[1]
* This is racy because both registers can't be updated at the same time * This is racy because both registers can't be updated at the same time
* but it doesn't matter much for now. * but it doesn't matter much for now.
*/ */
regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT0, info, pin->pin), regmap_update_bits(info->map, REG_ALT(0, info, pin->pin),
BIT(p), f << p); BIT(p), f << p);
regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT1, info, pin->pin), regmap_update_bits(info->map, REG_ALT(1, info, pin->pin),
BIT(p), f << (p - 1)); BIT(p), f << (p - 1));
return 0; return 0;
} }
#define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32)))
static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned int pin, bool input) unsigned int pin, bool input)
...@@ -445,9 +447,9 @@ static int ocelot_gpio_request_enable(struct pinctrl_dev *pctldev, ...@@ -445,9 +447,9 @@ static int ocelot_gpio_request_enable(struct pinctrl_dev *pctldev,
struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
unsigned int p = offset % 32; unsigned int p = offset % 32;
regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT0, info, offset), regmap_update_bits(info->map, REG_ALT(0, info, offset),
BIT(p), 0); BIT(p), 0);
regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT1, info, offset), regmap_update_bits(info->map, REG_ALT(1, info, offset),
BIT(p), 0); BIT(p), 0);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment