Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "can: sja1000: Prepare the use of a threaded handler"

Miquel Raynal provides a series for the sja1000 driver to work around
overrun stalls with a soft reset on Renesas SoCs.

Link: https://lore.kernel.org/all/20230616134553.2786391-1-miquel.raynal@bootlin.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

+39 -7
+34 -6
drivers/net/can/sja1000/sja1000.c
··· 387 387 netif_rx(skb); 388 388 } 389 389 390 + static irqreturn_t sja1000_reset_interrupt(int irq, void *dev_id) 391 + { 392 + struct net_device *dev = (struct net_device *)dev_id; 393 + 394 + netdev_dbg(dev, "performing a soft reset upon overrun\n"); 395 + sja1000_start(dev); 396 + 397 + return IRQ_HANDLED; 398 + } 399 + 390 400 static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) 391 401 { 392 402 struct sja1000_priv *priv = netdev_priv(dev); ··· 407 397 enum can_state rx_state, tx_state; 408 398 unsigned int rxerr, txerr; 409 399 uint8_t ecc, alc; 400 + int ret = 0; 410 401 411 402 skb = alloc_can_err_skb(dev, &cf); 412 403 if (skb == NULL) ··· 424 413 stats->rx_over_errors++; 425 414 stats->rx_errors++; 426 415 sja1000_write_cmdreg(priv, CMD_CDO); /* clear bit */ 416 + 417 + /* Some controllers needs additional handling upon overrun 418 + * condition: the controller may sometimes be totally confused 419 + * and refuse any new frame while its buffer is empty. The only 420 + * way to re-sync the read vs. write buffer offsets is to 421 + * stop any current handling and perform a reset. 422 + */ 423 + if (priv->flags & SJA1000_QUIRK_RESET_ON_OVERRUN) 424 + ret = IRQ_WAKE_THREAD; 427 425 } 428 426 429 427 if (isrc & IRQ_EI) { ··· 512 492 513 493 netif_rx(skb); 514 494 515 - return 0; 495 + return ret; 516 496 } 517 497 518 498 irqreturn_t sja1000_interrupt(int irq, void *dev_id) ··· 521 501 struct sja1000_priv *priv = netdev_priv(dev); 522 502 struct net_device_stats *stats = &dev->stats; 523 503 uint8_t isrc, status; 524 - int n = 0; 504 + irqreturn_t ret = 0; 505 + int n = 0, err; 525 506 526 507 if (priv->pre_irq) 527 508 priv->pre_irq(priv); ··· 567 546 } 568 547 if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) { 569 548 /* error interrupt */ 570 - if (sja1000_err(dev, isrc, status)) 549 + err = sja1000_err(dev, isrc, status); 550 + if (err == IRQ_WAKE_THREAD) 551 + ret = err; 552 + if (err) 571 553 break; 572 554 } 573 555 n++; 574 556 } 575 557 out: 558 + if (!ret) 559 + ret = (n) ? IRQ_HANDLED : IRQ_NONE; 560 + 576 561 if (priv->post_irq) 577 562 priv->post_irq(priv); 578 563 579 564 if (n >= SJA1000_MAX_IRQ) 580 565 netdev_dbg(dev, "%d messages handled in ISR", n); 581 566 582 - return (n) ? IRQ_HANDLED : IRQ_NONE; 567 + return ret; 583 568 } 584 569 EXPORT_SYMBOL_GPL(sja1000_interrupt); 585 570 ··· 604 577 605 578 /* register interrupt handler, if not done by the device driver */ 606 579 if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER)) { 607 - err = request_irq(dev->irq, sja1000_interrupt, priv->irq_flags, 608 - dev->name, (void *)dev); 580 + err = request_threaded_irq(dev->irq, sja1000_interrupt, 581 + sja1000_reset_interrupt, 582 + priv->irq_flags, dev->name, (void *)dev); 609 583 if (err) { 610 584 close_candev(dev); 611 585 return -EAGAIN;
+1
drivers/net/can/sja1000/sja1000.h
··· 147 147 */ 148 148 #define SJA1000_CUSTOM_IRQ_HANDLER BIT(0) 149 149 #define SJA1000_QUIRK_NO_CDR_REG BIT(1) 150 + #define SJA1000_QUIRK_RESET_ON_OVERRUN BIT(2) 150 151 151 152 /* 152 153 * SJA1000 private data structure
+4 -1
drivers/net/can/sja1000/sja1000_platform.c
··· 106 106 107 107 static void sp_rzn1_init(struct sja1000_priv *priv, struct device_node *of) 108 108 { 109 - priv->flags = SJA1000_QUIRK_NO_CDR_REG; 109 + priv->flags = SJA1000_QUIRK_NO_CDR_REG | SJA1000_QUIRK_RESET_ON_OVERRUN; 110 110 } 111 111 112 112 static void sp_populate(struct sja1000_priv *priv, ··· 276 276 } else { 277 277 priv->irq_flags = IRQF_SHARED; 278 278 } 279 + 280 + if (priv->flags & SJA1000_QUIRK_RESET_ON_OVERRUN) 281 + priv->irq_flags |= IRQF_ONESHOT; 279 282 280 283 dev->irq = irq; 281 284 priv->reg_base = addr;