diff --git a/target/linux/generic/patches-3.10/951-add-phy-debugfs-regdump.patch b/target/linux/generic/patches-3.10/951-add-phy-debugfs-regdump.patch new file mode 100644 index 0000000..6fe8412 --- /dev/null +++ b/target/linux/generic/patches-3.10/951-add-phy-debugfs-regdump.patch @@ -0,0 +1,160 @@ +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) +