Re: GPIO registration for external Ethernet PHY oscillator enable/disable

From: Michael Welling
Date: Fri Sep 26 2014 - 16:04:20 EST


On Fri, Sep 26, 2014 at 10:16:51AM -0700, Florian Fainelli wrote:
>
> Yes and no, this might feel like the wrong place, but ultimately, the
> Ethernet MAC is a consumer of the PHY device, and is in control, through
> the PHY library of how and when the PHY gets to be powered off.
>

So here is the patch that I made that hooks into the macb driver.

Please look it over and tell me if we are on the same page.

The thing that bothers me about this solution is that it will only work with the macb driver.
So everytime I use the same PHY/OSC combo with a different SoC I will have to do another patch.

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index e4e34b6..8cd363f 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -28,6 +28,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_net.h>
+#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>

#include "macb.h"
@@ -1833,6 +1834,16 @@ static int __init macb_probe(struct platform_device *pdev)
bp->phy_interface = err;
}

+ bp->phy_osc_gpio = of_get_named_gpio(pdev->dev.of_node, "osc-gpio", 0);
+
+ if (gpio_is_valid(bp->phy_osc_gpio))
+ {
+ if (gpio_request(bp->phy_osc_gpio, "osc-gpio") != 0) {
+ pr_info("Oscillator GPIO not available.\n");
+ bp->phy_osc_gpio = 0;
+ }
+ }
+
if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII)
macb_or_gem_writel(bp, USRIO, GEM_BIT(RGMII));
else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII)
@@ -1927,6 +1938,9 @@ static int macb_suspend(struct platform_device *pdev, pm_message_t state)
netif_carrier_off(netdev);
netif_device_detach(netdev);

+ if (gpio_is_valid(bp->phy_osc_gpio))
+ gpio_set_value_cansleep(bp->phy_osc_gpio, 0);
+
clk_disable_unprepare(bp->hclk);
clk_disable_unprepare(bp->pclk);

@@ -1941,6 +1955,9 @@ static int macb_resume(struct platform_device *pdev)
clk_prepare_enable(bp->pclk);
clk_prepare_enable(bp->hclk);

+ if (gpio_is_valid(bp->phy_osc_gpio))
+ gpio_set_value_cansleep(bp->phy_osc_gpio, 1);
+
netif_device_attach(netdev);

return 0;
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index f407615..8ca3dbd 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -596,6 +596,7 @@ struct macb {
u32 caps;

phy_interface_t phy_interface;
+ int phy_osc_gpio;

/* AT91RM9200 transmit */
struct sk_buff *skb; /* holds skb until xmit interrupt completes */


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/