Пример #1
0
static int
idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
		     bool force)
{
	unsigned long flags;
	cpumask_t online;
	unsigned int destination_bits;
	unsigned int distribution_mode;

	/* errout if no online cpu per @cpumask */
	if (!cpumask_and(&online, cpumask, cpu_online_mask))
		return -EINVAL;

	raw_spin_lock_irqsave(&mcip_lock, flags);

	destination_bits = cpumask_bits(&online)[0];
	idu_set_dest(data->hwirq, destination_bits);

	if (ffs(destination_bits) == fls(destination_bits))
		distribution_mode = IDU_M_DISTRI_DEST;
	else
		distribution_mode = IDU_M_DISTRI_RR;

	idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, distribution_mode);

	raw_spin_unlock_irqrestore(&mcip_lock, flags);

	return IRQ_SET_MASK_OK;
}
Пример #2
0
static int idu_irq_xlate(struct irq_domain *d, struct device_node *n,
			 const u32 *intspec, unsigned int intsize,
			 irq_hw_number_t *out_hwirq, unsigned int *out_type)
{
	irq_hw_number_t hwirq = *out_hwirq = intspec[0];
	int distri = intspec[1];
	unsigned long flags;

	*out_type = IRQ_TYPE_NONE;

	/* XXX: validate distribution scheme again online cpu mask */
	if (distri == 0) {
		/* 0 - Round Robin to all cpus, otherwise 1 bit per core */
		raw_spin_lock_irqsave(&mcip_lock, flags);
		idu_set_dest(hwirq, BIT(num_online_cpus()) - 1);
		idu_set_mode(hwirq, IDU_M_TRIG_LEVEL, IDU_M_DISTRI_RR);
		raw_spin_unlock_irqrestore(&mcip_lock, flags);
	} else {
		/*
		 * DEST based distribution for Level Triggered intr can only
		 * have 1 CPU, so generalize it to always contain 1 cpu
		 */
		int cpu = ffs(distri);

		if (cpu != fls(distri))
			pr_warn("IDU irq %lx distri mode set to cpu %x\n",
				hwirq, cpu);

		raw_spin_lock_irqsave(&mcip_lock, flags);
		idu_set_dest(hwirq, cpu);
		idu_set_mode(hwirq, IDU_M_TRIG_LEVEL, IDU_M_DISTRI_DEST);
		raw_spin_unlock_irqrestore(&mcip_lock, flags);
	}

	return 0;
}
Пример #3
0
static int
idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
                     bool force)
{
    unsigned long flags;
    cpumask_t online;

    /* errout if no online cpu per @cpumask */
    if (!cpumask_and(&online, cpumask, cpu_online_mask))
        return -EINVAL;

    raw_spin_lock_irqsave(&mcip_lock, flags);

    idu_set_dest(data->hwirq, cpumask_bits(&online)[0]);
    idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, IDU_M_DISTRI_RR);

    raw_spin_unlock_irqrestore(&mcip_lock, flags);

    return IRQ_SET_MASK_OK;
}