Lines Matching +full:non +full:- +full:interrupt
4 * SPDX-License-Identifier: Apache-2.0
39 * Define this to debug the choices made when allocating the interrupt. This leads to much debugging
40 * output within a critical region, which can lead to weird effects like e.g. the interrupt watchdog
49 /* Typedef for C-callable interrupt handler function */
67 * Interrupt handler table and unhandled interrupt routine. Duplicated
80 esp_rom_printf("Unhandled interrupt %d on cpu %d!\n", (int)arg, esp_cpu_get_core_id()); in default_intr_handler()
111 if (vd->cpu > to_insert->cpu) { in insert_vector_desc()
114 if (vd->cpu == to_insert->cpu && vd->intno >= to_insert->intno) { in insert_vector_desc()
118 vd = vd->next; in insert_vector_desc()
122 to_insert->next = vd; in insert_vector_desc()
125 prev->next = to_insert; in insert_vector_desc()
126 to_insert->next = vd; in insert_vector_desc()
136 if (vd->cpu == cpu && vd->intno == intno) { in find_desc_for_int()
139 vd = vd->next; in find_desc_for_int()
160 newvd->intno = intno; in get_desc_for_int()
161 newvd->cpu = cpu; in get_desc_for_int()
178 if (!(vd->flags & VECDESC_FL_SHARED)) { in find_desc_for_source()
179 if (vd->source == source && cpu == vd->cpu) { in find_desc_for_source()
182 } else if (vd->cpu == cpu) { in find_desc_for_source()
185 struct shared_vector_desc_t *svd = vd->shared_vec_info; in find_desc_for_source()
189 if (svd->source == source) { in find_desc_for_source()
193 svd = svd->next; in find_desc_for_source()
199 vd = vd->next; in find_desc_for_source()
217 return -EINVAL; in esp_intr_mark_shared()
220 return -EINVAL; in esp_intr_mark_shared()
228 return -ENOMEM; in esp_intr_mark_shared()
230 vd->flags = VECDESC_FL_SHARED; in esp_intr_mark_shared()
232 vd->flags |= VECDESC_FL_INIRAM; in esp_intr_mark_shared()
242 return -EINVAL; in esp_intr_reserve()
245 return -EINVAL; in esp_intr_reserve()
253 return -ENOMEM; in esp_intr_reserve()
255 vd->flags = VECDESC_FL_RESERVED; in esp_intr_reserve()
261 /* Returns true if handler for interrupt is not the default unhandled interrupt handler */
273 /* Check if interrupt is not reserved by design */ in is_vect_desc_usable()
274 int x = vd->intno; in is_vect_desc_usable()
283 if (intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_SPECIAL && force == -1) { in is_vect_desc_usable()
284 INTC_LOG("....Unusable: special-purpose int"); in is_vect_desc_usable()
289 /* Check if the interrupt priority is acceptable */ in is_vect_desc_usable()
302 /* check if interrupt is reserved at runtime */ in is_vect_desc_usable()
303 if (vd->flags & VECDESC_FL_RESERVED) { in is_vect_desc_usable()
308 /* Ints can't be both shared and non-shared. */ in is_vect_desc_usable()
309 assert(!((vd->flags & VECDESC_FL_SHARED) && (vd->flags & VECDESC_FL_NONSHARED))); in is_vect_desc_usable()
310 /* check if interrupt already is in use by a non-shared interrupt */ in is_vect_desc_usable()
311 if (vd->flags & VECDESC_FL_NONSHARED) { in is_vect_desc_usable()
312 INTC_LOG("....Unusable: already in (non-shared) use."); in is_vect_desc_usable()
315 /* check shared interrupt flags */ in is_vect_desc_usable()
316 if (vd->flags & VECDESC_FL_SHARED) { in is_vect_desc_usable()
319 bool desc_in_iram_flag = ((vd->flags & VECDESC_FL_INIRAM) != 0); in is_vect_desc_usable()
324 if ((vd->flags & VECDESC_FL_SHARED) && in is_vect_desc_usable()
334 INTC_LOG("...Unusable: int is shared, we need non-shared."); in is_vect_desc_usable()
338 /* Check if interrupt already is allocated by set_interrupt_handler */ in is_vect_desc_usable()
347 * Locate a free interrupt compatible with the flags given.
348 * The 'force' argument can be -1, or 0-31 to force checking a certain interrupt.
354 int best = -1; in get_available_int()
362 /* Level defaults to any low/med interrupt */ in get_available_int()
372 INTC_LOG("%s: existing vd found. intno: %d", __func__, vd->intno); in get_available_int()
373 if (force != -1 && force != vd->intno) { in get_available_int()
375 "existing intno: %d, force: %d", __func__, vd->intno, force); in get_available_int()
379 best = vd->intno; in get_available_int()
383 if (force != -1) { in get_available_int()
394 best = vd->intno; in get_available_int()
428 /* See if int already is used as a shared interrupt. */ in get_available_int()
429 if (vd->flags & VECDESC_FL_SHARED) { in get_available_int()
431 * We can use this already-marked-as-shared interrupt. Count the in get_available_int()
435 struct shared_vector_desc_t *svdesc = vd->shared_vec_info; in get_available_int()
439 svdesc = svdesc->next; in get_available_int()
455 if (best == -1) { in get_available_int()
457 * We haven't found a feasible shared interrupt yet. in get_available_int()
461 * interrupt that qualifies. in get_available_int()
474 * Seems this interrupt is feasible. Select it and break out of the loop in get_available_int()
494 /* Common shared isr handler. Chain-call all ISRs. */
498 struct shared_vector_desc_t *sh_vec = vd->shared_vec_info; in shared_intr_isr()
502 if (!sh_vec->disabled) { in shared_intr_isr()
503 if ((sh_vec->statusreg == NULL) || in shared_intr_isr()
504 (*sh_vec->statusreg & sh_vec->statusmask)) { in shared_intr_isr()
505 sh_vec->isr(sh_vec->arg); in shared_intr_isr()
508 sh_vec = sh_vec->next; in shared_intr_isr()
522 int force = -1; in esp_intr_alloc_intrstatus()
525 /* Shared interrupts should be level-triggered. */ in esp_intr_alloc_intrstatus()
527 return -EINVAL; in esp_intr_alloc_intrstatus()
529 /* You can't set an handler / arg for a non-C-callable interrupt. */ in esp_intr_alloc_intrstatus()
531 return -EINVAL; in esp_intr_alloc_intrstatus()
533 /* Shared ints should have handler and non-processor-local source */ in esp_intr_alloc_intrstatus()
535 return -EINVAL; in esp_intr_alloc_intrstatus()
539 return -EINVAL; in esp_intr_alloc_intrstatus()
542 * If the ISR is marked to be IRAM-resident, the handler must not be in the cached region in esp_intr_alloc_intrstatus()
543 * If we are to allow placing interrupt handlers into the 0x400c0000—0x400c2000 region, in esp_intr_alloc_intrstatus()
544 * we need to make sure the interrupt is connected to the CPU0. in esp_intr_alloc_intrstatus()
549 return -EINVAL; in esp_intr_alloc_intrstatus()
554 * Default to prio 1, 2 or 3 for non-shared interrupts. in esp_intr_alloc_intrstatus()
567 * Check 'special' interrupt sources. These are tied to one specific in esp_intr_alloc_intrstatus()
568 * interrupt, so we have to force get_available_int to only look at that. in esp_intr_alloc_intrstatus()
596 return -ENOMEM; in esp_intr_alloc_intrstatus()
601 /* See if we can find an interrupt that matches the flags. */ in esp_intr_alloc_intrstatus()
604 if (intr == -1) { in esp_intr_alloc_intrstatus()
608 return -ENODEV; in esp_intr_alloc_intrstatus()
616 return -ENOMEM; in esp_intr_alloc_intrstatus()
627 return -ENOMEM; in esp_intr_alloc_intrstatus()
630 sv->statusreg = (uint32_t *)intrstatusreg; in esp_intr_alloc_intrstatus()
631 sv->statusmask = intrstatusmask; in esp_intr_alloc_intrstatus()
632 sv->isr = handler; in esp_intr_alloc_intrstatus()
633 sv->arg = arg; in esp_intr_alloc_intrstatus()
634 sv->next = vd->shared_vec_info; in esp_intr_alloc_intrstatus()
635 sv->source = source; in esp_intr_alloc_intrstatus()
636 sv->disabled = 0; in esp_intr_alloc_intrstatus()
637 vd->shared_vec_info = sv; in esp_intr_alloc_intrstatus()
638 vd->flags |= VECDESC_FL_SHARED; in esp_intr_alloc_intrstatus()
639 /* (Re-)set shared isr handler to new value. */ in esp_intr_alloc_intrstatus()
642 /* Mark as unusable for other interrupt sources. This is ours now! */ in esp_intr_alloc_intrstatus()
643 vd->flags = VECDESC_FL_NONSHARED; in esp_intr_alloc_intrstatus()
650 vd->source = source; in esp_intr_alloc_intrstatus()
653 vd->flags |= VECDESC_FL_INIRAM; in esp_intr_alloc_intrstatus()
656 vd->flags &= ~VECDESC_FL_INIRAM; in esp_intr_alloc_intrstatus()
664 ret->vector_desc = vd; in esp_intr_alloc_intrstatus()
665 ret->shared_vector_desc = vd->shared_vec_info; in esp_intr_alloc_intrstatus()
667 /* Enable int at CPU-level; */ in esp_intr_alloc_intrstatus()
671 * If interrupt has to be started disabled, do that now; ints won't be enabled for in esp_intr_alloc_intrstatus()
679 /* Extract the level from the interrupt passed flags */ in esp_intr_alloc_intrstatus()
711 * As an optimization, we can create a table with the possible interrupt status in esp_intr_alloc()
721 return -EINVAL; in esp_intr_set_in_iram()
723 struct vector_desc_t *vd = handle->vector_desc; in esp_intr_set_in_iram()
725 if (vd->flags & VECDESC_FL_SHARED) { in esp_intr_set_in_iram()
726 return -EINVAL; in esp_intr_set_in_iram()
729 uint32_t mask = (1 << vd->intno); in esp_intr_set_in_iram()
732 vd->flags |= VECDESC_FL_INIRAM; in esp_intr_set_in_iram()
733 non_iram_int_mask[vd->cpu] &= ~mask; in esp_intr_set_in_iram()
735 vd->flags &= ~VECDESC_FL_INIRAM; in esp_intr_set_in_iram()
736 non_iram_int_mask[vd->cpu] |= mask; in esp_intr_set_in_iram()
747 return -EINVAL; in esp_intr_free()
752 if (handle->vector_desc->flags & VECDESC_FL_SHARED) { in esp_intr_free()
754 struct shared_vector_desc_t *svd = handle->vector_desc->shared_vec_info; in esp_intr_free()
759 if (svd == handle->shared_vector_desc) { in esp_intr_free()
762 prevsvd->next = svd->next; in esp_intr_free()
764 handle->vector_desc->shared_vec_info = svd->next; in esp_intr_free()
770 svd = svd->next; in esp_intr_free()
772 /* If nothing left, disable interrupt. */ in esp_intr_free()
773 if (handle->vector_desc->shared_vec_info == NULL) { in esp_intr_free()
781 if ((handle->vector_desc->flags & VECDESC_FL_NONSHARED) || free_shared_vector) { in esp_intr_free()
784 set_interrupt_handler(handle->vector_desc->intno, in esp_intr_free()
786 (void *)((int)handle->vector_desc->intno)); in esp_intr_free()
792 handle->vector_desc->flags &= ~(VECDESC_FL_NONSHARED | in esp_intr_free()
796 non_iram_int_mask[handle->vector_desc->cpu] &= ~(1 << (handle->vector_desc->intno)); in esp_intr_free()
805 return handle->vector_desc->intno; in esp_intr_get_intno()
810 return handle->vector_desc->cpu; in esp_intr_get_cpu()
814 * Interrupt disabling strategy:
815 * If the source is >=0 (meaning a muxed interrupt), we disable it by muxing the interrupt to a
816 * non-connected interrupt. If the source is <0 (meaning an internal, per-cpu interrupt).
822 * Muxing an interrupt source to interrupt 6, 7, 11, 15, 16 or 29
823 * cause the interrupt to effectively be disabled.
830 return -EINVAL; in esp_intr_enable()
835 if (handle->shared_vector_desc) { in esp_intr_enable()
836 handle->shared_vector_desc->disabled = 0; in esp_intr_enable()
837 source = handle->shared_vector_desc->source; in esp_intr_enable()
839 source = handle->vector_desc->source; in esp_intr_enable()
842 /* Disabled using int matrix; re-connect to enable */ in esp_intr_enable()
843 esp_rom_route_intr_matrix(handle->vector_desc->cpu, in esp_intr_enable()
844 source, handle->vector_desc->intno); in esp_intr_enable()
846 /* Re-enable using cpu int ena reg */ in esp_intr_enable()
847 if (handle->vector_desc->cpu != esp_cpu_get_core_id()) { in esp_intr_enable()
849 return -EINVAL; /* Can only enable these ints on this cpu */ in esp_intr_enable()
851 irq_enable(handle->vector_desc->intno); in esp_intr_enable()
860 return -EINVAL; in esp_intr_disable()
866 if (handle->shared_vector_desc) { in esp_intr_disable()
867 handle->shared_vector_desc->disabled = 1; in esp_intr_disable()
868 source = handle->shared_vector_desc->source; in esp_intr_disable()
870 struct shared_vector_desc_t *svd = handle->vector_desc->shared_vec_info; in esp_intr_disable()
874 if (svd->source == source && svd->disabled == 0) { in esp_intr_disable()
878 svd = svd->next; in esp_intr_disable()
881 source = handle->vector_desc->source; in esp_intr_disable()
887 esp_rom_route_intr_matrix(handle->vector_desc->cpu, in esp_intr_disable()
891 /* Disable using per-cpu regs */ in esp_intr_disable()
892 if (handle->vector_desc->cpu != esp_cpu_get_core_id()) { in esp_intr_disable()
894 return -EINVAL; /* Can only enable these ints on this cpu */ in esp_intr_disable()
896 irq_disable(handle->vector_desc->intno); in esp_intr_disable()