Index: linux-3.10.49/drivers/net/phy/mdio_bus.c =================================================================== --- linux-3.10.49.orig/drivers/net/phy/mdio_bus.c +++ linux-3.10.49/drivers/net/phy/mdio_bus.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -127,6 +128,82 @@ struct mii_bus *of_mdio_find_bus(struct EXPORT_SYMBOL(of_mdio_find_bus); #endif +struct dentry *mdiobus_debug_root; +EXPORT_SYMBOL_GPL(mdiobus_debug_root); + +static int mdiobus_debugfs_init(void) +{ + mdiobus_debug_root = debugfs_create_dir("mdio_bus", NULL); + if (!mdiobus_debug_root) + return -ENOENT; + return 0; +} + +static void mdiobus_debugfs_cleanup(void) +{ + debugfs_remove(mdiobus_debug_root); +} + + +static void mdiobus_debugfs_del(struct mii_bus *bus) +{ + debugfs_remove_recursive(bus->debugfs_dir); + bus->debugfs_dir = NULL; +} + +static int mdiobus_debugfs_add(struct mii_bus *bus) +{ + bus->debugfs_dir = debugfs_create_dir(bus->name, mdiobus_debug_root); + if (!bus->debugfs_dir) + return -ENODEV; + + return 0; +} + +static int phy_dump_show(struct seq_file *seq, void *v) +{ + int ret = 0, i; + u16 *buffer = NULL; + struct phy_device *phy = seq->private; + + buffer = kzalloc(32 * sizeof(u16), GFP_KERNEL); + if (!buffer) { + return -ENOMEM; + } + + for (i=0; i<32; i++) { + buffer[i] = mdiobus_read(phy->bus, phy->addr, i) & 0xffff; + } + ret = seq_write(seq, buffer, 32 * sizeof(*buffer)); + + kfree(buffer); + return ret; +} + +static int phy_dump_open(struct inode *inode, struct file *file) +{ + return single_open(file, phy_dump_show, inode->i_private); +} + +static const struct file_operations phy_dump_debugfs_fops = { + .owner = THIS_MODULE, + .open = phy_dump_open, + .release = single_release, + .read = seq_read, + .llseek = seq_lseek, +}; + + +void mdiobus_debugfs_add_phy(struct mii_bus *bus, struct phy_device *phydev) +{ + struct dentry *parent = debugfs_create_dir(dev_name(&phydev->dev), bus->debugfs_dir); + if (!parent) + return; + + debugfs_create_file("regdump", S_IRUSR, parent, + (void *)phydev, &phy_dump_debugfs_fops); +} + /** * mdiobus_register - bring up all the PHYs on a given bus and attach them to bus * @bus: target mii_bus @@ -159,6 +236,8 @@ int mdiobus_register(struct mii_bus *bus return -EINVAL; } + mdiobus_debugfs_add(bus); + mutex_init(&bus->mdio_lock); if (bus->reset) @@ -173,6 +252,8 @@ int mdiobus_register(struct mii_bus *bus err = PTR_ERR(phydev); goto error; } + if (phydev) + mdiobus_debugfs_add_phy(bus, phydev); } } @@ -185,6 +266,7 @@ error: if (bus->phy_map[i]) device_unregister(&bus->phy_map[i]->dev); } + mdiobus_debugfs_del(bus); device_del(&bus->dev); return err; } @@ -476,11 +558,14 @@ int __init mdio_bus_init(void) { int ret; + mdiobus_debugfs_init(); ret = class_register(&mdio_bus_class); if (!ret) { ret = bus_register(&mdio_bus_type); - if (ret) + if (ret) { class_unregister(&mdio_bus_class); + mdiobus_debugfs_cleanup(); + } } return ret; @@ -488,6 +573,7 @@ int __init mdio_bus_init(void) void mdio_bus_exit(void) { + mdiobus_debugfs_cleanup(); class_unregister(&mdio_bus_class); bus_unregister(&mdio_bus_type); } Index: linux-3.10.49/include/linux/phy.h =================================================================== --- linux-3.10.49.orig/include/linux/phy.h +++ linux-3.10.49/include/linux/phy.h @@ -128,6 +128,10 @@ struct mii_bus { * interrupt at the index matching its address */ int *irq; +#ifdef CONFIG_DEBUG_FS + /* debugfs directory node */ + struct dentry *debugfs_dir; +#endif }; #define to_mii_bus(d) container_of(d, struct mii_bus, dev)