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>
51 u8 affinity[MAX_WORDS * IRQS_PER_WORD]; member
86 return (0 * intc->n_words + word) * sizeof(u32); in reg_status()
92 return (1 * intc->n_words + word) * sizeof(u32); in reg_mask_status()
98 return (2 * intc->n_words + word) * sizeof(u32); in reg_mask_set()
104 return (3 * intc->n_words + word) * sizeof(u32); in reg_mask_clr()
131 cpu = intc->cpus[cpu_logical_map(smp_processor_id())]; in bcm7038_l1_irq_handle()
133 cpu = intc->cpus[0]; in bcm7038_l1_irq_handle()
138 for (idx = 0; idx < intc->n_words; idx++) { in bcm7038_l1_irq_handle()
143 raw_spin_lock_irqsave(&intc->lock, flags); in bcm7038_l1_irq_handle()
144 pending = l1_readl(cpu->map_base + reg_status(intc, idx)) & in bcm7038_l1_irq_handle()
145 ~cpu->mask_cache[idx]; in bcm7038_l1_irq_handle()
146 raw_spin_unlock_irqrestore(&intc->lock, flags); in bcm7038_l1_irq_handle()
149 generic_handle_irq(irq_find_mapping(intc->domain, in bcm7038_l1_irq_handle()
160 u32 word = d->hwirq / IRQS_PER_WORD; in __bcm7038_l1_unmask()
161 u32 mask = BIT(d->hwirq % IRQS_PER_WORD); in __bcm7038_l1_unmask()
163 intc->cpus[cpu_idx]->mask_cache[word] &= ~mask; in __bcm7038_l1_unmask()
164 l1_writel(mask, intc->cpus[cpu_idx]->map_base + in __bcm7038_l1_unmask()
171 u32 word = d->hwirq / IRQS_PER_WORD; in __bcm7038_l1_mask()
172 u32 mask = BIT(d->hwirq % IRQS_PER_WORD); in __bcm7038_l1_mask()
174 intc->cpus[cpu_idx]->mask_cache[word] |= mask; in __bcm7038_l1_mask()
175 l1_writel(mask, intc->cpus[cpu_idx]->map_base + in __bcm7038_l1_mask()
184 raw_spin_lock_irqsave(&intc->lock, flags); in bcm7038_l1_unmask()
185 __bcm7038_l1_unmask(d, intc->affinity[d->hwirq]); in bcm7038_l1_unmask()
186 raw_spin_unlock_irqrestore(&intc->lock, flags); in bcm7038_l1_unmask()
194 raw_spin_lock_irqsave(&intc->lock, flags); in bcm7038_l1_mask()
195 __bcm7038_l1_mask(d, intc->affinity[d->hwirq]); in bcm7038_l1_mask()
196 raw_spin_unlock_irqrestore(&intc->lock, flags); in bcm7038_l1_mask()
205 irq_hw_number_t hw = d->hwirq; in bcm7038_l1_set_affinity()
211 raw_spin_lock_irqsave(&intc->lock, flags); in bcm7038_l1_set_affinity()
213 was_disabled = !!(intc->cpus[intc->affinity[hw]]->mask_cache[word] & in bcm7038_l1_set_affinity()
215 __bcm7038_l1_mask(d, intc->affinity[hw]); in bcm7038_l1_set_affinity()
216 intc->affinity[hw] = first_cpu; in bcm7038_l1_set_affinity()
220 raw_spin_unlock_irqrestore(&intc->lock, flags); in bcm7038_l1_set_affinity()
233 /* This CPU was not on the affinity mask */ in bcm7038_l1_cpu_offline()
239 * Multiple CPU affinity, remove this CPU from the affinity in bcm7038_l1_cpu_offline()
264 return -EINVAL; in bcm7038_l1_init_one()
269 return -EINVAL; in bcm7038_l1_init_one()
270 else if (!intc->n_words) in bcm7038_l1_init_one()
271 intc->n_words = n_words; in bcm7038_l1_init_one()
272 else if (intc->n_words != n_words) in bcm7038_l1_init_one()
273 return -EINVAL; in bcm7038_l1_init_one()
275 ret = of_property_read_u32_array(dn , "brcm,int-fwd-mask", in bcm7038_l1_init_one()
276 intc->irq_fwd_mask, n_words); in bcm7038_l1_init_one()
277 if (ret != 0 && ret != -EINVAL) { in bcm7038_l1_init_one()
279 pr_err("invalid brcm,int-fwd-mask property\n"); in bcm7038_l1_init_one()
280 return -EINVAL; in bcm7038_l1_init_one()
283 cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32), in bcm7038_l1_init_one()
286 return -ENOMEM; in bcm7038_l1_init_one()
288 cpu->map_base = ioremap(res.start, sz); in bcm7038_l1_init_one()
289 if (!cpu->map_base) in bcm7038_l1_init_one()
290 return -ENOMEM; in bcm7038_l1_init_one()
293 l1_writel(~intc->irq_fwd_mask[i], in bcm7038_l1_init_one()
294 cpu->map_base + reg_mask_set(intc, i)); in bcm7038_l1_init_one()
295 l1_writel(intc->irq_fwd_mask[i], in bcm7038_l1_init_one()
296 cpu->map_base + reg_mask_clr(intc, i)); in bcm7038_l1_init_one()
297 cpu->mask_cache[i] = ~intc->irq_fwd_mask[i]; in bcm7038_l1_init_one()
302 pr_err("failed to map parent interrupt %d\n", parent_irq); in bcm7038_l1_init_one()
303 return -EINVAL; in bcm7038_l1_init_one()
306 if (of_property_read_bool(dn, "brcm,irq-can-wake")) in bcm7038_l1_init_one()
332 /* Wakeup interrupt should only come from the boot cpu */ in bcm7038_l1_suspend()
340 for (word = 0; word < intc->n_words; word++) { in bcm7038_l1_suspend()
341 val = intc->wake_mask[word] | intc->irq_fwd_mask[word]; in bcm7038_l1_suspend()
343 intc->cpus[boot_cpu]->map_base + reg_mask_set(intc, word)); in bcm7038_l1_suspend()
345 intc->cpus[boot_cpu]->map_base + reg_mask_clr(intc, word)); in bcm7038_l1_suspend()
364 for (word = 0; word < intc->n_words; word++) { in bcm7038_l1_resume()
365 l1_writel(intc->cpus[boot_cpu]->mask_cache[word], in bcm7038_l1_resume()
366 intc->cpus[boot_cpu]->map_base + reg_mask_set(intc, word)); in bcm7038_l1_resume()
367 l1_writel(~intc->cpus[boot_cpu]->mask_cache[word], in bcm7038_l1_resume()
368 intc->cpus[boot_cpu]->map_base + reg_mask_clr(intc, word)); in bcm7038_l1_resume()
382 u32 word = d->hwirq / IRQS_PER_WORD; in bcm7038_l1_set_wake()
383 u32 mask = BIT(d->hwirq % IRQS_PER_WORD); in bcm7038_l1_set_wake()
385 raw_spin_lock_irqsave(&intc->lock, flags); in bcm7038_l1_set_wake()
387 intc->wake_mask[word] |= mask; in bcm7038_l1_set_wake()
389 intc->wake_mask[word] &= ~mask; in bcm7038_l1_set_wake()
390 raw_spin_unlock_irqrestore(&intc->lock, flags); in bcm7038_l1_set_wake()
397 .name = "bcm7038-l1",
412 struct bcm7038_l1_chip *intc = d->host_data; in bcm7038_l1_map()
416 if (intc->irq_fwd_mask[word] & mask) in bcm7038_l1_map()
417 return -EPERM; in bcm7038_l1_map()
420 irq_set_chip_data(virq, d->host_data); in bcm7038_l1_map()
438 return -ENOMEM; in bcm7038_l1_of_init()
440 raw_spin_lock_init(&intc->lock); in bcm7038_l1_of_init()
451 intc->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * intc->n_words, in bcm7038_l1_of_init()
454 if (!intc->domain) { in bcm7038_l1_of_init()
455 ret = -ENOMEM; in bcm7038_l1_of_init()
462 list_add_tail(&intc->list, &bcm7038_l1_intcs_list); in bcm7038_l1_of_init()
470 dn, IRQS_PER_WORD * intc->n_words); in bcm7038_l1_of_init()
476 struct bcm7038_l1_cpu *cpu = intc->cpus[idx]; in bcm7038_l1_of_init()
479 if (cpu->map_base) in bcm7038_l1_of_init()
480 iounmap(cpu->map_base); in bcm7038_l1_of_init()
489 IRQCHIP_DECLARE(bcm7038_l1, "brcm,bcm7038-l1-intc", bcm7038_l1_of_init);