mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 23:58:05 +00:00
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: da801ab56a
pinctrl: ocelot: add MSCC Jaguar2 support
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
f2818ba3a0
commit
4b36082e2e
1 changed files with 9 additions and 7 deletions
|
@ -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,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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,
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue