This chip support high level and low level interrupts. Those
have to be implemented also to get a complete and clean driver.

Signed-off-by: Sergio Paracuellos <sergio.paracuel...@gmail.com>
---
 drivers/staging/mt7621-gpio/gpio-mt7621.c | 57 +++++++++++++++++++++++++------
 1 file changed, 46 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/mt7621-gpio/gpio-mt7621.c 
b/drivers/staging/mt7621-gpio/gpio-mt7621.c
index 5d082c8..b0cbb30 100644
--- a/drivers/staging/mt7621-gpio/gpio-mt7621.c
+++ b/drivers/staging/mt7621-gpio/gpio-mt7621.c
@@ -37,6 +37,8 @@
  * @bank: gpio bank number for the chip
  * @rising: mask for rising irqs
  * @falling: mask for falling irqs
+ * @hlevel: mask for high level irqs
+ * @llevel: mask for low level irqs
  */
 struct mtk_gc {
        struct gpio_chip chip;
@@ -44,6 +46,8 @@ struct mtk_gc {
        int bank;
        u32 rising;
        u32 falling;
+       u32 hlevel;
+       u32 llevel;
 };
 
 /**
@@ -114,7 +118,7 @@ mediatek_gpio_irq_unmask(struct irq_data *d)
        int bank = pin / MTK_BANK_WIDTH;
        struct mtk_gc *rg = &gpio_data->gc_map[bank];
        unsigned long flags;
-       u32 rise, fall;
+       u32 rise, fall, high, low;
 
        if (!rg)
                return;
@@ -122,10 +126,16 @@ mediatek_gpio_irq_unmask(struct irq_data *d)
        spin_lock_irqsave(&rg->lock, flags);
        rise = mtk_gpio_r32(rg, GPIO_REG_REDGE(bank));
        fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE(bank));
+       high = mtk_gpio_r32(rg, GPIO_REG_HLVL(bank));
+       low = mtk_gpio_r32(rg, GPIO_REG_LLVL(bank));
        mtk_gpio_w32(rg, GPIO_REG_REDGE(bank),
                     rise | (PIN_MASK(pin) & rg->rising));
        mtk_gpio_w32(rg, GPIO_REG_FEDGE(bank),
                     fall | (PIN_MASK(pin) & rg->falling));
+       mtk_gpio_w32(rg, GPIO_REG_HLVL(bank),
+                    high | (PIN_MASK(pin) & rg->hlevel));
+       mtk_gpio_w32(rg, GPIO_REG_LLVL(bank),
+                    low | (PIN_MASK(pin) & rg->llevel));
        spin_unlock_irqrestore(&rg->lock, flags);
 }
 
@@ -137,7 +147,7 @@ mediatek_gpio_irq_mask(struct irq_data *d)
        int bank = pin / MTK_BANK_WIDTH;
        struct mtk_gc *rg = &gpio_data->gc_map[bank];
        unsigned long flags;
-       u32 rise, fall;
+       u32 rise, fall, high, low;
 
        if (!rg)
                return;
@@ -145,8 +155,12 @@ mediatek_gpio_irq_mask(struct irq_data *d)
        spin_lock_irqsave(&rg->lock, flags);
        rise = mtk_gpio_r32(rg, GPIO_REG_REDGE(bank));
        fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE(bank));
+       high = mtk_gpio_r32(rg, GPIO_REG_HLVL(bank));
+       low = mtk_gpio_r32(rg, GPIO_REG_LLVL(bank));
        mtk_gpio_w32(rg, GPIO_REG_FEDGE(bank), fall & ~PIN_MASK(pin));
        mtk_gpio_w32(rg, GPIO_REG_REDGE(bank), rise & ~PIN_MASK(pin));
+       mtk_gpio_w32(rg, GPIO_REG_REDGE(bank), high & ~PIN_MASK(pin));
+       mtk_gpio_w32(rg, GPIO_REG_REDGE(bank), low & ~PIN_MASK(pin));
        spin_unlock_irqrestore(&rg->lock, flags);
 }
 
@@ -163,21 +177,42 @@ mediatek_gpio_irq_type(struct irq_data *d, unsigned int 
type)
                return -1;
 
        if (type == IRQ_TYPE_PROBE) {
-               if ((rg->rising | rg->falling) & mask)
+               if ((rg->rising | rg->falling |
+                    rg->hlevel | rg->llevel) & mask)
                        return 0;
 
-               type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+               type = (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+                       IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW);
        }
 
-       if (type & IRQ_TYPE_EDGE_RISING)
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
                rg->rising |= mask;
-       else
-               rg->rising &= ~mask;
-
-       if (type & IRQ_TYPE_EDGE_FALLING)
-               rg->falling |= mask;
-       else
                rg->falling &= ~mask;
+               rg->hlevel &= ~mask;
+               rg->llevel &= ~mask;
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               rg->falling |= mask;
+               rg->rising &= ~mask;
+               rg->hlevel &= ~mask;
+               rg->llevel &= ~mask;
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               rg->hlevel |= mask;
+               rg->rising &= ~mask;
+               rg->falling &= mask;
+               rg->llevel &= ~mask;
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               rg->llevel |= mask;
+               rg->rising &= ~mask;
+               rg->falling &= mask;
+               rg->hlevel &= ~mask;
+               break;
+       default:
+               return -EINVAL;
+       }
 
        return 0;
 }
-- 
2.7.4

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to