From 4c44963d06db8c89fe14a8fce6f9a8462d70d6e9 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 11 Oct 2023 10:04:40 +0200 Subject: [PATCH 1/2] core: native interrupt using DT bindings Adds information about the interrupt API functions to consider when using device tree to describe interrupts. Signed-off-by: Etienne Carriere --- architecture/core.rst | 71 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/architecture/core.rst b/architecture/core.rst index 9ae8f49..59cfbae 100644 --- a/architecture/core.rst +++ b/architecture/core.rst @@ -430,6 +430,28 @@ Interrupt consumers main API functions are: - ``interrupt_remove_handler()`` to unregister an interrupt handler function from an interrupt. +When the configuration switch ``CFG_DT`` is enabled, OP-TEE core provides a +way to describe the platform's interrupt topology using Device Tree. +When used, the platform must provide a secure device tree blob +(DTB) which platform and device drivers can use to get references to +interrupt controllers and relative interrupt numbers they consume. +The Main API functions are: + +    - ``dt_register_interrupt_provider()`` to register an interrupt +      controller related to a given node in the Device Tree. This function +      requires, among its arguments, a callback function that is called when +      an interrupt consumer requires a reference to a specific interrupt +      exposed by the controller. The callback function shall be of type +      ``dt_get_itr_func`` and it shall allocate a temporary instance of +      ``struct irq_desc`` to describe the interrupt. This allocation shall +      to done using ``malloc()`` or like (``calloc()``, ``memalign()`` +      etc...) and is automatically freed with ``free()``. + +    - ``dt_get_interrupt()``, ``dt_get_interrupt_by_index()`` and +      ``dt_get_interrupt_by_name()`` to be used by interrupt consumer driver +      to get the reference to the interrupt controller and number it consumes, +      based on the properties found in the consumer Device Tree node. + **Interrupt controller drivers** An interrupt controller instance, named chip (``struct itr_chip``) defines @@ -476,6 +498,10 @@ API function ``interrupt_add_handler()``, ``interrupt_add_handler_with_chip()`` and ``interrupt_alloc_add_handler()`` configure and register a handler function to a given interrupt. +API function ``interrupt_create_handler()`` only registers a handler +function for a given interrupt. It is to be used with dt_get_interrupt() +and friends, where these later are in charge on interrupt configuration. + API function ``interrupt_remove_handler()`` and ``interrupt_remove_free_handler()`` unregister a registered handler. @@ -533,6 +559,51 @@ interrupt occurs: } } +**Using device tree** + +Device drivers can rely on Device Tree to get references to the +interrupt they consume. Refer to the Device Tree documentation +for how to properly define interrupt controller chip devices and reference +interrupts in consumer device nodes. + +The example in the previous section implementing an interrupt consumer driver +could be implemented as below, when the platform uses Device Tree means +to define some platform resources. + +.. code-block:: c + + static TEE_Result foo_probe(const void *fdt, int node, const void *compat) + { + TEE_Result res = TEE_ERROR_GENERIC; + struct itr_handler *itr_handler = NULL; + struct itr_chip *itr_chip = NULL; + size_t itr_num = 0; + + res = dt_get_interrupt(fdt, node, &itr_chip, &itr_num); + if (res) + return res; + + res = interrupt_create_handler(&itr_chip, &itr_num, + foo_it_handler_fn, + &foo_int1_data, + &itr_handler); + if (res) + return res; + + interrupt_enable(itr_chip, it_num); + + (...) + + return TEE_SUCCESS; + + err_disable_release_irq: + interrupt_disable(itr_chip, it_num); + interrupt_remove_free_handler(itr_handler); + + return res; + + } + ---- .. _notifications: From bf660d1a938289de2b5f70bf8de258800ade34fb Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 3 Nov 2023 16:57:11 +0100 Subject: [PATCH 2/2] [review] core: native interrupt using DT bindings Fixes API function names and update dt_get_itr_func type callback function description. Signed-off-by: Etienne Carriere --- architecture/core.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/architecture/core.rst b/architecture/core.rst index 59cfbae..d3658e0 100644 --- a/architecture/core.rst +++ b/architecture/core.rst @@ -437,18 +437,16 @@ When used, the platform must provide a secure device tree blob interrupt controllers and relative interrupt numbers they consume. The Main API functions are: -    - ``dt_register_interrupt_provider()`` to register an interrupt +    - ``interrupt_register_provider()`` to register an interrupt       controller related to a given node in the Device Tree. This function       requires, among its arguments, a callback function that is called when       an interrupt consumer requires a reference to a specific interrupt       exposed by the controller. The callback function shall be of type -      ``dt_get_itr_func`` and it shall allocate a temporary instance of -      ``struct irq_desc`` to describe the interrupt. This allocation shall -      to done using ``malloc()`` or like (``calloc()``, ``memalign()`` -      etc...) and is automatically freed with ``free()``. +      ``itr_dt_get_func`` and, upon succes, it shall fill the provided + instance of ``struct irq_desc`` to describe the interrupt. -    - ``dt_get_interrupt()``, ``dt_get_interrupt_by_index()`` and -      ``dt_get_interrupt_by_name()`` to be used by interrupt consumer driver +    - ``interrupt_dt_get()``, ``interrupt_dt_get_by_index()`` and +      ``interrupt_dt_get_by_name()`` to be used by interrupt consumer driver       to get the reference to the interrupt controller and number it consumes,       based on the properties found in the consumer Device Tree node.