diff options
author | Alexander Stein <alexander.stein@systec-electronic.com> | 2016-03-23 13:01:27 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-03-31 04:41:50 -0400 |
commit | 16fe1ad289019d78a8f8fdb65f08d298ee921cb3 (patch) | |
tree | 72891a503d0271a52ae54d6151df32d584d9dfa5 /drivers/gpio | |
parent | 1418f9e6e02da2ad0a6aacc8645e6ad7496105e9 (diff) |
gpio: mcp23s08: Add support for level triggered interrupts
The interrupt for the corresponding pin is configured to trigger when the
pin state changes compared to a preconfigured state (Bit set in INTCON).
This state is set by setting/clearing the bit in DEFVAL.
In the interrupt handler we need also to check if the bit in INTCON is set
for level triggered interrupts.
Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-mcp23s08.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index c882c2be5a0e..ac22efc1840e 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
@@ -362,7 +362,8 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) | |||
362 | for (i = 0; i < mcp->chip.ngpio; i++) { | 362 | for (i = 0; i < mcp->chip.ngpio; i++) { |
363 | if ((BIT(i) & mcp->cache[MCP_INTF]) && | 363 | if ((BIT(i) & mcp->cache[MCP_INTF]) && |
364 | ((BIT(i) & intcap & mcp->irq_rise) || | 364 | ((BIT(i) & intcap & mcp->irq_rise) || |
365 | (mcp->irq_fall & ~intcap & BIT(i)))) { | 365 | (mcp->irq_fall & ~intcap & BIT(i)) || |
366 | (BIT(i) & mcp->cache[MCP_INTCON]))) { | ||
366 | child_irq = irq_find_mapping(mcp->chip.irqdomain, i); | 367 | child_irq = irq_find_mapping(mcp->chip.irqdomain, i); |
367 | handle_nested_irq(child_irq); | 368 | handle_nested_irq(child_irq); |
368 | } | 369 | } |
@@ -408,6 +409,12 @@ static int mcp23s08_irq_set_type(struct irq_data *data, unsigned int type) | |||
408 | mcp->cache[MCP_INTCON] &= ~BIT(pos); | 409 | mcp->cache[MCP_INTCON] &= ~BIT(pos); |
409 | mcp->irq_rise &= ~BIT(pos); | 410 | mcp->irq_rise &= ~BIT(pos); |
410 | mcp->irq_fall |= BIT(pos); | 411 | mcp->irq_fall |= BIT(pos); |
412 | } else if (type & IRQ_TYPE_LEVEL_HIGH) { | ||
413 | mcp->cache[MCP_INTCON] |= BIT(pos); | ||
414 | mcp->cache[MCP_DEFVAL] &= ~BIT(pos); | ||
415 | } else if (type & IRQ_TYPE_LEVEL_LOW) { | ||
416 | mcp->cache[MCP_INTCON] |= BIT(pos); | ||
417 | mcp->cache[MCP_DEFVAL] |= BIT(pos); | ||
411 | } else | 418 | } else |
412 | return -EINVAL; | 419 | return -EINVAL; |
413 | 420 | ||