powerpc/xics: Properly set Edge/Level type and enable resend
PATCH 1/1 powerpc/xics: Properly set Edge/Level type and enable resend
This sets the type of the interrupt appropriately. We set it as follow:
- If not mapped from the device-tree, we use edge. This is the case
of the virtual interrupts and PCI MSIs for example.
- If mapped from the device-tree and #interrupt-cells is 2 (PAPR
compliant), we use the second cell to set the appropriate type
- If mapped from the device-tree and #interrupt-cells is 1 (current
OPAL on P8 does that), we assume level sensitive since those are typically going to be the PSI LSIs which are level sensitive.
Additionally, we mark the interrupts requested via the opal_interrupts property all level. This is a bit fishy but the best we can do until we fix OPAL to properly expose them with a complete descriptor. It is also correct for the current HW anyway as OPAL interrupts are currently PCI error and PSI interrupts which are level.
Finally now that edge interrupts are properly identified, we can enable CONFIG_HARDIRQS_SW_RESEND which will make the core re-send them if they occur while masked, which some drivers rely upon.
This fixes issues with lost interrupts on some Mellanox adapters.
--- arch/powerpc/include/asm/xics.h | 2 + arch/powerpc/platforms/powernv/opal-irqchip.c | 3 +- arch/powerpc/sysdev/xics/Kconfig | 1 + arch/powerpc/sysdev/xics/ics-opal.c | 4 +- arch/powerpc/sysdev/xics/ics-rtas.c | 4 +- arch/powerpc/sysdev/xics/xics-common.c | 57 +++++++++++++++++++++++---- 6 files changed, 61 insertions(+), 10 deletions(-)
arch/powerpc/include/asm/xics.h +2 -0
@@ -159,6 +159,8 @@ extern void xics_teardown_cpu(void);extern void xics_kexec_teardown_cpu (int secondary);extern void xics_migrate_irqs_away (void );extern void icp_native_eoi (struct irq_data *d); +extern int xics_set_irq_type (struct irq_data *d,unsigned int flow_type); +extern int xics_retrigger (struct irq_data *data);#ifdef CONFIG_SMP extern int xics_get_irq_server (unsigned int virq,const struct cpumask *cpumask,unsigned int strict_check);
arch/powerpc/platforms/powernv/opal-irqchip.c +2 -1
@@ -228,7 +228,8 @@ int __init opal_event_init(void) }/* Install interrupt handler */ - rc =request_irq (virq, opal_interrupt,0 ,"opal" ,NULL ); + rc =request_irq (virq, opal_interrupt,IRQF_TRIGGER_LOW , +"opal" ,NULL );if (rc) {irq_dispose_mapping (virq); pr_warn("Error %d requesting irq %d (0x%x)\n",
arch/powerpc/sysdev/xics/Kconfig +1 -0
@@ -1,6 +1,7 @@ config PPC_XICS def_bool n select PPC_SMP_MUXED_IPI + select HARDIRQS_SW_RESEND config PPC_ICP_NATIVE def_bool n
arch/powerpc/sysdev/xics/ics-opal.c +3 -1
@@ -156,7 +156,9 @@ static struct irq_chip ics_opal_irq_chip = { .irq_mask = ics_opal_mask_irq, .irq_unmask = ics_opal_unmask_irq, .irq_eoi = NULL, /* Patched at init time */ - .irq_set_affinity = ics_opal_set_affinity + .irq_set_affinity = ics_opal_set_affinity, + .irq_set_type = xics_set_irq_type, + .irq_retrigger = xics_retrigger, };static int ics_opal_map (struct ics *ics,unsigned int virq);
arch/powerpc/sysdev/xics/ics-rtas.c +3 -1
@@ -163,7 +163,9 @@ static struct irq_chip ics_rtas_irq_chip = { .irq_mask = ics_rtas_mask_irq, .irq_unmask = ics_rtas_unmask_irq, .irq_eoi = NULL, /* Patched at init time */ - .irq_set_affinity = ics_rtas_set_affinity + .irq_set_affinity = ics_rtas_set_affinity, + .irq_set_type = xics_set_irq_type, + .irq_retrigger = xics_retrigger, };static int ics_rtas_map (struct ics *ics,unsigned int virq)
arch/powerpc/sysdev/xics/xics-common.c +50 -7
71 lines not on this page · raw message
Michael Ellerman
reviewerQuoted 18 lines · Benjamin Herrenschmidt
This sets the type of the interrupt appropriately. We set it as follow:
- If not mapped from the device-tree, we use edge. This is the case
of the virtual interrupts and PCI MSIs for example.- If mapped from the device-tree and #interrupt-cells is 2 (PAPR
compliant), we use the second cell to set the appropriate type- If mapped from the device-tree and #interrupt-cells is 1 (current
OPAL on P8 does that), we assume level sensitive since those are typically going to be the PSI LSIs which are level sensitive.Additionally, we mark the interrupts requested via the
opal_interruptsproperty all level. This is a bit fishy but the best we can do until we fix OPAL to properly expose them with a complete descriptor. It is also correct for the current HW anyway as OPAL interrupts are currently PCI error and PSI interrupts which are level.
Quoted 7 lines
Finally now that edge interrupts are properly identified, we can enable
CONFIG_HARDIRQS_SW_RESENDwhich will make the core re-send them if they occur while masked, which some drivers rely upon.This fixes issues with lost interrupts on some Mellanox adapters.
Signed-off-by Benjamin Herrenschmidt <[email protected]>
Broken since forever?
Cc stable?
cheers
Quoted 11 lines · Michael Ellerman
Quoted 7 lines
Finally now that edge interrupts are properly identified, we can enable
CONFIG_HARDIRQS_SW_RESENDwhich will make the core re-send them if they occur while masked, which some drivers rely upon.This fixes issues with lost interrupts on some Mellanox adapters.
Quoted 1 line
Signed-off-by Benjamin Herrenschmidt <[email protected]>Broken since forever?
Cc stable?
Broken since forever but I want a bit more testing before that goes to stable. Some drivers like Mellanox had a workaround but they want to remove it.
Cheers,
Ben.
Michael Ellerman
reviewerQuoted 9 lines · Benjamin Herrenschmidt
Quoted 8 lines · Michael Ellerman
Quoted 7 lines
Finally now that edge interrupts are properly identified, we can enable
CONFIG_HARDIRQS_SW_RESENDwhich will make the core re-send them if they occur while masked, which some drivers rely upon.This fixes issues with lost interrupts on some Mellanox adapters.
Quoted 1 line
Signed-off-by Benjamin Herrenschmidt <[email protected]>
Quoted 7 lines
Quoted 3 lines
Broken since forever?
Cc stable?
Broken since forever but I want a bit more testing before that goes to stable. Some drivers like Mellanox had a workaround but they want to remove it.
OK.
I've put it in fixes-test (should end up in fixes), and added it to my "probably for stable" list:
https://github.com/linuxppc/linux/issues/51
cheers
Michael Ellerman
AppliedQuoted 18 lines · Benjamin Herrenschmidt
This sets the type of the interrupt appropriately. We set it as follow:
- If not mapped from the device-tree, we use edge. This is the case
of the virtual interrupts and PCI MSIs for example.- If mapped from the device-tree and #interrupt-cells is 2 (PAPR
compliant), we use the second cell to set the appropriate type- If mapped from the device-tree and #interrupt-cells is 1 (current
OPAL on P8 does that), we assume level sensitive since those are typically going to be the PSI LSIs which are level sensitive.Additionally, we mark the interrupts requested via the
opal_interruptsproperty all level. This is a bit fishy but the best we can do until we fix OPAL to properly expose them with a complete descriptor. It is also correct for the current HW anyway as OPAL interrupts are currently PCI error and PSI interrupts which are level.
Quoted 7 lines
Finally now that edge interrupts are properly identified, we can enable
CONFIG_HARDIRQS_SW_RESENDwhich will make the core re-send them if they occur while masked, which some drivers rely upon.This fixes issues with lost interrupts on some Mellanox adapters.
Signed-off-by Benjamin Herrenschmidt <[email protected]>
Applied to powerpc fixes, thanks.
https://git.kernel.org/powerpc/c/880a3d6afd068682d6386a0528
cheers