[PATCH 2/3] bsps/qoriq: Allow setting EIRQ polarity and sense

Christian Mauderer christian.mauderer at embedded-brains.de
Tue Jan 23 09:09:00 UTC 2024


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(+)

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
-- 
2.35.3



More information about the devel mailing list