diff options
Diffstat (limited to '')
| -rw-r--r-- | drivers/gpio/gpio-vf610.c | 31 | 
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c index 07e5e6323e86..27eff741fe9a 100644 --- a/drivers/gpio/gpio-vf610.c +++ b/drivers/gpio/gpio-vf610.c @@ -97,7 +97,7 @@ static inline u32 vf610_gpio_readl(void __iomem *reg)  static int vf610_gpio_get(struct gpio_chip *gc, unsigned int gpio)  {  	struct vf610_gpio_port *port = gpiochip_get_data(gc); -	unsigned long mask = BIT(gpio); +	u32 mask = BIT(gpio);  	unsigned long offset = GPIO_PDIR;  	if (port->sdata->have_paddr) { @@ -112,16 +112,16 @@ static int vf610_gpio_get(struct gpio_chip *gc, unsigned int gpio)  static void vf610_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)  {  	struct vf610_gpio_port *port = gpiochip_get_data(gc); -	unsigned long mask = BIT(gpio); +	u32 mask = BIT(gpio);  	unsigned long offset = val ? GPIO_PSOR : GPIO_PCOR;  	vf610_gpio_writel(mask, port->gpio_base + offset);  } -static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)  {  	struct vf610_gpio_port *port = gpiochip_get_data(chip); -	unsigned long mask = BIT(gpio); +	u32 mask = BIT(gpio);  	u32 val;  	if (port->sdata->have_paddr) { @@ -133,11 +133,11 @@ static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)  	return pinctrl_gpio_direction_input(chip, gpio);  } -static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, +static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,  				       int value)  {  	struct vf610_gpio_port *port = gpiochip_get_data(chip); -	unsigned long mask = BIT(gpio); +	u32 mask = BIT(gpio);  	u32 val;  	vf610_gpio_set(chip, gpio, value); @@ -151,6 +151,19 @@ static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,  	return pinctrl_gpio_direction_output(chip, gpio);  } +static int vf610_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio) +{ +	struct vf610_gpio_port *port = gpiochip_get_data(gc); +	u32 mask = BIT(gpio); + +	mask &= vf610_gpio_readl(port->gpio_base + GPIO_PDDR); + +	if (mask) +		return GPIO_LINE_DIRECTION_OUT; + +	return GPIO_LINE_DIRECTION_IN; +} +  static void vf610_gpio_irq_handler(struct irq_desc *desc)  {  	struct vf610_gpio_port *port = @@ -362,6 +375,12 @@ static int vf610_gpio_probe(struct platform_device *pdev)  	gc->get = vf610_gpio_get;  	gc->direction_output = vf610_gpio_direction_output;  	gc->set = vf610_gpio_set; +	/* +	 * only IP has Port Data Direction Register(PDDR) can +	 * support get direction +	 */ +	if (port->sdata->have_paddr) +		gc->get_direction = vf610_gpio_get_direction;  	/* Mask all GPIO interrupts */  	for (i = 0; i < gc->ngpio; i++)  | 
