From 3e17683ff4a870ed99e989425bc976a944978711 Mon Sep 17 00:00:00 2001 From: Ludovic Barre Date: Mon, 6 Jun 2022 18:27:52 +0200 Subject: irqchip/stm32-exti: Fix irq_set_affinity return value When there is no parent, there is no specific action to do in stm32-exti irqchip. In such case, it's incorrect returning an error. Let irq_set_affinity to return IRQ_SET_MASK_OK_DONE when there is no parent. Signed-off-by: Ludovic Barre Signed-off-by: Antonio Borneo Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20220606162757.415354-2-antonio.borneo@foss.st.com --- drivers/irqchip/irq-stm32-exti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index 9d18f47040eb..10c9c742c216 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -614,7 +614,7 @@ static int stm32_exti_h_set_affinity(struct irq_data *d, if (d->parent_data->chip) return irq_chip_set_affinity_parent(d, dest, force); - return -EINVAL; + return IRQ_SET_MASK_OK_DONE; } static int __maybe_unused stm32_exti_h_suspend(void) -- cgit v1.2.3-70-g09d2 From f8b3eb4245113c8a9156d5db8e80c6134127bcc1 Mon Sep 17 00:00:00 2001 From: Loic Pallardy Date: Mon, 6 Jun 2022 18:27:53 +0200 Subject: irqchip/stm32-exti: Fix irq_mask/irq_unmask for direct events The driver has to mask/unmask the corresponding flag in the Interrupt Mask Register (IMR). This is already done for configurable event, while direct events only forward the mask/unmask request to the parent. Use the existing stm32_exti_h_mask()/stm32_exti_h_unmask() for direct events too. Signed-off-by: Loic Pallardy Signed-off-by: Antonio Borneo Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20220606162757.415354-3-antonio.borneo@foss.st.com --- drivers/irqchip/irq-stm32-exti.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index 10c9c742c216..1145f064faa8 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -691,8 +691,8 @@ static struct irq_chip stm32_exti_h_chip_direct = { .name = "stm32-exti-h-direct", .irq_eoi = irq_chip_eoi_parent, .irq_ack = irq_chip_ack_parent, - .irq_mask = irq_chip_mask_parent, - .irq_unmask = irq_chip_unmask_parent, + .irq_mask = stm32_exti_h_mask, + .irq_unmask = stm32_exti_h_unmask, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_type = irq_chip_set_type_parent, .irq_set_wake = stm32_exti_h_set_wake, -- cgit v1.2.3-70-g09d2 From c16ae609214e835692c33b1a090b5a15bf1b9e7e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 Jun 2022 18:27:54 +0200 Subject: irqchip/stm32-exti: Prevent illegal read due to unbounded DT value The value hwirq is received from DT. If it exceeds the maximum valid value it causes the code to address unexisting irq chips reading outside the array boundary. Check the value of hwirq before using it. Signed-off-by: Antonio Borneo Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20220606162757.415354-4-antonio.borneo@foss.st.com --- drivers/irqchip/irq-stm32-exti.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index 1145f064faa8..e2722e499ae5 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -713,6 +713,9 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm, int bank; hwirq = fwspec->param[0]; + if (hwirq >= host_data->drv_data->bank_nr * IRQS_PER_BANK) + return -EINVAL; + bank = hwirq / IRQS_PER_BANK; chip_data = &host_data->chips_data[bank]; -- cgit v1.2.3-70-g09d2 From b38040f0167d25092e813c8d1a70cf2708c1720b Mon Sep 17 00:00:00 2001 From: Alexandre Torgue Date: Mon, 6 Jun 2022 18:27:55 +0200 Subject: irqchip/stm32-exti: Tag emr register as undefined for stm32mp15 The reference manual RM0436 of stm32mp15 till version v4.0 was erroneously reporting the Event Mask Registers (EMR) for the Cortex-A CPUs. These registers have been removed from v5.0 of the manual and the corresponding offsets have been marked as 'Reserved'. Prevent accessing these reserved addresses by tagging the EMR offsets as UNDEF_REG and modifying the code to handle this case. Signed-off-by: Alexandre Torgue Signed-off-by: Antonio Borneo Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20220606162757.415354-5-antonio.borneo@foss.st.com --- drivers/irqchip/irq-stm32-exti.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index e2722e499ae5..e8fa91bda4ba 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -132,7 +132,7 @@ static const struct stm32_exti_drv_data stm32h7xx_drv_data = { static const struct stm32_exti_bank stm32mp1_exti_b1 = { .imr_ofst = 0x80, - .emr_ofst = 0x84, + .emr_ofst = UNDEF_REG, .rtsr_ofst = 0x00, .ftsr_ofst = 0x04, .swier_ofst = 0x08, @@ -142,7 +142,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b1 = { static const struct stm32_exti_bank stm32mp1_exti_b2 = { .imr_ofst = 0x90, - .emr_ofst = 0x94, + .emr_ofst = UNDEF_REG, .rtsr_ofst = 0x20, .ftsr_ofst = 0x24, .swier_ofst = 0x28, @@ -152,7 +152,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b2 = { static const struct stm32_exti_bank stm32mp1_exti_b3 = { .imr_ofst = 0xA0, - .emr_ofst = 0xA4, + .emr_ofst = UNDEF_REG, .rtsr_ofst = 0x40, .ftsr_ofst = 0x44, .swier_ofst = 0x48, @@ -795,7 +795,8 @@ stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data, * clear registers to avoid residue */ writel_relaxed(0, base + stm32_bank->imr_ofst); - writel_relaxed(0, base + stm32_bank->emr_ofst); + if (stm32_bank->emr_ofst != UNDEF_REG) + writel_relaxed(0, base + stm32_bank->emr_ofst); pr_info("%pOF: bank%d\n", node, bank_idx); -- cgit v1.2.3-70-g09d2 From ce4ef8f9f2abcf104a5417225cbfe3560e779093 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 Jun 2022 18:27:56 +0200 Subject: irqchip/stm32-exti: Read event trigger type from event_trg register The flag reporting whether an event is 'direct' or 'configurable' is available in the read-only registers EVENT_TRG. Drop this redundant information from the struct stm32_desc_irq and use the proper bit from EVENT_TRG register. On armv7a this patch reduces by 3% the size of the driver, from text data bss dec hex filename 7233 424 4 7661 1ded irq-stm32-exti.o to 6977 424 4 7405 1ced irq-stm32-exti.o Signed-off-by: Antonio Borneo Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20220606162757.415354-6-antonio.borneo@foss.st.com --- drivers/irqchip/irq-stm32-exti.c | 180 +++++++++++++++++++++------------------ 1 file changed, 96 insertions(+), 84 deletions(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index e8fa91bda4ba..045589627e67 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -34,6 +34,7 @@ struct stm32_exti_bank { u32 swier_ofst; u32 rpr_ofst; u32 fpr_ofst; + u32 trg_ofst; }; #define UNDEF_REG ~0 @@ -41,7 +42,6 @@ struct stm32_exti_bank { struct stm32_desc_irq { u32 exti; u32 irq_parent; - struct irq_chip *chip; }; struct stm32_exti_drv_data { @@ -78,6 +78,7 @@ static const struct stm32_exti_bank stm32f4xx_exti_b1 = { .swier_ofst = 0x10, .rpr_ofst = 0x14, .fpr_ofst = UNDEF_REG, + .trg_ofst = UNDEF_REG, }; static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = { @@ -97,6 +98,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b1 = { .swier_ofst = 0x08, .rpr_ofst = 0x88, .fpr_ofst = UNDEF_REG, + .trg_ofst = UNDEF_REG, }; static const struct stm32_exti_bank stm32h7xx_exti_b2 = { @@ -107,6 +109,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b2 = { .swier_ofst = 0x28, .rpr_ofst = 0x98, .fpr_ofst = UNDEF_REG, + .trg_ofst = UNDEF_REG, }; static const struct stm32_exti_bank stm32h7xx_exti_b3 = { @@ -117,6 +120,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b3 = { .swier_ofst = 0x48, .rpr_ofst = 0xA8, .fpr_ofst = UNDEF_REG, + .trg_ofst = UNDEF_REG, }; static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = { @@ -138,6 +142,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b1 = { .swier_ofst = 0x08, .rpr_ofst = 0x0C, .fpr_ofst = 0x10, + .trg_ofst = 0x3EC, }; static const struct stm32_exti_bank stm32mp1_exti_b2 = { @@ -148,6 +153,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b2 = { .swier_ofst = 0x28, .rpr_ofst = 0x2C, .fpr_ofst = 0x30, + .trg_ofst = 0x3E8, }; static const struct stm32_exti_bank stm32mp1_exti_b3 = { @@ -158,6 +164,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b3 = { .swier_ofst = 0x48, .rpr_ofst = 0x4C, .fpr_ofst = 0x50, + .trg_ofst = 0x3E4, }; static const struct stm32_exti_bank *stm32mp1_exti_banks[] = { @@ -170,90 +177,90 @@ static struct irq_chip stm32_exti_h_chip; static struct irq_chip stm32_exti_h_chip_direct; static const struct stm32_desc_irq stm32mp1_desc_irq[] = { - { .exti = 0, .irq_parent = 6, .chip = &stm32_exti_h_chip }, - { .exti = 1, .irq_parent = 7, .chip = &stm32_exti_h_chip }, - { .exti = 2, .irq_parent = 8, .chip = &stm32_exti_h_chip }, - { .exti = 3, .irq_parent = 9, .chip = &stm32_exti_h_chip }, - { .exti = 4, .irq_parent = 10, .chip = &stm32_exti_h_chip }, - { .exti = 5, .irq_parent = 23, .chip = &stm32_exti_h_chip }, - { .exti = 6, .irq_parent = 64, .chip = &stm32_exti_h_chip }, - { .exti = 7, .irq_parent = 65, .chip = &stm32_exti_h_chip }, - { .exti = 8, .irq_parent = 66, .chip = &stm32_exti_h_chip }, - { .exti = 9, .irq_parent = 67, .chip = &stm32_exti_h_chip }, - { .exti = 10, .irq_parent = 40, .chip = &stm32_exti_h_chip }, - { .exti = 11, .irq_parent = 42, .chip = &stm32_exti_h_chip }, - { .exti = 12, .irq_parent = 76, .chip = &stm32_exti_h_chip }, - { .exti = 13, .irq_parent = 77, .chip = &stm32_exti_h_chip }, - { .exti = 14, .irq_parent = 121, .chip = &stm32_exti_h_chip }, - { .exti = 15, .irq_parent = 127, .chip = &stm32_exti_h_chip }, - { .exti = 16, .irq_parent = 1, .chip = &stm32_exti_h_chip }, - { .exti = 19, .irq_parent = 3, .chip = &stm32_exti_h_chip_direct }, - { .exti = 21, .irq_parent = 31, .chip = &stm32_exti_h_chip_direct }, - { .exti = 22, .irq_parent = 33, .chip = &stm32_exti_h_chip_direct }, - { .exti = 23, .irq_parent = 72, .chip = &stm32_exti_h_chip_direct }, - { .exti = 24, .irq_parent = 95, .chip = &stm32_exti_h_chip_direct }, - { .exti = 25, .irq_parent = 107, .chip = &stm32_exti_h_chip_direct }, - { .exti = 26, .irq_parent = 37, .chip = &stm32_exti_h_chip_direct }, - { .exti = 27, .irq_parent = 38, .chip = &stm32_exti_h_chip_direct }, - { .exti = 28, .irq_parent = 39, .chip = &stm32_exti_h_chip_direct }, - { .exti = 29, .irq_parent = 71, .chip = &stm32_exti_h_chip_direct }, - { .exti = 30, .irq_parent = 52, .chip = &stm32_exti_h_chip_direct }, - { .exti = 31, .irq_parent = 53, .chip = &stm32_exti_h_chip_direct }, - { .exti = 32, .irq_parent = 82, .chip = &stm32_exti_h_chip_direct }, - { .exti = 33, .irq_parent = 83, .chip = &stm32_exti_h_chip_direct }, - { .exti = 47, .irq_parent = 93, .chip = &stm32_exti_h_chip_direct }, - { .exti = 48, .irq_parent = 138, .chip = &stm32_exti_h_chip_direct }, - { .exti = 50, .irq_parent = 139, .chip = &stm32_exti_h_chip_direct }, - { .exti = 52, .irq_parent = 140, .chip = &stm32_exti_h_chip_direct }, - { .exti = 53, .irq_parent = 141, .chip = &stm32_exti_h_chip_direct }, - { .exti = 54, .irq_parent = 135, .chip = &stm32_exti_h_chip_direct }, - { .exti = 61, .irq_parent = 100, .chip = &stm32_exti_h_chip_direct }, - { .exti = 65, .irq_parent = 144, .chip = &stm32_exti_h_chip }, - { .exti = 68, .irq_parent = 143, .chip = &stm32_exti_h_chip }, - { .exti = 70, .irq_parent = 62, .chip = &stm32_exti_h_chip_direct }, - { .exti = 73, .irq_parent = 129, .chip = &stm32_exti_h_chip }, + { .exti = 0, .irq_parent = 6 }, + { .exti = 1, .irq_parent = 7 }, + { .exti = 2, .irq_parent = 8 }, + { .exti = 3, .irq_parent = 9 }, + { .exti = 4, .irq_parent = 10 }, + { .exti = 5, .irq_parent = 23 }, + { .exti = 6, .irq_parent = 64 }, + { .exti = 7, .irq_parent = 65 }, + { .exti = 8, .irq_parent = 66 }, + { .exti = 9, .irq_parent = 67 }, + { .exti = 10, .irq_parent = 40 }, + { .exti = 11, .irq_parent = 42 }, + { .exti = 12, .irq_parent = 76 }, + { .exti = 13, .irq_parent = 77 }, + { .exti = 14, .irq_parent = 121 }, + { .exti = 15, .irq_parent = 127 }, + { .exti = 16, .irq_parent = 1 }, + { .exti = 19, .irq_parent = 3 }, + { .exti = 21, .irq_parent = 31 }, + { .exti = 22, .irq_parent = 33 }, + { .exti = 23, .irq_parent = 72 }, + { .exti = 24, .irq_parent = 95 }, + { .exti = 25, .irq_parent = 107 }, + { .exti = 26, .irq_parent = 37 }, + { .exti = 27, .irq_parent = 38 }, + { .exti = 28, .irq_parent = 39 }, + { .exti = 29, .irq_parent = 71 }, + { .exti = 30, .irq_parent = 52 }, + { .exti = 31, .irq_parent = 53 }, + { .exti = 32, .irq_parent = 82 }, + { .exti = 33, .irq_parent = 83 }, + { .exti = 47, .irq_parent = 93 }, + { .exti = 48, .irq_parent = 138 }, + { .exti = 50, .irq_parent = 139 }, + { .exti = 52, .irq_parent = 140 }, + { .exti = 53, .irq_parent = 141 }, + { .exti = 54, .irq_parent = 135 }, + { .exti = 61, .irq_parent = 100 }, + { .exti = 65, .irq_parent = 144 }, + { .exti = 68, .irq_parent = 143 }, + { .exti = 70, .irq_parent = 62 }, + { .exti = 73, .irq_parent = 129 }, }; static const struct stm32_desc_irq stm32mp13_desc_irq[] = { - { .exti = 0, .irq_parent = 6, .chip = &stm32_exti_h_chip }, - { .exti = 1, .irq_parent = 7, .chip = &stm32_exti_h_chip }, - { .exti = 2, .irq_parent = 8, .chip = &stm32_exti_h_chip }, - { .exti = 3, .irq_parent = 9, .chip = &stm32_exti_h_chip }, - { .exti = 4, .irq_parent = 10, .chip = &stm32_exti_h_chip }, - { .exti = 5, .irq_parent = 24, .chip = &stm32_exti_h_chip }, - { .exti = 6, .irq_parent = 65, .chip = &stm32_exti_h_chip }, - { .exti = 7, .irq_parent = 66, .chip = &stm32_exti_h_chip }, - { .exti = 8, .irq_parent = 67, .chip = &stm32_exti_h_chip }, - { .exti = 9, .irq_parent = 68, .chip = &stm32_exti_h_chip }, - { .exti = 10, .irq_parent = 41, .chip = &stm32_exti_h_chip }, - { .exti = 11, .irq_parent = 43, .chip = &stm32_exti_h_chip }, - { .exti = 12, .irq_parent = 77, .chip = &stm32_exti_h_chip }, - { .exti = 13, .irq_parent = 78, .chip = &stm32_exti_h_chip }, - { .exti = 14, .irq_parent = 106, .chip = &stm32_exti_h_chip }, - { .exti = 15, .irq_parent = 109, .chip = &stm32_exti_h_chip }, - { .exti = 16, .irq_parent = 1, .chip = &stm32_exti_h_chip }, - { .exti = 19, .irq_parent = 3, .chip = &stm32_exti_h_chip_direct }, - { .exti = 21, .irq_parent = 32, .chip = &stm32_exti_h_chip_direct }, - { .exti = 22, .irq_parent = 34, .chip = &stm32_exti_h_chip_direct }, - { .exti = 23, .irq_parent = 73, .chip = &stm32_exti_h_chip_direct }, - { .exti = 24, .irq_parent = 93, .chip = &stm32_exti_h_chip_direct }, - { .exti = 25, .irq_parent = 114, .chip = &stm32_exti_h_chip_direct }, - { .exti = 26, .irq_parent = 38, .chip = &stm32_exti_h_chip_direct }, - { .exti = 27, .irq_parent = 39, .chip = &stm32_exti_h_chip_direct }, - { .exti = 28, .irq_parent = 40, .chip = &stm32_exti_h_chip_direct }, - { .exti = 29, .irq_parent = 72, .chip = &stm32_exti_h_chip_direct }, - { .exti = 30, .irq_parent = 53, .chip = &stm32_exti_h_chip_direct }, - { .exti = 31, .irq_parent = 54, .chip = &stm32_exti_h_chip_direct }, - { .exti = 32, .irq_parent = 83, .chip = &stm32_exti_h_chip_direct }, - { .exti = 33, .irq_parent = 84, .chip = &stm32_exti_h_chip_direct }, - { .exti = 44, .irq_parent = 96, .chip = &stm32_exti_h_chip_direct }, - { .exti = 47, .irq_parent = 92, .chip = &stm32_exti_h_chip_direct }, - { .exti = 48, .irq_parent = 116, .chip = &stm32_exti_h_chip_direct }, - { .exti = 50, .irq_parent = 117, .chip = &stm32_exti_h_chip_direct }, - { .exti = 52, .irq_parent = 118, .chip = &stm32_exti_h_chip_direct }, - { .exti = 53, .irq_parent = 119, .chip = &stm32_exti_h_chip_direct }, - { .exti = 68, .irq_parent = 63, .chip = &stm32_exti_h_chip_direct }, - { .exti = 70, .irq_parent = 98, .chip = &stm32_exti_h_chip_direct }, + { .exti = 0, .irq_parent = 6 }, + { .exti = 1, .irq_parent = 7 }, + { .exti = 2, .irq_parent = 8 }, + { .exti = 3, .irq_parent = 9 }, + { .exti = 4, .irq_parent = 10 }, + { .exti = 5, .irq_parent = 24 }, + { .exti = 6, .irq_parent = 65 }, + { .exti = 7, .irq_parent = 66 }, + { .exti = 8, .irq_parent = 67 }, + { .exti = 9, .irq_parent = 68 }, + { .exti = 10, .irq_parent = 41 }, + { .exti = 11, .irq_parent = 43 }, + { .exti = 12, .irq_parent = 77 }, + { .exti = 13, .irq_parent = 78 }, + { .exti = 14, .irq_parent = 106 }, + { .exti = 15, .irq_parent = 109 }, + { .exti = 16, .irq_parent = 1 }, + { .exti = 19, .irq_parent = 3 }, + { .exti = 21, .irq_parent = 32 }, + { .exti = 22, .irq_parent = 34 }, + { .exti = 23, .irq_parent = 73 }, + { .exti = 24, .irq_parent = 93 }, + { .exti = 25, .irq_parent = 114 }, + { .exti = 26, .irq_parent = 38 }, + { .exti = 27, .irq_parent = 39 }, + { .exti = 28, .irq_parent = 40 }, + { .exti = 29, .irq_parent = 72 }, + { .exti = 30, .irq_parent = 53 }, + { .exti = 31, .irq_parent = 54 }, + { .exti = 32, .irq_parent = 83 }, + { .exti = 33, .irq_parent = 84 }, + { .exti = 44, .irq_parent = 96 }, + { .exti = 47, .irq_parent = 92 }, + { .exti = 48, .irq_parent = 116 }, + { .exti = 50, .irq_parent = 117 }, + { .exti = 52, .irq_parent = 118 }, + { .exti = 53, .irq_parent = 119 }, + { .exti = 68, .irq_parent = 63 }, + { .exti = 70, .irq_parent = 98 }, }; static const struct stm32_exti_drv_data stm32mp1_drv_data = { @@ -711,6 +718,8 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm, struct irq_fwspec p_fwspec; irq_hw_number_t hwirq; int bank; + u32 event_trg; + struct irq_chip *chip; hwirq = fwspec->param[0]; if (hwirq >= host_data->drv_data->bank_nr * IRQS_PER_BANK) @@ -724,8 +733,11 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm, if (!desc) return -EINVAL; - irq_domain_set_hwirq_and_chip(dm, virq, hwirq, desc->chip, - chip_data); + 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; + + irq_domain_set_hwirq_and_chip(dm, virq, hwirq, chip, chip_data); if (desc->irq_parent) { p_fwspec.fwnode = dm->parent->fwnode; p_fwspec.param_count = 3; -- cgit v1.2.3-70-g09d2 From c297493336b7bc0c12ced484a9e61d04ec2d9403 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 Jun 2022 18:27:57 +0200 Subject: irqchip/stm32-exti: Simplify irq description table Having removed the event trigger type from struct stm32_desc_irq makes worthless keep using a struct. Replace the struct by a single dimension array and use 8 bit type to reduce the overal memory footprint. On armv7a this patch reduces by 7% the size of the driver, from text data bss dec hex filename 6977 424 4 7405 1ced irq-stm32-exti.o to 6449 424 4 6877 1add irq-stm32-exti.o Signed-off-by: Antonio Borneo Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20220606162757.415354-7-antonio.borneo@foss.st.com --- drivers/irqchip/irq-stm32-exti.c | 220 ++++++++++++++++++--------------------- 1 file changed, 101 insertions(+), 119 deletions(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index 045589627e67..a73763d475f0 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -39,16 +39,10 @@ struct stm32_exti_bank { #define UNDEF_REG ~0 -struct stm32_desc_irq { - u32 exti; - u32 irq_parent; -}; - struct stm32_exti_drv_data { const struct stm32_exti_bank **exti_banks; - const struct stm32_desc_irq *desc_irqs; + const u8 *desc_irqs; u32 bank_nr; - u32 irq_nr; }; struct stm32_exti_chip_data { @@ -176,126 +170,114 @@ static const struct stm32_exti_bank *stm32mp1_exti_banks[] = { static struct irq_chip stm32_exti_h_chip; static struct irq_chip stm32_exti_h_chip_direct; -static const struct stm32_desc_irq stm32mp1_desc_irq[] = { - { .exti = 0, .irq_parent = 6 }, - { .exti = 1, .irq_parent = 7 }, - { .exti = 2, .irq_parent = 8 }, - { .exti = 3, .irq_parent = 9 }, - { .exti = 4, .irq_parent = 10 }, - { .exti = 5, .irq_parent = 23 }, - { .exti = 6, .irq_parent = 64 }, - { .exti = 7, .irq_parent = 65 }, - { .exti = 8, .irq_parent = 66 }, - { .exti = 9, .irq_parent = 67 }, - { .exti = 10, .irq_parent = 40 }, - { .exti = 11, .irq_parent = 42 }, - { .exti = 12, .irq_parent = 76 }, - { .exti = 13, .irq_parent = 77 }, - { .exti = 14, .irq_parent = 121 }, - { .exti = 15, .irq_parent = 127 }, - { .exti = 16, .irq_parent = 1 }, - { .exti = 19, .irq_parent = 3 }, - { .exti = 21, .irq_parent = 31 }, - { .exti = 22, .irq_parent = 33 }, - { .exti = 23, .irq_parent = 72 }, - { .exti = 24, .irq_parent = 95 }, - { .exti = 25, .irq_parent = 107 }, - { .exti = 26, .irq_parent = 37 }, - { .exti = 27, .irq_parent = 38 }, - { .exti = 28, .irq_parent = 39 }, - { .exti = 29, .irq_parent = 71 }, - { .exti = 30, .irq_parent = 52 }, - { .exti = 31, .irq_parent = 53 }, - { .exti = 32, .irq_parent = 82 }, - { .exti = 33, .irq_parent = 83 }, - { .exti = 47, .irq_parent = 93 }, - { .exti = 48, .irq_parent = 138 }, - { .exti = 50, .irq_parent = 139 }, - { .exti = 52, .irq_parent = 140 }, - { .exti = 53, .irq_parent = 141 }, - { .exti = 54, .irq_parent = 135 }, - { .exti = 61, .irq_parent = 100 }, - { .exti = 65, .irq_parent = 144 }, - { .exti = 68, .irq_parent = 143 }, - { .exti = 70, .irq_parent = 62 }, - { .exti = 73, .irq_parent = 129 }, +#define EXTI_INVALID_IRQ U8_MAX +#define STM32MP1_DESC_IRQ_SIZE (ARRAY_SIZE(stm32mp1_exti_banks) * IRQS_PER_BANK) + +static const u8 stm32mp1_desc_irq[] = { + /* default value */ + [0 ... (STM32MP1_DESC_IRQ_SIZE - 1)] = EXTI_INVALID_IRQ, + + [0] = 6, + [1] = 7, + [2] = 8, + [3] = 9, + [4] = 10, + [5] = 23, + [6] = 64, + [7] = 65, + [8] = 66, + [9] = 67, + [10] = 40, + [11] = 42, + [12] = 76, + [13] = 77, + [14] = 121, + [15] = 127, + [16] = 1, + [19] = 3, + [21] = 31, + [22] = 33, + [23] = 72, + [24] = 95, + [25] = 107, + [26] = 37, + [27] = 38, + [28] = 39, + [29] = 71, + [30] = 52, + [31] = 53, + [32] = 82, + [33] = 83, + [47] = 93, + [48] = 138, + [50] = 139, + [52] = 140, + [53] = 141, + [54] = 135, + [61] = 100, + [65] = 144, + [68] = 143, + [70] = 62, + [73] = 129, }; -static const struct stm32_desc_irq stm32mp13_desc_irq[] = { - { .exti = 0, .irq_parent = 6 }, - { .exti = 1, .irq_parent = 7 }, - { .exti = 2, .irq_parent = 8 }, - { .exti = 3, .irq_parent = 9 }, - { .exti = 4, .irq_parent = 10 }, - { .exti = 5, .irq_parent = 24 }, - { .exti = 6, .irq_parent = 65 }, - { .exti = 7, .irq_parent = 66 }, - { .exti = 8, .irq_parent = 67 }, - { .exti = 9, .irq_parent = 68 }, - { .exti = 10, .irq_parent = 41 }, - { .exti = 11, .irq_parent = 43 }, - { .exti = 12, .irq_parent = 77 }, - { .exti = 13, .irq_parent = 78 }, - { .exti = 14, .irq_parent = 106 }, - { .exti = 15, .irq_parent = 109 }, - { .exti = 16, .irq_parent = 1 }, - { .exti = 19, .irq_parent = 3 }, - { .exti = 21, .irq_parent = 32 }, - { .exti = 22, .irq_parent = 34 }, - { .exti = 23, .irq_parent = 73 }, - { .exti = 24, .irq_parent = 93 }, - { .exti = 25, .irq_parent = 114 }, - { .exti = 26, .irq_parent = 38 }, - { .exti = 27, .irq_parent = 39 }, - { .exti = 28, .irq_parent = 40 }, - { .exti = 29, .irq_parent = 72 }, - { .exti = 30, .irq_parent = 53 }, - { .exti = 31, .irq_parent = 54 }, - { .exti = 32, .irq_parent = 83 }, - { .exti = 33, .irq_parent = 84 }, - { .exti = 44, .irq_parent = 96 }, - { .exti = 47, .irq_parent = 92 }, - { .exti = 48, .irq_parent = 116 }, - { .exti = 50, .irq_parent = 117 }, - { .exti = 52, .irq_parent = 118 }, - { .exti = 53, .irq_parent = 119 }, - { .exti = 68, .irq_parent = 63 }, - { .exti = 70, .irq_parent = 98 }, +static const u8 stm32mp13_desc_irq[] = { + /* default value */ + [0 ... (STM32MP1_DESC_IRQ_SIZE - 1)] = EXTI_INVALID_IRQ, + + [0] = 6, + [1] = 7, + [2] = 8, + [3] = 9, + [4] = 10, + [5] = 24, + [6] = 65, + [7] = 66, + [8] = 67, + [9] = 68, + [10] = 41, + [11] = 43, + [12] = 77, + [13] = 78, + [14] = 106, + [15] = 109, + [16] = 1, + [19] = 3, + [21] = 32, + [22] = 34, + [23] = 73, + [24] = 93, + [25] = 114, + [26] = 38, + [27] = 39, + [28] = 40, + [29] = 72, + [30] = 53, + [31] = 54, + [32] = 83, + [33] = 84, + [44] = 96, + [47] = 92, + [48] = 116, + [50] = 117, + [52] = 118, + [53] = 119, + [68] = 63, + [70] = 98, }; static const struct stm32_exti_drv_data stm32mp1_drv_data = { .exti_banks = stm32mp1_exti_banks, .bank_nr = ARRAY_SIZE(stm32mp1_exti_banks), .desc_irqs = stm32mp1_desc_irq, - .irq_nr = ARRAY_SIZE(stm32mp1_desc_irq), }; static const struct stm32_exti_drv_data stm32mp13_drv_data = { .exti_banks = stm32mp1_exti_banks, .bank_nr = ARRAY_SIZE(stm32mp1_exti_banks), .desc_irqs = stm32mp13_desc_irq, - .irq_nr = ARRAY_SIZE(stm32mp13_desc_irq), }; -static const struct -stm32_desc_irq *stm32_exti_get_desc(const struct stm32_exti_drv_data *drv_data, - irq_hw_number_t hwirq) -{ - const struct stm32_desc_irq *desc = NULL; - int i; - - if (!drv_data->desc_irqs) - return NULL; - - for (i = 0; i < drv_data->irq_nr; i++) { - desc = &drv_data->desc_irqs[i]; - if (desc->exti == hwirq) - break; - } - - return desc; -} - static unsigned long stm32_exti_pending(struct irq_chip_generic *gc) { struct stm32_exti_chip_data *chip_data = gc->private; @@ -713,7 +695,7 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm, { struct stm32_exti_host_data *host_data = dm->host_data; struct stm32_exti_chip_data *chip_data; - const struct stm32_desc_irq *desc; + u8 desc_irq; struct irq_fwspec *fwspec = data; struct irq_fwspec p_fwspec; irq_hw_number_t hwirq; @@ -728,21 +710,21 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm, bank = hwirq / IRQS_PER_BANK; chip_data = &host_data->chips_data[bank]; - - desc = stm32_exti_get_desc(host_data->drv_data, hwirq); - if (!desc) - return -EINVAL; - 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; irq_domain_set_hwirq_and_chip(dm, virq, hwirq, chip, chip_data); - if (desc->irq_parent) { + + if (!host_data->drv_data || !host_data->drv_data->desc_irqs) + return -EINVAL; + + desc_irq = host_data->drv_data->desc_irqs[hwirq]; + if (desc_irq != EXTI_INVALID_IRQ) { p_fwspec.fwnode = dm->parent->fwnode; p_fwspec.param_count = 3; p_fwspec.param[0] = GIC_SPI; - p_fwspec.param[1] = desc->irq_parent; + p_fwspec.param[1] = desc_irq; p_fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH; return irq_domain_alloc_irqs_parent(dm, virq, 1, &p_fwspec); -- cgit v1.2.3-70-g09d2