Beispiel #1
0
static void sh_intc_toggle_mask(struct intc_desc *desc, intc_enum id,
				int enable, int is_group)
{
    struct intc_source *source = desc->sources + id;

    if (!id)
	return;

    if (!source->next_enum_id && (!source->enable_max || !source->vect)) {
#ifdef DEBUG_INTC_SOURCES
        printf("sh_intc: reserved interrupt source %d modified\n", id);
#endif
	return;
    }

    if (source->vect)
        sh_intc_toggle_source(source, enable ? 1 : -1, 0);

#ifdef DEBUG_INTC
    else {
        printf("setting interrupt group %d to %d\n", id, !!enable);
    }
#endif

    if ((is_group || !source->vect) && source->next_enum_id) {
        sh_intc_toggle_mask(desc, source->next_enum_id, enable, 1);
    }

#ifdef DEBUG_INTC
    if (!source->vect) {
        printf("setting interrupt group %d to %d - done\n", id, !!enable);
    }
#endif
}
Beispiel #2
0
static void sh_intc_write(void *opaque, hwaddr offset,
                          uint64_t value, unsigned size)
{
    struct intc_desc *desc = opaque;
    intc_enum *enum_ids = NULL;
    unsigned int first = 0;
    unsigned int width = 0;
    unsigned int mode = 0;
    unsigned int k;
    unsigned long *valuep;
    unsigned long mask;

#ifdef DEBUG_INTC
    printf("sh_intc_write 0x%lx 0x%08x\n", (unsigned long) offset, value);
#endif

    sh_intc_locate(desc, (unsigned long)offset, &valuep,
                   &enum_ids, &first, &width, &mode);

    switch (mode) {
    case INTC_MODE_ENABLE_REG | INTC_MODE_IS_PRIO:
        break;
    case INTC_MODE_DUAL_SET:
        value |= *valuep;
        break;
    case INTC_MODE_DUAL_CLR:
        value = *valuep & ~value;
        break;
    default:
        abort();
    }

    for (k = 0; k <= first; k++) {
        mask = ((1 << width) - 1) << ((first - k) * width);

        if ((*valuep & mask) == (value & mask))
            continue;
#if 0
        printf("k = %d, first = %d, enum = %d, mask = 0x%08x\n",
               k, first, enum_ids[k], (unsigned int)mask);
#endif
        sh_intc_toggle_mask(desc, enum_ids[k], value & mask, 0);
    }

    *valuep = value;

#ifdef DEBUG_INTC
    printf("sh_intc_write 0x%lx -> 0x%08x\n", (unsigned long) offset, value);
#endif
}