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.
This commit is contained in:
Christian Mauderer
2024-01-11 15:41:45 +01:00
parent c9dda8cda8
commit 529b70c828
2 changed files with 83 additions and 0 deletions

View File

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

View File

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