diff mbox series

[v2] net: phy: realtek: Dummy IRQ calls for RTL8366RB

Message ID 20190224001115.17497-1-linus.walleij@linaro.org
State Accepted
Delegated to: David Miller
Headers show
Series [v2] net: phy: realtek: Dummy IRQ calls for RTL8366RB | expand

Commit Message

Linus Walleij Feb. 24, 2019, 12:11 a.m. UTC
This fixes a regression introduced by
commit 0d2e778e38e0ddffab4bb2b0e9ed2ad5165c4bf7
"net: phy: replace PHY_HAS_INTERRUPT with a check for
config_intr and ack_interrupt".

This assumes that a PHY cannot trigger interrupt unless
it has .config_intr() or .ack_interrupt() implemented.
A later patch makes the code assume both need to be
implemented for interrupts to be present.

But this PHY (which is inside a DSA) will happily
fire interrupts without either callback.

Implement dummy callbacks for .config_intr() and
.ack_interrupt() in the phy header to fix this.

Tested on the RTL8366RB on D-Link DIR-685.

Fixes: 0d2e778e38e0 ("net: phy: replace PHY_HAS_INTERRUPT with a check for config_intr and ack_interrupt")
Cc: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Define generic inline helpers for
  genphy_no_ack_interrupt and genphy_no_config_intr
- Add a comment block explaining how interrupts are
  unmasked and ACKed in the RTL8366RB internal irqchip
  so it is clear what is going on.
---
 drivers/net/phy/realtek.c | 7 +++++++
 include/linux/phy.h       | 8 ++++++++
 2 files changed, 15 insertions(+)

Comments

Andrew Lunn Feb. 24, 2019, 1 a.m. UTC | #1
On Sun, Feb 24, 2019 at 01:11:15AM +0100, Linus Walleij wrote:
> This fixes a regression introduced by
> commit 0d2e778e38e0ddffab4bb2b0e9ed2ad5165c4bf7
> "net: phy: replace PHY_HAS_INTERRUPT with a check for
> config_intr and ack_interrupt".
> 
> This assumes that a PHY cannot trigger interrupt unless
> it has .config_intr() or .ack_interrupt() implemented.
> A later patch makes the code assume both need to be
> implemented for interrupts to be present.
> 
> But this PHY (which is inside a DSA) will happily
> fire interrupts without either callback.
> 
> Implement dummy callbacks for .config_intr() and
> .ack_interrupt() in the phy header to fix this.
> 
> Tested on the RTL8366RB on D-Link DIR-685.
> 
> Fixes: 0d2e778e38e0 ("net: phy: replace PHY_HAS_INTERRUPT with a check for config_intr and ack_interrupt")
> Cc: Heiner Kallweit <hkallweit1@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew
David Miller Feb. 24, 2019, 2:46 a.m. UTC | #2
From: Linus Walleij <linus.walleij@linaro.org>
Date: Sun, 24 Feb 2019 01:11:15 +0100

> This fixes a regression introduced by
> commit 0d2e778e38e0ddffab4bb2b0e9ed2ad5165c4bf7
> "net: phy: replace PHY_HAS_INTERRUPT with a check for
> config_intr and ack_interrupt".
> 
> This assumes that a PHY cannot trigger interrupt unless
> it has .config_intr() or .ack_interrupt() implemented.
> A later patch makes the code assume both need to be
> implemented for interrupts to be present.
> 
> But this PHY (which is inside a DSA) will happily
> fire interrupts without either callback.
> 
> Implement dummy callbacks for .config_intr() and
> .ack_interrupt() in the phy header to fix this.
> 
> Tested on the RTL8366RB on D-Link DIR-685.
> 
> Fixes: 0d2e778e38e0 ("net: phy: replace PHY_HAS_INTERRUPT with a check for config_intr and ack_interrupt")
> Cc: Heiner Kallweit <hkallweit1@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Applied.
diff mbox series

Patch

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index c6010fb1aa0f..cb4a23041a94 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -282,6 +282,13 @@  static struct phy_driver realtek_drvs[] = {
 		.name		= "RTL8366RB Gigabit Ethernet",
 		.features	= PHY_GBIT_FEATURES,
 		.config_init	= &rtl8366rb_config_init,
+		/* These interrupts are handled by the irq controller
+		 * embedded inside the RTL8366RB, they get unmasked when the
+		 * irq is requested and ACKed by reading the status register,
+		 * which is done by the irqchip code.
+		 */
+		.ack_interrupt	= genphy_no_ack_interrupt,
+		.config_intr	= genphy_no_config_intr,
 		.suspend	= genphy_suspend,
 		.resume		= genphy_resume,
 	},
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 127fcc9c3778..333b56d8f746 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -992,6 +992,14 @@  static inline int genphy_no_soft_reset(struct phy_device *phydev)
 {
 	return 0;
 }
+static inline int genphy_no_ack_interrupt(struct phy_device *phydev)
+{
+	return 0;
+}
+static inline int genphy_no_config_intr(struct phy_device *phydev)
+{
+	return 0;
+}
 int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad,
 				u16 regnum);
 int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum,