[2/3,v2] net: smsc911x: request and deassert optional RESET GPIO

Message ID 1472043582-7653-2-git-send-email-linus.walleij@linaro.org
State Superseded
Headers show

Commit Message

Linus Walleij Aug. 24, 2016, 12:59 p.m.
On some systems (such as the Qualcomm APQ8060 Dragonboard) the
RESET signal of the SMSC911x is not pulled up by a resistor but
connected to a GPIO line, so that the operating system must
explicitly deassert RESET before use.

Support this in the SMSC911x driver so this ethernet connector
can be used on such targets.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

---
ChangeLog v1->v2:
- Use devm_gpiod_request_optiona() and request the line with
  GPIOD_OUT_LOW so it is deasserted immediately if active.
---
 drivers/net/ethernet/smsc/smsc911x.c | 9 +++++++++
 1 file changed, 9 insertions(+)

-- 
2.7.4

Comments

Linus Walleij Sept. 7, 2016, 9:59 a.m. | #1
On Wed, Aug 31, 2016 at 5:08 PM, Jeremy Linton <jeremy.linton@arm.com> wrote:
> On 08/24/2016 07:59 AM, Linus Walleij wrote:

>>

>> On some systems (such as the Qualcomm APQ8060 Dragonboard) the

>> RESET signal of the SMSC911x is not pulled up by a resistor but

>> connected to a GPIO line, so that the operating system must

>> explicitly deassert RESET before use.

>>

>> Support this in the SMSC911x driver so this ethernet connector

>> can be used on such targets.

>

> Hmm, at least in our hardware case AFAIK (juno/lan9118) the hardware reset

> line on the lan9118 is active low, but the chip itself is documented as

> having internal pullups so that it may be left unconnected.


I guess this is only a comment about the contents of the commit message,
I'll check it up and augment.

This:

+       /* Request optional RESET GPIO */
+       pdata->reset_gpiod = devm_gpiod_get_optional(&pdev->dev,
+                                                    "reset",
+                                                    GPIOD_OUT_LOW);

Is Linux-internal way of saying "deassert the RESET" line, it does
*not* mean "drive it low".

GPIO lines are configured in the device tree for the platform in
question, and what you say about it being active low is true, and
that is why the device tree for the DragonBoard looks like so:

+ reset-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;

Flagging it active low in the device tree make sure it is driven
high by the statement in the code.

> Beyond that, is it not possible for the firmware to get the reset pin in the

> correct configuration, so that linux doesn't have to mess with it?


That is always possible, and in that case you simply do not specify
the GPIO line for RESET. But this firmware for the APQ8060 DragonBoard
does not do it and Qualcomm is not going to update it, and I need
to deal with it.

Yours,
Linus Walleij

Patch

diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index ca3134540d2d..8ab8d4b9614b 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -62,6 +62,7 @@ 
 #include <linux/acpi.h>
 #include <linux/pm_runtime.h>
 #include <linux/property.h>
+#include <linux/gpio/consumer.h>
 
 #include "smsc911x.h"
 
@@ -147,6 +148,9 @@  struct smsc911x_data {
 	/* regulators */
 	struct regulator_bulk_data supplies[SMSC911X_NUM_SUPPLIES];
 
+	/* Reset GPIO */
+	struct gpio_desc *reset_gpiod;
+
 	/* clock */
 	struct clk *clk;
 };
@@ -438,6 +442,11 @@  static int smsc911x_request_resources(struct platform_device *pdev)
 		netdev_err(ndev, "couldn't get regulators %d\n",
 				ret);
 
+	/* Request optional RESET GPIO */
+	pdata->reset_gpiod = devm_gpiod_get_optional(&pdev->dev,
+						     "reset",
+						     GPIOD_OUT_LOW);
+
 	/* Request clock */
 	pdata->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(pdata->clk))