Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: Add interrupt controller API #66505

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

bjarki-andreasen
Copy link
Collaborator

@bjarki-andreasen bjarki-andreasen commented Dec 13, 2023

This PR has now been updated to implement the solution described in this issue #67583

Size comparisons:

                        IRQ             SHARED          DYNAMIC         LVL        LTO
IRQ FLASH           38244 B            39652 B          39648 B     39776 B    34436 B
IRQ RAM              5912 B             5912 B           7848 B      7848 B     7840 B
SYS IRQ FLASH       42276 B            42276 B          42676 B     42676 B    36776 B
SYS IRQ RAM          5912 B             5912 B           6104 B      6104 B     5912 B

(note that no dynamic irq is registered, so LTO optimizes out the dynamic irq list)

Some example output of the generated code :)
Generated handlers:

static inline void __sys_intl_handler_8_5(void)
{
	/*
	 * Interrupt generating device: /soc/peripheral@50000000/clock@5000
	 */
	if (__sys_irq_handler_8_5_75()) {
		return;
	}

	/*
	 * Interrupt generating device: /soc/peripheral@50000000/power@5000
	 */
	if (__sys_irq_handler_8_5_117()) {
		return;
	}

	if (sys_irq_dynamic_handler(1)) {
		return;
	}

	sys_irq_log_spurious_intl(8, 5);

	sys_irq_spurious_handler();
}

Generated IRQ enumerations:

/*
 * Interrupt controller: /soc/interrupt-controller@e000e100
 * Interrupt line: 3
 * Interrupt generating device: /soc/spu@50003000
 */
#define SYS_DT_IRQN_8_3 0

/*
 * Interrupt controller: /soc/interrupt-controller@e000e100
 * Interrupt line: 5
 * Interrupt generating device: /soc/peripheral@50000000/clock@5000
 * Interrupt generating device: /soc/peripheral@50000000/power@5000
 */
#define SYS_DT_IRQN_8_5 1

A very cool solution I want to note as well is this macro:

INTC_DT_DEFINE_IRQ_VECTOR(node_id)
{
        return 1;
}

which wraps the existing ARCH_ISR_DIRECT_DECLARE(name) macro synthesizing the name of the function to match the weakly defined default vector in the vector table, allowing the existing infrastructure to be used, including ISR_DIRECT_PM()

For arch review

This PR introduces two new requirements:

  • We need to tell the kernel to generate interrupt handlers for devices which don't have status "okay" to:
    • Generate interrupt handlers for reserved devices, like RTCs reserved for sys tick or other SoC specific features
    • Generate interrupt handlers for devices, but not enable a driver for unit testing.
  • Interrupt handlers need to signal whether they handled an IRQ or not in case of:
    • Shared IRQs to inform the kernel when we can stop walking IRQ handlers
    • Shared and normal IRQs, to allow the kernel to detect spurious interrupts

To generate interrupt handlers, but exclude device drivers, the status "reserved" is used to mean "supported by kernel, don't include a driver for it".

IRQ handlers will signal whether they handled the IRQ or not by returning 1 if handled, 0 if not handled.

Analyzing code

INTC_DT_DEFINE_IRQ_VECTOR with and without LTO

mov     r0, sp
bic.w   r1, r0, #7
mov     sp, r1
push    {r0, lr}
ldr     r0, [pc, #16]
bl      0x2b00 <k_sem_give> /* first call in direct isr body (irq handler) */

SYS_DT_DEFINE_IRQ_HANDLER without LTO

mov     r0, sp
bic.w   r1, r0, #7
mov     sp, r1
push    {r0, lr}
bl      75c <__sys_irq_handler_7_20_107>
push    {r0, r1, r2, lr}
ldr     r3, [pc, #32]   ; (780 <__sys_irq_handler_7_20_107+0x24>)
ldr     r2, [pc, #32]   ; (784 <__sys_irq_handler_7_20_107+0x28>)
str     r3, [sp, #4]
ldr     r3, [pc, #32]   ; (788 <__sys_irq_handler_7_20_107+0x2c>)
ldr     r1, [pc, #36]   ; (78c <__sys_irq_handler_7_20_107+0x30>)
str     r3, [sp, #0]
movs    r0, #1
movs    r3, #34 ; 0x22
bl      158 <z_zassert.constprop.0>

SYS_DT_DEFINE_IRQ_HANDLER with LTO

mov     r0, sp
bic.w   r1, r0, #7
mov     sp, r1
push    {r0, lr}
ldr     r3, [pc, #40]   ; (3f14 <__intc_vector_7_20+0x34>)
sub     sp, #8
str     r3, [sp, #4]
ldr     r3, [pc, #36]   ; (3f18 <__intc_vector_7_20+0x38>)
ldr     r2, [pc, #40]   ; (3f1c <__intc_vector_7_20+0x3c>)
ldr     r1, [pc, #40]   ; (3f20 <__intc_vector_7_20+0x40>)
str     r3, [sp, #0]
movs    r0, #1
movs    r3, #34 ; 0x22
bl      581c <z_zassert.constprop.0>

ISR_DIRECT_DECLARE without LTO

mov     r0, sp
bic.w   r1, r0, #7
mov     sp, r1
push    {r0, lr}
ldr     r0, [pc, #16]   ; (1d0 <CONFIG_SRAM_SIZE+0x10>)
bl      4810 <z_impl_k_sem_give>

ISR_CONNECT with and without LTO

push    {r3, lr}
mrs     r3, IPSR
ldr     r2, [pc, #24]   ; (1500 <_isr_wrapper+0x20>)
subs    r3, #16
add.w   r1, r2, r3, lsl #3
ldr.w   r0, [r2, r3, lsl #3]
ldr     r1, [r1, #4]
blx     r1

@carlescufi
Copy link
Member

carlescufi commented Dec 19, 2023

Arch WG meeting:

  • @bjarki-trackunit presents the proposal
  • @carlescufi asks if the current irq_enable()-like APIs will be completely replaced by intc_ ones. @bjarki-trackunit answers that yes, they will
  • @gmarull asks if the compile-time checks will remain. @bjarki-trackunit says yes, with the help of the single-linked list
  • @carlescufi mentions direct ISRs and the current interrupt model with the software ISR table
  • @nashif mentions that the IRQ code needs to be available very early on (even pre-C)
  • @gmarull asks about the Devicetree layout. One of the issues is about GPIO being both a GPIO controller and an interrupt controller. @bjarki-trackunit explains how he's solved it
  • @carlescufi mentions the work by @rakons to enable LTO: LTO-compatible ISRs #66392

Copy link
Contributor

@andyross andyross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So... I don't hate the API, it's clean and reasonable (though it's also wordy, requiring three steps to do what a single IRQ_CONNECT() does right now).

But this seems like only about 1/3 of the solution. This is all about the user/driver/subsystem-facing API. But the API we have for that is really... not so bad right now. What's the story for why we want to merge this? What can we do with it that we can't right now?

The problems with our interrupt layer (and it has problems!) are on the other side:

  • There's no management of interrupt controller cascade by the framework. Every platform needs to write its own glue to call child interrupt controller handlers out of their parents, even though the structure of that tree is known at build time by devicetree. This PR seems targetted at only NVIC platforms without a secondary controller, meaning that it's really not seeing the mess we're currently living with.

  • The interrupt ID/number/index/offset management (i.e. the mapping between a given device interrupt and the index into the _sw_isr_table[] array) is likewise ad-hoc and platform dependent, and is generally implemented with a bunch of crazy magic numbers stored in kconfig. And again, a clean mapping could be trivially derived from the graph of controllers known to DTS.

Also, it's worth pointing out that this scheme is throwing out efficiency features we've had for a long time: Interrupts are 100% runtime now, you have to write and call C code to get an interrupt registered, spending bytes on code that has to execute and RAM on data structures that have to be mutated. Some platforms even today are still RAM-constrained and would like their ISR tables in pre-built flash. Maybe we don't care about apps like that anymore, it's an argument worth having. But we should be clear about what we're walking away from.

tl;dr: I guess my feeling is that if we're going to rewrite interrupt handling, we should sharpen the machetes and do it all, for everyone.

#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
#define IRQ_TYPE_LEVEL_HIGH (1U << 2)
#define IRQ_TYPE_LEVEL_LOW (1U << 3)
#define IRQ_TYPE_MASK (IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: use BIT() instead of manual shifts if you must have these be bitwise.

But I think having this be a simple integer enumerant (though not an enum, as this is DTS code) is probably better, the trickery with BOTH doesn't strike me as having much value vs. just testing for RISING/FALLING separately. In almost all cases code (especially devicetree code!) doesn't actually do runtime inspection of interrupt types anyway, it just sets the value and assumes the driver does it right.

* @note Identical to INTC_DT_GET_IRQ_SPEC_BY_NAME() if IRQ exists
* @see INTC_DT_GET_IRQ_SPEC_BY_NAME()
*/
#define INTC_DT_GET_OPT_IRQ_SPEC_BY_NAME(node_id, name) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having a hard time understanding the need for this API? Generally with static data like devicetree you either know or don't know if a node exists, which you can already test in the consumer's C code with more readable constructs like "#if". Or maybe you have an array of things and want a FOR_EACH enumerator. What's the situation where we have a device and a name for an interrupt that... might not exist?

Copy link
Collaborator Author

@bjarki-andreasen bjarki-andreasen Jan 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bus attached devices like sensors and RTCs are the rational for this API. Sensors often have 2-3 GPIO routed optional APIs, and there may be more than one instance of them, making IS_ENABLED and similar quite complex. See

#define LIS2DH_CFG_INT(inst) \
.gpio_drdy = \
COND_CODE_1(ANYM_ON_INT1(inst), \
({.port = NULL, .pin = 0, .dt_flags = 0}), \
(GPIO_DT_SPEC_INST_GET_BY_IDX_COND(inst, irq_gpios, 0))), \
.gpio_int = \
COND_CODE_1(ANYM_ON_INT1(inst), \
(GPIO_DT_SPEC_INST_GET_BY_IDX_COND(inst, irq_gpios, 0)), \
(GPIO_DT_SPEC_INST_GET_BY_IDX_COND(inst, irq_gpios, 1))), \
.int1_mode = DT_INST_PROP(inst, int1_gpio_config), \
.int2_mode = DT_INST_PROP(inst, int2_gpio_config),
#else
for example (and note that the API in this PR is intended to replace the interrupt part of the GPIO API)


/** Interrupt controller API structure */
struct intc_driver_api {
intc_api_request_irq request_irq;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't generally pass callback pointers as typed data. Putting the types into the api struct directly instead of typedefing them all would save a bunch of lines of code. Surely those typedefs aren't actually used anywhere else?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it looks good, it may be more lines, but every API in the struct does not have to be split into multiple lines :)

/** @cond INTERNAL_HIDDEN */

/** Interrupt request specification */
struct intc_irq_spec {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, API-wise, this is eliminating the old-style "interrupt number" scheme that our API has exposed, where there was a single integer for each registrable interrupt. That was a simpler API for users. This one is more complicated.

But it was also a simpler API for the backend, where that ID became an index into a big table of function pointers. I don't see how interpreting this thing in the interrupt entry path (literally the hottest of hot paths!) is anything but a loss? Or is the global index secretly stored somewhere else?

Copy link
Collaborator Author

@bjarki-andreasen bjarki-andreasen Jan 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue with the old-style number is that while being simple, it is lacking vital information, namely which interrupt controller the interrupt belongs to. The old style number is therefore only reflective of the devicetree, allowing DT_IRQN to return the correct IRQ number, if there is only one interrupt controller, at which point the instance can be omitted, and the API can just be static (as it is now).

An interrupt number is the interrupt line number of a specific interrupt controller. To clearly visualize the issue, consider how you would rewrite the GPIO API to only use an integer for the pin number, that also has to work with bus attached IO expanders (implementing the GPIO API)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is lacking vital information

It's not. Or rather it doesn't have to be. The controller is extractable if you know how the table is packed, which right now requires interpreting a bunch of kconfig values storing sizes and offets, and it's a mess. Which is why I'd like to see it reworked.

But that's not an indictment of using an integer. We can totally continue to use integers to identify interrupts. And (implemented correctly) integers have some excellent efficiency benefits which would be good to preserve.

(Also, just to repeat: this API requires a separate step to construct and extract that spec struct, vs. just using a by-value macro like DT_IRQN(). That right off the bat makes this a worse API, not a better one. It's not a critical problem, but it's still a cost we're paying for exposing the spec abstraction to the user)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you see the parallel I'm drawing between the GPIO API and the IRQ API? We have no problem pairing a GPIO controller to a pin and passing this to the GPIO API (in fact, its rather simple and elegant IMO), why treat IRQs differently?

/** Interrupt request priority */
uint16_t priority;
/** Interrupt request flags */
uint32_t flags;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're using restricted types for irq and priority but giving a whole word to flags? My suggestion would be to bit-pack these into a single word, maybe even encode the intc as a small integer index (since those will always be DTS-defined and known at build time).

But also note that this isn't sufficient in all cases anyway, in partcular x86 MSI has a very different model for how to target an interrupt. That's not a blocker (MSI is just weird and probably will always be special-cased), but is an argument for maybe not overdesigning.

Copy link
Collaborator Author

@bjarki-andreasen bjarki-andreasen Jan 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the priority and irq number are integers, which will probably never exceed an 65365, but do exceed 255, where the flags is a bitfield, so it should be as large as we can provide :)

That said, I may update flags to be a size_t, but it does seem MSI fields can fit inside a uint32 https://i.stack.imgur.com/RwenJ.jpg

Copy link
Collaborator

@tbursztyka tbursztyka Jul 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this is fine for MSI.

Anyway, the implementation of MSI/MSI-X is currently very much arch specific, that is: x86 specific. So there won't be any collision with such generic intc API.

It could change someday, since interrupt management implementation in x86 is messy to say the least (you always need to allocate an irq to get a vector for instance, that does not make much sense in case of MSI-X or multi-vector MSI).

@bjarki-andreasen Ask x86 maintainers if they would be willing to redo-x86 interrupt management, then it could affect your API for MSI multi-vector and MSI-X since these play with vectors and not irq. MSI/MSI-X interrupt management would need to be reworked as well then (from an API point of view I mean).


/** Interrupt request handle */
struct intc_irq {
/** Interrupt request single-linked list node */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A dynamic list pointer here tells me this probably doesn't go in a simple table of function pointers anymore?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it doesn't go anywhere? I can't find code that uses this. Is this a forgotten attempt to implement shared interrupts? As of right now it doesn't seem to work?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its supposed to be used for shared IRQs, and for secondary interrupt controllers like GPIOs, which usually only store a few IRQs relative to how many pins they have.

if (irq != NULL) { \
irq->handler(irq); \
} else { \
while (1) { \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not understanding this at all. Presumably you get here on a spurious interrupt? We have an existing spurious interrupt handler API the arch layers all honor, as that's a pretty routine glitch during device bringup (e.g. "oops typo in the interrupt number", or "oops, the bootloader left the UART RX interrupt enabled" -- absolutely routine things). Entering a silent infinite loop seems like exactly the wrong thing to do.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a reason this PR is a draft :D The driver I added here is very naive and only to test the viability of the API, it is not an optimal driver

@andyross
Copy link
Contributor

andyross commented Jan 9, 2024

Looks like the bot didn't assign reviewers, maybe because it's a draft? For sure @dcpleung @peter-mitsis @carlocaione @npitre want to get in on this. @tbursztyka should expand my note about MSI. Lots of platform folks will have important input too, especially ones who've had to deal with cascaded controllers.

@bjarki-andreasen
Copy link
Collaborator Author

bjarki-andreasen commented Jan 10, 2024

@andyross This API aims to solve points 1. and 2. while adding support for "secondary" interrupt controllers, like GPIO ports and other IO expanders which can route interrupts through IO pins.

  1. Interrupt cascading
    This API specifies every IRQ as an interrupt line of a specific interrupt controller, like a GPIO pin is a pin of a specific GPIO port. This reflects the devicetree (hardware) layout completely, as opposed to the current "absolute" ISR table, which tries to flatten the layout into a single list, which has spawned the need for encoding the IRQ number in levels.

  2. IRQ encoding
    This solution does not require IRQ encoding, as each IRQ number is relative to an the IRQs interrupt parent. Each parent manages its own list of IRQs in whicever way is most efficient. There is no absolute ISR table using this API, there can be as many tables as there are interrupt controllers, some interrupt controllers (like GPIOs) may simply store the few IRQs they manage in a single linked list to save memory as they do now.

  3. Efficiency
    This solution does remove the possibility of storing the SW IRQ table in ROM, but it can be quite a bit more efficient at storing IRQs, given that GPIOs may store their IRQs in single linked lists as they do now rather than an array of however many pins they have, for a chip with 4 ports of 32 pins, that'quite a bit. For really ressource constrained devices, direct IRQs can be used, without the need for creating a SW IRQ table. Direct IRQs can be created for every interrupt controller at any level with this API, including a GPIO pin :)

@andyross andyross mentioned this pull request Jan 10, 2024
6 tasks
@bjarki-andreasen bjarki-andreasen marked this pull request as ready for review January 11, 2024 06:21
@zephyrbot zephyrbot requested a review from 57300 January 11, 2024 06:21
zephyr_library()

zephyr_library_sources(arm_v8m_nvic.c)
zephyr_linker_sources(ROM_START SORT_KEY 0x0vectors irq-vector-table.ld)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this be an issue for the CMAKE_LINKER_GENERATOR?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so, I will need to look into making it more generic, it is a bit of a hack currently :)

Copy link

github-actions bot commented Sep 8, 2024

This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time.

@github-actions github-actions bot added the Stale label Sep 8, 2024
@bjarki-andreasen
Copy link
Collaborator Author

Hope to continue this within a couple of weeks

@github-actions github-actions bot removed the Stale label Sep 9, 2024
Add interrupt-lines property to interrupt-controller.yaml

This value will initially be optional, but it is required when
using the new system IRQ subsystem.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
@bjarki-andreasen
Copy link
Collaborator Author

Update

  • Fixed issue with LTO causing spurious interrupts (LTO optimized away entire vector table, fixed with __used attr)
  • Cleaned up sys_irq test suites
  • Rebased on latest main

@bjarki-andreasen
Copy link
Collaborator Author

Update

  • Added test suite for direct IRQs
  • Cleaned up a bit

@bjarki-andreasen
Copy link
Collaborator Author

bjarki-andreasen commented Sep 30, 2024

Update

  • Added INTC_DT_FOREACH_INTL and INTC_DT_FOREACH_IMPL_INTL macros for iterating over interrupt lines by interrupt controller. INTC_DT_FOREACH_INTL iterates over every interrupt line, whether any IRQ is implemented or not, while INTC_DT_FOREACH_IMPL_INTL only iterates over interrupt lines which are implemented (connected to node with status okay or reserved). This allows for drivers to either generate a full vector table, or create a minimal software table which only contains a map with only implemented interrupts. The latter is super useful for gpio controllers which often only have a few GPIOs interrupts implemented.
  • Updated NVIC drivers to use the new foreach macros

bjarki-andreasen and others added 13 commits October 2, 2024 17:47
This commit adds the interface for the system IRQ subsystem,
which is split into three files:
- include/zephyr/sys/irq.h contains the user facing APIs and
  macros, which includes creating interrupt handlers, and
  enabling/configuring/disabling interrupts.
- include/zephyr/sys/irq_handler.h contains the interrupt
  line handlers interrupt controllers will call.
- include/zephyr/sys/internal/irq.h contains internal
  structures required by irq.c

The headers all require snippets generated by the script
gen_sys_irq.py included with this commit. This commit adds a
target and custom command to the top CMakeLists.txt to
ensure snippets are generated if SYS_IRQ=y.

Lastly, the source implementing the APIs provided with the
interface, irq.c, is added.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Add intc.h device driver API header and inital Kconfig,
CMakeLists.txt and driver folder.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Add irq_vector.h interface which wraps the existing
ISR_DIRECT_DECLARE() macro adapting it to the system IRQ schema.

ISR_DIRECT_DECLARE(name)
{}

is wrapped within this macro

INTC_DT_DEFINE_IRQ_VECTOR(node_id)
{}

which uses the node identifier to synthesize the name
of the declared function, strongly defining the weak
default vector in the vector table.

This allows for the existing PM macros, swap return value etc.
to be reused with the system IRQ schema.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
With the system IRQ INTC_DT_DEFINE_IRQ_VECTOR wrapper, the
argument must be unwrapped before being used in the function.

Using UTIL_CAT is therefore required. (it also looks nicer)

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Add arm v8m nvic device driver implementing the new intc.h
device driver API and interfacing with the new system IRQ
subsystem.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Add ARM NVIC V7M device driver

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Add interrupt-lines properties to the nrf5340 cpuapp and cpunet.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Update nrf_rtc_timer.c to use system IRQ. This includes updating
the rtc1 nodes to be reserved rather than disabled.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Update clock_control_nrf.c device driver to use system IRQ

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Update uart_nrfx_uarte.c to use system IRQ

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Update gpio_nrfx.c to use system IRQ

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Add power subsystem and power driver for nrf_power using system IRQ.

TODO: Update nrfxlib to return handled or not, otherwise this or
clock isr will never be called if both are implemented.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Add test suites to validate the sys_irq API, shared IRQs,
dynamic IRQs and direct IRQs.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
@bjarki-andreasen
Copy link
Collaborator Author

Update

  • Quite a bit of cleanup
  • Added macros for getting the number of implemented and connected interrupt lines for each interrupt controller

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Architecture Review Discussion in the Architecture WG required area: Build System area: Devicetree Binding PR modifies or adds a Device Tree binding area: Devicetree area: Interrupt Controller
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

8 participants