diff options
-rw-r--r-- | drivers/irqchip/irq-stm32-exti.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index ded20d9bde73..c0a020aab557 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -36,6 +36,7 @@ struct stm32_exti_bank { u32 rpr_ofst; u32 fpr_ofst; u32 trg_ofst; + u32 seccfgr_ofst; }; #define UNDEF_REG ~0 @@ -54,10 +55,12 @@ struct stm32_exti_chip_data { u32 mask_cache; u32 rtsr_cache; u32 ftsr_cache; + u32 event_reserved; }; struct stm32_exti_host_data { void __iomem *base; + struct device *dev; struct stm32_exti_chip_data *chips_data; const struct stm32_exti_drv_data *drv_data; struct hwspinlock *hwlock; @@ -73,6 +76,7 @@ static const struct stm32_exti_bank stm32f4xx_exti_b1 = { .rpr_ofst = 0x14, .fpr_ofst = UNDEF_REG, .trg_ofst = UNDEF_REG, + .seccfgr_ofst = UNDEF_REG, }; static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = { @@ -93,6 +97,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b1 = { .rpr_ofst = 0x88, .fpr_ofst = UNDEF_REG, .trg_ofst = UNDEF_REG, + .seccfgr_ofst = UNDEF_REG, }; static const struct stm32_exti_bank stm32h7xx_exti_b2 = { @@ -104,6 +109,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b2 = { .rpr_ofst = 0x98, .fpr_ofst = UNDEF_REG, .trg_ofst = UNDEF_REG, + .seccfgr_ofst = UNDEF_REG, }; static const struct stm32_exti_bank stm32h7xx_exti_b3 = { @@ -115,6 +121,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b3 = { .rpr_ofst = 0xA8, .fpr_ofst = UNDEF_REG, .trg_ofst = UNDEF_REG, + .seccfgr_ofst = UNDEF_REG, }; static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = { @@ -137,6 +144,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b1 = { .rpr_ofst = 0x0C, .fpr_ofst = 0x10, .trg_ofst = 0x3EC, + .seccfgr_ofst = 0x14, }; static const struct stm32_exti_bank stm32mp1_exti_b2 = { @@ -148,6 +156,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b2 = { .rpr_ofst = 0x2C, .fpr_ofst = 0x30, .trg_ofst = 0x3E8, + .seccfgr_ofst = 0x34, }; static const struct stm32_exti_bank stm32mp1_exti_b3 = { @@ -159,6 +168,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b3 = { .rpr_ofst = 0x4C, .fpr_ofst = 0x50, .trg_ofst = 0x3E4, + .seccfgr_ofst = 0x54, }; static const struct stm32_exti_bank *stm32mp1_exti_banks[] = { @@ -706,6 +716,12 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm, bank = hwirq / IRQS_PER_BANK; chip_data = &host_data->chips_data[bank]; + /* Check if event is reserved (Secure) */ + if (chip_data->event_reserved & BIT(hwirq % IRQS_PER_BANK)) { + dev_err(host_data->dev, "event %lu is reserved, secure\n", hwirq); + return -EPERM; + } + event_trg = readl_relaxed(host_data->base + chip_data->reg_bank->trg_ofst); chip = (event_trg & BIT(hwirq % IRQS_PER_BANK)) ? &stm32_exti_h_chip : &stm32_exti_h_chip_direct; @@ -803,6 +819,10 @@ stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data, if (stm32_bank->emr_ofst != UNDEF_REG) writel_relaxed(0, base + stm32_bank->emr_ofst); + /* reserve Secure events */ + if (stm32_bank->seccfgr_ofst != UNDEF_REG) + chip_data->event_reserved = readl_relaxed(base + stm32_bank->seccfgr_ofst); + pr_info("%pOF: bank%d\n", node, bank_idx); return chip_data; @@ -908,6 +928,7 @@ static int stm32_exti_probe(struct platform_device *pdev) return -ENOMEM; dev_set_drvdata(dev, host_data); + host_data->dev = dev; /* check for optional hwspinlock which may be not available yet */ ret = of_hwspin_lock_get_id(np, 0); |