[PATCH 03/30] leon, ambapp_bus: IRQ affinity for on-chip AMBAPP bus
Daniel Hellstrom
daniel at gaisler.com
Thu Apr 13 19:31:12 UTC 2017
---
c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus.c | 38 +++++++++++++++++++++
.../libbsp/sparc/shared/drvmgr/ambapp_bus_grlib.c | 39 ++++++++++++++++++++++
.../sparc/shared/include/drvmgr/ambapp_bus.h | 4 +++
3 files changed, 81 insertions(+)
diff --git a/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus.c b/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus.c
index c48d12d..c80a2ad 100644
--- a/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus.c
+++ b/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus.c
@@ -54,6 +54,13 @@ int ambapp_bus_freq_get(
unsigned int *freq_hz);
void ambapp_dev_info(struct drvmgr_dev *, void (*print)(void *p, char *str), void *p);
+#ifdef RTEMS_SMP
+int ambapp_int_set_affinity(
+ struct drvmgr_dev *dev,
+ int index,
+ Processor_mask cpus);
+#endif
+
struct drvmgr_bus_ops ambapp_bus_ops =
{
.init =
@@ -69,6 +76,9 @@ struct drvmgr_bus_ops ambapp_bus_ops =
.int_unregister = ambapp_int_unregister,
.int_clear = ambapp_int_clear,
.int_mask = ambapp_int_mask,
+#ifdef RTEMS_SMP
+ .int_set_affinity = ambapp_int_set_affinity,
+#endif
.int_unmask = ambapp_int_unmask,
.get_params = ambapp_get_params,
.get_freq = ambapp_bus_freq_get,
@@ -781,3 +791,31 @@ int ambapp_bus_remove(struct drvmgr_bus *bus)
{
return DRVMGR_OK;
}
+
+#ifdef RTEMS_SMP
+int ambapp_int_set_affinity(
+ struct drvmgr_dev *dev,
+ int index,
+ Processor_mask cpus)
+{
+ struct ambapp_priv *priv;
+ int irq;
+
+ priv = dev->parent->priv;
+
+ /* Get IRQ number from index and device information */
+ irq = ambapp_int_get(dev, index);
+ if (irq < 0)
+ return DRVMGR_EINVAL;
+
+ DBG("Set interrupt affinity on 0x%x for dev 0x%x (IRQ: %d)\n",
+ (unsigned int)dev->parent->dev, (unsigned int)dev, irq);
+
+ if (priv->config->ops->int_set_affinity) {
+ /* Let device override driver default */
+ return priv->config->ops->int_set_affinity(dev, irq, cpus);
+ } else {
+ return DRVMGR_ENOSYS;
+ }
+}
+#endif
diff --git a/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_grlib.c b/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_grlib.c
index b0c47ff..5305527 100644
--- a/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_grlib.c
+++ b/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_grlib.c
@@ -46,6 +46,12 @@ int ambapp_grlib_int_mask(
int ambapp_grlib_int_unmask(
struct drvmgr_dev *dev,
int irq);
+#ifdef RTEMS_SMP
+int ambapp_grlib_int_set_affinity(
+ struct drvmgr_dev *dev,
+ int irq,
+ Processor_mask cpus);
+#endif
int ambapp_grlib_get_params(
struct drvmgr_dev *dev,
struct drvmgr_bus_params *params);
@@ -63,6 +69,9 @@ struct ambapp_ops ambapp_grlib_ops = {
.int_clear = ambapp_grlib_int_clear,
.int_mask = ambapp_grlib_int_mask,
.int_unmask = ambapp_grlib_int_unmask,
+#ifdef RTEMS_SMP
+ .int_set_affinity = ambapp_grlib_int_set_affinity,
+#endif
.get_params = ambapp_grlib_get_params
};
@@ -219,6 +228,36 @@ int ambapp_grlib_int_unmask
return DRVMGR_OK;
}
+#ifdef RTEMS_SMP
+int ambapp_grlib_int_set_affinity
+ (
+ struct drvmgr_dev *dev,
+ int irq,
+ Processor_mask cpus
+ )
+{
+ uint32_t cpu_count = rtems_get_processor_count();
+ uint32_t cpu_index;
+ int enabled_cnt = 0;
+
+ for (cpu_index = 0; cpu_index < cpu_count; cpu_index++) {
+ if (_Processor_mask_Is_set(cpus, cpu_index)) {
+ BSP_Cpu_Unmask_interrupt(irq, cpu_index);
+ enabled_cnt++;
+ }
+ }
+
+ /* Propagate the interrupt to all CPUs */
+ if (enabled_cnt > 1) {
+ LEON_Enable_interrupt_broadcast(irq);
+ } else {
+ LEON_Disable_interrupt_broadcast(irq);
+ }
+
+ return DRVMGR_OK;
+}
+#endif
+
int ambapp_grlib_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
{
/* Leave params->freq_hz untouched for default */
diff --git a/c/src/lib/libbsp/sparc/shared/include/drvmgr/ambapp_bus.h b/c/src/lib/libbsp/sparc/shared/include/drvmgr/ambapp_bus.h
index 1e8dde8..ee4a152 100644
--- a/c/src/lib/libbsp/sparc/shared/include/drvmgr/ambapp_bus.h
+++ b/c/src/lib/libbsp/sparc/shared/include/drvmgr/ambapp_bus.h
@@ -85,6 +85,10 @@ struct ambapp_ops {
int (*int_clear)(struct drvmgr_dev *dev, int index);
int (*int_mask)(struct drvmgr_dev *dev, int index);
int (*int_unmask)(struct drvmgr_dev *dev, int index);
+#ifdef RTEMS_SMP
+ int (*int_set_affinity)(struct drvmgr_dev *dev, int index,
+ Processor_mask cpus);
+#endif
int (*get_params)
(struct drvmgr_dev *, struct drvmgr_bus_params *);
};
--
2.7.4
More information about the devel
mailing list