void mcp2210_irq_do_gpio(struct mcp2210_device *dev, u16 old_val, u16 new_val) { uint i; for (i = 0; i < MCP2210_NUM_PINS; ++i) { struct mcp2210_pin_config *pin = &dev->config->pins[i]; int old_pin_val; int new_pin_val; int edge_mask, level_mask; struct irq_desc *desc; if (!pin->has_irq || pin->mode != MCP2210_PIN_GPIO) continue; old_pin_val = old_val & (1 << i); new_pin_val = new_val & (1 << i); level_mask = new_pin_val ? IRQ_TYPE_LEVEL_HIGH : IRQ_TYPE_LEVEL_LOW; desc = dev->irq_descs[pin->irq]; if (new_pin_val > old_val) edge_mask = IRQ_TYPE_EDGE_RISING; else if (new_pin_val < old_val) edge_mask = IRQ_TYPE_EDGE_FALLING; else edge_mask = 0; if (pin->irq_type & edge_mask) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0) handle_simple_irq(desc); #else handle_simple_irq(dev->irq_base + pin->irq, desc); #endif } if (pin->irq_type & level_mask) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0) handle_level_irq(desc); #else handle_level_irq(dev->irq_base + pin->irq, desc); #endif } } }
static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) { unsigned short intv = ctrl_inw(IRQ01_STS); struct irq_desc *ext_desc; unsigned int ext_irq = SE7722_FPGA_IRQ_BASE; intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; while (intv) { if (intv & 1) { ext_desc = irq_desc + ext_irq; handle_level_irq(ext_irq, ext_desc); } intv >>= 1; ext_irq++; } }