From 68430e200e6de56731e5acc8c85d6e987a13db72 Mon Sep 17 00:00:00 2001 From: Xiaoliang Yang 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 Reviewed-by: Po Liu (cherry picked from commit 0df3452eb1dec497ed75a7f804142e30972601b3) --- 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(-) diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 545b02cf1978..e4c17074a0d2 100644 --- 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 irq, void *data) /* 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; diff --git a/drivers/net/ethernet/mscc/ocelot_tsn.c b/drivers/net/ethernet/mscc/ocelot_tsn.c index d272736b704e..b8fcbfd810ce 100644 --- 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 *ocelot, int port, 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); + } +} diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index 7bee5bc9f878..08371f98361f 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -592,4 +592,5 @@ int ocelot_rtag_parse_enable(struct ocelot *ocelot, u8 port); 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