Skip to content

Commit df41b65

Browse files
AntonioBorneoKAGA-KOKO
authored andcommitted
irqchip/stm32-exti: Mark events reserved with RIF configuration check
EXTI events availability depends on Resource Isolation Framework (RIF) configuration. RIF grants access to buses with Compartment ID (CID) filtering, secure and privilege level. It also assigns EXTI events to one or several processors (CID, Secure, Privilege). EXTI events used by Linux must be CID-filtered (EnCIDCFGR.CFEN=1) and statically assigned to CID1 (EnCIDCFR.CID=CID1). EXTI events not filling these conditions are marked as reserved and can't be used by Linux. Signed-off-by: Antonio Borneo <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent c00a4cb commit df41b65

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

drivers/irqchip/irq-stm32-exti.c

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,22 @@
2323

2424
#include <dt-bindings/interrupt-controller/arm-gic.h>
2525

26-
#define IRQS_PER_BANK 32
26+
#define IRQS_PER_BANK 32
2727

28-
#define HWSPNLCK_TIMEOUT 1000 /* usec */
28+
#define HWSPNLCK_TIMEOUT 1000 /* usec */
29+
30+
#define EXTI_EnCIDCFGR(n) (0x180 + (n) * 4)
31+
#define EXTI_HWCFGR1 0x3f0
32+
33+
/* Register: EXTI_EnCIDCFGR(n) */
34+
#define EXTI_CIDCFGR_CFEN_MASK BIT(0)
35+
#define EXTI_CIDCFGR_CID_MASK GENMASK(6, 4)
36+
#define EXTI_CIDCFGR_CID_SHIFT 4
37+
38+
/* Register: EXTI_HWCFGR1 */
39+
#define EXTI_HWCFGR1_CIDWIDTH_MASK GENMASK(27, 24)
40+
41+
#define EXTI_CID1 1
2942

3043
struct stm32_exti_bank {
3144
u32 imr_ofst;
@@ -907,6 +920,27 @@ static const struct irq_domain_ops stm32_exti_h_domain_ops = {
907920
.xlate = irq_domain_xlate_twocell,
908921
};
909922

923+
static void stm32_exti_check_rif(struct stm32_exti_host_data *host_data)
924+
{
925+
unsigned int bank, i, event;
926+
u32 cid, cidcfgr, hwcfgr1;
927+
928+
/* quit on CID not supported */
929+
hwcfgr1 = readl_relaxed(host_data->base + EXTI_HWCFGR1);
930+
if ((hwcfgr1 & EXTI_HWCFGR1_CIDWIDTH_MASK) == 0)
931+
return;
932+
933+
for (bank = 0; bank < host_data->drv_data->bank_nr; bank++) {
934+
for (i = 0; i < IRQS_PER_BANK; i++) {
935+
event = bank * IRQS_PER_BANK + i;
936+
cidcfgr = readl_relaxed(host_data->base + EXTI_EnCIDCFGR(event));
937+
cid = (cidcfgr & EXTI_CIDCFGR_CID_MASK) >> EXTI_CIDCFGR_CID_SHIFT;
938+
if ((cidcfgr & EXTI_CIDCFGR_CFEN_MASK) && cid != EXTI_CID1)
939+
host_data->chips_data[bank].event_reserved |= BIT(i);
940+
}
941+
}
942+
}
943+
910944
static void stm32_exti_remove_irq(void *data)
911945
{
912946
struct irq_domain *domain = data;
@@ -969,6 +1003,8 @@ static int stm32_exti_probe(struct platform_device *pdev)
9691003
for (i = 0; i < drv_data->bank_nr; i++)
9701004
stm32_exti_chip_init(host_data, i, np);
9711005

1006+
stm32_exti_check_rif(host_data);
1007+
9721008
parent_domain = irq_find_host(of_irq_find_parent(np));
9731009
if (!parent_domain) {
9741010
dev_err(dev, "GIC interrupt-parent not found\n");

0 commit comments

Comments
 (0)