diff options
Diffstat (limited to 'target/mips/mikrotik-rb4xx/patches/3.14.15/0021-phy-add-mdio-boardinfo.patch')
-rw-r--r-- | target/mips/mikrotik-rb4xx/patches/3.14.15/0021-phy-add-mdio-boardinfo.patch | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/target/mips/mikrotik-rb4xx/patches/3.14.15/0021-phy-add-mdio-boardinfo.patch b/target/mips/mikrotik-rb4xx/patches/3.14.15/0021-phy-add-mdio-boardinfo.patch new file mode 100644 index 000000000..3ec15e171 --- /dev/null +++ b/target/mips/mikrotik-rb4xx/patches/3.14.15/0021-phy-add-mdio-boardinfo.patch @@ -0,0 +1,227 @@ +From b8d5957374dc0e6ec8687c6e1b154ea066d27a5b Mon Sep 17 00:00:00 2001 +From: Phil Sutter <phil@nwl.cc> +Date: Wed, 14 May 2014 02:44:43 +0200 +Subject: [PATCH] phy: add mdio boardinfo + +--- + drivers/net/Makefile | 2 +- + drivers/net/phy/Kconfig | 4 +++ + drivers/net/phy/Makefile | 2 ++ + drivers/net/phy/mdio-boardinfo.c | 58 ++++++++++++++++++++++++++++++++++++++++ + drivers/net/phy/mdio-boardinfo.h | 22 +++++++++++++++ + drivers/net/phy/mdio_bus.c | 20 ++++++++++++++ + include/linux/phy.h | 18 +++++++++++++ + 7 files changed, 125 insertions(+), 1 deletion(-) + create mode 100644 drivers/net/phy/mdio-boardinfo.c + create mode 100644 drivers/net/phy/mdio-boardinfo.h + +diff --git a/drivers/net/Makefile b/drivers/net/Makefile +index 3fef8a8..70b736b 100644 +--- a/drivers/net/Makefile ++++ b/drivers/net/Makefile +@@ -15,7 +15,7 @@ obj-$(CONFIG_MII) += mii.o + obj-$(CONFIG_MDIO) += mdio.o + obj-$(CONFIG_NET) += Space.o loopback.o + obj-$(CONFIG_NETCONSOLE) += netconsole.o +-obj-$(CONFIG_PHYLIB) += phy/ ++obj-y += phy/ + obj-$(CONFIG_RIONET) += rionet.o + obj-$(CONFIG_NET_TEAM) += team/ + obj-$(CONFIG_TUN) += tun.o +diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig +index 0414889..97ca8ec 100644 +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -12,6 +12,10 @@ menuconfig PHYLIB + + if PHYLIB + ++config MDIO_BOARDINFO ++ bool ++ default y ++ + config SWCONFIG + tristate "Switch configuration API" + ---help--- +diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile +index 3c76ff8..0c990a4 100644 +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -2,6 +2,8 @@ + + libphy-objs := phy.o phy_device.o mdio_bus.o + ++obj-$(CONFIG_MDIO_BOARDINFO) += mdio-boardinfo.o ++ + obj-$(CONFIG_PHYLIB) += libphy.o + obj-$(CONFIG_SWCONFIG) += swconfig.o + obj-$(CONFIG_MARVELL_PHY) += marvell.o +diff --git a/drivers/net/phy/mdio-boardinfo.c b/drivers/net/phy/mdio-boardinfo.c +new file mode 100644 +index 0000000..9b8aaed +--- /dev/null ++++ b/drivers/net/phy/mdio-boardinfo.c +@@ -0,0 +1,58 @@ ++/* ++ * mdio-boardinfo.c - collect pre-declarations of PHY devices ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/phy.h> ++#include <linux/slab.h> ++#include <linux/export.h> ++#include <linux/mutex.h> ++#include <linux/phy.h> ++ ++#include "mdio-boardinfo.h" ++ ++/* ++ * These symbols are exported ONLY FOR the mdio_bus component. ++ * No other users will be supported. ++ */ ++ ++LIST_HEAD(__mdio_board_list); ++EXPORT_SYMBOL_GPL(__mdio_board_list); ++ ++DEFINE_MUTEX(__mdio_board_lock); ++EXPORT_SYMBOL_GPL(__mdio_board_lock); ++ ++/** ++ * mdio_register_board_info - register PHY devices for a given board ++ * @info: array of chip descriptors ++ * @n: how many descriptors are provided ++ * Context: can sleep ++ * ++ * The board info passed can safely be __initdata ... but be careful of ++ * any embedded pointers (platform_data, etc), they're copied as-is. ++ */ ++int __init ++mdiobus_register_board_info(struct mdio_board_info const *info, unsigned n) ++{ ++ struct mdio_board_entry *be; ++ int i; ++ ++ be = kzalloc(n * sizeof(*be), GFP_KERNEL); ++ if (!be) ++ return -ENOMEM; ++ ++ for (i = 0; i < n; i++, be++, info++) { ++ memcpy(&be->board_info, info, sizeof(*info)); ++ mutex_lock(&__mdio_board_lock); ++ list_add_tail(&be->list, &__mdio_board_list); ++ mutex_unlock(&__mdio_board_lock); ++ } ++ ++ return 0; ++} +diff --git a/drivers/net/phy/mdio-boardinfo.h b/drivers/net/phy/mdio-boardinfo.h +new file mode 100644 +index 0000000..28fbc0d +--- /dev/null ++++ b/drivers/net/phy/mdio-boardinfo.h +@@ -0,0 +1,22 @@ ++/* ++ * mdio-boardinfo.h - boardinfo interface internal to the mdio_bus component ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ */ ++ ++#include <linux/mutex.h> ++ ++struct mdio_board_entry { ++ struct list_head list; ++ struct mdio_board_info board_info; ++}; ++ ++/* __mdio_board_lock protects __mdio_board_list ++ * only mdio_bus components are allowed to use these symbols. ++ */ ++extern struct mutex __mdio_board_lock; ++extern struct list_head __mdio_board_list; +diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c +index 71e4900..50fbe35 100644 +--- a/drivers/net/phy/mdio_bus.c ++++ b/drivers/net/phy/mdio_bus.c +@@ -38,6 +38,8 @@ + + #include <asm/irq.h> + ++#include "mdio-boardinfo.h" ++ + /** + * mdiobus_alloc_size - allocate a mii_bus structure + * @size: extra amount of memory to allocate for private storage. +@@ -224,15 +226,33 @@ void mdiobus_free(struct mii_bus *bus) + } + EXPORT_SYMBOL(mdiobus_free); + ++static void mdiobus_setup_phydev_from_boardinfo(struct mii_bus *bus, ++ struct phy_device *phydev, ++ struct mdio_board_info *bi) ++{ ++ if (strcmp(bus->id, bi->bus_id) || ++ bi->phy_addr != phydev->addr) ++ return; ++ ++ phydev->dev.platform_data = (void *) bi->platform_data; ++} ++ + struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) + { + struct phy_device *phydev; ++ struct mdio_board_entry *be; + int err; + + phydev = get_phy_device(bus, addr, false); + if (IS_ERR(phydev) || phydev == NULL) + return phydev; + ++ mutex_lock(&__mdio_board_lock); ++ list_for_each_entry(be, &__mdio_board_list, list) ++ mdiobus_setup_phydev_from_boardinfo(bus, phydev, ++ &be->board_info); ++ mutex_unlock(&__mdio_board_lock); ++ + err = phy_device_register(phydev); + if (err) { + phy_device_free(phydev); +diff --git a/include/linux/phy.h b/include/linux/phy.h +index f1441b4..9dca415 100644 +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -658,4 +658,22 @@ int __init mdio_bus_init(void); + void mdio_bus_exit(void); + + extern struct bus_type mdio_bus_type; ++ ++struct mdio_board_info { ++ const char *bus_id; ++ int phy_addr; ++ ++ const void *platform_data; ++}; ++ ++#ifdef CONFIG_MDIO_BOARDINFO ++int mdiobus_register_board_info(const struct mdio_board_info *info, unsigned n); ++#else ++static inline int ++mdiobus_register_board_info(const struct mdio_board_info *info, unsigned n) ++{ ++ return 0; ++} ++#endif ++ + #endif /* __PHY_H */ +-- +1.8.5.3 + |