[PATCH 1/9] net: eqos: Add PHY reset control for i.MX platform

Parse the "phy-reset-gpios", "phy-reset-post-delay" and "phy-reset-duration" properties from eqos node to control the ethernet PHY reset at driver probe. Reset PHY once is enough that can reduce the time cost to get IP after the first time.
Signed-off-by: Ye Li ye.li@nxp.com --- drivers/net/dwc_eth_qos.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e8242ca..14aafc6 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -303,6 +303,8 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio; + uint32_t reset_delay; + uint32_t reset_post_delay; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref; @@ -1880,6 +1882,7 @@ static int eqos_probe_resources_imx(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); phy_interface_t interface; + int ret = 0;
debug("%s(dev=%p):\n", __func__, dev);
@@ -1890,8 +1893,52 @@ static int eqos_probe_resources_imx(struct udevice *dev) return -EINVAL; }
+ ret = gpio_request_by_name(dev, "phy-reset-gpios", 0, + &eqos->phy_reset_gpio, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + if (ret) { + pr_debug("gpio_request_by_name(phy reset) failed: %d", ret); + } + + if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) { + eqos->reset_delay = dev_read_u32_default(dev, "phy-reset-duration", 1); + if (eqos->reset_delay > 1000) { + pr_err("phy reset duration should be <= 1000ms\n"); + /* property value wrong, use default value */ + eqos->reset_delay = 1; + } + + mdelay(eqos->reset_delay); + + eqos->reset_post_delay = dev_read_u32_default(dev, + "phy-reset-post-delay", + 0); + if (eqos->reset_post_delay > 1000) { + pr_err("phy reset post delay should be <= 1000ms\n"); + /* property value wrong, use default value */ + eqos->reset_post_delay = 0; + } + + ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0); + if (ret < 0) { + pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", ret); + goto err_free_gpio_phy_reset; + } + + if (eqos->reset_post_delay) + mdelay(eqos->reset_post_delay); + } + debug("%s: OK\n", __func__); return 0; + +err_free_gpio_phy_reset: + if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) { + dm_gpio_free(dev, &eqos->phy_reset_gpio); + } + + debug("%s: returns %d\n", __func__, ret); + return ret; }
static phy_interface_t eqos_get_interface_imx(struct udevice *dev) @@ -1951,6 +1998,14 @@ static int eqos_remove_resources_stm32(struct udevice *dev)
static int eqos_remove_resources_imx(struct udevice *dev) { + struct eqos_priv *eqos = dev_get_priv(dev); + + debug("%s(dev=%p):\n", __func__, dev); + if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) { + dm_gpio_free(dev, &eqos->phy_reset_gpio); + } + + debug("%s: OK\n", __func__); return 0; }

i.MX8MP has two ENET controllers, have to update the function to enable loading two MAC addresses.
Signed-off-by: Ye Li ye.li@nxp.com --- arch/arm/mach-imx/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/mac.c b/arch/arm/mach-imx/mac.c index 3b1496b..9bb63d2 100644 --- a/arch/arm/mach-imx/mac.c +++ b/arch/arm/mach-imx/mac.c @@ -31,7 +31,7 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
offset = is_mx6() ? MAC_FUSE_MX6_OFFSET : MAC_FUSE_MX7_OFFSET; fuse = (struct imx_mac_fuse *)(ulong)(OCOTP_BASE_ADDR + offset); - has_second_mac = is_mx7() || is_mx6sx() || is_mx6ul() || is_mx6ull(); + has_second_mac = is_mx7() || is_mx6sx() || is_mx6ul() || is_mx6ull() || is_imx8mp();
if (has_second_mac && dev_id == 1) { u32 value = readl(&fuse->mac_addr2);

i.MX8MP has one DWC EQoS controller, so allow to build mac.c when only this driver is enabled.
Signed-off-by: Ye Li ye.li@nxp.com --- arch/arm/mach-imx/Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 1aa26a5..df2253d 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o endif obj-$(CONFIG_ENV_IS_IN_MMC) += mmc_env.o obj-$(CONFIG_FEC_MXC) += mac.o +obj-$(CONFIG_DWC_ETH_QOS) += mac.o obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o obj-y += cpu.o endif

Add node for EQoS ethernet controller as the second ethernet port on i.MX8MP
Signed-off-by: Ye Li ye.li@nxp.com --- arch/arm/dts/imx8mp.dtsi | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/arch/arm/dts/imx8mp.dtsi b/arch/arm/dts/imx8mp.dtsi index ecccfbb..813dc66 100644 --- a/arch/arm/dts/imx8mp.dtsi +++ b/arch/arm/dts/imx8mp.dtsi @@ -18,6 +18,7 @@
aliases { ethernet0 = &fec; + ethernet1 = &eqos; gpio0 = &gpio1; gpio1 = &gpio2; gpio2 = &gpio3; @@ -771,6 +772,28 @@ fsl,num-rx-queues = <3>; status = "disabled"; }; + + eqos: ethernet@30bf0000 { + compatible = "nxp,imx8mp-dwmac-eqos", "snps,dwmac-5.10a"; + reg = <0x30bf0000 0x10000>; + interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "eth_wake_irq", "macirq"; + clocks = <&clk IMX8MP_CLK_ENET_QOS_ROOT>, + <&clk IMX8MP_CLK_QOS_ENET_ROOT>, + <&clk IMX8MP_CLK_ENET_QOS_TIMER>, + <&clk IMX8MP_CLK_ENET_QOS>; + clock-names = "stmmaceth", "pclk", "ptp_ref", "tx"; + assigned-clocks = <&clk IMX8MP_CLK_ENET_AXI>, + <&clk IMX8MP_CLK_ENET_QOS_TIMER>, + <&clk IMX8MP_CLK_ENET_QOS>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>, + <&clk IMX8MP_SYS_PLL2_100M>, + <&clk IMX8MP_SYS_PLL2_125M>; + assigned-clock-rates = <0>, <100000000>, <125000000>; + intf_mode = <&gpr 0x4>; + status = "disabled"; + }; };
gic: interrupt-controller@38800000 {

i.MX8MP EVK has two ethernet ports. Add relevant nodes and properties for EQoS port to the EVK DTS file. In -u-boot.dtsi, change the u-boot eqos compatible string, add PHY reset gpio and remove assigned clocks as not supported in CCF.
Signed-off-by: Ye Li ye.li@nxp.com --- arch/arm/dts/imx8mp-evk-u-boot.dtsi | 11 ++++++++++ arch/arm/dts/imx8mp-evk.dts | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+)
diff --git a/arch/arm/dts/imx8mp-evk-u-boot.dtsi b/arch/arm/dts/imx8mp-evk-u-boot.dtsi index 6a91404..3f5fb47 100644 --- a/arch/arm/dts/imx8mp-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-evk-u-boot.dtsi @@ -140,6 +140,17 @@ u-boot,dm-spl; };
+&eqos { + compatible = "fsl,imx-eqos"; + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; + /delete-property/ assigned-clock-rates; + + phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; + phy-reset-duration = <15>; + phy-reset-post-delay = <100>; +}; + &fec { phy-reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>; phy-reset-duration = <15>; diff --git a/arch/arm/dts/imx8mp-evk.dts b/arch/arm/dts/imx8mp-evk.dts index b10dce8..f846d69 100644 --- a/arch/arm/dts/imx8mp-evk.dts +++ b/arch/arm/dts/imx8mp-evk.dts @@ -74,6 +74,26 @@ status = "okay"; };
+&eqos { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_eqos>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy0>; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + eee-broken-1000t; + }; + }; +}; + &flexcan2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_flexcan2>; @@ -160,6 +180,26 @@ };
&iomuxc { + pinctrl_eqos: eqosgrp { + fsl,pins = < + MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3 + MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3 + MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 + MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 + MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91 + MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91 + MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91 + MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 + MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f + MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f + MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f + MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f + MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f + MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f + MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x19 + >; + }; + pinctrl_fec: fecgrp { fsl,pins = < MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3

The setup functions should be independent for two ethernet controllers
Signed-off-by: Ye Li ye.li@nxp.com --- board/freescale/imx8mp_evk/imx8mp_evk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/board/freescale/imx8mp_evk/imx8mp_evk.c b/board/freescale/imx8mp_evk/imx8mp_evk.c index 89cc17c..bc4753c 100644 --- a/board/freescale/imx8mp_evk/imx8mp_evk.c +++ b/board/freescale/imx8mp_evk/imx8mp_evk.c @@ -101,9 +101,10 @@ int board_init(void)
if (CONFIG_IS_ENABLED(FEC_MXC)) { setup_fec(); + }
- if (CONFIG_IS_ENABLED(DWC_ETH_QOS)) - ret = setup_eqos(); + if (CONFIG_IS_ENABLED(DWC_ETH_QOS)) { + ret = setup_eqos(); }
return ret;

Since we uses the DTS and PHY reset gpio in EQoS driver to do the reset, remove the duplicated codes from board file.
Signed-off-by: Ye Li ye.li@nxp.com --- board/freescale/imx8mp_evk/imx8mp_evk.c | 19 ------------------- 1 file changed, 19 deletions(-)
diff --git a/board/freescale/imx8mp_evk/imx8mp_evk.c b/board/freescale/imx8mp_evk/imx8mp_evk.c index bc4753c..62096c2 100644 --- a/board/freescale/imx8mp_evk/imx8mp_evk.c +++ b/board/freescale/imx8mp_evk/imx8mp_evk.c @@ -54,30 +54,11 @@ static void setup_fec(void) setbits_le32(&gpr->gpr[1], BIT(22)); }
-#define EQOS_RST_PAD IMX_GPIO_NR(4, 22) -static iomux_v3_cfg_t const eqos_rst_pads[] = { - MX8MP_PAD_SAI2_RXC__GPIO4_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL), -}; - -static void setup_iomux_eqos(void) -{ - imx_iomux_v3_setup_multiple_pads(eqos_rst_pads, - ARRAY_SIZE(eqos_rst_pads)); - - gpio_request(EQOS_RST_PAD, "eqos_rst"); - gpio_direction_output(EQOS_RST_PAD, 0); - mdelay(15); - gpio_direction_output(EQOS_RST_PAD, 1); - mdelay(100); -} - static int setup_eqos(void) { struct iomuxc_gpr_base_regs *gpr = (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
- setup_iomux_eqos(); - /* set INTF as RGMII, enable RGMII TXC clock */ clrsetbits_le32(&gpr->gpr[1], IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK, BIT(16));

DWC EQOS driver has removed to use noncached memory, so delete the configuration from iMX8MP EVK head file.
Signed-off-by: Ye Li ye.li@nxp.com --- include/configs/imx8mp_evk.h | 3 --- 1 file changed, 3 deletions(-)
diff --git a/include/configs/imx8mp_evk.h b/include/configs/imx8mp_evk.h index 4850b1b..8c2e583 100644 --- a/include/configs/imx8mp_evk.h +++ b/include/configs/imx8mp_evk.h @@ -50,9 +50,6 @@ #define FEC_QUIRK_ENET_MAC
#define DWC_NET_PHYADDR 1 -#ifdef CONFIG_DWC_ETH_QOS -#define CONFIG_SYS_NONCACHED_MEMORY (1 * SZ_1M) /* 1M */ -#endif
#define PHY_ANEG_TIMEOUT 20000

Enable the EQoS i.MX driver in defconfig, also enable the PHYLIB to facilitate the case that only has FEC enabled.
Signed-off-by: Ye Li ye.li@nxp.com --- configs/imx8mp_evk_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig index e70c430..4611934 100644 --- a/configs/imx8mp_evk_defconfig +++ b/configs/imx8mp_evk_defconfig @@ -80,9 +80,11 @@ CONFIG_MMC_HS400_ES_SUPPORT=y CONFIG_MMC_HS400_SUPPORT=y CONFIG_FSL_ESDHC_IMX=y CONFIG_PHY_REALTEK=y +CONFIG_PHYLIB=y CONFIG_DM_ETH=y CONFIG_PHY_GIGE=y CONFIG_DWC_ETH_QOS=y +CONFIG_DWC_ETH_QOS_IMX=y CONFIG_FEC_MXC=y CONFIG_MII=y CONFIG_PINCTRL=y

Hi Ye,
series was completely lost on my side, I tried to check it today but it is obsolete now and conflicts with Peng's series for MX8ULP. So I drop it, yorry, you should rebase and post it again.
Best regards, Stefano Babic
On 19.02.21 08:07, Ye Li wrote:
Parse the "phy-reset-gpios", "phy-reset-post-delay" and "phy-reset-duration" properties from eqos node to control the ethernet PHY reset at driver probe. Reset PHY once is enough that can reduce the time cost to get IP after the first time.
Signed-off-by: Ye Li ye.li@nxp.com
drivers/net/dwc_eth_qos.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e8242ca..14aafc6 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -303,6 +303,8 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio;
- uint32_t reset_delay;
- uint32_t reset_post_delay; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref;
@@ -1880,6 +1882,7 @@ static int eqos_probe_resources_imx(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); phy_interface_t interface;
int ret = 0;
debug("%s(dev=%p):\n", __func__, dev);
@@ -1890,8 +1893,52 @@ static int eqos_probe_resources_imx(struct udevice *dev) return -EINVAL; }
- ret = gpio_request_by_name(dev, "phy-reset-gpios", 0,
&eqos->phy_reset_gpio,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
- if (ret) {
pr_debug("gpio_request_by_name(phy reset) failed: %d", ret);
- }
- if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
eqos->reset_delay = dev_read_u32_default(dev, "phy-reset-duration", 1);
if (eqos->reset_delay > 1000) {
pr_err("phy reset duration should be <= 1000ms\n");
/* property value wrong, use default value */
eqos->reset_delay = 1;
}
mdelay(eqos->reset_delay);
eqos->reset_post_delay = dev_read_u32_default(dev,
"phy-reset-post-delay",
0);
if (eqos->reset_post_delay > 1000) {
pr_err("phy reset post delay should be <= 1000ms\n");
/* property value wrong, use default value */
eqos->reset_post_delay = 0;
}
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
if (ret < 0) {
pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", ret);
goto err_free_gpio_phy_reset;
}
if (eqos->reset_post_delay)
mdelay(eqos->reset_post_delay);
- }
- debug("%s: OK\n", __func__); return 0;
+err_free_gpio_phy_reset:
if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
dm_gpio_free(dev, &eqos->phy_reset_gpio);
}
debug("%s: returns %d\n", __func__, ret);
return ret; }
static phy_interface_t eqos_get_interface_imx(struct udevice *dev)
@@ -1951,6 +1998,14 @@ static int eqos_remove_resources_stm32(struct udevice *dev)
static int eqos_remove_resources_imx(struct udevice *dev) {
- struct eqos_priv *eqos = dev_get_priv(dev);
- debug("%s(dev=%p):\n", __func__, dev);
- if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
dm_gpio_free(dev, &eqos->phy_reset_gpio);
- }
- debug("%s: OK\n", __func__); return 0; }

Hi Stefano,
Ok. I will rebase the patches after the 8ULP is merged.
Best regards, Ye Li
-----Original Message----- From: Stefano Babic sbabic@denx.de Sent: Saturday, July 17, 2021 8:54 PM To: Ye Li ye.li@nxp.com; sbabic@denx.de; u-boot@lists.denx.de; Peng Fan peng.fan@nxp.com; marex@denx.de Cc: rfried.dev@gmail.com; dl-uboot-imx uboot-imx@nxp.com; s.arendt@sensopart.de Subject: [EXT] Re: [PATCH 1/9] net: eqos: Add PHY reset control for i.MX platform
Caution: EXT Email
Hi Ye,
series was completely lost on my side, I tried to check it today but it is obsolete now and conflicts with Peng's series for MX8ULP. So I drop it, yorry, you should rebase and post it again.
Best regards, Stefano Babic
On 19.02.21 08:07, Ye Li wrote:
Parse the "phy-reset-gpios", "phy-reset-post-delay" and "phy-reset-duration" properties from eqos node to control the ethernet PHY reset at driver probe. Reset PHY once is enough that can reduce the time cost to get IP after the first time.
Signed-off-by: Ye Li ye.li@nxp.com
drivers/net/dwc_eth_qos.c | 55
+++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e8242ca..14aafc6 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -303,6 +303,8 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio;
uint32_t reset_delay;
uint32_t reset_post_delay; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref;
@@ -1880,6 +1882,7 @@ static int eqos_probe_resources_imx(struct
udevice *dev)
{ struct eqos_priv *eqos = dev_get_priv(dev); phy_interface_t interface;
int ret = 0; debug("%s(dev=%p):\n", __func__, dev);
@@ -1890,8 +1893,52 @@ static int eqos_probe_resources_imx(struct
udevice *dev)
return -EINVAL; }
ret = gpio_request_by_name(dev, "phy-reset-gpios", 0,
&eqos->phy_reset_gpio,
GPIOD_IS_OUT |
GPIOD_IS_OUT_ACTIVE);
if (ret) {
pr_debug("gpio_request_by_name(phy reset) failed: %d",
ret);
}
if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
eqos->reset_delay = dev_read_u32_default(dev,
"phy-reset-duration", 1);
if (eqos->reset_delay > 1000) {
pr_err("phy reset duration should be <=
1000ms\n");
/* property value wrong, use default value */
eqos->reset_delay = 1;
}
mdelay(eqos->reset_delay);
eqos->reset_post_delay = dev_read_u32_default(dev,
"phy-reset-post-delay",
0);
if (eqos->reset_post_delay > 1000) {
pr_err("phy reset post delay should be <=
1000ms\n");
/* property value wrong, use default value */
eqos->reset_post_delay = 0;
}
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
if (ret < 0) {
pr_err("dm_gpio_set_value(phy_reset, deassert)
failed: %d", ret);
goto err_free_gpio_phy_reset;
}
if (eqos->reset_post_delay)
mdelay(eqos->reset_post_delay);
}
debug("%s: OK\n", __func__); return 0;
+err_free_gpio_phy_reset:
if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
dm_gpio_free(dev, &eqos->phy_reset_gpio);
}
debug("%s: returns %d\n", __func__, ret);
return ret;
}
static phy_interface_t eqos_get_interface_imx(struct udevice *dev)
@@ -1951,6 +1998,14 @@ static int eqos_remove_resources_stm32(struct udevice *dev)
static int eqos_remove_resources_imx(struct udevice *dev) {
struct eqos_priv *eqos = dev_get_priv(dev);
debug("%s(dev=%p):\n", __func__, dev);
if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
dm_gpio_free(dev, &eqos->phy_reset_gpio);
}
}debug("%s: OK\n", __func__); return 0;
--
===== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de ================================================================ =====
participants (2)
-
Stefano Babic
-
Ye Li