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: sunxi: Implement gpiochip::get_direction()

After commit 471e998c0e31 ("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 e623c4303ed1 ("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 <wens@kernel.org>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>

authored by

Chen-Yu Tsai and committed by
Linus Walleij
01e10d02 45fe4592

+51
+51
drivers/pinctrl/sunxi/pinctrl-sunxi.c
··· 204 204 return NULL; 205 205 } 206 206 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 + 207 233 static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev) 208 234 { 209 235 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); ··· 956 930 .strict = true, 957 931 }; 958 932 933 + static int sunxi_pinctrl_gpio_get_direction(struct gpio_chip *chip, 934 + unsigned int offset) 935 + { 936 + struct sunxi_pinctrl *pctl = gpiochip_get_data(chip); 937 + const struct sunxi_desc_function *func; 938 + u32 pin = offset + chip->base; 939 + u32 reg, shift, mask; 940 + u8 muxval; 941 + 942 + sunxi_mux_reg(pctl, offset, &reg, &shift, &mask); 943 + 944 + muxval = (readl(pctl->membase + reg) & mask) >> shift; 945 + 946 + func = sunxi_pinctrl_desc_find_function_by_pin_and_mux(pctl, pin, muxval); 947 + if (!func) 948 + return -ENODEV; 949 + 950 + if (!strcmp(func->name, "gpio_out")) 951 + return GPIO_LINE_DIRECTION_OUT; 952 + if (!strcmp(func->name, "gpio_in") || !strcmp(func->name, "irq")) 953 + return GPIO_LINE_DIRECTION_IN; 954 + return -EINVAL; 955 + } 956 + 959 957 static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip, 960 958 unsigned offset) 961 959 { ··· 1649 1599 pctl->chip->request = gpiochip_generic_request; 1650 1600 pctl->chip->free = gpiochip_generic_free; 1651 1601 pctl->chip->set_config = gpiochip_generic_config; 1602 + pctl->chip->get_direction = sunxi_pinctrl_gpio_get_direction; 1652 1603 pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input; 1653 1604 pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output; 1654 1605 pctl->chip->get = sunxi_pinctrl_gpio_get;