static int intc_set_type(struct irq_data *data, unsigned int type) { unsigned int irq = data->irq; struct intc_desc_int *d = get_intc_desc(irq); unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK]; struct intc_handle_int *ihp; unsigned long addr; if (!value) return -EINVAL; value &= ~SENSE_VALID_FLAG; ihp = intc_find_irq(d->sense, d->nr_sense, irq); if (ihp) { /* PINT has 2-bit sense registers, should fail on EDGE_BOTH */ if (value >= (1 << _INTC_WIDTH(ihp->handle))) return -EINVAL; addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0); intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value); } return 0; }
int intc_set_priority(unsigned int irq, unsigned int prio) { struct intc_desc_int *d = get_intc_desc(irq); struct irq_data *data = irq_get_irq_data(irq); struct intc_handle_int *ihp; if (!intc_get_prio_level(irq) || prio <= 1) return -EINVAL; ihp = intc_find_irq(d->prio, d->nr_prio, irq); if (ihp) { if (prio >= (1 << _INTC_WIDTH(ihp->handle))) return -EINVAL; intc_set_prio_level(irq, prio); /* * only set secondary masking method directly * primary masking method is using intc_prio_level[irq] * priority level will be set during next enable() */ if (_INTC_FN(ihp->handle) != REG_FN_ERR) _intc_enable(data, ihp->handle); } return 0; }
unsigned long intc_get_field_from_handle(unsigned int value, unsigned int handle) { unsigned int width = _INTC_WIDTH(handle); unsigned int shift = _INTC_SHIFT(handle); unsigned int mask = ((1 << width) - 1) << shift; return (value & mask) >> shift; }
static unsigned long intc_mode_field(unsigned long addr, unsigned long handle, unsigned long (*fn)(unsigned long, unsigned long, unsigned long), unsigned int irq) { return fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1)); }
unsigned int intc_set_field_from_handle(unsigned int value, unsigned int field_value, unsigned int handle) { unsigned int width = _INTC_WIDTH(handle); unsigned int shift = _INTC_SHIFT(handle); value &= ~(((1 << width) - 1) << shift); value |= field_value << shift; return value; }
int intc_set_priority(unsigned int irq, unsigned int prio) { struct intc_desc_int *d = get_intc_desc(irq); struct irq_data *data = irq_get_irq_data(irq); struct intc_handle_int *ihp; if (!intc_get_prio_level(irq) || prio <= 1) return -EINVAL; ihp = intc_find_irq(d->prio, d->nr_prio, irq); if (ihp) { if (prio >= (1 << _INTC_WIDTH(ihp->handle))) return -EINVAL; intc_set_prio_level(irq, prio); if (_INTC_FN(ihp->handle) != REG_FN_ERR) _intc_enable(data, ihp->handle); } return 0; }