1 --- a/drivers/net/phy/mdio_bus.c
2 +++ b/drivers/net/phy/mdio_bus.c
5 #include <asm/uaccess.h>
7 +struct mdio_board_entry {
8 + struct list_head list;
9 + struct mdio_board_info board_info;
12 +static LIST_HEAD(mdio_board_list);
13 +static DEFINE_MUTEX(mdio_board_lock);
16 + * mdio_register_board_info - register PHY devices for a given board
17 + * @info: array of chip descriptors
18 + * @n: how many descriptors are provided
19 + * Context: can sleep
21 + * The board info passed can safely be __initdata ... but be careful of
22 + * any embedded pointers (platform_data, etc), they're copied as-is.
25 +mdiobus_register_board_info(struct mdio_board_info const *info, unsigned n)
27 + struct mdio_board_entry *be;
30 + be = kzalloc(n * sizeof(*be), GFP_KERNEL);
34 + for (i = 0; i < n; i++, be++, info++) {
35 + memcpy(&be->board_info, info, sizeof(*info));
36 + mutex_lock(&mdio_board_lock);
37 + list_add_tail(&be->list, &mdio_board_list);
38 + mutex_unlock(&mdio_board_lock);
46 * mdiobus_alloc_size - allocate a mii_bus structure
47 * @size: extra amount of memory to allocate for private storage.
48 @@ -192,15 +230,31 @@ void mdiobus_free(struct mii_bus *bus)
50 EXPORT_SYMBOL(mdiobus_free);
52 +static void mdiobus_setup_phydev_from_boardinfo(struct mii_bus *bus,
53 + struct phy_device *phydev,
54 + struct mdio_board_info *bi)
56 + if (strcmp(bus->id, bi->bus_id) ||
57 + bi->phy_addr != phydev->addr)
60 + phydev->dev.platform_data = (void *) bi->platform_data;
63 struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
65 struct phy_device *phydev;
66 + struct mdio_board_entry *be;
69 phydev = get_phy_device(bus, addr);
70 if (IS_ERR(phydev) || phydev == NULL)
73 + list_for_each_entry(be, &mdio_board_list, list)
74 + mdiobus_setup_phydev_from_boardinfo(bus, phydev,
77 err = phy_device_register(phydev);
79 phy_device_free(phydev);
80 --- a/include/linux/phy.h
81 +++ b/include/linux/phy.h
82 @@ -399,8 +399,8 @@ struct phy_driver {
83 /* Determines the negotiated speed and duplex */
84 int (*read_status)(struct phy_device *phydev);
87 - * Update the value in phydev->link to reflect the
89 + * Update the value in phydev->link to reflect the
92 int (*update_link)(struct phy_device *phydev);
93 @@ -543,4 +543,22 @@ int __init mdio_bus_init(void);
94 void mdio_bus_exit(void);
96 extern struct bus_type mdio_bus_type;
98 +struct mdio_board_info {
102 + const void *platform_data;
105 +#ifdef CONFIG_PHYLIB
106 +int mdiobus_register_board_info(struct mdio_board_info const *info, unsigned n);
109 +mdiobus_register_board_info(struct mdio_board_info const *info, unsigned n)