Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: zynq: Report gpio direction at boot

The Zynq's gpios can be configured by the bootloader. But Linux will
erroneously report all gpios as inputs unless we implement
get_direction().

Signed-off-by: Brandon Maier <Brandon.Maier@collins.com>
Tested-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Brandon Maier and committed by
Linus Walleij
6169005c 9904f032

+23
+23
drivers/gpio/gpio-zynq.c
··· 358 358 } 359 359 360 360 /** 361 + * zynq_gpio_get_direction - Read the direction of the specified GPIO pin 362 + * @chip: gpio_chip instance to be worked on 363 + * @pin: gpio pin number within the device 364 + * 365 + * This function returns the direction of the specified GPIO. 366 + * 367 + * Return: 0 for output, 1 for input 368 + */ 369 + static int zynq_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) 370 + { 371 + u32 reg; 372 + unsigned int bank_num, bank_pin_num; 373 + struct zynq_gpio *gpio = gpiochip_get_data(chip); 374 + 375 + zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); 376 + 377 + reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); 378 + 379 + return !(reg & BIT(bank_pin_num)); 380 + } 381 + 382 + /** 361 383 * zynq_gpio_irq_mask - Disable the interrupts for a gpio pin 362 384 * @irq_data: per irq and chip data passed down to chip functions 363 385 * ··· 847 825 chip->free = zynq_gpio_free; 848 826 chip->direction_input = zynq_gpio_dir_in; 849 827 chip->direction_output = zynq_gpio_dir_out; 828 + chip->get_direction = zynq_gpio_get_direction; 850 829 chip->base = of_alias_get_id(pdev->dev.of_node, "gpio"); 851 830 chip->ngpio = gpio->p_data->ngpio; 852 831