static void ep93xx_gpio_irq_unmask(struct irq_data *d) { int line = irq_to_gpio(d->irq); int port = line >> 3; gpio_int_unmasked[port] |= 1 << (line & 7); ep93xx_gpio_update_int_params(port); }
static void ep93xx_gpio_irq_ack(struct irq_data *d) { int line = irq_to_gpio(d->irq); int port = line >> 3; int port_mask = 1 << (line & 7); if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { gpio_int_type2[port] ^= port_mask; /* switch edge direction */ ep93xx_gpio_update_int_params(port); } writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port])); }
/* * gpio_int_type1 controls whether the interrupt is level (0) or * edge (1) triggered, while gpio_int_type2 controls whether it * triggers on low/falling (0) or high/rising (1). */ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) { const int gpio = irq_to_gpio(d->irq); const int port = gpio >> 3; const int port_mask = 1 << (gpio & 7); irq_flow_handler_t handler; gpio_direction_input(gpio); switch (type) { case IRQ_TYPE_EDGE_RISING: gpio_int_type1[port] |= port_mask; gpio_int_type2[port] |= port_mask; handler = handle_edge_irq; break; case IRQ_TYPE_EDGE_FALLING: gpio_int_type1[port] |= port_mask; gpio_int_type2[port] &= ~port_mask; handler = handle_edge_irq; break; case IRQ_TYPE_LEVEL_HIGH: gpio_int_type1[port] &= ~port_mask; gpio_int_type2[port] |= port_mask; handler = handle_level_irq; break; case IRQ_TYPE_LEVEL_LOW: gpio_int_type1[port] &= ~port_mask; gpio_int_type2[port] &= ~port_mask; handler = handle_level_irq; break; case IRQ_TYPE_EDGE_BOTH: gpio_int_type1[port] |= port_mask; /* set initial polarity based on current input level */ if (gpio_get_value(gpio)) gpio_int_type2[port] &= ~port_mask; /* falling */ else gpio_int_type2[port] |= port_mask; /* rising */ handler = handle_edge_irq; break; default: return -EINVAL; } __irq_set_handler_locked(d->irq, handler); gpio_int_enabled[port] |= port_mask; ep93xx_gpio_update_int_params(port); return 0; }
static void ep93xx_gpio_irq_mask_ack(struct irq_data *d) { int line = irq_to_gpio(d->irq); int port = line >> 3; int port_mask = 1 << (line & 7); if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) gpio_int_type2[port] ^= port_mask; gpio_int_unmasked[port] &= ~port_mask; ep93xx_gpio_update_int_params(port); __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port])); }