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

core: native interrupt using DT bindings #218

Closed
wants to merge 2 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions architecture/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
etienne-lms marked this conversation as resolved.
Show resolved Hide resolved
      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
etienne-lms marked this conversation as resolved.
Show resolved Hide resolved
      ``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
etienne-lms marked this conversation as resolved.
Show resolved Hide resolved
      ``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
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it be better with an example in the code where it's implemented?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this snippet illustrate well hiw it's expected to be used.
That said, you're right,n a real example would be better.
I have stm32 candidate drivers but they have not yet moved to this API.
Would you prefer this doc change to wait those are ready?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess it's OK for now, as long as it compiles if copied.

{
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:
Expand Down