The documentation recommends to read and then write-back the entire
register, when ending interrupts.
Signed-off-by: Mateusz Karlic <mkarlic@antmicro.com>
Convert SYS_INIT to DEVICE_DT_INST_DEFINE, this allows the build system
to track the device dependencies and ensure that the interrupt
controller is initialized before other devices using it.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
The init infrastructure, found in `init.h`, is currently used by:
- `SYS_INIT`: to call functions before `main`
- `DEVICE_*`: to initialize devices
They are all sorted according to an initialization level + a priority.
`SYS_INIT` calls are really orthogonal to devices, however, the required
function signature requires a `const struct device *dev` as a first
argument. The only reason for that is because the same init machinery is
used by devices, so we have something like:
```c
struct init_entry {
int (*init)(const struct device *dev);
/* only set by DEVICE_*, otherwise NULL */
const struct device *dev;
}
```
As a result, we end up with such weird/ugly pattern:
```c
static int my_init(const struct device *dev)
{
/* always NULL! add ARG_UNUSED to avoid compiler warning */
ARG_UNUSED(dev);
...
}
```
This is really a result of poor internals isolation. This patch proposes
a to make init entries more flexible so that they can accept sytem
initialization calls like this:
```c
static int my_init(void)
{
...
}
```
This is achieved using a union:
```c
union init_function {
/* for SYS_INIT, used when init_entry.dev == NULL */
int (*sys)(void);
/* for DEVICE*, used when init_entry.dev != NULL */
int (*dev)(const struct device *dev);
};
struct init_entry {
/* stores init function (either for SYS_INIT or DEVICE*)
union init_function init_fn;
/* stores device pointer for DEVICE*, NULL for SYS_INIT. Allows
* to know which union entry to call.
*/
const struct device *dev;
}
```
This solution **does not increase ROM usage**, and allows to offer clean
public APIs for both SYS_INIT and DEVICE*. Note that however, init
machinery keeps a coupling with devices.
**NOTE**: This is a breaking change! All `SYS_INIT` functions will need
to be converted to the new signature. See the script offered in the
following commit.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
init: convert SYS_INIT functions to the new signature
Conversion scripted using scripts/utils/migrate_sys_init.py.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
manifest: update projects for SYS_INIT changes
Update modules with updated SYS_INIT calls:
- hal_ti
- lvgl
- sof
- TraceRecorderSource
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
tests: devicetree: devices: adjust test
Adjust test according to the recently introduced SYS_INIT
infrastructure.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
tests: kernel: threads: adjust SYS_INIT call
Adjust to the new signature: int (*init_fn)(void);
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Replace usage of CONFIG_MP_NUM_CPUS with CONFIG_MP_MAX_NUM_CPUS for
init and declaration as we phase out CONFIG_MP_NUM_CPUS usage.
Signed-off-by: Kumar Gala <kumar.gala@intel.com>
Change for loops of the form:
for (i = 0; i < CONFIG_MP_NUM_CPUS; i++)
...
to
unsigned int num_cpus = arch_num_cpus();
for (i = 0; i < num_cpus; i++)
...
We do the call outside of the for loop so that it only happens once,
rather than on every iteration.
Signed-off-by: Kumar Gala <kumar.gala@intel.com>
The sys* ops like sys_clear_bit are indirectly included via arch CPU
header. Other stuff like find_msb_set end up included via this header as
well.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
In order to bring consistency in-tree, migrate all drivers to the new
prefix <zephyr/...>. Note that the conversion has been scripted, refer
to #45388 for more details.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Refactors interrupt controller drivers to use the shared driver class
initialization priority configuration, CONFIG_INTC_INIT_PRIORITY, to
allow configuring interrupt controller drivers separately from other
devices. This is similar to other driver classes.
The default is set to CONFIG_KERNEL_INIT_PRIORITY_DEFAULT to preserve
the existing default initialization priority for most drivers.
Signed-off-by: Maureen Helm <maureen.helm@intel.com>
For functions returning nothing, there is no need to document
with @return, as Doxgen complains about "documented empty
return type of ...".
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
Change to use macro DT_FOREACH_CHILD_STATUS_OKAY to avoid routing the
interrupts to the disabled cores.
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
We only need to distribute interrupts to CPU Cores with the count
of CONFIG_MP_NUM_CPUS, and get Core's MPID from CPU nodes in dts.
Signed-off-by: Jiafei Pan <Jiafei.Pan@nxp.com>
The GIC interrupt controller driver is using a custom init function
called directly from the prep_c function. For consistency move that to
use SYS_INIT.
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
It is desired to have the peripheral writes completed to clear the
interrupt condition and de-assert the interrupt request to GIC before
EOI write. Failing which spurious interrupt will occur.
A barrier is needed to ensure peripheral register write transfers are
complete before EOI is done.
GICv2 memory mapped DEVICE nGnR(n)E writes are ordered from core point
of view. However these writes may pass over different interconnects,
bridges, buffers leaving some rare chances for the actual write to
complete out of order.
GICv3 ICC EOI system register writes have no ordering against nGnR(n)E
memory writes as they are over different interfaces.
Hence a dsb can ensure from core no writes are issued before the
previous writes are *complete*.
Signed-off-by: Sandeep Tripathy <sandeep.tripathy@broadcom.com>
Add basic driver for GIC V3 interrupt controller.
This implementation supports
- distributor, re-distributor and cpu interface initialization
- configuration and handling of SPI, PPI and SGI.
- V2 Legacy mode is not supported and uses system interface.
Current implementation supports GIC secure state only.
All interrupts are routed to Secure EL1 as 'irq' by configuring
them as Group1 Secure.
TODO:
- MPIDR based affinity routing setting.
- percpu redistributor probe
- message based SPI and SGI generation api
- EL1NS support. Legacy mode support.
- LPI/ITS is not supported.
Signed-off-by: Sandeep Tripathy <sandeep.tripathy@broadcom.com>
Fixing ICFGRn register access with `sys_{read,write}32`
since this register is not byte-accessible.
Type of `val` changed to u32 to match reg width.
Fixes#24339
Supersedes #24422
Signed-off-by: Bartlomiej Flak <flakbartlomiej@gmail.com>
This commit fixes the field definition names for `GICD_ICFGR`, which
were incorrectly prefixed with `GICC_`.
Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
The current Generic Interrupt Controller (GIC) driver makes use of the
multi-level interrupt mechanism and `irq_nextlevel` public interface.
This is a less-than-ideal implementation for the following reasons:
1. The GIC is often used as the main interrupt controller for the
Cortex-A and Cortex-R family SoCs and, in this case, it is not a 2nd
level interrupt controller; in fact, it is the root interrupt
controller and therefore should be treated as such.
2. The only reason for using `irq_nextlevel` here is to interface the
architecture implementation to the interrupt controller functions.
Since there is no nesting or multiple instances of an interrupt
controller involved, there is really no point in adding such an
abstraction.
3. 2nd level topology adds many unnecessary abstractions and results
in strange coding artefacts as well as performance penalty due to
additional branching.
This commit refactors the GIC driver interface as follows:
1. Remove the current GIC driver interface based on the multi-level
interrupt mechanism and the `irq_nextlevel` public interface.
2. Define the GIC driver interface in
`include/drivers/interrupt_controller/gic.h` and allow the arch
implementation to directly invoke this interface.
Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
The current GIC driver implementation only supports the GIC-400, which
implements the GICv2 interface.
This commit refactors the GIC driver to support multiple GIC versions
and adds GICv1 interface support (GICv1 and GICv2 interfaces are very
similar).
Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
Pattern being <domain>_<model>.<c/h>.
Here interrupt_controller as a domain would be far too long so
shortening it to "intc", as DTS does actually.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
The GIC-400 driver currently only supports SPIs because the (32) offset
for the INTIDs is hard-coded in the driver. At the driver level there is
no really difference between PPIs and SPIs so we can easily extend the
driver to support PPIs as well.
This is useful if we want to add support for the ARM Generic Timers that
use INTIDs in the PPI range.
SPI interrupts are in the range [0-987]. PPI interrupts are in the range
[0-15].
This commit adds interrupt 'type' cell to the GIC device tree binding
and changes the 'irq' cell to use interrupt type-specific index, rather
than a linear IRQ number.
The 'type'+'irq (index)' combo is automatically fixed up into a linear
IRQ number by the scripts/dts/gen_defines.py script.
Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
The GIC400 is a common interrupt controller that can be used with the
Cortex A and R series processors. This patch adds basic interrupt
handling for the GIC, but does not handle multiple routing or
priorities.
Signed-off-by: Bradley Bolen <bbolen@lexmark.com>