diff options
author | Imre Kaloz <kaloz@openwrt.org> | 2014-06-17 15:13:10 +0000 |
---|---|---|
committer | Imre Kaloz <kaloz@openwrt.org> | 2014-06-17 15:13:10 +0000 |
commit | b3ca5188500e75c541ed7904faf5cdc174d1daf8 (patch) | |
tree | 8e49b4fed47204d364c9b2097a3b2b7cd012b2a9 /target/linux/mvebu/patches-3.14/019-add_fixed_phy_register.patch | |
parent | f71d455502323e4bce3df847fb5481adcf5602c7 (diff) | |
download | upstream-b3ca5188500e75c541ed7904faf5cdc174d1daf8.tar.gz upstream-b3ca5188500e75c541ed7904faf5cdc174d1daf8.tar.bz2 upstream-b3ca5188500e75c541ed7904faf5cdc174d1daf8.zip |
[mvebu]: preliminary support for the WRT1900AC (work in progress)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@41232 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/mvebu/patches-3.14/019-add_fixed_phy_register.patch')
-rw-r--r-- | target/linux/mvebu/patches-3.14/019-add_fixed_phy_register.patch | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.14/019-add_fixed_phy_register.patch b/target/linux/mvebu/patches-3.14/019-add_fixed_phy_register.patch new file mode 100644 index 0000000000..ad37aabcf6 --- /dev/null +++ b/target/linux/mvebu/patches-3.14/019-add_fixed_phy_register.patch @@ -0,0 +1,134 @@ +From a75951217472c522c324adb0a4de3ba69d656ef5 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Date: Fri, 16 May 2014 16:14:04 +0200 +Subject: net: phy: extend fixed driver with fixed_phy_register() + +The existing fixed_phy_add() function has several drawbacks that +prevents it from being used as is for OF-based declaration of fixed +PHYs: + + * The address of the PHY on the fake bus needs to be passed, while a + dynamic allocation is desired. + + * Since the phy_device instantiation is post-poned until the next + mdiobus scan, there is no way to associate the fixed PHY with its + OF node, which later prevents of_phy_connect() from finding this + fixed PHY from a given OF node. + +To solve this, this commit introduces fixed_phy_register(), which will +allocate an available PHY address, add the PHY using fixed_phy_add() +and instantiate the phy_device structure associated with the provided +OF node. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Acked-by: Florian Fainelli <f.fainelli@gmail.com> +Acked-by: Grant Likely <grant.likely@linaro.org> +Tested-by: Florian Fainelli <f.fainelli@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +--- a/drivers/net/phy/fixed.c ++++ b/drivers/net/phy/fixed.c +@@ -21,6 +21,7 @@ + #include <linux/phy_fixed.h> + #include <linux/err.h> + #include <linux/slab.h> ++#include <linux/of.h> + + #define MII_REGS_NUM 29 + +@@ -203,6 +204,66 @@ err_regs: + } + EXPORT_SYMBOL_GPL(fixed_phy_add); + ++void fixed_phy_del(int phy_addr) ++{ ++ struct fixed_mdio_bus *fmb = &platform_fmb; ++ struct fixed_phy *fp, *tmp; ++ ++ list_for_each_entry_safe(fp, tmp, &fmb->phys, node) { ++ if (fp->addr == phy_addr) { ++ list_del(&fp->node); ++ kfree(fp); ++ return; ++ } ++ } ++} ++EXPORT_SYMBOL_GPL(fixed_phy_del); ++ ++static int phy_fixed_addr; ++static DEFINE_SPINLOCK(phy_fixed_addr_lock); ++ ++int fixed_phy_register(unsigned int irq, ++ struct fixed_phy_status *status, ++ struct device_node *np) ++{ ++ struct fixed_mdio_bus *fmb = &platform_fmb; ++ struct phy_device *phy; ++ int phy_addr; ++ int ret; ++ ++ /* Get the next available PHY address, up to PHY_MAX_ADDR */ ++ spin_lock(&phy_fixed_addr_lock); ++ if (phy_fixed_addr == PHY_MAX_ADDR) { ++ spin_unlock(&phy_fixed_addr_lock); ++ return -ENOSPC; ++ } ++ phy_addr = phy_fixed_addr++; ++ spin_unlock(&phy_fixed_addr_lock); ++ ++ ret = fixed_phy_add(PHY_POLL, phy_addr, status); ++ if (ret < 0) ++ return ret; ++ ++ phy = get_phy_device(fmb->mii_bus, phy_addr, false); ++ if (!phy || IS_ERR(phy)) { ++ fixed_phy_del(phy_addr); ++ return -EINVAL; ++ } ++ ++ of_node_get(np); ++ phy->dev.of_node = np; ++ ++ ret = phy_device_register(phy); ++ if (ret) { ++ phy_device_free(phy); ++ of_node_put(np); ++ fixed_phy_del(phy_addr); ++ return ret; ++ } ++ ++ return 0; ++} ++ + static int __init fixed_mdio_bus_init(void) + { + struct fixed_mdio_bus *fmb = &platform_fmb; +--- a/include/linux/phy_fixed.h ++++ b/include/linux/phy_fixed.h +@@ -9,15 +9,26 @@ struct fixed_phy_status { + int asym_pause; + }; + ++struct device_node; ++ + #ifdef CONFIG_FIXED_PHY + extern int fixed_phy_add(unsigned int irq, int phy_id, + struct fixed_phy_status *status); ++extern int fixed_phy_register(unsigned int irq, ++ struct fixed_phy_status *status, ++ struct device_node *np); + #else + static inline int fixed_phy_add(unsigned int irq, int phy_id, + struct fixed_phy_status *status) + { + return -ENODEV; + } ++static inline int fixed_phy_register(unsigned int irq, ++ struct fixed_phy_status *status, ++ struct device_node *np) ++{ ++ return -ENODEV; ++} + #endif /* CONFIG_FIXED_PHY */ + + /* |