struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
u32 int_value;
u32 int_type;
+ u32 int_any;
u32 mask = BIT(d->hwirq);
int ret = 0;
int_value = ioread32(cgpio->regs + CDNS_GPIO_IRQ_VALUE) & ~mask;
int_type = ioread32(cgpio->regs + CDNS_GPIO_IRQ_TYPE) & ~mask;
-
/*
- * The GPIO controller doesn't have an ACK register.
- * All interrupt statuses are cleared on a status register read.
- * Don't support edge interrupts for now.
+ * Interrupt polarity and trigger behaviour is configured like this:
+ *
+ * (type, value)
+ * (0, 0) = Falling edge triggered
+ * (0, 1) = Rising edge triggered
+ * (1, 0) = Low level triggered
+ * (1, 1) = High level triggered
*/
+ int_any = ioread32(cgpio->regs + CDNS_GPIO_IRQ_ANY_EDGE) & ~mask;
if (type == IRQ_TYPE_LEVEL_HIGH) {
int_type |= mask;
int_value |= mask;
} else if (type == IRQ_TYPE_LEVEL_LOW) {
int_type |= mask;
+ } else if (type == IRQ_TYPE_EDGE_RISING) {
+ int_value |= mask;
+ } else if (type == IRQ_TYPE_EDGE_FALLING) {
+ /* edge trigger, int_value remains cleared for falling */
+ } else if (type == IRQ_TYPE_EDGE_BOTH) {
+ int_any |= mask;
} else {
return -EINVAL;
}
iowrite32(int_value, cgpio->regs + CDNS_GPIO_IRQ_VALUE);
iowrite32(int_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE);
+ iowrite32(int_any, cgpio->regs + CDNS_GPIO_IRQ_ANY_EDGE);
return ret;
}