Merge tag 'regmap-v3.15-nodev' of git://git.kernel.org/pub/scm/linux/kernel/git/broon...
[cascardo/linux.git] / drivers / pinctrl / pinctrl-at91.c
index d990e33..5d24aae 100644 (file)
@@ -1137,6 +1137,17 @@ static void at91_gpio_free(struct gpio_chip *chip, unsigned offset)
        pinctrl_free_gpio(gpio);
 }
 
+static int at91_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+       struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+       void __iomem *pio = at91_gpio->regbase;
+       unsigned mask = 1 << offset;
+       u32 osr;
+
+       osr = readl_relaxed(pio + PIO_OSR);
+       return !(osr & mask);
+}
+
 static int at91_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 {
        struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
@@ -1325,6 +1336,31 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type)
        return 0;
 }
 
+static unsigned int gpio_irq_startup(struct irq_data *d)
+{
+       struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
+       unsigned        pin = d->hwirq;
+       int ret;
+
+       ret = gpio_lock_as_irq(&at91_gpio->chip, pin);
+       if (ret) {
+               dev_err(at91_gpio->chip.dev, "unable to lock pind %lu IRQ\n",
+                       d->hwirq);
+               return ret;
+       }
+       gpio_irq_unmask(d);
+       return 0;
+}
+
+static void gpio_irq_shutdown(struct irq_data *d)
+{
+       struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
+       unsigned        pin = d->hwirq;
+
+       gpio_irq_mask(d);
+       gpio_unlock_as_irq(&at91_gpio->chip, pin);
+}
+
 #ifdef CONFIG_PM
 
 static u32 wakeups[MAX_GPIO_BANKS];
@@ -1399,6 +1435,8 @@ void at91_pinctrl_gpio_resume(void)
 
 static struct irq_chip gpio_irqchip = {
        .name           = "GPIO",
+       .irq_startup    = gpio_irq_startup,
+       .irq_shutdown   = gpio_irq_shutdown,
        .irq_disable    = gpio_irq_mask,
        .irq_mask       = gpio_irq_mask,
        .irq_unmask     = gpio_irq_unmask,
@@ -1543,6 +1581,7 @@ static int at91_gpio_of_irq_setup(struct device_node *node,
 static struct gpio_chip at91_gpio_template = {
        .request                = at91_gpio_request,
        .free                   = at91_gpio_free,
+       .get_direction          = at91_gpio_get_direction,
        .direction_input        = at91_gpio_direction_input,
        .get                    = at91_gpio_get,
        .direction_output       = at91_gpio_direction_output,