diff options
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/aquantia_main.c | 15 | ||||
-rw-r--r-- | drivers/net/phy/broadcom.c | 13 | ||||
-rw-r--r-- | drivers/net/phy/dp83822.c | 4 | ||||
-rw-r--r-- | drivers/net/phy/dp83867.c | 10 | ||||
-rw-r--r-- | drivers/net/phy/mdio-i2c.c | 3 | ||||
-rw-r--r-- | drivers/net/phy/mdio-i2c.h | 16 | ||||
-rw-r--r-- | drivers/net/phy/mdio-mux-meson-g12a.c | 23 | ||||
-rw-r--r-- | drivers/net/phy/mdio-thunder.c | 1 | ||||
-rw-r--r-- | drivers/net/phy/mdio-xgene.c | 2 | ||||
-rw-r--r-- | drivers/net/phy/mdio-xgene.h | 130 | ||||
-rw-r--r-- | drivers/net/phy/mdio_bus.c | 10 | ||||
-rw-r--r-- | drivers/net/phy/meson-gxl.c | 4 | ||||
-rw-r--r-- | drivers/net/phy/micrel.c | 12 | ||||
-rw-r--r-- | drivers/net/phy/microchip.c | 32 | ||||
-rw-r--r-- | drivers/net/phy/phy_device.c | 1 | ||||
-rw-r--r-- | drivers/net/phy/sfp.c | 4 | ||||
-rw-r--r-- | drivers/net/phy/smsc.c | 5 | ||||
-rw-r--r-- | drivers/net/phy/xilinx_gmii2rgmii.c | 1 |
18 files changed, 114 insertions, 172 deletions
diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia_main.c index 975789d9349d..75d8351ee250 100644 --- a/drivers/net/phy/aquantia_main.c +++ b/drivers/net/phy/aquantia_main.c @@ -34,6 +34,8 @@ #define MDIO_AN_VEND_PROV 0xc400 #define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) #define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) +#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11) +#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10) #define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4) #define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0) #define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4 @@ -230,9 +232,20 @@ static int aqr_config_aneg(struct phy_device *phydev) phydev->advertising)) reg |= MDIO_AN_VEND_PROV_1000BASET_HALF; + /* Handle the case when the 2.5G and 5G speeds are not advertised */ + if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + phydev->advertising)) + reg |= MDIO_AN_VEND_PROV_2500BASET_FULL; + + if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + phydev->advertising)) + reg |= MDIO_AN_VEND_PROV_5000BASET_FULL; + ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, MDIO_AN_VEND_PROV_1000BASET_HALF | - MDIO_AN_VEND_PROV_1000BASET_FULL, reg); + MDIO_AN_VEND_PROV_1000BASET_FULL | + MDIO_AN_VEND_PROV_2500BASET_FULL | + MDIO_AN_VEND_PROV_5000BASET_FULL, reg); if (ret < 0) return ret; if (ret > 0) diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 7be75a611e9e..0e0bcc304d6c 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -425,6 +425,17 @@ static int bcm5482_read_status(struct phy_device *phydev) return err; } +static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum) +{ + return -EOPNOTSUPP; +} + +static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum, + u16 val) +{ + return -EOPNOTSUPP; +} + static int bcm5481_config_aneg(struct phy_device *phydev) { struct device_node *np = phydev->mdio.dev.of_node; @@ -696,6 +707,8 @@ static struct phy_driver broadcom_drivers[] = { .phy_id_mask = 0xfffffff0, .name = "Broadcom BCM54810", /* PHY_GBIT_FEATURES */ + .read_mmd = bcm54810_read_mmd, + .write_mmd = bcm54810_write_mmd, .config_init = bcm54xx_config_init, .config_aneg = bcm5481_config_aneg, .ack_interrupt = bcm_phy_ack_intr, diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c index ae17d2f9d534..da3983352dd4 100644 --- a/drivers/net/phy/dp83822.c +++ b/drivers/net/phy/dp83822.c @@ -197,9 +197,7 @@ static int dp83822_config_intr(struct phy_device *phydev) if (misr_status < 0) return misr_status; - misr_status |= (DP83822_RX_ERR_HF_INT_EN | - DP83822_FALSE_CARRIER_HF_INT_EN | - DP83822_ANEG_COMPLETE_INT_EN | + misr_status |= (DP83822_ANEG_COMPLETE_INT_EN | DP83822_DUP_MODE_CHANGE_INT_EN | DP83822_SPEED_CHANGED_INT_EN | DP83822_LINK_STAT_INT_EN | diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index 87c0cdbf262a..1375beb3cf83 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -432,6 +432,14 @@ static int dp83867_config_init(struct phy_device *phydev) else val &= ~DP83867_SGMII_TYPE; phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val); + + /* This is a SW workaround for link instability if RX_CTRL is + * not strapped to mode 3 or 4 in HW. This is required for SGMII + * in addition to clearing bit 7, handled above. + */ + if (dp83867->rxctrl_strap_quirk) + phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, + BIT(8)); } val = phy_read(phydev, DP83867_CFG3); @@ -468,7 +476,7 @@ static int dp83867_phy_reset(struct phy_device *phydev) { int err; - err = phy_write(phydev, DP83867_CTRL, DP83867_SW_RESTART); + err = phy_write(phydev, DP83867_CTRL, DP83867_SW_RESET); if (err < 0) return err; diff --git a/drivers/net/phy/mdio-i2c.c b/drivers/net/phy/mdio-i2c.c index 0dce67672548..5969878e0aa7 100644 --- a/drivers/net/phy/mdio-i2c.c +++ b/drivers/net/phy/mdio-i2c.c @@ -10,10 +10,9 @@ * of their settings. */ #include <linux/i2c.h> +#include <linux/mdio/mdio-i2c.h> #include <linux/phy.h> -#include "mdio-i2c.h" - /* * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is * specified to be present in SFP modules. These correspond with PHY diff --git a/drivers/net/phy/mdio-i2c.h b/drivers/net/phy/mdio-i2c.h deleted file mode 100644 index 751dab281f57..000000000000 --- a/drivers/net/phy/mdio-i2c.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * MDIO I2C bridge - * - * Copyright (C) 2015 Russell King - */ -#ifndef MDIO_I2C_H -#define MDIO_I2C_H - -struct device; -struct i2c_adapter; -struct mii_bus; - -struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c); - -#endif diff --git a/drivers/net/phy/mdio-mux-meson-g12a.c b/drivers/net/phy/mdio-mux-meson-g12a.c index 7a9ad54582e1..aa3ad38e37d7 100644 --- a/drivers/net/phy/mdio-mux-meson-g12a.c +++ b/drivers/net/phy/mdio-mux-meson-g12a.c @@ -4,6 +4,7 @@ */ #include <linux/bitfield.h> +#include <linux/delay.h> #include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/device.h> @@ -148,6 +149,7 @@ static const struct clk_ops g12a_ephy_pll_ops = { static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv) { + u32 value; int ret; /* Enable the phy clock */ @@ -161,18 +163,25 @@ static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv) /* Initialize ephy control */ writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0); - writel(FIELD_PREP(PHY_CNTL1_ST_MODE, 3) | - FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) | - FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) | - PHY_CNTL1_CLK_EN | - PHY_CNTL1_CLKFREQ | - PHY_CNTL1_PHY_ENB, - priv->regs + ETH_PHY_CNTL1); + + /* Make sure we get a 0 -> 1 transition on the enable bit */ + value = FIELD_PREP(PHY_CNTL1_ST_MODE, 3) | + FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) | + FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) | + PHY_CNTL1_CLK_EN | + PHY_CNTL1_CLKFREQ; + writel(value, priv->regs + ETH_PHY_CNTL1); writel(PHY_CNTL2_USE_INTERNAL | PHY_CNTL2_SMI_SRC_MAC | PHY_CNTL2_RX_CLK_EPHY, priv->regs + ETH_PHY_CNTL2); + value |= PHY_CNTL1_PHY_ENB; + writel(value, priv->regs + ETH_PHY_CNTL1); + + /* The phy needs a bit of time to power up */ + mdelay(10); + return 0; } diff --git a/drivers/net/phy/mdio-thunder.c b/drivers/net/phy/mdio-thunder.c index 1e2f57ed1ef7..31ca0361a11e 100644 --- a/drivers/net/phy/mdio-thunder.c +++ b/drivers/net/phy/mdio-thunder.c @@ -104,6 +104,7 @@ static int thunder_mdiobus_pci_probe(struct pci_dev *pdev, if (i >= ARRAY_SIZE(nexus->buses)) break; } + fwnode_handle_put(fwn); return 0; err_release_regions: diff --git a/drivers/net/phy/mdio-xgene.c b/drivers/net/phy/mdio-xgene.c index 34990eaa3298..461207cdf5d6 100644 --- a/drivers/net/phy/mdio-xgene.c +++ b/drivers/net/phy/mdio-xgene.c @@ -11,6 +11,7 @@ #include <linux/efi.h> #include <linux/if_vlan.h> #include <linux/io.h> +#include <linux/mdio/mdio-xgene.h> #include <linux/module.h> #include <linux/of_platform.h> #include <linux/of_net.h> @@ -18,7 +19,6 @@ #include <linux/prefetch.h> #include <linux/phy.h> #include <net/ip.h> -#include "mdio-xgene.h" static bool xgene_mdio_status; diff --git a/drivers/net/phy/mdio-xgene.h b/drivers/net/phy/mdio-xgene.h deleted file mode 100644 index b1f5ccb4ad9c..000000000000 --- a/drivers/net/phy/mdio-xgene.h +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* Applied Micro X-Gene SoC MDIO Driver - * - * Copyright (c) 2016, Applied Micro Circuits Corporation - * Author: Iyappan Subramanian <isubramanian@apm.com> - */ - -#ifndef __MDIO_XGENE_H__ -#define __MDIO_XGENE_H__ - -#define BLOCK_XG_MDIO_CSR_OFFSET 0x5000 -#define BLOCK_DIAG_CSR_OFFSET 0xd000 -#define XGENET_CONFIG_REG_ADDR 0x20 - -#define MAC_ADDR_REG_OFFSET 0x00 -#define MAC_COMMAND_REG_OFFSET 0x04 -#define MAC_WRITE_REG_OFFSET 0x08 -#define MAC_READ_REG_OFFSET 0x0c -#define MAC_COMMAND_DONE_REG_OFFSET 0x10 - -#define CLKEN_OFFSET 0x08 -#define SRST_OFFSET 0x00 - -#define MENET_CFG_MEM_RAM_SHUTDOWN_ADDR 0x70 -#define MENET_BLOCK_MEM_RDY_ADDR 0x74 - -#define MAC_CONFIG_1_ADDR 0x00 -#define MII_MGMT_COMMAND_ADDR 0x24 -#define MII_MGMT_ADDRESS_ADDR 0x28 -#define MII_MGMT_CONTROL_ADDR 0x2c -#define MII_MGMT_STATUS_ADDR 0x30 -#define MII_MGMT_INDICATORS_ADDR 0x34 -#define SOFT_RESET BIT(31) - -#define MII_MGMT_CONFIG_ADDR 0x20 -#define MII_MGMT_COMMAND_ADDR 0x24 -#define MII_MGMT_ADDRESS_ADDR 0x28 -#define MII_MGMT_CONTROL_ADDR 0x2c -#define MII_MGMT_STATUS_ADDR 0x30 -#define MII_MGMT_INDICATORS_ADDR 0x34 - -#define MIIM_COMMAND_ADDR 0x20 -#define MIIM_FIELD_ADDR 0x24 -#define MIIM_CONFIGURATION_ADDR 0x28 -#define MIIM_LINKFAILVECTOR_ADDR 0x2c -#define MIIM_INDICATOR_ADDR 0x30 -#define MIIMRD_FIELD_ADDR 0x34 - -#define MDIO_CSR_OFFSET 0x5000 - -#define REG_ADDR_POS 0 -#define REG_ADDR_LEN 5 -#define PHY_ADDR_POS 8 -#define PHY_ADDR_LEN 5 - -#define HSTMIIMWRDAT_POS 0 -#define HSTMIIMWRDAT_LEN 16 -#define HSTPHYADX_POS 23 -#define HSTPHYADX_LEN 5 -#define HSTREGADX_POS 18 -#define HSTREGADX_LEN 5 -#define HSTLDCMD BIT(3) -#define HSTMIIMCMD_POS 0 -#define HSTMIIMCMD_LEN 3 - -#define BUSY_MASK BIT(0) -#define READ_CYCLE_MASK BIT(0) - -enum xgene_enet_cmd { - XGENE_ENET_WR_CMD = BIT(31), - XGENE_ENET_RD_CMD = BIT(30) -}; - -enum { - MIIM_CMD_IDLE, - MIIM_CMD_LEGACY_WRITE, - MIIM_CMD_LEGACY_READ, -}; - -enum xgene_mdio_id { - XGENE_MDIO_RGMII = 1, - XGENE_MDIO_XFI -}; - -struct xgene_mdio_pdata { - struct clk *clk; - struct device *dev; - void __iomem *mac_csr_addr; - void __iomem *diag_csr_addr; - void __iomem *mdio_csr_addr; - struct mii_bus *mdio_bus; - int mdio_id; - spinlock_t mac_lock; /* mac lock */ -}; - -/* Set the specified value into a bit-field defined by its starting position - * and length within a single u64. - */ -static inline u64 xgene_enet_set_field_value(int pos, int len, u64 val) -{ - return (val & ((1ULL << len) - 1)) << pos; -} - -#define SET_VAL(field, val) \ - xgene_enet_set_field_value(field ## _POS, field ## _LEN, val) - -#define SET_BIT(field) \ - xgene_enet_set_field_value(field ## _POS, 1, 1) - -/* Get the value from a bit-field defined by its starting position - * and length within the specified u64. - */ -static inline u64 xgene_enet_get_field_value(int pos, int len, u64 src) -{ - return (src >> pos) & ((1ULL << len) - 1); -} - -#define GET_VAL(field, src) \ - xgene_enet_get_field_value(field ## _POS, field ## _LEN, src) - -#define GET_BIT(field, src) \ - xgene_enet_get_field_value(field ## _POS, 1, src) - -u32 xgene_mdio_rd_mac(struct xgene_mdio_pdata *pdata, u32 rd_addr); -void xgene_mdio_wr_mac(struct xgene_mdio_pdata *pdata, u32 wr_addr, u32 data); -int xgene_mdio_rgmii_read(struct mii_bus *bus, int phy_id, int reg); -int xgene_mdio_rgmii_write(struct mii_bus *bus, int phy_id, int reg, u16 data); -struct phy_device *xgene_enet_phy_register(struct mii_bus *bus, int phy_addr); - -#endif /* __MDIO_XGENE_H__ */ diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index b0a439248ff6..fdf8221f46fa 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -117,7 +117,12 @@ EXPORT_SYMBOL(mdiobus_unregister_device); struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr) { - struct mdio_device *mdiodev = bus->mdio_map[addr]; + struct mdio_device *mdiodev; + + if (addr < 0 || addr >= ARRAY_SIZE(bus->mdio_map)) + return NULL; + + mdiodev = bus->mdio_map[addr]; if (!mdiodev) return NULL; @@ -419,7 +424,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner) bus->reset(bus); for (i = 0; i < PHY_MAX_ADDR; i++) { - if ((bus->phy_mask & (1 << i)) == 0) { + if ((bus->phy_mask & BIT(i)) == 0) { struct phy_device *phydev; phydev = mdiobus_scan(bus, i); @@ -753,7 +758,6 @@ int __init mdio_bus_init(void) return ret; } -EXPORT_SYMBOL_GPL(mdio_bus_init); #if IS_ENABLED(CONFIG_PHYLIB) void mdio_bus_exit(void) diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c index e8f2ca625837..39151ec6f65e 100644 --- a/drivers/net/phy/meson-gxl.c +++ b/drivers/net/phy/meson-gxl.c @@ -235,6 +235,8 @@ static struct phy_driver meson_gxl_phy[] = { .config_intr = meson_gxl_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, + .read_mmd = genphy_read_mmd_unsupported, + .write_mmd = genphy_write_mmd_unsupported, }, { PHY_ID_MATCH_EXACT(0x01803301), .name = "Meson G12A Internal PHY", @@ -245,6 +247,8 @@ static struct phy_driver meson_gxl_phy[] = { .config_intr = meson_gxl_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, + .read_mmd = genphy_read_mmd_unsupported, + .write_mmd = genphy_write_mmd_unsupported, }, }; diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 18cc5e4280e8..caaa51a70cbd 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -282,7 +282,7 @@ static int kszphy_config_reset(struct phy_device *phydev) } } - if (priv->led_mode >= 0) + if (priv->type && priv->led_mode >= 0) kszphy_setup_led(phydev, priv->type->led_mode_reg, priv->led_mode); return 0; @@ -298,10 +298,10 @@ static int kszphy_config_init(struct phy_device *phydev) type = priv->type; - if (type->has_broadcast_disable) + if (type && type->has_broadcast_disable) kszphy_broadcast_disable(phydev); - if (type->has_nand_tree_disable) + if (type && type->has_nand_tree_disable) kszphy_nand_tree_disable(phydev); return kszphy_config_reset(phydev); @@ -939,7 +939,7 @@ static int kszphy_probe(struct phy_device *phydev) priv->type = type; - if (type->led_mode_reg) { + if (type && type->led_mode_reg) { ret = of_property_read_u32(np, "micrel,led-mode", &priv->led_mode); if (ret) @@ -960,7 +960,8 @@ static int kszphy_probe(struct phy_device *phydev) unsigned long rate = clk_get_rate(clk); bool rmii_ref_clk_sel_25_mhz; - priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel; + if (type) + priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel; rmii_ref_clk_sel_25_mhz = of_property_read_bool(np, "micrel,rmii-reference-clock-select-25-mhz"); @@ -1155,6 +1156,7 @@ static struct phy_driver ksphy_driver[] = { /* PHY_GBIT_FEATURES */ .driver_data = &ksz9021_type, .probe = kszphy_probe, + .soft_reset = genphy_soft_reset, .config_init = ksz9131_config_init, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c index a644e8e5071c..375bbd60b38a 100644 --- a/drivers/net/phy/microchip.c +++ b/drivers/net/phy/microchip.c @@ -326,6 +326,37 @@ static int lan88xx_config_aneg(struct phy_device *phydev) return genphy_config_aneg(phydev); } +static void lan88xx_link_change_notify(struct phy_device *phydev) +{ + int temp; + + /* At forced 100 F/H mode, chip may fail to set mode correctly + * when cable is switched between long(~50+m) and short one. + * As workaround, set to 10 before setting to 100 + * at forced 100 F/H mode. + */ + if (!phydev->autoneg && phydev->speed == 100) { + /* disable phy interrupt */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; + phy_write(phydev, LAN88XX_INT_MASK, temp); + + temp = phy_read(phydev, MII_BMCR); + temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); + phy_write(phydev, MII_BMCR, temp); /* set to 10 first */ + temp |= BMCR_SPEED100; + phy_write(phydev, MII_BMCR, temp); /* set to 100 later */ + + /* clear pending interrupt generated while workaround */ + temp = phy_read(phydev, LAN88XX_INT_STS); + + /* enable phy interrupt back */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; + phy_write(phydev, LAN88XX_INT_MASK, temp); + } +} + static struct phy_driver microchip_phy_driver[] = { { .phy_id = 0x0007c130, @@ -339,6 +370,7 @@ static struct phy_driver microchip_phy_driver[] = { .config_init = lan88xx_config_init, .config_aneg = lan88xx_config_aneg, + .link_change_notify = lan88xx_link_change_notify, .ack_interrupt = lan88xx_phy_ack_interrupt, .config_intr = lan88xx_phy_config_intr, diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 78b918dcd547..388799985720 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1312,6 +1312,7 @@ error: error_module_put: module_put(d->driver->owner); + d->driver = NULL; error_put_device: put_device(d); if (ndev_owner != bus->owner) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 5657c604602e..9639aa181968 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -7,6 +7,7 @@ #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/jiffies.h> +#include <linux/mdio/mdio-i2c.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/of.h> @@ -16,7 +17,6 @@ #include <linux/slab.h> #include <linux/workqueue.h> -#include "mdio-i2c.h" #include "sfp.h" #include "swphy.h" @@ -1878,7 +1878,7 @@ static int sfp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, sfp); - err = devm_add_action(sfp->dev, sfp_cleanup, sfp); + err = devm_add_action_or_reset(sfp->dev, sfp_cleanup, sfp); if (err < 0) return err; diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index b73298250793..e387c219f17d 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -108,8 +108,11 @@ static int lan911x_config_init(struct phy_device *phydev) static int lan87xx_read_status(struct phy_device *phydev) { struct smsc_phy_priv *priv = phydev->priv; + int err; - int err = genphy_read_status(phydev); + err = genphy_read_status(phydev); + if (err) + return err; if (!phydev->link && priv->energy_enable) { int i; diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c index 151c2a3f0b3a..7a78dfdfa5bd 100644 --- a/drivers/net/phy/xilinx_gmii2rgmii.c +++ b/drivers/net/phy/xilinx_gmii2rgmii.c @@ -82,6 +82,7 @@ static int xgmiitorgmii_probe(struct mdio_device *mdiodev) if (!priv->phy_dev->drv) { dev_info(dev, "Attached phy not ready\n"); + put_device(&priv->phy_dev->mdio.dev); return -EPROBE_DEFER; } |