Lines Matching +full:chip +full:- +full:relative

1 // SPDX-License-Identifier: GPL-2.0
3 * Library implementing the most common irq chip callback functions
22 * irq_gc_noop - NOOP function
31 * irq_gc_mask_disable_reg - Mask chip via disable register
34 * Chip has separate enable/disable registers instead of a single mask
41 u32 mask = d->mask; in irq_gc_mask_disable_reg()
43 guard(raw_spinlock)(&gc->lock); in irq_gc_mask_disable_reg()
44 irq_reg_writel(gc, mask, ct->regs.disable); in irq_gc_mask_disable_reg()
45 *ct->mask_cache &= ~mask; in irq_gc_mask_disable_reg()
50 * irq_gc_mask_set_bit - Mask chip via setting bit in mask register
53 * Chip has a single mask register. Values of this register are cached
54 * and protected by gc->lock
60 u32 mask = d->mask; in irq_gc_mask_set_bit()
62 guard(raw_spinlock)(&gc->lock); in irq_gc_mask_set_bit()
63 *ct->mask_cache |= mask; in irq_gc_mask_set_bit()
64 irq_reg_writel(gc, *ct->mask_cache, ct->regs.mask); in irq_gc_mask_set_bit()
69 * irq_gc_mask_clr_bit - Mask chip via clearing bit in mask register
72 * Chip has a single mask register. Values of this register are cached
73 * and protected by gc->lock
79 u32 mask = d->mask; in irq_gc_mask_clr_bit()
81 guard(raw_spinlock)(&gc->lock); in irq_gc_mask_clr_bit()
82 *ct->mask_cache &= ~mask; in irq_gc_mask_clr_bit()
83 irq_reg_writel(gc, *ct->mask_cache, ct->regs.mask); in irq_gc_mask_clr_bit()
88 * irq_gc_unmask_enable_reg - Unmask chip via enable register
91 * Chip has separate enable/disable registers instead of a single mask
98 u32 mask = d->mask; in irq_gc_unmask_enable_reg()
100 guard(raw_spinlock)(&gc->lock); in irq_gc_unmask_enable_reg()
101 irq_reg_writel(gc, mask, ct->regs.enable); in irq_gc_unmask_enable_reg()
102 *ct->mask_cache |= mask; in irq_gc_unmask_enable_reg()
107 * irq_gc_ack_set_bit - Ack pending interrupt via setting bit
114 u32 mask = d->mask; in irq_gc_ack_set_bit()
116 guard(raw_spinlock)(&gc->lock); in irq_gc_ack_set_bit()
117 irq_reg_writel(gc, mask, ct->regs.ack); in irq_gc_ack_set_bit()
122 * irq_gc_ack_clr_bit - Ack pending interrupt via clearing bit
129 u32 mask = ~d->mask; in irq_gc_ack_clr_bit()
131 guard(raw_spinlock)(&gc->lock); in irq_gc_ack_clr_bit()
132 irq_reg_writel(gc, mask, ct->regs.ack); in irq_gc_ack_clr_bit()
136 * irq_gc_mask_disable_and_ack_set - Mask and ack pending interrupt
151 u32 mask = d->mask; in irq_gc_mask_disable_and_ack_set()
153 guard(raw_spinlock)(&gc->lock); in irq_gc_mask_disable_and_ack_set()
154 irq_reg_writel(gc, mask, ct->regs.disable); in irq_gc_mask_disable_and_ack_set()
155 *ct->mask_cache &= ~mask; in irq_gc_mask_disable_and_ack_set()
156 irq_reg_writel(gc, mask, ct->regs.ack); in irq_gc_mask_disable_and_ack_set()
161 * irq_gc_eoi - EOI interrupt
168 u32 mask = d->mask; in irq_gc_eoi()
170 guard(raw_spinlock)(&gc->lock); in irq_gc_eoi()
171 irq_reg_writel(gc, mask, ct->regs.eoi); in irq_gc_eoi()
175 * irq_gc_set_wake - Set/clr wake bit for an interrupt
186 u32 mask = d->mask; in irq_gc_set_wake()
188 if (!(mask & gc->wake_enabled)) in irq_gc_set_wake()
189 return -EINVAL; in irq_gc_set_wake()
191 guard(raw_spinlock)(&gc->lock); in irq_gc_set_wake()
193 gc->wake_active |= mask; in irq_gc_set_wake()
195 gc->wake_active &= ~mask; in irq_gc_set_wake()
214 struct irq_chip_type *ct = gc->chip_types; in irq_init_generic_chip()
217 raw_spin_lock_init(&gc->lock); in irq_init_generic_chip()
218 gc->num_ct = num_ct; in irq_init_generic_chip()
219 gc->irq_base = irq_base; in irq_init_generic_chip()
220 gc->reg_base = reg_base; in irq_init_generic_chip()
222 ct[i].chip.name = name; in irq_init_generic_chip()
223 gc->chip_types->handler = handler; in irq_init_generic_chip()
227 * irq_alloc_generic_chip - Allocate a generic chip and initialize it
228 * @name: Name of the irq chip
230 * @irq_base: Interrupt base nr for this chip
232 * @handler: Default flow handler associated with this chip
234 * Returns an initialized irq_chip_generic structure. The chip defaults
255 struct irq_chip_type *ct = gc->chip_types; in irq_gc_init_mask_cache()
256 u32 *mskptr = &gc->mask_cache, mskreg = ct->regs.mask; in irq_gc_init_mask_cache()
259 for (i = 0; i < gc->num_ct; i++) { in irq_gc_init_mask_cache()
271 * irq_domain_alloc_generic_chips - Allocate generic chips for an irq domain
273 * @info: Generic chip information
289 if (d->gc) in irq_domain_alloc_generic_chips()
290 return -EBUSY; in irq_domain_alloc_generic_chips()
292 numchips = DIV_ROUND_UP(d->revmap_size, info->irqs_per_chip); in irq_domain_alloc_generic_chips()
294 return -EINVAL; in irq_domain_alloc_generic_chips()
296 /* Allocate a pointer, generic chip and chiptypes for each chip */ in irq_domain_alloc_generic_chips()
297 gc_sz = struct_size(gc, chip_types, info->num_ct); in irq_domain_alloc_generic_chips()
303 return -ENOMEM; in irq_domain_alloc_generic_chips()
304 dgc->irqs_per_chip = info->irqs_per_chip; in irq_domain_alloc_generic_chips()
305 dgc->num_chips = numchips; in irq_domain_alloc_generic_chips()
306 dgc->irq_flags_to_set = info->irq_flags_to_set; in irq_domain_alloc_generic_chips()
307 dgc->irq_flags_to_clear = info->irq_flags_to_clear; in irq_domain_alloc_generic_chips()
308 dgc->gc_flags = info->gc_flags; in irq_domain_alloc_generic_chips()
309 dgc->exit = info->exit; in irq_domain_alloc_generic_chips()
310 d->gc = dgc; in irq_domain_alloc_generic_chips()
312 /* Calc pointer to the first generic chip */ in irq_domain_alloc_generic_chips()
315 /* Store the pointer to the generic chip */ in irq_domain_alloc_generic_chips()
316 dgc->gc[i] = gc = tmp; in irq_domain_alloc_generic_chips()
317 irq_init_generic_chip(gc, info->name, info->num_ct, in irq_domain_alloc_generic_chips()
318 i * dgc->irqs_per_chip, NULL, in irq_domain_alloc_generic_chips()
319 info->handler); in irq_domain_alloc_generic_chips()
321 gc->domain = d; in irq_domain_alloc_generic_chips()
322 if (dgc->gc_flags & IRQ_GC_BE_IO) { in irq_domain_alloc_generic_chips()
323 gc->reg_readl = &irq_readl_be; in irq_domain_alloc_generic_chips()
324 gc->reg_writel = &irq_writel_be; in irq_domain_alloc_generic_chips()
327 if (info->init) { in irq_domain_alloc_generic_chips()
328 ret = info->init(gc); in irq_domain_alloc_generic_chips()
334 list_add_tail(&gc->list, &gc_list); in irq_domain_alloc_generic_chips()
335 /* Calc pointer to the next generic chip */ in irq_domain_alloc_generic_chips()
341 while (i--) { in irq_domain_alloc_generic_chips()
342 if (dgc->exit) in irq_domain_alloc_generic_chips()
343 dgc->exit(dgc->gc[i]); in irq_domain_alloc_generic_chips()
344 irq_remove_generic_chip(dgc->gc[i], ~0U, 0, 0); in irq_domain_alloc_generic_chips()
346 d->gc = NULL; in irq_domain_alloc_generic_chips()
353 * irq_domain_remove_generic_chips - Remove generic chips from an irq domain
358 struct irq_domain_chip_generic *dgc = d->gc; in irq_domain_remove_generic_chips()
364 for (i = 0; i < dgc->num_chips; i++) { in irq_domain_remove_generic_chips()
365 if (dgc->exit) in irq_domain_remove_generic_chips()
366 dgc->exit(dgc->gc[i]); in irq_domain_remove_generic_chips()
367 irq_remove_generic_chip(dgc->gc[i], ~0U, 0, 0); in irq_domain_remove_generic_chips()
369 d->gc = NULL; in irq_domain_remove_generic_chips()
375 * __irq_alloc_domain_generic_chips - Allocate generic chips for an irq domain
377 * @irqs_per_chip: Number of interrupts each chip handles (max 32)
379 * @name: Name of the irq chip
383 * @gcflags: Generic chip specific setup flags
408 struct irq_domain_chip_generic *dgc = d->gc; in __irq_get_domain_generic_chip()
412 return ERR_PTR(-ENODEV); in __irq_get_domain_generic_chip()
413 idx = hw_irq / dgc->irqs_per_chip; in __irq_get_domain_generic_chip()
414 if (idx >= dgc->num_chips) in __irq_get_domain_generic_chip()
415 return ERR_PTR(-EINVAL); in __irq_get_domain_generic_chip()
416 return dgc->gc[idx]; in __irq_get_domain_generic_chip()
420 * irq_get_domain_generic_chip - Get a pointer to the generic chip of a hw_irq
434 * Separate lockdep classes for interrupt chip which can nest irq_desc
441 * irq_map_generic_chip - Map a generic chip for an irq domain
447 struct irq_domain_chip_generic *dgc = d->gc; in irq_map_generic_chip()
450 struct irq_chip *chip; in irq_map_generic_chip() local
457 idx = hw_irq % dgc->irqs_per_chip; in irq_map_generic_chip()
459 if (test_bit(idx, &gc->unused)) in irq_map_generic_chip()
460 return -ENOTSUPP; in irq_map_generic_chip()
462 if (test_bit(idx, &gc->installed)) in irq_map_generic_chip()
463 return -EBUSY; in irq_map_generic_chip()
465 ct = gc->chip_types; in irq_map_generic_chip()
466 chip = &ct->chip; in irq_map_generic_chip()
468 /* We only init the cache for the first mapping of a generic chip */ in irq_map_generic_chip()
469 if (!gc->installed) { in irq_map_generic_chip()
470 guard(raw_spinlock_irqsave)(&gc->lock); in irq_map_generic_chip()
471 irq_gc_init_mask_cache(gc, dgc->gc_flags); in irq_map_generic_chip()
475 set_bit(idx, &gc->installed); in irq_map_generic_chip()
477 if (dgc->gc_flags & IRQ_GC_INIT_NESTED_LOCK) in irq_map_generic_chip()
481 if (chip->irq_calc_mask) in irq_map_generic_chip()
482 chip->irq_calc_mask(data); in irq_map_generic_chip()
484 data->mask = 1 << idx; in irq_map_generic_chip()
486 irq_domain_set_info(d, virq, hw_irq, chip, gc, ct->handler, NULL, NULL); in irq_map_generic_chip()
487 irq_modify_status(virq, dgc->irq_flags_to_clear, dgc->irq_flags_to_set); in irq_map_generic_chip()
494 struct irq_domain_chip_generic *dgc = d->gc; in irq_unmap_generic_chip()
495 unsigned int hw_irq = data->hwirq; in irq_unmap_generic_chip()
503 irq_idx = hw_irq % dgc->irqs_per_chip; in irq_unmap_generic_chip()
505 clear_bit(irq_idx, &gc->installed); in irq_unmap_generic_chip()
519 * irq_setup_generic_chip - Setup a range of interrupts with a generic chip
520 * @gc: Generic irq chip holding all data
521 * @msk: Bitmask holding the irqs to initialize relative to gc->irq_base
526 * Set up max. 32 interrupts starting from gc->irq_base. Note, this
534 struct irq_chip_type *ct = gc->chip_types; in irq_setup_generic_chip()
535 struct irq_chip *chip = &ct->chip; in irq_setup_generic_chip() local
539 list_add_tail(&gc->list, &gc_list); in irq_setup_generic_chip()
543 for (i = gc->irq_base; msk; msk >>= 1, i++) { in irq_setup_generic_chip()
554 if (chip->irq_calc_mask) in irq_setup_generic_chip()
555 chip->irq_calc_mask(d); in irq_setup_generic_chip()
557 d->mask = 1 << (i - gc->irq_base); in irq_setup_generic_chip()
559 irq_set_chip_and_handler(i, chip, ct->handler); in irq_setup_generic_chip()
563 gc->irq_cnt = i - gc->irq_base; in irq_setup_generic_chip()
568 * irq_setup_alt_chip - Switch to alternative chip
572 * Only to be called from chip->irq_set_type() callbacks.
577 struct irq_chip_type *ct = gc->chip_types; in irq_setup_alt_chip()
580 for (i = 0; i < gc->num_ct; i++, ct++) { in irq_setup_alt_chip()
581 if (ct->type & type) { in irq_setup_alt_chip()
582 d->chip = &ct->chip; in irq_setup_alt_chip()
583 irq_data_to_desc(d)->handle_irq = ct->handler; in irq_setup_alt_chip()
587 return -EINVAL; in irq_setup_alt_chip()
592 * irq_remove_generic_chip - Remove a chip
593 * @gc: Generic irq chip holding all data
594 * @msk: Bitmask holding the irqs to initialize relative to gc->irq_base
598 * Remove up to 32 interrupts starting from gc->irq_base.
606 list_del(&gc->list); in irq_remove_generic_chip()
617 if (gc->domain) { in irq_remove_generic_chip()
618 virq = irq_find_mapping(gc->domain, gc->irq_base + i); in irq_remove_generic_chip()
622 virq = gc->irq_base + i; in irq_remove_generic_chip()
638 if (!gc->domain) in irq_gc_get_irq_data()
639 return irq_get_irq_data(gc->irq_base); in irq_gc_get_irq_data()
645 if (!gc->installed) in irq_gc_get_irq_data()
648 virq = irq_find_mapping(gc->domain, gc->irq_base + __ffs(gc->installed)); in irq_gc_get_irq_data()
658 struct irq_chip_type *ct = gc->chip_types; in irq_gc_suspend()
660 if (ct->chip.irq_suspend) { in irq_gc_suspend()
664 ct->chip.irq_suspend(data); in irq_gc_suspend()
667 if (gc->suspend) in irq_gc_suspend()
668 gc->suspend(gc); in irq_gc_suspend()
678 struct irq_chip_type *ct = gc->chip_types; in irq_gc_resume()
680 if (gc->resume) in irq_gc_resume()
681 gc->resume(gc); in irq_gc_resume()
683 if (ct->chip.irq_resume) { in irq_gc_resume()
687 ct->chip.irq_resume(data); in irq_gc_resume()
701 struct irq_chip_type *ct = gc->chip_types; in irq_gc_shutdown()
703 if (ct->chip.irq_pm_shutdown) { in irq_gc_shutdown()
707 ct->chip.irq_pm_shutdown(data); in irq_gc_shutdown()