net: phy: at803x: don't depend on GPIOLIB
Subsystems (3)
PATCH 1/1 net: phy: at803x: don't depend on GPIOLIB
Commit 687908c2b649 ("net: phy: at803x: simplify using devm_gpiod_get_optional and its 4th argument") introduced a dependency on GPIOLIB that was not there before.
This commit removes such dependency by checking the return code and comparing it against ENOSYS which is returned when GPIOLIB is not selected.
devm_gpiod_get_optional and its 4th argument")
--- drivers/net/phy/at803x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/phy/at803x.c +3 -1
@@ -252,7 +252,9 @@ static int at803x_probe(struct phy_device *phydev)return -ENOMEM ; gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); -if (IS_ERR (gpiod_reset)) +if (PTR_ERR (gpiod_reset) == -ENOSYS ) + gpiod_reset =NULL ; +else if (IS_ERR (gpiod_reset))return PTR_ERR (gpiod_reset); priv->gpiod_reset = gpiod_reset;
Signature · 1 line
2.1.4
[ CCing a few devs who might be interested ]
Quoted 32 lines · Sebastian Frias
Commit
687908c2b649("net: phy: at803x: simplify usingdevm_gpiod_get_optionaland its 4th argument") introduced a dependency on GPIOLIB that was not there before.This commit removes such dependency by checking the return code and comparing it against ENOSYS which is returned when GPIOLIB is not selected.
Fixes 687908c2b649 ("net: phy: at803x: simplify using
devm_gpiod_get_optionaland its 4th argument")Signed-off-by Sebastian Frias <[email protected]>--- drivers/net/phy/at803x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/net/phy/at803x.c +3
-1@@ -252,7 +252,9 @@ static int at803x_probe(struct phy_device *phydev)return -ENOMEM ; gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); -if (IS_ERR (gpiod_reset)) +if (PTR_ERR (gpiod_reset) == -ENOSYS ) + gpiod_reset =NULL ; +else if (IS_ERR (gpiod_reset))return PTR_ERR (gpiod_reset); priv->gpiod_reset = gpiod_reset;
[expand cc a bit more]
Hello,
Quoted 20 lines · Sebastian Frias
Commit
687908c2b649("net: phy: at803x: simplify usingdevm_gpiod_get_optionaland its 4th argument") introduced a dependency on GPIOLIB that was not there before.This commit removes such dependency by checking the return code and comparing it against ENOSYS which is returned when GPIOLIB is not selected.
Fixes 687908c2b649 ("net: phy: at803x: simplify using devm_gpiod_get_optional and its 4th argument")Signed-off-by Sebastian Frias <[email protected]>--- drivers/net/phy/at803x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/net/phy/at803x.c +0
-0
drivers/net/phy/at803x.c static int at803x_probe(struct phy_device *phydev) · line 257
Quoted 7 lines
drivers/net/phy/at803x.c +3
-1@@ -252,7 +252,9 @@ static int at803x_probe(struct phy_device *phydev)return -ENOMEM ; gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); -if (IS_ERR (gpiod_reset)) +if (PTR_ERR (gpiod_reset) == -ENOSYS ) + gpiod_reset =NULL ; +else if (IS_ERR (gpiod_reset))
this isn't better either (IMHO it's worse, but maybe this is debatable and also depends on your POV).
With 687908c2b649 I made kernels without GPIOLIB fail to bind this device. I admit this is not maximally nice.
Your change makes the driver bind in this case again and then the reset gpio isn't handled at all which might result in a later and harder to debug error.
The better approach to fix your problem is: make the driver depend (or force) on GPIOLIB. Or alternatively, drop reset-handling from the driver.
From a driver perspecitive, it would be nice if devm_gpiod_get_optional returned NULL iff the respective gpio isn't specified even with GPIOLIB=n, but this isn't sensible either because it would result in quite some gpiolib code to not being conditionally compiled on CONFIG_GPIOLIB any more.
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ |
Hi Uwe, Daniel,
Quoted 27 lines · Uwe Kleine-König
[expand cc a bit more]
Hello,
Quoted 22 lines · Sebastian Frias
Commit
687908c2b649("net: phy: at803x: simplify usingdevm_gpiod_get_optionaland its 4th argument") introduced a dependency on GPIOLIB that was not there before.This commit removes such dependency by checking the return code and comparing it against ENOSYS which is returned when GPIOLIB is not selected.
Fixes 687908c2b649 ("net: phy: at803x: simplify using devm_gpiod_get_optional and its 4th argument")Signed-off-by Sebastian Frias <[email protected]>--- drivers/net/phy/at803x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/net/phy/at803x.c +0
-0@@ -252,7 +252,9 @@ static int at803x_probe(struct phy_device *phydev)return -ENOMEM ;
Quoted 8 lines
drivers/net/phy/at803x.c static int at803x_probe(struct phy_device *phydev) · line 257
Quoted 5 lines
drivers/net/phy/at803x.c +3
-1gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); -if (IS_ERR (gpiod_reset)) +if (PTR_ERR (gpiod_reset) == -ENOSYS ) + gpiod_reset =NULL ; +else if (IS_ERR (gpiod_reset))this isn't better either (IMHO it's worse, but maybe this is debatable and also depends on your POV).
Well, from the code, the reset hack is only required when the PHY is ATH8030_PHY_ID, right?
However, such change was introduced by Daniel Mack on commit 13a56b449325. Hopefully he can chime in and give his opinion on this.
Daniel, while on the subject, I have a question for you:
Change 2b8f2a28eac1 introduced "link_status_notify" callback which is called systematically on the PHY state machine.
Any reason to make the call systematic as opposed to let say:
if (phydev->state != old_state) {
if (phydev->drv->link_change_notify)
phydev->drv->link_change_notify(phydev);
}(it does means that the callback would be called after the state machine processing though)
Quoted 3 lines
With
687908c2b649I made kernels without GPIOLIB fail to bind this device. I admit this is not maximally nice.
I see, that was not clear from the commit message, sorry.
Quoted 7 lines
Your change makes the driver bind in this case again and then the reset gpio isn't handled at all which might result in a later and harder to debug error.
The better approach to fix your problem is: make the driver depend (or force) on GPIOLIB.
It was one of the solutions I had in mind, but:
- since the dependency on GPIOLIB was not included on the patch
- and given that the previous code had provision to work without GPIO I thought it was an overlook.
Quoted 8 lines
Or alternatively, drop reset-handling from the
driver.From a driver perspecitive, it would be nice if
devm_gpiod_get_optionalreturned NULL iff the respective gpio isn't specified even with GPIOLIB=n, but this isn't sensible either because it would result in quite some gpiolib code to not being conditionally compiled onCONFIG_GPIOLIBany more.
Let's say that was the case, what would the PHY code do?
I mean, it did not get a GPIO, whether it was because GPIOLIB=n or because there's no 'reset' GPIO attached
Shall it fail? Shall it continue in a sort of degraded mode? Shall it warn? Because that's the real question here.
What would you think of making at803x_link_change_notify() print a message every time it should do a reset but does not has a way to do it? I can make such change to my patch if everybody agrees on it. By the way, in that case, can somebody suggest a way to print such warning? Would printk() be ok or should I use dev_dbg() ?
Best regards,
Sebastian
Quoted 4 lines
Best regards
Uwe
Hello Sebastian,
Quoted 8 lines · Sebastian Frias
Quoted 5 lines · Uwe Kleine-König
From a driver perspecitive, it would be nice if
devm_gpiod_get_optionalreturned NULL iff the respective gpio isn't specified even with GPIOLIB=n, but this isn't sensible either because it would result in quite some gpiolib code to not being conditionally compiled onCONFIG_GPIOLIBany more.Let's say that was the case, what would the PHY code do?
With reset gpios it might not be that critical, but consider an optional enable gpio. (Optional in the sense, that some device have it and others don't, e.g. because the pin is pulled into active level by hardware.)
Now you do:
gpiod = gpiod_get_optional("enable");and if gpiod now is an error pointer, you must assume that you cannot operate the device. And even with GPIOLIB=n (and gpiod = ERR_PTR(-ENOSYS)) you cannot ignore the error. For consistency I'd recommend to do the same for reset even though there is a chance to get a working device.
Quoted 2 lines
What would you think of making
at803x_link_change_notify()print a message every time it should do a reset but does not has a way to do it?
Then this question is obsolete because the device doesn't probe.
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ |
Quoted 6 lines · Uwe Kleine-König
Quoted 2 lines · Sebastian Frias
What would you think of making
at803x_link_change_notify()print a message every time it should do a reset but does not has a way to do it?Then this question is obsolete because the device doesn't probe.
I don't understand this statement.
What does it mean for a question to be obsolete?
Regards.
Hello,
Quoted 4 lines · Mason
Quoted 2 lines · Uwe Kleine-König
On Fri, Mar 18, 2016 at 04:56:21PM +0100, Sebastian Frias wrote:
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
What would you think of making
at803x_link_change_notify()print a message every time it should do a reset but does not has a way to do it?Then this question is obsolete because the device doesn't probe.
I don't understand this statement.
What does it mean for a question to be obsolete?
If the driver doesn't probe because it cannot control the reset line, you don't need to think about how it should behave in at803x_link_change_notify without control of the reset line, because this code isn't reached then.
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ |
Quoted 13 lines · Uwe Kleine-König
Hello,
Quoted 9 lines · Mason
Quoted 6 lines · Uwe Kleine-König
Quoted 2 lines · Sebastian Frias
What would you think of making
at803x_link_change_notify()print a message every time it should do a reset but does not has a way to do it?Then this question is obsolete because the device doesn't probe.
Quoted 8 lines
Quoted 3 lines
I don't understand this statement.
What does it mean for a question to be obsolete?
If the driver doesn't probe because it cannot control the reset line, you don't need to think about how it should behave in
at803x_link_change_notifywithout control of the reset line, because this code isn't reached then.
If I understand correctly, it is possible to soft-reset the PHY by writing to a specific register. The GPIO pin is useful only to force a hardware-reset when the PHY is wedged by some random event.
(Or am I completely off the mark?)
Regards.
Quoted 19 lines · Mason
Quoted 17 lines · Uwe Kleine-König
Hello,
Quoted 12 lines · Mason
Quoted 6 lines · Uwe Kleine-König
Quoted 2 lines · Sebastian Frias
What would you think of making
at803x_link_change_notify()print a message every time it should do a reset but does not has a way to do it?Then this question is obsolete because the device doesn't probe.
I don't understand this statement.
What does it mean for a question to be obsolete?
Quoted 8 lines
Quoted 4 lines
If the driver doesn't probe because it cannot control the reset line, you don't need to think about how it should behave in
at803x_link_change_notifywithout control of the reset line, because this code isn't reached then.If I understand correctly, it is possible to soft-reset the PHY by writing to a specific register. The GPIO pin is useful only to force a hardware-reset when the PHY is wedged by some random event.
Yes, and some variants of this phy are broken and require a hard reset in certain situations. At least that's what the comment in the code says.
Signature · 1 line
Måns Rullgård
Hi Uwe,
Quoted 16 lines · Uwe Kleine-König
Hello Sebastian,
Quoted 8 lines · Sebastian Frias
Quoted 5 lines · Uwe Kleine-König
From a driver perspecitive, it would be nice if
devm_gpiod_get_optionalreturned NULL iff the respective gpio isn't specified even with GPIOLIB=n, but this isn't sensible either because it would result in quite some gpiolib code to not being conditionally compiled onCONFIG_GPIOLIBany more.Let's say that was the case, what would the PHY code do?
With reset gpios it might not be that critical, but consider an optional enable gpio. (Optional in the sense, that some device have it and others don't, e.g. because the pin is pulled into active level by hardware.)
Quoted 7 lines
Now you do:
gpiod = gpiod_get_optional("enable");and if gpiod now is an error pointer, you must assume that you cannot operate the device. And even with GPIOLIB=n (and gpiod =
ERR_PTR(-ENOSYS)) you cannot ignore the error.
Two things:
- I suppose that in such hypothetical case the dependency on GPIOLIB would be required and thus be there
- We'd also need to check that 'gpiod' is not NULL
In the scenario at hand only some devices require a hack and gpiod_reset=NULL is valid (ie: device will not fail probing)
Quoted 2 lines
For consistency I'd recommend to do the
same for reset even though there is a chance to get a working device.
I'm not so sure, because then information would be lost, handling both ("enable" and "reset") the same way aliases different intents and requirements.
Indeed, only "enable" would be really mandatory, "reset" is essentially optional (only 1 of 3 devices of the family require the hack).
Besides, if "reset" was really mandatory, we would also fail the probe if the pointer for the reset GPIO is NULL.
Indeed, even with GPIOLIB=y the pointer can be NULL if the "reset" (or "enable" in your scenario) is not present.
From a functionality perspective, a NULL pointer for "reset" will result in the same behaviour as GPIOLIB=n, ie: not being able to reset the PHY.
So, the current code (your commit) and previous code (Daniel's commit) clearly points to "reset" being optional.
Furthermore, I think we should not even register the "link_change_notify" callback when dealing with AT803x PHYs that do not require the hack.
Another solution (considering the callback is statically registered in the "phy_driver" structs for all AT803x PHYs) would be for the callback to disable itself.
Once it detects that the PHY does not require the hack, it could just perform:
phydev->drv->link_change_notify = NULL;
or call a new generic function to do the same if encapsulation is required.
If everybody agrees I can make such change as well, but I really think Daniel should give his opinion first.
Quoted 5 lines
Quoted 3 lines
What would you think of making
at803x_link_change_notify()print a message every time it should do a reset but does not has a way to do it?Then this question is obsolete because the device doesn't probe.
I think you assume that "reset" is mandatory for all AT803x devices, but that's not what the code says.
As such, my proposal was to:
- keep my proposed patch
- make another patch to print a warning when gpiod_reset is NULL (which can happen, even without my patch)
What do you think?
Best regards,
Sebastian
Hello Sebastian,
Quoted 19 lines · Sebastian Frias
Quoted 18 lines · Uwe Kleine-König
Quoted 8 lines · Sebastian Frias
Quoted 5 lines · Uwe Kleine-König
From a driver perspecitive, it would be nice if
devm_gpiod_get_optionalreturned NULL iff the respective gpio isn't specified even with GPIOLIB=n, but this isn't sensible either because it would result in quite some gpiolib code to not being conditionally compiled onCONFIG_GPIOLIBany more.Let's say that was the case, what would the PHY code do?
With reset gpios it might not be that critical, but consider an optional enable gpio. (Optional in the sense, that some device have it and others don't, e.g. because the pin is pulled into active level by hardware.)
Now you do:
gpiod = gpiod_get_optional("enable");
Quoted 7 lines
Quoted 3 lines
and if gpiod now is an error pointer, you must assume that you cannot operate the device. And even with GPIOLIB=n (and gpiod =
ERR_PTR(-ENOSYS)) you cannot ignore the error.Two things:
- I suppose that in such hypothetical case the dependency on GPIOLIB would be required and thus be there
I don't agree. There are bugs out there, and maybe the reason is as simple as "the implementor of the reset-gpio handling had GPIOLIB on and didn't test without GPIOLIB".
Quoted 1 line
- We'd also need to check that 'gpiod' is not NULL
That is the optional part. If gpiod is NULL, you have one of the devices that don't need to handle the enable line.
Quoted 2 lines
In the scenario at hand only some devices require a hack and gpiod_reset=NULL is valid (ie: device will not fail probing)
With your patch and GPIOLIB=n you bind the driver even for the devices that need the hack. This is broken!
Quoted 11 lines
Quoted 2 lines
For consistency I'd recommend to do the
same for reset even though there is a chance to get a working device.I'm not so sure, because then information would be lost, handling both ("enable" and "reset") the same way aliases different intents and requirements.
Indeed, only "enable" would be really mandatory, "reset" is essentially optional (only 1 of 3 devices of the family require the hack).Besides, if "reset" was really mandatory, we would also fail the probe if the pointer for the reset GPIO is NULL.
No, if reset was mandatory you'd use gpiod_get instead of gpiod_get_optional and fail iff that call fails, too.
Quoted 4 lines
Indeed, even with GPIOLIB=y the pointer can be NULL if the "reset" (or "enable" in your scenario) is not present.
From a functionality perspective, a NULL pointer for "reset" will result in the same behaviour as GPIOLIB=n, ie: not being able to reset the PHY.
Right, but you only get reset=NULL iff the device tree (or whatever is the source of information for gpiod_get) doesn't specify a reset gpio which then means "This device doesn't need a reset gpio.". This is different from the GPIOLIB=n case, where the return code signals "It's unknown if the device needs a reset gpio.".
Quoted 20 lines
So, the current code (your commit) and previous code (Daniel's commit) clearly points to "reset" being optional.
Furthermore, I think we should not even register the "
link_change_notify" callback when dealing with AT803x PHYs that do not require the hack.
Another solution (considering the callback is statically registered in the "phy_driver" structs for all AT803x PHYs) would be for the callback to disable itself.
Once it detects that the PHY does not require the hack, it could just perform:phydev->drv->link_change_notify = NULL;or call a new generic function to do the same if encapsulation is required.
If everybody agrees I can make such change as well, but I really think Daniel should give his opinion first.
Quoted 1 line
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
What would you think of making
at803x_link_change_notify()print a message every time it should do a reset but does not has a way to do it?Then this question is obsolete because the device doesn't probe.
I think you assume that "reset" is mandatory for all AT803x devices, but that's not what the code says.
No, you're wrong here. I'm aware that the code supports devices without reset.
Quoted 2 lines
As such, my proposal was to:
- keep my proposed patch
I don't agree.
Quoted 2 lines
- make another patch to print a warning when
gpiod_resetis NULL (which can happen, even without my patch)
This only happens if no reset gpio is needed and in this case the driver does the right thing. So if you ask me, there is no need to modify the driver. Better add a dependency to GPIOLIB. This is necessary even for devices which don't need a reset gpio to answer the question "does this driver need a reset gpio?" correctly.
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ |
Hi Uwe,
Quoted 8 lines · Uwe Kleine-König
Quoted 4 lines
Two things:
- I suppose that in such hypothetical case the dependency on GPIOLIB would be required and thus be thereI don't agree. There are bugs out there, and maybe the reason is as simple as "the implementor of the reset-gpio handling had GPIOLIB on and didn't test without GPIOLIB".
:-) fair enough, let's wait for his comments then.
Quoted 5 lines
Quoted 2 lines
- We'd also need to check that 'gpiod' is not NULL
That is the optional part. If gpiod is NULL, you have one of the devices that don't need to handle the enable line.
gpiod=NULL (because the key is not there) or gpiod=ERR (because GPIOLIB=n + my patch) will result in the same behaviour, ie: driver binds, but fails to reset.
Quoted 6 lines
Quoted 3 lines
In the scenario at hand only some devices require a hack and gpiod_reset=NULL is valid (ie: device will not fail probing)
With your patch and GPIOLIB=n you bind the driver even for the devices that need the hack. This is broken!
It is a degraded mode I agree and had proposed to print a warning. However, I fail to see how is GPIOLIB=n different from just not having "reset" present.
The fact that GPIOLIB=y does not means that the "reset" key will be there. I mean, you assume that "reset" will be present for devices that need the hack, yet there is no such guarantee and the code clearly assumes that it can be missing.
For all we know, the key is actually missing on systems that do use the faulty PHY (all systems designed prior to the hack being implemented) And that, regardless of GPIOLIB status.
Since the reset line can be missing, it can be missing for whatever reason. Whether it is because the "reset" key is not present or because GPIOLIB=n, it does not matter, it will result on the same outcome.
Furthermore, if "reset" is really required for certain devices that need the hack, then both cases:
- GPIOLIB=n
- "reset" not present
should be handled the same way (ie: not bind the driver) for such devices.
By the way, I think not binding the driver is too strong too. Having a GPIO free and being able to route it to the PHY for reset may not even be possible on some systems.
Are they supposed to stop working?
Quoted 10 lines
Quoted 10 lines
Quoted 3 lines
For consistency I'd recommend to do the
same for reset even though there is a chance to get a working device.I'm not so sure, because then information would be lost, handling both ("enable" and "reset") the same way aliases different intents and requirements.
Indeed, only "enable" would be really mandatory, "reset" is essentially optional (only 1 of 3 devices of the family require the hack).
Quoted 5 lines
Quoted 2 lines
Besides, if "reset" was really mandatory, we would also fail the probe if the pointer for the reset GPIO is NULL.
No, if reset was mandatory you'd use
gpiod_getinstead ofgpiod_get_optionaland fail iff that call fails, too.
Ok, but the current code for "reset" is using devm_gpiod_get_optional() so "reset" is clearly optional.
And that call will return NULL if "reset" is not present, even with GPIOLIB=y
Quoted 11 lines
Quoted 5 lines
Indeed, even with GPIOLIB=y the pointer can be NULL if the "reset" (or "enable" in your scenario) is not present.
From a functionality perspective, a NULL pointer for "reset" will result in the same behaviour as GPIOLIB=n, ie: not being able to reset the PHY.Right, but you only get reset=NULL iff the device tree (or whatever is the source of information for
gpiod_get) doesn't specify a reset gpio which then means "This device doesn't need a reset gpio.". This is different from the GPIOLIB=n case, where the return code signals "It's unknown if the device needs a reset gpio.".
I think somehow you try to make a difference on the reason why the reset=INVALID (NULL or ERR), but IMHO there's none.
If somebody using AT8030 PHY (the one that requires the hack) either does not configure a "reset" key on the DT, either does not enable GPIOLIB, the result will be the same.
There is no warning in either case and it will run on a degraded mode.
Quoted 24 lines
Quoted 24 lines
So, the current code (your commit) and previous code (Daniel's commit) clearly points to "reset" being optional.
Furthermore, I think we should not even register the "
link_change_notify" callback when dealing with AT803x PHYs that do not require the hack.
Another solution (considering the callback is statically registered in the "phy_driver" structs for all AT803x PHYs) would be for the callback to disable itself.
Once it detects that the PHY does not require the hack, it could just perform:phydev->drv->link_change_notify = NULL;or call a new generic function to do the same if encapsulation is required.
If everybody agrees I can make such change as well, but I really think Daniel should give his opinion first.
Quoted 4 lines
Quoted 3 lines
What would you think of making
at803x_link_change_notify()print a message every time it should do a reset but does not has a way to do it?
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Then this question is obsolete because the device doesn't probe.
I think you assume that "reset" is mandatory for all AT803x devices, but that's not what the code says.
No, you're wrong here. I'm aware that the code supports devices without reset.
Ok, then I did not understand what you meant with "the question is obsolete because the device doesn't probe".
Unless I'm missing something, the only way the driver won't bind correctly with current code is if GPIOLIB=n
Systems using the faulty PHY and having GPIOLIB=y but with an outdated DT that does not has a "reset" key would have the PHY driver bind yet have it fail due to missing "reset".
Quoted 6 lines
Quoted 3 lines
As such, my proposal was to:
- keep my proposed patchI don't agree.
Quoted 8 lines
Quoted 2 lines
- make another patch to print a warning when
gpiod_resetis NULL (which can happen, even without my patch)This only happens if no reset gpio is needed and in this case the driver does the right thing. So if you ask me, there is no need to modify the driver. Better add a dependency to GPIOLIB. This is necessary even for devices which don't need a reset gpio to answer the question "does this driver need a reset gpio?" correctly.
I don't see how the dependency on GPIOLIB=y improves the situation in any useful way.
To put an example: in our case we don't use the faulty PHY. So, the DT does not has the "reset" key.
Why should then the PHY driver be dependent on GPIOLIB?
Best regards,
Sebastian
Hello Sebastian,
Quoted 9 lines · Sebastian Frias
Quoted 4 lines · Uwe Kleine-König
Quoted 1 line
- We'd also need to check that 'gpiod' is not NULL
That is the optional part. If gpiod is NULL, you have one of the devices that don't need to handle the enable line.
gpiod=NULL (because the key is not there) or gpiod=ERR (because GPIOLIB=n + my patch) will result in the same behaviour, ie: driver binds, but fails to reset.
Assuming the source for the hardware description is dt (the same argument applies if it's ACPI or something else).
The driver uses devm_gpiod_get_optional(..."reset"...). That means some hardware has a reset line, some don't. If a reset gpio specification is there, that means the hardware has such a signal and it seems that means it must not be ignored. If there is no reset gpio specification that means that driver has to assume there is no reset line. (In the real world there might be other reasons the reset line isn't in the device tree, but it's not in the scope of the driver to guess why it's missing. If it's not there the only sensible thing to assume for the driver is:
There is no reset line.)
So the conclusions are: If there is a reset line in dt, it must be used. If you don't know if there is a reset line (because GPIOLIB=n) the driver should not bind. Everything else yields to more problems than good.
Quoted 9 lines
Quoted 5 lines
Quoted 2 lines
In the scenario at hand only some devices require a hack and gpiod_reset=NULL is valid (ie: device will not fail probing)
With your patch and GPIOLIB=n you bind the driver even for the devices that need the hack. This is broken!
It is a degraded mode I agree and had proposed to print a warning. However, I fail to see how is GPIOLIB=n different from just not having "reset" present.
GPIOLIB=n means "the driver doesn't know if a reset line is present/necessary", not having reset means "there is no reset line".
And don't do error handling by printk assuming anyone will read it. That doesn't work.
Quoted 1 line
The fact that GPIOLIB=y does not means that the "reset" key will be there.
Right, but with GPIOLIB=y you know if it's there, and if yes, you can control the line.
Quoted 3 lines
I mean, you assume that "reset" will be present for devices that need the hack, yet there is no such guarantee and the code clearly assumes that it can be missing.
The driver must assume that the device tree is right. If it's not fix the device tree, don't implement clumsy work arounds in the driver.
Quoted 3 lines
For all we know, the key is actually missing on systems that do use the faulty PHY (all systems designed prior to the hack being implemented) And that, regardless of GPIOLIB status.
Then fix the device tree.
Quoted 9 lines
Since the reset line can be missing, it can be missing for whatever reason. Whether it is because the "reset" key is not present or because GPIOLIB=n, it does not matter, it will result on the same outcome.
Furthermore, if "reset" is really required for certain devices that need the hack, then both cases:
- GPIOLIB=n
- "reset" not present
should be handled the same way (ie: not bind the driver) for such devices.
If you can detect by other means that "reset is necessary", then yes, the driver should ideally also fail in this case with no reset specified in dt.
Quoted 4 lines
By the way, I think not binding the driver is too strong too. Having a GPIO free and being able to route it to the PHY for reset may not even be possible on some systems.
Are they supposed to stop working?
Sometimes no driver is better than an unreliable one.
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
Quoted 2 lines
For consistency I'd recommend to do the
same for reset even though there is a chance to get a working device.I'm not so sure, because then information would be lost, handling both ("enable" and "reset") the same way aliases different intents and requirements.
Indeed, only "enable" would be really mandatory, "reset" is essentially optional (only 1 of 3 devices of the family require the hack).Besides, if "reset" was really mandatory, we would also fail the probe if the pointer for the reset GPIO is NULL.
Quoted 7 lines
Quoted 2 lines
No, if reset was mandatory you'd use
gpiod_getinstead ofgpiod_get_optionaland fail iff that call fails, too.Ok, but the current code for "reset" is using
devm_gpiod_get_optional()so "reset" is clearly optional.
And that call will return NULL if "reset" is not present, even with GPIOLIB=y
s/even//. And returning NULL is not an error. It means: There is no reset line specified in dt.
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Indeed, even with GPIOLIB=y the pointer can be NULL if the "reset" (or "enable" in your scenario) is not present.
From a functionality perspective, a NULL pointer for "reset" will result in the same behaviour as GPIOLIB=n, ie: not being able to reset the PHY.
Quoted 8 lines
Quoted 5 lines
Right, but you only get reset=NULL iff the device tree (or whatever is the source of information for
gpiod_get) doesn't specify a reset gpio which then means "This device doesn't need a reset gpio.". This is different from the GPIOLIB=n case, where the return code signals "It's unknown if the device needs a reset gpio.".I think somehow you try to make a difference on the reason why the reset=INVALID (NULL or ERR), but IMHO there's none.
NULL is not invalid. With devm_gpiod_get_optional the driver asks: "Is there a reset gpio, and if yes, which one?". The reset line is optional, that means "some devices have one, some others don't.". It does NOT mean "You can ignore if there is a reset line or not."!
Quoted 4 lines
If somebody using AT8030 PHY (the one that requires the hack) either does not configure a "reset" key on the DT, either does not enable GPIOLIB, the result will be the same.
There is no warning in either case and it will run on a degraded mode.
My expectation is that if the dt includes a reset property, it should be used. So, there is a fine option for each situation:
- device that doesn't need the hack => everything is fine;
- AT8030 with reset to a gpio => specify the reset in dt;
- AT8030 without a controllable reset line => don't specify a reset property;
if you have a broken device with a reset line you can even drop the reset property from dt and not make use of the reset gpio if you think it's a good idea.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Quoted 2 lines
What would you think of making
at803x_link_change_notify()print a message every time it should do a reset but does not has a way to do it?Then this question is obsolete because the device doesn't probe.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
I think you assume that "reset" is mandatory for all AT803x devices, but that's not what the code says.
No, you're wrong here. I'm aware that the code supports devices without reset.
Ok, then I did not understand what you meant with "the question is obsolete because the device doesn't probe".
if (GPIOLIB=y):
if (device has a reset property):
driver runs fine with being able to reset.
else:
if (device needs reset to function properly):
ideally fail to probe
else:
driver runs fine without reset and without the need
to bother the user about the absense of the gpio
else:
driver fails to bind
In no branch of these cases there is a situation where you must issue a reset but cannot. So there is no need to ask if you should issue a message each time this happens. That's what I meant with "the question is obsolete".
Quoted 2 lines
Unless I'm missing something, the only way the driver won't bind correctly with current code is if GPIOLIB=n
Right, because with GPIOLIB=n you cannot control a gpio line, but you don't know if you must.
Consider you are an electrician (driver) and you should repair a power socket (control a device) but forgot your phase tester (GPIOLIB=n). So there is no way you can determine if it's save to modify the socket. You can choose the optimistic way and say: "If there is no voltage on the socket, I can repair it successfully" and just try it. Or you take the safe approach and say: "I don't know if it's safe to do, so I better don't.".
The same applies to drivers: If it might be necessary to handle a gpio, but you cannot know if that's the case or not: Don't try it.
Quoted 3 lines
Systems using the faulty PHY and having GPIOLIB=y but with an outdated DT that does not has a "reset" key would have the PHY driver bind yet have it fail due to missing "reset".
dt compatibility is fine. So if you want to handle the situation properly, change the compatible and there make sure that the presence or absence of the reset property matches reality with the new binding. And continue to handle the old compatible the way you did before. But don't ignore errors returned by gpiod_get et al.
Quoted 9 lines
Quoted 8 lines
Quoted 2 lines
- make another patch to print a warning when
gpiod_resetis NULL (which can happen, even without my patch)This only happens if no reset gpio is needed and in this case the driver does the right thing. So if you ask me, there is no need to modify the driver. Better add a dependency to GPIOLIB. This is necessary even for devices which don't need a reset gpio to answer the question "does this driver need a reset gpio?" correctly.
Quoted 6 lines
I don't see how the dependency on GPIOLIB=y improves the situation in any useful way.
To put an example: in our case we don't use the faulty PHY. So, the DT does not has the "reset" key.
Why should then the PHY driver be dependent on GPIOLIB?
You want GPIOLIB to know that you don't need to handle the reset gpio.
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ |
Hi Uwe,
I think we are in a deadlock :-)
I'm going to reply inline below, but I will also send a different email to Daniel with a small recap.
I think he should share the intent of the "reset" mechanism he introduced, in particular if it is mandatory.
Quoted 5 lines · Uwe Kleine-König
Quoted 4 lines
gpiod=NULL (because the key is not there) or gpiod=ERR (because GPIOLIB=n + my patch) will result in the same behaviour, ie: driver binds, but fails to reset.
Quoted 7 lines
Assuming the source for the hardware description is dt (the same argument applies if it's ACPI or something else).
The driver uses
devm_gpiod_get_optional(..."reset"...). That means some hardware has a reset line, some don't. If a reset gpio specification is there, that means the hardware has such a signal and it seems that means it must not be ignored.
The problem is all those "it seems" :-)
"it seems it must not be ignored" is also an hypothesis considering the driver is not refusing to work even if it detects that the faulty PHY has not been provided with a reset line.
Also, further down the thread you acknowledge that's a possibility.
Quoted 6 lines
If there is no reset gpio specification that
means that driver has to assume there is no reset line. (In the real world there might be other reasons the reset line isn't in the device tree, but it's not in the scope of the driver to guess why it's missing. If it's not there the only sensible thing to assume for the driver is:
There is no reset line.)
But that is not what the current code does, the current code does not checks if the DT presents the "reset" property directly.
It assumes that GPIOLIB works and checks GPIOLIB return codes, to indirectly (and incorrectly) guess if a given device has a "reset" property. It has not been clearly explained anywhere that the "reset" property for AT8030 is supposed to be mandatory and that the driver should fail if not provided with one.
The code does not back up such hypothesis either, ie: GPIOLIB=y + missing "reset" will still allow the driver to work.
Quoted 5 lines
So the conclusions are: If there is a reset line in dt, it must be used. If you don't know if there is a reset line (because GPIOLIB=n) the driver should not bind. Everything else yields to more problems than good.
a) "If there is a reset line in dt, it must be used": that is an hypothesis (I would say "it can be used");
b) if it were true, then another way of knowing if the "reset" key is present should be used;
indeed, there should be:
c) a way to unambiguously determine if the "reset" key is in the DT (regardless of GPIOLIB status);
that in order to know if the DT is specifying that the "reset" mechanism must be used, then:
d) iff the "reset" is absolutely necessary (ie: the faulty PHY is in use AND the original intention of the hack was for it *mandatory* for faulty PHYs), some decision can be taken;
However, right now those conditions are not met.
Quoted 9 lines
Quoted 6 lines
Quoted 2 lines
With your patch and GPIOLIB=n you bind the driver even for the devices that need the hack. This is broken!
It is a degraded mode I agree and had proposed to print a warning. However, I fail to see how is GPIOLIB=n different from just not having "reset" present.
GPIOLIB=n means "the driver doesn't know if a reset line is present/necessary", not having reset means "there is no reset line".
That's the problem, that the driver is relying on GPIOLIB to know if:
- "reset" key is present
- it should fail to bind or not
and it does that based solely on GPIOLIB return codes, thus indirectly. As opposed to checking directly the presence of the "reset" key (regardless of GPIOLIB status) and failing immediately.
Quoted 3 lines
And don't do error handling by printk assuming anyone will read it. That doesn't work.
I proposed a warning, not error handling.
Also if we assume people won't read the logs, why put any at all? Some people may not read the logs, some others will, it is their choice to bang their heads one way or another.
Currently there's no warning.
So I had to debug why the driver was not binding, and it is not obvious that GPIOLIB must be selected, considering:
- I don't have a faulty PHY
- I don't have a "reset" key on DT
- Even if I wanted, I don't have a GPIO to connect to it
(also, even if this driver does not bind, some generic one would take over)
Quoted 5 lines
Quoted 2 lines
The fact that GPIOLIB=y does not means that the "reset" key will be there.
Right, but with GPIOLIB=y you know if it's there, and if yes, you can control the line.
Exactly, and what I say is that knowing if "reset" is there or not should not depend on having GPIOLIB=y
To me the problem comes from the aliasing between "GPIOLIB=y" and "reset" present.
Indeed, the driver should query if the "reset" key is present (regardless of GPIOLIB status), and then try to acquire the GPIO line. If it cannot get the reset GPIO, then it can give up saying "you told me I need a reset line but then you did not give me one".
Quoted 7 lines
Quoted 4 lines
I mean, you assume that "reset" will be present for devices that need the hack, yet there is no such guarantee and the code clearly assumes that it can be missing.
The driver must assume that the device tree is right. If it's not fix the device tree, don't implement clumsy work arounds in the driver.
I doubt it is like that.
I mean, it may sound easy to say "just update the DT and add the 'reset' key", but the DT is describing a physical connections in this case. Changing that may not be as easy.
IMHO it would be far better if the driver made the check on the PHY ID (8030) at probe time and refused to bind if:
- the "reset" is absolutely necessary per design (ie: intended by Daniel) and
- it did not get a reset line (for whatever reason).
That was not done.
Maybe because it is not possible because the ID may not be known at that time (strange since it is being probed);
Maybe because Daniel meant the whole thing to be optional; Or maybe for other reasons.
Quoted 6 lines
Quoted 4 lines
For all we know, the key is actually missing on systems that do use the faulty PHY (all systems designed prior to the hack being implemented) And that, regardless of GPIOLIB status.
Then fix the device tree.
Changing the device tree does not automagically creates a connection between a given GPIO (which must be available) and the PHY reset line. GPIOs and reset lines are physical things.
But maybe I'm missing something and board designers always route GPIOs to each and every peripheral's reset line.
Quoted 11 lines
Quoted 10 lines
Since the reset line can be missing, it can be missing for whatever reason. Whether it is because the "reset" key is not present or because GPIOLIB=n, it does not matter, it will result on the same outcome.
Furthermore, if "reset" is really required for certain devices that need the hack, then both cases:
- GPIOLIB=n
- "reset" not present
should be handled the same way (ie: not bind the driver) for such devices.
Quoted 3 lines
If you can detect by other means that "reset is necessary", then yes, the driver should ideally also fail in this case with no reset specified in dt.
Well, the problem is that right now we don't know what was the intention of the person that implemented the "reset" mechanism.
Both of us are arguing about our own hypothesis.
You have yours "reset is necessary and driver should not bind without". And I have mine "nothing in the code implies it is necessary".
Quoted 7 lines
Quoted 5 lines
By the way, I think not binding the driver is too strong too. Having a GPIO free and being able to route it to the PHY for reset may not even be possible on some systems.
Are they supposed to stop working?Sometimes no driver is better than an unreliable one.
It appears that if this driver does not binds, then a generic one (which arguably will also lack the reset behaviour) will take over. How can that be any better?
Quoted 11 lines
Quoted 8 lines
Quoted 3 lines
No, if reset was mandatory you'd use
gpiod_getinstead ofgpiod_get_optionaland fail iff that call fails, too.Ok, but the current code for "reset" is using
devm_gpiod_get_optional()so "reset" is clearly optional.
And that call will return NULL if "reset" is not present, even with GPIOLIB=ys/even//. And returning NULL is not an error. It means: There is no reset line specified in dt.
Indeed, and it is totally possible that the PHY ID is a faulty one, yet the driver will bind anyway.
You argue about a case "reset is absolutely necessary for some devices", but the code does not enforce that.
Quoted 8 lines
Quoted 3 lines
I think somehow you try to make a difference on the reason why the reset=INVALID (NULL or ERR), but IMHO there's none.
NULL is not invalid. With
devm_gpiod_get_optionalthe driver asks: "Is there a reset gpio, and if yes, which one?". The reset line is optional, that means "some devices have one, some others don't.". It does NOT mean "You can ignore if there is a reset line or not."!
But the current code does ignore it :-)
Even for faulty devices.
Again, if you take a faulty PHY and a DT without the "reset" key, the driver will bind.
Don't you think that goes against your hypothesis of "reset must be present and available for some devices"?
By the way, is the "reset" key documented somewhere? How would the DT look like?
Maybe in such documentation there's some explanation about the key being compulsory or not.
Quoted 6 lines
Quoted 5 lines
If somebody using AT8030 PHY (the one that requires the hack) either does not configure a "reset" key on the DT, either does not enable GPIOLIB, the result will be the same.
There is no warning in either case and it will run on a degraded mode.
Quoted 7 lines
My expectation is that if the dt includes a reset property, it should be used. So, there is a fine option for each situation:
- device that doesn't need the hack => everything is fine;
- AT8030 with reset to a gpio => specify the reset in dt;
- AT8030 without a controllable reset line => don't specify a reset property;
You do realise that in this last case the device will work in degraded mode, right?
Quoted 5 lines
if you have a broken device with a reset line you can even drop the reset property from dt and not make use of the reset gpio if you think it's a good idea.
So you are saying that "reset" is optional, even for faulty PHYs.
Quoted 4 lines
Quoted 3 lines
Ok, then I did not understand what you meant with "the question is obsolete because the device doesn't probe".
Quoted 11 lines
if (GPIOLIB=y):
if (device has a reset property):
driver runs fine with being able to reset.
else:
if (device needs reset to function properly):
ideally fail to probe
else:
driver runs fine without reset and without the need
to bother the user about the absense of the gpio
else:
driver fails to bind
To me it should be:
if (device needs reset):
if (DT has reset):
if (GPIOLIB=y):
gpiod=callback, driver gets a reset line and can operate
properly (ie: perform the hack)
else
gpiod=-ENOSYS, driver does not get reset line: should it
fail to bind? should it continue?
else
gpiod=NULL, driver does not get a reset line: should it fail to
bind? should it continue?
else
gpiod is not even requested, driver does not need a reset line and
can operate properly.
Quoted 3 lines
In no branch of these cases there is a situation where you must issue a reset but cannot.
Well, the thing is that what you described does not match the code, AFAIK current code does:
if (GPIOLIB=y):
if (DT has reset):
gpiod=callback
bind driver
if (faulty PHY):
use gpiod
else
gpiod=NULL
bind driver
if (faulty PHY)
cannot use gpiod, but continue anyway without warning
else
gpiod=-ENOSYS, fail to bind, regardless of PHY being faulty, and
regardless of "reset" presence (*)
(*) the way the code is written, "reset" presence is not checked directly, but as a side-effect of GPIOLIB
Quoted 9 lines
So there is no need to ask if you should issue a
message each time this happens. That's what I meant with "the question is obsolete".Quoted 2 lines
Unless I'm missing something, the only way the driver won't bind correctly with current code is if GPIOLIB=n
Right, because with GPIOLIB=n you cannot control a gpio line, but you don't know if you must.
Well right now nobody knows if the "reset" is actually a must, even for faulty PHYs.
The driver binds happily without, even on faulty devices.
Quoted 8 lines
Consider you are an electrician (driver) and you should repair a power socket (control a device) but forgot your phase tester (GPIOLIB=n). So there is no way you can determine if it's save to modify the socket. You can choose the optimistic way and say: "If there is no voltage on the socket, I can repair it successfully" and just try it. Or you take the safe approach and say: "I don't know if it's safe to do, so I better don't.".
:-) thanks for the analogy.
Quoted 4 lines
The same applies to drivers: If it might be necessary to handle a gpio, but you cannot know if that's the case or not: Don't try it.
But that's not how the code was written.
It is not mentioned anywhere that that was the initial intention either.
Quoted 6 lines
Quoted 4 lines
To put an example: in our case we don't use the faulty PHY. So, the DT does not has the "reset" key.
Why should then the PHY driver be dependent on GPIOLIB?You want GPIOLIB to know that you don't need to handle the reset gpio.
But that's like saying "you want all possible drivers linked-in, if they are not in DT they won't load/probe, so it's fine"
We don't want GPIOLIB because it is a bunch of useless code in our case. We know in advance that the DT will not have the "reset" key. We know in advance that the PHY is not faulty.
Why should we link-in a bunch of useless code then?
Alternatively, if GPIOLIB is mandatory due to the way drivers are written or the way DT works, then why make it optional?
Best regards,
Sebastian
Hello Sebastian,
Quoted 5 lines · Sebastian Frias
I think we are in a deadlock :-)
I'm going to reply inline below, but I will also send a different email to Daniel with a small recap.
I think he should share the intent of the "reset" mechanism he introduced, in particular if it is mandatory.
The things I said in my mail are valid in general, not only for the at803x phy.
Let me repeat them once more:
Preconditions:
- Some of the devices a given driver handles have a reset line and others don't.
- A non-empty subset (maybe all) of the devices that have a reset line require that this reset line is used.
Then the way to handle this in the driver should be done as follows:
unless reset_handling_not_necessary():
gpio = gpiod_get_optional("reset")
if IS_ERR(gpio):
return PTR_ERR(gpio)
Checking for -ENOSYS or GPIOLIB=n is not allowed because the device you're currently handling might need the GPIO, so you must not continue without the ability to control the line.
So the options you have (as you have a phy that doesn't need the reset handling):
- enable GPIOLIB (either in your .config or introduce a Kconfig dependency)
- improve reset_handling_not_necessary() to return true for your case
There is nothing else.
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ |
Hi Uwe,
Quoted 31 lines · Uwe Kleine-König
Hello Sebastian,
Quoted 5 lines · Sebastian Frias
I think we are in a deadlock :-)
I'm going to reply inline below, but I will also send a different email to Daniel with a small recap.
I think he should share the intent of the "reset" mechanism he introduced, in particular if it is mandatory.The things I said in my mail are valid in general, not only for the at803x phy.
Let me repeat them once more:
Preconditions:
- Some of the devices a given driver handles have a reset line and others don't.
- A non-empty subset (maybe all) of the devices that have a reset line require that this reset line is used.Then the way to handle this in the driver should be done as follows:
unless
reset_handling_not_necessary():
gpio =gpiod_get_optional("reset")
ifIS_ERR(gpio):
returnPTR_ERR(gpio)Checking for
-ENOSYSor GPIOLIB=n is not allowed because the device you're currently handling might need the GPIO, so you must not continue without the ability to control the line.
Quoted 7 lines
So the options you have (as you have a phy that doesn't need the reset handling):
- enable GPIOLIB (either in your .config or introduce a
Kconfigdependency)
- improvereset_handling_not_necessary()to return true for your case
I will see if I can "improve reset_handling_not_necessary() to return true".
Best regards,
Sebastian
PATCH 1/1 net: phy: at803x: Request 'reset' GPIO only for AT8030 PHY
This removes the dependency on GPIOLIB for non faulty PHYs.
Indeed, without this patch, if GPIOLIB is not selected devm_gpiod_get_optional() will return -ENOSYS and the driver probe call will fail, regardless of the actual PHY hardware.
Out of the 3 PHYs supported by this driver (AT8030, AT8031, AT8035), only AT8030 presents the issues that commit 13a56b449325 ("net: phy:
at803x: Add support for hardware reset") attempts to work-around by using a 'reset' GPIO line.
Hence, only AT8030 should depend on GPIOLIB operating properly.
--- drivers/net/phy/at803x.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/phy/at803x.c +4 -0
@@ -251,12 +251,16 @@ static int at803x_probe(struct phy_device *phydev)if (!priv)return -ENOMEM ; +if (phydev->drv->phy_id !=ATH8030_PHY_ID ) + goto does_not_require_reset_workaround; + gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH );if (IS_ERR (gpiod_reset))return PTR_ERR (gpiod_reset); priv->gpiod_reset = gpiod_reset; +does_not_require_reset_workaround: phydev->priv = priv;return 0 ;
Signature · 1 line
2.1.4
Re: [PATCH] net: phy: at803x: Request 'reset' GPIO only for AT8030 PHY
From: Sebastian Frias <[email protected]>
Date: Wed, 23 Mar 2016 11:49:09 +0100
Quoted 11 lines
This removes the dependency on GPIOLIB for non faulty PHYs.
Indeed, without this patch, if GPIOLIB is not selected
devm_gpiod_get_optional()will return-ENOSYSand the driver probe call will fail, regardless of the actual PHY hardware.Out of the 3 PHYs supported by this driver (AT8030, AT8031, AT8035), only AT8030 presents the issues that commit
13a56b449325("net: phy:
at803x: Add support for hardware reset") attempts to work-around by using a 'reset' GPIO line.
Quoted 5 lines
Hence, only AT8030 should depend on GPIOLIB operating properly.
Fixes 13a56b449325 ("net: phy: at803x: Add support for hardware reset")Signed-off-by Sebastian Frias <[email protected]>
Applied.
Re: [PATCH] net: phy: at803x: Request 'reset' GPIO only for AT8030 PHY
In reply to Sebastian FriasHello.
Quoted 11 lines · Sebastian Frias
This removes the dependency on GPIOLIB for non faulty PHYs.
Indeed, without this patch, if GPIOLIB is not selected
devm_gpiod_get_optional()will return-ENOSYSand the driver probe call will fail, regardless of the actual PHY hardware.Out of the 3 PHYs supported by this driver (AT8030, AT8031, AT8035), only AT8030 presents the issues that commit
13a56b449325("net: phy:
at803x: Add support for hardware reset") attempts to work-around by using a 'reset' GPIO line.
Quoted 5 lines
Hence, only AT8030 should depend on GPIOLIB operating properly.
Fixes 13a56b449325 ("net: phy: at803x: Add support for hardware reset")Signed-off-by Sebastian Frias <[email protected]>
[...]
What I don't understand is why the link_change_notify() method ptr is
populated for all 3 supported chips while only being needed on 8030...
MBR, Sergei
Re: [PATCH] net: phy: at803x: Request 'reset' GPIO only for AT8030 PHY
Hi Sergei,
Quoted 17 lines · Sergei Shtylyov
Hello.
Quoted 13 lines · Sebastian Frias
This removes the dependency on GPIOLIB for non faulty PHYs.
Indeed, without this patch, if GPIOLIB is not selected
devm_gpiod_get_optional()will return-ENOSYSand the driver probe call will fail, regardless of the actual PHY hardware.Out of the 3 PHYs supported by this driver (AT8030, AT8031, AT8035), only AT8030 presents the issues that commit
13a56b449325("net: phy:
at803x: Add support for hardware reset") attempts to work-around by using a 'reset' GPIO line.Hence, only AT8030 should depend on GPIOLIB operating properly.
Quoted 7 lines
Quoted 3 lines
Fixes 13a56b449325 ("net: phy: at803x: Add support for hardware reset")Signed-off-by Sebastian Frias <[email protected]>[...]
What I don't understand is why the
link_change_notify()method ptr is
populated for all 3 supported chips while only being needed on 8030...
You are right.
I had commented on that here
https://marc.info/?l=linux-netdev&m=145856582932498&w=2
<quote>
Furthermore, I think we should not even register the "link_change_notify" callback when dealing with AT803x PHYs that do not require the hack.
Another solution (considering the callback is statically registered in the "phy_driver" structs for all AT803x PHYs) would be for the callback to disable itself.
</quote>
I was waiting for comments from the original implementor.
However, I guess we can remove them as well.
I will make another patch.
Best regards,
Sebastian
Re: [PATCH] net: phy: at803x: Request 'reset' GPIO only for AT8030 PHY
Hi Sergei,
Quoted 4 lines
Quoted 2 lines
What I don't understand is why the
link_change_notify()method ptr is
populated for all 3 supported chips while only being needed on 8030...You are right.
I made the patch but I'm unsure about it because it could conflict with yours.
I mean, I think you submitted a patch to change the GPIO handling on the link_change_notify() function, right?
Well, if we only register the callback for the AT8030, then there is no more need for the callback to check the PHY ID.
However, if I change that, the whole block moves as I remove one indentation level (the one required by the PHY ID check).
Any suggestions on how to create a patch that won't conflict? I probably need to use a tree that already has your patch applied.
Best regards,
Sebastian
Re: [PATCH] net: phy: at803x: Request 'reset' GPIO only for AT8030 PHY
Quoted 10 lines · Sebastian Frias
Quoted 4 lines
Quoted 2 lines
What I don't understand is why the
link_change_notify()method ptr is
populated for all 3 supported chips while only being needed on 8030...You are right.
I made the patch but I'm unsure about it because it could conflict with yours.
I mean, I think you submitted a patch to change the GPIO handling on thelink_change_notify()function, right?
Quoted 7 lines
Well, if we only register the callback for the AT8030, then there is no more need for the callback to check the PHY ID.
However, if I change that, the whole block moves as I remove one indentation level (the one required by the PHY ID check).Any suggestions on how to create a patch that won't conflict? I probably need to use a tree that already has your patch applied.
My patch is already in Linus' tree, so should be merged back from net.git
into net-next.git
soon. I suggest that you wait until net-next is open again.
Quoted 3 lines
Best regards,
Sebastian
MBR, Sergei
Quoted 17 lines · Uwe Kleine-König
Preconditions:
- Some of the devices a given driver handles have a reset line and others don't.
- A non-empty subset (maybe all) of the devices that have a reset line require that this reset line is used.Then the way to handle this in the driver should be done as follows:
unless
reset_handling_not_necessary():
gpio =gpiod_get_optional("reset")
ifIS_ERR(gpio):
returnPTR_ERR(gpio)Checking for
-ENOSYSor GPIOLIB=n is not allowed because the device you're currently handling might need the GPIO, so you must not continue without the ability to control the line.
Quoted 8 lines
So the options you have (as you have a phy that doesn't need the reset handling):
- enable GPIOLIB (either in your .config or introduce a
Kconfigdependency)
- improvereset_handling_not_necessary()to return true for your caseThere is nothing else.
Here are some numbers for GPIOLIB, on an ARM build:
text data bss dec hex filename
1830 0 0 1830 726 devres.o
627 0 0 627 273 gpiolib-legacy.o 11018 40 4 11062 2b36 gpiolib.o
1598 0 0 1598 63e gpiolib-of.o
--------------------------------------------------------
15073 40 4 15117 3b0d built-in.o
So ~15 kilobytes.
By the way, since the "reset-by-GPIO" solution is used only for the Atheros 8030, would it be possible to make the devm_gpiod_get_optional conditional on ATH8030_PHY_ID?
I'm thinking of something along these lines, for illustration:
drivers/net/phy/at803x.c +4 -0
@@ -198,12 +198,16 @@ static int at803x_probe(struct phy_device *phydev)if (!priv)return -ENOMEM ; +if (phydev->drv->phy_id !=ATH8030_PHY_ID ) + goto no_gpio; + gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH );if (IS_ERR (gpiod_reset))return PTR_ERR (gpiod_reset); priv->gpiod_reset = gpiod_reset; +no_gpio: phydev->priv = priv;return 0 ;
Regards.
Hello.
Quoted 50 lines · Mason
Quoted 17 lines
Preconditions:
- Some of the devices a given driver handles have a reset line and others don't.
- A non-empty subset (maybe all) of the devices that have a reset line require that this reset line is used.Then the way to handle this in the driver should be done as follows:
unless
reset_handling_not_necessary():
gpio =gpiod_get_optional("reset")
ifIS_ERR(gpio):
returnPTR_ERR(gpio)Checking for
-ENOSYSor GPIOLIB=n is not allowed because the device you're currently handling might need the GPIO, so you must not continue without the ability to control the line.Quoted 8 lines
So the options you have (as you have a phy that doesn't need the reset handling):
- enable GPIOLIB (either in your .config or introduce a
Kconfigdependency)
- improvereset_handling_not_necessary()to return true for your caseThere is nothing else.
Here are some numbers for GPIOLIB, on an ARM build:
text data bss dec hex filename 1830 0 0 1830 726 devres.o 627 0 0 627 273 gpiolib-legacy.o 11018 40 4 11062 2b36 gpiolib.o 1598 0 0 1598 63e gpiolib-of.o--------------------------------------------------------
15073 40 4 15117 3b0d built-in.oSo ~15 kilobytes.
By the way, since the "reset-by-GPIO" solution is used only for the Atheros 8030, would it be possible to make the
devm_gpiod_get_optionalconditional onATH8030_PHY_ID?I'm thinking of something along these lines, for illustration:
drivers/net/phy/at803x.c +0
-0
drivers/net/phy/at803x.c static int at803x_probe(struct phy_device *phydev) · line 204
Quoted 7 lines
drivers/net/phy/at803x.c +3
-0@@ -198,12 +198,16 @@ static int at803x_probe(struct phy_device *phydev)if (!priv)return -ENOMEM ; +if (phydev->drv->phy_id !=ATH8030_PHY_ID ) + goto no_gpio; + gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH );
We shouldn't call _optional() then, should we?
Quoted 11 lines
drivers/net/phy/at803x.c +1
-0if (IS_ERR (gpiod_reset))return PTR_ERR (gpiod_reset); priv->gpiod_reset = gpiod_reset; +no_gpio: phydev->priv = priv;return 0 ;
Quoted 1 line
Regards.
MBR, Sergei
Hi Sergei,
Quoted 4 lines · Sergei Shtylyov
Quoted 2 lines
gpiod_reset= devm_gpiod_get_optional(dev, "reset",GPIOD_OUT_HIGH);We shouldn't call
_optional()then, should we?
I could imagine the original intention was to be backward compatible.
Indeed, if this call is not optional, systems using AT8030 and lacking a reset line on DT will have their behaviour affected.
NOTE: they would still work because even if this driver fails to bind a generic one will take over.
Best regards,
Sebastian
Hi Daniel,
Would you mind commenting on this thread?
Uwe and I are in a sort of deadlock because we each have a different understanding of the intention of your commit 13a56b449325.
Basically the questions are:
- What is the intention of 13a56b449325?
- Did you mean for "reset" to be mandatory for faulty PHYs? Mandatory meaning that you do not want the driver to work without.
- What do you think about the dependency on GPIOLIB?
You did not introduced such dependency with your change so it may point to "reset" not being mandatory.
Best regards,
Sebastian
Quoted 107 lines · Sebastian Frias
Hi Uwe, Daniel,
Quoted 27 lines · Uwe Kleine-König
[expand cc a bit more]
Hello,
Quoted 22 lines · Sebastian Frias
Commit
687908c2b649("net: phy: at803x: simplify usingdevm_gpiod_get_optionaland its 4th argument") introduced a dependency on GPIOLIB that was not there before.This commit removes such dependency by checking the return code and comparing it against ENOSYS which is returned when GPIOLIB is not selected.
Fixes 687908c2b649 ("net: phy: at803x: simplify using devm_gpiod_get_optional and its 4th argument")Signed-off-by Sebastian Frias <[email protected]>--- drivers/net/phy/at803x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/net/phy/at803x.c +0
-0@@ -252,7 +252,9 @@ static int at803x_probe(struct phy_device *phydev)return -ENOMEM ;Quoted 8 lines
drivers/net/phy/at803x.c static int at803x_probe(struct phy_device *phydev) · line 257
Quoted 5 lines
drivers/net/phy/at803x.c +3
-1gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); -if (IS_ERR (gpiod_reset)) +if (PTR_ERR (gpiod_reset) == -ENOSYS ) + gpiod_reset =NULL ; +else if (IS_ERR (gpiod_reset))this isn't better either (IMHO it's worse, but maybe this is debatable and also depends on your POV).
Well, from the code, the reset hack is only required when the PHY is
ATH8030_PHY_ID, right?
However, such change was introduced by Daniel Mack on commit13a56b449325. Hopefully he can chime in and give his opinion on this.Daniel, while on the subject, I have a question for you:
Change
2b8f2a28eac1introduced "link_status_notify" callback which is called systematically on the PHY state machine.
Any reason to make the call systematic as opposed to let say:if (phydev->state != old_state) { if (phydev->drv->link_change_notify) phydev->drv->link_change_notify(phydev); }(it does means that the callback would be called after the state machine processing though)
Quoted 3 lines
With
687908c2b649I made kernels without GPIOLIB fail to bind this device. I admit this is not maximally nice.I see, that was not clear from the commit message, sorry.
Quoted 7 lines
Your change makes the driver bind in this case again and then the reset gpio isn't handled at all which might result in a later and harder to debug error.
The better approach to fix your problem is: make the driver depend (or force) on GPIOLIB.
It was one of the solutions I had in mind, but:
- since the dependency on GPIOLIB was not included on the patch
- and given that the previous code had provision to work without GPIO I thought it was an overlook.Quoted 8 lines
Or alternatively, drop reset-handling from the
driver.From a driver perspecitive, it would be nice if
devm_gpiod_get_optionalreturned NULL iff the respective gpio isn't specified even with GPIOLIB=n, but this isn't sensible either because it would result in quite some gpiolib code to not being conditionally compiled onCONFIG_GPIOLIBany more.Let's say that was the case, what would the PHY code do?
I mean, it did not get a GPIO, whether it was because GPIOLIB=n or because there's no 'reset' GPIO attached
Shall it fail? Shall it continue in a sort of degraded mode? Shall it warn? Because that's the real question here.What would you think of making
at803x_link_change_notify()print a message every time it should do a reset but does not has a way to do it? I can make such change to my patch if everybody agrees on it. By the way, in that case, can somebody suggest a way to print such warning? Wouldprintk()be ok or should I usedev_dbg()?Best regards,
Sebastian
Quoted 4 lines
Best regards
Uwe
Hello.
Quoted 4 lines · Sebastian Frias
Commit
687908c2b649("net: phy: at803x: simplify usingdevm_gpiod_get_optionaland its 4th argument") introduced a dependency on GPIOLIB that was not there before.
Quoted 8 lines
This commit removes such dependency by checking the return code and comparing it against ENOSYS which is returned when GPIOLIB is not selected.
Fixes 687908c2b649 ("net: phy: at803x: simplify using
devm_gpiod_get_optionaland its 4th argument")Signed-off-by Sebastian Frias <[email protected]>
Do you have the PHY that requires the GPIO reset workaround?
Askinjg because I have the patch adding the "reset-gpios" prop handling to phylib and your patch made me aware that I'll have to modify this driver in order to do that...
Quoted 9 lines
--- drivers/net/phy/at803x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/net/phy/at803x.c +0
-0
drivers/net/phy/at803x.c static int at803x_probe(struct phy_device *phydev) · line 257
Quoted 7 lines
drivers/net/phy/at803x.c +3
-1@@ -252,7 +252,9 @@ static int at803x_probe(struct phy_device *phydev)return -ENOMEM ; gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); -if (IS_ERR (gpiod_reset)) +if (PTR_ERR (gpiod_reset) == -ENOSYS ) + gpiod_reset =NULL ; +else if (IS_ERR (gpiod_reset))
return PTR_ERR(gpiod_reset);
My patch basically gets rid of all this code. The thing that worries me is
that the driver assumes that the reset singal is active low, despite what the GPIO specifier in the device tree has for the GPIO polarity. In fact, it will only work correctly if the specified has GPIO_ACTIVE_HIGH -- which is wrong because the reset signal is active low!
Can you point me to an actual device tree using this erratic PHY?
WBR, Sergei
Hello Sergei,
Quoted 38 lines · Sergei Shtylyov
Quoted 4 lines · Sebastian Frias
Commit
687908c2b649("net: phy: at803x: simplify usingdevm_gpiod_get_optionaland its 4th argument") introduced a dependency on GPIOLIB that was not there before.Quoted 8 lines
This commit removes such dependency by checking the return code and comparing it against ENOSYS which is returned when GPIOLIB is not selected.
Fixes 687908c2b649 ("net: phy: at803x: simplify using
devm_gpiod_get_optionaland its 4th argument")Signed-off-by Sebastian Frias <[email protected]>Do you have the PHY that requires the GPIO reset workaround?
Askinjg because I have the patch adding the "reset-gpios" prop handling to phylib and your patch made me aware that I'll have to modify this driver in order to do that...Quoted 9 lines
--- drivers/net/phy/at803x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/net/phy/at803x.c +0
-0drivers/net/phy/at803x.c static int at803x_probe(struct phy_device *phydev) · line 257
Quoted 7 lines
drivers/net/phy/at803x.c +3
-1@@ -252,7 +252,9 @@ static int at803x_probe(struct phy_device *phydev)return -ENOMEM ; gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); -if (IS_ERR (gpiod_reset)) +if (PTR_ERR (gpiod_reset) == -ENOSYS ) + gpiod_reset =NULL ; +else if (IS_ERR (gpiod_reset))return
PTR_ERR(gpiod_reset);
Quoted 5 lines
My patch basically gets rid of all this code. The thing that worries me
is that the driver assumes that the reset singal is active low, despite what the GPIO specifier in the device tree has for the GPIO polarity. In fact, it will only work correctly if the specified hasGPIO_ACTIVE_HIGH-- which is wrong because the reset signal is active low!
Note that gpio descriptors handle the polarity just fine (i.e. the pin is set to 0 after doing gpiod_set_value(1) if the gpio is active low).
But having said that, the driver gets it wrong.
The right sequence to reset a device using a gpio is:
gpiod_set_value(priv->gpiod_reset, 1); msleep(some_time); gpiod_set_value(priv->gpiod_reset, 0);
and if the gpio is active low, this should be specified in the device tree. This was done wrong in 13a56b449325 (net: phy: at803x: Add support for hardware reset).
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ |
Quoted 36 lines · Uwe Kleine-König
Quoted 36 lines
Quoted 4 lines
Commit
687908c2b649("net: phy: at803x: simplify usingdevm_gpiod_get_optionaland its 4th argument") introduced a dependency on GPIOLIB that was not there before.Quoted 8 lines
This commit removes such dependency by checking the return code and comparing it against ENOSYS which is returned when GPIOLIB is not selected.
Fixes 687908c2b649 ("net: phy: at803x: simplify using
devm_gpiod_get_optionaland its 4th argument")Signed-off-by Sebastian Frias <[email protected]>Do you have the PHY that requires the GPIO reset workaround?
Askinjg because I have the patch adding the "reset-gpios" prop handling to phylib and your patch made me aware that I'll have to modify this driver in order to do that...Quoted 9 lines
--- drivers/net/phy/at803x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/net/phy/at803x.c +0
-0drivers/net/phy/at803x.c static int at803x_probe(struct phy_device *phydev) · line 257
Quoted 7 lines
drivers/net/phy/at803x.c +3
-1@@ -252,7 +252,9 @@ static int at803x_probe(struct phy_device *phydev)return -ENOMEM ; gpiod_reset =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); -if (IS_ERR (gpiod_reset)) +if (PTR_ERR (gpiod_reset) == -ENOSYS ) + gpiod_reset =NULL ; +else if (IS_ERR (gpiod_reset))return PTR_ERR(gpiod_reset);
Quoted 8 lines
Quoted 5 lines
My patch basically gets rid of all this code. The thing that worries me
is that the driver assumes that the reset singal is active low, despite what the GPIO specifier in the device tree has for the GPIO polarity. In fact, it will only work correctly if the specified hasGPIO_ACTIVE_HIGH-- which is wrong because the reset signal is active low!Note that gpio descriptors handle the polarity just fine (i.e. the pin is set to 0 after doing
gpiod_set_value(1)if the gpio is active low).
I know. :-)
Quoted 11 lines
But having said that, the driver gets it wrong.
The right sequence to reset a device using a gpio is:
gpiod_set_value(priv->gpiod_reset, 1); msleep(some_time); gpiod_set_value(priv->gpiod_reset, 0);and if the gpio is active low, this should be specified in the device tree. This was done wrong in
13a56b449325(net: phy: at803x: Add support for hardware reset).
I wonder if that was done before GPIO_ACTIVE_* thing was introduced...
there are precedents in other MAC drivers that want a separate "phy-reset-active-low" or even -"high" prop...
Quoted 2 lines
Best regards
Uwe
MBR, Sergei
Hi,
Quoted 9 lines · Uwe Kleine-König
Quoted 5 lines
My patch basically gets rid of all this code. The thing that worries me
is that the driver assumes that the reset singal is active low, despite what the GPIO specifier in the device tree has for the GPIO polarity. In fact, it will only work correctly if the specified hasGPIO_ACTIVE_HIGH-- which is wrong because the reset signal is active low!Note that gpio descriptors handle the polarity just fine (i.e. the pin is set to 0 after doing
gpiod_set_value(1)if the gpio is active low).
Isn't that source of bugs?
What about using some #define (or probably better, an enum)?, something like:
gpiod_set_value(gpiod, GPIO_SET_VALUE_ACTIVE) gpiod_set_value(gpiod, GPIO_SET_VALUE_INACTIVE) gpiod_set_value(gpiod, GPIO_SET_VALUE_TRISTATE)
then, somebody reading the code would have to stop and think what do these mean.
IIUC, currently the "0" or "1" can easily be confused with the actual logical value of the GPIO.
gpiod_set_value() could also return an int with the actual value it applied to the GPIO.
For example: if gpiod is active low, gpiod_set_value(gpiod, GPIO_SET_VALUE_ACTIVE) would return 0;
Conversely, if gpiod is active high, gpiod_set_value(gpiod, GPIO_SET_VALUE_ACTIVE) would return 1;
Best regards,
Sebastian
Quoted 15 lines
But having said that, the driver gets it wrong.
The right sequence to reset a device using a gpio is:
gpiod_set_value(priv->gpiod_reset, 1); msleep(some_time); gpiod_set_value(priv->gpiod_reset, 0);and if the gpio is active low, this should be specified in the device tree. This was done wrong in
13a56b449325(net: phy: at803x: Add support for hardware reset).Best regards
Uwe
Hi Sergei,
Quoted 2 lines · Sergei Shtylyov
Do you have the PHY that requires the GPIO reset workaround?
Unfortunately (or luckily :-) ) I don't have the faulty PHY, sorry.
Best regards,
Sebastian