static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, struct pt_regs *regs, int intc_offset) { int pnd; int offset; pnd = __raw_readl(intc->reg_intpnd); if (!pnd) return false; /* non-dt machines use individual domains */ if (!irq_domain_get_of_node(intc->domain)) intc_offset = 0; /* We have a problem that the INTOFFSET register does not always * show one interrupt. Occasionally we get two interrupts through * the prioritiser, and this causes the INTOFFSET register to show * what looks like the logical-or of the two interrupt numbers. * * Thanks to Klaus, Shannon, et al for helping to debug this problem */ offset = __raw_readl(intc->reg_intpnd + 4); /* Find the bit manually, when the offset is wrong. * The pending register only ever contains the one bit of the next * interrupt to handle. */ if (!(pnd & (1 << offset))) offset = __ffs(pnd); handle_domain_irq(intc->domain, intc_offset + offset, regs); return true; }
static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node, enum irq_domain_bus_token bus_token) { /* Exact match, unless ehv_pic node is NULL */ struct device_node *of_node = irq_domain_get_of_node(h); return of_node == NULL || of_node == node; }
static void s3c_irq_demux(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc); struct s3c_irq_intc *intc = irq_data->intc; struct s3c_irq_intc *sub_intc = irq_data->sub_intc; unsigned int n, offset, irq; unsigned long src, msk; /* we're using individual domains for the non-dt case * and one big domain for the dt case where the subintc * starts at hwirq number 32. */ offset = irq_domain_get_of_node(intc->domain) ? 32 : 0; chained_irq_enter(chip, desc); src = __raw_readl(sub_intc->reg_pending); msk = __raw_readl(sub_intc->reg_mask); src &= ~msk; src &= irq_data->sub_bits; while (src) { n = __ffs(src); src &= ~(1 << n); irq = irq_find_mapping(sub_intc->domain, offset + n); generic_handle_irq(irq); } chained_irq_exit(chip, desc); }
static int combiner_irq_domain_xlate(struct irq_domain *d, struct device_node *controller, const u32 *intspec, unsigned int intsize, unsigned long *out_hwirq, unsigned int *out_type) { if (irq_domain_get_of_node(d) != controller) return -EINVAL; if (intsize < 2) return -EINVAL; *out_hwirq = intspec[0] * IRQ_IN_COMBINER + intspec[1]; *out_type = 0; return 0; }
static int rps_irq_domain_xlate(struct irq_domain *d, struct device_node *controller, const u32 *intspec, unsigned int intsize, unsigned long *out_hwirq, unsigned int *out_type) { #if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) if (d->of_node != controller) #else if (irq_domain_get_of_node(d) != controller) #endif return -EINVAL; if (intsize < 1) return -EINVAL; *out_hwirq = intspec[0]; /* Honestly I do not know the type */ *out_type = IRQ_TYPE_LEVEL_HIGH; return 0; }
int mpic_msi_init_allocator(struct mpic *mpic) { int rc; rc = msi_bitmap_alloc(&mpic->msi_bitmap, mpic->num_sources, irq_domain_get_of_node(mpic->irqhost)); if (rc) return rc; rc = msi_bitmap_reserve_dt_hwirqs(&mpic->msi_bitmap); if (rc > 0) { if (mpic->flags & MPIC_U3_HT_IRQS) rc = mpic_msi_reserve_u3_hwirqs(mpic); if (rc) { msi_bitmap_free(&mpic->msi_bitmap); return rc; } } return 0; }
static int allocate_gic_irq(struct irq_domain *domain, unsigned virq, irq_hw_number_t hwirq) { struct irq_fwspec fwspec; int i; int err; if (!irq_domain_get_of_node(domain->parent)) return -EINVAL; raw_spin_lock(&cb->lock); for (i = cb->int_max - 1; i >= 0; i--) { if (cb->irq_map[i] == IRQ_FREE) { cb->irq_map[i] = hwirq; break; } } raw_spin_unlock(&cb->lock); if (i < 0) return -ENODEV; fwspec.fwnode = domain->parent->fwnode; fwspec.param_count = 3; fwspec.param[0] = 0; /* SPI */ fwspec.param[1] = i; fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH; err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); if (err) cb->irq_map[i] = IRQ_FREE; else cb->write(i, hwirq); return err; }
static int i8259_host_match(struct irq_domain *h, struct device_node *node, enum irq_domain_bus_token bus_token) { struct device_node *of_node = irq_domain_get_of_node(h); return of_node == NULL || of_node == node; }
static int opal_event_match(struct irq_domain *h, struct device_node *node, enum irq_domain_bus_token bus_token) { return irq_domain_get_of_node(h) == node; }