Loading drivers/net/phy/fixed_phy.c +23 −1 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <linux/gpio.h> #include <linux/gpio.h> #include <linux/seqlock.h> #include <linux/seqlock.h> #include <linux/idr.h> #include <linux/idr.h> #include <linux/netdevice.h> #include "swphy.h" #include "swphy.h" Loading @@ -38,6 +39,7 @@ struct fixed_phy { struct phy_device *phydev; struct phy_device *phydev; seqcount_t seqcount; seqcount_t seqcount; struct fixed_phy_status status; struct fixed_phy_status status; bool no_carrier; int (*link_update)(struct net_device *, struct fixed_phy_status *); int (*link_update)(struct net_device *, struct fixed_phy_status *); struct list_head node; struct list_head node; int link_gpio; int link_gpio; Loading @@ -48,9 +50,28 @@ static struct fixed_mdio_bus platform_fmb = { .phys = LIST_HEAD_INIT(platform_fmb.phys), .phys = LIST_HEAD_INIT(platform_fmb.phys), }; }; int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier) { struct fixed_mdio_bus *fmb = &platform_fmb; struct phy_device *phydev = dev->phydev; struct fixed_phy *fp; if (!phydev || !phydev->mdio.bus) return -EINVAL; list_for_each_entry(fp, &fmb->phys, node) { if (fp->addr == phydev->mdio.addr) { fp->no_carrier = !new_carrier; return 0; } } return -EINVAL; } EXPORT_SYMBOL_GPL(fixed_phy_change_carrier); static void fixed_phy_update(struct fixed_phy *fp) static void fixed_phy_update(struct fixed_phy *fp) { { if (gpio_is_valid(fp->link_gpio)) if (!fp->no_carrier && gpio_is_valid(fp->link_gpio)) fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio); fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio); } } Loading @@ -66,6 +87,7 @@ static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num) do { do { s = read_seqcount_begin(&fp->seqcount); s = read_seqcount_begin(&fp->seqcount); fp->status.link = !fp->no_carrier; /* Issue callback if user registered it. */ /* Issue callback if user registered it. */ if (fp->link_update) { if (fp->link_update) { fp->link_update(fp->phydev->attached_dev, fp->link_update(fp->phydev->attached_dev, Loading include/linux/phy_fixed.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -13,6 +13,7 @@ struct fixed_phy_status { struct device_node; struct device_node; #if IS_ENABLED(CONFIG_FIXED_PHY) #if IS_ENABLED(CONFIG_FIXED_PHY) extern int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier); extern int fixed_phy_add(unsigned int irq, int phy_id, extern int fixed_phy_add(unsigned int irq, int phy_id, struct fixed_phy_status *status, struct fixed_phy_status *status, int link_gpio); int link_gpio); Loading Loading @@ -47,6 +48,10 @@ static inline int fixed_phy_set_link_update(struct phy_device *phydev, { { return -ENODEV; return -ENODEV; } } static inline int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier) { return -EINVAL; } #endif /* CONFIG_FIXED_PHY */ #endif /* CONFIG_FIXED_PHY */ #endif /* __PHY_FIXED_H */ #endif /* __PHY_FIXED_H */ Loading
drivers/net/phy/fixed_phy.c +23 −1 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <linux/gpio.h> #include <linux/gpio.h> #include <linux/seqlock.h> #include <linux/seqlock.h> #include <linux/idr.h> #include <linux/idr.h> #include <linux/netdevice.h> #include "swphy.h" #include "swphy.h" Loading @@ -38,6 +39,7 @@ struct fixed_phy { struct phy_device *phydev; struct phy_device *phydev; seqcount_t seqcount; seqcount_t seqcount; struct fixed_phy_status status; struct fixed_phy_status status; bool no_carrier; int (*link_update)(struct net_device *, struct fixed_phy_status *); int (*link_update)(struct net_device *, struct fixed_phy_status *); struct list_head node; struct list_head node; int link_gpio; int link_gpio; Loading @@ -48,9 +50,28 @@ static struct fixed_mdio_bus platform_fmb = { .phys = LIST_HEAD_INIT(platform_fmb.phys), .phys = LIST_HEAD_INIT(platform_fmb.phys), }; }; int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier) { struct fixed_mdio_bus *fmb = &platform_fmb; struct phy_device *phydev = dev->phydev; struct fixed_phy *fp; if (!phydev || !phydev->mdio.bus) return -EINVAL; list_for_each_entry(fp, &fmb->phys, node) { if (fp->addr == phydev->mdio.addr) { fp->no_carrier = !new_carrier; return 0; } } return -EINVAL; } EXPORT_SYMBOL_GPL(fixed_phy_change_carrier); static void fixed_phy_update(struct fixed_phy *fp) static void fixed_phy_update(struct fixed_phy *fp) { { if (gpio_is_valid(fp->link_gpio)) if (!fp->no_carrier && gpio_is_valid(fp->link_gpio)) fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio); fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio); } } Loading @@ -66,6 +87,7 @@ static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num) do { do { s = read_seqcount_begin(&fp->seqcount); s = read_seqcount_begin(&fp->seqcount); fp->status.link = !fp->no_carrier; /* Issue callback if user registered it. */ /* Issue callback if user registered it. */ if (fp->link_update) { if (fp->link_update) { fp->link_update(fp->phydev->attached_dev, fp->link_update(fp->phydev->attached_dev, Loading
include/linux/phy_fixed.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -13,6 +13,7 @@ struct fixed_phy_status { struct device_node; struct device_node; #if IS_ENABLED(CONFIG_FIXED_PHY) #if IS_ENABLED(CONFIG_FIXED_PHY) extern int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier); extern int fixed_phy_add(unsigned int irq, int phy_id, extern int fixed_phy_add(unsigned int irq, int phy_id, struct fixed_phy_status *status, struct fixed_phy_status *status, int link_gpio); int link_gpio); Loading Loading @@ -47,6 +48,10 @@ static inline int fixed_phy_set_link_update(struct phy_device *phydev, { { return -ENODEV; return -ENODEV; } } static inline int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier) { return -EINVAL; } #endif /* CONFIG_FIXED_PHY */ #endif /* CONFIG_FIXED_PHY */ #endif /* __PHY_FIXED_H */ #endif /* __PHY_FIXED_H */