From 529b70c828ea5a981ae576ebc6d3a1b45b3b2ab8 Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Thu, 11 Jan 2024 15:41:45 +0100 Subject: bsps/qoriq: Allow setting EIRQ polarity and sense Add a function that allows to set the polarity (active-low / negative edge triggered or active-high / positive edge triggered) and sense (level or edge sensitive) of the external interrupts. --- bsps/powerpc/qoriq/include/bsp/irq.h | 27 +++++++++++++++++ bsps/powerpc/qoriq/irq/irq.c | 56 ++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) (limited to 'bsps') diff --git a/bsps/powerpc/qoriq/include/bsp/irq.h b/bsps/powerpc/qoriq/include/bsp/irq.h index 5719701d02..f197f7ab6e 100644 --- a/bsps/powerpc/qoriq/include/bsp/irq.h +++ b/bsps/powerpc/qoriq/include/bsp/irq.h @@ -279,6 +279,8 @@ extern "C" { #define QORIQ_IRQ_EXT_10 (QORIQ_IRQ_EXT_BASE + 10) #define QORIQ_IRQ_EXT_11 (QORIQ_IRQ_EXT_BASE + 11) +#define QORIQ_IRQ_IS_EXT(vector) \ + ((vector) >= QORIQ_IRQ_EXT_0 && (vector) <= QORIQ_IRQ_EXT_11) /** @} */ /** @@ -429,6 +431,31 @@ rtems_status_code qoriq_pic_msi_map( uint32_t *data ); +typedef enum { + QORIQ_EIRQ_TRIGGER_EDGE_FALLING, + QORIQ_EIRQ_TRIGGER_EDGE_RISING, + QORIQ_EIRQ_TRIGGER_LEVEL_LOW, + QORIQ_EIRQ_TRIGGER_LEVEL_HIGH, +} qoriq_eirq_sense_and_polarity; + +/** + * @brief Change polarity and sense settings of external interrupts. + * + * NOTE: There are only very rare edge cases where you need this function. + * + * @a vector must be the vector number of an external interrupt. + * + * Use @a new_sense_and_polarity to select the new setting. If @a + * old_sense_and_polarity is not NULL, the old value is returned. + * + * @returns RTEMS_SUCCSSSFUL on sucess or other values for invalid settings. + */ +rtems_status_code qoriq_pic_set_sense_and_polarity( + rtems_vector_number vector, + qoriq_eirq_sense_and_polarity new_sense_and_polarity, + qoriq_eirq_sense_and_polarity *old_sense_and_polarity +); + /** @} */ #ifdef __cplusplus diff --git a/bsps/powerpc/qoriq/irq/irq.c b/bsps/powerpc/qoriq/irq/irq.c index 1a650ddc83..8d6afa6c12 100644 --- a/bsps/powerpc/qoriq/irq/irq.c +++ b/bsps/powerpc/qoriq/irq/irq.c @@ -338,6 +338,62 @@ rtems_status_code qoriq_pic_set_priority( return sc; } +rtems_status_code qoriq_pic_set_sense_and_polarity( + rtems_vector_number vector, + qoriq_eirq_sense_and_polarity new_sense_and_polarity, + qoriq_eirq_sense_and_polarity *old_sense_and_polarity +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + uint32_t old_vpr = 0; + volatile qoriq_pic_src_cfg *src_cfg; + rtems_interrupt_lock_context lock_context; + uint32_t new_p_s = 0; + + if (!QORIQ_IRQ_IS_EXT(vector)) { + return RTEMS_UNSATISFIED; + } + + if (new_sense_and_polarity == QORIQ_EIRQ_TRIGGER_EDGE_RISING || + new_sense_and_polarity == QORIQ_EIRQ_TRIGGER_LEVEL_HIGH) { + new_p_s |= VPR_P; + } + + if (new_sense_and_polarity == QORIQ_EIRQ_TRIGGER_LEVEL_HIGH || + new_sense_and_polarity == QORIQ_EIRQ_TRIGGER_LEVEL_LOW) { + new_p_s |= VPR_S; + } + + src_cfg = get_src_cfg(vector); + + rtems_interrupt_lock_acquire(&lock, &lock_context); + old_vpr = src_cfg->vpr; + src_cfg->vpr = (old_vpr & ~(VPR_P | VPR_S)) | new_p_s; + rtems_interrupt_lock_release(&lock, &lock_context); + + if (old_sense_and_polarity != NULL) { + if ((old_vpr & VPR_P) == 0) { + if ((old_vpr & VPR_S) == 0) { + *old_sense_and_polarity = + QORIQ_EIRQ_TRIGGER_EDGE_FALLING; + } else { + *old_sense_and_polarity = + QORIQ_EIRQ_TRIGGER_LEVEL_LOW; + } + } else { + if ((old_vpr & VPR_S) == 0) { + *old_sense_and_polarity = + QORIQ_EIRQ_TRIGGER_EDGE_RISING; + } else { + *old_sense_and_polarity = + QORIQ_EIRQ_TRIGGER_LEVEL_HIGH; + } + } + } + + return sc; +} + rtems_status_code bsp_interrupt_set_affinity( rtems_vector_number vector, const Processor_mask *affinity -- cgit v1.2.3