summaryrefslogtreecommitdiffstats
path: root/bsps
diff options
context:
space:
mode:
authorChristian Mauderer <christian.mauderer@embedded-brains.de>2024-01-11 15:41:45 +0100
committerChristian Mauderer <christian.mauderer@embedded-brains.de>2024-01-31 09:54:57 +0100
commit529b70c828ea5a981ae576ebc6d3a1b45b3b2ab8 (patch)
treee9dd2bafc39b7dbb515879121f032e1f3039dcc3 /bsps
parentbsps/qoriq: Add MMU regions for PCIe based on fdt (diff)
downloadrtems-529b70c828ea5a981ae576ebc6d3a1b45b3b2ab8.tar.bz2
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.
Diffstat (limited to 'bsps')
-rw-r--r--bsps/powerpc/qoriq/include/bsp/irq.h27
-rw-r--r--bsps/powerpc/qoriq/irq/irq.c56
2 files changed, 83 insertions, 0 deletions
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