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

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to