Lines Matching +full:interrupt +full:- +full:affinity
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Broadcom BCM7038 style Level 1 interrupt controller driver
14 #include <linux/interrupt.h>
42 u8 affinity[MAX_WORDS * IRQS_PER_WORD]; member
77 return (0 * intc->n_words + word) * sizeof(u32); in reg_status()
83 return (1 * intc->n_words + word) * sizeof(u32); in reg_mask_status()
89 return (2 * intc->n_words + word) * sizeof(u32); in reg_mask_set()
95 return (3 * intc->n_words + word) * sizeof(u32); in reg_mask_clr()
122 cpu = intc->cpus[cpu_logical_map(smp_processor_id())]; in bcm7038_l1_irq_handle()
124 cpu = intc->cpus[0]; in bcm7038_l1_irq_handle()
129 for (idx = 0; idx < intc->n_words; idx++) { in bcm7038_l1_irq_handle()
134 raw_spin_lock_irqsave(&intc->lock, flags); in bcm7038_l1_irq_handle()
135 pending = l1_readl(cpu->map_base + reg_status(intc, idx)) & in bcm7038_l1_irq_handle()
136 ~cpu->mask_cache[idx]; in bcm7038_l1_irq_handle()
137 raw_spin_unlock_irqrestore(&intc->lock, flags); in bcm7038_l1_irq_handle()
140 generic_handle_irq(irq_find_mapping(intc->domain, in bcm7038_l1_irq_handle()
151 u32 word = d->hwirq / IRQS_PER_WORD; in __bcm7038_l1_unmask()
152 u32 mask = BIT(d->hwirq % IRQS_PER_WORD); in __bcm7038_l1_unmask()
154 intc->cpus[cpu_idx]->mask_cache[word] &= ~mask; in __bcm7038_l1_unmask()
155 l1_writel(mask, intc->cpus[cpu_idx]->map_base + in __bcm7038_l1_unmask()
162 u32 word = d->hwirq / IRQS_PER_WORD; in __bcm7038_l1_mask()
163 u32 mask = BIT(d->hwirq % IRQS_PER_WORD); in __bcm7038_l1_mask()
165 intc->cpus[cpu_idx]->mask_cache[word] |= mask; in __bcm7038_l1_mask()
166 l1_writel(mask, intc->cpus[cpu_idx]->map_base + in __bcm7038_l1_mask()
175 raw_spin_lock_irqsave(&intc->lock, flags); in bcm7038_l1_unmask()
176 __bcm7038_l1_unmask(d, intc->affinity[d->hwirq]); in bcm7038_l1_unmask()
177 raw_spin_unlock_irqrestore(&intc->lock, flags); in bcm7038_l1_unmask()
185 raw_spin_lock_irqsave(&intc->lock, flags); in bcm7038_l1_mask()
186 __bcm7038_l1_mask(d, intc->affinity[d->hwirq]); in bcm7038_l1_mask()
187 raw_spin_unlock_irqrestore(&intc->lock, flags); in bcm7038_l1_mask()
196 irq_hw_number_t hw = d->hwirq; in bcm7038_l1_set_affinity()
202 raw_spin_lock_irqsave(&intc->lock, flags); in bcm7038_l1_set_affinity()
204 was_disabled = !!(intc->cpus[intc->affinity[hw]]->mask_cache[word] & in bcm7038_l1_set_affinity()
206 __bcm7038_l1_mask(d, intc->affinity[hw]); in bcm7038_l1_set_affinity()
207 intc->affinity[hw] = first_cpu; in bcm7038_l1_set_affinity()
211 raw_spin_unlock_irqrestore(&intc->lock, flags); in bcm7038_l1_set_affinity()
224 /* This CPU was not on the affinity mask */ in bcm7038_l1_cpu_offline()
230 * Multiple CPU affinity, remove this CPU from the affinity in bcm7038_l1_cpu_offline()
254 return -EINVAL; in bcm7038_l1_init_one()
259 return -EINVAL; in bcm7038_l1_init_one()
260 else if (!intc->n_words) in bcm7038_l1_init_one()
261 intc->n_words = n_words; in bcm7038_l1_init_one()
262 else if (intc->n_words != n_words) in bcm7038_l1_init_one()
263 return -EINVAL; in bcm7038_l1_init_one()
265 cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32), in bcm7038_l1_init_one()
268 return -ENOMEM; in bcm7038_l1_init_one()
270 cpu->map_base = ioremap(res.start, sz); in bcm7038_l1_init_one()
271 if (!cpu->map_base) in bcm7038_l1_init_one()
272 return -ENOMEM; in bcm7038_l1_init_one()
275 l1_writel(0xffffffff, cpu->map_base + reg_mask_set(intc, i)); in bcm7038_l1_init_one()
276 cpu->mask_cache[i] = 0xffffffff; in bcm7038_l1_init_one()
281 pr_err("failed to map parent interrupt %d\n", parent_irq); in bcm7038_l1_init_one()
282 return -EINVAL; in bcm7038_l1_init_one()
291 .name = "bcm7038-l1",
304 irq_set_chip_data(virq, d->host_data); in bcm7038_l1_map()
322 return -ENOMEM; in bcm7038_l1_of_init()
324 raw_spin_lock_init(&intc->lock); in bcm7038_l1_of_init()
335 intc->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * intc->n_words, in bcm7038_l1_of_init()
338 if (!intc->domain) { in bcm7038_l1_of_init()
339 ret = -ENOMEM; in bcm7038_l1_of_init()
344 dn, IRQS_PER_WORD * intc->n_words); in bcm7038_l1_of_init()
350 struct bcm7038_l1_cpu *cpu = intc->cpus[idx]; in bcm7038_l1_of_init()
353 if (cpu->map_base) in bcm7038_l1_of_init()
354 iounmap(cpu->map_base); in bcm7038_l1_of_init()
363 IRQCHIP_DECLARE(bcm7038_l1, "brcm,bcm7038-l1-intc", bcm7038_l1_of_init);