Index: drivers/soc/asic3_base.c =================================================================== RCS file: /cvs/linux/kernel26/drivers/soc/asic3_base.c,v retrieving revision 1.22 diff -u -r1.22 asic3_base.c --- drivers/soc/asic3_base.c 1 Dec 2006 18:28:05 -0000 1.22 +++ drivers/soc/asic3_base.c 1 Dec 2006 20:37:57 -0000 @@ -44,6 +44,9 @@ int irq_base; int irq_nr; + u16 irq_bothedge[4]; + struct device *dev; /* FIXME */ + struct platform_device *mmc_dev; }; @@ -304,13 +307,20 @@ __asic3_write_register (asic, base + _IPAQ_ASIC3_GPIO_IntStatus, 0); for (i = 0; i < 16; i++) { - if (istat & (1 << i)) { + int bit = (1 << i); + if (istat & bit) { unsigned int irqnr; irqnr = asic->irq_base + (16 * bank) + i; desc = irq_desc + irqnr; desc->handle_irq (irqnr, desc, regs); + if (asic->irq_bothedge[bank] & bit) { + u16 edge; + __asic3_read_register (asic, base + _IPAQ_ASIC3_GPIO_EdgeTrigger, edge); + edge ^= bit; + __asic3_write_register (asic, base + _IPAQ_ASIC3_GPIO_EdgeTrigger, edge); + } } } } @@ -503,6 +513,7 @@ level = __asic3_read_register (asic, bank + _IPAQ_ASIC3_GPIO_LevelTrigger); edge = __asic3_read_register (asic, bank + _IPAQ_ASIC3_GPIO_EdgeTrigger); trigger = __asic3_read_register (asic, bank + _IPAQ_ASIC3_GPIO_TriggerType); + asic3->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit; if (type == IRQT_RISING) { trigger |= bit; edge |= bit; @@ -511,6 +522,16 @@ trigger |= bit; edge &= ~bit; } + else if (type == IRQT_BOTHEDGE) { + trigger |= bit; + if (asic3_get_gpio_bit(asic->dev, irq - asic3->irq_base) { + edge &= ~bit; + } + else { + edge |= bit; + } + asic3->irq_bothedge[(irq - asic->irq_base) >> 4] |= bit; + } else if (type == IRQT_LOW) { trigger &= ~bit; level &= ~bit; @@ -636,6 +657,7 @@ spin_lock_init (&asic3_gpio_lock); platform_set_drvdata(pdev, asic); + asic->dev = &pdev->dev; asic->mapping = ioremap ((unsigned long)pdev->resource[0].start, IPAQ_ASIC3_MAP_SIZE); if (!asic->mapping) {