leon, ambapp_bus: IRQ affinity for on-chip AMBAPP bus

This commit is contained in:
Daniel Hellstrom
2017-04-07 08:31:48 +02:00
parent 7075fb1134
commit ae203e0d41
3 changed files with 81 additions and 0 deletions

View File

@@ -55,6 +55,13 @@ int ambapp_bus_freq_get(
unsigned int *freq_hz); unsigned int *freq_hz);
void ambapp_dev_info(struct drvmgr_dev *, void (*print)(void *p, char *str), void *p); 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 = struct drvmgr_bus_ops ambapp_bus_ops =
{ {
.init = .init =
@@ -70,6 +77,9 @@ struct drvmgr_bus_ops ambapp_bus_ops =
.int_unregister = ambapp_int_unregister, .int_unregister = ambapp_int_unregister,
.int_clear = ambapp_int_clear, .int_clear = ambapp_int_clear,
.int_mask = ambapp_int_mask, .int_mask = ambapp_int_mask,
#ifdef RTEMS_SMP
.int_set_affinity = ambapp_int_set_affinity,
#endif
.int_unmask = ambapp_int_unmask, .int_unmask = ambapp_int_unmask,
.get_params = ambapp_get_params, .get_params = ambapp_get_params,
.get_freq = ambapp_bus_freq_get, .get_freq = ambapp_bus_freq_get,
@@ -782,3 +792,31 @@ int ambapp_bus_remove(struct drvmgr_bus *bus)
{ {
return DRVMGR_OK; 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

View File

@@ -46,6 +46,12 @@ int ambapp_grlib_int_mask(
int ambapp_grlib_int_unmask( int ambapp_grlib_int_unmask(
struct drvmgr_dev *dev, struct drvmgr_dev *dev,
int irq); 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( int ambapp_grlib_get_params(
struct drvmgr_dev *dev, struct drvmgr_dev *dev,
struct drvmgr_bus_params *params); struct drvmgr_bus_params *params);
@@ -63,6 +69,9 @@ struct ambapp_ops ambapp_grlib_ops = {
.int_clear = ambapp_grlib_int_clear, .int_clear = ambapp_grlib_int_clear,
.int_mask = ambapp_grlib_int_mask, .int_mask = ambapp_grlib_int_mask,
.int_unmask = ambapp_grlib_int_unmask, .int_unmask = ambapp_grlib_int_unmask,
#ifdef RTEMS_SMP
.int_set_affinity = ambapp_grlib_int_set_affinity,
#endif
.get_params = ambapp_grlib_get_params .get_params = ambapp_grlib_get_params
}; };
@@ -219,6 +228,36 @@ int ambapp_grlib_int_unmask
return DRVMGR_OK; 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) int ambapp_grlib_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
{ {
/* Leave params->freq_hz untouched for default */ /* Leave params->freq_hz untouched for default */

View File

@@ -85,6 +85,10 @@ struct ambapp_ops {
int (*int_clear)(struct drvmgr_dev *dev, int index); int (*int_clear)(struct drvmgr_dev *dev, int index);
int (*int_mask)(struct drvmgr_dev *dev, int index); int (*int_mask)(struct drvmgr_dev *dev, int index);
int (*int_unmask)(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) int (*get_params)
(struct drvmgr_dev *, struct drvmgr_bus_params *); (struct drvmgr_dev *, struct drvmgr_bus_params *);
}; };