Loading arch/arm/boot/dts/qcom/mdm9607-pinctrl.dtsi +10 −8 Original line number Diff line number Diff line Loading @@ -791,7 +791,7 @@ }; emac0 { emac0_active: emac0_active { emac0_mdio_active: emac0_mdio_active { /* active state */ mux { /* MDC MDIO */ Loading @@ -806,7 +806,7 @@ }; }; emac0_sleep: emac0_sleep { emac0_mdio_sleep: emac0_mdio_sleep { /* suspended state */ mux { /* MDC MDIO */ Loading @@ -821,25 +821,26 @@ }; }; emac0_rst_active: emac0_rst_active { emac0_ephy_active: emac0_ephy_active { /* active state */ mux { /* ETH RST */ /* EPHY RST */ pins = "gpio29"; function = "gpio"; }; config { pins = "gpio29"; drive-strength = <16>; /* 8 MA */ drive-strength = <16>; /* 16 MA */ bias-pull-up; output-high; }; }; emac0_rst_sleep: emac0_rst_sleep { emac0_ephy_sleep: emac0_ephy_sleep { /* suspended state */ mux { /* ETH RST */ /* EPHY RST */ pins = "gpio29"; function = "gpio"; }; Loading @@ -847,7 +848,8 @@ config { pins = "gpio29"; drive-strength = <2>; /* 2 MA */ bias-pull-down; bias-disable; output-low; }; }; }; Loading arch/arm/boot/dts/qcom/mdm9607.dtsi +6 −3 Original line number Diff line number Diff line Loading @@ -1369,9 +1369,12 @@ <&clock_gcc clk_gcc_emac_0_sys_clk>; clock-names = "axi_clk", "cfg_ahb_clk", "125m_clk", "25m_clk", "tx_clk", "rx_clk", "sys_clk"; pinctrl-names = "emac_active", "emac_sleep"; pinctrl-0 = <&emac0_active &emac0_rst_active>; pinctrl-1 = <&emac0_sleep &emac0_rst_sleep>; pinctrl-names = "emac_mdio_active", "emac_mdio_sleep", "emac_ephy_active", "emac_ephy_sleep"; pinctrl-0 = <&emac0_mdio_active>; pinctrl-1 = <&emac0_mdio_sleep>; pinctrl-2 = <&emac0_ephy_active>; pinctrl-3 = <&emac0_ephy_sleep>; qcom,emac-tstamp-en; qcom,emac-ptp-frac-ns-adj = <125000000 1>; phy-mode = "sgmii"; Loading drivers/net/ethernet/qualcomm/emac/emac.h +6 −4 Original line number Diff line number Diff line Loading @@ -723,10 +723,12 @@ struct emac_adapter { u16 msg_enable; unsigned long flags; struct pinctrl *pinctrl; struct pinctrl_state *pins_active; struct pinctrl_state *pins_sleep; int (*gpio_on)(struct emac_adapter *adpt); int (*gpio_off)(struct emac_adapter *adpt); struct pinctrl_state *mdio_pins_active; struct pinctrl_state *mdio_pins_sleep; struct pinctrl_state *ephy_pins_active; struct pinctrl_state *ephy_pins_sleep; int (*gpio_on)(struct emac_adapter *adpt, bool mdio, bool ephy); int (*gpio_off)(struct emac_adapter *adpt, bool mdio, bool ephy); struct wakeup_source link_wlock; }; Loading drivers/net/ethernet/qualcomm/emac/emac_main.c +121 −47 Original line number Diff line number Diff line Loading @@ -70,8 +70,10 @@ static struct of_device_id emac_dt_match[]; #define EMAC_SKB_CB(skb) ((struct emac_skb_cb *)(skb)->cb) #define EMAC_PINCTRL_STATE_ACTIVE "emac_active" #define EMAC_PINCTRL_STATE_SLEEP "emac_sleep" #define EMAC_PINCTRL_STATE_MDIO_ACTIVE "emac_mdio_active" #define EMAC_PINCTRL_STATE_MDIO_SLEEP "emac_mdio_sleep" #define EMAC_PINCTRL_STATE_EPHY_ACTIVE "emac_ephy_active" #define EMAC_PINCTRL_STATE_EPHY_SLEEP "emac_ephy_sleep" #define EMAC_VREG1_VOLTAGE 1250000 #define EMAC_VREG2_VOLTAGE 1800000 Loading Loading @@ -1873,58 +1875,110 @@ static int emac_change_mtu(struct net_device *netdev, int new_mtu) return 0; } static inline int msm_emac_request_gpio_on(struct emac_adapter *adpt) static inline int msm_emac_request_gpio_on(struct emac_adapter *adpt, bool mdio, bool ephy) { int i = 0; int result = 0; struct emac_phy *phy = &adpt->phy; if (phy->external) { for (i = 0; phy->uses_gpios && i < EMAC_GPIO_CNT; i++) { result = gpio_request(adpt->gpio[i], emac_gpio_name[i]); if (result) { emac_err(adpt, "error:%d on gpio_request(%d:%s)\n", emac_err(adpt, "error:%d on gpio_request(%d:%s)\n", result, adpt->gpio[i], emac_gpio_name[i]); while (--i >= 0) gpio_free(adpt->gpio[i]); goto error; } } } return 0; error: return result; } static inline int msm_emac_request_gpio_off(struct emac_adapter *adpt) static inline int msm_emac_request_gpio_off(struct emac_adapter *adpt, bool mdio, bool ephy) { int i = 0; struct emac_phy *phy = &adpt->phy; if (phy->external) { for (i = 0; phy->uses_gpios && i < EMAC_GPIO_CNT; i++) gpio_free(adpt->gpio[i]); } return 0; } static inline int msm_emac_request_pinctrl_on(struct emac_adapter *adpt) static inline int msm_emac_request_pinctrl_on(struct emac_adapter *adpt, bool mdio, bool ephy) { int result = 0; int ret = 0; struct emac_phy *phy = &adpt->phy; result = pinctrl_select_state(adpt->pinctrl, adpt->pins_active); if (phy->external) { if (mdio) { result = pinctrl_select_state(adpt->pinctrl, adpt->mdio_pins_active); if (result) emac_err(adpt, "error:%d Can not set %s pins\n", result, EMAC_PINCTRL_STATE_ACTIVE); return result; emac_err(adpt, "error:%d Can not switch on %s pins\n", result, EMAC_PINCTRL_STATE_MDIO_ACTIVE); ret = result; } if (ephy) { result = pinctrl_select_state(adpt->pinctrl, adpt->ephy_pins_active); if (result) emac_err(adpt, "error:%d Can not switch on %s pins\n", result, EMAC_PINCTRL_STATE_EPHY_ACTIVE); if (!ret) ret = result; } } return ret; } static inline int msm_emac_request_pinctrl_off(struct emac_adapter *adpt) static inline int msm_emac_request_pinctrl_off(struct emac_adapter *adpt, bool mdio, bool ephy) { int result = 0; int ret = 0; struct emac_phy *phy = &adpt->phy; result = pinctrl_select_state(adpt->pinctrl, adpt->pins_sleep); if (phy->external) { if (mdio) { result = pinctrl_select_state(adpt->pinctrl, adpt->mdio_pins_sleep); if (result) emac_err(adpt, "error:%d Can not set %s pins\n", result, EMAC_PINCTRL_STATE_SLEEP); return result; emac_err(adpt, "error:%d Can not switch off %s pins\n", result, EMAC_PINCTRL_STATE_MDIO_SLEEP); ret = result; } if (ephy) { result = pinctrl_select_state(adpt->pinctrl, adpt->ephy_pins_sleep); if (result) emac_err(adpt, "error:%d Can not switch off %s pins\n", result, EMAC_PINCTRL_STATE_EPHY_SLEEP); if (!ret) ret = result; } } return ret; } /* Bringup the interface/HW */ Loading @@ -1946,10 +2000,6 @@ int emac_up(struct emac_adapter *adpt) if (retval) return retval; retval = adpt->gpio_on(adpt); if (retval < 0) goto err_request_gpio; for (i = 0; i < EMAC_IRQ_CNT; i++) { struct emac_irq_per_dev *irq = &adpt->irq[i]; const struct emac_irq_common *irq_cmn = &emac_irq_cmn_tbl[i]; Loading Loading @@ -1989,8 +2039,6 @@ int emac_up(struct emac_adapter *adpt) return retval; err_request_irq: adpt->gpio_off(adpt); err_request_gpio: adpt->phy.ops.down(adpt); return retval; } Loading Loading @@ -2018,8 +2066,6 @@ void emac_down(struct emac_adapter *adpt, u32 ctrl) if (adpt->irq[i].irq) free_irq(adpt->irq[i].irq, &adpt->irq[i]); adpt->gpio_off(adpt); CLR_FLAG(adpt, ADPT_TASK_LSC_REQ); CLR_FLAG(adpt, ADPT_TASK_REINIT_REQ); CLR_FLAG(adpt, ADPT_TASK_CHK_SGMII_REQ); Loading Loading @@ -2718,20 +2764,36 @@ static int msm_emac_pinctrl_init(struct emac_adapter *adpt, struct device *dev) PTR_ERR(adpt->pinctrl)); return PTR_ERR(adpt->pinctrl); } adpt->pins_active = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_ACTIVE); if (IS_ERR_OR_NULL(adpt->pins_active)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup pinctrl active state\n", PTR_ERR(adpt->pins_active)); return PTR_ERR(adpt->pins_active); adpt->mdio_pins_active = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_MDIO_ACTIVE); if (IS_ERR_OR_NULL(adpt->mdio_pins_active)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup mdio pinctrl active state\n", PTR_ERR(adpt->mdio_pins_active)); return PTR_ERR(adpt->mdio_pins_active); } adpt->mdio_pins_sleep = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_MDIO_SLEEP); if (IS_ERR_OR_NULL(adpt->mdio_pins_sleep)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup mdio pinctrl sleep state\n", PTR_ERR(adpt->mdio_pins_sleep)); return PTR_ERR(adpt->mdio_pins_sleep); } adpt->ephy_pins_active = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_EPHY_ACTIVE); if (IS_ERR_OR_NULL(adpt->ephy_pins_active)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup ephy pinctrl active state\n", PTR_ERR(adpt->ephy_pins_active)); return PTR_ERR(adpt->ephy_pins_active); } adpt->pins_sleep = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_SLEEP); if (IS_ERR_OR_NULL(adpt->pins_sleep)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup pinctrl sleep state\n", PTR_ERR(adpt->pins_sleep)); return PTR_ERR(adpt->pins_sleep); adpt->ephy_pins_sleep = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_EPHY_SLEEP); if (IS_ERR_OR_NULL(adpt->ephy_pins_sleep)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup ephy pinctrl sleep state\n", PTR_ERR(adpt->ephy_pins_sleep)); return PTR_ERR(adpt->ephy_pins_sleep); } return 0; Loading Loading @@ -3116,6 +3178,8 @@ static int emac_suspend(struct device *device) emac_hw_config_pow_save(hw, phy->link_speed, !!wufc, !!(wufc & EMAC_WOL_MAGIC)); /* Don't reset ephy as need it for WOL/Link detection later */ adpt->gpio_off(adpt, true, false); emac_disable_clks(adpt); emac_disable_regulator(adpt); return 0; Loading @@ -3130,11 +3194,13 @@ static int emac_resume(struct device *device) struct emac_hw *hw = &adpt->hw; u32 retval; adpt->gpio_on(adpt, true, false); emac_enable_regulator(adpt); emac_init_clks(adpt); emac_enable_clks(adpt); emac_hw_reset_mac(hw); emac_phy_reset_external(adpt); retval = emac_phy_setup_link(adpt, phy->autoneg_advertised, true, !phy->disable_fc_autoneg); if (retval) Loading Loading @@ -3244,6 +3310,11 @@ static int emac_probe(struct platform_device *pdev) if (retval) goto err_clk_en; /* Configure MDIO lines */ retval = adpt->gpio_on(adpt, true, true); if (retval) goto err_init_mdio_gpio; /* init external phy */ retval = emac_phy_init_external(adpt); if (retval) Loading Loading @@ -3313,6 +3384,8 @@ static int emac_probe(struct platform_device *pdev) err_register_netdev: err_phy_link: err_init_ephy: adpt->gpio_off(adpt, true, true); err_init_mdio_gpio: err_clk_en: err_init_phy: err_clk_init: Loading @@ -3339,6 +3412,7 @@ static int emac_remove(struct platform_device *pdev) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_remove(netdev); adpt->gpio_off(adpt, true, true); emac_disable_regulator(adpt); emac_disable_clks(adpt); emac_release_resources(adpt); Loading drivers/net/ethernet/qualcomm/emac/emac_phy.c +16 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -217,6 +217,19 @@ int emac_phy_write(struct emac_adapter *adpt, u16 phy_addr, u16 reg_addr, return retval; } /* reset external phy */ void emac_phy_reset_external(struct emac_adapter *adpt) { /* Trigger ephy reset by pulling line low */ adpt->gpio_off(adpt, false, true); /* need delay to complete ephy reset */ usleep_range(10000, 20000); /* Complete ephy reset by pulling line back up */ adpt->gpio_on(adpt, false, true); /* need delay to complete ephy reset */ usleep_range(10000, 20000); } /* initialize external phy */ int emac_phy_init_external(struct emac_adapter *adpt) { Loading @@ -226,6 +239,8 @@ int emac_phy_init_external(struct emac_adapter *adpt) int retval = 0; if (phy->external) { emac_phy_reset_external(adpt); retval = emac_phy_read(adpt, phy->addr, MII_PHYSID1, &phy_id[0]); if (retval) Loading Loading
arch/arm/boot/dts/qcom/mdm9607-pinctrl.dtsi +10 −8 Original line number Diff line number Diff line Loading @@ -791,7 +791,7 @@ }; emac0 { emac0_active: emac0_active { emac0_mdio_active: emac0_mdio_active { /* active state */ mux { /* MDC MDIO */ Loading @@ -806,7 +806,7 @@ }; }; emac0_sleep: emac0_sleep { emac0_mdio_sleep: emac0_mdio_sleep { /* suspended state */ mux { /* MDC MDIO */ Loading @@ -821,25 +821,26 @@ }; }; emac0_rst_active: emac0_rst_active { emac0_ephy_active: emac0_ephy_active { /* active state */ mux { /* ETH RST */ /* EPHY RST */ pins = "gpio29"; function = "gpio"; }; config { pins = "gpio29"; drive-strength = <16>; /* 8 MA */ drive-strength = <16>; /* 16 MA */ bias-pull-up; output-high; }; }; emac0_rst_sleep: emac0_rst_sleep { emac0_ephy_sleep: emac0_ephy_sleep { /* suspended state */ mux { /* ETH RST */ /* EPHY RST */ pins = "gpio29"; function = "gpio"; }; Loading @@ -847,7 +848,8 @@ config { pins = "gpio29"; drive-strength = <2>; /* 2 MA */ bias-pull-down; bias-disable; output-low; }; }; }; Loading
arch/arm/boot/dts/qcom/mdm9607.dtsi +6 −3 Original line number Diff line number Diff line Loading @@ -1369,9 +1369,12 @@ <&clock_gcc clk_gcc_emac_0_sys_clk>; clock-names = "axi_clk", "cfg_ahb_clk", "125m_clk", "25m_clk", "tx_clk", "rx_clk", "sys_clk"; pinctrl-names = "emac_active", "emac_sleep"; pinctrl-0 = <&emac0_active &emac0_rst_active>; pinctrl-1 = <&emac0_sleep &emac0_rst_sleep>; pinctrl-names = "emac_mdio_active", "emac_mdio_sleep", "emac_ephy_active", "emac_ephy_sleep"; pinctrl-0 = <&emac0_mdio_active>; pinctrl-1 = <&emac0_mdio_sleep>; pinctrl-2 = <&emac0_ephy_active>; pinctrl-3 = <&emac0_ephy_sleep>; qcom,emac-tstamp-en; qcom,emac-ptp-frac-ns-adj = <125000000 1>; phy-mode = "sgmii"; Loading
drivers/net/ethernet/qualcomm/emac/emac.h +6 −4 Original line number Diff line number Diff line Loading @@ -723,10 +723,12 @@ struct emac_adapter { u16 msg_enable; unsigned long flags; struct pinctrl *pinctrl; struct pinctrl_state *pins_active; struct pinctrl_state *pins_sleep; int (*gpio_on)(struct emac_adapter *adpt); int (*gpio_off)(struct emac_adapter *adpt); struct pinctrl_state *mdio_pins_active; struct pinctrl_state *mdio_pins_sleep; struct pinctrl_state *ephy_pins_active; struct pinctrl_state *ephy_pins_sleep; int (*gpio_on)(struct emac_adapter *adpt, bool mdio, bool ephy); int (*gpio_off)(struct emac_adapter *adpt, bool mdio, bool ephy); struct wakeup_source link_wlock; }; Loading
drivers/net/ethernet/qualcomm/emac/emac_main.c +121 −47 Original line number Diff line number Diff line Loading @@ -70,8 +70,10 @@ static struct of_device_id emac_dt_match[]; #define EMAC_SKB_CB(skb) ((struct emac_skb_cb *)(skb)->cb) #define EMAC_PINCTRL_STATE_ACTIVE "emac_active" #define EMAC_PINCTRL_STATE_SLEEP "emac_sleep" #define EMAC_PINCTRL_STATE_MDIO_ACTIVE "emac_mdio_active" #define EMAC_PINCTRL_STATE_MDIO_SLEEP "emac_mdio_sleep" #define EMAC_PINCTRL_STATE_EPHY_ACTIVE "emac_ephy_active" #define EMAC_PINCTRL_STATE_EPHY_SLEEP "emac_ephy_sleep" #define EMAC_VREG1_VOLTAGE 1250000 #define EMAC_VREG2_VOLTAGE 1800000 Loading Loading @@ -1873,58 +1875,110 @@ static int emac_change_mtu(struct net_device *netdev, int new_mtu) return 0; } static inline int msm_emac_request_gpio_on(struct emac_adapter *adpt) static inline int msm_emac_request_gpio_on(struct emac_adapter *adpt, bool mdio, bool ephy) { int i = 0; int result = 0; struct emac_phy *phy = &adpt->phy; if (phy->external) { for (i = 0; phy->uses_gpios && i < EMAC_GPIO_CNT; i++) { result = gpio_request(adpt->gpio[i], emac_gpio_name[i]); if (result) { emac_err(adpt, "error:%d on gpio_request(%d:%s)\n", emac_err(adpt, "error:%d on gpio_request(%d:%s)\n", result, adpt->gpio[i], emac_gpio_name[i]); while (--i >= 0) gpio_free(adpt->gpio[i]); goto error; } } } return 0; error: return result; } static inline int msm_emac_request_gpio_off(struct emac_adapter *adpt) static inline int msm_emac_request_gpio_off(struct emac_adapter *adpt, bool mdio, bool ephy) { int i = 0; struct emac_phy *phy = &adpt->phy; if (phy->external) { for (i = 0; phy->uses_gpios && i < EMAC_GPIO_CNT; i++) gpio_free(adpt->gpio[i]); } return 0; } static inline int msm_emac_request_pinctrl_on(struct emac_adapter *adpt) static inline int msm_emac_request_pinctrl_on(struct emac_adapter *adpt, bool mdio, bool ephy) { int result = 0; int ret = 0; struct emac_phy *phy = &adpt->phy; result = pinctrl_select_state(adpt->pinctrl, adpt->pins_active); if (phy->external) { if (mdio) { result = pinctrl_select_state(adpt->pinctrl, adpt->mdio_pins_active); if (result) emac_err(adpt, "error:%d Can not set %s pins\n", result, EMAC_PINCTRL_STATE_ACTIVE); return result; emac_err(adpt, "error:%d Can not switch on %s pins\n", result, EMAC_PINCTRL_STATE_MDIO_ACTIVE); ret = result; } if (ephy) { result = pinctrl_select_state(adpt->pinctrl, adpt->ephy_pins_active); if (result) emac_err(adpt, "error:%d Can not switch on %s pins\n", result, EMAC_PINCTRL_STATE_EPHY_ACTIVE); if (!ret) ret = result; } } return ret; } static inline int msm_emac_request_pinctrl_off(struct emac_adapter *adpt) static inline int msm_emac_request_pinctrl_off(struct emac_adapter *adpt, bool mdio, bool ephy) { int result = 0; int ret = 0; struct emac_phy *phy = &adpt->phy; result = pinctrl_select_state(adpt->pinctrl, adpt->pins_sleep); if (phy->external) { if (mdio) { result = pinctrl_select_state(adpt->pinctrl, adpt->mdio_pins_sleep); if (result) emac_err(adpt, "error:%d Can not set %s pins\n", result, EMAC_PINCTRL_STATE_SLEEP); return result; emac_err(adpt, "error:%d Can not switch off %s pins\n", result, EMAC_PINCTRL_STATE_MDIO_SLEEP); ret = result; } if (ephy) { result = pinctrl_select_state(adpt->pinctrl, adpt->ephy_pins_sleep); if (result) emac_err(adpt, "error:%d Can not switch off %s pins\n", result, EMAC_PINCTRL_STATE_EPHY_SLEEP); if (!ret) ret = result; } } return ret; } /* Bringup the interface/HW */ Loading @@ -1946,10 +2000,6 @@ int emac_up(struct emac_adapter *adpt) if (retval) return retval; retval = adpt->gpio_on(adpt); if (retval < 0) goto err_request_gpio; for (i = 0; i < EMAC_IRQ_CNT; i++) { struct emac_irq_per_dev *irq = &adpt->irq[i]; const struct emac_irq_common *irq_cmn = &emac_irq_cmn_tbl[i]; Loading Loading @@ -1989,8 +2039,6 @@ int emac_up(struct emac_adapter *adpt) return retval; err_request_irq: adpt->gpio_off(adpt); err_request_gpio: adpt->phy.ops.down(adpt); return retval; } Loading Loading @@ -2018,8 +2066,6 @@ void emac_down(struct emac_adapter *adpt, u32 ctrl) if (adpt->irq[i].irq) free_irq(adpt->irq[i].irq, &adpt->irq[i]); adpt->gpio_off(adpt); CLR_FLAG(adpt, ADPT_TASK_LSC_REQ); CLR_FLAG(adpt, ADPT_TASK_REINIT_REQ); CLR_FLAG(adpt, ADPT_TASK_CHK_SGMII_REQ); Loading Loading @@ -2718,20 +2764,36 @@ static int msm_emac_pinctrl_init(struct emac_adapter *adpt, struct device *dev) PTR_ERR(adpt->pinctrl)); return PTR_ERR(adpt->pinctrl); } adpt->pins_active = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_ACTIVE); if (IS_ERR_OR_NULL(adpt->pins_active)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup pinctrl active state\n", PTR_ERR(adpt->pins_active)); return PTR_ERR(adpt->pins_active); adpt->mdio_pins_active = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_MDIO_ACTIVE); if (IS_ERR_OR_NULL(adpt->mdio_pins_active)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup mdio pinctrl active state\n", PTR_ERR(adpt->mdio_pins_active)); return PTR_ERR(adpt->mdio_pins_active); } adpt->mdio_pins_sleep = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_MDIO_SLEEP); if (IS_ERR_OR_NULL(adpt->mdio_pins_sleep)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup mdio pinctrl sleep state\n", PTR_ERR(adpt->mdio_pins_sleep)); return PTR_ERR(adpt->mdio_pins_sleep); } adpt->ephy_pins_active = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_EPHY_ACTIVE); if (IS_ERR_OR_NULL(adpt->ephy_pins_active)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup ephy pinctrl active state\n", PTR_ERR(adpt->ephy_pins_active)); return PTR_ERR(adpt->ephy_pins_active); } adpt->pins_sleep = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_SLEEP); if (IS_ERR_OR_NULL(adpt->pins_sleep)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup pinctrl sleep state\n", PTR_ERR(adpt->pins_sleep)); return PTR_ERR(adpt->pins_sleep); adpt->ephy_pins_sleep = pinctrl_lookup_state(adpt->pinctrl, EMAC_PINCTRL_STATE_EPHY_SLEEP); if (IS_ERR_OR_NULL(adpt->ephy_pins_sleep)) { emac_dbg(adpt, probe, "error:%ld Failed to lookup ephy pinctrl sleep state\n", PTR_ERR(adpt->ephy_pins_sleep)); return PTR_ERR(adpt->ephy_pins_sleep); } return 0; Loading Loading @@ -3116,6 +3178,8 @@ static int emac_suspend(struct device *device) emac_hw_config_pow_save(hw, phy->link_speed, !!wufc, !!(wufc & EMAC_WOL_MAGIC)); /* Don't reset ephy as need it for WOL/Link detection later */ adpt->gpio_off(adpt, true, false); emac_disable_clks(adpt); emac_disable_regulator(adpt); return 0; Loading @@ -3130,11 +3194,13 @@ static int emac_resume(struct device *device) struct emac_hw *hw = &adpt->hw; u32 retval; adpt->gpio_on(adpt, true, false); emac_enable_regulator(adpt); emac_init_clks(adpt); emac_enable_clks(adpt); emac_hw_reset_mac(hw); emac_phy_reset_external(adpt); retval = emac_phy_setup_link(adpt, phy->autoneg_advertised, true, !phy->disable_fc_autoneg); if (retval) Loading Loading @@ -3244,6 +3310,11 @@ static int emac_probe(struct platform_device *pdev) if (retval) goto err_clk_en; /* Configure MDIO lines */ retval = adpt->gpio_on(adpt, true, true); if (retval) goto err_init_mdio_gpio; /* init external phy */ retval = emac_phy_init_external(adpt); if (retval) Loading Loading @@ -3313,6 +3384,8 @@ static int emac_probe(struct platform_device *pdev) err_register_netdev: err_phy_link: err_init_ephy: adpt->gpio_off(adpt, true, true); err_init_mdio_gpio: err_clk_en: err_init_phy: err_clk_init: Loading @@ -3339,6 +3412,7 @@ static int emac_remove(struct platform_device *pdev) if (TEST_FLAG(hw, HW_PTP_CAP)) emac_ptp_remove(netdev); adpt->gpio_off(adpt, true, true); emac_disable_regulator(adpt); emac_disable_clks(adpt); emac_release_resources(adpt); Loading
drivers/net/ethernet/qualcomm/emac/emac_phy.c +16 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -217,6 +217,19 @@ int emac_phy_write(struct emac_adapter *adpt, u16 phy_addr, u16 reg_addr, return retval; } /* reset external phy */ void emac_phy_reset_external(struct emac_adapter *adpt) { /* Trigger ephy reset by pulling line low */ adpt->gpio_off(adpt, false, true); /* need delay to complete ephy reset */ usleep_range(10000, 20000); /* Complete ephy reset by pulling line back up */ adpt->gpio_on(adpt, false, true); /* need delay to complete ephy reset */ usleep_range(10000, 20000); } /* initialize external phy */ int emac_phy_init_external(struct emac_adapter *adpt) { Loading @@ -226,6 +239,8 @@ int emac_phy_init_external(struct emac_adapter *adpt) int retval = 0; if (phy->external) { emac_phy_reset_external(adpt); retval = emac_phy_read(adpt, phy->addr, MII_PHYSID1, &phy_id[0]); if (retval) Loading