Difference between revisions of "Interrupt overview"

[quality revision] [quality revision]
m
 


Template:ArticleMainWriter Template:ArticleApprovedVersion


SUMMARY
This article explains stm32mp157 interrupt topology and its management on Linux® environment.

1 Framework purpose[edit]

The Linux® kernel software layer that handles the interrupts is splitted into two parts:"

  • A generic part:
    • providing a common API to request and configure an interrupt line.
    • creating a virtual mapping for all interrupts in order to have only one ID per interrupt.
    • providing callback for irqchip registering.
  • An irqchip driver part:
    • handling hardware accesses and managing specific features.

For more information refer to Linux® kernel documentation in core-api/genericirq.html[1].

2 STM32 interrupt topology[edit]

As explain in Framework purpose, the irqchip driver makes the interface with the hardware to configure and manage an interrupt. On STM32MP1 devices, a hardware interrupt can be generated by GIC, EXTI, PWR or GPIO. Several irqchip drivers are consequently required, one per hardware block.

The next section provides topology information for each kind of interrupt source.

2.1 Overview[edit]

Interrupts overview.png

2.2 Component description[edit]

  • procfs: provides interrupt information to the user space.
  • foo_driver: device driver requesting an interrupt line.
  • interrupt framework: generic part described in the Framework purpose section.
  • Irqchips:
    • GIC irqchip: GIC irqchip driver part. This irqchip driver is used when a GIC interrupt is directly requested by a device. This is the case for all the peripheral interrupts that are not wakeup sources. This irqchip is in charge of controlling the GIC internal peripheral (hardware). An example of GIG irqchip usage is available here.
    • EXTI irqchip: EXTI irqchip driver part. This irqchip driver is used when an EXTI interrupt (EXTernal Interrupt) is requested by a device. This kind of interrupts is used to wake up the system from low-power mode. This irqchip directly controls the EXTI internal peripheral but it is also linked to the gic irqchip through the hierarchical irq domain mechanism[2]. This link is transparent for the requester.
    • EXTI_pwr irqchip: EXTI_pwr irqchip driver part. This irqchip driver is used when an EXTI interrupt mapped to a wakeup pin is requested by a device. This kind of interrupts is used to wake up the system from the deepest low-power mode (more details about low-power modes are available here). This irqchip directly controls the EXTI internal peripheral but it is also linked to the pwr irqchip through the hierarchical irq domain mechanism[2]. The pwr irqchip in turn controls the PWR internal peripheral and it is also linked to the gic irqchip through the same hierarchical irq domain mechanism[2]. These hierarchical links are transparent for the requester.
    • Pinctrl irqchip: Pinctrl irqchip driver part. This irqchip driver is used when a device wants to configure/request a GPIO as an interrupt. It directly controls the GPIO internal peripheral but it is also linked to the EXTI irqchip through the hierarchical irq domain mechanism[2]. This link is transparent for the requester.
  • STM32 hardware peripherals: GIC, EXTI, PWR, GPIO

3 API description[edit]

The kernel space API is the interface for declaring and managing interrupts. The user space interface is used to monitor interrupt information or set interrupt affinity.

3.1 User space API[edit]

procfs performs the following tasks:

  • It provides information about interrupts such as the virtual number, the hardware ID and the irqchip used (see chapter 1.2 Kernel data of /proc kernel documentation[3]).
root@stm32mp1:~# cat /proc/interrupts 
           CPU0       CPU1       
 17:          0          0     GIC-0  37 Level     rcc irq
 20:    7509664    7509640     GIC-0  27 Level     arch_timer
 22:          0          0     GIC-0 232 Level     arm-pmu
 23:          0          0     GIC-0 233 Level     arm-pmu
 24:          0          0     GIC-0  68 Level     4000b000.audio-controller
 26:          0          0  stm32-exti-h  27 Edge      4000e000.serial:wakeup
 27:       8915          0     GIC-0  84 Level     40010000.serial
 28:          0          0  stm32-exti-h  30 Edge      40010000.serial:wakeup
 29:        654          0     GIC-0  63 Level     40012000.i2c
 30:          0          0     GIC-0  64 Level     40012000.i2c
 31:          0          0  stm32-exti-h  21 Edge      40012000.i2c:wakeup
 33:          0          0     GIC-0 123 Level     4400b004.audio-controller, 4400b024.audio-controller
...
  • It configures interrupt affinity[4], that is assigns an interrupt to a dedicated CPU.

3.2 Kernel space API[edit]

The main kernel API drivers for users are the following:

  • devm_request_irq: requests an interrupt.
  • devm_free_irq: frees an interrupt.
  • enable_irq: enables a requested interrupt.
  • disable_irq: disables a requested interrupt.
  • enable_irq_wake: enables a requested interrupt that could wake up the system.
  • disable_irq_wake: disables a requested interrupt that could wake up the system.

... The available routines can be found in Linux® kernel header file: include/linux/interrupt.h[5].

4 Configuration[edit]

4.1 Kernel configuration[edit]

The interrupt framework and irqchip drivers are enabled by default.

4.2 Device tree configuration[edit]

The generic way to declare an interrupt in the device tree is declared in Linux® kernel documentation in: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt [6].

However each irqchip driver has his own bindings description. The below chapters provide the link to the bindings documentation for each interrupt controller as well as a simple example of interrupt declaration.

4.2.1 GIC irqchip[edit]

  • Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt [7]
  • Device tree usage:
&foo_node {
        ...
	interrupts = <&intc GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
	interrupt-names = "foo_name";
	...
};

4.2.2 EXTI irqchip[edit]

  • Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt [8]
  • Device tree usage:
&foo_node {
        ...
	interrupts-extended = <&exti 26 IRQ_TYPE_EDGE_RISING>,
	interrupt-names = "foo_name";
	...
};

4.2.3 EXTI_PWR irqchip[edit]

  • Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt [8]
  • Device tree usage:
&foo_node {
        ...
	interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>,
	interrupt-names = "foo_name";
	...
};

4.2.4 pinctrl irqchip[edit]

  • Device tree usage:
&foo_node {
        ...
	interrupts-extended = <&gpioa 14 IRQ_TYPE_EDGE_FALLING>,
	interrupt-names = "foo_name";
	...
};

4.2.5 pwr irqchip[edit]

Pwr irqchip has not to be used directly. User has to use exti_pwr to invoke pwr irqchip thanks to the hierarchical implementation.

5 References[edit]

<noinclude>

{{ArticleBasedOnModel|[[Framework overview article model]]}}
{{ArticleMainWriter|AlexandreT}}
{{ ArticleApprovedVersion| AlexandreT| LudovicB, LoicP | No previous approved version | AnneJ - 21Jan'19 - 10414 | 18Jan'19 }} 

[[Category:Interrupts|0]]</noinclude>


'''SUMMARY'''<br>
This article explains stm32mp157 interrupt topology and its management on Linux<sup>&reg;</sup> environment.

==Framework purpose==
The Linux<sup>&reg;</sup> kernel software layer that handles the interrupts is splitted into two parts:"

*A generic part:
**providing a common API to request and configure an interrupt line.
**creating a virtual mapping for all interrupts in order to have only one ID per interrupt.
**providing callback for irqchip registering.
*An irqchip driver part:
**handling hardware accesses and managing specific features.

For more information refer to Linux<sup>&reg;</sup> kernel documentation in ''core-api/genericirq.html''<ref>[https://www.kernel.org/doc/html/latest/core-api/genericirq.html https://www.kernel.org/doc/html/latest/core-api/genericirq.html(master)], Generic IRQ documentation</ref>.

==STM32 interrupt topology==
As explain in [[Interrupt_overview#Framework_purpose | Framework purpose]], the irqchip driver makes the interface with the hardware to configure and manage an interrupt. On STM32MP1 devices, a hardware interrupt can be generated by GIC, EXTI, PWR or GPIO. Several irqchip drivers are consequently required, one per hardware block. 

The next section provides topology information for each kind of interrupt source. 

=== Overview ===

[[File:Interrupts_overview.png]]

===Component description===
*'''procfs:''' provides interrupt information to the user space.
*'''foo_driver:''' device driver requesting an interrupt line.
*'''interrupt framework:''' generic part described in the [[Interrupt_overview#Framework_purpose | Framework purpose]] section.
*'''Irqchips:'''
**'''GIC irqchip:''' GIC irqchip driver part. This irqchip driver is used when a GIC interrupt is directly requested by a device. This is the case for all the peripheral interrupts that are not wakeup sources. This irqchip is in charge of controlling the [[GIC_internal_peripheral | GIC]] internal peripheral (hardware). An example of GIG irqchip usage is available  [[Interrupt_overview#GIC_irqchip | here]]. 
**'''EXTI irqchip:''' EXTI irqchip driver part. This irqchip driver is used when an EXTI interrupt (EXTernal Interrupt) is requested by a device. This kind of interrupts is used to wake up the system from [[Power_overview | low-power mode]]. This irqchip directly controls the [[EXTI_internal_peripheral | EXTI]] internal peripheral but it is also linked to the '''gic irqchip''' through the hierarchical irq domain mechanism<ref name="irq_hierarchic">[https://www.kernel.org/doc/Documentation/IRQ-domain.txt  https://www.kernel.org/doc/Documentation/IRQ-domain.txt(master)], IRQ domain documentation</ref>. This link is transparent for the requester.
**'''EXTI_pwr irqchip:''' EXTI_pwr irqchip driver part. This irqchip driver is used when an EXTI interrupt mapped to a wakeup pin is requested by a device. This kind of interrupts is used to wake up the system from the deepest low-power mode (more details about low-power modes are available [[Power_overview | here]]). This irqchip directly controls the [[EXTI_internal_peripheral | EXTI]] internal peripheral but it is also linked to the '''pwr irqchip''' through the hierarchical irq domain mechanism<ref name="irq_hierarchic" />. The '''pwr irqchip''' in turn controls the [[PWR_internal_peripheral | PWR]] internal peripheral and it is also linked to the '''gic irqchip''' through the same hierarchical irq domain mechanism<ref name="irq_hierarchic" />. These hierarchical links are transparent for the requester.  
**''' Pinctrl irqchip:''' Pinctrl irqchip driver part. This irqchip driver is used when a device wants to configure/request a GPIO as an interrupt. It directly controls the  [[GPIO_internal_peripheral | GPIO]] internal peripheral but it is also linked to the '''EXTI irqchip''' through the hierarchical irq domain mechanism<ref name="irq_hierarchic" />. This link is transparent for the requester.
*'''STM32 hardware peripherals:'''[[GIC_internal_peripheral | GIC]], [[EXTI_internal_peripheral | EXTI]], [[PWR_internal_peripheral | PWR]], [[GPIO_internal_peripheral | GPIO]]

== API description ==
The kernel space API is the interface for declaring and managing interrupts. The user space interface is used to monitor interrupt information or set interrupt affinity.

===User space API ===
[[Pseudo_filesystem | procfs]] performs the following tasks:
* It provides information about interrupts such as the virtual number, the hardware ID and the irqchip used (see chapter ''1.2 Kernel data'' of /proc kernel documentation<ref>[https://www.kernel.org/doc/Documentation/filesystems/proc.txt  https://www.kernel.org/doc/Documentation/filesystems/proc.txt(master)], User space /proc documentation</ref>).
<pre>

root@stm32mp1:~# cat /proc/interrupts 
           CPU0       CPU1       
 17:          0          0     GIC-0  37 Level     rcc irq
 20:    7509664    7509640     GIC-0  27 Level     arch_timer
 22:          0          0     GIC-0 232 Level     arm-pmu
 23:          0          0     GIC-0 233 Level     arm-pmu
 24:          0          0     GIC-0  68 Level     4000b000.audio-controller
 26:          0          0  stm32-exti-h  27 Edge      4000e000.serial:wakeup
 27:       8915          0     GIC-0  84 Level     40010000.serial
 28:          0          0  stm32-exti-h  30 Edge      40010000.serial:wakeup
 29:        654          0     GIC-0  63 Level     40012000.i2c
 30:          0          0     GIC-0  64 Level     40012000.i2c
 31:          0          0  stm32-exti-h  21 Edge      40012000.i2c:wakeup
 33:          0          0     GIC-0 123 Level     4400b004.audio-controller, 4400b024.audio-controller
...</pre>


*It configures interrupt affinity<ref>[https://www.kernel.org/doc/Documentation/IRQ-affinity.txt  https://www.kernel.org/doc/Documentation/IRQ-affinity.txt(master)], IRQ affinity documentation</ref>, that is assigns an interrupt to a dedicated CPU.

=== Kernel space API ===
The main kernel API drivers for users are the following:

*'''devm_request_irq:''' requests an interrupt.
*'''devm_free_irq:''' frees an interrupt.
*'''enable_irq:''' enables a requested interrupt.
*'''disable_irq:''' disables a requested interrupt.
*'''enable_irq_wake:''' enables a requested interrupt that could wake up the system.
*'''disable_irq_wake:''' disables a requested interrupt that could wake up the system.
...
The available routines can be found in Linux<sup>&reg;</sup> kernel header file: ''include/linux/interrupt.h''<ref>[https://www.kernel.org/doc/include/linux/interrupt.h https://www.kernel.org/doc/include/linux/interrupt.h(master)], Kernel interrupt API</ref>.

== Configuration ==
=== Kernel configuration ===
The interrupt framework and irqchip drivers are enabled by default.<br>


=== Device tree configuration ===
The generic way to declare an interrupt in the device tree is declared in Linux<sup>&reg;</sup> kernel documentation in: ''Documentation/devicetree/bindings/interrupt-controller/interrupts.txt'' <ref>[https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt Generic interrupts bindings documentation], Generic interrupts bindings documentation</ref>. 

However each irqchip driver has his own bindings description. The below chapters provide the link to the bindings documentation for each interrupt controller as well as a simple example of interrupt declaration.

==== GIC irqchip ====
*''Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt'' <ref>[https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt(master)], GIC controller binding documentation</ref>

* Device tree  usage:<pre>

&foo_node {
        ...
	interrupts = <&intc GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
	interrupt-names = "foo_name";
	...
};</pre>


==== EXTI irqchip ====
*''Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt'' <ref name="exti">[https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt(master)], Exti interrupts bindings documentation</ref>

* Device tree  usage:<pre>

&foo_node {
        ...
	interrupts-extended = <&exti 26 IRQ_TYPE_EDGE_RISING>,
	interrupt-names = "foo_name";
	...
};</pre>


==== EXTI_PWR irqchip ====
*''Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt'' <ref name="exti" />

* Device tree  usage:<pre>

&foo_node {
        ...
	interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>,
	interrupt-names = "foo_name";
	...
};</pre>


==== pinctrl irqchip ====
* Device tree  usage:<pre>

&foo_node {
        ...
	interrupts-extended = <&gpioa 14 IRQ_TYPE_EDGE_FALLING>,
	interrupt-names = "foo_name";
	...
};</pre>


==== pwr irqchip ====
Pwr irqchip has not to be used directly. User has to use ''exti_pwr'' to invoke pwr irqchip thanks to the hierarchical implementation.

==References==
<references />

<noinclude>

[[Category:Interrupts|0]]
{{PublicationRequestId | 10414 | 2019-01-21 | AnneJ}}
{{ArticleBasedOnModel|Framework overview article model}}</noinclude>
Line 1: Line 1:
<noinclude>
 
{{ArticleBasedOnModel|[[Framework overview article model]]}}
 
{{ArticleMainWriter|AlexandreT}}
 
{{ ArticleApprovedVersion| AlexandreT| LudovicB, LoicP | No previous approved version | AnneJ - 21Jan'19 - 10414 | 18Jan'19 }}
 
 
 
[[Category:Interrupts|0]]
 
</noinclude>
 
 
'''SUMMARY'''<br>
 
 
This article explains stm32mp157 interrupt topology and its management on Linux<sup>&reg;</sup> environment.
 
This article explains stm32mp157 interrupt topology and its management on Linux<sup>&reg;</sup> environment.
   
Line 142: Line 132:
   
 
==References==
 
==References==
  +
<references />
   
<references />
+
<noinclude>
  +
[[Category:Interrupts|0]]
  +
{{PublicationRequestId | 10414 | 2019-01-21 | AnneJ}}
  +
{{ArticleBasedOnModel|Framework overview article model}}
  +
</noinclude>