| From 5d246e343440ee4915109dac66543d02d71ca900 Mon Sep 17 00:00:00 2001 |
| From: Xiaoliang Yang <xiaoliang.yang_1@nxp.com> |
| Date: Tue, 11 Feb 2020 15:33:46 +0800 |
| Subject: [PATCH] LF-457: ocelot: tsn: clean preempt interrupt status |
| |
| The INTB interrupt is used both for 1588 interrupt and preemption status |
| change interrupt on each port. So clean preempt status interrupt in IRQ |
| handle function. Without handling it, driver may get interrupt storm. |
| |
| Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com> |
| Reviewed-by: Po Liu <Po.Liu@nxp.com> |
| --- |
| drivers/net/dsa/ocelot/felix.c | 5 +---- |
| drivers/net/ethernet/mscc/ocelot_tsn.c | 14 ++++++++++++++ |
| include/soc/mscc/ocelot.h | 1 + |
| 3 files changed, 16 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/net/dsa/ocelot/felix.c |
| +++ b/drivers/net/dsa/ocelot/felix.c |
| @@ -688,12 +688,9 @@ static irqreturn_t felix_irq_handler(int |
| |
| /* The INTB interrupt is used for both PTP TX timestamp interrupt |
| * and preemption status change interrupt on each port. |
| - * |
| - * - Get txtstamp if have |
| - * - TODO: handle preemption. Without handling it, driver may get |
| - * interrupt storm. |
| */ |
| |
| + ocelot_preempt_irq_clean(ocelot); |
| ocelot_get_txtstamp(ocelot); |
| |
| return IRQ_HANDLED; |
| --- a/drivers/net/ethernet/mscc/ocelot_tsn.c |
| +++ b/drivers/net/ethernet/mscc/ocelot_tsn.c |
| @@ -1570,3 +1570,17 @@ int ocelot_dscp_set(struct ocelot *ocelo |
| |
| return 0; |
| } |
| + |
| +void ocelot_preempt_irq_clean(struct ocelot *ocelot) |
| +{ |
| + struct ocelot_port *ocelot_port; |
| + int port; |
| + u32 val; |
| + |
| + val = DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_ACTIVE_STICKY; |
| + for (port = 0; port < ocelot->num_phys_ports; port++) { |
| + ocelot_port = ocelot->ports[port]; |
| + ocelot_port_rmwl(ocelot_port, val, val, |
| + DEV_GMII_MM_STATISTICS_MM_STATUS); |
| + } |
| +} |
| --- a/include/soc/mscc/ocelot.h |
| +++ b/include/soc/mscc/ocelot.h |
| @@ -592,4 +592,5 @@ int ocelot_rtag_parse_enable(struct ocel |
| int ocelot_dscp_set(struct ocelot *ocelot, int port, |
| bool enable, const u8 dscp_ix, |
| struct tsn_qos_switch_dscp_conf *c); |
| +void ocelot_preempt_irq_clean(struct ocelot *ocelot); |
| #endif |