Commit e8e3edb9 authored by Mario Rugiero's avatar Mario Rugiero Committed by Brian Norris

mtd: create per-device and module-scope debugfs entries

Several MTD devices are using debugfs entries created in the root.
This commit provides the means for a standardized subtree, creating
one "mtd" entry at root, and one entry per device inside it, named
after the device.
The tree is registered in add_mtd_device, and released in
del_mtd_device.
Devices docg3, mtdswap and nandsim were updated to use this subtree
instead of custom ones, and their entries were prefixed with the
drivers' names.
Signed-off-by: default avatarMario J. Rugiero <mrugiero@gmail.com>
Acked-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent 5771a8c0
...@@ -1809,37 +1809,22 @@ static int dbg_protection_show(struct seq_file *s, void *p) ...@@ -1809,37 +1809,22 @@ static int dbg_protection_show(struct seq_file *s, void *p)
} }
DEBUGFS_RO_ATTR(protection, dbg_protection_show); DEBUGFS_RO_ATTR(protection, dbg_protection_show);
static int __init doc_dbg_register(struct docg3 *docg3) static void __init doc_dbg_register(struct mtd_info *floor)
{
struct dentry *root, *entry;
root = debugfs_create_dir("docg3", NULL);
if (!root)
return -ENOMEM;
entry = debugfs_create_file("flashcontrol", S_IRUSR, root, docg3,
&flashcontrol_fops);
if (entry)
entry = debugfs_create_file("asic_mode", S_IRUSR, root,
docg3, &asic_mode_fops);
if (entry)
entry = debugfs_create_file("device_id", S_IRUSR, root,
docg3, &device_id_fops);
if (entry)
entry = debugfs_create_file("protection", S_IRUSR, root,
docg3, &protection_fops);
if (entry) {
docg3->debugfs_root = root;
return 0;
} else {
debugfs_remove_recursive(root);
return -ENOMEM;
}
}
static void doc_dbg_unregister(struct docg3 *docg3)
{ {
debugfs_remove_recursive(docg3->debugfs_root); struct dentry *root = floor->dbg.dfs_dir;
struct docg3 *docg3 = floor->priv;
if (IS_ERR_OR_NULL(root))
return;
debugfs_create_file("docg3_flashcontrol", S_IRUSR, root, docg3,
&flashcontrol_fops);
debugfs_create_file("docg3_asic_mode", S_IRUSR, root, docg3,
&asic_mode_fops);
debugfs_create_file("docg3_device_id", S_IRUSR, root, docg3,
&device_id_fops);
debugfs_create_file("docg3_protection", S_IRUSR, root, docg3,
&protection_fops);
} }
/** /**
...@@ -2114,6 +2099,8 @@ static int __init docg3_probe(struct platform_device *pdev) ...@@ -2114,6 +2099,8 @@ static int __init docg3_probe(struct platform_device *pdev)
0); 0);
if (ret) if (ret)
goto err_probe; goto err_probe;
doc_dbg_register(cascade->floors[floor]);
} }
ret = doc_register_sysfs(pdev, cascade); ret = doc_register_sysfs(pdev, cascade);
...@@ -2121,7 +2108,6 @@ static int __init docg3_probe(struct platform_device *pdev) ...@@ -2121,7 +2108,6 @@ static int __init docg3_probe(struct platform_device *pdev)
goto err_probe; goto err_probe;
platform_set_drvdata(pdev, cascade); platform_set_drvdata(pdev, cascade);
doc_dbg_register(cascade->floors[0]->priv);
return 0; return 0;
notfound: notfound:
...@@ -2148,7 +2134,6 @@ static int docg3_release(struct platform_device *pdev) ...@@ -2148,7 +2134,6 @@ static int docg3_release(struct platform_device *pdev)
int floor; int floor;
doc_unregister_sysfs(pdev, cascade); doc_unregister_sysfs(pdev, cascade);
doc_dbg_unregister(docg3);
for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
if (cascade->floors[floor]) if (cascade->floors[floor])
doc_release_device(cascade->floors[floor]); doc_release_device(cascade->floors[floor]);
......
...@@ -299,7 +299,6 @@ struct docg3_cascade { ...@@ -299,7 +299,6 @@ struct docg3_cascade {
* @oob_autoecc: if 1, use only bytes 0-7, 15, and fill the others with HW ECC * @oob_autoecc: if 1, use only bytes 0-7, 15, and fill the others with HW ECC
* if 0, use all the 16 bytes. * if 0, use all the 16 bytes.
* @oob_write_buf: prepared OOB for next page_write * @oob_write_buf: prepared OOB for next page_write
* @debugfs_root: debugfs root node
*/ */
struct docg3 { struct docg3 {
struct device *dev; struct device *dev;
...@@ -312,7 +311,6 @@ struct docg3 { ...@@ -312,7 +311,6 @@ struct docg3 {
loff_t oob_write_ofs; loff_t oob_write_ofs;
int oob_autoecc; int oob_autoecc;
u8 oob_write_buf[DOC_LAYOUT_OOB_SIZE]; u8 oob_write_buf[DOC_LAYOUT_OOB_SIZE];
struct dentry *debugfs_root;
}; };
#define doc_err(fmt, arg...) dev_err(docg3->dev, (fmt), ## arg) #define doc_err(fmt, arg...) dev_err(docg3->dev, (fmt), ## arg)
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/debugfs.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
...@@ -477,6 +478,8 @@ int mtd_pairing_groups(struct mtd_info *mtd) ...@@ -477,6 +478,8 @@ int mtd_pairing_groups(struct mtd_info *mtd)
} }
EXPORT_SYMBOL_GPL(mtd_pairing_groups); EXPORT_SYMBOL_GPL(mtd_pairing_groups);
static struct dentry *dfs_dir_mtd;
/** /**
* add_mtd_device - register an MTD device * add_mtd_device - register an MTD device
* @mtd: pointer to new MTD device info structure * @mtd: pointer to new MTD device info structure
...@@ -552,6 +555,14 @@ int add_mtd_device(struct mtd_info *mtd) ...@@ -552,6 +555,14 @@ int add_mtd_device(struct mtd_info *mtd)
if (error) if (error)
goto fail_added; goto fail_added;
if (!IS_ERR_OR_NULL(dfs_dir_mtd)) {
mtd->dbg.dfs_dir = debugfs_create_dir(dev_name(&mtd->dev), dfs_dir_mtd);
if (IS_ERR_OR_NULL(mtd->dbg.dfs_dir)) {
pr_debug("mtd device %s won't show data in debugfs\n",
dev_name(&mtd->dev));
}
}
device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL, device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL,
"mtd%dro", i); "mtd%dro", i);
...@@ -594,6 +605,8 @@ int del_mtd_device(struct mtd_info *mtd) ...@@ -594,6 +605,8 @@ int del_mtd_device(struct mtd_info *mtd)
mutex_lock(&mtd_table_mutex); mutex_lock(&mtd_table_mutex);
debugfs_remove_recursive(mtd->dbg.dfs_dir);
if (idr_find(&mtd_idr, mtd->index) != mtd) { if (idr_find(&mtd_idr, mtd->index) != mtd) {
ret = -ENODEV; ret = -ENODEV;
goto out_error; goto out_error;
...@@ -1811,6 +1824,8 @@ static int __init init_mtd(void) ...@@ -1811,6 +1824,8 @@ static int __init init_mtd(void)
if (ret) if (ret)
goto out_procfs; goto out_procfs;
dfs_dir_mtd = debugfs_create_dir("mtd", NULL);
return 0; return 0;
out_procfs: out_procfs:
...@@ -1826,6 +1841,7 @@ static int __init init_mtd(void) ...@@ -1826,6 +1841,7 @@ static int __init init_mtd(void)
static void __exit cleanup_mtd(void) static void __exit cleanup_mtd(void)
{ {
debugfs_remove_recursive(dfs_dir_mtd);
cleanup_mtdchar(); cleanup_mtdchar();
if (proc_mtd) if (proc_mtd)
remove_proc_entry("mtd", NULL); remove_proc_entry("mtd", NULL);
......
...@@ -138,8 +138,6 @@ struct mtdswap_dev { ...@@ -138,8 +138,6 @@ struct mtdswap_dev {
char *page_buf; char *page_buf;
char *oob_buf; char *oob_buf;
struct dentry *debugfs_root;
}; };
struct mtdswap_oobdata { struct mtdswap_oobdata {
...@@ -1318,26 +1316,19 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d) ...@@ -1318,26 +1316,19 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)
struct gendisk *gd = d->mbd_dev->disk; struct gendisk *gd = d->mbd_dev->disk;
struct device *dev = disk_to_dev(gd); struct device *dev = disk_to_dev(gd);
struct dentry *root; struct dentry *root = d->mtd->dbg.dfs_dir;
struct dentry *dent; struct dentry *dent;
root = debugfs_create_dir(gd->disk_name, NULL); if (!IS_ENABLED(CONFIG_DEBUG_FS))
if (IS_ERR(root))
return 0; return 0;
if (!root) { if (IS_ERR_OR_NULL(root))
dev_err(dev, "failed to initialize debugfs\n");
return -1; return -1;
}
d->debugfs_root = root;
dent = debugfs_create_file("stats", S_IRUSR, root, d, dent = debugfs_create_file("mtdswap_stats", S_IRUSR, root, d,
&mtdswap_fops); &mtdswap_fops);
if (!dent) { if (!dent) {
dev_err(d->dev, "debugfs_create_file failed\n"); dev_err(d->dev, "debugfs_create_file failed\n");
debugfs_remove_recursive(root);
d->debugfs_root = NULL;
return -1; return -1;
} }
...@@ -1540,7 +1531,6 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev) ...@@ -1540,7 +1531,6 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev)
{ {
struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev); struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
debugfs_remove_recursive(d->debugfs_root);
del_mtd_blktrans_dev(dev); del_mtd_blktrans_dev(dev);
mtdswap_cleanup(d); mtdswap_cleanup(d);
kfree(d); kfree(d);
......
...@@ -287,11 +287,6 @@ MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should " ...@@ -287,11 +287,6 @@ MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should "
/* Maximum page cache pages needed to read or write a NAND page to the cache_file */ /* Maximum page cache pages needed to read or write a NAND page to the cache_file */
#define NS_MAX_HELD_PAGES 16 #define NS_MAX_HELD_PAGES 16
struct nandsim_debug_info {
struct dentry *dfs_root;
struct dentry *dfs_wear_report;
};
/* /*
* A union to represent flash memory contents and flash buffer. * A union to represent flash memory contents and flash buffer.
*/ */
...@@ -370,8 +365,6 @@ struct nandsim { ...@@ -370,8 +365,6 @@ struct nandsim {
void *file_buf; void *file_buf;
struct page *held_pages[NS_MAX_HELD_PAGES]; struct page *held_pages[NS_MAX_HELD_PAGES];
int held_cnt; int held_cnt;
struct nandsim_debug_info dbg;
}; };
/* /*
...@@ -524,39 +517,23 @@ static const struct file_operations dfs_fops = { ...@@ -524,39 +517,23 @@ static const struct file_operations dfs_fops = {
*/ */
static int nandsim_debugfs_create(struct nandsim *dev) static int nandsim_debugfs_create(struct nandsim *dev)
{ {
struct nandsim_debug_info *dbg = &dev->dbg; struct dentry *root = nsmtd->dbg.dfs_dir;
struct dentry *dent; struct dentry *dent;
if (!IS_ENABLED(CONFIG_DEBUG_FS)) if (!IS_ENABLED(CONFIG_DEBUG_FS))
return 0; return 0;
dent = debugfs_create_dir("nandsim", NULL); if (IS_ERR_OR_NULL(root))
if (!dent) { return -1;
NS_ERR("cannot create \"nandsim\" debugfs directory\n");
return -ENODEV;
}
dbg->dfs_root = dent;
dent = debugfs_create_file("wear_report", S_IRUSR, dent = debugfs_create_file("nandsim_wear_report", S_IRUSR,
dbg->dfs_root, dev, &dfs_fops); root, dev, &dfs_fops);
if (!dent) if (IS_ERR_OR_NULL(dent)) {
goto out_remove; NS_ERR("cannot create \"nandsim_wear_report\" debugfs entry\n");
dbg->dfs_wear_report = dent; return -1;
}
return 0; return 0;
out_remove:
debugfs_remove_recursive(dbg->dfs_root);
return -ENODEV;
}
/**
* nandsim_debugfs_remove - destroy all debugfs files
*/
static void nandsim_debugfs_remove(struct nandsim *ns)
{
if (IS_ENABLED(CONFIG_DEBUG_FS))
debugfs_remove_recursive(ns->dbg.dfs_root);
} }
/* /*
...@@ -2352,9 +2329,6 @@ static int __init ns_init_module(void) ...@@ -2352,9 +2329,6 @@ static int __init ns_init_module(void)
if ((retval = setup_wear_reporting(nsmtd)) != 0) if ((retval = setup_wear_reporting(nsmtd)) != 0)
goto err_exit; goto err_exit;
if ((retval = nandsim_debugfs_create(nand)) != 0)
goto err_exit;
if ((retval = init_nandsim(nsmtd)) != 0) if ((retval = init_nandsim(nsmtd)) != 0)
goto err_exit; goto err_exit;
...@@ -2370,6 +2344,9 @@ static int __init ns_init_module(void) ...@@ -2370,6 +2344,9 @@ static int __init ns_init_module(void)
if (retval != 0) if (retval != 0)
goto err_exit; goto err_exit;
if ((retval = nandsim_debugfs_create(nand)) != 0)
goto err_exit;
return 0; return 0;
err_exit: err_exit:
...@@ -2395,7 +2372,6 @@ static void __exit ns_cleanup_module(void) ...@@ -2395,7 +2372,6 @@ static void __exit ns_cleanup_module(void)
struct nandsim *ns = nand_get_controller_data(chip); struct nandsim *ns = nand_get_controller_data(chip);
int i; int i;
nandsim_debugfs_remove(ns);
free_nandsim(ns); /* Free nandsim private resources */ free_nandsim(ns); /* Free nandsim private resources */
nand_release(nsmtd); /* Unregister driver */ nand_release(nsmtd); /* Unregister driver */
for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i)
......
...@@ -206,6 +206,15 @@ struct mtd_pairing_scheme { ...@@ -206,6 +206,15 @@ struct mtd_pairing_scheme {
struct module; /* only needed for owner field in mtd_info */ struct module; /* only needed for owner field in mtd_info */
/**
* struct mtd_debug_info - debugging information for an MTD device.
*
* @dfs_dir: direntry object of the MTD device debugfs directory
*/
struct mtd_debug_info {
struct dentry *dfs_dir;
};
struct mtd_info { struct mtd_info {
u_char type; u_char type;
uint32_t flags; uint32_t flags;
...@@ -346,6 +355,7 @@ struct mtd_info { ...@@ -346,6 +355,7 @@ struct mtd_info {
struct module *owner; struct module *owner;
struct device dev; struct device dev;
int usecount; int usecount;
struct mtd_debug_info dbg;
}; };
int mtd_ooblayout_ecc(struct mtd_info *mtd, int section, int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment