Skip to content

Commit 01e10d0

Browse files
wenslinusw
authored andcommitted
pinctrl: sunxi: Implement gpiochip::get_direction()
After commit 471e998 ("gpiolib: remove redundant callback check"), a warning will be printed if the gpio driver does not implement this callback. The warning was added in commit e623c43 ("gpiolib: sanitize the return value of gpio_chip::get_direction()"), but was masked by the "redundant" check. The warning can be triggered by any action that calls the callback, such as dumping the GPIO state from /sys/kernel/debug/gpio. Implement it for the sunxi driver. This is simply a matter of reading out the mux value from the registers, then checking if it is one of the GPIO functions and which direction it is. Signed-off-by: Chen-Yu Tsai <[email protected]> Reviewed-by: Jernej Skrabec <[email protected]> Reviewed-by: Bartosz Golaszewski <[email protected]> Reviewed-by: Andre Przywara <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent 45fe459 commit 01e10d0

1 file changed

Lines changed: 51 additions & 0 deletions

File tree

drivers/pinctrl/sunxi/pinctrl-sunxi.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,32 @@ sunxi_pinctrl_desc_find_function_by_pin(struct sunxi_pinctrl *pctl,
204204
return NULL;
205205
}
206206

207+
static struct sunxi_desc_function *
208+
sunxi_pinctrl_desc_find_function_by_pin_and_mux(struct sunxi_pinctrl *pctl,
209+
const u16 pin_num,
210+
const u8 muxval)
211+
{
212+
for (unsigned int i = 0; i < pctl->desc->npins; i++) {
213+
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
214+
struct sunxi_desc_function *func = pin->functions;
215+
216+
if (pin->pin.number != pin_num)
217+
continue;
218+
219+
if (pin->variant && !(pctl->variant & pin->variant))
220+
continue;
221+
222+
while (func->name) {
223+
if (func->muxval == muxval)
224+
return func;
225+
226+
func++;
227+
}
228+
}
229+
230+
return NULL;
231+
}
232+
207233
static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
208234
{
209235
struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
@@ -930,6 +956,30 @@ static const struct pinmux_ops sunxi_pmx_ops = {
930956
.strict = true,
931957
};
932958

959+
static int sunxi_pinctrl_gpio_get_direction(struct gpio_chip *chip,
960+
unsigned int offset)
961+
{
962+
struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
963+
const struct sunxi_desc_function *func;
964+
u32 pin = offset + chip->base;
965+
u32 reg, shift, mask;
966+
u8 muxval;
967+
968+
sunxi_mux_reg(pctl, offset, &reg, &shift, &mask);
969+
970+
muxval = (readl(pctl->membase + reg) & mask) >> shift;
971+
972+
func = sunxi_pinctrl_desc_find_function_by_pin_and_mux(pctl, pin, muxval);
973+
if (!func)
974+
return -ENODEV;
975+
976+
if (!strcmp(func->name, "gpio_out"))
977+
return GPIO_LINE_DIRECTION_OUT;
978+
if (!strcmp(func->name, "gpio_in") || !strcmp(func->name, "irq"))
979+
return GPIO_LINE_DIRECTION_IN;
980+
return -EINVAL;
981+
}
982+
933983
static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
934984
unsigned offset)
935985
{
@@ -1599,6 +1649,7 @@ int sunxi_pinctrl_init_with_flags(struct platform_device *pdev,
15991649
pctl->chip->request = gpiochip_generic_request;
16001650
pctl->chip->free = gpiochip_generic_free;
16011651
pctl->chip->set_config = gpiochip_generic_config;
1652+
pctl->chip->get_direction = sunxi_pinctrl_gpio_get_direction;
16021653
pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input;
16031654
pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output;
16041655
pctl->chip->get = sunxi_pinctrl_gpio_get;

0 commit comments

Comments
 (0)