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: Mario J. Rugiero <mrugiero@gmail.com> Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
This commit is contained in:
parent
5771a8c088
commit
e8e3edb95c
|
@ -1809,37 +1809,22 @@ static int dbg_protection_show(struct seq_file *s, void *p)
|
|||
}
|
||||
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;
|
||||
struct dentry *root = floor->dbg.dfs_dir;
|
||||
struct docg3 *docg3 = floor->priv;
|
||||
|
||||
root = debugfs_create_dir("docg3", NULL);
|
||||
if (!root)
|
||||
return -ENOMEM;
|
||||
if (IS_ERR_OR_NULL(root))
|
||||
return;
|
||||
|
||||
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);
|
||||
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)
|
|||
0);
|
||||
if (ret)
|
||||
goto err_probe;
|
||||
|
||||
doc_dbg_register(cascade->floors[floor]);
|
||||
}
|
||||
|
||||
ret = doc_register_sysfs(pdev, cascade);
|
||||
|
@ -2121,7 +2108,6 @@ static int __init docg3_probe(struct platform_device *pdev)
|
|||
goto err_probe;
|
||||
|
||||
platform_set_drvdata(pdev, cascade);
|
||||
doc_dbg_register(cascade->floors[0]->priv);
|
||||
return 0;
|
||||
|
||||
notfound:
|
||||
|
@ -2148,7 +2134,6 @@ static int docg3_release(struct platform_device *pdev)
|
|||
int floor;
|
||||
|
||||
doc_unregister_sysfs(pdev, cascade);
|
||||
doc_dbg_unregister(docg3);
|
||||
for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
|
||||
if (cascade->floors[floor])
|
||||
doc_release_device(cascade->floors[floor]);
|
||||
|
|
|
@ -299,7 +299,6 @@ struct docg3_cascade {
|
|||
* @oob_autoecc: if 1, use only bytes 0-7, 15, and fill the others with HW ECC
|
||||
* if 0, use all the 16 bytes.
|
||||
* @oob_write_buf: prepared OOB for next page_write
|
||||
* @debugfs_root: debugfs root node
|
||||
*/
|
||||
struct docg3 {
|
||||
struct device *dev;
|
||||
|
@ -312,7 +311,6 @@ struct docg3 {
|
|||
loff_t oob_write_ofs;
|
||||
int oob_autoecc;
|
||||
u8 oob_write_buf[DOC_LAYOUT_OOB_SIZE];
|
||||
struct dentry *debugfs_root;
|
||||
};
|
||||
|
||||
#define doc_err(fmt, arg...) dev_err(docg3->dev, (fmt), ## arg)
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
@ -477,6 +478,8 @@ int mtd_pairing_groups(struct mtd_info *mtd)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(mtd_pairing_groups);
|
||||
|
||||
static struct dentry *dfs_dir_mtd;
|
||||
|
||||
/**
|
||||
* add_mtd_device - register an MTD device
|
||||
* @mtd: pointer to new MTD device info structure
|
||||
|
@ -552,6 +555,14 @@ int add_mtd_device(struct mtd_info *mtd)
|
|||
if (error)
|
||||
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,
|
||||
"mtd%dro", i);
|
||||
|
||||
|
@ -594,6 +605,8 @@ int del_mtd_device(struct mtd_info *mtd)
|
|||
|
||||
mutex_lock(&mtd_table_mutex);
|
||||
|
||||
debugfs_remove_recursive(mtd->dbg.dfs_dir);
|
||||
|
||||
if (idr_find(&mtd_idr, mtd->index) != mtd) {
|
||||
ret = -ENODEV;
|
||||
goto out_error;
|
||||
|
@ -1811,6 +1824,8 @@ static int __init init_mtd(void)
|
|||
if (ret)
|
||||
goto out_procfs;
|
||||
|
||||
dfs_dir_mtd = debugfs_create_dir("mtd", NULL);
|
||||
|
||||
return 0;
|
||||
|
||||
out_procfs:
|
||||
|
@ -1826,6 +1841,7 @@ static int __init init_mtd(void)
|
|||
|
||||
static void __exit cleanup_mtd(void)
|
||||
{
|
||||
debugfs_remove_recursive(dfs_dir_mtd);
|
||||
cleanup_mtdchar();
|
||||
if (proc_mtd)
|
||||
remove_proc_entry("mtd", NULL);
|
||||
|
|
|
@ -138,8 +138,6 @@ struct mtdswap_dev {
|
|||
|
||||
char *page_buf;
|
||||
char *oob_buf;
|
||||
|
||||
struct dentry *debugfs_root;
|
||||
};
|
||||
|
||||
struct mtdswap_oobdata {
|
||||
|
@ -1318,26 +1316,19 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)
|
|||
struct gendisk *gd = d->mbd_dev->disk;
|
||||
struct device *dev = disk_to_dev(gd);
|
||||
|
||||
struct dentry *root;
|
||||
struct dentry *root = d->mtd->dbg.dfs_dir;
|
||||
struct dentry *dent;
|
||||
|
||||
root = debugfs_create_dir(gd->disk_name, NULL);
|
||||
if (IS_ERR(root))
|
||||
if (!IS_ENABLED(CONFIG_DEBUG_FS))
|
||||
return 0;
|
||||
|
||||
if (!root) {
|
||||
dev_err(dev, "failed to initialize debugfs\n");
|
||||
if (IS_ERR_OR_NULL(root))
|
||||
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);
|
||||
if (!dent) {
|
||||
dev_err(d->dev, "debugfs_create_file failed\n");
|
||||
debugfs_remove_recursive(root);
|
||||
d->debugfs_root = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1540,7 +1531,6 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev)
|
|||
{
|
||||
struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
|
||||
|
||||
debugfs_remove_recursive(d->debugfs_root);
|
||||
del_mtd_blktrans_dev(dev);
|
||||
mtdswap_cleanup(d);
|
||||
kfree(d);
|
||||
|
|
|
@ -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 */
|
||||
#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.
|
||||
*/
|
||||
|
@ -370,8 +365,6 @@ struct nandsim {
|
|||
void *file_buf;
|
||||
struct page *held_pages[NS_MAX_HELD_PAGES];
|
||||
int held_cnt;
|
||||
|
||||
struct nandsim_debug_info dbg;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -524,39 +517,23 @@ static const struct file_operations dfs_fops = {
|
|||
*/
|
||||
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;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_DEBUG_FS))
|
||||
return 0;
|
||||
|
||||
dent = debugfs_create_dir("nandsim", NULL);
|
||||
if (!dent) {
|
||||
NS_ERR("cannot create \"nandsim\" debugfs directory\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
dbg->dfs_root = dent;
|
||||
if (IS_ERR_OR_NULL(root))
|
||||
return -1;
|
||||
|
||||
dent = debugfs_create_file("wear_report", S_IRUSR,
|
||||
dbg->dfs_root, dev, &dfs_fops);
|
||||
if (!dent)
|
||||
goto out_remove;
|
||||
dbg->dfs_wear_report = dent;
|
||||
dent = debugfs_create_file("nandsim_wear_report", S_IRUSR,
|
||||
root, dev, &dfs_fops);
|
||||
if (IS_ERR_OR_NULL(dent)) {
|
||||
NS_ERR("cannot create \"nandsim_wear_report\" debugfs entry\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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)
|
|||
if ((retval = setup_wear_reporting(nsmtd)) != 0)
|
||||
goto err_exit;
|
||||
|
||||
if ((retval = nandsim_debugfs_create(nand)) != 0)
|
||||
goto err_exit;
|
||||
|
||||
if ((retval = init_nandsim(nsmtd)) != 0)
|
||||
goto err_exit;
|
||||
|
||||
|
@ -2370,6 +2344,9 @@ static int __init ns_init_module(void)
|
|||
if (retval != 0)
|
||||
goto err_exit;
|
||||
|
||||
if ((retval = nandsim_debugfs_create(nand)) != 0)
|
||||
goto err_exit;
|
||||
|
||||
return 0;
|
||||
|
||||
err_exit:
|
||||
|
@ -2395,7 +2372,6 @@ static void __exit ns_cleanup_module(void)
|
|||
struct nandsim *ns = nand_get_controller_data(chip);
|
||||
int i;
|
||||
|
||||
nandsim_debugfs_remove(ns);
|
||||
free_nandsim(ns); /* Free nandsim private resources */
|
||||
nand_release(nsmtd); /* Unregister driver */
|
||||
for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i)
|
||||
|
|
|
@ -206,6 +206,15 @@ struct mtd_pairing_scheme {
|
|||
|
||||
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 {
|
||||
u_char type;
|
||||
uint32_t flags;
|
||||
|
@ -346,6 +355,7 @@ struct mtd_info {
|
|||
struct module *owner;
|
||||
struct device dev;
|
||||
int usecount;
|
||||
struct mtd_debug_info dbg;
|
||||
};
|
||||
|
||||
int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
|
|
Loading…
Reference in New Issue