netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] of_mdio: fix phy interrupt passing
@ 2014-02-17 16:29 Ben Dooks
       [not found] ` < 20140218093024.D0E94C403C8@trevor.secretlab.ca>
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Ben Dooks @ 2014-02-17 16:29 UTC (permalink / raw)
  To: grant.likely-QSEj5FYQhm4dnm+yROfE0A
  Cc: linux-kernel-81qHHgoATdFT9dQujB1mzip2UmYkHbXO,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA,
	sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8, Ben Dooks

The of_mdiobus_register_phy() is not setting phy->irq this causing
some drivers to incorrectly assume that the PHY does not have an
IRQ associated with it or install an interrupt handler for the
PHY.

Simplify the code setting irq and set the phy->irq at the same
time so that the case if mdio->irq is not NULL is easier to read.

This fixes the issue:
 net eth0: attached PHY 1 (IRQ -1) to driver Micrel KSZ8041RNLI

to the correct:
 net eth0: attached PHY 1 (IRQ 416) to driver Micrel KSZ8041RNLI

Signed-off-by: Ben Dooks <ben.dooks-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org>
---
 drivers/of/of_mdio.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 875b7b6..7b3e7b0 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -44,7 +44,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
 {
 	struct phy_device *phy;
 	bool is_c45;
-	int rc, prev_irq;
+	int rc;
 	u32 max_speed = 0;
 
 	is_c45 = of_device_is_compatible(child,
@@ -55,11 +55,11 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
 		return 1;
 
 	if (mdio->irq) {
-		prev_irq = mdio->irq[addr];
-		mdio->irq[addr] =
-			irq_of_parse_and_map(child, 0);
-		if (!mdio->irq[addr])
-			mdio->irq[addr] = prev_irq;
+		rc = irq_of_parse_and_map(child, 0);
+		if (rc > 0) {
+			mdio->irq[addr] = rc;
+			phy->irq = rc;
+		}
 	}
 
 	/* Associate the OF node with the device structure so it
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] of_mdio: fix phy interrupt passing
  2014-02-17 16:29 [PATCH] of_mdio: fix phy interrupt passing Ben Dooks
       [not found] ` < 20140218093024.D0E94C403C8@trevor.secretlab.ca>
@ 2014-02-17 17:26 ` Florian Fainelli
  2014-02-17 17:42   ` Ben Dooks
  2014-02-17 17:56   ` Ben Dooks
  2014-02-18  9:30 ` Grant Likely
  2 siblings, 2 replies; 11+ messages in thread
From: Florian Fainelli @ 2014-02-17 17:26 UTC (permalink / raw)
  To: Ben Dooks
  Cc: Grant Likely, linux-kernel, devicetree, linux-kernel, netdev,
	Linux-sh list, Sergei Shtylyov

Hi Ben,

2014-02-17 8:29 GMT-08:00 Ben Dooks <ben.dooks@codethink.co.uk>:
> The of_mdiobus_register_phy() is not setting phy->irq this causing
> some drivers to incorrectly assume that the PHY does not have an
> IRQ associated with it or install an interrupt handler for the
> PHY.
>
> Simplify the code setting irq and set the phy->irq at the same
> time so that the case if mdio->irq is not NULL is easier to read.

The real bug fix, which is not properly explained here, is that
irq_of_parse_and_map() should return values > 0 when the interrupt is
valid, so this makes me wonder why we are not propagating the return
value from irq_of_parse_and_map() in case the call to
of_irq_parse_one() does return something non-zero?

Other than that, I agree with the resolution, but it deserves a better
commit message, and eventually doing this in two steps:

- first fix the bug by changing the if (!mdio->irq[addr]) into a if
(mdio->irq[addr] <= 0)
- second submit a patch which cleanups the assignment

>
> This fixes the issue:
>  net eth0: attached PHY 1 (IRQ -1) to driver Micrel KSZ8041RNLI
>
> to the correct:
>  net eth0: attached PHY 1 (IRQ 416) to driver Micrel KSZ8041RNLI
>
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
>  drivers/of/of_mdio.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
> index 875b7b6..7b3e7b0 100644
> --- a/drivers/of/of_mdio.c
> +++ b/drivers/of/of_mdio.c
> @@ -44,7 +44,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
>  {
>         struct phy_device *phy;
>         bool is_c45;
> -       int rc, prev_irq;
> +       int rc;
>         u32 max_speed = 0;
>
>         is_c45 = of_device_is_compatible(child,
> @@ -55,11 +55,11 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
>                 return 1;
>
>         if (mdio->irq) {
> -               prev_irq = mdio->irq[addr];
> -               mdio->irq[addr] =
> -                       irq_of_parse_and_map(child, 0);
> -               if (!mdio->irq[addr])
> -                       mdio->irq[addr] = prev_irq;
> +               rc = irq_of_parse_and_map(child, 0);
> +               if (rc > 0) {
> +                       mdio->irq[addr] = rc;
> +                       phy->irq = rc;
> +               }
>         }
>
>         /* Associate the OF node with the device structure so it
> --
> 1.8.5.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Florian

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] of_mdio: fix phy interrupt passing
  2014-02-17 17:26 ` Florian Fainelli
@ 2014-02-17 17:42   ` Ben Dooks
  2014-02-17 17:48     ` Florian Fainelli
  2014-02-17 17:56   ` Ben Dooks
  1 sibling, 1 reply; 11+ messages in thread
From: Ben Dooks @ 2014-02-17 17:42 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Grant Likely, linux-kernel, devicetree, linux-kernel, netdev,
	Linux-sh list, Sergei Shtylyov

On 17/02/14 17:26, Florian Fainelli wrote:
> Hi Ben,
>
> 2014-02-17 8:29 GMT-08:00 Ben Dooks <ben.dooks@codethink.co.uk>:
>> The of_mdiobus_register_phy() is not setting phy->irq this causing
>> some drivers to incorrectly assume that the PHY does not have an
>> IRQ associated with it or install an interrupt handler for the
>> PHY.
>>
>> Simplify the code setting irq and set the phy->irq at the same
>> time so that the case if mdio->irq is not NULL is easier to read.
>
> The real bug fix, which is not properly explained here, is that
> irq_of_parse_and_map() should return values > 0 when the interrupt is
> valid, so this makes me wonder why we are not propagating the return
> value from irq_of_parse_and_map() in case the call to
> of_irq_parse_one() does return something non-zero?

No, the first issue is phy->dev never gets set, which causes the
issue. The cleanup was added as it seemed easier to put it in with
this.

I think phy->irq is already initialised to PHY_POLL and thus there
is no need to set phy->irq if the irq_of_parse_and_map() fails.

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] of_mdio: fix phy interrupt passing
  2014-02-17 17:42   ` Ben Dooks
@ 2014-02-17 17:48     ` Florian Fainelli
  2014-02-17 17:58       ` Ben Dooks
  2014-02-19 20:18       ` Sergei Shtylyov
  0 siblings, 2 replies; 11+ messages in thread
From: Florian Fainelli @ 2014-02-17 17:48 UTC (permalink / raw)
  To: Ben Dooks
  Cc: Grant Likely, linux-kernel, devicetree, linux-kernel, netdev,
	Linux-sh list, Sergei Shtylyov

2014-02-17 9:42 GMT-08:00 Ben Dooks <ben.dooks@codethink.co.uk>:
> On 17/02/14 17:26, Florian Fainelli wrote:
>>
>> Hi Ben,
>>
>> 2014-02-17 8:29 GMT-08:00 Ben Dooks <ben.dooks@codethink.co.uk>:
>>>
>>> The of_mdiobus_register_phy() is not setting phy->irq this causing
>>> some drivers to incorrectly assume that the PHY does not have an
>>> IRQ associated with it or install an interrupt handler for the
>>> PHY.
>>>
>>> Simplify the code setting irq and set the phy->irq at the same
>>> time so that the case if mdio->irq is not NULL is easier to read.
>>
>>
>> The real bug fix, which is not properly explained here, is that
>> irq_of_parse_and_map() should return values > 0 when the interrupt is
>> valid, so this makes me wonder why we are not propagating the return
>> value from irq_of_parse_and_map() in case the call to
>> of_irq_parse_one() does return something non-zero?
>
>
> No, the first issue is phy->dev never gets set, which causes the
> issue. The cleanup was added as it seemed easier to put it in with
> this.

Ok, that really needs to be mentioned in the commit message, even
being quite familiar (and possibly dumb too) with the code, I could
not figure this out by reading your patch.

>
> I think phy->irq is already initialised to PHY_POLL and thus there
> is no need to set phy->irq if the irq_of_parse_and_map() fails.

That is correct, the reason why I introduced 7d97637 ("net: of_mdio:
do not overwrite PHY interrupt configuration") was that you are also
allowed to change the irq type before calling into
of_mdiobus_register(), so we want to preserve other irq values being
set here, such as PHY_IGNORE_INTERRUPT. Your patch does take care of
that since it only overrides the irq in case we could parse it.
-- 
Florian

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] of_mdio: fix phy interrupt passing
  2014-02-17 17:26 ` Florian Fainelli
  2014-02-17 17:42   ` Ben Dooks
@ 2014-02-17 17:56   ` Ben Dooks
  1 sibling, 0 replies; 11+ messages in thread
From: Ben Dooks @ 2014-02-17 17:56 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Grant Likely, linux-kernel, devicetree, linux-kernel, netdev,
	Linux-sh list, Sergei Shtylyov

On 17/02/14 17:26, Florian Fainelli wrote:
> Hi Ben,
>
> 2014-02-17 8:29 GMT-08:00 Ben Dooks <ben.dooks@codethink.co.uk>:
>> The of_mdiobus_register_phy() is not setting phy->irq this causing
>> some drivers to incorrectly assume that the PHY does not have an
>> IRQ associated with it or install an interrupt handler for the
>> PHY.
>>
>> Simplify the code setting irq and set the phy->irq at the same
>> time so that the case if mdio->irq is not NULL is easier to read.
>
> The real bug fix, which is not properly explained here, is that
> irq_of_parse_and_map() should return values > 0 when the interrupt is
> valid, so this makes me wonder why we are not propagating the return
> value from irq_of_parse_and_map() in case the call to
> of_irq_parse_one() does return something non-zero?

	rc = irq_of_parse_and_map(child, 0);
	if (rc > 0) {
		mdio->irq[addr] = rc;
		phy->irq = rc;
	}

Unfortunately we do not get any idea of what error went wrong
when doing this, all we get it 0 on failure. So we cannot tell
if the problem was due to no interrupt being there or there was
an interrupt and it could not be parsed properly.

The best we can do is assume that the PHY is happy with being
polled and the specific driver will error out if it expects to
be able to work with an interrupt.

If we error out, we may end up stopping any PHYs where there is
no interrupt available from working. Also, if we fail to parse
then we can generally fall back to polling.

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] of_mdio: fix phy interrupt passing
  2014-02-17 17:48     ` Florian Fainelli
@ 2014-02-17 17:58       ` Ben Dooks
  2014-02-19 20:18       ` Sergei Shtylyov
  1 sibling, 0 replies; 11+ messages in thread
From: Ben Dooks @ 2014-02-17 17:58 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Grant Likely, linux-kernel, devicetree, linux-kernel, netdev,
	Linux-sh list, Sergei Shtylyov

On 17/02/14 17:48, Florian Fainelli wrote:
> 2014-02-17 9:42 GMT-08:00 Ben Dooks <ben.dooks@codethink.co.uk>:
>> On 17/02/14 17:26, Florian Fainelli wrote:
>>>
>>> Hi Ben,
>>>
>>> 2014-02-17 8:29 GMT-08:00 Ben Dooks <ben.dooks@codethink.co.uk>:
>>>>
>>>> The of_mdiobus_register_phy() is not setting phy->irq this causing
>>>> some drivers to incorrectly assume that the PHY does not have an
>>>> IRQ associated with it or install an interrupt handler for the
>>>> PHY.
>>>>
>>>> Simplify the code setting irq and set the phy->irq at the same
>>>> time so that the case if mdio->irq is not NULL is easier to read.
>>>
>>>
>>> The real bug fix, which is not properly explained here, is that
>>> irq_of_parse_and_map() should return values > 0 when the interrupt is
>>> valid, so this makes me wonder why we are not propagating the return
>>> value from irq_of_parse_and_map() in case the call to
>>> of_irq_parse_one() does return something non-zero?
>>
>>
>> No, the first issue is phy->dev never gets set, which causes the
>> issue. The cleanup was added as it seemed easier to put it in with
>> this.
>
> Ok, that really needs to be mentioned in the commit message, even
> being quite familiar (and possibly dumb too) with the code, I could
> not figure this out by reading your patch.
>
>>
>> I think phy->irq is already initialised to PHY_POLL and thus there
>> is no need to set phy->irq if the irq_of_parse_and_map() fails.
>
> That is correct, the reason why I introduced 7d97637 ("net: of_mdio:
> do not overwrite PHY interrupt configuration") was that you are also
> allowed to change the irq type before calling into
> of_mdiobus_register(), so we want to preserve other irq values being
> set here, such as PHY_IGNORE_INTERRUPT. Your patch does take care of
> that since it only overrides the irq in case we could parse it.

Ok, the first sentence has a spell of thus, but does refer to phy->irq
being the problem we are looking to fix in this patch.

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] of_mdio: fix phy interrupt passing
  2014-02-17 16:29 [PATCH] of_mdio: fix phy interrupt passing Ben Dooks
       [not found] ` < 20140218093024.D0E94C403C8@trevor.secretlab.ca>
  2014-02-17 17:26 ` Florian Fainelli
@ 2014-02-18  9:30 ` Grant Likely
  2014-02-18  9:40   ` Ben Dooks
  2 siblings, 1 reply; 11+ messages in thread
From: Grant Likely @ 2014-02-18  9:30 UTC (permalink / raw)
  To: Ben Dooks
  Cc: linux-kernel, devicetree, linux-kernel, netdev, linux-sh,
	sergei.shtylyov, Ben Dooks

On Mon, 17 Feb 2014 16:29:40 +0000, Ben Dooks <ben.dooks@codethink.co.uk> wrote:
> The of_mdiobus_register_phy() is not setting phy->irq this causing
> some drivers to incorrectly assume that the PHY does not have an
> IRQ associated with it or install an interrupt handler for the
> PHY.
> 
> Simplify the code setting irq and set the phy->irq at the same
> time so that the case if mdio->irq is not NULL is easier to read.
> 
> This fixes the issue:
>  net eth0: attached PHY 1 (IRQ -1) to driver Micrel KSZ8041RNLI
> 
> to the correct:
>  net eth0: attached PHY 1 (IRQ 416) to driver Micrel KSZ8041RNLI
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
>  drivers/of/of_mdio.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
> index 875b7b6..7b3e7b0 100644
> --- a/drivers/of/of_mdio.c
> +++ b/drivers/of/of_mdio.c
> @@ -44,7 +44,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
>  {
>  	struct phy_device *phy;
>  	bool is_c45;
> -	int rc, prev_irq;
> +	int rc;
>  	u32 max_speed = 0;
>  
>  	is_c45 = of_device_is_compatible(child,
> @@ -55,11 +55,11 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
>  		return 1;
>  
>  	if (mdio->irq) {
> -		prev_irq = mdio->irq[addr];
> -		mdio->irq[addr] =
> -			irq_of_parse_and_map(child, 0);
> -		if (!mdio->irq[addr])
> -			mdio->irq[addr] = prev_irq;

I cannot for the life for me remeber why the code was structured that
way. Your change is better.

> +		rc = irq_of_parse_and_map(child, 0);
> +		if (rc > 0) {
> +			mdio->irq[addr] = rc;
> +			phy->irq = rc;
> +		}
>  	}

The outer if is merely protecting against no irq array being allocated
for the bus. Would not the following be better:

	rc = irq_of_parse_and_map(child, 0);
	if (rc > 0) {
		phy->irq = rc;
		if (mdio->irq)
			mdio->irq[addr] = rc;
	}

g.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] of_mdio: fix phy interrupt passing
  2014-02-18  9:30 ` Grant Likely
@ 2014-02-18  9:40   ` Ben Dooks
  2014-02-18 17:02     ` Grant Likely
  0 siblings, 1 reply; 11+ messages in thread
From: Ben Dooks @ 2014-02-18  9:40 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, devicetree, linux-kernel, netdev, linux-sh,
	sergei.shtylyov

On 18/02/14 09:30, Grant Likely wrote:
> On Mon, 17 Feb 2014 16:29:40 +0000, Ben Dooks <ben.dooks@codethink.co.uk> wrote:
>> The of_mdiobus_register_phy() is not setting phy->irq this causing
>> some drivers to incorrectly assume that the PHY does not have an
>> IRQ associated with it or install an interrupt handler for the
>> PHY.
>>
>> Simplify the code setting irq and set the phy->irq at the same
>> time so that the case if mdio->irq is not NULL is easier to read.
>>
>> This fixes the issue:
>>   net eth0: attached PHY 1 (IRQ -1) to driver Micrel KSZ8041RNLI
>>
>> to the correct:
>>   net eth0: attached PHY 1 (IRQ 416) to driver Micrel KSZ8041RNLI
>>
>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>> ---
>>   drivers/of/of_mdio.c | 12 ++++++------
>>   1 file changed, 6 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
>> index 875b7b6..7b3e7b0 100644
>> --- a/drivers/of/of_mdio.c
>> +++ b/drivers/of/of_mdio.c
>> @@ -44,7 +44,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
>>   {
>>   	struct phy_device *phy;
>>   	bool is_c45;
>> -	int rc, prev_irq;
>> +	int rc;
>>   	u32 max_speed = 0;
>>
>>   	is_c45 = of_device_is_compatible(child,
>> @@ -55,11 +55,11 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
>>   		return 1;
>>
>>   	if (mdio->irq) {
>> -		prev_irq = mdio->irq[addr];
>> -		mdio->irq[addr] =
>> -			irq_of_parse_and_map(child, 0);
>> -		if (!mdio->irq[addr])
>> -			mdio->irq[addr] = prev_irq;
>
> I cannot for the life for me remeber why the code was structured that
> way. Your change is better.
>
>> +		rc = irq_of_parse_and_map(child, 0);
>> +		if (rc > 0) {
>> +			mdio->irq[addr] = rc;
>> +			phy->irq = rc;
>> +		}
>>   	}
>
> The outer if is merely protecting against no irq array being allocated
> for the bus. Would not the following be better:
>
> 	rc = irq_of_parse_and_map(child, 0);
> 	if (rc > 0) {
> 		phy->irq = rc;
> 		if (mdio->irq)
> 			mdio->irq[addr] = rc;
> 	}

Thanks, that makes sense, although we've both failed to work
out if mdio->irq is set, and rc <= 0 case, so:

  	rc = irq_of_parse_and_map(child, 0);
  	if (rc > 0) {
  		phy->irq = rc;
  		if (mdio->irq)
  			mdio->irq[addr] = rc;
  	} else {
		if (mdio->irq)
			phy->irq = mdio->irq[addr];
	}

I think that covers all cases. This does rely on mdio->irq
being initialised to PHY_POLL if allocated.

Once this is in, it may be easier then to not allocate
mdio->irq for the OF case by default unless the driver
registering the PHY knows it has the interrupt number(s)
for the PHY already.

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] of_mdio: fix phy interrupt passing
  2014-02-18  9:40   ` Ben Dooks
@ 2014-02-18 17:02     ` Grant Likely
  2014-02-18 18:06       ` Sergei Shtylyov
  0 siblings, 1 reply; 11+ messages in thread
From: Grant Likely @ 2014-02-18 17:02 UTC (permalink / raw)
  To: Ben Dooks
  Cc: linux-kernel, devicetree, linux-kernel, netdev, linux-sh,
	sergei.shtylyov

On Tue, 18 Feb 2014 09:40:39 +0000, Ben Dooks <ben.dooks@codethink.co.uk> wrote:
> On 18/02/14 09:30, Grant Likely wrote:
> > On Mon, 17 Feb 2014 16:29:40 +0000, Ben Dooks <ben.dooks@codethink.co.uk> wrote:
> >> The of_mdiobus_register_phy() is not setting phy->irq this causing
> >> some drivers to incorrectly assume that the PHY does not have an
> >> IRQ associated with it or install an interrupt handler for the
> >> PHY.
> >>
> >> Simplify the code setting irq and set the phy->irq at the same
> >> time so that the case if mdio->irq is not NULL is easier to read.
> >>
> >> This fixes the issue:
> >>   net eth0: attached PHY 1 (IRQ -1) to driver Micrel KSZ8041RNLI
> >>
> >> to the correct:
> >>   net eth0: attached PHY 1 (IRQ 416) to driver Micrel KSZ8041RNLI
> >>
> >> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> >> ---
> >>   drivers/of/of_mdio.c | 12 ++++++------
> >>   1 file changed, 6 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
> >> index 875b7b6..7b3e7b0 100644
> >> --- a/drivers/of/of_mdio.c
> >> +++ b/drivers/of/of_mdio.c
> >> @@ -44,7 +44,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
> >>   {
> >>   	struct phy_device *phy;
> >>   	bool is_c45;
> >> -	int rc, prev_irq;
> >> +	int rc;
> >>   	u32 max_speed = 0;
> >>
> >>   	is_c45 = of_device_is_compatible(child,
> >> @@ -55,11 +55,11 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
> >>   		return 1;
> >>
> >>   	if (mdio->irq) {
> >> -		prev_irq = mdio->irq[addr];
> >> -		mdio->irq[addr] =
> >> -			irq_of_parse_and_map(child, 0);
> >> -		if (!mdio->irq[addr])
> >> -			mdio->irq[addr] = prev_irq;
> >
> > I cannot for the life for me remeber why the code was structured that
> > way. Your change is better.
> >
> >> +		rc = irq_of_parse_and_map(child, 0);
> >> +		if (rc > 0) {
> >> +			mdio->irq[addr] = rc;
> >> +			phy->irq = rc;
> >> +		}
> >>   	}
> >
> > The outer if is merely protecting against no irq array being allocated
> > for the bus. Would not the following be better:
> >
> > 	rc = irq_of_parse_and_map(child, 0);
> > 	if (rc > 0) {
> > 		phy->irq = rc;
> > 		if (mdio->irq)
> > 			mdio->irq[addr] = rc;
> > 	}
> 
> Thanks, that makes sense, although we've both failed to work
> out if mdio->irq is set, and rc <= 0 case, so:
> 
>   	rc = irq_of_parse_and_map(child, 0);
>   	if (rc > 0) {
>   		phy->irq = rc;
>   		if (mdio->irq)
>   			mdio->irq[addr] = rc;
>   	} else {
> 		if (mdio->irq)
> 			phy->irq = mdio->irq[addr];
> 	}

Is this actually a valid thing to do? I think the only time mdio->irq[]
is non-zero is when it is set to PHY_POLL. Is it valid to set phy->irq
to PHY_POLL? I didn't think it was.

g.

> 
> I think that covers all cases. This does rely on mdio->irq
> being initialised to PHY_POLL if allocated.
> 
> Once this is in, it may be easier then to not allocate
> mdio->irq for the OF case by default unless the driver
> registering the PHY knows it has the interrupt number(s)
> for the PHY already.
> 
> -- 
> Ben Dooks				http://www.codethink.co.uk/
> Senior Engineer				Codethink - Providing Genius

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] of_mdio: fix phy interrupt passing
  2014-02-18 17:02     ` Grant Likely
@ 2014-02-18 18:06       ` Sergei Shtylyov
  0 siblings, 0 replies; 11+ messages in thread
From: Sergei Shtylyov @ 2014-02-18 18:06 UTC (permalink / raw)
  To: Grant Likely, Ben Dooks
  Cc: linux-kernel, devicetree, linux-kernel, netdev, linux-sh

Hello.

On 02/18/2014 08:02 PM, Grant Likely wrote:

>>> On Mon, 17 Feb 2014 16:29:40 +0000, Ben Dooks <ben.dooks@codethink.co.uk> wrote:
>>>> The of_mdiobus_register_phy() is not setting phy->irq this causing
>>>> some drivers to incorrectly assume that the PHY does not have an
>>>> IRQ associated with it or install an interrupt handler for the
>>>> PHY.

>>>> Simplify the code setting irq and set the phy->irq at the same
>>>> time so that the case if mdio->irq is not NULL is easier to read.

>>>> This fixes the issue:
>>>>    net eth0: attached PHY 1 (IRQ -1) to driver Micrel KSZ8041RNLI

>>>> to the correct:
>>>>    net eth0: attached PHY 1 (IRQ 416) to driver Micrel KSZ8041RNLI

>>>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>>>> ---
>>>>    drivers/of/of_mdio.c | 12 ++++++------
>>>>    1 file changed, 6 insertions(+), 6 deletions(-)

>>>> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
>>>> index 875b7b6..7b3e7b0 100644
>>>> --- a/drivers/of/of_mdio.c
>>>> +++ b/drivers/of/of_mdio.c
>>>> @@ -44,7 +44,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
>>>>    {
>>>>    	struct phy_device *phy;
>>>>    	bool is_c45;
>>>> -	int rc, prev_irq;
>>>> +	int rc;
>>>>    	u32 max_speed = 0;
>>>>
>>>>    	is_c45 = of_device_is_compatible(child,
>>>> @@ -55,11 +55,11 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
>>>>    		return 1;
>>>>
>>>>    	if (mdio->irq) {
>>>> -		prev_irq = mdio->irq[addr];
>>>> -		mdio->irq[addr] =
>>>> -			irq_of_parse_and_map(child, 0);
>>>> -		if (!mdio->irq[addr])
>>>> -			mdio->irq[addr] = prev_irq;

>>> I cannot for the life for me remeber why the code was structured that
>>> way. Your change is better.

>>>> +		rc = irq_of_parse_and_map(child, 0);
>>>> +		if (rc > 0) {
>>>> +			mdio->irq[addr] = rc;
>>>> +			phy->irq = rc;
>>>> +		}
>>>>    	}

>>> The outer if is merely protecting against no irq array being allocated
>>> for the bus. Would not the following be better:

>>> 	rc = irq_of_parse_and_map(child, 0);
>>> 	if (rc > 0) {
>>> 		phy->irq = rc;
>>> 		if (mdio->irq)
>>> 			mdio->irq[addr] = rc;
>>> 	}

>> Thanks, that makes sense, although we've both failed to work
>> out if mdio->irq is set, and rc <= 0 case, so:

>>    	rc = irq_of_parse_and_map(child, 0);
>>    	if (rc > 0) {
>>    		phy->irq = rc;
>>    		if (mdio->irq)
>>    			mdio->irq[addr] = rc;
>>    	} else {
>> 		if (mdio->irq)
>> 			phy->irq = mdio->irq[addr];
>> 	}

> Is this actually a valid thing to do? I think the only time mdio->irq[]
> is non-zero is when it is set to PHY_POLL. Is it valid to set phy->irq
> to PHY_POLL? I didn't think it was.

    It is valid, AFAIK.

> g.

>> --
>> Ben Dooks				http://www.codethink.co.uk/
>> Senior Engineer				Codethink - Providing Genius

WBR, Sergei


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] of_mdio: fix phy interrupt passing
  2014-02-17 17:48     ` Florian Fainelli
  2014-02-17 17:58       ` Ben Dooks
@ 2014-02-19 20:18       ` Sergei Shtylyov
  1 sibling, 0 replies; 11+ messages in thread
From: Sergei Shtylyov @ 2014-02-19 20:18 UTC (permalink / raw)
  To: Florian Fainelli, Ben Dooks
  Cc: Grant Likely, linux-kernel, devicetree, linux-kernel, netdev,
	Linux-sh list

Hello.

On 02/17/2014 08:48 PM, Florian Fainelli wrote:

>>>> The of_mdiobus_register_phy() is not setting phy->irq this causing
>>>> some drivers to incorrectly assume that the PHY does not have an
>>>> IRQ associated with it or install an interrupt handler for the
>>>> PHY.

>>>> Simplify the code setting irq and set the phy->irq at the same
>>>> time so that the case if mdio->irq is not NULL is easier to read.

>>> The real bug fix, which is not properly explained here, is that
>>> irq_of_parse_and_map() should return values > 0 when the interrupt is
>>> valid, so this makes me wonder why we are not propagating the return
>>> value from irq_of_parse_and_map() in case the call to
>>> of_irq_parse_one() does return something non-zero?

>> No, the first issue is phy->dev never gets set, which causes the
>> issue. The cleanup was added as it seemed easier to put it in with
>> this.

> Ok, that really needs to be mentioned in the commit message, even
> being quite familiar (and possibly dumb too) with the code, I could
> not figure this out by reading your patch.

    Yes, the main issue was that phy->irq wasn't overridden from the value set 
by phy_device_create().

>> I think phy->irq is already initialised to PHY_POLL and thus there
>> is no need to set phy->irq if the irq_of_parse_and_map() fails.

> That is correct, the reason why I introduced 7d97637 ("net: of_mdio:
> do not overwrite PHY interrupt configuration") was that you are also
> allowed to change the irq type before calling into
> of_mdiobus_register(),

    Not really: of_mdiobus_register() init's all of mdio->irq[] with IRQ_POLL, 
thus wiping out all of the previous initialization, so I don't know what you 
did achieve with the aforementioned commit.

> so we want to preserve other irq values being
> set here, such as PHY_IGNORE_INTERRUPT. Your patch does take care of
> that since it only overrides the irq in case we could parse it.

    And it should have stayed that way. The latter change was unnecessary.

WBR, Sergei


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-02-19 20:18 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-17 16:29 [PATCH] of_mdio: fix phy interrupt passing Ben Dooks
     [not found] ` < 20140218093024.D0E94C403C8@trevor.secretlab.ca>
2014-02-17 17:26 ` Florian Fainelli
2014-02-17 17:42   ` Ben Dooks
2014-02-17 17:48     ` Florian Fainelli
2014-02-17 17:58       ` Ben Dooks
2014-02-19 20:18       ` Sergei Shtylyov
2014-02-17 17:56   ` Ben Dooks
2014-02-18  9:30 ` Grant Likely
2014-02-18  9:40   ` Ben Dooks
2014-02-18 17:02     ` Grant Likely
2014-02-18 18:06       ` Sergei Shtylyov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).