Date
1 - 8 of 8
[PATCH 5.10.y-cip] can: rcar_canfd: fix channel specific IRQ handling for RZ/G2L
Biju Das
commit d887087c896881715c1a82f1d4f71fbfe5344ffd upstream.
RZ/G2L has separate channel specific IRQs for transmit and error interrupts. But the IRQ handler processes both channels, even if there no interrupt occurred on one of the channels. This patch fixes the issue by passing a channel specific context parameter instead of global one for the IRQ register and the IRQ handler, it just handles the channel which is triggered the interrupt. Fixes: 76e9353a80e9 ("can: rcar_canfd: Add support for RZ/G2L family") Signed-off-by: Biju Das <biju.das.jz@...> Link: https://lore.kernel.org/all/20221025155657.1426948-3-biju.das.jz@bp.renesas.com Cc: stable@... [mkl: adjust commit message] Signed-off-by: Marc Kleine-Budde <mkl@...> [biju: fixed the conflicts manually] Signed-off-by: Biju Das <biju.das.jz@...> --- drivers/net/can/rcar/rcar_canfd.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index 8acae71eb8bf..feba57833cdc 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -1195,11 +1195,9 @@ static void rcar_canfd_handle_channel_tx(struct rcar_canfd_global *gpriv, u32 ch static irqreturn_t rcar_canfd_channel_tx_interrupt(int irq, void *dev_id) { - struct rcar_canfd_global *gpriv = dev_id; - u32 ch; + struct rcar_canfd_channel *priv = dev_id; - for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) - rcar_canfd_handle_channel_tx(gpriv, ch); + rcar_canfd_handle_channel_tx(priv->gpriv, priv->channel); return IRQ_HANDLED; } @@ -1227,11 +1225,9 @@ static void rcar_canfd_handle_channel_err(struct rcar_canfd_global *gpriv, u32 c static irqreturn_t rcar_canfd_channel_err_interrupt(int irq, void *dev_id) { - struct rcar_canfd_global *gpriv = dev_id; - u32 ch; + struct rcar_canfd_channel *priv = dev_id; - for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) - rcar_canfd_handle_channel_err(gpriv, ch); + rcar_canfd_handle_channel_err(priv->gpriv, priv->channel); return IRQ_HANDLED; } @@ -1649,6 +1645,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, priv->ndev = ndev; priv->base = gpriv->base; priv->channel = ch; + priv->gpriv = gpriv; priv->can.clock.freq = fcan_freq; dev_info(&pdev->dev, "can_clk rate is %u\n", priv->can.clock.freq); @@ -1677,7 +1674,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, } err = devm_request_irq(&pdev->dev, err_irq, rcar_canfd_channel_err_interrupt, 0, - irq_name, gpriv); + irq_name, priv); if (err) { dev_err(&pdev->dev, "devm_request_irq CH Err(%d) failed, error %d\n", err_irq, err); @@ -1691,7 +1688,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, } err = devm_request_irq(&pdev->dev, tx_irq, rcar_canfd_channel_tx_interrupt, 0, - irq_name, gpriv); + irq_name, priv); if (err) { dev_err(&pdev->dev, "devm_request_irq Tx (%d) failed, error %d\n", tx_irq, err); @@ -1715,7 +1712,6 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, priv->can.do_set_mode = rcar_canfd_do_set_mode; priv->can.do_get_berr_counter = rcar_canfd_get_berr_counter; - priv->gpriv = gpriv; SET_NETDEV_DEV(ndev, &pdev->dev); netif_napi_add(ndev, &priv->napi, rcar_canfd_rx_poll, -- 2.25.1 |
|
Pavel Machek
Hi!
commit d887087c896881715c1a82f1d4f71fbfe5344ffd upstream.Can you elaborate what "the issue" is? AFAICT the code worked before, and will work after the patch, with maybe tiny little less overhead after the patch? Thanks and best regards, Pavel static irqreturn_t rcar_canfd_channel_tx_interrupt(int irq, void *dev_id)-- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany |
|
Biju Das
Subject: Re: [PATCH 5.10.y-cip] can: rcar_canfd: fix channel specificBasically, tx IRQs are channel specific. Previously if any txIRQ is triggered, you are unnecessarily Checking IRQ status of the txIRQ which is not triggered. For eg: if ch0 IRQ is triggered you are checking for ch1 IRQ status as well. Similarly, if ch1 IRQ is triggered, then you are checking ch0 IRQ status. Previous implementation is good for shared IRQ's like R-Car Cheers, Biju static irqreturn_t rcar_canfd_channel_tx_interrupt(int irq, void-- |
|
Pavel Machek
Hi!
Understood, but checking ch1 status on ch0 IRQ is not going to causeBasically, tx IRQs are channel specific.RZ/G2L has separate channel specific IRQs for transmit and errorthere any problems, right? Best regards, Pavel -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany |
|
Biju Das
Subject: Re: [PATCH 5.10.y-cip] can: rcar_canfd: fix channel specificIRQ processing should be fast as possible. You are improving latency of the system by avoiding unnecessary checks and by calling an unwanted function call. If it is shared IRQ, then it make sense you don't have any other alternative. Since you have dedicated handler, make use of it and don't call any Unnecessary function and checks in IRQ routine. Cheers, Biju |
|
Pavel Machek
Hi!
I understand it is just a performance tweak. Correct me if I'm wrong.IRQ processing should be fast as possible. You are improving latency ofFor eg: if ch0 IRQ is triggered you are checking for ch1 IRQ statusaswell. Similarly, if ch1 IRQ is triggered, then you are checking ch0Understood, but checking ch1 status on ch0 IRQ is not going to cause If there are no other comments and if testing passes I can apply the patch. Best regards, Pavel -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany |
|
Biju Das
Subject: Re: [PATCH 5.10.y-cip] can: rcar_canfd: fix channel specificYes, performance is one thing, also it will avoid unnecessary races when you start handling IRQ's in both the cores. Eg:- ch0 IRQ handler executed on core0 and ch1 IRQ handler on core 1, which unnecessarily calls ch0 routine. See the races in rcar_canfd_tx_done(). Cheers, Biju
|
|
Pavel Machek
Hi!
commit d887087c896881715c1a82f1d4f71fbfe5344ffd upstream.Thank you, applied. Best regards, Pavel -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany |
|