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; }
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; }
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; }