diff mbox series

[net] net: phy: ti: take into account all possible interrupt sources

Message ID 20210226153020.867852-1-ciorneiioana@gmail.com (mailing list archive)
State Accepted
Delegated to: Netdev Maintainers
Headers show
Series [net] net: phy: ti: take into account all possible interrupt sources | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Clearly marked for net
netdev/subject_prefix success Link
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 66 lines checked
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/header_inline success Link
netdev/stable success Stable not CCed

Commit Message

Ioana Ciornei Feb. 26, 2021, 3:30 p.m. UTC
From: Ioana Ciornei <ioana.ciornei@nxp.com>

The previous implementation of .handle_interrupt() did not take into
account the fact that all the interrupt status registers should be
acknowledged since multiple interrupt sources could be asserted.

Fix this by reading all the status registers before exiting with
IRQ_NONE or triggering the PHY state machine.

Fixes: 1d1ae3c6ca3f ("net: phy: ti: implement generic .handle_interrupt() callback")
Reported-by: Sven Schuchmann <schuchmann@schleissheimer.de>
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/net/phy/dp83822.c   |  9 +++++----
 drivers/net/phy/dp83tc811.c | 11 ++++++-----
 2 files changed, 11 insertions(+), 9 deletions(-)

Comments

Jakub Kicinski Feb. 28, 2021, 8 p.m. UTC | #1
On Fri, 26 Feb 2021 17:30:20 +0200 Ioana Ciornei wrote:
> diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
> index be1224b4447b..f7a2ec150e54 100644
> --- a/drivers/net/phy/dp83822.c
> +++ b/drivers/net/phy/dp83822.c
> @@ -290,6 +290,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
>  
>  static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
>  {
> +	bool trigger_machine = false;
>  	int irq_status;
>  
>  	/* The MISR1 and MISR2 registers are holding the interrupt status in
> @@ -305,7 +306,7 @@ static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
>  		return IRQ_NONE;
>  	}
>  	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
> -		goto trigger_machine;
> +		trigger_machine = true;
>  
>  	irq_status = phy_read(phydev, MII_DP83822_MISR2);
>  	if (irq_status < 0) {
> @@ -313,11 +314,11 @@ static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
>  		return IRQ_NONE;
>  	}
>  	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
> -		goto trigger_machine;
> +		trigger_machine = true;
>  
> -	return IRQ_NONE;
> +	if (!trigger_machine)
> +		return IRQ_NONE;
>  
> -trigger_machine:
>  	phy_trigger_machine(phydev);
>  
>  	return IRQ_HANDLED;

Would it be better to code it up as:

	irqreturn_t ret = IRQ_NONE;

	if (irq_status & ...)
		ret = IRQ_HANDLED;

	/* .. */

	if (ret != IRQ_NONE)
		phy_trigger_machine(phydev);

	return ret;

That reads a tiny bit better to me, but it's probably majorly
subjective so I'm happy with existing patch if you prefer it.
Ioana Ciornei March 1, 2021, 8:21 a.m. UTC | #2
On Sun, Feb 28, 2021 at 12:00:27PM -0800, Jakub Kicinski wrote:
> On Fri, 26 Feb 2021 17:30:20 +0200 Ioana Ciornei wrote:
> > diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
> > index be1224b4447b..f7a2ec150e54 100644
> > --- a/drivers/net/phy/dp83822.c
> > +++ b/drivers/net/phy/dp83822.c
> > @@ -290,6 +290,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
> >  
> >  static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
> >  {
> > +	bool trigger_machine = false;
> >  	int irq_status;
> >  
> >  	/* The MISR1 and MISR2 registers are holding the interrupt status in
> > @@ -305,7 +306,7 @@ static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
> >  		return IRQ_NONE;
> >  	}
> >  	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
> > -		goto trigger_machine;
> > +		trigger_machine = true;
> >  
> >  	irq_status = phy_read(phydev, MII_DP83822_MISR2);
> >  	if (irq_status < 0) {
> > @@ -313,11 +314,11 @@ static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
> >  		return IRQ_NONE;
> >  	}
> >  	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
> > -		goto trigger_machine;
> > +		trigger_machine = true;
> >  
> > -	return IRQ_NONE;
> > +	if (!trigger_machine)
> > +		return IRQ_NONE;
> >  
> > -trigger_machine:
> >  	phy_trigger_machine(phydev);
> >  
> >  	return IRQ_HANDLED;
> 
> Would it be better to code it up as:
> 
> 	irqreturn_t ret = IRQ_NONE;
> 
> 	if (irq_status & ...)
> 		ret = IRQ_HANDLED;
> 
> 	/* .. */
> 
> 	if (ret != IRQ_NONE)
> 		phy_trigger_machine(phydev);
> 
> 	return ret;
> 
> That reads a tiny bit better to me, but it's probably majorly
> subjective so I'm happy with existing patch if you prefer it.

I think I prefer it as it is and this is because it would be in line
with all the other PHY drivers which do this:

	if (!(irq_status & int_enabled))
		return IRQ_NONE;

	phy_trigger_machine(phydev);

	return IRQ_HANDLED;

Ioana
Jakub Kicinski March 1, 2021, 7:48 p.m. UTC | #3
On Mon, 1 Mar 2021 10:21:14 +0200 Ioana Ciornei wrote:
> On Sun, Feb 28, 2021 at 12:00:27PM -0800, Jakub Kicinski wrote:
> > On Fri, 26 Feb 2021 17:30:20 +0200 Ioana Ciornei wrote:  
> > > diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
> > > index be1224b4447b..f7a2ec150e54 100644
> > > --- a/drivers/net/phy/dp83822.c
> > > +++ b/drivers/net/phy/dp83822.c
> > > @@ -290,6 +290,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
> > >  
> > >  static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
> > >  {
> > > +	bool trigger_machine = false;
> > >  	int irq_status;
> > >  
> > >  	/* The MISR1 and MISR2 registers are holding the interrupt status in
> > > @@ -305,7 +306,7 @@ static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
> > >  		return IRQ_NONE;
> > >  	}
> > >  	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
> > > -		goto trigger_machine;
> > > +		trigger_machine = true;
> > >  
> > >  	irq_status = phy_read(phydev, MII_DP83822_MISR2);
> > >  	if (irq_status < 0) {
> > > @@ -313,11 +314,11 @@ static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
> > >  		return IRQ_NONE;
> > >  	}
> > >  	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
> > > -		goto trigger_machine;
> > > +		trigger_machine = true;
> > >  
> > > -	return IRQ_NONE;
> > > +	if (!trigger_machine)
> > > +		return IRQ_NONE;
> > >  
> > > -trigger_machine:
> > >  	phy_trigger_machine(phydev);
> > >  
> > >  	return IRQ_HANDLED;  
> > 
> > Would it be better to code it up as:
> > 
> > 	irqreturn_t ret = IRQ_NONE;
> > 
> > 	if (irq_status & ...)
> > 		ret = IRQ_HANDLED;
> > 
> > 	/* .. */
> > 
> > 	if (ret != IRQ_NONE)
> > 		phy_trigger_machine(phydev);
> > 
> > 	return ret;
> > 
> > That reads a tiny bit better to me, but it's probably majorly
> > subjective so I'm happy with existing patch if you prefer it.  
> 
> I think I prefer it as it is and this is because it would be in line
> with all the other PHY drivers which do this:
> 
> 	if (!(irq_status & int_enabled))
> 		return IRQ_NONE;
> 
> 	phy_trigger_machine(phydev);
> 

Okay, applied, thanks!
diff mbox series

Patch

diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
index be1224b4447b..f7a2ec150e54 100644
--- a/drivers/net/phy/dp83822.c
+++ b/drivers/net/phy/dp83822.c
@@ -290,6 +290,7 @@  static int dp83822_config_intr(struct phy_device *phydev)
 
 static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
 {
+	bool trigger_machine = false;
 	int irq_status;
 
 	/* The MISR1 and MISR2 registers are holding the interrupt status in
@@ -305,7 +306,7 @@  static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
 		return IRQ_NONE;
 	}
 	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
-		goto trigger_machine;
+		trigger_machine = true;
 
 	irq_status = phy_read(phydev, MII_DP83822_MISR2);
 	if (irq_status < 0) {
@@ -313,11 +314,11 @@  static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
 		return IRQ_NONE;
 	}
 	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
-		goto trigger_machine;
+		trigger_machine = true;
 
-	return IRQ_NONE;
+	if (!trigger_machine)
+		return IRQ_NONE;
 
-trigger_machine:
 	phy_trigger_machine(phydev);
 
 	return IRQ_HANDLED;
diff --git a/drivers/net/phy/dp83tc811.c b/drivers/net/phy/dp83tc811.c
index 688fadffb249..7ea32fb77190 100644
--- a/drivers/net/phy/dp83tc811.c
+++ b/drivers/net/phy/dp83tc811.c
@@ -264,6 +264,7 @@  static int dp83811_config_intr(struct phy_device *phydev)
 
 static irqreturn_t dp83811_handle_interrupt(struct phy_device *phydev)
 {
+	bool trigger_machine = false;
 	int irq_status;
 
 	/* The INT_STAT registers 1, 2 and 3 are holding the interrupt status
@@ -279,7 +280,7 @@  static irqreturn_t dp83811_handle_interrupt(struct phy_device *phydev)
 		return IRQ_NONE;
 	}
 	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
-		goto trigger_machine;
+		trigger_machine = true;
 
 	irq_status = phy_read(phydev, MII_DP83811_INT_STAT2);
 	if (irq_status < 0) {
@@ -287,7 +288,7 @@  static irqreturn_t dp83811_handle_interrupt(struct phy_device *phydev)
 		return IRQ_NONE;
 	}
 	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
-		goto trigger_machine;
+		trigger_machine = true;
 
 	irq_status = phy_read(phydev, MII_DP83811_INT_STAT3);
 	if (irq_status < 0) {
@@ -295,11 +296,11 @@  static irqreturn_t dp83811_handle_interrupt(struct phy_device *phydev)
 		return IRQ_NONE;
 	}
 	if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
-		goto trigger_machine;
+		trigger_machine = true;
 
-	return IRQ_NONE;
+	if (!trigger_machine)
+		return IRQ_NONE;
 
-trigger_machine:
 	phy_trigger_machine(phydev);
 
 	return IRQ_HANDLED;