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

Message ID 20190224001115.17497-1-linus.walleij@linaro.org
State New
Headers show
Series
  • [v2] net: phy: realtek: Dummy IRQ calls for RTL8366RB
Related show

Commit Message

Linus Walleij Feb. 24, 2019, 12:11 a.m.
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(+)

-- 
2.20.1

Comments

Andrew Lunn Feb. 24, 2019, 1 a.m. | #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. | #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.

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,