From de2fadf566cb9277bea22993ed95cc5177280251 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:08 +0100 Subject: [PATCH 001/102] zswap: ignore debugfs_create_dir() return value When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Seth Jennings Cc: linux-mm@kvack.org Acked-by: Dan Streetman Signed-off-by: Greg Kroah-Hartman --- mm/zswap.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/mm/zswap.c b/mm/zswap.c index 2412042f5550..0e22744a76cb 100644 --- a/mm/zswap.c +++ b/mm/zswap.c @@ -1253,8 +1253,6 @@ static int __init zswap_debugfs_init(void) return -ENODEV; zswap_debugfs_root = debugfs_create_dir("zswap", NULL); - if (!zswap_debugfs_root) - return -ENOMEM; debugfs_create_u64("pool_limit_hit", 0444, zswap_debugfs_root, &zswap_pool_limit_hit); From 6a54cd872f50ef3b090fdd53d1b67f5b43e97315 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:40 +0100 Subject: [PATCH 002/102] trace: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Steven Rostedt Cc: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1c80521fd436..a95c5cd28135 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8604,10 +8604,6 @@ struct dentry *tracing_init_dentry(void) */ tr->dir = debugfs_create_automount("tracing", NULL, trace_automount, NULL); - if (!tr->dir) { - pr_warn_once("Could not create debugfs directory 'tracing'\n"); - return ERR_PTR(-ENOMEM); - } return NULL; } From 3e6f176f304ee8effec698ebaff6b7baecb5e1e6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:41 +0100 Subject: [PATCH 003/102] blktrace: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Jens Axboe Cc: Steven Rostedt Cc: Ingo Molnar Cc: linux-block@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- kernel/trace/blktrace.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index e1c6d79fb4cc..2d6e93ab0478 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -512,8 +512,6 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, dir = debugfs_lookup(buts->name, blk_debugfs_root); if (!dir) bt->dir = dir = debugfs_create_dir(buts->name, blk_debugfs_root); - if (!dir) - goto err; bt->dev = dev; atomic_set(&bt->dropped, 0); @@ -522,12 +520,8 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, ret = -EIO; bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt, &blk_dropped_fops); - if (!bt->dropped_file) - goto err; bt->msg_file = debugfs_create_file("msg", 0222, dir, bt, &blk_msg_fops); - if (!bt->msg_file) - goto err; bt->rchan = relay_open("trace", dir, buts->buf_size, buts->buf_nr, &blk_relay_callbacks, bt); From 4268509a36a79a6e449a4937d88bb4d21f8b2078 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:09 +0100 Subject: [PATCH 004/102] zsmalloc: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Minchan Kim Cc: Nitin Gupta Cc: Sergey Senozhatsky Cc: linux-mm@kvack.org Signed-off-by: Greg Kroah-Hartman --- mm/zsmalloc.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 0787d33b80d8..1347d7922ea2 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -575,8 +575,6 @@ static void __init zs_stat_init(void) } zs_stat_root = debugfs_create_dir("zsmalloc", NULL); - if (!zs_stat_root) - pr_warn("debugfs 'zsmalloc' stat dir creation failed\n"); } static void __exit zs_stat_exit(void) @@ -654,22 +652,10 @@ static void zs_pool_stat_create(struct zs_pool *pool, const char *name) return; } - entry = debugfs_create_dir(name, zs_stat_root); - if (!entry) { - pr_warn("debugfs dir <%s> creation failed\n", name); - return; - } - pool->stat_dentry = entry; + pool->stat_dentry = debugfs_create_dir(name, zs_stat_root); - entry = debugfs_create_file("classes", S_IFREG | 0444, - pool->stat_dentry, pool, - &zs_stats_size_fops); - if (!entry) { - pr_warn("%s: debugfs file entry <%s> creation failed\n", - name, "classes"); - debugfs_remove_recursive(pool->stat_dentry); - pool->stat_dentry = NULL; - } + debugfs_create_file("classes", S_IFREG | 0444, pool->stat_dentry, pool, + &zs_stats_size_fops); } static void zs_pool_stat_destroy(struct zs_pool *pool) From 282401df902465186ff6ed5a7ba4894c589553f2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:12 +0100 Subject: [PATCH 005/102] mm: kmemleak: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Catalin Marinas Cc: linux-mm@kvack.org Signed-off-by: Greg Kroah-Hartman --- mm/kmemleak.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index e57bf810f798..9857446021af 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -2118,14 +2118,9 @@ void __init kmemleak_init(void) */ static int __init kmemleak_late_init(void) { - struct dentry *dentry; - kmemleak_initialized = 1; - dentry = debugfs_create_file("kmemleak", 0644, NULL, NULL, - &kmemleak_fops); - if (!dentry) - pr_warn("Failed to create the debugfs kmemleak file\n"); + debugfs_create_file("kmemleak", 0644, NULL, NULL, &kmemleak_fops); if (kmemleak_error) { /* From 2fcc6e202a9d45f1556365ee4f4de973e1c834ec Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:10 +0100 Subject: [PATCH 006/102] hwpoison-inject: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Naoya Horiguchi Cc: linux-mm@kvack.org Signed-off-by: Greg Kroah-Hartman --- mm/hwpoison-inject.c | 55 +++++++++++++------------------------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c index 1a7497d015b2..5b7430bd83a6 100644 --- a/mm/hwpoison-inject.c +++ b/mm/hwpoison-inject.c @@ -77,63 +77,40 @@ static void pfn_inject_exit(void) static int pfn_inject_init(void) { - struct dentry *dentry; - hwpoison_dir = debugfs_create_dir("hwpoison", NULL); - if (hwpoison_dir == NULL) - return -ENOMEM; /* * Note that the below poison/unpoison interfaces do not involve * hardware status change, hence do not require hardware support. * They are mainly for testing hwpoison in software level. */ - dentry = debugfs_create_file("corrupt-pfn", 0200, hwpoison_dir, - NULL, &hwpoison_fops); - if (!dentry) - goto fail; + debugfs_create_file("corrupt-pfn", 0200, hwpoison_dir, NULL, + &hwpoison_fops); - dentry = debugfs_create_file("unpoison-pfn", 0200, hwpoison_dir, - NULL, &unpoison_fops); - if (!dentry) - goto fail; + debugfs_create_file("unpoison-pfn", 0200, hwpoison_dir, NULL, + &unpoison_fops); - dentry = debugfs_create_u32("corrupt-filter-enable", 0600, - hwpoison_dir, &hwpoison_filter_enable); - if (!dentry) - goto fail; + debugfs_create_u32("corrupt-filter-enable", 0600, hwpoison_dir, + &hwpoison_filter_enable); - dentry = debugfs_create_u32("corrupt-filter-dev-major", 0600, - hwpoison_dir, &hwpoison_filter_dev_major); - if (!dentry) - goto fail; + debugfs_create_u32("corrupt-filter-dev-major", 0600, hwpoison_dir, + &hwpoison_filter_dev_major); - dentry = debugfs_create_u32("corrupt-filter-dev-minor", 0600, - hwpoison_dir, &hwpoison_filter_dev_minor); - if (!dentry) - goto fail; + debugfs_create_u32("corrupt-filter-dev-minor", 0600, hwpoison_dir, + &hwpoison_filter_dev_minor); - dentry = debugfs_create_u64("corrupt-filter-flags-mask", 0600, - hwpoison_dir, &hwpoison_filter_flags_mask); - if (!dentry) - goto fail; + debugfs_create_u64("corrupt-filter-flags-mask", 0600, hwpoison_dir, + &hwpoison_filter_flags_mask); - dentry = debugfs_create_u64("corrupt-filter-flags-value", 0600, - hwpoison_dir, &hwpoison_filter_flags_value); - if (!dentry) - goto fail; + debugfs_create_u64("corrupt-filter-flags-value", 0600, hwpoison_dir, + &hwpoison_filter_flags_value); #ifdef CONFIG_MEMCG - dentry = debugfs_create_u64("corrupt-filter-memcg", 0600, - hwpoison_dir, &hwpoison_filter_memcg); - if (!dentry) - goto fail; + debugfs_create_u64("corrupt-filter-memcg", 0600, hwpoison_dir, + &hwpoison_filter_memcg); #endif return 0; -fail: - pfn_inject_exit(); - return -ENOMEM; } module_init(pfn_inject_init); From 03eb2a08fccc49f93587666e4e1a14ce00df955a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 15:50:30 +0100 Subject: [PATCH 007/102] sh: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Yoshinori Sato Cc: Rich Felker Cc: Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/kdebugfs.c | 3 --- arch/sh/mm/asids-debugfs.c | 11 +++-------- arch/sh/mm/cache-debugfs.c | 20 ++++---------------- arch/sh/mm/pmb.c | 9 ++------- arch/sh/mm/tlb-debugfs.c | 20 ++++---------------- 5 files changed, 13 insertions(+), 50 deletions(-) diff --git a/arch/sh/kernel/kdebugfs.c b/arch/sh/kernel/kdebugfs.c index 95428e05d212..8b505e1556a5 100644 --- a/arch/sh/kernel/kdebugfs.c +++ b/arch/sh/kernel/kdebugfs.c @@ -9,9 +9,6 @@ EXPORT_SYMBOL(arch_debugfs_dir); static int __init arch_kdebugfs_init(void) { arch_debugfs_dir = debugfs_create_dir("sh", NULL); - if (!arch_debugfs_dir) - return -ENOMEM; - return 0; } arch_initcall(arch_kdebugfs_init); diff --git a/arch/sh/mm/asids-debugfs.c b/arch/sh/mm/asids-debugfs.c index e5539e0f8e3b..4c1ca197e9c5 100644 --- a/arch/sh/mm/asids-debugfs.c +++ b/arch/sh/mm/asids-debugfs.c @@ -63,13 +63,8 @@ static const struct file_operations asids_debugfs_fops = { static int __init asids_debugfs_init(void) { - struct dentry *asids_dentry; - - asids_dentry = debugfs_create_file("asids", S_IRUSR, arch_debugfs_dir, - NULL, &asids_debugfs_fops); - if (!asids_dentry) - return -ENOMEM; - - return PTR_ERR_OR_ZERO(asids_dentry); + debugfs_create_file("asids", S_IRUSR, arch_debugfs_dir, NULL, + &asids_debugfs_fops); + return 0; } device_initcall(asids_debugfs_init); diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c index 4eb9d43578b4..17d780794497 100644 --- a/arch/sh/mm/cache-debugfs.c +++ b/arch/sh/mm/cache-debugfs.c @@ -109,22 +109,10 @@ static const struct file_operations cache_debugfs_fops = { static int __init cache_debugfs_init(void) { - struct dentry *dcache_dentry, *icache_dentry; - - dcache_dentry = debugfs_create_file("dcache", S_IRUSR, arch_debugfs_dir, - (unsigned int *)CACHE_TYPE_DCACHE, - &cache_debugfs_fops); - if (!dcache_dentry) - return -ENOMEM; - - icache_dentry = debugfs_create_file("icache", S_IRUSR, arch_debugfs_dir, - (unsigned int *)CACHE_TYPE_ICACHE, - &cache_debugfs_fops); - if (!icache_dentry) { - debugfs_remove(dcache_dentry); - return -ENOMEM; - } - + debugfs_create_file("dcache", S_IRUSR, arch_debugfs_dir, + (void *)CACHE_TYPE_DCACHE, &cache_debugfs_fops); + debugfs_create_file("icache", S_IRUSR, arch_debugfs_dir, + (void *)CACHE_TYPE_ICACHE, &cache_debugfs_fops); return 0; } module_init(cache_debugfs_init); diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index a53a040d0054..b59bad86b31e 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -861,13 +861,8 @@ static const struct file_operations pmb_debugfs_fops = { static int __init pmb_debugfs_init(void) { - struct dentry *dentry; - - dentry = debugfs_create_file("pmb", S_IFREG | S_IRUGO, - arch_debugfs_dir, NULL, &pmb_debugfs_fops); - if (!dentry) - return -ENOMEM; - + debugfs_create_file("pmb", S_IFREG | S_IRUGO, arch_debugfs_dir, NULL, + &pmb_debugfs_fops); return 0; } subsys_initcall(pmb_debugfs_init); diff --git a/arch/sh/mm/tlb-debugfs.c b/arch/sh/mm/tlb-debugfs.c index dea637a09246..11c6148283f3 100644 --- a/arch/sh/mm/tlb-debugfs.c +++ b/arch/sh/mm/tlb-debugfs.c @@ -149,22 +149,10 @@ static const struct file_operations tlb_debugfs_fops = { static int __init tlb_debugfs_init(void) { - struct dentry *itlb, *utlb; - - itlb = debugfs_create_file("itlb", S_IRUSR, arch_debugfs_dir, - (unsigned int *)TLB_TYPE_ITLB, - &tlb_debugfs_fops); - if (unlikely(!itlb)) - return -ENOMEM; - - utlb = debugfs_create_file("utlb", S_IRUSR, arch_debugfs_dir, - (unsigned int *)TLB_TYPE_UTLB, - &tlb_debugfs_fops); - if (unlikely(!utlb)) { - debugfs_remove(itlb); - return -ENOMEM; - } - + debugfs_create_file("itlb", S_IRUSR, arch_debugfs_dir, + (void *)TLB_TYPE_ITLB, &tlb_debugfs_fops); + debugfs_create_file("utlb", S_IRUSR, arch_debugfs_dir, + (void *)TLB_TYPE_UTLB, &tlb_debugfs_fops); return 0; } module_init(tlb_debugfs_init); From 4aa3b1f67d3dbac6864095273bc3466d2099ad05 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:44 +0100 Subject: [PATCH 008/102] fail_function: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Kees Cook Cc: Josef Bacik Cc: Thomas Gleixner Cc: "Naveen N. Rao" Cc: zhong jiang Acked-by: Masami Hiramatsu Signed-off-by: Greg Kroah-Hartman --- kernel/fail_function.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/kernel/fail_function.c b/kernel/fail_function.c index feb80712b913..63b349168da7 100644 --- a/kernel/fail_function.c +++ b/kernel/fail_function.c @@ -152,20 +152,13 @@ static int fei_retval_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(fei_retval_ops, fei_retval_get, fei_retval_set, "%llx\n"); -static int fei_debugfs_add_attr(struct fei_attr *attr) +static void fei_debugfs_add_attr(struct fei_attr *attr) { struct dentry *dir; dir = debugfs_create_dir(attr->kp.symbol_name, fei_debugfs_dir); - if (!dir) - return -ENOMEM; - if (!debugfs_create_file("retval", 0600, dir, attr, &fei_retval_ops)) { - debugfs_remove_recursive(dir); - return -ENOMEM; - } - - return 0; + debugfs_create_file("retval", 0600, dir, attr, &fei_retval_ops); } static void fei_debugfs_remove_attr(struct fei_attr *attr) @@ -306,7 +299,7 @@ static ssize_t fei_write(struct file *file, const char __user *buffer, ret = register_kprobe(&attr->kp); if (!ret) - ret = fei_debugfs_add_attr(attr); + fei_debugfs_add_attr(attr); if (ret < 0) fei_attr_remove(attr); else { @@ -337,19 +330,13 @@ static int __init fei_debugfs_init(void) return PTR_ERR(dir); /* injectable attribute is just a symlink of error_inject/list */ - if (!debugfs_create_symlink("injectable", dir, - "../error_injection/list")) - goto error; + debugfs_create_symlink("injectable", dir, "../error_injection/list"); - if (!debugfs_create_file("inject", 0600, dir, NULL, &fei_ops)) - goto error; + debugfs_create_file("inject", 0600, dir, NULL, &fei_ops); fei_debugfs_dir = dir; return 0; -error: - debugfs_remove_recursive(dir); - return -ENOMEM; } late_initcall(fei_debugfs_init); From 8c0fd1fa64c6120f3f02d4e8d8949e7599530286 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:46 +0100 Subject: [PATCH 009/102] kprobes: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: "Naveen N. Rao" Cc: Anil S Keshavamurthy Cc: "David S. Miller" Acked-by: Masami Hiramatsu Signed-off-by: Greg Kroah-Hartman --- kernel/kprobes.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 445337c107e0..9f5433a52488 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -2570,33 +2570,20 @@ static const struct file_operations fops_kp = { static int __init debugfs_kprobe_init(void) { - struct dentry *dir, *file; + struct dentry *dir; unsigned int value = 1; dir = debugfs_create_dir("kprobes", NULL); - if (!dir) - return -ENOMEM; - file = debugfs_create_file("list", 0400, dir, NULL, - &debugfs_kprobes_operations); - if (!file) - goto error; + debugfs_create_file("list", 0400, dir, NULL, + &debugfs_kprobes_operations); - file = debugfs_create_file("enabled", 0600, dir, - &value, &fops_kp); - if (!file) - goto error; + debugfs_create_file("enabled", 0600, dir, &value, &fops_kp); - file = debugfs_create_file("blacklist", 0400, dir, NULL, - &debugfs_kprobe_blacklist_ops); - if (!file) - goto error; + debugfs_create_file("blacklist", 0400, dir, NULL, + &debugfs_kprobe_blacklist_ops); return 0; - -error: - debugfs_remove(dir); - return -ENOMEM; } late_initcall(debugfs_kprobe_init); From c4e41349a85c52456fea4903dde459302d54c67c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:11 +0100 Subject: [PATCH 010/102] mm: cleancache: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: linux-mm@kvack.org Acked-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- mm/cleancache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mm/cleancache.c b/mm/cleancache.c index 2bf12da9baa0..082fdda7aaa6 100644 --- a/mm/cleancache.c +++ b/mm/cleancache.c @@ -305,8 +305,7 @@ static int __init init_cleancache(void) { #ifdef CONFIG_DEBUG_FS struct dentry *root = debugfs_create_dir("cleancache", NULL); - if (root == NULL) - return -ENXIO; + debugfs_create_u64("succ_gets", 0444, root, &cleancache_succ_gets); debugfs_create_u64("failed_gets", 0444, root, &cleancache_failed_gets); debugfs_create_u64("puts", 0444, root, &cleancache_puts); From 2d146b924ec3c0873f06308d149684dc1105d9a3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:07 +0100 Subject: [PATCH 011/102] backing-dev: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. And as the return value does not matter at all, no need to save the dentry in struct backing_dev_info, so delete it. Cc: Andrew Morton Cc: Anders Roxell Cc: Arnd Bergmann Cc: Michal Hocko Cc: linux-mm@kvack.org Reviewed-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman --- include/linux/backing-dev-defs.h | 1 - mm/backing-dev.c | 24 +++++------------------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h index 07e02d6df5ad..6a1a8a314d85 100644 --- a/include/linux/backing-dev-defs.h +++ b/include/linux/backing-dev-defs.h @@ -203,7 +203,6 @@ struct backing_dev_info { #ifdef CONFIG_DEBUG_FS struct dentry *debug_dir; - struct dentry *debug_stats; #endif }; diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 909dae445ea7..e8e89158adec 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -103,39 +103,25 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v) } DEFINE_SHOW_ATTRIBUTE(bdi_debug_stats); -static int bdi_debug_register(struct backing_dev_info *bdi, const char *name) +static void bdi_debug_register(struct backing_dev_info *bdi, const char *name) { - if (!bdi_debug_root) - return -ENOMEM; - bdi->debug_dir = debugfs_create_dir(name, bdi_debug_root); - if (!bdi->debug_dir) - return -ENOMEM; - bdi->debug_stats = debugfs_create_file("stats", 0444, bdi->debug_dir, - bdi, &bdi_debug_stats_fops); - if (!bdi->debug_stats) { - debugfs_remove(bdi->debug_dir); - bdi->debug_dir = NULL; - return -ENOMEM; - } - - return 0; + debugfs_create_file("stats", 0444, bdi->debug_dir, bdi, + &bdi_debug_stats_fops); } static void bdi_debug_unregister(struct backing_dev_info *bdi) { - debugfs_remove(bdi->debug_stats); - debugfs_remove(bdi->debug_dir); + debugfs_remove_recursive(bdi->debug_dir); } #else static inline void bdi_debug_init(void) { } -static inline int bdi_debug_register(struct backing_dev_info *bdi, +static inline void bdi_debug_register(struct backing_dev_info *bdi, const char *name) { - return 0; } static inline void bdi_debug_unregister(struct backing_dev_info *bdi) { From ad09137631e6e5acfaf288f3ba3f4b3a9f855d16 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 15:35:42 +0100 Subject: [PATCH 012/102] x86: xen: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Boris Ostrovsky Cc: Stefano Stabellini Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: "H. Peter Anvin" Cc: Cc: Reviewed-by: Juergen Gross Signed-off-by: Greg Kroah-Hartman --- arch/x86/xen/debugfs.c | 7 +------ arch/x86/xen/p2m.c | 3 --- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/arch/x86/xen/debugfs.c b/arch/x86/xen/debugfs.c index 13da87918b4f..532410998684 100644 --- a/arch/x86/xen/debugfs.c +++ b/arch/x86/xen/debugfs.c @@ -9,13 +9,8 @@ static struct dentry *d_xen_debug; struct dentry * __init xen_init_debugfs(void) { - if (!d_xen_debug) { + if (!d_xen_debug) d_xen_debug = debugfs_create_dir("xen", NULL); - - if (!d_xen_debug) - pr_warning("Could not create 'xen' debugfs directory\n"); - } - return d_xen_debug; } diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 95ce9b5be411..0acba2c712ab 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -817,9 +817,6 @@ static int __init xen_p2m_debugfs(void) { struct dentry *d_xen = xen_init_debugfs(); - if (d_xen == NULL) - return -ENOMEM; - d_mmu_debug = debugfs_create_dir("mmu", d_xen); debugfs_create_file("p2m", 0600, d_mmu_debug, NULL, &p2m_dump_fops); From d5ddd5a51726f46d9f2a119c461ab28ca09b9e69 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 15:41:13 +0100 Subject: [PATCH 013/102] arm: omap1: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Paul Walmsley Cc: Aaro Koskinen Cc: Russell King Cc: Kevin Hilman Cc: linux-omap@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Acked-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap1/clock.c | 63 +++++++------------------------------ arch/arm/mach-omap1/pm.c | 7 ++--- 2 files changed, 14 insertions(+), 56 deletions(-) diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index c8c6fe88b2d6..3d7ab2bcf46c 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -990,84 +990,45 @@ static int debug_clock_show(struct seq_file *s, void *unused) DEFINE_SHOW_ATTRIBUTE(debug_clock); -static int clk_debugfs_register_one(struct clk *c) +static void clk_debugfs_register_one(struct clk *c) { - int err; struct dentry *d; struct clk *pa = c->parent; d = debugfs_create_dir(c->name, pa ? pa->dent : clk_debugfs_root); - if (!d) - return -ENOMEM; c->dent = d; - d = debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount); - if (!d) { - err = -ENOMEM; - goto err_out; - } - d = debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate); - if (!d) { - err = -ENOMEM; - goto err_out; - } - d = debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags); - if (!d) { - err = -ENOMEM; - goto err_out; - } - return 0; - -err_out: - debugfs_remove_recursive(c->dent); - return err; + debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount); + debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate); + debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags); } -static int clk_debugfs_register(struct clk *c) +static void clk_debugfs_register(struct clk *c) { int err; struct clk *pa = c->parent; - if (pa && !pa->dent) { - err = clk_debugfs_register(pa); - if (err) - return err; - } + if (pa && !pa->dent) + clk_debugfs_register(pa); - if (!c->dent) { - err = clk_debugfs_register_one(c); - if (err) - return err; - } - return 0; + if (!c->dent) + clk_debugfs_register_one(c); } static int __init clk_debugfs_init(void) { struct clk *c; struct dentry *d; - int err; d = debugfs_create_dir("clock", NULL); - if (!d) - return -ENOMEM; clk_debugfs_root = d; - list_for_each_entry(c, &clocks, node) { - err = clk_debugfs_register(c); - if (err) - goto err_out; - } + list_for_each_entry(c, &clocks, node) + clk_debugfs_register(c); - d = debugfs_create_file("summary", S_IRUGO, - d, NULL, &debug_clock_fops); - if (!d) - return -ENOMEM; + debugfs_create_file("summary", S_IRUGO, d, NULL, &debug_clock_fops); return 0; -err_out: - debugfs_remove_recursive(clk_debugfs_root); - return err; } late_initcall(clk_debugfs_init); diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 998075d3ef86..d068958d6f8a 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -539,11 +539,8 @@ static void omap_pm_init_debugfs(void) struct dentry *d; d = debugfs_create_dir("pm_debug", NULL); - if (!d) - return; - - (void) debugfs_create_file("omap_pm", S_IWUSR | S_IRUGO, - d, NULL, &omap_pm_debug_fops); + debugfs_create_file("omap_pm", S_IWUSR | S_IRUGO, d, NULL, + &omap_pm_debug_fops); } #endif /* CONFIG_DEBUG_FS */ From 30ed997a878ec34f4e2fab9f417cbfd401743a29 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 15:41:14 +0100 Subject: [PATCH 014/102] arm: omap2: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Kevin Hilman Cc: Russell King Cc: linux-omap@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Acked-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/pm-debug.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 5a8839203958..1f9334a3d611 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -193,9 +193,8 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir) return 0; d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir); - if (d) - (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, - (void *)pwrdm, &pwrdm_suspend_fops); + debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, pwrdm, + &pwrdm_suspend_fops); return 0; } @@ -233,16 +232,14 @@ static int __init pm_dbg_init(void) return 0; d = debugfs_create_dir("pm_debug", NULL); - if (!d) - return -EINVAL; - (void) debugfs_create_file("count", 0444, d, NULL, &pm_dbg_counters_fops); - (void) debugfs_create_file("time", 0444, d, NULL, &pm_dbg_timers_fops); + debugfs_create_file("count", 0444, d, NULL, &pm_dbg_counters_fops); + debugfs_create_file("time", 0444, d, NULL, &pm_dbg_timers_fops); pwrdm_for_each(pwrdms_setup, (void *)d); - (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, - &enable_off_mode, &pm_dbg_option_fops); + debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, + &enable_off_mode, &pm_dbg_option_fops); pm_dbg_init_done = 1; return 0; From db0487abd641db12a74a413067519a741e01dc57 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 15:41:12 +0100 Subject: [PATCH 015/102] arm: dump: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Russell King Cc: Jinbum Park Cc: linux-arm-kernel@lists.infradead.org Reviewed-by: Kees Cook Acked-by: Laura Abbott Signed-off-by: Greg Kroah-Hartman --- arch/arm/include/asm/ptdump.h | 9 +++------ arch/arm/mm/dump.c | 4 ++-- arch/arm/mm/ptdump_debugfs.c | 8 ++------ 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/arch/arm/include/asm/ptdump.h b/arch/arm/include/asm/ptdump.h index 3ebf9718288d..0c2d3d0d4cc6 100644 --- a/arch/arm/include/asm/ptdump.h +++ b/arch/arm/include/asm/ptdump.h @@ -21,13 +21,10 @@ struct ptdump_info { void ptdump_walk_pgd(struct seq_file *s, struct ptdump_info *info); #ifdef CONFIG_ARM_PTDUMP_DEBUGFS -int ptdump_debugfs_register(struct ptdump_info *info, const char *name); +void ptdump_debugfs_register(struct ptdump_info *info, const char *name); #else -static inline int ptdump_debugfs_register(struct ptdump_info *info, - const char *name) -{ - return 0; -} +static inline void ptdump_debugfs_register(struct ptdump_info *info, + const char *name) { } #endif /* CONFIG_ARM_PTDUMP_DEBUGFS */ void ptdump_check_wx(void); diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c index 084779c5c893..eb385a500ed0 100644 --- a/arch/arm/mm/dump.c +++ b/arch/arm/mm/dump.c @@ -450,7 +450,7 @@ void ptdump_check_wx(void) static int ptdump_init(void) { ptdump_initialize(); - return ptdump_debugfs_register(&kernel_ptdump_info, - "kernel_page_tables"); + ptdump_debugfs_register(&kernel_ptdump_info, "kernel_page_tables"); + return 0; } __initcall(ptdump_init); diff --git a/arch/arm/mm/ptdump_debugfs.c b/arch/arm/mm/ptdump_debugfs.c index be8d87be4b93..598b636615a2 100644 --- a/arch/arm/mm/ptdump_debugfs.c +++ b/arch/arm/mm/ptdump_debugfs.c @@ -24,11 +24,7 @@ static const struct file_operations ptdump_fops = { .release = single_release, }; -int ptdump_debugfs_register(struct ptdump_info *info, const char *name) +void ptdump_debugfs_register(struct ptdump_info *info, const char *name) { - struct dentry *pe; - - pe = debugfs_create_file(name, 0400, NULL, info, &ptdump_fops); - return pe ? 0 : -ENOMEM; - + debugfs_create_file(name, 0400, NULL, info, &ptdump_fops); } From 5dd82ba9e2d6112c8c9a1d92ad244171a5f4755b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 15:35:40 +0100 Subject: [PATCH 016/102] x86: mm: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Dave Hansen Cc: Andy Lutomirski Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: "H. Peter Anvin" Cc: x86@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/mm/debug_pagetables.c | 35 +++++++--------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c index c6f4982d5401..39001a401eff 100644 --- a/arch/x86/mm/debug_pagetables.c +++ b/arch/x86/mm/debug_pagetables.c @@ -26,8 +26,6 @@ static int ptdump_curknl_show(struct seq_file *m, void *v) DEFINE_SHOW_ATTRIBUTE(ptdump_curknl); #ifdef CONFIG_PAGE_TABLE_ISOLATION -static struct dentry *pe_curusr; - static int ptdump_curusr_show(struct seq_file *m, void *v) { if (current->mm->pgd) { @@ -42,8 +40,6 @@ DEFINE_SHOW_ATTRIBUTE(ptdump_curusr); #endif #if defined(CONFIG_EFI) && defined(CONFIG_X86_64) -static struct dentry *pe_efi; - static int ptdump_efi_show(struct seq_file *m, void *v) { if (efi_mm.pgd) @@ -54,41 +50,24 @@ static int ptdump_efi_show(struct seq_file *m, void *v) DEFINE_SHOW_ATTRIBUTE(ptdump_efi); #endif -static struct dentry *dir, *pe_knl, *pe_curknl; +static struct dentry *dir; static int __init pt_dump_debug_init(void) { dir = debugfs_create_dir("page_tables", NULL); - if (!dir) - return -ENOMEM; - pe_knl = debugfs_create_file("kernel", 0400, dir, NULL, - &ptdump_fops); - if (!pe_knl) - goto err; - - pe_curknl = debugfs_create_file("current_kernel", 0400, - dir, NULL, &ptdump_curknl_fops); - if (!pe_curknl) - goto err; + debugfs_create_file("kernel", 0400, dir, NULL, &ptdump_fops); + debugfs_create_file("current_kernel", 0400, dir, NULL, + &ptdump_curknl_fops); #ifdef CONFIG_PAGE_TABLE_ISOLATION - pe_curusr = debugfs_create_file("current_user", 0400, - dir, NULL, &ptdump_curusr_fops); - if (!pe_curusr) - goto err; + debugfs_create_file("current_user", 0400, dir, NULL, + &ptdump_curusr_fops); #endif - #if defined(CONFIG_EFI) && defined(CONFIG_X86_64) - pe_efi = debugfs_create_file("efi", 0400, dir, NULL, &ptdump_efi_fops); - if (!pe_efi) - goto err; + debugfs_create_file("efi", 0400, dir, NULL, &ptdump_efi_fops); #endif - return 0; -err: - debugfs_remove_recursive(dir); - return -ENOMEM; } static void __exit pt_dump_debug_exit(void) From 519e96ee114ff70e420111b39d884153250626dd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 15:35:41 +0100 Subject: [PATCH 017/102] x86: platform: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: "H. Peter Anvin" Cc: Signed-off-by: Greg Kroah-Hartman --- arch/x86/platform/atom/punit_atom_debug.c | 23 ++++------------------- arch/x86/platform/intel-quark/imr.c | 14 ++++---------- arch/x86/platform/intel/iosf_mbi.c | 21 +++------------------ arch/x86/platform/uv/tlb_uv.c | 15 ++------------- 4 files changed, 13 insertions(+), 60 deletions(-) diff --git a/arch/x86/platform/atom/punit_atom_debug.c b/arch/x86/platform/atom/punit_atom_debug.c index 6cb6076223ba..58f1023cf9bc 100644 --- a/arch/x86/platform/atom/punit_atom_debug.c +++ b/arch/x86/platform/atom/punit_atom_debug.c @@ -113,24 +113,12 @@ DEFINE_SHOW_ATTRIBUTE(punit_dev_state); static struct dentry *punit_dbg_file; -static int punit_dbgfs_register(struct punit_device *punit_device) +static void punit_dbgfs_register(struct punit_device *punit_device) { - struct dentry *dev_state; - punit_dbg_file = debugfs_create_dir("punit_atom", NULL); - if (!punit_dbg_file) - return -ENXIO; - dev_state = debugfs_create_file("dev_power_state", 0444, - punit_dbg_file, punit_device, - &punit_dev_state_fops); - if (!dev_state) { - pr_err("punit_dev_state register failed\n"); - debugfs_remove(punit_dbg_file); - return -ENXIO; - } - - return 0; + debugfs_create_file("dev_power_state", 0444, punit_dbg_file, + punit_device, &punit_dev_state_fops); } static void punit_dbgfs_unregister(void) @@ -154,15 +142,12 @@ MODULE_DEVICE_TABLE(x86cpu, intel_punit_cpu_ids); static int __init punit_atom_debug_init(void) { const struct x86_cpu_id *id; - int ret; id = x86_match_cpu(intel_punit_cpu_ids); if (!id) return -ENODEV; - ret = punit_dbgfs_register((struct punit_device *)id->driver_data); - if (ret < 0) - return ret; + punit_dbgfs_register((struct punit_device *)id->driver_data); return 0; } diff --git a/arch/x86/platform/intel-quark/imr.c b/arch/x86/platform/intel-quark/imr.c index b5420371d32d..6dd25dc5f027 100644 --- a/arch/x86/platform/intel-quark/imr.c +++ b/arch/x86/platform/intel-quark/imr.c @@ -35,7 +35,6 @@ #include struct imr_device { - struct dentry *file; bool init; struct mutex lock; int max_imr; @@ -231,13 +230,11 @@ DEFINE_SHOW_ATTRIBUTE(imr_dbgfs_state); * imr_debugfs_register - register debugfs hooks. * * @idev: pointer to imr_device structure. - * @return: 0 on success - errno on failure. */ -static int imr_debugfs_register(struct imr_device *idev) +static void imr_debugfs_register(struct imr_device *idev) { - idev->file = debugfs_create_file("imr_state", 0444, NULL, idev, - &imr_dbgfs_state_fops); - return PTR_ERR_OR_ZERO(idev->file); + debugfs_create_file("imr_state", 0444, NULL, idev, + &imr_dbgfs_state_fops); } /** @@ -582,7 +579,6 @@ static const struct x86_cpu_id imr_ids[] __initconst = { static int __init imr_init(void) { struct imr_device *idev = &imr_dev; - int ret; if (!x86_match_cpu(imr_ids) || !iosf_mbi_available()) return -ENODEV; @@ -592,9 +588,7 @@ static int __init imr_init(void) idev->init = true; mutex_init(&idev->lock); - ret = imr_debugfs_register(idev); - if (ret != 0) - pr_warn("debugfs register failed!\n"); + imr_debugfs_register(idev); imr_fixup_memmap(idev); return 0; } diff --git a/arch/x86/platform/intel/iosf_mbi.c b/arch/x86/platform/intel/iosf_mbi.c index a9f2e888e135..b18d4dec4658 100644 --- a/arch/x86/platform/intel/iosf_mbi.c +++ b/arch/x86/platform/intel/iosf_mbi.c @@ -470,31 +470,16 @@ static struct dentry *iosf_dbg; static void iosf_sideband_debug_init(void) { - struct dentry *d; - iosf_dbg = debugfs_create_dir("iosf_sb", NULL); - if (IS_ERR_OR_NULL(iosf_dbg)) - return; /* mdr */ - d = debugfs_create_x32("mdr", 0660, iosf_dbg, &dbg_mdr); - if (!d) - goto cleanup; + debugfs_create_x32("mdr", 0660, iosf_dbg, &dbg_mdr); /* mcrx */ - d = debugfs_create_x32("mcrx", 0660, iosf_dbg, &dbg_mcrx); - if (!d) - goto cleanup; + debugfs_create_x32("mcrx", 0660, iosf_dbg, &dbg_mcrx); /* mcr - initiates mailbox tranaction */ - d = debugfs_create_file("mcr", 0660, iosf_dbg, &dbg_mcr, &iosf_mcr_fops); - if (!d) - goto cleanup; - - return; - -cleanup: - debugfs_remove_recursive(d); + debugfs_create_file("mcr", 0660, iosf_dbg, &dbg_mcr, &iosf_mcr_fops); } static void iosf_debugfs_init(void) diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 0c7dfec4acac..20c389a91b80 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -66,7 +66,6 @@ static struct tunables tunables[] = { }; static struct dentry *tunables_dir; -static struct dentry *tunables_file; /* these correspond to the statistics printed by ptc_seq_show() */ static char *stat_description[] = { @@ -1700,18 +1699,8 @@ static int __init uv_ptc_init(void) } tunables_dir = debugfs_create_dir(UV_BAU_TUNABLES_DIR, NULL); - if (!tunables_dir) { - pr_err("unable to create debugfs directory %s\n", - UV_BAU_TUNABLES_DIR); - return -EINVAL; - } - tunables_file = debugfs_create_file(UV_BAU_TUNABLES_FILE, 0600, - tunables_dir, NULL, &tunables_fops); - if (!tunables_file) { - pr_err("unable to create debugfs file %s\n", - UV_BAU_TUNABLES_FILE); - return -EINVAL; - } + debugfs_create_file(UV_BAU_TUNABLES_FILE, 0600, tunables_dir, NULL, + &tunables_fops); return 0; } From 0fc811e5d7f9095f4a5732a34a19eff49fcb3ad6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 15:35:38 +0100 Subject: [PATCH 018/102] x86: kdebugfs: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: "H. Peter Anvin" Cc: Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/kdebugfs.c | 60 +++++++------------------------------- 1 file changed, 11 insertions(+), 49 deletions(-) diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c index fd6f8fbbe6f2..0758e7ca8977 100644 --- a/arch/x86/kernel/kdebugfs.c +++ b/arch/x86/kernel/kdebugfs.c @@ -68,33 +68,18 @@ static const struct file_operations fops_setup_data = { .llseek = default_llseek, }; -static int __init +static void __init create_setup_data_node(struct dentry *parent, int no, struct setup_data_node *node) { - struct dentry *d, *type, *data; + struct dentry *d; char buf[16]; sprintf(buf, "%d", no); d = debugfs_create_dir(buf, parent); - if (!d) - return -ENOMEM; - type = debugfs_create_x32("type", S_IRUGO, d, &node->type); - if (!type) - goto err_dir; - - data = debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data); - if (!data) - goto err_type; - - return 0; - -err_type: - debugfs_remove(type); -err_dir: - debugfs_remove(d); - return -ENOMEM; + debugfs_create_x32("type", S_IRUGO, d, &node->type); + debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data); } static int __init create_setup_data_nodes(struct dentry *parent) @@ -107,8 +92,6 @@ static int __init create_setup_data_nodes(struct dentry *parent) int no = 0; d = debugfs_create_dir("setup_data", parent); - if (!d) - return -ENOMEM; pa_data = boot_params.hdr.setup_data; @@ -129,19 +112,17 @@ static int __init create_setup_data_nodes(struct dentry *parent) node->paddr = pa_data; node->type = data->type; node->len = data->len; - error = create_setup_data_node(d, no, node); + create_setup_data_node(d, no, node); pa_data = data->next; memunmap(data); - if (error) - goto err_dir; no++; } return 0; err_dir: - debugfs_remove(d); + debugfs_remove_recursive(d); return error; } @@ -152,35 +133,18 @@ static struct debugfs_blob_wrapper boot_params_blob = { static int __init boot_params_kdebugfs_init(void) { - struct dentry *dbp, *version, *data; - int error = -ENOMEM; + struct dentry *dbp; + int error; dbp = debugfs_create_dir("boot_params", arch_debugfs_dir); - if (!dbp) - return -ENOMEM; - version = debugfs_create_x16("version", S_IRUGO, dbp, - &boot_params.hdr.version); - if (!version) - goto err_dir; - - data = debugfs_create_blob("data", S_IRUGO, dbp, - &boot_params_blob); - if (!data) - goto err_version; + debugfs_create_x16("version", S_IRUGO, dbp, &boot_params.hdr.version); + debugfs_create_blob("data", S_IRUGO, dbp, &boot_params_blob); error = create_setup_data_nodes(dbp); if (error) - goto err_data; + debugfs_remove_recursive(dbp); - return 0; - -err_data: - debugfs_remove(data); -err_version: - debugfs_remove(version); -err_dir: - debugfs_remove(dbp); return error; } #endif /* CONFIG_DEBUG_BOOT_PARAMS */ @@ -190,8 +154,6 @@ static int __init arch_kdebugfs_init(void) int error = 0; arch_debugfs_dir = debugfs_create_dir("x86", NULL); - if (!arch_debugfs_dir) - return -ENOMEM; #ifdef CONFIG_DEBUG_BOOT_PARAMS error = boot_params_kdebugfs_init(); From 1c769fc41ac574e4957a6a874334eed1631e5f59 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:48 +0100 Subject: [PATCH 019/102] gcov: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Also delete the dentry variable as it is never needed. Acked-by: Peter Oberparleiter Signed-off-by: Greg Kroah-Hartman --- kernel/gcov/fs.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/kernel/gcov/fs.c b/kernel/gcov/fs.c index 6e40ff6be083..e5eb5ea7ea59 100644 --- a/kernel/gcov/fs.c +++ b/kernel/gcov/fs.c @@ -64,7 +64,6 @@ struct gcov_node { static const char objtree[] = OBJTREE; static const char srctree[] = SRCTREE; static struct gcov_node root_node; -static struct dentry *reset_dentry; static LIST_HEAD(all_head); static DEFINE_MUTEX(node_lock); @@ -387,8 +386,6 @@ static void add_links(struct gcov_node *node, struct dentry *parent) goto out_err; node->links[i] = debugfs_create_symlink(deskew(basename), parent, target); - if (!node->links[i]) - goto out_err; kfree(target); } @@ -450,11 +447,6 @@ static struct gcov_node *new_node(struct gcov_node *parent, parent->dentry, node, &gcov_data_fops); } else node->dentry = debugfs_create_dir(node->name, parent->dentry); - if (!node->dentry) { - pr_warn("could not create file\n"); - kfree(node); - return NULL; - } if (info) add_links(node, parent->dentry); list_add(&node->list, &parent->children); @@ -761,32 +753,20 @@ void gcov_event(enum gcov_action action, struct gcov_info *info) /* Create debugfs entries. */ static __init int gcov_fs_init(void) { - int rc = -EIO; - init_node(&root_node, NULL, NULL, NULL); /* * /sys/kernel/debug/gcov will be parent for the reset control file * and all profiling files. */ root_node.dentry = debugfs_create_dir("gcov", NULL); - if (!root_node.dentry) - goto err_remove; /* * Create reset file which resets all profiling counts when written * to. */ - reset_dentry = debugfs_create_file("reset", 0600, root_node.dentry, - NULL, &gcov_reset_fops); - if (!reset_dentry) - goto err_remove; + debugfs_create_file("reset", 0600, root_node.dentry, NULL, + &gcov_reset_fops); /* Replay previous events to get our fs hierarchy up-to-date. */ gcov_enable_events(); return 0; - -err_remove: - pr_err("init failed\n"); - debugfs_remove(root_node.dentry); - - return rc; } device_initcall(gcov_fs_init); From a9a9da47f8e6c1fe24c8bfe36c7f5ee6fc3700a1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 16 Apr 2019 16:15:54 +0200 Subject: [PATCH 020/102] mailbox: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Jassi Brar Signed-off-by: Greg Kroah-Hartman --- drivers/mailbox/bcm-flexrm-mailbox.c | 28 +++++----------------------- drivers/mailbox/bcm-pdc-mailbox.c | 8 ++------ 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c index a64116586b4c..43b336316fde 100644 --- a/drivers/mailbox/bcm-flexrm-mailbox.c +++ b/drivers/mailbox/bcm-flexrm-mailbox.c @@ -296,8 +296,6 @@ struct flexrm_mbox { struct dma_pool *bd_pool; struct dma_pool *cmpl_pool; struct dentry *root; - struct dentry *config; - struct dentry *stats; struct mbox_controller controller; }; @@ -1603,7 +1601,6 @@ static int flexrm_mbox_probe(struct platform_device *pdev) 1 << RING_CMPL_ALIGN_ORDER, 0); if (!mbox->cmpl_pool) { ret = -ENOMEM; - goto fail_destroy_bd_pool; } /* Allocate platform MSIs for each ring */ @@ -1624,28 +1621,15 @@ static int flexrm_mbox_probe(struct platform_device *pdev) /* Create debugfs root entry */ mbox->root = debugfs_create_dir(dev_name(mbox->dev), NULL); - if (IS_ERR_OR_NULL(mbox->root)) { - ret = PTR_ERR_OR_ZERO(mbox->root); - goto fail_free_msis; - } /* Create debugfs config entry */ - mbox->config = debugfs_create_devm_seqfile(mbox->dev, - "config", mbox->root, - flexrm_debugfs_conf_show); - if (IS_ERR_OR_NULL(mbox->config)) { - ret = PTR_ERR_OR_ZERO(mbox->config); - goto fail_free_debugfs_root; - } + debugfs_create_devm_seqfile(mbox->dev, "config", mbox->root, + flexrm_debugfs_conf_show); /* Create debugfs stats entry */ - mbox->stats = debugfs_create_devm_seqfile(mbox->dev, - "stats", mbox->root, - flexrm_debugfs_stats_show); - if (IS_ERR_OR_NULL(mbox->stats)) { - ret = PTR_ERR_OR_ZERO(mbox->stats); - goto fail_free_debugfs_root; - } + debugfs_create_devm_seqfile(mbox->dev, "stats", mbox->root, + flexrm_debugfs_stats_show); + skip_debugfs: /* Initialize mailbox controller */ @@ -1676,11 +1660,9 @@ skip_debugfs: fail_free_debugfs_root: debugfs_remove_recursive(mbox->root); -fail_free_msis: platform_msi_domain_free_irqs(dev); fail_destroy_cmpl_pool: dma_pool_destroy(mbox->cmpl_pool); -fail_destroy_bd_pool: dma_pool_destroy(mbox->bd_pool); fail: return ret; diff --git a/drivers/mailbox/bcm-pdc-mailbox.c b/drivers/mailbox/bcm-pdc-mailbox.c index ccf3d62af7e7..a8c291386142 100644 --- a/drivers/mailbox/bcm-pdc-mailbox.c +++ b/drivers/mailbox/bcm-pdc-mailbox.c @@ -406,8 +406,6 @@ struct pdc_state { */ struct scatterlist *src_sg[PDC_RING_ENTRIES]; - struct dentry *debugfs_stats; /* debug FS stats file for this PDC */ - /* counters */ u32 pdc_requests; /* number of request messages submitted */ u32 pdc_replies; /* number of reply messages received */ @@ -512,9 +510,8 @@ static void pdc_setup_debugfs(struct pdc_state *pdcs) debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); /* S_IRUSR == 0400 */ - pdcs->debugfs_stats = debugfs_create_file(spu_stats_name, 0400, - debugfs_dir, pdcs, - &pdc_debugfs_stats); + debugfs_create_file(spu_stats_name, 0400, debugfs_dir, pdcs, + &pdc_debugfs_stats); } static void pdc_free_debugfs(void) @@ -1614,7 +1611,6 @@ static int pdc_probe(struct platform_device *pdev) if (err) goto cleanup_buf_pool; - pdcs->debugfs_stats = NULL; pdc_setup_debugfs(pdcs); dev_dbg(dev, "pdc_probe() successful"); From 36b7ee4dce9e519cf87917eccbaabb53638fdf03 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 4 Jan 2019 14:25:20 +0100 Subject: [PATCH 021/102] btrfs: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Chris Mason Cc: Josef Bacik Cc: David Sterba Cc: linux-btrfs@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/sysfs.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 2f078b77fe14..a1481808db80 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -910,12 +910,10 @@ void btrfs_sysfs_feature_update(struct btrfs_fs_info *fs_info, ret = sysfs_create_group(fsid_kobj, &btrfs_feature_attr_group); } -static int btrfs_init_debugfs(void) +static void btrfs_init_debugfs(void) { #ifdef CONFIG_DEBUG_FS btrfs_debugfs_root_dentry = debugfs_create_dir("btrfs", NULL); - if (!btrfs_debugfs_root_dentry) - return -ENOMEM; /* * Example code, how to export data through debugfs. @@ -929,7 +927,6 @@ static int btrfs_init_debugfs(void) #endif #endif - return 0; } int __init btrfs_init_sysfs(void) @@ -940,9 +937,7 @@ int __init btrfs_init_sysfs(void) if (!btrfs_kset) return -ENOMEM; - ret = btrfs_init_debugfs(); - if (ret) - goto out1; + btrfs_init_debugfs(); init_feature_attrs(); ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_feature_attr_group); @@ -959,7 +954,6 @@ out_remove_group: sysfs_remove_group(&btrfs_kset->kobj, &btrfs_feature_attr_group); out2: debugfs_remove_recursive(btrfs_debugfs_root_dentry); -out1: kset_unregister(btrfs_kset); return ret; From c9c2c27d7ceca8c2856c5008f2002bddb384f518 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 16 Apr 2019 15:46:55 +0200 Subject: [PATCH 022/102] debugfs: make debugfs_create_u32_array() return void The single user of debugfs_create_u32_array() does not care about the return value of it, so make it return void as there is no need to do anything with the return value. Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 2 +- fs/debugfs/file.c | 14 ++++---------- include/linux/debugfs.h | 12 +++++------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 4a0a9c3f4af6..9e27c843d00e 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -169,7 +169,7 @@ byte offsets over a base for the register block. If you want to dump an u32 array in debugfs, you can create file with: - struct dentry *debugfs_create_u32_array(const char *name, umode_t mode, + void debugfs_create_u32_array(const char *name, umode_t mode, struct dentry *parent, u32 *array, u32 elements); diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index ddd708b09fa1..93e4ca6b2ad7 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -997,25 +997,19 @@ static const struct file_operations u32_array_fops = { * @array as data. If the @mode variable is so set it can be read from. * Writing is not supported. Seek within the file is also not supported. * Once array is created its size can not be changed. - * - * The function returns a pointer to dentry on success. If an error occurs, - * %ERR_PTR(-ERROR) or NULL will be returned. If debugfs is not enabled in - * the kernel, the value %ERR_PTR(-ENODEV) will be returned. */ -struct dentry *debugfs_create_u32_array(const char *name, umode_t mode, - struct dentry *parent, - u32 *array, u32 elements) +void debugfs_create_u32_array(const char *name, umode_t mode, + struct dentry *parent, u32 *array, u32 elements) { struct array_data *data = kmalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) - return NULL; + return; data->array = array; data->elements = elements; - return debugfs_create_file_unsafe(name, mode, parent, data, - &u32_array_fops); + debugfs_create_file_unsafe(name, mode, parent, data, &u32_array_fops); } EXPORT_SYMBOL_GPL(debugfs_create_u32_array); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 3b0ba54cc4d5..58424eb3b329 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -133,9 +133,8 @@ struct dentry *debugfs_create_regset32(const char *name, umode_t mode, void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, int nregs, void __iomem *base, char *prefix); -struct dentry *debugfs_create_u32_array(const char *name, umode_t mode, - struct dentry *parent, - u32 *array, u32 elements); +void debugfs_create_u32_array(const char *name, umode_t mode, + struct dentry *parent, u32 *array, u32 elements); struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name, struct dentry *parent, @@ -353,11 +352,10 @@ static inline bool debugfs_initialized(void) return false; } -static inline struct dentry *debugfs_create_u32_array(const char *name, umode_t mode, - struct dentry *parent, - u32 *array, u32 elements) +static inline void debugfs_create_u32_array(const char *name, umode_t mode, + struct dentry *parent, u32 *array, + u32 elements) { - return ERR_PTR(-ENODEV); } static inline struct dentry *debugfs_create_devm_seqfile(struct device *dev, From 64ae0e71c60dc4bd3a59ae709b807f96f68df495 Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Tue, 4 Jun 2019 18:57:39 -0700 Subject: [PATCH 023/102] mm/zsmalloc.c: remove unused variable The variable 'entry' is no longer used and the compiler rightly complains that it should be removed. ../mm/zsmalloc.c: In function `zs_pool_stat_create': ../mm/zsmalloc.c:648:17: warning: unused variable `entry' [-Wunused-variable] struct dentry *entry; ^~~~~ Rework to remove the unused variable. Link: http://lkml.kernel.org/r/20190604065826.26064-1-anders.roxell@linaro.org Fixes: 4268509a36a7 ("zsmalloc: no need to check return value of debugfs_create functions") Signed-off-by: Anders Roxell Cc: Minchan Kim Cc: Sergey Senozhatsky Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/zsmalloc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 1347d7922ea2..db09eb3669c5 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -645,8 +645,6 @@ DEFINE_SHOW_ATTRIBUTE(zs_stats_size); static void zs_pool_stat_create(struct zs_pool *pool, const char *name) { - struct dentry *entry; - if (!zs_stat_root) { pr_warn("no root stat dir, not creating <%s> stat dir\n", name); return; From ddaf29fd9bb6a8192153bc097615765d202b0ab3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 May 2019 11:26:43 +0200 Subject: [PATCH 024/102] firmware: Free temporary page table after vmapping Once after performing vmap() to map the S/G pages, our own page table becomes superfluous since the pages can be released via vfree() automatically. Let's change the buffer release code and discard the page table array for saving some memory. Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/fallback.c | 7 ++++++- drivers/base/firmware_loader/main.c | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index f962488546b6..a0a1856aac84 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -222,7 +222,7 @@ static ssize_t firmware_loading_show(struct device *dev, /* one pages buffer should be mapped/unmapped only once */ static int map_fw_priv_pages(struct fw_priv *fw_priv) { - if (!fw_priv->is_paged_buf) + if (!fw_priv->pages) return 0; vunmap(fw_priv->data); @@ -230,6 +230,11 @@ static int map_fw_priv_pages(struct fw_priv *fw_priv) PAGE_KERNEL_RO); if (!fw_priv->data) return -ENOMEM; + + /* page table is no longer needed after mapping, let's free */ + vfree(fw_priv->pages); + fw_priv->pages = NULL; + return 0; } diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 7eaaf5ee5ba6..aed1a7c56713 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -252,13 +252,13 @@ static void __free_fw_priv(struct kref *ref) spin_unlock(&fwc->lock); #ifdef CONFIG_FW_LOADER_USER_HELPER - if (fw_priv->is_paged_buf) { + if (fw_priv->pages) { + /* free leftover pages */ int i; - vunmap(fw_priv->data); for (i = 0; i < fw_priv->nr_pages; i++) __free_page(fw_priv->pages[i]); vfree(fw_priv->pages); - } else + } #endif if (!fw_priv->allocated_size) vfree(fw_priv->data); From 8f58570b98c090a4544ef9eaea1f419706672845 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 May 2019 11:26:44 +0200 Subject: [PATCH 025/102] firmware: Unify the paged buffer release helper Use a common helper to release the paged buffer resources. This is rather a preparation for the upcoming decompression support. Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/fallback.c | 8 +------- drivers/base/firmware_loader/firmware.h | 6 ++++++ drivers/base/firmware_loader/main.c | 27 ++++++++++++++++--------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index a0a1856aac84..8970a5315e85 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -259,7 +259,6 @@ static ssize_t firmware_loading_store(struct device *dev, struct fw_priv *fw_priv; ssize_t written = count; int loading = simple_strtol(buf, NULL, 10); - int i; mutex_lock(&fw_lock); fw_priv = fw_sysfs->fw_priv; @@ -270,12 +269,7 @@ static ssize_t firmware_loading_store(struct device *dev, case 1: /* discarding any previous partial load */ if (!fw_sysfs_done(fw_priv)) { - for (i = 0; i < fw_priv->nr_pages; i++) - __free_page(fw_priv->pages[i]); - vfree(fw_priv->pages); - fw_priv->pages = NULL; - fw_priv->page_array_size = 0; - fw_priv->nr_pages = 0; + fw_free_paged_buf(fw_priv); fw_state_start(fw_priv); } break; diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h index 4c1395f8e7ed..d20d4e7f9e71 100644 --- a/drivers/base/firmware_loader/firmware.h +++ b/drivers/base/firmware_loader/firmware.h @@ -133,4 +133,10 @@ static inline void fw_state_done(struct fw_priv *fw_priv) int assign_fw(struct firmware *fw, struct device *device, enum fw_opt opt_flags); +#ifdef CONFIG_FW_LOADER_USER_HELPER +void fw_free_paged_buf(struct fw_priv *fw_priv); +#else +static inline void fw_free_paged_buf(struct fw_priv *fw_priv) {} +#endif + #endif /* __FIRMWARE_LOADER_H */ diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index aed1a7c56713..083fc3e4f2fd 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -251,15 +251,7 @@ static void __free_fw_priv(struct kref *ref) list_del(&fw_priv->list); spin_unlock(&fwc->lock); -#ifdef CONFIG_FW_LOADER_USER_HELPER - if (fw_priv->pages) { - /* free leftover pages */ - int i; - for (i = 0; i < fw_priv->nr_pages; i++) - __free_page(fw_priv->pages[i]); - vfree(fw_priv->pages); - } -#endif + fw_free_paged_buf(fw_priv); /* free leftover pages */ if (!fw_priv->allocated_size) vfree(fw_priv->data); kfree_const(fw_priv->fw_name); @@ -274,6 +266,23 @@ static void free_fw_priv(struct fw_priv *fw_priv) spin_unlock(&fwc->lock); } +#ifdef CONFIG_FW_LOADER_USER_HELPER +void fw_free_paged_buf(struct fw_priv *fw_priv) +{ + int i; + + if (!fw_priv->pages) + return; + + for (i = 0; i < fw_priv->nr_pages; i++) + __free_page(fw_priv->pages[i]); + vfree(fw_priv->pages); + fw_priv->pages = NULL; + fw_priv->page_array_size = 0; + fw_priv->nr_pages = 0; +} +#endif + /* direct firmware loading support */ static char fw_path_para[256]; static const char * const fw_path[] = { From 993f5d11a9631face2bb597826b86f476a9b915b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 May 2019 11:26:45 +0200 Subject: [PATCH 026/102] firmware: Use kvmalloc for page tables This is a minor optimization to use kvmalloc() variant for allocating the page table for the SG-buffer. They aren't so big in general, so kmalloc() would fit often better. Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/fallback.c | 7 ++++--- drivers/base/firmware_loader/main.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index 8970a5315e85..b5cd96fd0e77 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -232,7 +232,7 @@ static int map_fw_priv_pages(struct fw_priv *fw_priv) return -ENOMEM; /* page table is no longer needed after mapping, let's free */ - vfree(fw_priv->pages); + kvfree(fw_priv->pages); fw_priv->pages = NULL; return 0; @@ -397,7 +397,8 @@ static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size) fw_priv->page_array_size * 2); struct page **new_pages; - new_pages = vmalloc(array_size(new_array_size, sizeof(void *))); + new_pages = kvmalloc_array(new_array_size, sizeof(void *), + GFP_KERNEL); if (!new_pages) { fw_load_abort(fw_sysfs); return -ENOMEM; @@ -406,7 +407,7 @@ static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size) fw_priv->page_array_size * sizeof(void *)); memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * (new_array_size - fw_priv->page_array_size)); - vfree(fw_priv->pages); + kvfree(fw_priv->pages); fw_priv->pages = new_pages; fw_priv->page_array_size = new_array_size; } diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 083fc3e4f2fd..2e74a1b73dae 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -276,7 +276,7 @@ void fw_free_paged_buf(struct fw_priv *fw_priv) for (i = 0; i < fw_priv->nr_pages; i++) __free_page(fw_priv->pages[i]); - vfree(fw_priv->pages); + kvfree(fw_priv->pages); fw_priv->pages = NULL; fw_priv->page_array_size = 0; fw_priv->nr_pages = 0; From 225afca60b8a21bb53ca461eef78a60958ff95e4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2019 20:55:28 +0200 Subject: [PATCH 027/102] vmw_balloon: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Julien Freche Cc: "VMware, Inc." Cc: Arnd Bergmann Cc: linux-kernel@vger.kernel.org Acked-by: Nadav Amit Signed-off-by: Greg Kroah-Hartman --- drivers/misc/vmw_balloon.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index ad807d5a3141..fdf5ad757226 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c @@ -1516,19 +1516,10 @@ static int vmballoon_debug_show(struct seq_file *f, void *offset) DEFINE_SHOW_ATTRIBUTE(vmballoon_debug); -static int __init vmballoon_debugfs_init(struct vmballoon *b) +static void __init vmballoon_debugfs_init(struct vmballoon *b) { - int error; - b->dbg_entry = debugfs_create_file("vmmemctl", S_IRUGO, NULL, b, &vmballoon_debug_fops); - if (IS_ERR(b->dbg_entry)) { - error = PTR_ERR(b->dbg_entry); - pr_err("failed to create debugfs entry, error: %d\n", error); - return error; - } - - return 0; } static void __exit vmballoon_debugfs_exit(struct vmballoon *b) @@ -1541,9 +1532,8 @@ static void __exit vmballoon_debugfs_exit(struct vmballoon *b) #else -static inline int vmballoon_debugfs_init(struct vmballoon *b) +static inline void vmballoon_debugfs_init(struct vmballoon *b) { - return 0; } static inline void vmballoon_debugfs_exit(struct vmballoon *b) @@ -1555,7 +1545,6 @@ static inline void vmballoon_debugfs_exit(struct vmballoon *b) static int __init vmballoon_init(void) { enum vmballoon_page_size_type page_size; - int error; /* * Check if we are running on VMware's hypervisor and bail out @@ -1571,9 +1560,7 @@ static int __init vmballoon_init(void) INIT_DELAYED_WORK(&balloon.dwork, vmballoon_work); - error = vmballoon_debugfs_init(&balloon); - if (error) - return error; + vmballoon_debugfs_init(&balloon); spin_lock_init(&balloon.comm_lock); init_rwsem(&balloon.conf_sem); From 5a2338dbf97fac3a93e2ffefa5ab907ac5a9ba56 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2019 20:32:13 +0200 Subject: [PATCH 028/102] lkdtm: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Arnd Bergmann Cc: linux-kernel@vger.kernel.org Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- drivers/misc/lkdtm/core.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index 1972dad966f5..bae3b3763f3e 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -429,22 +429,13 @@ static int __init lkdtm_module_init(void) /* Register debugfs interface */ lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL); - if (!lkdtm_debugfs_root) { - pr_err("creating root dir failed\n"); - return -ENODEV; - } /* Install debugfs trigger files. */ for (i = 0; i < ARRAY_SIZE(crashpoints); i++) { struct crashpoint *cur = &crashpoints[i]; - struct dentry *de; - de = debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root, - cur, &cur->fops); - if (de == NULL) { - pr_err("could not create crashpoint %s\n", cur->name); - goto out_err; - } + debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root, cur, + &cur->fops); } /* Install crashpoint if one was selected. */ From 909bad2d978737592b70a0546edfa8bd023ab147 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2019 20:45:03 +0200 Subject: [PATCH 029/102] ti-st: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: linux-kernel@vger.kernel.org Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_kim.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index e7cfdbd1f66d..93821c11bff9 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -761,10 +761,6 @@ static int kim_probe(struct platform_device *pdev) pr_info("sysfs entries created\n"); kim_debugfs_dir = debugfs_create_dir("ti-st", NULL); - if (!kim_debugfs_dir) { - pr_err(" debugfs entries creation failed "); - return 0; - } debugfs_create_file("version", S_IRUGO, kim_debugfs_dir, kim_gdata, &version_fops); From ef254d13f1783793747c639d8e79843d5caf995a Mon Sep 17 00:00:00 2001 From: Kimberly Brown Date: Fri, 7 Jun 2019 14:23:00 -0400 Subject: [PATCH 030/102] gfs2: replace ktype default_attrs with default_groups The kobj_type default_attrs field is being replaced by the default_groups field. Replace the default_attrs field in gfs2_ktype with default_groups. Use the ATTRIBUTE_GROUPS macro to create gfs2_groups. Signed-off-by: Kimberly Brown Signed-off-by: Greg Kroah-Hartman --- fs/gfs2/sys.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 08e4996adc23..fddfb87abd38 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -299,6 +299,7 @@ static struct attribute *gfs2_attrs[] = { &gfs2_attr_demote_rq.attr, NULL, }; +ATTRIBUTE_GROUPS(gfs2); static void gfs2_sbd_release(struct kobject *kobj) { @@ -309,7 +310,7 @@ static void gfs2_sbd_release(struct kobject *kobj) static struct kobj_type gfs2_ktype = { .release = gfs2_sbd_release, - .default_attrs = gfs2_attrs, + .default_groups = gfs2_groups, .sysfs_ops = &gfs2_attr_ops, }; From 59137a93f3af3ffb31c5c538357486df3d2e40d9 Mon Sep 17 00:00:00 2001 From: Kimberly Brown Date: Wed, 8 May 2019 16:07:48 -0400 Subject: [PATCH 031/102] ext4: replace ktype default_attrs with default_groups The kobj_type default_attrs field is being replaced by the default_groups field. Replace the default_attrs field in ext4_sb_ktype and ext4_feat_ktype with default_groups. Use the ATTRIBUTE_GROUPS macro to create ext4_groups and ext4_feat_groups. Signed-off-by: Kimberly Brown Signed-off-by: Greg Kroah-Hartman --- fs/ext4/sysfs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c index 04b4f53f0659..b3cd7655a6ff 100644 --- a/fs/ext4/sysfs.c +++ b/fs/ext4/sysfs.c @@ -230,6 +230,7 @@ static struct attribute *ext4_attrs[] = { ATTR_LIST(journal_task), NULL, }; +ATTRIBUTE_GROUPS(ext4); /* Features this copy of ext4 supports */ EXT4_ATTR_FEATURE(lazy_itable_init); @@ -256,6 +257,7 @@ static struct attribute *ext4_feat_attrs[] = { ATTR_LIST(metadata_csum_seed), NULL, }; +ATTRIBUTE_GROUPS(ext4_feat); static void *calc_ptr(struct ext4_attr *a, struct ext4_sb_info *sbi) { @@ -374,13 +376,13 @@ static const struct sysfs_ops ext4_attr_ops = { }; static struct kobj_type ext4_sb_ktype = { - .default_attrs = ext4_attrs, + .default_groups = ext4_groups, .sysfs_ops = &ext4_attr_ops, .release = ext4_sb_release, }; static struct kobj_type ext4_feat_ktype = { - .default_attrs = ext4_feat_attrs, + .default_groups = ext4_feat_groups, .sysfs_ops = &ext4_attr_ops, .release = (void (*)(struct kobject *))kfree, }; From c9c5b5e1565d6166e8d477d598e82652d0d7542d Mon Sep 17 00:00:00 2001 From: Kimberly Brown Date: Tue, 7 May 2019 21:48:05 -0400 Subject: [PATCH 032/102] dlm: Replace default_attrs in dlm_ktype with default_groups The kobj_type default_attrs field is being replaced by the default_groups field, so replace the default_attrs field in dlm_ktype with default_groups. Use the ATTRIBUTE_GROUPS macro to create dlm_groups. Signed-off-by: Kimberly Brown Signed-off-by: Greg Kroah-Hartman --- fs/dlm/lockspace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 4c2c85a223ac..afb8340918b8 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -158,6 +158,7 @@ static struct attribute *dlm_attrs[] = { &dlm_attr_recover_nodeid.attr, NULL, }; +ATTRIBUTE_GROUPS(dlm); static ssize_t dlm_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) @@ -187,7 +188,7 @@ static const struct sysfs_ops dlm_attr_ops = { }; static struct kobj_type dlm_ktype = { - .default_attrs = dlm_attrs, + .default_groups = dlm_groups, .sysfs_ops = &dlm_attr_ops, .release = lockspace_kobj_release, }; From dad4afe746b3e73dbc8ef8d60a3645a78a919026 Mon Sep 17 00:00:00 2001 From: Kimberly Brown Date: Fri, 7 Jun 2019 13:40:41 -0400 Subject: [PATCH 033/102] f2fs: replace ktype default_attrs with default_groups The kobj_type default_attrs field is being replaced by the default_groups field. Replace the default_attrs fields in f2fs_sb_ktype and f2fs_feat_ktype with default_groups. Use the ATTRIBUTE_GROUPS macro to create f2fs_groups and f2fs_feat_groups. Signed-off-by: Kimberly Brown Reviewed-by: Chao Yu Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/sysfs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 729f46a3c9ee..5c85166677d4 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -501,6 +501,7 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(current_reserved_blocks), NULL, }; +ATTRIBUTE_GROUPS(f2fs); static struct attribute *f2fs_feat_attrs[] = { #ifdef CONFIG_FS_ENCRYPTION @@ -520,6 +521,7 @@ static struct attribute *f2fs_feat_attrs[] = { ATTR_LIST(sb_checksum), NULL, }; +ATTRIBUTE_GROUPS(f2fs_feat); static const struct sysfs_ops f2fs_attr_ops = { .show = f2fs_attr_show, @@ -527,7 +529,7 @@ static const struct sysfs_ops f2fs_attr_ops = { }; static struct kobj_type f2fs_sb_ktype = { - .default_attrs = f2fs_attrs, + .default_groups = f2fs_groups, .sysfs_ops = &f2fs_attr_ops, .release = f2fs_sb_release, }; @@ -541,7 +543,7 @@ static struct kset f2fs_kset = { }; static struct kobj_type f2fs_feat_ktype = { - .default_attrs = f2fs_feat_attrs, + .default_groups = f2fs_feat_groups, .sysfs_ops = &f2fs_attr_ops, }; From ed66bcd0674a97cbacb01e7d140eea0f882d31a6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Jun 2019 23:04:07 -0300 Subject: [PATCH 034/102] ABI: fix some syntax issues at the ABI database On those three files, the ABI representation described at README are violated. - at sysfs-bus-iio-proximity-as3935: a ':' character is missing after "What" - at sysfs-class-devfreq: there's a typo at Description - at sysfs-class-cxl, it is using the ":" character at a file preamble, causing it to be misinterpreted as a tag. - On the other files, instead of "What", they use "Where". Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab Acked-by: Rafael J. Wysocki Acked-by: Andrew Donnellan # cxl Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/pstore | 2 +- .../sysfs-bus-event_source-devices-format | 2 +- .../ABI/testing/sysfs-bus-i2c-devices-hm6352 | 6 ++--- .../ABI/testing/sysfs-bus-iio-distance-srf08 | 4 ++-- .../testing/sysfs-bus-iio-proximity-as3935 | 4 ++-- .../ABI/testing/sysfs-bus-pci-devices-cciss | 22 +++++++++---------- .../testing/sysfs-bus-usb-devices-usbsevseg | 12 +++++----- Documentation/ABI/testing/sysfs-class-cxl | 6 ++--- Documentation/ABI/testing/sysfs-class-devfreq | 2 +- .../ABI/testing/sysfs-class-powercap | 2 +- Documentation/ABI/testing/sysfs-kernel-fscaps | 2 +- .../ABI/testing/sysfs-kernel-vmcoreinfo | 2 +- 12 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Documentation/ABI/testing/pstore b/Documentation/ABI/testing/pstore index 5fca9f5e10a3..8d6e48f4e8ef 100644 --- a/Documentation/ABI/testing/pstore +++ b/Documentation/ABI/testing/pstore @@ -1,4 +1,4 @@ -Where: /sys/fs/pstore/... (or /dev/pstore/...) +What: /sys/fs/pstore/... (or /dev/pstore/...) Date: March 2011 Kernel Version: 2.6.39 Contact: tony.luck@intel.com diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-format b/Documentation/ABI/testing/sysfs-bus-event_source-devices-format index 77f47ff5ee02..b6f8748e0200 100644 --- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-format +++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-format @@ -1,4 +1,4 @@ -Where: /sys/bus/event_source/devices//format +What: /sys/bus/event_source/devices//format Date: January 2012 Kernel Version: 3.3 Contact: Jiri Olsa diff --git a/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 b/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 index feb2e4a87075..29bd447e50a0 100644 --- a/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 +++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 @@ -1,18 +1,18 @@ -Where: /sys/bus/i2c/devices/.../heading0_input +What: /sys/bus/i2c/devices/.../heading0_input Date: April 2010 Kernel Version: 2.6.36? Contact: alan.cox@intel.com Description: Reports the current heading from the compass as a floating point value in degrees. -Where: /sys/bus/i2c/devices/.../power_state +What: /sys/bus/i2c/devices/.../power_state Date: April 2010 Kernel Version: 2.6.36? Contact: alan.cox@intel.com Description: Sets the power state of the device. 0 sets the device into sleep mode, 1 wakes it up. -Where: /sys/bus/i2c/devices/.../calibration +What: /sys/bus/i2c/devices/.../calibration Date: April 2010 Kernel Version: 2.6.36? Contact: alan.cox@intel.com diff --git a/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 b/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 index 0a1ca1487fa9..a133fd8d081a 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 +++ b/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 @@ -1,4 +1,4 @@ -What /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity +What: /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity Date: January 2017 KernelVersion: 4.11 Contact: linux-iio@vger.kernel.org @@ -6,7 +6,7 @@ Description: Show or set the gain boost of the amp, from 0-31 range. default 31 -What /sys/bus/iio/devices/iio:deviceX/sensor_max_range +What: /sys/bus/iio/devices/iio:deviceX/sensor_max_range Date: January 2017 KernelVersion: 4.11 Contact: linux-iio@vger.kernel.org diff --git a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 index 9a17ab5036a4..c59d95346341 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 +++ b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 @@ -1,4 +1,4 @@ -What /sys/bus/iio/devices/iio:deviceX/in_proximity_input +What: /sys/bus/iio/devices/iio:deviceX/in_proximity_input Date: March 2014 KernelVersion: 3.15 Contact: Matt Ranostay @@ -6,7 +6,7 @@ Description: Get the current distance in meters of storm (1km steps) 1000-40000 = distance in meters -What /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity +What: /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity Date: March 2014 KernelVersion: 3.15 Contact: Matt Ranostay diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss index 53d99edd1d75..eb449169c30b 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss @@ -1,66 +1,66 @@ -Where: /sys/bus/pci/devices//ccissX/cXdY/model +What: /sys/bus/pci/devices//ccissX/cXdY/model Date: March 2009 Kernel Version: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 0 model for logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/rev +What: /sys/bus/pci/devices//ccissX/cXdY/rev Date: March 2009 Kernel Version: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 0 revision for logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/unique_id +What: /sys/bus/pci/devices//ccissX/cXdY/unique_id Date: March 2009 Kernel Version: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 83 serial number for logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/vendor +What: /sys/bus/pci/devices//ccissX/cXdY/vendor Date: March 2009 Kernel Version: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 0 vendor for logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/block:cciss!cXdY +What: /sys/bus/pci/devices//ccissX/cXdY/block:cciss!cXdY Date: March 2009 Kernel Version: 2.6.30 Contact: iss_storagedev@hp.com Description: A symbolic link to /sys/block/cciss!cXdY -Where: /sys/bus/pci/devices//ccissX/rescan +What: /sys/bus/pci/devices//ccissX/rescan Date: August 2009 Kernel Version: 2.6.31 Contact: iss_storagedev@hp.com Description: Kicks of a rescan of the controller to discover logical drive topology changes. -Where: /sys/bus/pci/devices//ccissX/cXdY/lunid +What: /sys/bus/pci/devices//ccissX/cXdY/lunid Date: August 2009 Kernel Version: 2.6.31 Contact: iss_storagedev@hp.com Description: Displays the 8-byte LUN ID used to address logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/raid_level +What: /sys/bus/pci/devices//ccissX/cXdY/raid_level Date: August 2009 Kernel Version: 2.6.31 Contact: iss_storagedev@hp.com Description: Displays the RAID level of logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/usage_count +What: /sys/bus/pci/devices//ccissX/cXdY/usage_count Date: August 2009 Kernel Version: 2.6.31 Contact: iss_storagedev@hp.com Description: Displays the usage count (number of opens) of logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/resettable +What: /sys/bus/pci/devices//ccissX/resettable Date: February 2011 Kernel Version: 2.6.38 Contact: iss_storagedev@hp.com @@ -71,7 +71,7 @@ Description: Value of 1 indicates the controller can honor the reset_devices a dump device, as kdump requires resetting the device in order to work reliably. -Where: /sys/bus/pci/devices//ccissX/transport_mode +What: /sys/bus/pci/devices//ccissX/transport_mode Date: July 2011 Kernel Version: 3.0 Contact: iss_storagedev@hp.com diff --git a/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg b/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg index 70d00dfa443d..f6199b314196 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg +++ b/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg @@ -1,12 +1,12 @@ -Where: /sys/bus/usb/.../powered +What: /sys/bus/usb/.../powered Date: August 2008 Kernel Version: 2.6.26 Contact: Harrison Metzger Description: Controls whether the device's display will powered. A value of 0 is off and a non-zero value is on. -Where: /sys/bus/usb/.../mode_msb -Where: /sys/bus/usb/.../mode_lsb +What: /sys/bus/usb/.../mode_msb +What: /sys/bus/usb/.../mode_lsb Date: August 2008 Kernel Version: 2.6.26 Contact: Harrison Metzger @@ -16,7 +16,7 @@ Description: Controls the devices display mode. for an 8 character display the values are MSB 0x08; LSB 0xFF. -Where: /sys/bus/usb/.../textmode +What: /sys/bus/usb/.../textmode Date: August 2008 Kernel Version: 2.6.26 Contact: Harrison Metzger @@ -25,13 +25,13 @@ Description: Controls the way the device interprets its text buffer. hex: each character is between 0-15 ascii: each character is between '0'-'9' and 'A'-'F'. -Where: /sys/bus/usb/.../text +What: /sys/bus/usb/.../text Date: August 2008 Kernel Version: 2.6.26 Contact: Harrison Metzger Description: The text (or data) for the device to display -Where: /sys/bus/usb/.../decimals +What: /sys/bus/usb/.../decimals Date: August 2008 Kernel Version: 2.6.26 Contact: Harrison Metzger diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index bbbabffc682a..7970e3713e70 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl @@ -1,6 +1,6 @@ -Note: Attributes that are shared between devices are stored in the directory -pointed to by the symlink device/. -Example: The real path of the attribute /sys/class/cxl/afu0.0s/irqs_max is +Please note that attributes that are shared between devices are stored in +the directory pointed to by the symlink device/. +For example, the real path of the attribute /sys/class/cxl/afu0.0s/irqs_max is /sys/class/cxl/afu0.0s/device/irqs_max, i.e. /sys/class/cxl/afu0.0/irqs_max. diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index ee39acacf6f8..01196e19afca 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -47,7 +47,7 @@ Description: What: /sys/class/devfreq/.../trans_stat Date: October 2012 Contact: MyungJoo Ham -Descrtiption: +Description: This ABI shows the statistics of devfreq behavior on a specific device. It shows the time spent in each state and the number of transitions between states. diff --git a/Documentation/ABI/testing/sysfs-class-powercap b/Documentation/ABI/testing/sysfs-class-powercap index db3b3ff70d84..f333a0ccc29b 100644 --- a/Documentation/ABI/testing/sysfs-class-powercap +++ b/Documentation/ABI/testing/sysfs-class-powercap @@ -147,6 +147,6 @@ What: /sys/class/powercap/...//enabled Date: September 2013 KernelVersion: 3.13 Contact: linux-pm@vger.kernel.org -Description +Description: This allows to enable/disable power capping at power zone level. This applies to current power zone and its children. diff --git a/Documentation/ABI/testing/sysfs-kernel-fscaps b/Documentation/ABI/testing/sysfs-kernel-fscaps index 50a3033b5e15..bcff34665192 100644 --- a/Documentation/ABI/testing/sysfs-kernel-fscaps +++ b/Documentation/ABI/testing/sysfs-kernel-fscaps @@ -2,7 +2,7 @@ What: /sys/kernel/fscaps Date: February 2011 KernelVersion: 2.6.38 Contact: Ludwig Nussel -Description +Description: Shows whether file system capabilities are honored when executing a binary diff --git a/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo b/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo index 7bd81168e063..1f1087a5f075 100644 --- a/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo +++ b/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo @@ -4,7 +4,7 @@ KernelVersion: 2.6.24 Contact: Ken'ichi Ohmichi Kexec Mailing List Vivek Goyal -Description +Description: Shows physical address and size of vmcoreinfo ELF note. First value contains physical address of note in hex and second value contains the size of note in hex. This ELF From 745b2888a2afdb33055f62ba3b245b79e2462e65 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Jun 2019 23:04:08 -0300 Subject: [PATCH 035/102] ABI: sysfs-driver-hid: the "What" field doesn't parse fine The What: field on this ABI description use a different syntax than expected, causing it to not be properly parsed by script. Fix it. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-driver-hid | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-driver-hid b/Documentation/ABI/testing/sysfs-driver-hid index 48942cacb0bf..a59533410871 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid +++ b/Documentation/ABI/testing/sysfs-driver-hid @@ -1,6 +1,6 @@ -What: For USB devices : /sys/bus/usb/devices/-:./::./report_descriptor - For BT devices : /sys/class/bluetooth/hci/::./report_descriptor - Symlink : /sys/class/hidraw/hidraw/device/report_descriptor +What: /sys/bus/usb/devices/-:./::./report_descriptor +What: /sys/class/bluetooth/hci/::./report_descriptor +What: /sys/class/hidraw/hidraw/device/report_descriptor Date: Jan 2011 KernelVersion: 2.0.39 Contact: Alan Ott @@ -9,9 +9,9 @@ Description: When read, this file returns the device's raw binary HID This file cannot be written. Users: HIDAPI library (http://www.signal11.us/oss/hidapi) -What: For USB devices : /sys/bus/usb/devices/-:./::./country - For BT devices : /sys/class/bluetooth/hci/::./country - Symlink : /sys/class/hidraw/hidraw/device/country +What: /sys/bus/usb/devices/-:./::./country +What: /sys/class/bluetooth/hci/::./country +What: /sys/class/hidraw/hidraw/device/country Date: February 2015 KernelVersion: 3.19 Contact: Olivier Gay From d59f0ec7151e8f70ceaf58e2ddd057e3296cc2d7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Jun 2019 23:04:09 -0300 Subject: [PATCH 036/102] ABI: sysfs-class-uwb_rc: remove a duplicated incomplete entry There are two entries for /sys/class/uwb_rc/uwbN//BPST. The second one has a missing description. Get rid of it. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-class-uwb_rc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-uwb_rc b/Documentation/ABI/testing/sysfs-class-uwb_rc index 85f4875d16ac..a0578751c1e3 100644 --- a/Documentation/ABI/testing/sysfs-class-uwb_rc +++ b/Documentation/ABI/testing/sysfs-class-uwb_rc @@ -125,12 +125,6 @@ Description: The EUI-48 of this device in colon separated hex octets. -What: /sys/class/uwb_rc/uwbN//BPST -Date: July 2008 -KernelVersion: 2.6.27 -Contact: linux-usb@vger.kernel.org -Description: - What: /sys/class/uwb_rc/uwbN//IEs Date: July 2008 KernelVersion: 2.6.27 From 1107049034ac094dd66998ec91d59d8f8807c88a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Jun 2019 23:04:10 -0300 Subject: [PATCH 037/102] ABI: better identificate tables When parsing via script, it is important to know if the script should consider a description as a literal block that should be displayed as-is, or if the description can be considered as a normal text. Change descriptions to ensure that the preceding line of a table ends with a colon. That makes easy to identify the need of a literal block. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra | 2 +- .../ABI/testing/sysfs-class-backlight-driver-lm3533 | 6 +++--- Documentation/ABI/testing/sysfs-class-led-driver-lm3533 | 8 ++++---- Documentation/ABI/testing/sysfs-class-leds-gt683r | 4 ++-- Documentation/ABI/testing/sysfs-driver-hid-roccat-kone | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra index 16020b31ae64..5d41ebadf15e 100644 --- a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra +++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra @@ -5,7 +5,7 @@ Description: It is possible to switch the cpi setting of the mouse with the press of a button. When read, this file returns the raw number of the actual cpi setting reported by the mouse. This number has to be further - processed to receive the real dpi value. + processed to receive the real dpi value: VALUE DPI 1 400 diff --git a/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 b/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 index 77cf7ac949af..c0e0a9ae7b3d 100644 --- a/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 +++ b/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 @@ -4,7 +4,7 @@ KernelVersion: 3.5 Contact: Johan Hovold Description: Get the ALS output channel used as input in - ALS-current-control mode (0, 1), where + ALS-current-control mode (0, 1), where: 0 - out_current0 (backlight 0) 1 - out_current1 (backlight 1) @@ -28,7 +28,7 @@ Date: April 2012 KernelVersion: 3.5 Contact: Johan Hovold Description: - Set the brightness-mapping mode (0, 1), where + Set the brightness-mapping mode (0, 1), where: 0 - exponential mode 1 - linear mode @@ -38,7 +38,7 @@ Date: April 2012 KernelVersion: 3.5 Contact: Johan Hovold Description: - Set the PWM-input control mask (5 bits), where + Set the PWM-input control mask (5 bits), where: bit 5 - PWM-input enabled in Zone 4 bit 4 - PWM-input enabled in Zone 3 diff --git a/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 b/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 index 620ebb3b9baa..e4c89b261546 100644 --- a/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 +++ b/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 @@ -4,7 +4,7 @@ KernelVersion: 3.5 Contact: Johan Hovold Description: Set the ALS output channel to use as input in - ALS-current-control mode (1, 2), where + ALS-current-control mode (1, 2), where: 1 - out_current1 2 - out_current2 @@ -22,7 +22,7 @@ Date: April 2012 KernelVersion: 3.5 Contact: Johan Hovold Description: - Set the pattern generator fall and rise times (0..7), where + Set the pattern generator fall and rise times (0..7), where: 0 - 2048 us 1 - 262 ms @@ -45,7 +45,7 @@ Date: April 2012 KernelVersion: 3.5 Contact: Johan Hovold Description: - Set the brightness-mapping mode (0, 1), where + Set the brightness-mapping mode (0, 1), where: 0 - exponential mode 1 - linear mode @@ -55,7 +55,7 @@ Date: April 2012 KernelVersion: 3.5 Contact: Johan Hovold Description: - Set the PWM-input control mask (5 bits), where + Set the PWM-input control mask (5 bits), where: bit 5 - PWM-input enabled in Zone 4 bit 4 - PWM-input enabled in Zone 3 diff --git a/Documentation/ABI/testing/sysfs-class-leds-gt683r b/Documentation/ABI/testing/sysfs-class-leds-gt683r index e4fae6026e79..6adab27f646e 100644 --- a/Documentation/ABI/testing/sysfs-class-leds-gt683r +++ b/Documentation/ABI/testing/sysfs-class-leds-gt683r @@ -5,7 +5,7 @@ Contact: Janne Kanniainen Description: Set the mode of LEDs. You should notice that changing the mode of one LED will update the mode of its two sibling devices as - well. + well. Possible values are: 0 - normal 1 - audio @@ -13,4 +13,4 @@ Description: Normal: LEDs are fully on when enabled Audio: LEDs brightness depends on sound level - Breathing: LEDs brightness varies at human breathing rate \ No newline at end of file + Breathing: LEDs brightness varies at human breathing rate diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone index 3ca3971109bf..8f7982c70d72 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone @@ -5,7 +5,7 @@ Description: It is possible to switch the dpi setting of the mouse with the press of a button. When read, this file returns the raw number of the actual dpi setting reported by the mouse. This number has to be further - processed to receive the real dpi value. + processed to receive the real dpi value: VALUE DPI 1 800 From abf313b5a8b72302062dd407ed7e470d67d389bb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Jun 2019 14:52:15 -0300 Subject: [PATCH 038/102] ABI: sysfs-bus-pci-devices-aer_stats uses an invalid tag According with Documentation/ABI/, the right tag to describe an ABI symbol is "What:", and not "Where:". Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-bus-pci-devices-aer_stats | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats index 4b0318c99507..ff229d71961c 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats @@ -9,7 +9,7 @@ errors may be "seen" / reported by the link partner and not the problematic endpoint itself (which may report all counters as 0 as it never saw any problems). -Where: /sys/bus/pci/devices//aer_dev_correctable +What: /sys/bus/pci/devices//aer_dev_correctable Date: July 2018 Kernel Version: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com @@ -31,7 +31,7 @@ Header Log Overflow 0 TOTAL_ERR_COR 2 ------------------------------------------------------------------------- -Where: /sys/bus/pci/devices//aer_dev_fatal +What: /sys/bus/pci/devices//aer_dev_fatal Date: July 2018 Kernel Version: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com @@ -62,7 +62,7 @@ TLP Prefix Blocked Error 0 TOTAL_ERR_FATAL 0 ------------------------------------------------------------------------- -Where: /sys/bus/pci/devices//aer_dev_nonfatal +What: /sys/bus/pci/devices//aer_dev_nonfatal Date: July 2018 Kernel Version: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com @@ -103,19 +103,19 @@ collectors) that are AER capable. These indicate the number of error messages as device, so these counters include them and are thus cumulative of all the error messages on the PCI hierarchy originating at that root port. -Where: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_cor +What: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_cor Date: July 2018 Kernel Version: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: Total number of ERR_COR messages reported to rootport. -Where: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_fatal +What: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_fatal Date: July 2018 Kernel Version: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: Total number of ERR_FATAL messages reported to rootport. -Where: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_nonfatal +What: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_nonfatal Date: July 2018 Kernel Version: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com From 129fb4cb3b6a352a1ba3e9b4d2c41fbfa06f28a2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Jun 2019 14:52:16 -0300 Subject: [PATCH 039/102] ABI: Fix KernelVersion tags It is "KernelVersion:" and not "Kernel Version:". Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/pstore | 2 +- .../sysfs-bus-event_source-devices-format | 2 +- .../ABI/testing/sysfs-bus-i2c-devices-hm6352 | 6 ++--- .../testing/sysfs-bus-pci-devices-aer_stats | 12 +++++----- .../ABI/testing/sysfs-bus-pci-devices-cciss | 22 +++++++++---------- .../testing/sysfs-bus-usb-devices-usbsevseg | 10 ++++----- .../ABI/testing/sysfs-driver-altera-cvp | 2 +- Documentation/ABI/testing/sysfs-driver-ppi | 2 +- Documentation/ABI/testing/sysfs-driver-st | 2 +- Documentation/ABI/testing/sysfs-driver-wacom | 2 +- 10 files changed, 31 insertions(+), 31 deletions(-) diff --git a/Documentation/ABI/testing/pstore b/Documentation/ABI/testing/pstore index 8d6e48f4e8ef..d45209abdb1b 100644 --- a/Documentation/ABI/testing/pstore +++ b/Documentation/ABI/testing/pstore @@ -1,6 +1,6 @@ What: /sys/fs/pstore/... (or /dev/pstore/...) Date: March 2011 -Kernel Version: 2.6.39 +KernelVersion: 2.6.39 Contact: tony.luck@intel.com Description: Generic interface to platform dependent persistent storage. diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-format b/Documentation/ABI/testing/sysfs-bus-event_source-devices-format index b6f8748e0200..5bb793ec926c 100644 --- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-format +++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-format @@ -1,6 +1,6 @@ What: /sys/bus/event_source/devices//format Date: January 2012 -Kernel Version: 3.3 +KernelVersion: 3.3 Contact: Jiri Olsa Description: Attribute group to describe the magic bits that go into diff --git a/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 b/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 index 29bd447e50a0..4a251b7f11e4 100644 --- a/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 +++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 @@ -1,20 +1,20 @@ What: /sys/bus/i2c/devices/.../heading0_input Date: April 2010 -Kernel Version: 2.6.36? +KernelVersion: 2.6.36? Contact: alan.cox@intel.com Description: Reports the current heading from the compass as a floating point value in degrees. What: /sys/bus/i2c/devices/.../power_state Date: April 2010 -Kernel Version: 2.6.36? +KernelVersion: 2.6.36? Contact: alan.cox@intel.com Description: Sets the power state of the device. 0 sets the device into sleep mode, 1 wakes it up. What: /sys/bus/i2c/devices/.../calibration Date: April 2010 -Kernel Version: 2.6.36? +KernelVersion: 2.6.36? Contact: alan.cox@intel.com Description: Sets the calibration on or off (1 = on, 0 = off). See the chip data sheet. diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats index ff229d71961c..3c9a8c4a25eb 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats @@ -11,7 +11,7 @@ saw any problems). What: /sys/bus/pci/devices//aer_dev_correctable Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: List of correctable errors seen and reported by this PCI device using ERR_COR. Note that since multiple errors may @@ -33,7 +33,7 @@ TOTAL_ERR_COR 2 What: /sys/bus/pci/devices//aer_dev_fatal Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: List of uncorrectable fatal errors seen and reported by this PCI device using ERR_FATAL. Note that since multiple errors may @@ -64,7 +64,7 @@ TOTAL_ERR_FATAL 0 What: /sys/bus/pci/devices//aer_dev_nonfatal Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: List of uncorrectable nonfatal errors seen and reported by this PCI device using ERR_NONFATAL. Note that since multiple errors @@ -105,18 +105,18 @@ messages on the PCI hierarchy originating at that root port. What: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_cor Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: Total number of ERR_COR messages reported to rootport. What: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_fatal Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: Total number of ERR_FATAL messages reported to rootport. What: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_nonfatal Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: Total number of ERR_NONFATAL messages reported to rootport. diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss index eb449169c30b..92a94e1068c2 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss @@ -1,68 +1,68 @@ What: /sys/bus/pci/devices//ccissX/cXdY/model Date: March 2009 -Kernel Version: 2.6.30 +KernelVersion: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 0 model for logical drive Y of controller X. What: /sys/bus/pci/devices//ccissX/cXdY/rev Date: March 2009 -Kernel Version: 2.6.30 +KernelVersion: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 0 revision for logical drive Y of controller X. What: /sys/bus/pci/devices//ccissX/cXdY/unique_id Date: March 2009 -Kernel Version: 2.6.30 +KernelVersion: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 83 serial number for logical drive Y of controller X. What: /sys/bus/pci/devices//ccissX/cXdY/vendor Date: March 2009 -Kernel Version: 2.6.30 +KernelVersion: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 0 vendor for logical drive Y of controller X. What: /sys/bus/pci/devices//ccissX/cXdY/block:cciss!cXdY Date: March 2009 -Kernel Version: 2.6.30 +KernelVersion: 2.6.30 Contact: iss_storagedev@hp.com Description: A symbolic link to /sys/block/cciss!cXdY What: /sys/bus/pci/devices//ccissX/rescan Date: August 2009 -Kernel Version: 2.6.31 +KernelVersion: 2.6.31 Contact: iss_storagedev@hp.com Description: Kicks of a rescan of the controller to discover logical drive topology changes. What: /sys/bus/pci/devices//ccissX/cXdY/lunid Date: August 2009 -Kernel Version: 2.6.31 +KernelVersion: 2.6.31 Contact: iss_storagedev@hp.com Description: Displays the 8-byte LUN ID used to address logical drive Y of controller X. What: /sys/bus/pci/devices//ccissX/cXdY/raid_level Date: August 2009 -Kernel Version: 2.6.31 +KernelVersion: 2.6.31 Contact: iss_storagedev@hp.com Description: Displays the RAID level of logical drive Y of controller X. What: /sys/bus/pci/devices//ccissX/cXdY/usage_count Date: August 2009 -Kernel Version: 2.6.31 +KernelVersion: 2.6.31 Contact: iss_storagedev@hp.com Description: Displays the usage count (number of opens) of logical drive Y of controller X. What: /sys/bus/pci/devices//ccissX/resettable Date: February 2011 -Kernel Version: 2.6.38 +KernelVersion: 2.6.38 Contact: iss_storagedev@hp.com Description: Value of 1 indicates the controller can honor the reset_devices kernel parameter. Value of 0 indicates reset_devices cannot be @@ -73,7 +73,7 @@ Description: Value of 1 indicates the controller can honor the reset_devices What: /sys/bus/pci/devices//ccissX/transport_mode Date: July 2011 -Kernel Version: 3.0 +KernelVersion: 3.0 Contact: iss_storagedev@hp.com Description: Value of "simple" indicates that the controller has been placed in "simple mode". Value of "performant" indicates that the diff --git a/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg b/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg index f6199b314196..9ade80f81f96 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg +++ b/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg @@ -1,6 +1,6 @@ What: /sys/bus/usb/.../powered Date: August 2008 -Kernel Version: 2.6.26 +KernelVersion: 2.6.26 Contact: Harrison Metzger Description: Controls whether the device's display will powered. A value of 0 is off and a non-zero value is on. @@ -8,7 +8,7 @@ Description: Controls whether the device's display will powered. What: /sys/bus/usb/.../mode_msb What: /sys/bus/usb/.../mode_lsb Date: August 2008 -Kernel Version: 2.6.26 +KernelVersion: 2.6.26 Contact: Harrison Metzger Description: Controls the devices display mode. For a 6 character display the values are @@ -18,7 +18,7 @@ Description: Controls the devices display mode. What: /sys/bus/usb/.../textmode Date: August 2008 -Kernel Version: 2.6.26 +KernelVersion: 2.6.26 Contact: Harrison Metzger Description: Controls the way the device interprets its text buffer. raw: each character controls its segment manually @@ -27,13 +27,13 @@ Description: Controls the way the device interprets its text buffer. What: /sys/bus/usb/.../text Date: August 2008 -Kernel Version: 2.6.26 +KernelVersion: 2.6.26 Contact: Harrison Metzger Description: The text (or data) for the device to display What: /sys/bus/usb/.../decimals Date: August 2008 -Kernel Version: 2.6.26 +KernelVersion: 2.6.26 Contact: Harrison Metzger Description: Controls the decimal places on the device. To set the nth decimal place, give this field diff --git a/Documentation/ABI/testing/sysfs-driver-altera-cvp b/Documentation/ABI/testing/sysfs-driver-altera-cvp index 8cde64a71edb..fbd8078fd7ad 100644 --- a/Documentation/ABI/testing/sysfs-driver-altera-cvp +++ b/Documentation/ABI/testing/sysfs-driver-altera-cvp @@ -1,6 +1,6 @@ What: /sys/bus/pci/drivers/altera-cvp/chkcfg Date: May 2017 -Kernel Version: 4.13 +KernelVersion: 4.13 Contact: Anatolij Gustschin Description: Contains either 1 or 0 and controls if configuration diff --git a/Documentation/ABI/testing/sysfs-driver-ppi b/Documentation/ABI/testing/sysfs-driver-ppi index 9921ef285899..1a56fc507689 100644 --- a/Documentation/ABI/testing/sysfs-driver-ppi +++ b/Documentation/ABI/testing/sysfs-driver-ppi @@ -1,6 +1,6 @@ What: /sys/class/tpm/tpmX/ppi/ Date: August 2012 -Kernel Version: 3.6 +KernelVersion: 3.6 Contact: xiaoyan.zhang@intel.com Description: This folder includes the attributes related with PPI (Physical diff --git a/Documentation/ABI/testing/sysfs-driver-st b/Documentation/ABI/testing/sysfs-driver-st index ba5d77008a85..88cab66fd77f 100644 --- a/Documentation/ABI/testing/sysfs-driver-st +++ b/Documentation/ABI/testing/sysfs-driver-st @@ -1,6 +1,6 @@ What: /sys/bus/scsi/drivers/st/debug_flag Date: October 2015 -Kernel Version: ?.? +KernelVersion: ?.? Contact: shane.seymour@hpe.com Description: This file allows you to turn debug output from the st driver diff --git a/Documentation/ABI/testing/sysfs-driver-wacom b/Documentation/ABI/testing/sysfs-driver-wacom index 2aa5503ee200..afc48fc163b5 100644 --- a/Documentation/ABI/testing/sysfs-driver-wacom +++ b/Documentation/ABI/testing/sysfs-driver-wacom @@ -1,6 +1,6 @@ What: /sys/bus/hid/devices/::./speed Date: April 2010 -Kernel Version: 2.6.35 +KernelVersion: 2.6.35 Contact: linux-bluetooth@vger.kernel.org Description: The /sys/bus/hid/devices/::./speed file From 5669245b57df8a0edae475e06d1b851729a21457 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 17 Jun 2019 14:55:02 +0200 Subject: [PATCH 040/102] ARM: omap1: remove unused variable The cleanup of the debugfs functions left one variable behind that should now be removed as well: arch/arm/mach-omap1/clock.c:1008:6: error: unused variable 'err' [-Werror,-Wunused-variable] Fixes: d5ddd5a51726 ("arm: omap1: no need to check return value of debugfs_create functions") Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap1/clock.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 3d7ab2bcf46c..a5a50efc8e17 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -1005,7 +1005,6 @@ static void clk_debugfs_register_one(struct clk *c) static void clk_debugfs_register(struct clk *c) { - int err; struct clk *pa = c->parent; if (pa && !pa->dent) From 2472d64af2d3561954e2f05365a67692bb852f2a Mon Sep 17 00:00:00 2001 From: Sven Van Asbroeck Date: Mon, 17 Jun 2019 14:23:54 -0400 Subject: [PATCH 041/102] firmware: improve LSM/IMA security behaviour The firmware loader queries if LSM/IMA permits it to load firmware via the sysfs fallback. Unfortunately, the code does the opposite: it expressly permits sysfs fw loading if security_kernel_load_data( LOADING_FIRMWARE) returns -EACCES. This happens because a zero-on-success return value is cast to a bool that's true on success. Fix the return value handling so we get the correct behaviour. Fixes: 6e852651f28e ("firmware: add call to LSM hook before firmware sysfs fallback") Cc: Stable Cc: Mimi Zohar Cc: Kees Cook To: Luis Chamberlain Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: linux-kernel@vger.kernel.org Signed-off-by: Sven Van Asbroeck Reviewed-by: Mimi Zohar Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/fallback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index b5cd96fd0e77..29becea1910d 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -659,7 +659,7 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags) /* Also permit LSMs and IMA to fail firmware sysfs fallback */ ret = security_kernel_load_data(LOADING_FIRMWARE); if (ret < 0) - return ret; + return false; return fw_force_sysfs_fallback(opt_flags); } From 3aa6980139d19542d9204387fadadd3861e433ec Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 17 Jun 2019 16:41:22 +0200 Subject: [PATCH 042/102] tools/firmware: Add missing newline at end of file "git diff" says: \ No newline at end of file after modifying the file. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- tools/firmware/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/firmware/Makefile b/tools/firmware/Makefile index d329825aa31b..cfb297e6ef5a 100644 --- a/tools/firmware/Makefile +++ b/tools/firmware/Makefile @@ -10,4 +10,4 @@ all: ihex2fw clean: $(RM) ihex2fw -.PHONY: all clean \ No newline at end of file +.PHONY: all clean From 5342e7093ff298d9cbd40f9342b607adb02b2dd0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Jun 2019 14:26:24 +0200 Subject: [PATCH 043/102] firmware: Factor out the paged buffer handling code This is merely a preparation for the upcoming compressed firmware support and no functional changes. It moves the code to handle the paged buffer allocation and mapping out of fallback.c into the main code, so that they can be used commonly. Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/fallback.c | 61 +++---------------------- drivers/base/firmware_loader/firmware.h | 4 ++ drivers/base/firmware_loader/main.c | 52 +++++++++++++++++++++ 3 files changed, 63 insertions(+), 54 deletions(-) diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index 29becea1910d..62ee90b4db56 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -219,25 +219,6 @@ static ssize_t firmware_loading_show(struct device *dev, return sprintf(buf, "%d\n", loading); } -/* one pages buffer should be mapped/unmapped only once */ -static int map_fw_priv_pages(struct fw_priv *fw_priv) -{ - if (!fw_priv->pages) - return 0; - - vunmap(fw_priv->data); - fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0, - PAGE_KERNEL_RO); - if (!fw_priv->data) - return -ENOMEM; - - /* page table is no longer needed after mapping, let's free */ - kvfree(fw_priv->pages); - fw_priv->pages = NULL; - - return 0; -} - /** * firmware_loading_store() - set value in the 'loading' control file * @dev: device pointer @@ -283,7 +264,7 @@ static ssize_t firmware_loading_store(struct device *dev, * see the mapped 'buf->data' once the loading * is completed. * */ - rc = map_fw_priv_pages(fw_priv); + rc = fw_map_paged_buf(fw_priv); if (rc) dev_err(dev, "%s: map pages failed\n", __func__); @@ -388,41 +369,13 @@ out: static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size) { - struct fw_priv *fw_priv= fw_sysfs->fw_priv; - int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT; + int err; - /* If the array of pages is too small, grow it... */ - if (fw_priv->page_array_size < pages_needed) { - int new_array_size = max(pages_needed, - fw_priv->page_array_size * 2); - struct page **new_pages; - - new_pages = kvmalloc_array(new_array_size, sizeof(void *), - GFP_KERNEL); - if (!new_pages) { - fw_load_abort(fw_sysfs); - return -ENOMEM; - } - memcpy(new_pages, fw_priv->pages, - fw_priv->page_array_size * sizeof(void *)); - memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * - (new_array_size - fw_priv->page_array_size)); - kvfree(fw_priv->pages); - fw_priv->pages = new_pages; - fw_priv->page_array_size = new_array_size; - } - - while (fw_priv->nr_pages < pages_needed) { - fw_priv->pages[fw_priv->nr_pages] = - alloc_page(GFP_KERNEL | __GFP_HIGHMEM); - - if (!fw_priv->pages[fw_priv->nr_pages]) { - fw_load_abort(fw_sysfs); - return -ENOMEM; - } - fw_priv->nr_pages++; - } - return 0; + err = fw_grow_paged_buf(fw_sysfs->fw_priv, + PAGE_ALIGN(min_size) >> PAGE_SHIFT); + if (err) + fw_load_abort(fw_sysfs); + return err; } /** diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h index d20d4e7f9e71..35f4e58b2d98 100644 --- a/drivers/base/firmware_loader/firmware.h +++ b/drivers/base/firmware_loader/firmware.h @@ -135,8 +135,12 @@ int assign_fw(struct firmware *fw, struct device *device, #ifdef CONFIG_FW_LOADER_USER_HELPER void fw_free_paged_buf(struct fw_priv *fw_priv); +int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed); +int fw_map_paged_buf(struct fw_priv *fw_priv); #else static inline void fw_free_paged_buf(struct fw_priv *fw_priv) {} +int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed) { return -ENXIO; } +int fw_map_paged_buf(struct fw_priv *fw_priv) { return -ENXIO; } #endif #endif /* __FIRMWARE_LOADER_H */ diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 2e74a1b73dae..7e12732f4705 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -281,6 +281,58 @@ void fw_free_paged_buf(struct fw_priv *fw_priv) fw_priv->page_array_size = 0; fw_priv->nr_pages = 0; } + +int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed) +{ + /* If the array of pages is too small, grow it */ + if (fw_priv->page_array_size < pages_needed) { + int new_array_size = max(pages_needed, + fw_priv->page_array_size * 2); + struct page **new_pages; + + new_pages = kvmalloc_array(new_array_size, sizeof(void *), + GFP_KERNEL); + if (!new_pages) + return -ENOMEM; + memcpy(new_pages, fw_priv->pages, + fw_priv->page_array_size * sizeof(void *)); + memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * + (new_array_size - fw_priv->page_array_size)); + kvfree(fw_priv->pages); + fw_priv->pages = new_pages; + fw_priv->page_array_size = new_array_size; + } + + while (fw_priv->nr_pages < pages_needed) { + fw_priv->pages[fw_priv->nr_pages] = + alloc_page(GFP_KERNEL | __GFP_HIGHMEM); + + if (!fw_priv->pages[fw_priv->nr_pages]) + return -ENOMEM; + fw_priv->nr_pages++; + } + + return 0; +} + +int fw_map_paged_buf(struct fw_priv *fw_priv) +{ + /* one pages buffer should be mapped/unmapped only once */ + if (!fw_priv->pages) + return 0; + + vunmap(fw_priv->data); + fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0, + PAGE_KERNEL_RO); + if (!fw_priv->data) + return -ENOMEM; + + /* page table is no longer needed after mapping, let's free */ + kvfree(fw_priv->pages); + fw_priv->pages = NULL; + + return 0; +} #endif /* direct firmware loading support */ From 82fd7a8142a10b8eb41313074b3859d82c0857dc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Jun 2019 14:26:25 +0200 Subject: [PATCH 044/102] firmware: Add support for loading compressed files This patch adds the support for loading compressed firmware files. The primary motivation is to reduce the storage size; e.g. currently the files in /lib/firmware on my machine counts up to 419MB, while they can be reduced to 130MB by file compression. The patch introduces a new kconfig option CONFIG_FW_LOADER_COMPRESS. Even with this option set, the firmware loader still tries to load the original firmware file as-is at first, but then falls back to the file with ".xz" extension when it's not found, and the decompressed file content is returned to the caller of request_firmware(). So, no change is needed for the rest. Currently only XZ format is supported. A caveat is that the kernel XZ helper code supports only CRC32 (or none) integrity check type, so you'll have to compress the files via xz -C crc32 option. Since we can't determine the expanded size immediately from an XZ file, the patch re-uses the paged buffer that was used for the user-mode fallback; it puts the decompressed content page, which are vmapped at the end. The paged buffer code is conditionally built with a new Kconfig that is selected automatically. Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/Kconfig | 18 +++ drivers/base/firmware_loader/firmware.h | 8 +- drivers/base/firmware_loader/main.c | 147 ++++++++++++++++++++++-- 3 files changed, 161 insertions(+), 12 deletions(-) diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig index 38f2da6f5c2b..3f9e274e2ed3 100644 --- a/drivers/base/firmware_loader/Kconfig +++ b/drivers/base/firmware_loader/Kconfig @@ -26,6 +26,9 @@ config FW_LOADER if FW_LOADER +config FW_LOADER_PAGED_BUF + bool + config EXTRA_FIRMWARE string "Build named firmware blobs into the kernel binary" help @@ -67,6 +70,7 @@ config EXTRA_FIRMWARE_DIR config FW_LOADER_USER_HELPER bool "Enable the firmware sysfs fallback mechanism" + select FW_LOADER_PAGED_BUF help This option enables a sysfs loading facility to enable firmware loading to the kernel through userspace as a fallback mechanism @@ -151,5 +155,19 @@ config FW_LOADER_USER_HELPER_FALLBACK If you are unsure about this, say N here. +config FW_LOADER_COMPRESS + bool "Enable compressed firmware support" + select FW_LOADER_PAGED_BUF + select XZ_DEC + help + This option enables the support for loading compressed firmware + files. The caller of firmware API receives the decompressed file + content. The compressed file is loaded as a fallback, only after + loading the raw file failed at first. + + Currently only XZ-compressed files are supported, and they have to + be compressed with either none or crc32 integrity check type (pass + "-C crc32" option to xz command). + endif # FW_LOADER endmenu diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h index 35f4e58b2d98..7048a41973ed 100644 --- a/drivers/base/firmware_loader/firmware.h +++ b/drivers/base/firmware_loader/firmware.h @@ -64,12 +64,14 @@ struct fw_priv { void *data; size_t size; size_t allocated_size; -#ifdef CONFIG_FW_LOADER_USER_HELPER +#ifdef CONFIG_FW_LOADER_PAGED_BUF bool is_paged_buf; - bool need_uevent; struct page **pages; int nr_pages; int page_array_size; +#endif +#ifdef CONFIG_FW_LOADER_USER_HELPER + bool need_uevent; struct list_head pending_list; #endif const char *fw_name; @@ -133,7 +135,7 @@ static inline void fw_state_done(struct fw_priv *fw_priv) int assign_fw(struct firmware *fw, struct device *device, enum fw_opt opt_flags); -#ifdef CONFIG_FW_LOADER_USER_HELPER +#ifdef CONFIG_FW_LOADER_PAGED_BUF void fw_free_paged_buf(struct fw_priv *fw_priv); int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed); int fw_map_paged_buf(struct fw_priv *fw_priv); diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 7e12732f4705..bf44c79beae9 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -266,7 +267,7 @@ static void free_fw_priv(struct fw_priv *fw_priv) spin_unlock(&fwc->lock); } -#ifdef CONFIG_FW_LOADER_USER_HELPER +#ifdef CONFIG_FW_LOADER_PAGED_BUF void fw_free_paged_buf(struct fw_priv *fw_priv) { int i; @@ -335,6 +336,105 @@ int fw_map_paged_buf(struct fw_priv *fw_priv) } #endif +/* + * XZ-compressed firmware support + */ +#ifdef CONFIG_FW_LOADER_COMPRESS +/* show an error and return the standard error code */ +static int fw_decompress_xz_error(struct device *dev, enum xz_ret xz_ret) +{ + if (xz_ret != XZ_STREAM_END) { + dev_warn(dev, "xz decompression failed (xz_ret=%d)\n", xz_ret); + return xz_ret == XZ_MEM_ERROR ? -ENOMEM : -EINVAL; + } + return 0; +} + +/* single-shot decompression onto the pre-allocated buffer */ +static int fw_decompress_xz_single(struct device *dev, struct fw_priv *fw_priv, + size_t in_size, const void *in_buffer) +{ + struct xz_dec *xz_dec; + struct xz_buf xz_buf; + enum xz_ret xz_ret; + + xz_dec = xz_dec_init(XZ_SINGLE, (u32)-1); + if (!xz_dec) + return -ENOMEM; + + xz_buf.in_size = in_size; + xz_buf.in = in_buffer; + xz_buf.in_pos = 0; + xz_buf.out_size = fw_priv->allocated_size; + xz_buf.out = fw_priv->data; + xz_buf.out_pos = 0; + + xz_ret = xz_dec_run(xz_dec, &xz_buf); + xz_dec_end(xz_dec); + + fw_priv->size = xz_buf.out_pos; + return fw_decompress_xz_error(dev, xz_ret); +} + +/* decompression on paged buffer and map it */ +static int fw_decompress_xz_pages(struct device *dev, struct fw_priv *fw_priv, + size_t in_size, const void *in_buffer) +{ + struct xz_dec *xz_dec; + struct xz_buf xz_buf; + enum xz_ret xz_ret; + struct page *page; + int err = 0; + + xz_dec = xz_dec_init(XZ_DYNALLOC, (u32)-1); + if (!xz_dec) + return -ENOMEM; + + xz_buf.in_size = in_size; + xz_buf.in = in_buffer; + xz_buf.in_pos = 0; + + fw_priv->is_paged_buf = true; + fw_priv->size = 0; + do { + if (fw_grow_paged_buf(fw_priv, fw_priv->nr_pages + 1)) { + err = -ENOMEM; + goto out; + } + + /* decompress onto the new allocated page */ + page = fw_priv->pages[fw_priv->nr_pages - 1]; + xz_buf.out = kmap(page); + xz_buf.out_pos = 0; + xz_buf.out_size = PAGE_SIZE; + xz_ret = xz_dec_run(xz_dec, &xz_buf); + kunmap(page); + fw_priv->size += xz_buf.out_pos; + /* partial decompression means either end or error */ + if (xz_buf.out_pos != PAGE_SIZE) + break; + } while (xz_ret == XZ_OK); + + err = fw_decompress_xz_error(dev, xz_ret); + if (!err) + err = fw_map_paged_buf(fw_priv); + + out: + xz_dec_end(xz_dec); + return err; +} + +static int fw_decompress_xz(struct device *dev, struct fw_priv *fw_priv, + size_t in_size, const void *in_buffer) +{ + /* if the buffer is pre-allocated, we can perform in single-shot mode */ + if (fw_priv->data) + return fw_decompress_xz_single(dev, fw_priv, in_size, in_buffer); + else + return fw_decompress_xz_pages(dev, fw_priv, in_size, in_buffer); +} +#endif /* CONFIG_FW_LOADER_COMPRESS */ + /* direct firmware loading support */ static char fw_path_para[256]; static const char * const fw_path[] = { @@ -354,7 +454,12 @@ module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); static int -fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) +fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv, + const char *suffix, + int (*decompress)(struct device *dev, + struct fw_priv *fw_priv, + size_t in_size, + const void *in_buffer)) { loff_t size; int i, len; @@ -362,9 +467,11 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) char *path; enum kernel_read_file_id id = READING_FIRMWARE; size_t msize = INT_MAX; + void *buffer = NULL; /* Already populated data member means we're loading into a buffer */ - if (fw_priv->data) { + if (!decompress && fw_priv->data) { + buffer = fw_priv->data; id = READING_FIRMWARE_PREALLOC_BUFFER; msize = fw_priv->allocated_size; } @@ -378,15 +485,15 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) if (!fw_path[i][0]) continue; - len = snprintf(path, PATH_MAX, "%s/%s", - fw_path[i], fw_priv->fw_name); + len = snprintf(path, PATH_MAX, "%s/%s%s", + fw_path[i], fw_priv->fw_name, suffix); if (len >= PATH_MAX) { rc = -ENAMETOOLONG; break; } fw_priv->size = 0; - rc = kernel_read_file_from_path(path, &fw_priv->data, &size, + rc = kernel_read_file_from_path(path, &buffer, &size, msize, id); if (rc) { if (rc != -ENOENT) @@ -397,8 +504,24 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) path); continue; } - dev_dbg(device, "direct-loading %s\n", fw_priv->fw_name); - fw_priv->size = size; + if (decompress) { + dev_dbg(device, "f/w decompressing %s\n", + fw_priv->fw_name); + rc = decompress(device, fw_priv, size, buffer); + /* discard the superfluous original content */ + vfree(buffer); + buffer = NULL; + if (rc) { + fw_free_paged_buf(fw_priv); + continue; + } + } else { + dev_dbg(device, "direct-loading %s\n", + fw_priv->fw_name); + if (!fw_priv->data) + fw_priv->data = buffer; + fw_priv->size = size; + } fw_state_done(fw_priv); break; } @@ -645,7 +768,13 @@ _request_firmware(const struct firmware **firmware_p, const char *name, if (ret <= 0) /* error or already assigned */ goto out; - ret = fw_get_filesystem_firmware(device, fw->priv); + ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL); +#ifdef CONFIG_FW_LOADER_COMPRESS + if (ret == -ENOENT) + ret = fw_get_filesystem_firmware(device, fw->priv, ".xz", + fw_decompress_xz); +#endif + if (ret) { if (!(opt_flags & FW_OPT_NO_WARN)) dev_warn(device, From 108ae07c50363d0768a4c2bb7454a717fd36af52 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Jun 2019 14:26:26 +0200 Subject: [PATCH 045/102] selftests: firmware: Add compressed firmware tests This patch adds the test cases for checking compressed firmware load. Two more cases are added to fw_filesystem.sh: - Both a plain file and an xz file are present, and load the former - Only an xz file is present, and load without '.xz' suffix The tests are enabled only when CONFIG_FW_LOADER_COMPRESS is enabled and xz program is installed. Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- .../selftests/firmware/fw_filesystem.sh | 73 ++++++++++++++++--- tools/testing/selftests/firmware/fw_lib.sh | 7 ++ .../selftests/firmware/fw_run_tests.sh | 1 + 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh index a4320c4b44dc..f901076aa2ea 100755 --- a/tools/testing/selftests/firmware/fw_filesystem.sh +++ b/tools/testing/selftests/firmware/fw_filesystem.sh @@ -153,13 +153,18 @@ config_set_read_fw_idx() read_firmwares() { + if [ "$1" = "xzonly" ]; then + fwfile="${FW}-orig" + else + fwfile="$FW" + fi for i in $(seq 0 3); do config_set_read_fw_idx $i # Verify the contents are what we expect. # -Z required for now -- check for yourself, md5sum # on $FW and DIR/read_firmware will yield the same. Even # cmp agrees, so something is off. - if ! diff -q -Z "$FW" $DIR/read_firmware 2>/dev/null ; then + if ! diff -q -Z "$fwfile" $DIR/read_firmware 2>/dev/null ; then echo "request #$i: firmware was not loaded" >&2 exit 1 fi @@ -246,17 +251,17 @@ test_request_firmware_nowait_custom_nofile() test_batched_request_firmware() { - echo -n "Batched request_firmware() try #$1: " + echo -n "Batched request_firmware() $2 try #$1: " config_reset config_trigger_sync - read_firmwares + read_firmwares $2 release_all_firmware echo "OK" } test_batched_request_firmware_direct() { - echo -n "Batched request_firmware_direct() try #$1: " + echo -n "Batched request_firmware_direct() $2 try #$1: " config_reset config_set_sync_direct config_trigger_sync @@ -266,7 +271,7 @@ test_batched_request_firmware_direct() test_request_firmware_nowait_uevent() { - echo -n "Batched request_firmware_nowait(uevent=true) try #$1: " + echo -n "Batched request_firmware_nowait(uevent=true) $2 try #$1: " config_reset config_trigger_async release_all_firmware @@ -275,11 +280,16 @@ test_request_firmware_nowait_uevent() test_request_firmware_nowait_custom() { - echo -n "Batched request_firmware_nowait(uevent=false) try #$1: " + echo -n "Batched request_firmware_nowait(uevent=false) $2 try #$1: " config_reset config_unset_uevent RANDOM_FILE_PATH=$(setup_random_file) RANDOM_FILE="$(basename $RANDOM_FILE_PATH)" + if [ "$2" = "both" ]; then + xz -9 -C crc32 -k $RANDOM_FILE_PATH + elif [ "$2" = "xzonly" ]; then + xz -9 -C crc32 $RANDOM_FILE_PATH + fi config_set_name $RANDOM_FILE config_trigger_async release_all_firmware @@ -294,19 +304,19 @@ test_config_present echo echo "Testing with the file present..." for i in $(seq 1 5); do - test_batched_request_firmware $i + test_batched_request_firmware $i normal done for i in $(seq 1 5); do - test_batched_request_firmware_direct $i + test_batched_request_firmware_direct $i normal done for i in $(seq 1 5); do - test_request_firmware_nowait_uevent $i + test_request_firmware_nowait_uevent $i normal done for i in $(seq 1 5); do - test_request_firmware_nowait_custom $i + test_request_firmware_nowait_custom $i normal done # Test for file not found, errors are expected, the failure would be @@ -329,4 +339,47 @@ for i in $(seq 1 5); do test_request_firmware_nowait_custom_nofile $i done +test "$HAS_FW_LOADER_COMPRESS" != "yes" && exit 0 + +# test with both files present +xz -9 -C crc32 -k $FW +config_set_name $NAME +echo +echo "Testing with both plain and xz files present..." +for i in $(seq 1 5); do + test_batched_request_firmware $i both +done + +for i in $(seq 1 5); do + test_batched_request_firmware_direct $i both +done + +for i in $(seq 1 5); do + test_request_firmware_nowait_uevent $i both +done + +for i in $(seq 1 5); do + test_request_firmware_nowait_custom $i both +done + +# test with only xz file present +mv "$FW" "${FW}-orig" +echo +echo "Testing with only xz file present..." +for i in $(seq 1 5); do + test_batched_request_firmware $i xzonly +done + +for i in $(seq 1 5); do + test_batched_request_firmware_direct $i xzonly +done + +for i in $(seq 1 5); do + test_request_firmware_nowait_uevent $i xzonly +done + +for i in $(seq 1 5); do + test_request_firmware_nowait_custom $i xzonly +done + exit 0 diff --git a/tools/testing/selftests/firmware/fw_lib.sh b/tools/testing/selftests/firmware/fw_lib.sh index 1cbb12e284a6..f236cc295450 100755 --- a/tools/testing/selftests/firmware/fw_lib.sh +++ b/tools/testing/selftests/firmware/fw_lib.sh @@ -50,6 +50,7 @@ check_setup() { HAS_FW_LOADER_USER_HELPER="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER=y)" HAS_FW_LOADER_USER_HELPER_FALLBACK="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y)" + HAS_FW_LOADER_COMPRESS="$(kconfig_has CONFIG_FW_LOADER_COMPRESS=y)" PROC_FW_IGNORE_SYSFS_FALLBACK="0" PROC_FW_FORCE_SYSFS_FALLBACK="0" @@ -84,6 +85,12 @@ check_setup() fi OLD_FWPATH="$(cat /sys/module/firmware_class/parameters/path)" + + if [ "$HAS_FW_LOADER_COMPRESS" = "yes" ]; then + if ! which xz 2> /dev/null > /dev/null; then + HAS_FW_LOADER_COMPRESS="" + fi + fi } verify_reqs() diff --git a/tools/testing/selftests/firmware/fw_run_tests.sh b/tools/testing/selftests/firmware/fw_run_tests.sh index cffdd4eb0a57..8e14d555c197 100755 --- a/tools/testing/selftests/firmware/fw_run_tests.sh +++ b/tools/testing/selftests/firmware/fw_run_tests.sh @@ -11,6 +11,7 @@ source $TEST_DIR/fw_lib.sh export HAS_FW_LOADER_USER_HELPER="" export HAS_FW_LOADER_USER_HELPER_FALLBACK="" +export HAS_FW_LOADER_COMPRESS="" run_tests() { From 72c9f26b583c54e89de386e0eb63398c07d95cfa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 13 Jun 2019 20:38:30 +0200 Subject: [PATCH 046/102] thermal: intel: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Zhang Rui Cc: Eduardo Valentin Cc: linux-pm@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Reviewed-by: Daniel Lezcano Signed-off-by: Greg Kroah-Hartman --- drivers/thermal/intel/x86_pkg_temp_thermal.c | 25 ++++---------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index 1ef937d799e4..f0441ac25555 100644 --- a/drivers/thermal/intel/x86_pkg_temp_thermal.c +++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c @@ -87,29 +87,14 @@ static struct dentry *debugfs; static unsigned int pkg_interrupt_cnt; static unsigned int pkg_work_cnt; -static int pkg_temp_debugfs_init(void) +static void pkg_temp_debugfs_init(void) { - struct dentry *d; - debugfs = debugfs_create_dir("pkg_temp_thermal", NULL); - if (!debugfs) - return -ENOENT; - d = debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs, - &pkg_interrupt_cnt); - if (!d) - goto err_out; - - d = debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs, - &pkg_work_cnt); - if (!d) - goto err_out; - - return 0; - -err_out: - debugfs_remove_recursive(debugfs); - return -ENOENT; + debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs, + &pkg_interrupt_cnt); + debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs, + &pkg_work_cnt); } /* From c008c6754c109fed660221e4d8b8194bbcd003ed Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 13 Jun 2019 20:38:10 +0200 Subject: [PATCH 047/102] thermal: intel_powerclamp: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Zhang Rui Cc: Eduardo Valentin Cc: Daniel Lezcano Cc: Finn Thain Cc: linux-pm@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Reviewed-by: Daniel Lezcano Signed-off-by: Greg Kroah-Hartman --- drivers/thermal/intel/intel_powerclamp.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c index ac7256b5f020..39c6b589f2ed 100644 --- a/drivers/thermal/intel/intel_powerclamp.c +++ b/drivers/thermal/intel/intel_powerclamp.c @@ -713,17 +713,9 @@ DEFINE_SHOW_ATTRIBUTE(powerclamp_debug); static inline void powerclamp_create_debug_files(void) { debug_dir = debugfs_create_dir("intel_powerclamp", NULL); - if (!debug_dir) - return; - if (!debugfs_create_file("powerclamp_calib", S_IRUGO, debug_dir, - cal_data, &powerclamp_debug_fops)) - goto file_error; - - return; - -file_error: - debugfs_remove_recursive(debug_dir); + debugfs_create_file("powerclamp_calib", S_IRUGO, debug_dir, cal_data, + &powerclamp_debug_fops); } static enum cpuhp_state hp_state; From f9d5de4064e57017b75cfed9c7cfdff73bb52681 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 13 Jun 2019 20:37:53 +0200 Subject: [PATCH 048/102] thermal: tegra: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Zhang Rui Cc: Eduardo Valentin Cc: Daniel Lezcano Cc: Thierry Reding Cc: Jonathan Hunter Cc: Wei Ni Cc: Yangtao Li Cc: linux-pm@vger.kernel.org Acked-by: Thierry Reding Signed-off-by: Greg Kroah-Hartman --- drivers/thermal/tegra/soctherm.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index fcf70a3728b6..43941eb734eb 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -1485,23 +1485,13 @@ DEFINE_SHOW_ATTRIBUTE(regs); static void soctherm_debug_init(struct platform_device *pdev) { struct tegra_soctherm *tegra = platform_get_drvdata(pdev); - struct dentry *root, *file; + struct dentry *root; root = debugfs_create_dir("soctherm", NULL); - if (!root) { - dev_err(&pdev->dev, "failed to create debugfs directory\n"); - return; - } tegra->debugfs_dir = root; - file = debugfs_create_file("reg_contents", 0644, root, - pdev, ®s_fops); - if (!file) { - dev_err(&pdev->dev, "failed to create debugfs file\n"); - debugfs_remove_recursive(tegra->debugfs_dir); - tegra->debugfs_dir = NULL; - } + debugfs_create_file("reg_contents", 0644, root, pdev, ®s_fops); } #else static inline void soctherm_debug_init(struct platform_device *pdev) {} From 4a14abc4bbe58aa465f0f5599bf4c612cfeb367f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 17:54:18 +0200 Subject: [PATCH 049/102] cxl: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Because there's no need to check, also make the return value of the local debugfs_create_io_x64() call void, as no one ever did anything with the return value (as they did not need to.) And make the cxl_debugfs_* calls return void as no one was even checking their return value at all. Cc: linuxppc-dev@lists.ozlabs.org Acked-by: Andrew Donnellan Reviewed-by: Frederic Barrat Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/misc/cxl/cxl.h | 15 ++++++--------- drivers/misc/cxl/debugfs.c | 36 +++++++++++------------------------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index a73c9e669d78..5dc0f6093f9d 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -908,11 +908,11 @@ void cxl_update_dedicated_ivtes_psl8(struct cxl_context *ctx); #ifdef CONFIG_DEBUG_FS -int cxl_debugfs_init(void); +void cxl_debugfs_init(void); void cxl_debugfs_exit(void); -int cxl_debugfs_adapter_add(struct cxl *adapter); +void cxl_debugfs_adapter_add(struct cxl *adapter); void cxl_debugfs_adapter_remove(struct cxl *adapter); -int cxl_debugfs_afu_add(struct cxl_afu *afu); +void cxl_debugfs_afu_add(struct cxl_afu *afu); void cxl_debugfs_afu_remove(struct cxl_afu *afu); void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir); void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir); @@ -921,27 +921,24 @@ void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir); #else /* CONFIG_DEBUG_FS */ -static inline int __init cxl_debugfs_init(void) +static inline void __init cxl_debugfs_init(void) { - return 0; } static inline void cxl_debugfs_exit(void) { } -static inline int cxl_debugfs_adapter_add(struct cxl *adapter) +static inline void cxl_debugfs_adapter_add(struct cxl *adapter) { - return 0; } static inline void cxl_debugfs_adapter_remove(struct cxl *adapter) { } -static inline int cxl_debugfs_afu_add(struct cxl_afu *afu) +static inline void cxl_debugfs_afu_add(struct cxl_afu *afu) { - return 0; } static inline void cxl_debugfs_afu_remove(struct cxl_afu *afu) diff --git a/drivers/misc/cxl/debugfs.c b/drivers/misc/cxl/debugfs.c index 1fda22c24c93..7b987bf498b5 100644 --- a/drivers/misc/cxl/debugfs.c +++ b/drivers/misc/cxl/debugfs.c @@ -26,11 +26,11 @@ static int debugfs_io_u64_set(void *data, u64 val) DEFINE_DEBUGFS_ATTRIBUTE(fops_io_x64, debugfs_io_u64_get, debugfs_io_u64_set, "0x%016llx\n"); -static struct dentry *debugfs_create_io_x64(const char *name, umode_t mode, - struct dentry *parent, u64 __iomem *value) +static void debugfs_create_io_x64(const char *name, umode_t mode, + struct dentry *parent, u64 __iomem *value) { - return debugfs_create_file_unsafe(name, mode, parent, - (void __force *)value, &fops_io_x64); + debugfs_create_file_unsafe(name, mode, parent, (void __force *)value, + &fops_io_x64); } void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir) @@ -54,25 +54,22 @@ void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir) debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_TRACE)); } -int cxl_debugfs_adapter_add(struct cxl *adapter) +void cxl_debugfs_adapter_add(struct cxl *adapter) { struct dentry *dir; char buf[32]; if (!cxl_debugfs) - return -ENODEV; + return; snprintf(buf, 32, "card%i", adapter->adapter_num); dir = debugfs_create_dir(buf, cxl_debugfs); - if (IS_ERR(dir)) - return PTR_ERR(dir); adapter->debugfs = dir; debugfs_create_io_x64("err_ivte", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_ErrIVTE)); if (adapter->native->sl_ops->debugfs_add_adapter_regs) adapter->native->sl_ops->debugfs_add_adapter_regs(adapter, dir); - return 0; } void cxl_debugfs_adapter_remove(struct cxl *adapter) @@ -96,18 +93,16 @@ void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir) debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SLICE_TRACE)); } -int cxl_debugfs_afu_add(struct cxl_afu *afu) +void cxl_debugfs_afu_add(struct cxl_afu *afu) { struct dentry *dir; char buf[32]; if (!afu->adapter->debugfs) - return -ENODEV; + return; snprintf(buf, 32, "psl%i.%i", afu->adapter->adapter_num, afu->slice); dir = debugfs_create_dir(buf, afu->adapter->debugfs); - if (IS_ERR(dir)) - return PTR_ERR(dir); afu->debugfs = dir; debugfs_create_io_x64("sr", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SR_An)); @@ -118,8 +113,6 @@ int cxl_debugfs_afu_add(struct cxl_afu *afu) if (afu->adapter->native->sl_ops->debugfs_add_afu_regs) afu->adapter->native->sl_ops->debugfs_add_afu_regs(afu, dir); - - return 0; } void cxl_debugfs_afu_remove(struct cxl_afu *afu) @@ -127,19 +120,12 @@ void cxl_debugfs_afu_remove(struct cxl_afu *afu) debugfs_remove_recursive(afu->debugfs); } -int __init cxl_debugfs_init(void) +void __init cxl_debugfs_init(void) { - struct dentry *ent; - if (!cpu_has_feature(CPU_FTR_HVMODE)) - return 0; + return; - ent = debugfs_create_dir("cxl", NULL); - if (IS_ERR(ent)) - return PTR_ERR(ent); - cxl_debugfs = ent; - - return 0; + cxl_debugfs = debugfs_create_dir("cxl", NULL); } void cxl_debugfs_exit(void) From 9fd714cd7f4676e8ff3f840911a8d64cacbeab8b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 17:35:34 +0200 Subject: [PATCH 050/102] lib: dynamic_debug: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: linux-kernel@vger.kernel.org Acked-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 8a16c2d498e9..c60409138e13 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -993,20 +993,14 @@ static __initdata int ddebug_init_success; static int __init dynamic_debug_init_debugfs(void) { - struct dentry *dir, *file; + struct dentry *dir; if (!ddebug_init_success) return -ENODEV; dir = debugfs_create_dir("dynamic_debug", NULL); - if (!dir) - return -ENOMEM; - file = debugfs_create_file("control", 0644, dir, NULL, - &ddebug_proc_fops); - if (!file) { - debugfs_remove(dir); - return -ENOMEM; - } + debugfs_create_file("control", 0644, dir, NULL, &ddebug_proc_fops); + return 0; } From 053cf51040ed0ebc56c1b58453ad502dc4d0927b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 11:58:28 +0200 Subject: [PATCH 051/102] fault-inject: clean up debugfs file creation logic There is no need to check the return value of a debugfs_create_file call, a caller should never change what they do depending on if debugfs is working properly or not, so remove the checks, simplifying the logic in the file a lot. Also fix up the error check for debugfs_create_dir() which was not returning NULL for an error, but rather a error pointer. Cc: linux-kernel@vger.kernel.org Reviewed-by: Akinobu Mita Signed-off-by: Greg Kroah-Hartman --- lib/fault-inject.c | 71 ++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 46 deletions(-) diff --git a/lib/fault-inject.c b/lib/fault-inject.c index 3cb21b2bf088..8186ca84910b 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -166,10 +166,10 @@ static int debugfs_ul_get(void *data, u64 *val) DEFINE_SIMPLE_ATTRIBUTE(fops_ul, debugfs_ul_get, debugfs_ul_set, "%llu\n"); -static struct dentry *debugfs_create_ul(const char *name, umode_t mode, - struct dentry *parent, unsigned long *value) +static void debugfs_create_ul(const char *name, umode_t mode, + struct dentry *parent, unsigned long *value) { - return debugfs_create_file(name, mode, parent, value, &fops_ul); + debugfs_create_file(name, mode, parent, value, &fops_ul); } #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER @@ -185,12 +185,11 @@ static int debugfs_stacktrace_depth_set(void *data, u64 val) DEFINE_SIMPLE_ATTRIBUTE(fops_stacktrace_depth, debugfs_ul_get, debugfs_stacktrace_depth_set, "%llu\n"); -static struct dentry *debugfs_create_stacktrace_depth( - const char *name, umode_t mode, - struct dentry *parent, unsigned long *value) +static void debugfs_create_stacktrace_depth(const char *name, umode_t mode, + struct dentry *parent, + unsigned long *value) { - return debugfs_create_file(name, mode, parent, value, - &fops_stacktrace_depth); + debugfs_create_file(name, mode, parent, value, &fops_stacktrace_depth); } #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ @@ -202,51 +201,31 @@ struct dentry *fault_create_debugfs_attr(const char *name, struct dentry *dir; dir = debugfs_create_dir(name, parent); - if (!dir) - return ERR_PTR(-ENOMEM); + if (IS_ERR(dir)) + return dir; - if (!debugfs_create_ul("probability", mode, dir, &attr->probability)) - goto fail; - if (!debugfs_create_ul("interval", mode, dir, &attr->interval)) - goto fail; - if (!debugfs_create_atomic_t("times", mode, dir, &attr->times)) - goto fail; - if (!debugfs_create_atomic_t("space", mode, dir, &attr->space)) - goto fail; - if (!debugfs_create_ul("verbose", mode, dir, &attr->verbose)) - goto fail; - if (!debugfs_create_u32("verbose_ratelimit_interval_ms", mode, dir, - &attr->ratelimit_state.interval)) - goto fail; - if (!debugfs_create_u32("verbose_ratelimit_burst", mode, dir, - &attr->ratelimit_state.burst)) - goto fail; - if (!debugfs_create_bool("task-filter", mode, dir, &attr->task_filter)) - goto fail; + debugfs_create_ul("probability", mode, dir, &attr->probability); + debugfs_create_ul("interval", mode, dir, &attr->interval); + debugfs_create_atomic_t("times", mode, dir, &attr->times); + debugfs_create_atomic_t("space", mode, dir, &attr->space); + debugfs_create_ul("verbose", mode, dir, &attr->verbose); + debugfs_create_u32("verbose_ratelimit_interval_ms", mode, dir, + &attr->ratelimit_state.interval); + debugfs_create_u32("verbose_ratelimit_burst", mode, dir, + &attr->ratelimit_state.burst); + debugfs_create_bool("task-filter", mode, dir, &attr->task_filter); #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER - - if (!debugfs_create_stacktrace_depth("stacktrace-depth", mode, dir, - &attr->stacktrace_depth)) - goto fail; - if (!debugfs_create_ul("require-start", mode, dir, - &attr->require_start)) - goto fail; - if (!debugfs_create_ul("require-end", mode, dir, &attr->require_end)) - goto fail; - if (!debugfs_create_ul("reject-start", mode, dir, &attr->reject_start)) - goto fail; - if (!debugfs_create_ul("reject-end", mode, dir, &attr->reject_end)) - goto fail; - + debugfs_create_stacktrace_depth("stacktrace-depth", mode, dir, + &attr->stacktrace_depth); + debugfs_create_ul("require-start", mode, dir, &attr->require_start); + debugfs_create_ul("require-end", mode, dir, &attr->require_end); + debugfs_create_ul("reject-start", mode, dir, &attr->reject_start); + debugfs_create_ul("reject-end", mode, dir, &attr->reject_end); #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ attr->dname = dget(dir); return dir; -fail: - debugfs_remove_recursive(dir); - - return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL_GPL(fault_create_debugfs_attr); From 7e9f02a7896bf12bddfa28c4fdc442aa6cc6eda1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2019 20:43:23 +0200 Subject: [PATCH 052/102] mic: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Ashutosh Dixit Cc: linux-kernel@vger.kernel.org Reviewed-by: Arnd Bergmann Reviewed-by: Sudeep Dutt Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mic/card/mic_debugfs.c | 18 ++---------------- drivers/misc/mic/cosm/cosm_debugfs.c | 4 ---- drivers/misc/mic/host/mic_debugfs.c | 4 ---- drivers/misc/mic/scif/scif_debugfs.c | 5 ----- drivers/misc/mic/vop/vop_debugfs.c | 4 ---- 5 files changed, 2 insertions(+), 33 deletions(-) diff --git a/drivers/misc/mic/card/mic_debugfs.c b/drivers/misc/mic/card/mic_debugfs.c index 7a4140874888..fa2b5fefb791 100644 --- a/drivers/misc/mic/card/mic_debugfs.c +++ b/drivers/misc/mic/card/mic_debugfs.c @@ -63,25 +63,13 @@ DEFINE_SHOW_ATTRIBUTE(mic_intr); */ void __init mic_create_card_debug_dir(struct mic_driver *mdrv) { - struct dentry *d; - if (!mic_dbg) return; mdrv->dbg_dir = debugfs_create_dir(mdrv->name, mic_dbg); - if (!mdrv->dbg_dir) { - dev_err(mdrv->dev, "Cant create dbg_dir %s\n", mdrv->name); - return; - } - d = debugfs_create_file("intr_test", 0444, mdrv->dbg_dir, - mdrv, &mic_intr_fops); - - if (!d) { - dev_err(mdrv->dev, - "Cant create dbg intr_test %s\n", mdrv->name); - return; - } + debugfs_create_file("intr_test", 0444, mdrv->dbg_dir, mdrv, + &mic_intr_fops); } /** @@ -101,8 +89,6 @@ void mic_delete_card_debug_dir(struct mic_driver *mdrv) void __init mic_init_card_debugfs(void) { mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!mic_dbg) - pr_err("can't create debugfs dir\n"); } /** diff --git a/drivers/misc/mic/cosm/cosm_debugfs.c b/drivers/misc/mic/cosm/cosm_debugfs.c index 71c216d0504d..340ea7171411 100644 --- a/drivers/misc/mic/cosm/cosm_debugfs.c +++ b/drivers/misc/mic/cosm/cosm_debugfs.c @@ -105,8 +105,6 @@ void cosm_create_debug_dir(struct cosm_device *cdev) scnprintf(name, sizeof(name), "mic%d", cdev->index); cdev->dbg_dir = debugfs_create_dir(name, cosm_dbg); - if (!cdev->dbg_dir) - return; debugfs_create_file("log_buf", 0444, cdev->dbg_dir, cdev, &log_buf_fops); @@ -125,8 +123,6 @@ void cosm_delete_debug_dir(struct cosm_device *cdev) void cosm_init_debugfs(void) { cosm_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!cosm_dbg) - pr_err("can't create debugfs dir\n"); } void cosm_exit_debugfs(void) diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c index c6e3c764699f..370f98c7b752 100644 --- a/drivers/misc/mic/host/mic_debugfs.c +++ b/drivers/misc/mic/host/mic_debugfs.c @@ -125,8 +125,6 @@ void mic_create_debug_dir(struct mic_device *mdev) scnprintf(name, sizeof(name), "mic%d", mdev->id); mdev->dbg_dir = debugfs_create_dir(name, mic_dbg); - if (!mdev->dbg_dir) - return; debugfs_create_file("smpt", 0444, mdev->dbg_dir, mdev, &mic_smpt_fops); @@ -155,8 +153,6 @@ void mic_delete_debug_dir(struct mic_device *mdev) void __init mic_init_debugfs(void) { mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!mic_dbg) - pr_err("can't create debugfs dir\n"); } /** diff --git a/drivers/misc/mic/scif/scif_debugfs.c b/drivers/misc/mic/scif/scif_debugfs.c index a6820480105a..8fe38e7ca6e6 100644 --- a/drivers/misc/mic/scif/scif_debugfs.c +++ b/drivers/misc/mic/scif/scif_debugfs.c @@ -103,11 +103,6 @@ DEFINE_SHOW_ATTRIBUTE(scif_rma); void __init scif_init_debugfs(void) { scif_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!scif_dbg) { - dev_err(scif_info.mdev.this_device, - "can't create debugfs dir scif\n"); - return; - } debugfs_create_file("scif_dev", 0444, scif_dbg, NULL, &scif_dev_fops); debugfs_create_file("scif_rma", 0444, scif_dbg, NULL, &scif_rma_fops); diff --git a/drivers/misc/mic/vop/vop_debugfs.c b/drivers/misc/mic/vop/vop_debugfs.c index 2ccef52aca23..d4551d522188 100644 --- a/drivers/misc/mic/vop/vop_debugfs.c +++ b/drivers/misc/mic/vop/vop_debugfs.c @@ -186,10 +186,6 @@ void vop_init_debugfs(struct vop_info *vi) snprintf(name, sizeof(name), "%s%d", KBUILD_MODNAME, vi->vpdev->dnode); vi->dbg = debugfs_create_dir(name, NULL); - if (!vi->dbg) { - pr_err("can't create debugfs dir vop\n"); - return; - } debugfs_create_file("dp", 0444, vi->dbg, vi, &vop_dp_fops); debugfs_create_file("vdev_info", 0444, vi->dbg, vi, &vop_vdev_info_fops); } From d7ef4857d947a0c9ba26bfe02bac1629bda9f9a0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2019 20:41:07 +0200 Subject: [PATCH 053/102] genwq: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Frank Haverkamp Cc: linux-kernel@vger.kernel.org Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_base.c | 5 - drivers/misc/genwqe/card_base.h | 2 +- drivers/misc/genwqe/card_debugfs.c | 165 ++++++----------------------- drivers/misc/genwqe/card_dev.c | 6 +- 4 files changed, 32 insertions(+), 146 deletions(-) diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index d137d0fab9bf..f9f329651037 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -1377,10 +1377,6 @@ static int __init genwqe_init_module(void) class_genwqe->devnode = genwqe_devnode; debugfs_genwqe = debugfs_create_dir(GENWQE_DEVNAME, NULL); - if (!debugfs_genwqe) { - rc = -ENOMEM; - goto err_out; - } rc = pci_register_driver(&genwqe_driver); if (rc != 0) { @@ -1392,7 +1388,6 @@ static int __init genwqe_init_module(void) err_out0: debugfs_remove(debugfs_genwqe); - err_out: class_destroy(class_genwqe); return rc; } diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h index 77ed3967c5b0..d9e4a6e5fe3c 100644 --- a/drivers/misc/genwqe/card_base.h +++ b/drivers/misc/genwqe/card_base.h @@ -445,7 +445,7 @@ int genwqe_device_create(struct genwqe_dev *cd); int genwqe_device_remove(struct genwqe_dev *cd); /* debugfs */ -int genwqe_init_debugfs(struct genwqe_dev *cd); +void genwqe_init_debugfs(struct genwqe_dev *cd); void genqwe_exit_debugfs(struct genwqe_dev *cd); int genwqe_read_softreset(struct genwqe_dev *cd); diff --git a/drivers/misc/genwqe/card_debugfs.c b/drivers/misc/genwqe/card_debugfs.c index 6f7e39f07811..3e319743e5a3 100644 --- a/drivers/misc/genwqe/card_debugfs.c +++ b/drivers/misc/genwqe/card_debugfs.c @@ -324,11 +324,9 @@ static int info_show(struct seq_file *s, void *unused) DEFINE_SHOW_ATTRIBUTE(info); -int genwqe_init_debugfs(struct genwqe_dev *cd) +void genwqe_init_debugfs(struct genwqe_dev *cd) { struct dentry *root; - struct dentry *file; - int ret; char card_name[64]; char name[64]; unsigned int i; @@ -336,153 +334,50 @@ int genwqe_init_debugfs(struct genwqe_dev *cd) sprintf(card_name, "%s%d_card", GENWQE_DEVNAME, cd->card_idx); root = debugfs_create_dir(card_name, cd->debugfs_genwqe); - if (!root) { - ret = -ENOMEM; - goto err0; - } /* non privileged interfaces are done here */ - file = debugfs_create_file("ddcb_info", S_IRUGO, root, cd, - &ddcb_info_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("info", S_IRUGO, root, cd, - &info_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_x64("err_inject", 0666, root, &cd->err_inject); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_u32("ddcb_software_timeout", 0666, root, - &cd->ddcb_software_timeout); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_u32("kill_timeout", 0666, root, - &cd->kill_timeout); - if (!file) { - ret = -ENOMEM; - goto err1; - } + debugfs_create_file("ddcb_info", S_IRUGO, root, cd, &ddcb_info_fops); + debugfs_create_file("info", S_IRUGO, root, cd, &info_fops); + debugfs_create_x64("err_inject", 0666, root, &cd->err_inject); + debugfs_create_u32("ddcb_software_timeout", 0666, root, + &cd->ddcb_software_timeout); + debugfs_create_u32("kill_timeout", 0666, root, &cd->kill_timeout); /* privileged interfaces follow here */ if (!genwqe_is_privileged(cd)) { cd->debugfs_root = root; - return 0; + return; } - file = debugfs_create_file("curr_regs", S_IRUGO, root, cd, - &curr_regs_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("curr_dbg_uid0", S_IRUGO, root, cd, - &curr_dbg_uid0_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("curr_dbg_uid1", S_IRUGO, root, cd, - &curr_dbg_uid1_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("curr_dbg_uid2", S_IRUGO, root, cd, - &curr_dbg_uid2_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("prev_regs", S_IRUGO, root, cd, - &prev_regs_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("prev_dbg_uid0", S_IRUGO, root, cd, - &prev_dbg_uid0_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("prev_dbg_uid1", S_IRUGO, root, cd, - &prev_dbg_uid1_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("prev_dbg_uid2", S_IRUGO, root, cd, - &prev_dbg_uid2_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } + debugfs_create_file("curr_regs", S_IRUGO, root, cd, &curr_regs_fops); + debugfs_create_file("curr_dbg_uid0", S_IRUGO, root, cd, + &curr_dbg_uid0_fops); + debugfs_create_file("curr_dbg_uid1", S_IRUGO, root, cd, + &curr_dbg_uid1_fops); + debugfs_create_file("curr_dbg_uid2", S_IRUGO, root, cd, + &curr_dbg_uid2_fops); + debugfs_create_file("prev_regs", S_IRUGO, root, cd, &prev_regs_fops); + debugfs_create_file("prev_dbg_uid0", S_IRUGO, root, cd, + &prev_dbg_uid0_fops); + debugfs_create_file("prev_dbg_uid1", S_IRUGO, root, cd, + &prev_dbg_uid1_fops); + debugfs_create_file("prev_dbg_uid2", S_IRUGO, root, cd, + &prev_dbg_uid2_fops); for (i = 0; i < GENWQE_MAX_VFS; i++) { sprintf(name, "vf%u_jobtimeout_msec", i); - - file = debugfs_create_u32(name, 0666, root, - &cd->vf_jobtimeout_msec[i]); - if (!file) { - ret = -ENOMEM; - goto err1; - } + debugfs_create_u32(name, 0666, root, + &cd->vf_jobtimeout_msec[i]); } - file = debugfs_create_file("jobtimer", S_IRUGO, root, cd, - &jtimer_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("queue_working_time", S_IRUGO, root, cd, - &queue_working_time_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_u32("skip_recovery", 0666, root, - &cd->skip_recovery); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_u32("use_platform_recovery", 0666, root, - &cd->use_platform_recovery); - if (!file) { - ret = -ENOMEM; - goto err1; - } + debugfs_create_file("jobtimer", S_IRUGO, root, cd, &jtimer_fops); + debugfs_create_file("queue_working_time", S_IRUGO, root, cd, + &queue_working_time_fops); + debugfs_create_u32("skip_recovery", 0666, root, &cd->skip_recovery); + debugfs_create_u32("use_platform_recovery", 0666, root, + &cd->use_platform_recovery); cd->debugfs_root = root; - return 0; -err1: - debugfs_remove_recursive(root); -err0: - return ret; } void genqwe_exit_debugfs(struct genwqe_dev *cd) diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 8c1b63a4337b..b5942e8943ef 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -1307,14 +1307,10 @@ int genwqe_device_create(struct genwqe_dev *cd) goto err_cdev; } - rc = genwqe_init_debugfs(cd); - if (rc != 0) - goto err_debugfs; + genwqe_init_debugfs(cd); return 0; - err_debugfs: - device_destroy(cd->class_genwqe, cd->devnum_genwqe); err_cdev: cdev_del(&cd->cdev_genwqe); err_add: From 5666d896e838c974c535b3949353c83d68ce4384 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2019 20:38:16 +0200 Subject: [PATCH 054/102] mei: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Tomas Winkler Cc: Arnd Bergmann Cc: linux-kernel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/debugfs.c | 47 +++++++++----------------------------- drivers/misc/mei/main.c | 8 +------ drivers/misc/mei/mei_dev.h | 7 ++---- 3 files changed, 14 insertions(+), 48 deletions(-) diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index 0970142bcace..df6bf8b81936 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -233,47 +233,22 @@ void mei_dbgfs_deregister(struct mei_device *dev) * * @dev: the mei device structure * @name: the mei device name - * - * Return: 0 on success, <0 on failure. */ -int mei_dbgfs_register(struct mei_device *dev, const char *name) +void mei_dbgfs_register(struct mei_device *dev, const char *name) { - struct dentry *dir, *f; + struct dentry *dir; dir = debugfs_create_dir(name, NULL); - if (!dir) - return -ENOMEM; - dev->dbgfs_dir = dir; - f = debugfs_create_file("meclients", S_IRUSR, dir, - dev, &mei_dbgfs_fops_meclients); - if (!f) { - dev_err(dev->dev, "meclients: registration failed\n"); - goto err; - } - f = debugfs_create_file("active", S_IRUSR, dir, - dev, &mei_dbgfs_fops_active); - if (!f) { - dev_err(dev->dev, "active: registration failed\n"); - goto err; - } - f = debugfs_create_file("devstate", S_IRUSR, dir, - dev, &mei_dbgfs_fops_devstate); - if (!f) { - dev_err(dev->dev, "devstate: registration failed\n"); - goto err; - } - f = debugfs_create_file("allow_fixed_address", S_IRUSR | S_IWUSR, dir, - &dev->allow_fixed_address, - &mei_dbgfs_fops_allow_fa); - if (!f) { - dev_err(dev->dev, "allow_fixed_address: registration failed\n"); - goto err; - } - return 0; -err: - mei_dbgfs_deregister(dev); - return -ENODEV; + debugfs_create_file("meclients", S_IRUSR, dir, dev, + &mei_dbgfs_fops_meclients); + debugfs_create_file("active", S_IRUSR, dir, dev, + &mei_dbgfs_fops_active); + debugfs_create_file("devstate", S_IRUSR, dir, dev, + &mei_dbgfs_fops_devstate); + debugfs_create_file("allow_fixed_address", S_IRUSR | S_IWUSR, dir, + &dev->allow_fixed_address, + &mei_dbgfs_fops_allow_fa); } diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index ad02097d7fee..f894d1f8a53e 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -984,16 +984,10 @@ int mei_register(struct mei_device *dev, struct device *parent) goto err_dev_create; } - ret = mei_dbgfs_register(dev, dev_name(clsdev)); - if (ret) { - dev_err(clsdev, "cannot register debugfs ret = %d\n", ret); - goto err_dev_dbgfs; - } + mei_dbgfs_register(dev, dev_name(clsdev)); return 0; -err_dev_dbgfs: - device_destroy(mei_class, devno); err_dev_create: cdev_del(&dev->cdev); err_dev_add: diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index fca832fcac57..f71a023aed3c 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -718,13 +718,10 @@ bool mei_hbuf_acquire(struct mei_device *dev); bool mei_write_is_idle(struct mei_device *dev); #if IS_ENABLED(CONFIG_DEBUG_FS) -int mei_dbgfs_register(struct mei_device *dev, const char *name); +void mei_dbgfs_register(struct mei_device *dev, const char *name); void mei_dbgfs_deregister(struct mei_device *dev); #else -static inline int mei_dbgfs_register(struct mei_device *dev, const char *name) -{ - return 0; -} +static inline void mei_dbgfs_register(struct mei_device *dev, const char *name) {} static inline void mei_dbgfs_deregister(struct mei_device *dev) {} #endif /* CONFIG_DEBUG_FS */ From 122f8ec7b78e2d0f2dc6c966bef96b47c955ca36 Mon Sep 17 00:00:00 2001 From: Lin Yi Date: Mon, 3 Jun 2019 16:08:10 +0800 Subject: [PATCH 055/102] lib : kobject: fix refcount imblance on kobject_rename the kobj refcount increased by kobject_get should be released before error return, otherwise lead to a memory leak. Signed-off-by: Lin Yi Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/kobject.c b/lib/kobject.c index f2ccdbac8ed9..83198cb37d8d 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -498,8 +498,10 @@ int kobject_rename(struct kobject *kobj, const char *new_name) kobj = kobject_get(kobj); if (!kobj) return -EINVAL; - if (!kobj->parent) + if (!kobj->parent) { + kobject_put(kobj); return -EINVAL; + } devpath = kobject_get_path(kobj, GFP_KERNEL); if (!devpath) { From 5d8a437c583de22451e2787a20bdf12a52bfb447 Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Fri, 14 Jun 2019 19:27:45 +0530 Subject: [PATCH 056/102] firmware: ti_sci: Use the correct style for SPDX License Identifier This patch corrects the SPDX License Identifier style in header file related to Firmware Drivers for Texas Instruments SCI Protocol. For C header files Documentation/process/license-rules.rst mandates C-like comments (opposed to C source files where C++ style should be used) Changes made by using a script provided by Joe Perches here: https://lkml.org/lkml/2019/2/7/46 Suggested-by: Joe Perches Signed-off-by: Nishad Kamdar Reviewed-by: Lokesh Vutla Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/ti_sci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 4983827151bf..adbeeefaca92 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause */ /* * Texas Instruments System Control Interface (TISCI) Protocol * From d2527682160a09e4eb5e9abcf37e83ee5239561a Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Thu, 13 Jun 2019 19:30:03 +0530 Subject: [PATCH 057/102] firmware: arm_scmi: Use the correct style for SPDX License Identifier This patch corrects the SPDX License Identifier style in header file related to Firmware Drivers for ARM SCMI Message Protocol. For C header files Documentation/process/license-rules.rst mandates C-like comments (opposed to C source files where C++ style should be used) Changes made by using a script provided by Joe Perches here: https://lkml.org/lkml/2019/2/7/46 Suggested-by: Joe Perches Signed-off-by: Nishad Kamdar Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/arm_scmi/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 937a930ce87d..44fd4f9404a9 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * System Control and Management Interface (SCMI) Message Protocol * driver common header file containing some definitions, structures From 7c7e301406d0a93051d236600a72066278c2e4dc Mon Sep 17 00:00:00 2001 From: Kimberly Brown Date: Thu, 2 May 2019 13:34:45 -0400 Subject: [PATCH 058/102] btrfs: sysfs: Replace default_attrs in ktypes with groups The kobj_type default_attrs field is being replaced by the default_groups field. Replace the default_attrs fields in btrfs_raid_ktype and space_info_ktype with default_groups. Change "raid_attributes" to "raid_attrs", and use the ATTRIBUTE_GROUPS macro to create raid_groups and space_info_groups. Signed-off-by: Kimberly Brown Acked-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/sysfs.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index a1481808db80..c1dfc97893ba 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -303,11 +303,12 @@ static ssize_t raid_bytes_show(struct kobject *kobj, return snprintf(buf, PAGE_SIZE, "%llu\n", val); } -static struct attribute *raid_attributes[] = { +static struct attribute *raid_attrs[] = { BTRFS_ATTR_PTR(raid, total_bytes), BTRFS_ATTR_PTR(raid, used_bytes), NULL }; +ATTRIBUTE_GROUPS(raid); static void release_raid_kobj(struct kobject *kobj) { @@ -317,7 +318,7 @@ static void release_raid_kobj(struct kobject *kobj) struct kobj_type btrfs_raid_ktype = { .sysfs_ops = &kobj_sysfs_ops, .release = release_raid_kobj, - .default_attrs = raid_attributes, + .default_groups = raid_groups, }; #define SPACE_INFO_ATTR(field) \ @@ -364,6 +365,7 @@ static struct attribute *space_info_attrs[] = { BTRFS_ATTR_PTR(space_info, total_bytes_pinned), NULL, }; +ATTRIBUTE_GROUPS(space_info); static void space_info_release(struct kobject *kobj) { @@ -375,7 +377,7 @@ static void space_info_release(struct kobject *kobj) struct kobj_type space_info_ktype = { .sysfs_ops = &kobj_sysfs_ops, .release = space_info_release, - .default_attrs = space_info_attrs, + .default_groups = space_info_groups, }; static const struct attribute *allocation_attrs[] = { From 200f3a3fec0c1efab6dcdadc18c65eb61b4c89ce Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 18 Jun 2019 17:52:46 +0200 Subject: [PATCH 059/102] coresight: cpu-debug: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Suzuki K Poulose Cc: Alexander Shishkin Cc: linux-arm-kernel@lists.infradead.org Reviewed-by: Mathieu Poirier Tested-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-cpu-debug.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c index e8819d750938..6446ed69ab2f 100644 --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -525,23 +525,12 @@ static const struct file_operations debug_func_knob_fops = { static int debug_func_init(void) { - struct dentry *file; int ret; /* Create debugfs node */ debug_debugfs_dir = debugfs_create_dir("coresight_cpu_debug", NULL); - if (!debug_debugfs_dir) { - pr_err("%s: unable to create debugfs directory\n", __func__); - return -ENOMEM; - } - - file = debugfs_create_file("enable", 0644, debug_debugfs_dir, NULL, - &debug_func_knob_fops); - if (!file) { - pr_err("%s: unable to create enable knob file\n", __func__); - ret = -ENOMEM; - goto err; - } + debugfs_create_file("enable", 0644, debug_debugfs_dir, NULL, + &debug_func_knob_fops); /* Register function to be called for panic */ ret = atomic_notifier_chain_register(&panic_notifier_list, From 1012592cce2c59d85b7f535eb21d38d131167f07 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 18 Jun 2019 17:58:30 +0200 Subject: [PATCH 060/102] watchdog: mei_wdt: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Tomas Winkler Cc: Wim Van Sebroeck Cc: linux-watchdog@vger.kernel.org Reviewed-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/mei_wdt.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c index 8023cf28657a..96a770938ff0 100644 --- a/drivers/watchdog/mei_wdt.c +++ b/drivers/watchdog/mei_wdt.c @@ -539,38 +539,23 @@ static void dbgfs_unregister(struct mei_wdt *wdt) wdt->dbgfs_dir = NULL; } -static int dbgfs_register(struct mei_wdt *wdt) +static void dbgfs_register(struct mei_wdt *wdt) { - struct dentry *dir, *f; + struct dentry *dir; dir = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!dir) - return -ENOMEM; - wdt->dbgfs_dir = dir; - f = debugfs_create_file("state", S_IRUSR, dir, wdt, &dbgfs_fops_state); - if (!f) - goto err; - f = debugfs_create_file("activation", S_IRUSR, - dir, wdt, &dbgfs_fops_activation); - if (!f) - goto err; + debugfs_create_file("state", S_IRUSR, dir, wdt, &dbgfs_fops_state); - return 0; -err: - dbgfs_unregister(wdt); - return -ENODEV; + debugfs_create_file("activation", S_IRUSR, dir, wdt, + &dbgfs_fops_activation); } #else static inline void dbgfs_unregister(struct mei_wdt *wdt) {} - -static inline int dbgfs_register(struct mei_wdt *wdt) -{ - return 0; -} +static inline void dbgfs_register(struct mei_wdt *wdt) {} #endif /* CONFIG_DEBUG_FS */ static int mei_wdt_probe(struct mei_cl_device *cldev, @@ -623,8 +608,7 @@ static int mei_wdt_probe(struct mei_cl_device *cldev, if (ret) goto err_disable; - if (dbgfs_register(wdt)) - dev_warn(&cldev->dev, "cannot register debugfs\n"); + dbgfs_register(wdt); return 0; From 8bff68b80964134085a2f58642f22f6ea1b54857 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 18 Jun 2019 17:58:09 +0200 Subject: [PATCH 061/102] watchdog: bcm_kona_wdt: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Wim Van Sebroeck Cc: Florian Fainelli Cc: Ray Jui Cc: Scott Branden Cc: bcm-kernel-feedback-list@broadcom.com Cc: linux-watchdog@vger.kernel.org Reviewed-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/bcm_kona_wdt.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c index e2ad44816359..921291025680 100644 --- a/drivers/watchdog/bcm_kona_wdt.c +++ b/drivers/watchdog/bcm_kona_wdt.c @@ -143,24 +143,18 @@ static void bcm_kona_wdt_debug_init(struct platform_device *pdev) wdt->debugfs = NULL; dir = debugfs_create_dir(BCM_KONA_WDT_NAME, NULL); - if (IS_ERR_OR_NULL(dir)) - return; - if (debugfs_create_file("info", S_IFREG | S_IRUGO, dir, wdt, - &bcm_kona_fops)) - wdt->debugfs = dir; - else - debugfs_remove_recursive(dir); + debugfs_create_file("info", S_IFREG | S_IRUGO, dir, wdt, + &bcm_kona_fops); + wdt->debugfs = dir; } static void bcm_kona_wdt_debug_exit(struct platform_device *pdev) { struct bcm_kona_wdt *wdt = platform_get_drvdata(pdev); - if (wdt && wdt->debugfs) { + if (wdt) debugfs_remove_recursive(wdt->debugfs); - wdt->debugfs = NULL; - } } #else From 6987738dfa4cdd8ef68149c2fe644d9c20397d76 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 14 Jun 2019 09:14:23 +0200 Subject: [PATCH 062/102] 6lowpan: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Because we don't care if debugfs works or not, this trickles back a bit so we can clean things up by making some functions return void instead of an error value that is never going to fail. Cc: Alexander Aring Cc: Jukka Rissanen Cc: "David S. Miller" Cc: linux-bluetooth@vger.kernel.org Cc: linux-wpan@vger.kernel.org Cc: netdev@vger.kernel.org Acked-by: Jukka Rissanen Signed-off-by: Greg Kroah-Hartman --- net/6lowpan/6lowpan_i.h | 16 ++----- net/6lowpan/core.c | 8 +--- net/6lowpan/debugfs.c | 97 +++++++++++------------------------------ 3 files changed, 32 insertions(+), 89 deletions(-) diff --git a/net/6lowpan/6lowpan_i.h b/net/6lowpan/6lowpan_i.h index 53cf446ce2e3..01853cec0209 100644 --- a/net/6lowpan/6lowpan_i.h +++ b/net/6lowpan/6lowpan_i.h @@ -18,24 +18,16 @@ extern const struct ndisc_ops lowpan_ndisc_ops; int addrconf_ifid_802154_6lowpan(u8 *eui, struct net_device *dev); #ifdef CONFIG_6LOWPAN_DEBUGFS -int lowpan_dev_debugfs_init(struct net_device *dev); +void lowpan_dev_debugfs_init(struct net_device *dev); void lowpan_dev_debugfs_exit(struct net_device *dev); -int __init lowpan_debugfs_init(void); +void __init lowpan_debugfs_init(void); void lowpan_debugfs_exit(void); #else -static inline int lowpan_dev_debugfs_init(struct net_device *dev) -{ - return 0; -} - +static inline void lowpan_dev_debugfs_init(struct net_device *dev) { } static inline void lowpan_dev_debugfs_exit(struct net_device *dev) { } -static inline int __init lowpan_debugfs_init(void) -{ - return 0; -} - +static inline void __init lowpan_debugfs_init(void) { } static inline void lowpan_debugfs_exit(void) { } #endif /* CONFIG_6LOWPAN_DEBUGFS */ diff --git a/net/6lowpan/core.c b/net/6lowpan/core.c index 2d68351f1ac4..a068757eabaf 100644 --- a/net/6lowpan/core.c +++ b/net/6lowpan/core.c @@ -42,9 +42,7 @@ int lowpan_register_netdevice(struct net_device *dev, if (ret < 0) return ret; - ret = lowpan_dev_debugfs_init(dev); - if (ret < 0) - unregister_netdevice(dev); + lowpan_dev_debugfs_init(dev); return ret; } @@ -152,9 +150,7 @@ static int __init lowpan_module_init(void) { int ret; - ret = lowpan_debugfs_init(); - if (ret < 0) - return ret; + lowpan_debugfs_init(); ret = register_netdevice_notifier(&lowpan_notifier); if (ret < 0) { diff --git a/net/6lowpan/debugfs.c b/net/6lowpan/debugfs.c index f5a8eec9d7a3..1c140af06d52 100644 --- a/net/6lowpan/debugfs.c +++ b/net/6lowpan/debugfs.c @@ -163,11 +163,11 @@ static const struct file_operations lowpan_ctx_pfx_fops = { .release = single_release, }; -static int lowpan_dev_debugfs_ctx_init(struct net_device *dev, - struct dentry *ctx, u8 id) +static void lowpan_dev_debugfs_ctx_init(struct net_device *dev, + struct dentry *ctx, u8 id) { struct lowpan_dev *ldev = lowpan_dev(dev); - struct dentry *dentry, *root; + struct dentry *root; char buf[32]; WARN_ON_ONCE(id > LOWPAN_IPHC_CTX_TABLE_SIZE); @@ -175,34 +175,18 @@ static int lowpan_dev_debugfs_ctx_init(struct net_device *dev, sprintf(buf, "%d", id); root = debugfs_create_dir(buf, ctx); - if (!root) - return -EINVAL; - dentry = debugfs_create_file_unsafe("active", 0644, root, - &ldev->ctx.table[id], - &lowpan_ctx_flag_active_fops); - if (!dentry) - return -EINVAL; + debugfs_create_file("active", 0644, root, &ldev->ctx.table[id], + &lowpan_ctx_flag_active_fops); - dentry = debugfs_create_file_unsafe("compression", 0644, root, - &ldev->ctx.table[id], - &lowpan_ctx_flag_c_fops); - if (!dentry) - return -EINVAL; + debugfs_create_file("compression", 0644, root, &ldev->ctx.table[id], + &lowpan_ctx_flag_c_fops); - dentry = debugfs_create_file("prefix", 0644, root, - &ldev->ctx.table[id], - &lowpan_ctx_pfx_fops); - if (!dentry) - return -EINVAL; + debugfs_create_file("prefix", 0644, root, &ldev->ctx.table[id], + &lowpan_ctx_pfx_fops); - dentry = debugfs_create_file_unsafe("prefix_len", 0644, root, - &ldev->ctx.table[id], - &lowpan_ctx_plen_fops); - if (!dentry) - return -EINVAL; - - return 0; + debugfs_create_file("prefix_len", 0644, root, &ldev->ctx.table[id], + &lowpan_ctx_plen_fops); } static int lowpan_context_show(struct seq_file *file, void *offset) @@ -242,64 +226,39 @@ static int lowpan_short_addr_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(lowpan_short_addr_fops, lowpan_short_addr_get, NULL, "0x%04llx\n"); -static int lowpan_dev_debugfs_802154_init(const struct net_device *dev, +static void lowpan_dev_debugfs_802154_init(const struct net_device *dev, struct lowpan_dev *ldev) { - struct dentry *dentry, *root; + struct dentry *root; if (!lowpan_is_ll(dev, LOWPAN_LLTYPE_IEEE802154)) - return 0; + return; root = debugfs_create_dir("ieee802154", ldev->iface_debugfs); - if (!root) - return -EINVAL; - dentry = debugfs_create_file_unsafe("short_addr", 0444, root, - lowpan_802154_dev(dev)->wdev->ieee802154_ptr, - &lowpan_short_addr_fops); - if (!dentry) - return -EINVAL; - - return 0; + debugfs_create_file("short_addr", 0444, root, + lowpan_802154_dev(dev)->wdev->ieee802154_ptr, + &lowpan_short_addr_fops); } -int lowpan_dev_debugfs_init(struct net_device *dev) +void lowpan_dev_debugfs_init(struct net_device *dev) { struct lowpan_dev *ldev = lowpan_dev(dev); - struct dentry *contexts, *dentry; - int ret, i; + struct dentry *contexts; + int i; /* creating the root */ ldev->iface_debugfs = debugfs_create_dir(dev->name, lowpan_debugfs); - if (!ldev->iface_debugfs) - goto fail; contexts = debugfs_create_dir("contexts", ldev->iface_debugfs); - if (!contexts) - goto remove_root; - dentry = debugfs_create_file("show", 0644, contexts, - &lowpan_dev(dev)->ctx, - &lowpan_context_fops); - if (!dentry) - goto remove_root; + debugfs_create_file("show", 0644, contexts, &lowpan_dev(dev)->ctx, + &lowpan_context_fops); - for (i = 0; i < LOWPAN_IPHC_CTX_TABLE_SIZE; i++) { - ret = lowpan_dev_debugfs_ctx_init(dev, contexts, i); - if (ret < 0) - goto remove_root; - } + for (i = 0; i < LOWPAN_IPHC_CTX_TABLE_SIZE; i++) + lowpan_dev_debugfs_ctx_init(dev, contexts, i); - ret = lowpan_dev_debugfs_802154_init(dev, ldev); - if (ret < 0) - goto remove_root; - - return 0; - -remove_root: - lowpan_dev_debugfs_exit(dev); -fail: - return -EINVAL; + lowpan_dev_debugfs_802154_init(dev, ldev); } void lowpan_dev_debugfs_exit(struct net_device *dev) @@ -307,13 +266,9 @@ void lowpan_dev_debugfs_exit(struct net_device *dev) debugfs_remove_recursive(lowpan_dev(dev)->iface_debugfs); } -int __init lowpan_debugfs_init(void) +void __init lowpan_debugfs_init(void) { lowpan_debugfs = debugfs_create_dir("6lowpan", NULL); - if (!lowpan_debugfs) - return -EINVAL; - - return 0; } void lowpan_debugfs_exit(void) From 10ff826ab0a46e6fbac324b3a633c4943e2a745e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2019 20:05:47 +0200 Subject: [PATCH 063/102] power: avs: smartreflex: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. And even when not checking the return value, no need to cast away the call to (void), as these functions were never a "must check" type of a function, so remove that odd cast. Cc: Kevin Hilman Cc: Nishanth Menon Cc: linux-pm@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/power/avs/smartreflex.c | 41 +++++++++------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c index c96c01e09740..4684e7df833a 100644 --- a/drivers/power/avs/smartreflex.c +++ b/drivers/power/avs/smartreflex.c @@ -899,38 +899,19 @@ static int omap_sr_probe(struct platform_device *pdev) } dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__); - if (!sr_dbg_dir) { + if (!sr_dbg_dir) sr_dbg_dir = debugfs_create_dir("smartreflex", NULL); - if (IS_ERR_OR_NULL(sr_dbg_dir)) { - ret = PTR_ERR(sr_dbg_dir); - pr_err("%s:sr debugfs dir creation failed(%d)\n", - __func__, ret); - goto err_list_del; - } - } sr_info->dbg_dir = debugfs_create_dir(sr_info->name, sr_dbg_dir); - if (IS_ERR_OR_NULL(sr_info->dbg_dir)) { - dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", - __func__); - ret = PTR_ERR(sr_info->dbg_dir); - goto err_debugfs; - } - (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, - sr_info->dbg_dir, (void *)sr_info, &pm_sr_fops); - (void) debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir, - &sr_info->err_weight); - (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir, - &sr_info->err_maxlimit); + debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, sr_info->dbg_dir, + (void *)sr_info, &pm_sr_fops); + debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir, + &sr_info->err_weight); + debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir, + &sr_info->err_maxlimit); nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); - if (IS_ERR_OR_NULL(nvalue_dir)) { - dev_err(&pdev->dev, "%s: Unable to create debugfs directory for n-values\n", - __func__); - ret = PTR_ERR(nvalue_dir); - goto err_debugfs; - } if (sr_info->nvalue_count == 0 || !sr_info->nvalue_table) { dev_warn(&pdev->dev, "%s: %s: No Voltage table for the corresponding vdd. Cannot create debugfs entries for n-values\n", @@ -945,12 +926,12 @@ static int omap_sr_probe(struct platform_device *pdev) snprintf(name, sizeof(name), "volt_%lu", sr_info->nvalue_table[i].volt_nominal); - (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, - &(sr_info->nvalue_table[i].nvalue)); + debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, + &(sr_info->nvalue_table[i].nvalue)); snprintf(name, sizeof(name), "errminlimit_%lu", sr_info->nvalue_table[i].volt_nominal); - (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, - &(sr_info->nvalue_table[i].errminlimit)); + debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, + &(sr_info->nvalue_table[i].errminlimit)); } From a6cd400ac8a8b39b6830621eb51db351e1048f79 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 13 Jun 2019 20:37:29 +0200 Subject: [PATCH 064/102] thermal: bcm2835: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Zhang Rui Cc: Eduardo Valentin Cc: Daniel Lezcano Cc: Florian Fainelli Cc: Ray Jui Cc: Scott Branden Cc: bcm-kernel-feedback-list@broadcom.com Cc: linux-pm@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/thermal/broadcom/bcm2835_thermal.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index ba39647a690c..3199977f1e73 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -123,8 +123,6 @@ static void bcm2835_thermal_debugfs(struct platform_device *pdev) struct debugfs_regset32 *regset; data->debugfsdir = debugfs_create_dir("bcm2835_thermal", NULL); - if (!data->debugfsdir) - return; regset = devm_kzalloc(&pdev->dev, sizeof(*regset), GFP_KERNEL); if (!regset) From 58cb346c7188f04bafa2a089ab0b093f5642572c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Jun 2019 15:55:12 -0300 Subject: [PATCH 065/102] drivers: base/node.c: fixes a kernel-doc markups There was a typo at the name of the vars inside the kernel-doc comment, causing those warnings: ./drivers/base/node.c:690: warning: Function parameter or member 'mem_nid' not described in 'register_memory_node_under_compute_node' ./drivers/base/node.c:690: warning: Function parameter or member 'cpu_nid' not described in 'register_memory_node_under_compute_node' ./drivers/base/node.c:690: warning: Excess function parameter 'mem_node' description in 'register_memory_node_under_compute_node' ./drivers/base/node.c:690: warning: Excess function parameter 'cpu_node' description in 'register_memory_node_under_compute_node' There's also a description missing here: ./drivers/base/node.c:78: warning: Function parameter or member 'hmem_attrs' not described in 'node_access_nodes' Copy an existing description from another function call. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/base/node.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/base/node.c b/drivers/base/node.c index 8598fcbd2a17..aa878fbcf705 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -66,6 +66,7 @@ static DEVICE_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL); * @dev: Device for this memory access class * @list_node: List element in the node's access list * @access: The access class rank + * @hmem_attrs: Heterogeneous memory performance attributes */ struct node_access_nodes { struct device dev; @@ -673,8 +674,8 @@ int register_cpu_under_node(unsigned int cpu, unsigned int nid) /** * register_memory_node_under_compute_node - link memory node to its compute * node for a given access class. - * @mem_node: Memory node number - * @cpu_node: Cpu node number + * @mem_nid: Memory node number + * @cpu_nid: Cpu node number * @access: Access class to register * * Description: From 4489f161b739f01ab60a58784f6ef7de9d7a1352 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Jun 2019 17:53:27 -0300 Subject: [PATCH 066/102] docs: driver-model: convert docs to ReST and rename to *.rst Convert the various documents at the driver-model, preparing them to be part of the driver-api book. The conversion is actually: - add blank lines and identation in order to identify paragraphs; - fix tables markups; - add some lists markups; - mark literal blocks; - adjust title markups. At its new index.rst, let's add a :orphan: while this is not linked to the main index.rst file, in order to avoid build warnings. Signed-off-by: Mauro Carvalho Chehab Acked-by: Jeff Kirsher # ice Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/gpio/driver.rst | 2 +- .../driver-model/{binding.txt => binding.rst} | 20 +- .../driver-model/{bus.txt => bus.rst} | 69 ++-- .../driver-model/{class.txt => class.rst} | 74 ++-- ...esign-patterns.txt => design-patterns.rst} | 106 +++--- .../driver-model/{device.txt => device.rst} | 57 +-- .../driver-model/{devres.txt => devres.rst} | 50 +-- .../driver-model/{driver.txt => driver.rst} | 112 +++--- Documentation/driver-model/index.rst | 26 ++ .../{overview.txt => overview.rst} | 37 +- .../{platform.txt => platform.rst} | 30 +- .../driver-model/{porting.txt => porting.rst} | 333 +++++++++--------- Documentation/eisa.txt | 4 +- Documentation/hwmon/submitting-patches.rst | 2 +- drivers/base/platform.c | 2 +- drivers/gpio/gpio-cs5535.c | 2 +- drivers/net/ethernet/intel/ice/ice_main.c | 2 +- scripts/coccinelle/free/devm_free.cocci | 2 +- 18 files changed, 489 insertions(+), 441 deletions(-) rename Documentation/driver-model/{binding.txt => binding.rst} (92%) rename Documentation/driver-model/{bus.txt => bus.rst} (76%) rename Documentation/driver-model/{class.txt => class.rst} (75%) rename Documentation/driver-model/{design-patterns.txt => design-patterns.rst} (59%) rename Documentation/driver-model/{device.txt => device.rst} (71%) rename Documentation/driver-model/{devres.txt => devres.rst} (93%) rename Documentation/driver-model/{driver.txt => driver.rst} (75%) create mode 100644 Documentation/driver-model/index.rst rename Documentation/driver-model/{overview.txt => overview.rst} (90%) rename Documentation/driver-model/{platform.txt => platform.rst} (95%) rename Documentation/driver-model/{porting.txt => porting.rst} (62%) diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst index 1ce7fcd0f989..f931597fe7be 100644 --- a/Documentation/driver-api/gpio/driver.rst +++ b/Documentation/driver-api/gpio/driver.rst @@ -399,7 +399,7 @@ symbol: will pass the struct gpio_chip* for the chip to all IRQ callbacks, so the callbacks need to embed the gpio_chip in its state container and obtain a pointer to the container using container_of(). - (See Documentation/driver-model/design-patterns.txt) + (See Documentation/driver-model/design-patterns.rst) - gpiochip_irqchip_add_nested(): adds a nested cascaded irqchip to a gpiochip, as discussed above regarding different types of cascaded irqchips. The diff --git a/Documentation/driver-model/binding.txt b/Documentation/driver-model/binding.rst similarity index 92% rename from Documentation/driver-model/binding.txt rename to Documentation/driver-model/binding.rst index abfc8e290d53..7ea1d7a41e1d 100644 --- a/Documentation/driver-model/binding.txt +++ b/Documentation/driver-model/binding.rst @@ -1,5 +1,6 @@ - +============== Driver Binding +============== Driver binding is the process of associating a device with a device driver that can control it. Bus drivers have typically handled this @@ -25,7 +26,7 @@ device_register When a new device is added, the bus's list of drivers is iterated over to find one that supports it. In order to determine that, the device ID of the device must match one of the device IDs that the driver -supports. The format and semantics for comparing IDs is bus-specific. +supports. The format and semantics for comparing IDs is bus-specific. Instead of trying to derive a complex state machine and matching algorithm, it is up to the bus driver to provide a callback to compare a device against the IDs of a driver. The bus returns 1 if a match was @@ -36,14 +37,14 @@ int match(struct device * dev, struct device_driver * drv); If a match is found, the device's driver field is set to the driver and the driver's probe callback is called. This gives the driver a chance to verify that it really does support the hardware, and that -it's in a working state. +it's in a working state. Device Class ~~~~~~~~~~~~ Upon the successful completion of probe, the device is registered with the class to which it belongs. Device drivers belong to one and only one -class, and that is set in the driver's devclass field. +class, and that is set in the driver's devclass field. devclass_add_device is called to enumerate the device within the class and actually register it with the class, which happens with the class's register_dev callback. @@ -53,7 +54,7 @@ Driver ~~~~~~ When a driver is attached to a device, the device is inserted into the -driver's list of devices. +driver's list of devices. sysfs @@ -67,18 +68,18 @@ to the device's directory in the physical hierarchy. A directory for the device is created in the class's directory. A symlink is created in that directory that points to the device's -physical location in the sysfs tree. +physical location in the sysfs tree. A symlink can be created (though this isn't done yet) in the device's physical directory to either its class directory, or the class's top-level directory. One can also be created to point to its driver's -directory also. +directory also. driver_register ~~~~~~~~~~~~~~~ -The process is almost identical for when a new driver is added. +The process is almost identical for when a new driver is added. The bus's list of devices is iterated over to find a match. Devices that already have a driver are skipped. All the devices are iterated over, to bind as many devices as possible to the driver. @@ -94,5 +95,4 @@ of the driver is decremented. All symlinks between the two are removed. When a driver is removed, the list of devices that it supports is iterated over, and the driver's remove callback is called for each -one. The device is removed from that list and the symlinks removed. - +one. The device is removed from that list and the symlinks removed. diff --git a/Documentation/driver-model/bus.txt b/Documentation/driver-model/bus.rst similarity index 76% rename from Documentation/driver-model/bus.txt rename to Documentation/driver-model/bus.rst index c247b488a567..016b15a6e8ea 100644 --- a/Documentation/driver-model/bus.txt +++ b/Documentation/driver-model/bus.rst @@ -1,5 +1,6 @@ - -Bus Types +========= +Bus Types +========= Definition ~~~~~~~~~~ @@ -13,12 +14,12 @@ Declaration Each bus type in the kernel (PCI, USB, etc) should declare one static object of this type. They must initialize the name field, and may -optionally initialize the match callback. +optionally initialize the match callback:: -struct bus_type pci_bus_type = { - .name = "pci", - .match = pci_bus_match, -}; + struct bus_type pci_bus_type = { + .name = "pci", + .match = pci_bus_match, + }; The structure should be exported to drivers in a header file: @@ -30,8 +31,8 @@ Registration When a bus driver is initialized, it calls bus_register. This initializes the rest of the fields in the bus object and inserts it -into a global list of bus types. Once the bus object is registered, -the fields in it are usable by the bus driver. +into a global list of bus types. Once the bus object is registered, +the fields in it are usable by the bus driver. Callbacks @@ -43,17 +44,17 @@ match(): Attaching Drivers to Devices The format of device ID structures and the semantics for comparing them are inherently bus-specific. Drivers typically declare an array of device IDs of devices they support that reside in a bus-specific -driver structure. +driver structure. The purpose of the match callback is to give the bus an opportunity to determine if a particular driver supports a particular device by comparing the device IDs the driver supports with the device ID of a particular device, without sacrificing bus-specific functionality or -type-safety. +type-safety. When a driver is registered with the bus, the bus's list of devices is iterated over, and the match callback is called for each device that -does not have a driver associated with it. +does not have a driver associated with it. @@ -64,22 +65,23 @@ The lists of devices and drivers are intended to replace the local lists that many buses keep. They are lists of struct devices and struct device_drivers, respectively. Bus drivers are free to use the lists as they please, but conversion to the bus-specific type may be -necessary. +necessary. -The LDM core provides helper functions for iterating over each list. +The LDM core provides helper functions for iterating over each list:: -int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, - int (*fn)(struct device *, void *)); + int bus_for_each_dev(struct bus_type * bus, struct device * start, + void * data, + int (*fn)(struct device *, void *)); -int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, - void * data, int (*fn)(struct device_driver *, void *)); + int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, + void * data, int (*fn)(struct device_driver *, void *)); These helpers iterate over the respective list, and call the callback for each device or driver in the list. All list accesses are synchronized by taking the bus's lock (read currently). The reference count on each object in the list is incremented before the callback is called; it is decremented after the next object has been obtained. The -lock is not held when calling the callback. +lock is not held when calling the callback. sysfs @@ -87,14 +89,14 @@ sysfs There is a top-level directory named 'bus'. Each bus gets a directory in the bus directory, along with two default -directories: +directories:: /sys/bus/pci/ |-- devices `-- drivers Drivers registered with the bus get a directory in the bus's drivers -directory: +directory:: /sys/bus/pci/ |-- devices @@ -106,7 +108,7 @@ directory: Each device that is discovered on a bus of that type gets a symlink in the bus's devices directory to the device's directory in the physical -hierarchy: +hierarchy:: /sys/bus/pci/ |-- devices @@ -118,26 +120,27 @@ hierarchy: Exporting Attributes ~~~~~~~~~~~~~~~~~~~~ -struct bus_attribute { + +:: + + struct bus_attribute { struct attribute attr; ssize_t (*show)(struct bus_type *, char * buf); ssize_t (*store)(struct bus_type *, const char * buf, size_t count); -}; + }; Bus drivers can export attributes using the BUS_ATTR_RW macro that works similarly to the DEVICE_ATTR_RW macro for devices. For example, a -definition like this: +definition like this:: -static BUS_ATTR_RW(debug); + static BUS_ATTR_RW(debug); -is equivalent to declaring: +is equivalent to declaring:: -static bus_attribute bus_attr_debug; + static bus_attribute bus_attr_debug; This can then be used to add and remove the attribute from the bus's -sysfs directory using: - -int bus_create_file(struct bus_type *, struct bus_attribute *); -void bus_remove_file(struct bus_type *, struct bus_attribute *); - +sysfs directory using:: + int bus_create_file(struct bus_type *, struct bus_attribute *); + void bus_remove_file(struct bus_type *, struct bus_attribute *); diff --git a/Documentation/driver-model/class.txt b/Documentation/driver-model/class.rst similarity index 75% rename from Documentation/driver-model/class.txt rename to Documentation/driver-model/class.rst index 1fefc480a80b..fff55b80e86a 100644 --- a/Documentation/driver-model/class.txt +++ b/Documentation/driver-model/class.rst @@ -1,6 +1,6 @@ - +============== Device Classes - +============== Introduction ~~~~~~~~~~~~ @@ -13,37 +13,37 @@ device. The following device classes have been identified: Each device class defines a set of semantics and a programming interface that devices of that class adhere to. Device drivers are the implementation of that programming interface for a particular device on -a particular bus. +a particular bus. Device classes are agnostic with respect to what bus a device resides -on. +on. Programming Interface ~~~~~~~~~~~~~~~~~~~~~ -The device class structure looks like: +The device class structure looks like:: -typedef int (*devclass_add)(struct device *); -typedef void (*devclass_remove)(struct device *); + typedef int (*devclass_add)(struct device *); + typedef void (*devclass_remove)(struct device *); See the kerneldoc for the struct class. -A typical device class definition would look like: +A typical device class definition would look like:: -struct device_class input_devclass = { + struct device_class input_devclass = { .name = "input", .add_device = input_add_device, .remove_device = input_remove_device, -}; + }; Each device class structure should be exported in a header file so it can be used by drivers, extensions and interfaces. -Device classes are registered and unregistered with the core using: +Device classes are registered and unregistered with the core using:: -int devclass_register(struct device_class * cls); -void devclass_unregister(struct device_class * cls); + int devclass_register(struct device_class * cls); + void devclass_unregister(struct device_class * cls); Devices @@ -52,16 +52,16 @@ As devices are bound to drivers, they are added to the device class that the driver belongs to. Before the driver model core, this would typically happen during the driver's probe() callback, once the device has been initialized. It now happens after the probe() callback -finishes from the core. +finishes from the core. The device is enumerated in the class. Each time a device is added to the class, the class's devnum field is incremented and assigned to the device. The field is never decremented, so if the device is removed from the class and re-added, it will receive a different enumerated -value. +value. The class is allowed to create a class-specific structure for the -device and store it in the device's class_data pointer. +device and store it in the device's class_data pointer. There is no list of devices in the device class. Each driver has a list of devices that it supports. The device class has a list of @@ -73,15 +73,15 @@ Device Drivers ~~~~~~~~~~~~~~ Device drivers are added to device classes when they are registered with the core. A driver specifies the class it belongs to by setting -the struct device_driver::devclass field. +the struct device_driver::devclass field. sysfs directory structure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There is a top-level sysfs directory named 'class'. +There is a top-level sysfs directory named 'class'. Each class gets a directory in the class directory, along with two -default subdirectories: +default subdirectories:: class/ `-- input @@ -89,8 +89,8 @@ default subdirectories: `-- drivers -Drivers registered with the class get a symlink in the drivers/ directory -that points to the driver's directory (under its bus directory): +Drivers registered with the class get a symlink in the drivers/ directory +that points to the driver's directory (under its bus directory):: class/ `-- input @@ -99,8 +99,8 @@ that points to the driver's directory (under its bus directory): `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/ -Each device gets a symlink in the devices/ directory that points to the -device's directory in the physical hierarchy: +Each device gets a symlink in the devices/ directory that points to the +device's directory in the physical hierarchy:: class/ `-- input @@ -111,37 +111,39 @@ device's directory in the physical hierarchy: Exporting Attributes ~~~~~~~~~~~~~~~~~~~~ -struct devclass_attribute { + +:: + + struct devclass_attribute { struct attribute attr; ssize_t (*show)(struct device_class *, char * buf, size_t count, loff_t off); ssize_t (*store)(struct device_class *, const char * buf, size_t count, loff_t off); -}; + }; Class drivers can export attributes using the DEVCLASS_ATTR macro that works -similarly to the DEVICE_ATTR macro for devices. For example, a definition -like this: +similarly to the DEVICE_ATTR macro for devices. For example, a definition +like this:: -static DEVCLASS_ATTR(debug,0644,show_debug,store_debug); + static DEVCLASS_ATTR(debug,0644,show_debug,store_debug); -is equivalent to declaring: +is equivalent to declaring:: -static devclass_attribute devclass_attr_debug; + static devclass_attribute devclass_attr_debug; The bus driver can add and remove the attribute from the class's -sysfs directory using: +sysfs directory using:: -int devclass_create_file(struct device_class *, struct devclass_attribute *); -void devclass_remove_file(struct device_class *, struct devclass_attribute *); + int devclass_create_file(struct device_class *, struct devclass_attribute *); + void devclass_remove_file(struct device_class *, struct devclass_attribute *); In the example above, the file will be named 'debug' in placed in the -class's directory in sysfs. +class's directory in sysfs. Interfaces ~~~~~~~~~~ There may exist multiple mechanisms for accessing the same device of a -particular class type. Device interfaces describe these mechanisms. +particular class type. Device interfaces describe these mechanisms. When a device is added to a device class, the core attempts to add it to every interface that is registered with the device class. - diff --git a/Documentation/driver-model/design-patterns.txt b/Documentation/driver-model/design-patterns.rst similarity index 59% rename from Documentation/driver-model/design-patterns.txt rename to Documentation/driver-model/design-patterns.rst index ba7b2df64904..41eb8f41f7dd 100644 --- a/Documentation/driver-model/design-patterns.txt +++ b/Documentation/driver-model/design-patterns.rst @@ -1,6 +1,6 @@ - +============================= Device Driver Design Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +============================= This document describes a few common design patterns found in device drivers. It is likely that subsystem maintainers will ask driver developers to @@ -19,23 +19,23 @@ that the device the driver binds to will appear in several instances. This means that the probe() function and all callbacks need to be reentrant. The most common way to achieve this is to use the state container design -pattern. It usually has this form: +pattern. It usually has this form:: -struct foo { - spinlock_t lock; /* Example member */ - (...) -}; + struct foo { + spinlock_t lock; /* Example member */ + (...) + }; -static int foo_probe(...) -{ - struct foo *foo; + static int foo_probe(...) + { + struct foo *foo; - foo = devm_kzalloc(dev, sizeof(*foo), GFP_KERNEL); - if (!foo) - return -ENOMEM; - spin_lock_init(&foo->lock); - (...) -} + foo = devm_kzalloc(dev, sizeof(*foo), GFP_KERNEL); + if (!foo) + return -ENOMEM; + spin_lock_init(&foo->lock); + (...) + } This will create an instance of struct foo in memory every time probe() is called. This is our state container for this instance of the device driver. @@ -43,21 +43,21 @@ Of course it is then necessary to always pass this instance of the state around to all functions that need access to the state and its members. For example, if the driver is registering an interrupt handler, you would -pass around a pointer to struct foo like this: +pass around a pointer to struct foo like this:: -static irqreturn_t foo_handler(int irq, void *arg) -{ - struct foo *foo = arg; - (...) -} + static irqreturn_t foo_handler(int irq, void *arg) + { + struct foo *foo = arg; + (...) + } -static int foo_probe(...) -{ - struct foo *foo; + static int foo_probe(...) + { + struct foo *foo; - (...) - ret = request_irq(irq, foo_handler, 0, "foo", foo); -} + (...) + ret = request_irq(irq, foo_handler, 0, "foo", foo); + } This way you always get a pointer back to the correct instance of foo in your interrupt handler. @@ -66,38 +66,38 @@ your interrupt handler. 2. container_of() ~~~~~~~~~~~~~~~~~ -Continuing on the above example we add an offloaded work: +Continuing on the above example we add an offloaded work:: -struct foo { - spinlock_t lock; - struct workqueue_struct *wq; - struct work_struct offload; - (...) -}; + struct foo { + spinlock_t lock; + struct workqueue_struct *wq; + struct work_struct offload; + (...) + }; -static void foo_work(struct work_struct *work) -{ - struct foo *foo = container_of(work, struct foo, offload); + static void foo_work(struct work_struct *work) + { + struct foo *foo = container_of(work, struct foo, offload); - (...) -} + (...) + } -static irqreturn_t foo_handler(int irq, void *arg) -{ - struct foo *foo = arg; + static irqreturn_t foo_handler(int irq, void *arg) + { + struct foo *foo = arg; - queue_work(foo->wq, &foo->offload); - (...) -} + queue_work(foo->wq, &foo->offload); + (...) + } -static int foo_probe(...) -{ - struct foo *foo; + static int foo_probe(...) + { + struct foo *foo; - foo->wq = create_singlethread_workqueue("foo-wq"); - INIT_WORK(&foo->offload, foo_work); - (...) -} + foo->wq = create_singlethread_workqueue("foo-wq"); + INIT_WORK(&foo->offload, foo_work); + (...) + } The design pattern is the same for an hrtimer or something similar that will return a single argument which is a pointer to a struct member in the diff --git a/Documentation/driver-model/device.txt b/Documentation/driver-model/device.rst similarity index 71% rename from Documentation/driver-model/device.txt rename to Documentation/driver-model/device.rst index 2403eb856187..2b868d49d349 100644 --- a/Documentation/driver-model/device.txt +++ b/Documentation/driver-model/device.rst @@ -1,6 +1,6 @@ - +========================== The Basic Device Structure -~~~~~~~~~~~~~~~~~~~~~~~~~~ +========================== See the kerneldoc for the struct device. @@ -8,9 +8,9 @@ See the kerneldoc for the struct device. Programming Interface ~~~~~~~~~~~~~~~~~~~~~ The bus driver that discovers the device uses this to register the -device with the core: +device with the core:: -int device_register(struct device * dev); + int device_register(struct device * dev); The bus should initialize the following fields: @@ -20,30 +20,33 @@ The bus should initialize the following fields: - bus A device is removed from the core when its reference count goes to -0. The reference count can be adjusted using: +0. The reference count can be adjusted using:: -struct device * get_device(struct device * dev); -void put_device(struct device * dev); + struct device * get_device(struct device * dev); + void put_device(struct device * dev); get_device() will return a pointer to the struct device passed to it if the reference is not already 0 (if it's in the process of being removed already). -A driver can access the lock in the device structure using: +A driver can access the lock in the device structure using:: -void lock_device(struct device * dev); -void unlock_device(struct device * dev); + void lock_device(struct device * dev); + void unlock_device(struct device * dev); Attributes ~~~~~~~~~~ -struct device_attribute { + +:: + + struct device_attribute { struct attribute attr; ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf); ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -}; + }; Attributes of devices can be exported by a device driver through sysfs. @@ -54,39 +57,39 @@ As explained in Documentation/kobject.txt, device attributes must be created before the KOBJ_ADD uevent is generated. The only way to realize that is by defining an attribute group. -Attributes are declared using a macro called DEVICE_ATTR: +Attributes are declared using a macro called DEVICE_ATTR:: -#define DEVICE_ATTR(name,mode,show,store) + #define DEVICE_ATTR(name,mode,show,store) -Example: +Example::: -static DEVICE_ATTR(type, 0444, show_type, NULL); -static DEVICE_ATTR(power, 0644, show_power, store_power); + static DEVICE_ATTR(type, 0444, show_type, NULL); + static DEVICE_ATTR(power, 0644, show_power, store_power); This declares two structures of type struct device_attribute with respective names 'dev_attr_type' and 'dev_attr_power'. These two attributes can be -organized as follows into a group: +organized as follows into a group:: -static struct attribute *dev_attrs[] = { + static struct attribute *dev_attrs[] = { &dev_attr_type.attr, &dev_attr_power.attr, NULL, -}; + }; -static struct attribute_group dev_attr_group = { + static struct attribute_group dev_attr_group = { .attrs = dev_attrs, -}; + }; -static const struct attribute_group *dev_attr_groups[] = { + static const struct attribute_group *dev_attr_groups[] = { &dev_attr_group, NULL, -}; + }; This array of groups can then be associated with a device by setting the -group pointer in struct device before device_register() is invoked: +group pointer in struct device before device_register() is invoked:: - dev->groups = dev_attr_groups; - device_register(dev); + dev->groups = dev_attr_groups; + device_register(dev); The device_register() function will use the 'groups' pointer to create the device attributes and the device_unregister() function will use this pointer diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.rst similarity index 93% rename from Documentation/driver-model/devres.txt rename to Documentation/driver-model/devres.rst index 69c7fa7f616c..4ac99122b5f1 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.rst @@ -1,3 +1,4 @@ +================================ Devres - Managed Device Resource ================================ @@ -5,17 +6,18 @@ Tejun Heo First draft 10 January 2007 +.. contents -1. Intro : Huh? Devres? -2. Devres : Devres in a nutshell -3. Devres Group : Group devres'es and release them together -4. Details : Life time rules, calling context, ... -5. Overhead : How much do we have to pay for this? -6. List of managed interfaces : Currently implemented managed interfaces + 1. Intro : Huh? Devres? + 2. Devres : Devres in a nutshell + 3. Devres Group : Group devres'es and release them together + 4. Details : Life time rules, calling context, ... + 5. Overhead : How much do we have to pay for this? + 6. List of managed interfaces: Currently implemented managed interfaces - 1. Intro - -------- +1. Intro +-------- devres came up while trying to convert libata to use iomap. Each iomapped address should be kept and unmapped on driver detach. For @@ -42,8 +44,8 @@ would leak resources or even cause oops when failure occurs. iomap adds more to this mix. So do msi and msix. - 2. Devres - --------- +2. Devres +--------- devres is basically linked list of arbitrarily sized memory areas associated with a struct device. Each devres entry is associated with @@ -58,7 +60,7 @@ using dma_alloc_coherent(). The managed version is called dmam_alloc_coherent(). It is identical to dma_alloc_coherent() except for the DMA memory allocated using it is managed and will be automatically released on driver detach. Implementation looks like -the following. +the following:: struct dma_devres { size_t size; @@ -98,7 +100,7 @@ If a driver uses dmam_alloc_coherent(), the area is guaranteed to be freed whether initialization fails half-way or the device gets detached. If most resources are acquired using managed interface, a driver can have much simpler init and exit code. Init path basically -looks like the following. +looks like the following:: my_init_one() { @@ -119,7 +121,7 @@ looks like the following. return register_to_upper_layer(d); } -And exit path, +And exit path:: my_remove_one() { @@ -140,13 +142,13 @@ on you. In some cases this may mean introducing checks that were not necessary before moving to the managed devm_* calls. - 3. Devres group - --------------- +3. Devres group +--------------- Devres entries can be grouped using devres group. When a group is released, all contained normal devres entries and properly nested groups are released. One usage is to rollback series of acquired -resources on failure. For example, +resources on failure. For example:: if (!devres_open_group(dev, NULL, GFP_KERNEL)) return -ENOMEM; @@ -172,7 +174,7 @@ like above are usually useful in midlayer driver (e.g. libata core layer) where interface function shouldn't have side effect on failure. For LLDs, just returning error code suffices in most cases. -Each group is identified by void *id. It can either be explicitly +Each group is identified by `void *id`. It can either be explicitly specified by @id argument to devres_open_group() or automatically created by passing NULL as @id as in the above example. In both cases, devres_open_group() returns the group's id. The returned id @@ -180,7 +182,7 @@ can be passed to other devres functions to select the target group. If NULL is given to those functions, the latest open group is selected. -For example, you can do something like the following. +For example, you can do something like the following:: int my_midlayer_create_something() { @@ -199,8 +201,8 @@ For example, you can do something like the following. } - 4. Details - ---------- +4. Details +---------- Lifetime of a devres entry begins on devres allocation and finishes when it is released or destroyed (removed and freed) - no reference @@ -220,8 +222,8 @@ All devres interface functions can be called without context if the right gfp mask is given. - 5. Overhead - ----------- +5. Overhead +----------- Each devres bookkeeping info is allocated together with requested data area. With debug option turned off, bookkeeping info occupies 16 @@ -237,8 +239,8 @@ and 400 bytes on 32bit machine after naive conversion (we can certainly invest a bit more effort into libata core layer). - 6. List of managed interfaces - ----------------------------- +6. List of managed interfaces +----------------------------- CLOCK devm_clk_get() diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.rst similarity index 75% rename from Documentation/driver-model/driver.txt rename to Documentation/driver-model/driver.rst index d661e6f7e6a0..11d281506a04 100644 --- a/Documentation/driver-model/driver.txt +++ b/Documentation/driver-model/driver.rst @@ -1,5 +1,6 @@ - +============== Device Drivers +============== See the kerneldoc for the struct device_driver. @@ -26,50 +27,50 @@ Declaration As stated above, struct device_driver objects are statically allocated. Below is an example declaration of the eepro100 driver. This declaration is hypothetical only; it relies on the driver -being converted completely to the new model. +being converted completely to the new model:: -static struct device_driver eepro100_driver = { - .name = "eepro100", - .bus = &pci_bus_type, - - .probe = eepro100_probe, - .remove = eepro100_remove, - .suspend = eepro100_suspend, - .resume = eepro100_resume, -}; + static struct device_driver eepro100_driver = { + .name = "eepro100", + .bus = &pci_bus_type, + + .probe = eepro100_probe, + .remove = eepro100_remove, + .suspend = eepro100_suspend, + .resume = eepro100_resume, + }; Most drivers will not be able to be converted completely to the new model because the bus they belong to has a bus-specific structure with -bus-specific fields that cannot be generalized. +bus-specific fields that cannot be generalized. The most common example of this are device ID structures. A driver typically defines an array of device IDs that it supports. The format of these structures and the semantics for comparing device IDs are completely bus-specific. Defining them as bus-specific entities would -sacrifice type-safety, so we keep bus-specific structures around. +sacrifice type-safety, so we keep bus-specific structures around. Bus-specific drivers should include a generic struct device_driver in -the definition of the bus-specific driver. Like this: +the definition of the bus-specific driver. Like this:: -struct pci_driver { - const struct pci_device_id *id_table; - struct device_driver driver; -}; + struct pci_driver { + const struct pci_device_id *id_table; + struct device_driver driver; + }; A definition that included bus-specific fields would look like -(using the eepro100 driver again): +(using the eepro100 driver again):: -static struct pci_driver eepro100_driver = { - .id_table = eepro100_pci_tbl, - .driver = { + static struct pci_driver eepro100_driver = { + .id_table = eepro100_pci_tbl, + .driver = { .name = "eepro100", .bus = &pci_bus_type, .probe = eepro100_probe, .remove = eepro100_remove, .suspend = eepro100_suspend, .resume = eepro100_resume, - }, -}; + }, + }; Some may find the syntax of embedded struct initialization awkward or even a bit ugly. So far, it's the best way we've found to do what we want... @@ -77,12 +78,14 @@ even a bit ugly. So far, it's the best way we've found to do what we want... Registration ~~~~~~~~~~~~ -int driver_register(struct device_driver * drv); +:: + + int driver_register(struct device_driver *drv); The driver registers the structure on startup. For drivers that have no bus-specific fields (i.e. don't have a bus-specific driver structure), they would use driver_register and pass a pointer to their -struct device_driver object. +struct device_driver object. Most drivers, however, will have a bus-specific structure and will need to register with the bus using something like pci_driver_register. @@ -101,7 +104,7 @@ By defining wrapper functions, the transition to the new model can be made easier. Drivers can ignore the generic structure altogether and let the bus wrapper fill in the fields. For the callbacks, the bus can define generic callbacks that forward the call to the bus-specific -callbacks of the drivers. +callbacks of the drivers. This solution is intended to be only temporary. In order to get class information in the driver, the drivers must be modified anyway. Since @@ -113,16 +116,16 @@ Access ~~~~~~ Once the object has been registered, it may access the common fields of -the object, like the lock and the list of devices. +the object, like the lock and the list of devices:: -int driver_for_each_dev(struct device_driver * drv, void * data, - int (*callback)(struct device * dev, void * data)); + int driver_for_each_dev(struct device_driver *drv, void *data, + int (*callback)(struct device *dev, void *data)); The devices field is a list of all the devices that have been bound to the driver. The LDM core provides a helper function to operate on all the devices a driver controls. This helper locks the driver on each node access, and does proper reference counting on each device as it -accesses it. +accesses it. sysfs @@ -142,7 +145,9 @@ supports. Callbacks ~~~~~~~~~ - int (*probe) (struct device * dev); +:: + + int (*probe) (struct device *dev); The probe() entry is called in task context, with the bus's rwsem locked and the driver partially bound to the device. Drivers commonly use @@ -162,9 +167,9 @@ the driver to that device. A driver's probe() may return a negative errno value to indicate that the driver did not bind to this device, in which case it should have -released all resources it allocated. +released all resources it allocated:: - int (*remove) (struct device * dev); + int (*remove) (struct device *dev); remove is called to unbind a driver from a device. This may be called if a device is physically removed from the system, if the @@ -173,43 +178,46 @@ in other cases. It is up to the driver to determine if the device is present or not. It should free any resources allocated specifically for the -device; i.e. anything in the device's driver_data field. +device; i.e. anything in the device's driver_data field. If the device is still present, it should quiesce the device and place -it into a supported low-power state. +it into a supported low-power state:: - int (*suspend) (struct device * dev, pm_message_t state); + int (*suspend) (struct device *dev, pm_message_t state); -suspend is called to put the device in a low power state. +suspend is called to put the device in a low power state:: - int (*resume) (struct device * dev); + int (*resume) (struct device *dev); Resume is used to bring a device back from a low power state. Attributes ~~~~~~~~~~ -struct driver_attribute { - struct attribute attr; - ssize_t (*show)(struct device_driver *driver, char *buf); - ssize_t (*store)(struct device_driver *, const char * buf, size_t count); -}; -Device drivers can export attributes via their sysfs directories. +:: + + struct driver_attribute { + struct attribute attr; + ssize_t (*show)(struct device_driver *driver, char *buf); + ssize_t (*store)(struct device_driver *, const char *buf, size_t count); + }; + +Device drivers can export attributes via their sysfs directories. Drivers can declare attributes using a DRIVER_ATTR_RW and DRIVER_ATTR_RO macro that works identically to the DEVICE_ATTR_RW and DEVICE_ATTR_RO macros. -Example: +Example:: -DRIVER_ATTR_RW(debug); + DRIVER_ATTR_RW(debug); -This is equivalent to declaring: +This is equivalent to declaring:: -struct driver_attribute driver_attr_debug; + struct driver_attribute driver_attr_debug; This can then be used to add and remove the attribute from the -driver's directory using: +driver's directory using:: -int driver_create_file(struct device_driver *, const struct driver_attribute *); -void driver_remove_file(struct device_driver *, const struct driver_attribute *); + int driver_create_file(struct device_driver *, const struct driver_attribute *); + void driver_remove_file(struct device_driver *, const struct driver_attribute *); diff --git a/Documentation/driver-model/index.rst b/Documentation/driver-model/index.rst new file mode 100644 index 000000000000..9f85d579ce56 --- /dev/null +++ b/Documentation/driver-model/index.rst @@ -0,0 +1,26 @@ +:orphan: + +============ +Driver Model +============ + +.. toctree:: + :maxdepth: 1 + + binding + bus + class + design-patterns + device + devres + driver + overview + platform + porting + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/driver-model/overview.txt b/Documentation/driver-model/overview.rst similarity index 90% rename from Documentation/driver-model/overview.txt rename to Documentation/driver-model/overview.rst index 6a8f9a8075d8..d4d1e9b40e0c 100644 --- a/Documentation/driver-model/overview.txt +++ b/Documentation/driver-model/overview.rst @@ -1,4 +1,6 @@ +============================= The Linux Kernel Device Model +============================= Patrick Mochel @@ -41,14 +43,14 @@ data structure. These fields must still be accessed by the bus layers, and sometimes by the device-specific drivers. Other bus layers are encouraged to do what has been done for the PCI layer. -struct pci_dev now looks like this: +struct pci_dev now looks like this:: -struct pci_dev { + struct pci_dev { ... struct device dev; /* Generic device interface */ ... -}; + }; Note first that the struct device dev within the struct pci_dev is statically allocated. This means only one allocation on device discovery. @@ -80,26 +82,26 @@ easy. This has been accomplished by implementing a special purpose virtual file system named sysfs. Almost all mainstream Linux distros mount this filesystem automatically; you -can see some variation of the following in the output of the "mount" command: +can see some variation of the following in the output of the "mount" command:: -$ mount -... -none on /sys type sysfs (rw,noexec,nosuid,nodev) -... -$ + $ mount + ... + none on /sys type sysfs (rw,noexec,nosuid,nodev) + ... + $ The auto-mounting of sysfs is typically accomplished by an entry similar to -the following in the /etc/fstab file: +the following in the /etc/fstab file:: -none /sys sysfs defaults 0 0 + none /sys sysfs defaults 0 0 -or something similar in the /lib/init/fstab file on Debian-based systems: +or something similar in the /lib/init/fstab file on Debian-based systems:: -none /sys sysfs nodev,noexec,nosuid 0 0 + none /sys sysfs nodev,noexec,nosuid 0 0 -If sysfs is not automatically mounted, you can always do it manually with: +If sysfs is not automatically mounted, you can always do it manually with:: -# mount -t sysfs sysfs /sys + # mount -t sysfs sysfs /sys Whenever a device is inserted into the tree, a directory is created for it. This directory may be populated at each layer of discovery - the global layer, @@ -108,7 +110,7 @@ the bus layer, or the device layer. The global layer currently creates two files - 'name' and 'power'. The former only reports the name of the device. The latter reports the current power state of the device. It will also be used to set the current -power state. +power state. The bus layer may also create files for the devices it finds while probing the bus. For example, the PCI layer currently creates 'irq' and 'resource' files @@ -118,6 +120,5 @@ A device-specific driver may also export files in its directory to expose device-specific data or tunable interfaces. More information about the sysfs directory layout can be found in -the other documents in this directory and in the file +the other documents in this directory and in the file Documentation/filesystems/sysfs.txt. - diff --git a/Documentation/driver-model/platform.txt b/Documentation/driver-model/platform.rst similarity index 95% rename from Documentation/driver-model/platform.txt rename to Documentation/driver-model/platform.rst index 9d9e47dfc013..334dd4071ae4 100644 --- a/Documentation/driver-model/platform.txt +++ b/Documentation/driver-model/platform.rst @@ -1,5 +1,7 @@ +============================ Platform Devices and Drivers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +============================ + See for the driver model interface to the platform bus: platform_device, and platform_driver. This pseudo-bus is used to connect devices on busses with minimal infrastructure, @@ -19,15 +21,15 @@ be connected through a segment of some other kind of bus; but its registers will still be directly addressable. Platform devices are given a name, used in driver binding, and a -list of resources such as addresses and IRQs. +list of resources such as addresses and IRQs:: -struct platform_device { + struct platform_device { const char *name; u32 id; struct device dev; u32 num_resources; struct resource *resource; -}; + }; Platform drivers @@ -35,9 +37,9 @@ Platform drivers Platform drivers follow the standard driver model convention, where discovery/enumeration is handled outside the drivers, and drivers provide probe() and remove() methods. They support power management -and shutdown notifications using the standard conventions. +and shutdown notifications using the standard conventions:: -struct platform_driver { + struct platform_driver { int (*probe)(struct platform_device *); int (*remove)(struct platform_device *); void (*shutdown)(struct platform_device *); @@ -46,25 +48,25 @@ struct platform_driver { int (*resume_early)(struct platform_device *); int (*resume)(struct platform_device *); struct device_driver driver; -}; + }; Note that probe() should in general verify that the specified device hardware actually exists; sometimes platform setup code can't be sure. The probing can use device resources, including clocks, and device platform_data. -Platform drivers register themselves the normal way: +Platform drivers register themselves the normal way:: int platform_driver_register(struct platform_driver *drv); Or, in common situations where the device is known not to be hot-pluggable, the probe() routine can live in an init section to reduce the driver's -runtime memory footprint: +runtime memory footprint:: int platform_driver_probe(struct platform_driver *drv, int (*probe)(struct platform_device *)) Kernel modules can be composed of several platform drivers. The platform core -provides helpers to register and unregister an array of drivers: +provides helpers to register and unregister an array of drivers:: int __platform_register_drivers(struct platform_driver * const *drivers, unsigned int count, struct module *owner); @@ -73,7 +75,7 @@ provides helpers to register and unregister an array of drivers: If one of the drivers fails to register, all drivers registered up to that point will be unregistered in reverse order. Note that there is a convenience -macro that passes THIS_MODULE as owner parameter: +macro that passes THIS_MODULE as owner parameter:: #define platform_register_drivers(drivers, count) @@ -81,7 +83,7 @@ macro that passes THIS_MODULE as owner parameter: Device Enumeration ~~~~~~~~~~~~~~~~~~ As a rule, platform specific (and often board-specific) setup code will -register platform devices: +register platform devices:: int platform_device_register(struct platform_device *pdev); @@ -133,14 +135,14 @@ tend to already have "normal" modes, such as ones using device nodes that were created by PNP or by platform device setup. None the less, there are some APIs to support such legacy drivers. Avoid -using these calls except with such hotplug-deficient drivers. +using these calls except with such hotplug-deficient drivers:: struct platform_device *platform_device_alloc( const char *name, int id); You can use platform_device_alloc() to dynamically allocate a device, which you will then initialize with resources and platform_device_register(). -A better solution is usually: +A better solution is usually:: struct platform_device *platform_device_register_simple( const char *name, int id, diff --git a/Documentation/driver-model/porting.txt b/Documentation/driver-model/porting.rst similarity index 62% rename from Documentation/driver-model/porting.txt rename to Documentation/driver-model/porting.rst index 453053f1661f..ae4bf843c1d6 100644 --- a/Documentation/driver-model/porting.txt +++ b/Documentation/driver-model/porting.rst @@ -1,5 +1,6 @@ - +======================================= Porting Drivers to the New Driver Model +======================================= Patrick Mochel @@ -8,8 +9,8 @@ Patrick Mochel Overview -Please refer to Documentation/driver-model/*.txt for definitions of -various driver types and concepts. +Please refer to `Documentation/driver-model/*.rst` for definitions of +various driver types and concepts. Most of the work of porting devices drivers to the new model happens at the bus driver layer. This was intentional, to minimize the @@ -18,11 +19,11 @@ of bus drivers. In a nutshell, the driver model consists of a set of objects that can be embedded in larger, bus-specific objects. Fields in these generic -objects can replace fields in the bus-specific objects. +objects can replace fields in the bus-specific objects. The generic objects must be registered with the driver model core. By doing so, they will exported via the sysfs filesystem. sysfs can be -mounted by doing +mounted by doing:: # mount -t sysfs sysfs /sys @@ -30,108 +31,109 @@ mounted by doing The Process -Step 0: Read include/linux/device.h for object and function definitions. +Step 0: Read include/linux/device.h for object and function definitions. -Step 1: Registering the bus driver. +Step 1: Registering the bus driver. -- Define a struct bus_type for the bus driver. +- Define a struct bus_type for the bus driver:: -struct bus_type pci_bus_type = { - .name = "pci", -}; + struct bus_type pci_bus_type = { + .name = "pci", + }; - Register the bus type. + This should be done in the initialization function for the bus type, - which is usually the module_init(), or equivalent, function. + which is usually the module_init(), or equivalent, function:: -static int __init pci_driver_init(void) -{ - return bus_register(&pci_bus_type); -} + static int __init pci_driver_init(void) + { + return bus_register(&pci_bus_type); + } -subsys_initcall(pci_driver_init); + subsys_initcall(pci_driver_init); The bus type may be unregistered (if the bus driver may be compiled - as a module) by doing: + as a module) by doing:: bus_unregister(&pci_bus_type); -- Export the bus type for others to use. +- Export the bus type for others to use. - Other code may wish to reference the bus type, so declare it in a + Other code may wish to reference the bus type, so declare it in a shared header file and export the symbol. -From include/linux/pci.h: +From include/linux/pci.h:: -extern struct bus_type pci_bus_type; + extern struct bus_type pci_bus_type; -From file the above code appears in: +From file the above code appears in:: -EXPORT_SYMBOL(pci_bus_type); + EXPORT_SYMBOL(pci_bus_type); - This will cause the bus to show up in /sys/bus/pci/ with two - subdirectories: 'devices' and 'drivers'. + subdirectories: 'devices' and 'drivers':: -# tree -d /sys/bus/pci/ -/sys/bus/pci/ -|-- devices -`-- drivers + # tree -d /sys/bus/pci/ + /sys/bus/pci/ + |-- devices + `-- drivers -Step 2: Registering Devices. +Step 2: Registering Devices. struct device represents a single device. It mainly contains metadata -describing the relationship the device has to other entities. +describing the relationship the device has to other entities. -- Embed a struct device in the bus-specific device type. +- Embed a struct device in the bus-specific device type:: -struct pci_dev { - ... - struct device dev; /* Generic device interface */ - ... -}; + struct pci_dev { + ... + struct device dev; /* Generic device interface */ + ... + }; - It is recommended that the generic device not be the first item in + It is recommended that the generic device not be the first item in the struct to discourage programmers from doing mindless casts between the object types. Instead macros, or inline functions, - should be created to convert from the generic object type. + should be created to convert from the generic object type:: -#define to_pci_dev(n) container_of(n, struct pci_dev, dev) + #define to_pci_dev(n) container_of(n, struct pci_dev, dev) -or + or -static inline struct pci_dev * to_pci_dev(struct kobject * kobj) -{ + static inline struct pci_dev * to_pci_dev(struct kobject * kobj) + { return container_of(n, struct pci_dev, dev); -} + } - This allows the compiler to verify type-safety of the operations + This allows the compiler to verify type-safety of the operations that are performed (which is Good). - Initialize the device on registration. - When devices are discovered or registered with the bus type, the + When devices are discovered or registered with the bus type, the bus driver should initialize the generic device. The most important things to initialize are the bus_id, parent, and bus fields. The bus_id is an ASCII string that contains the device's address on the bus. The format of this string is bus-specific. This is - necessary for representing devices in sysfs. + necessary for representing devices in sysfs. parent is the physical parent of the device. It is important that - the bus driver sets this field correctly. + the bus driver sets this field correctly. The driver model maintains an ordered list of devices that it uses for power management. This list must be in order to guarantee that @@ -140,13 +142,13 @@ static inline struct pci_dev * to_pci_dev(struct kobject * kobj) devices. Also, the location of the device's sysfs directory depends on a - device's parent. sysfs exports a directory structure that mirrors + device's parent. sysfs exports a directory structure that mirrors the device hierarchy. Accurately setting the parent guarantees that sysfs will accurately represent the hierarchy. The device's bus field is a pointer to the bus type the device belongs to. This should be set to the bus_type that was declared - and initialized before. + and initialized before. Optionally, the bus driver may set the device's name and release fields. @@ -155,107 +157,107 @@ static inline struct pci_dev * to_pci_dev(struct kobject * kobj) "ATI Technologies Inc Radeon QD" - The release field is a callback that the driver model core calls - when the device has been removed, and all references to it have + The release field is a callback that the driver model core calls + when the device has been removed, and all references to it have been released. More on this in a moment. -- Register the device. +- Register the device. Once the generic device has been initialized, it can be registered - with the driver model core by doing: + with the driver model core by doing:: device_register(&dev->dev); - It can later be unregistered by doing: + It can later be unregistered by doing:: device_unregister(&dev->dev); - This should happen on buses that support hotpluggable devices. + This should happen on buses that support hotpluggable devices. If a bus driver unregisters a device, it should not immediately free - it. It should instead wait for the driver model core to call the - device's release method, then free the bus-specific object. + it. It should instead wait for the driver model core to call the + device's release method, then free the bus-specific object. (There may be other code that is currently referencing the device - structure, and it would be rude to free the device while that is + structure, and it would be rude to free the device while that is happening). - When the device is registered, a directory in sysfs is created. - The PCI tree in sysfs looks like: + When the device is registered, a directory in sysfs is created. + The PCI tree in sysfs looks like:: -/sys/devices/pci0/ -|-- 00:00.0 -|-- 00:01.0 -| `-- 01:00.0 -|-- 00:02.0 -| `-- 02:1f.0 -| `-- 03:00.0 -|-- 00:1e.0 -| `-- 04:04.0 -|-- 00:1f.0 -|-- 00:1f.1 -| |-- ide0 -| | |-- 0.0 -| | `-- 0.1 -| `-- ide1 -| `-- 1.0 -|-- 00:1f.2 -|-- 00:1f.3 -`-- 00:1f.5 + /sys/devices/pci0/ + |-- 00:00.0 + |-- 00:01.0 + | `-- 01:00.0 + |-- 00:02.0 + | `-- 02:1f.0 + | `-- 03:00.0 + |-- 00:1e.0 + | `-- 04:04.0 + |-- 00:1f.0 + |-- 00:1f.1 + | |-- ide0 + | | |-- 0.0 + | | `-- 0.1 + | `-- ide1 + | `-- 1.0 + |-- 00:1f.2 + |-- 00:1f.3 + `-- 00:1f.5 Also, symlinks are created in the bus's 'devices' directory - that point to the device's directory in the physical hierarchy. + that point to the device's directory in the physical hierarchy:: -/sys/bus/pci/devices/ -|-- 00:00.0 -> ../../../devices/pci0/00:00.0 -|-- 00:01.0 -> ../../../devices/pci0/00:01.0 -|-- 00:02.0 -> ../../../devices/pci0/00:02.0 -|-- 00:1e.0 -> ../../../devices/pci0/00:1e.0 -|-- 00:1f.0 -> ../../../devices/pci0/00:1f.0 -|-- 00:1f.1 -> ../../../devices/pci0/00:1f.1 -|-- 00:1f.2 -> ../../../devices/pci0/00:1f.2 -|-- 00:1f.3 -> ../../../devices/pci0/00:1f.3 -|-- 00:1f.5 -> ../../../devices/pci0/00:1f.5 -|-- 01:00.0 -> ../../../devices/pci0/00:01.0/01:00.0 -|-- 02:1f.0 -> ../../../devices/pci0/00:02.0/02:1f.0 -|-- 03:00.0 -> ../../../devices/pci0/00:02.0/02:1f.0/03:00.0 -`-- 04:04.0 -> ../../../devices/pci0/00:1e.0/04:04.0 + /sys/bus/pci/devices/ + |-- 00:00.0 -> ../../../devices/pci0/00:00.0 + |-- 00:01.0 -> ../../../devices/pci0/00:01.0 + |-- 00:02.0 -> ../../../devices/pci0/00:02.0 + |-- 00:1e.0 -> ../../../devices/pci0/00:1e.0 + |-- 00:1f.0 -> ../../../devices/pci0/00:1f.0 + |-- 00:1f.1 -> ../../../devices/pci0/00:1f.1 + |-- 00:1f.2 -> ../../../devices/pci0/00:1f.2 + |-- 00:1f.3 -> ../../../devices/pci0/00:1f.3 + |-- 00:1f.5 -> ../../../devices/pci0/00:1f.5 + |-- 01:00.0 -> ../../../devices/pci0/00:01.0/01:00.0 + |-- 02:1f.0 -> ../../../devices/pci0/00:02.0/02:1f.0 + |-- 03:00.0 -> ../../../devices/pci0/00:02.0/02:1f.0/03:00.0 + `-- 04:04.0 -> ../../../devices/pci0/00:1e.0/04:04.0 Step 3: Registering Drivers. struct device_driver is a simple driver structure that contains a set -of operations that the driver model core may call. +of operations that the driver model core may call. -- Embed a struct device_driver in the bus-specific driver. +- Embed a struct device_driver in the bus-specific driver. - Just like with devices, do something like: + Just like with devices, do something like:: -struct pci_driver { - ... - struct device_driver driver; -}; + struct pci_driver { + ... + struct device_driver driver; + }; -- Initialize the generic driver structure. +- Initialize the generic driver structure. When the driver registers with the bus (e.g. doing pci_register_driver()), initialize the necessary fields of the driver: the name and bus - fields. + fields. - Register the driver. - After the generic driver has been initialized, call + After the generic driver has been initialized, call:: driver_register(&drv->driver); to register the driver with the core. When the driver is unregistered from the bus, unregister it from the - core by doing: + core by doing:: driver_unregister(&drv->driver); @@ -265,15 +267,15 @@ struct pci_driver { - Sysfs representation. - Drivers are exported via sysfs in their bus's 'driver's directory. - For example: + Drivers are exported via sysfs in their bus's 'driver's directory. + For example:: -/sys/bus/pci/drivers/ -|-- 3c59x -|-- Ensoniq AudioPCI -|-- agpgart-amdk7 -|-- e100 -`-- serial + /sys/bus/pci/drivers/ + |-- 3c59x + |-- Ensoniq AudioPCI + |-- agpgart-amdk7 + |-- e100 + `-- serial Step 4: Define Generic Methods for Drivers. @@ -281,30 +283,30 @@ Step 4: Define Generic Methods for Drivers. struct device_driver defines a set of operations that the driver model core calls. Most of these operations are probably similar to operations the bus already defines for drivers, but taking different -parameters. +parameters. It would be difficult and tedious to force every driver on a bus to simultaneously convert their drivers to generic format. Instead, the bus driver should define single instances of the generic methods that -forward call to the bus-specific drivers. For instance: +forward call to the bus-specific drivers. For instance:: -static int pci_device_remove(struct device * dev) -{ - struct pci_dev * pci_dev = to_pci_dev(dev); - struct pci_driver * drv = pci_dev->driver; + static int pci_device_remove(struct device * dev) + { + struct pci_dev * pci_dev = to_pci_dev(dev); + struct pci_driver * drv = pci_dev->driver; - if (drv) { - if (drv->remove) - drv->remove(pci_dev); - pci_dev->driver = NULL; - } - return 0; -} + if (drv) { + if (drv->remove) + drv->remove(pci_dev); + pci_dev->driver = NULL; + } + return 0; + } The generic driver should be initialized with these methods before it -is registered. +is registered:: /* initialize common driver fields */ drv->driver.name = drv->name; @@ -320,23 +322,23 @@ is registered. Ideally, the bus should only initialize the fields if they are not already set. This allows the drivers to implement their own generic -methods. +methods. -Step 5: Support generic driver binding. +Step 5: Support generic driver binding. The model assumes that a device or driver can be dynamically registered with the bus at any time. When registration happens, devices must be bound to a driver, or drivers must be bound to all -devices that it supports. +devices that it supports. A driver typically contains a list of device IDs that it supports. The -bus driver compares these IDs to the IDs of devices registered with it. +bus driver compares these IDs to the IDs of devices registered with it. The format of the device IDs, and the semantics for comparing them are -bus-specific, so the generic model does attempt to generalize them. +bus-specific, so the generic model does attempt to generalize them. Instead, a bus may supply a method in struct bus_type that does the -comparison: +comparison:: int (*match)(struct device * dev, struct device_driver * drv); @@ -346,59 +348,59 @@ and zero otherwise. It may also return error code (for example not possible. When a device is registered, the bus's list of drivers is iterated -over. bus->match() is called for each one until a match is found. +over. bus->match() is called for each one until a match is found. When a driver is registered, the bus's list of devices is iterated over. bus->match() is called for each device that is not already -claimed by a driver. +claimed by a driver. When a device is successfully bound to a driver, device->driver is set, the device is added to a per-driver list of devices, and a symlink is created in the driver's sysfs directory that points to the -device's physical directory: +device's physical directory:: -/sys/bus/pci/drivers/ -|-- 3c59x -| `-- 00:0b.0 -> ../../../../devices/pci0/00:0b.0 -|-- Ensoniq AudioPCI -|-- agpgart-amdk7 -| `-- 00:00.0 -> ../../../../devices/pci0/00:00.0 -|-- e100 -| `-- 00:0c.0 -> ../../../../devices/pci0/00:0c.0 -`-- serial + /sys/bus/pci/drivers/ + |-- 3c59x + | `-- 00:0b.0 -> ../../../../devices/pci0/00:0b.0 + |-- Ensoniq AudioPCI + |-- agpgart-amdk7 + | `-- 00:00.0 -> ../../../../devices/pci0/00:00.0 + |-- e100 + | `-- 00:0c.0 -> ../../../../devices/pci0/00:0c.0 + `-- serial This driver binding should replace the existing driver binding -mechanism the bus currently uses. +mechanism the bus currently uses. Step 6: Supply a hotplug callback. Whenever a device is registered with the driver model core, the -userspace program /sbin/hotplug is called to notify userspace. +userspace program /sbin/hotplug is called to notify userspace. Users can define actions to perform when a device is inserted or -removed. +removed. The driver model core passes several arguments to userspace via environment variables, including - ACTION: set to 'add' or 'remove' -- DEVPATH: set to the device's physical path in sysfs. +- DEVPATH: set to the device's physical path in sysfs. A bus driver may also supply additional parameters for userspace to consume. To do this, a bus must implement the 'hotplug' method in -struct bus_type: +struct bus_type:: - int (*hotplug) (struct device *dev, char **envp, + int (*hotplug) (struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); -This is called immediately before /sbin/hotplug is executed. +This is called immediately before /sbin/hotplug is executed. Step 7: Cleaning up the bus driver. The generic bus, device, and driver structures provide several fields -that can replace those defined privately to the bus driver. +that can replace those defined privately to the bus driver. - Device list. @@ -407,36 +409,36 @@ type. This includes all devices on all instances of that bus type. An internal list that the bus uses may be removed, in favor of using this one. -The core provides an iterator to access these devices. +The core provides an iterator to access these devices:: -int bus_for_each_dev(struct bus_type * bus, struct device * start, - void * data, int (*fn)(struct device *, void *)); + int bus_for_each_dev(struct bus_type * bus, struct device * start, + void * data, int (*fn)(struct device *, void *)); - Driver list. struct bus_type also contains a list of all drivers registered with -it. An internal list of drivers that the bus driver maintains may -be removed in favor of using the generic one. +it. An internal list of drivers that the bus driver maintains may +be removed in favor of using the generic one. -The drivers may be iterated over, like devices: +The drivers may be iterated over, like devices:: -int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, - void * data, int (*fn)(struct device_driver *, void *)); + int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, + void * data, int (*fn)(struct device_driver *, void *)); Please see drivers/base/bus.c for more information. -- rwsem +- rwsem struct bus_type contains an rwsem that protects all core accesses to the device and driver lists. This can be used by the bus driver internally, and should be used when accessing the device or driver -lists the bus maintains. +lists the bus maintains. -- Device and driver fields. +- Device and driver fields. Some of the fields in struct device and struct device_driver duplicate fields in the bus-specific representations of these objects. Feel free @@ -444,4 +446,3 @@ to remove the bus-specific ones and favor the generic ones. Note though, that this will likely mean fixing up all the drivers that reference the bus-specific fields (though those should all be 1-line changes). - diff --git a/Documentation/eisa.txt b/Documentation/eisa.txt index 2806e5544e43..f388545a85a7 100644 --- a/Documentation/eisa.txt +++ b/Documentation/eisa.txt @@ -103,7 +103,7 @@ id_table an array of NULL terminated EISA id strings, (driver_data). driver a generic driver, such as described in - Documentation/driver-model/driver.txt. Only .name, + Documentation/driver-model/driver.rst. Only .name, .probe and .remove members are mandatory. =============== ==================================================== @@ -152,7 +152,7 @@ state set of flags indicating the state of the device. Current flags are EISA_CONFIG_ENABLED and EISA_CONFIG_FORCED. res set of four 256 bytes I/O regions allocated to this device dma_mask DMA mask set from the parent device. -dev generic device (see Documentation/driver-model/device.txt) +dev generic device (see Documentation/driver-model/device.rst) ======== ============================================================ You can get the 'struct eisa_device' from 'struct device' using the diff --git a/Documentation/hwmon/submitting-patches.rst b/Documentation/hwmon/submitting-patches.rst index f9796b9d9db6..d5b05d3e54ba 100644 --- a/Documentation/hwmon/submitting-patches.rst +++ b/Documentation/hwmon/submitting-patches.rst @@ -89,7 +89,7 @@ increase the chances of your change being accepted. console. Excessive logging can seriously affect system performance. * Use devres functions whenever possible to allocate resources. For rationale - and supported functions, please see Documentation/driver-model/devres.txt. + and supported functions, please see Documentation/driver-model/devres.rst. If a function is not supported by devres, consider using devm_add_action(). * If the driver has a detect function, make sure it is silent. Debug messages diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 4d1729853d1a..713903290385 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -5,7 +5,7 @@ * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs * - * Please see Documentation/driver-model/platform.txt for more + * Please see Documentation/driver-model/platform.rst for more * information. */ diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c index 6314225dbed0..3611a0571667 100644 --- a/drivers/gpio/gpio-cs5535.c +++ b/drivers/gpio/gpio-cs5535.c @@ -41,7 +41,7 @@ MODULE_PARM_DESC(mask, "GPIO channel mask."); /* * FIXME: convert this singleton driver to use the state container - * design pattern, see Documentation/driver-model/design-patterns.txt + * design pattern, see Documentation/driver-model/design-patterns.rst */ static struct cs5535_gpio_chip { struct gpio_chip chip; diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 7843abf4d44d..98a62072d81e 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -2237,7 +2237,7 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) struct ice_hw *hw; int err; - /* this driver uses devres, see Documentation/driver-model/devres.txt */ + /* this driver uses devres, see Documentation/driver-model/devres.rst */ err = pcim_enable_device(pdev); if (err) return err; diff --git a/scripts/coccinelle/free/devm_free.cocci b/scripts/coccinelle/free/devm_free.cocci index b2a2cf8bf81f..e32236a979a8 100644 --- a/scripts/coccinelle/free/devm_free.cocci +++ b/scripts/coccinelle/free/devm_free.cocci @@ -2,7 +2,7 @@ /// functions. Values allocated using the devm_functions are freed when /// the device is detached, and thus the use of the standard freeing /// function would cause a double free. -/// See Documentation/driver-model/devres.txt for more information. +/// See Documentation/driver-model/devres.rst for more information. /// /// A difficulty of detecting this problem is that the standard freeing /// function might be called from a different function than the one From bbc249f2b85916da489111f6d33bf1da2be444bb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:22:55 -0300 Subject: [PATCH 067/102] scripts: add an script to parse the ABI files Add a script to parse the Documentation/ABI files and produce an output with all entries inside an ABI (sub)directory. Right now, it outputs its contents on ReST format. It shouldn't be hard to make it produce other kind of outputs, since the ABI file parser is implemented in separate than the output generator. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 212 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100755 scripts/get_abi.pl diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl new file mode 100755 index 000000000000..f7c9944a833c --- /dev/null +++ b/scripts/get_abi.pl @@ -0,0 +1,212 @@ +#!/usr/bin/perl + +use strict; +use Pod::Usage; +use Getopt::Long; +use File::Find; +use Fcntl ':mode'; + +my $help; +my $man; +my $debug; + +GetOptions( + "debug|d+" => \$debug, + 'help|?' => \$help, + man => \$man +) or pod2usage(2); + +pod2usage(1) if $help; +pod2usage(-exitstatus => 0, -verbose => 2) if $man; + +pod2usage(2) if (scalar @ARGV != 1); + +my ($prefix) = @ARGV; + +require Data::Dumper if ($debug); + +my %data; + +# +# Displays an error message, printing file name and line +# +sub parse_error($$$$) { + my ($file, $ln, $msg, $data) = @_; + + print STDERR "file $file#$ln: $msg at\n\t$data"; +} + +# +# Parse an ABI file, storing its contents at %data +# +sub parse_abi { + my $file = $File::Find::name; + + my $mode = (stat($file))[2]; + return if ($mode & S_IFDIR); + return if ($file =~ m,/README,); + + my $name = $file; + $name =~ s,.*/,,; + + my $type = $file; + $type =~ s,.*/(.*)/.*,$1,; + + my $what; + my $new_what; + my $tag; + my $ln; + + print STDERR "Opening $file\n" if ($debug > 1); + open IN, $file; + while() { + $ln++; + if (m/^(\S+):\s*(.*)/i) { + my $new_tag = lc($1); + my $content = $2; + + if (!($new_tag =~ m/(what|date|kernelversion|contact|description|users)/)) { + if ($tag eq "description") { + $data{$what}->{$tag} .= "\n$content";; + $data{$what}->{$tag} =~ s/\n+$//; + next; + } else { + parse_error($file, $ln, "tag '$tag' is invalid", $_); + } + } + + if ($new_tag =~ m/what/) { + if ($tag =~ m/what/) { + $what .= ", " . $content; + } else { + $what = $content; + $new_what = 1; + } + $tag = $new_tag; + next; + } + + $tag = $new_tag; + + if ($new_what) { + $new_what = 0; + + $data{$what}->{type} = $type; + $data{$what}->{file} = $name; + print STDERR "\twhat: $what\n" if ($debug > 1); + } + + if (!$what) { + parse_error($file, $ln, "'What:' should come first:", $_); + next; + } + $data{$what}->{$tag} = $content; + next; + } + + # Silently ignore any headers before the database + next if (!$tag); + + if (m/^\s*(.*)/) { + $data{$what}->{$tag} .= "\n$1"; + $data{$what}->{$tag} =~ s/\n+$//; + next; + } + + # Everything else is error + parse_error($file, $ln, "Unexpected line:", $_); + } + close IN; +} + +# Outputs the output on ReST format +sub output_rest { + foreach my $what (sort keys %data) { + my $type = $data{$what}->{type}; + my $file = $data{$what}->{file}; + + my $w = $what; + $w =~ s/([\(\)\_\-\*\=\^\~\\])/\\$1/g; + + print "$w\n\n"; + print "- defined on file $file (type: $type)\n\n::\n\n"; + + my $desc = $data{$what}->{description}; + $desc =~ s/^\s+//; + + # Remove title markups from the description, as they won't work + $desc =~ s/\n[\-\*\=\^\~]+\n/\n/g; + + # put everything inside a code block + $desc =~ s/\n/\n /g; + + + if (!($desc =~ /^\s*$/)) { + print " $desc\n\n"; + } else { + print " DESCRIPTION MISSING\n\n"; + } + } +} + +# +# Parses all ABI files located at $prefix dir +# +find({wanted =>\&parse_abi, no_chdir => 1}, $prefix); + +print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); + +# +# Outputs an ReST file with the ABI contents +# +output_rest + + +__END__ + +=head1 NAME + +abi_book.pl - parse the Linux ABI files and produce a ReST book. + +=head1 SYNOPSIS + +B [--debug] ] + +=head1 OPTIONS + +=over 8 + +=item B<--debug> + +Put the script in verbose mode, useful for debugging. Can be called multiple +times, to increase verbosity. + +=item B<--help> + +Prints a brief help message and exits. + +=item B<--man> + +Prints the manual page and exits. + +=back + +=head1 DESCRIPTION + +Parse the Linux ABI files from ABI DIR (usually located at Documentation/ABI) +and produce a ReST book containing the Linux ABI. + +=head1 BUGS + +Report bugs to Mauro Carvalho Chehab + +=head1 COPYRIGHT + +Copyright (c) 2016 by Mauro Carvalho Chehab . + +License GPLv2: GNU GPL version 2 . + +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +=cut From 6619c6617a88e3b5e35b12aed069aabe35c370e0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:22:56 -0300 Subject: [PATCH 068/102] scripts/get_abi.pl: parse files with text at beginning It sounds usefult o parse files with has some text at the beginning. Add support for it. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 59 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index f7c9944a833c..ef9b6e108973 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -55,7 +55,10 @@ sub parse_abi { my $what; my $new_what; my $tag; + my $label; my $ln; + my $has_file; + my $xrefs; print STDERR "Opening $file\n" if ($debug > 1); open IN, $file; @@ -67,7 +70,7 @@ sub parse_abi { if (!($new_tag =~ m/(what|date|kernelversion|contact|description|users)/)) { if ($tag eq "description") { - $data{$what}->{$tag} .= "\n$content";; + $data{$what}->{$tag} .= "\n$content"; $data{$what}->{$tag} =~ s/\n+$//; next; } else { @@ -83,6 +86,25 @@ sub parse_abi { $new_what = 1; } $tag = $new_tag; + + if ($has_file) { + $label = "abi_" . $content . " "; + $label =~ tr/A-Z/a-z/; + + # Convert special chars to "_" + $label =~s/[\x00-\x2f]+/_/g; + $label =~s/[\x3a-\x40]+/_/g; + $label =~s/[\x7b-\xff]+/_/g; + $label =~ s,_+,_,g; + $label =~ s,_$,,; + + $data{$what}->{label} .= $label; + + # Escape special chars from content + $content =~s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g; + + $xrefs .= "- :ref:`$content <$label>`\n\n"; + } next; } @@ -104,8 +126,18 @@ sub parse_abi { next; } - # Silently ignore any headers before the database - next if (!$tag); + # Store any contents before the database + if (!$tag) { + next if (/^\n/); + + my $my_what = "File $name"; + $data{$my_what}->{what} = "File $name"; + $data{$my_what}->{type} = "File"; + $data{$my_what}->{file} = $name; + $data{$my_what}->{description} .= $_; + $has_file = 1; + next; + } if (m/^\s*(.*)/) { $data{$what}->{$tag} .= "\n$1"; @@ -117,6 +149,11 @@ sub parse_abi { parse_error($file, $ln, "Unexpected line:", $_); } close IN; + + if ($has_file) { + my $my_what = "File $name"; + $data{$my_what}->{xrefs} = $xrefs; + } } # Outputs the output on ReST format @@ -128,8 +165,17 @@ sub output_rest { my $w = $what; $w =~ s/([\(\)\_\-\*\=\^\~\\])/\\$1/g; + if ($data{$what}->{label}) { + my @labels = split(/\s/, $data{$what}->{label}); + foreach my $label (@labels) { + printf ".. _%s:\n\n", $label; + } + } + print "$w\n\n"; - print "- defined on file $file (type: $type)\n\n::\n\n"; + + print "- defined on file $file (type: $type)\n\n" if ($type ne "File"); + print "::\n\n"; my $desc = $data{$what}->{description}; $desc =~ s/^\s+//; @@ -144,8 +190,11 @@ sub output_rest { if (!($desc =~ /^\s*$/)) { print " $desc\n\n"; } else { - print " DESCRIPTION MISSING\n\n"; + print " DESCRIPTION MISSING for $what\n\n"; } + + printf "Has the following ABI:\n\n%s", $data{$what}->{xrefs} if ($data{$what}->{xrefs}); + } } From 4e6a6234da84496c6173ebe991060fe382ec4f15 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:22:57 -0300 Subject: [PATCH 069/102] scripts/get_abi.pl: avoid use literal blocks when not needed The usage of literal blocks make the document very complex, causing the browser to take a long time to load. On most ABI descriptions, they're a plain text, and don't require a literal block. So, add a logic there with identifies when a literal block is needed. As, on literal blocks, we need to respect the original document space, the most complex part of this patch is to preserve the original spacing where needed. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 104 +++++++++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 26 deletions(-) diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index ef9b6e108973..0ede9593c639 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -59,29 +59,34 @@ sub parse_abi { my $ln; my $has_file; my $xrefs; + my $space; print STDERR "Opening $file\n" if ($debug > 1); open IN, $file; while() { $ln++; - if (m/^(\S+):\s*(.*)/i) { + if (m/^(\S+)(:\s*)(.*)/i) { my $new_tag = lc($1); - my $content = $2; + my $sep = $2; + my $content = $3; if (!($new_tag =~ m/(what|date|kernelversion|contact|description|users)/)) { if ($tag eq "description") { - $data{$what}->{$tag} .= "\n$content"; - $data{$what}->{$tag} =~ s/\n+$//; - next; + # New "tag" is actually part of + # description. Don't consider it a tag + $new_tag = ""; } else { parse_error($file, $ln, "tag '$tag' is invalid", $_); } } if ($new_tag =~ m/what/) { + $space = ""; if ($tag =~ m/what/) { $what .= ", " . $content; } else { + parse_error($file, $ln, "What '$what' doesn't have a description", "") if ($what && !$data{$what}->{description}); + $what = $content; $new_what = 1; } @@ -108,25 +113,38 @@ sub parse_abi { next; } - $tag = $new_tag; + if ($new_tag) { + $tag = $new_tag; - if ($new_what) { - $new_what = 0; + if ($new_what) { + $new_what = 0; - $data{$what}->{type} = $type; - $data{$what}->{file} = $name; - print STDERR "\twhat: $what\n" if ($debug > 1); - } + $data{$what}->{type} = $type; + $data{$what}->{file} = $name; + print STDERR "\twhat: $what\n" if ($debug > 1); + } - if (!$what) { - parse_error($file, $ln, "'What:' should come first:", $_); + if (!$what) { + parse_error($file, $ln, "'What:' should come first:", $_); + next; + } + if ($tag eq "description") { + next if ($content =~ m/^\s*$/); + if ($content =~ m/^(\s*)(.*)/) { + my $new_content = $2; + $space = $new_tag . $sep . $1; + while ($space =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {} + $space =~ s/./ /g; + $data{$what}->{$tag} .= "$new_content\n"; + } + } else { + $data{$what}->{$tag} = $content; + } next; } - $data{$what}->{$tag} = $content; - next; } - # Store any contents before the database + # Store any contents before tags at the database if (!$tag) { next if (/^\n/); @@ -139,6 +157,32 @@ sub parse_abi { next; } + if ($tag eq "description") { + if (!$data{$what}->{description}) { + next if (m/^\s*\n/); + if (m/^(\s*)(.*)/) { + $space = $1; + while ($space =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {} + $data{$what}->{$tag} .= "$2\n"; + } + } else { + my $content = $_; + if (m/^\s*\n/) { + $data{$what}->{$tag} .= $content; + next; + } + + while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {} + $space = "" if (!($content =~ s/^($space)//)); + + # Compress spaces with tabs + $content =~ s<^ {8}> <\t>; + $content =~ s<^ {1,7}\t> <\t>; + $content =~ s< {1,7}\t> <\t>; + $data{$what}->{$tag} .= $content; + } + next; + } if (m/^\s*(.*)/) { $data{$what}->{$tag} .= "\n$1"; $data{$what}->{$tag} =~ s/\n+$//; @@ -165,6 +209,9 @@ sub output_rest { my $w = $what; $w =~ s/([\(\)\_\-\*\=\^\~\\])/\\$1/g; + my $bar = $w; + $bar =~ s/./-/g; + if ($data{$what}->{label}) { my @labels = split(/\s/, $data{$what}->{label}); foreach my $label (@labels) { @@ -172,10 +219,9 @@ sub output_rest { } } - print "$w\n\n"; + print "$w\n$bar\n\n"; print "- defined on file $file (type: $type)\n\n" if ($type ne "File"); - print "::\n\n"; my $desc = $data{$what}->{description}; $desc =~ s/^\s+//; @@ -183,18 +229,24 @@ sub output_rest { # Remove title markups from the description, as they won't work $desc =~ s/\n[\-\*\=\^\~]+\n/\n/g; - # put everything inside a code block - $desc =~ s/\n/\n /g; - - if (!($desc =~ /^\s*$/)) { - print " $desc\n\n"; + if ($desc =~ m/\:\n/ || $desc =~ m/\n[\t ]+/ || $desc =~ m/[\x00-\x08\x0b-\x1f\x7b-\xff]/) { + # put everything inside a code block + $desc =~ s/\n/\n /g; + + print "::\n\n"; + print " $desc\n\n"; + } else { + # Escape any special chars from description + $desc =~s/([\x00-\x08\x0b-\x1f\x21-\x2a\x2d\x2f\x3c-\x40\x5c\x5e-\x60\x7b-\xff])/\\$1/g; + + print "$desc\n\n"; + } } else { - print " DESCRIPTION MISSING for $what\n\n"; + print "DESCRIPTION MISSING for $what\n\n"; } printf "Has the following ABI:\n\n%s", $data{$what}->{xrefs} if ($data{$what}->{xrefs}); - } } From d0ebaf51d219b63f87f3dc1da4c9da501d0519a4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:22:58 -0300 Subject: [PATCH 070/102] scripts/get_abi.pl: split label naming from xref logic Instead of using a ReST compilant label while parsing, move the label to ReST output. That makes the parsing logic more generic, allowing it to provide other types of output. As a side effect, now all files used to generate the output will be output. We can later add command line arguments to filter. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 94 ++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 0ede9593c639..f84d321a72bb 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -49,17 +49,23 @@ sub parse_abi { my $name = $file; $name =~ s,.*/,,; + my $nametag = "File $name"; + $data{$nametag}->{what} = "File $name"; + $data{$nametag}->{type} = "File"; + $data{$nametag}->{file} = $name; + $data{$nametag}->{is_file} = 1; + my $type = $file; $type =~ s,.*/(.*)/.*,$1,; my $what; my $new_what; my $tag; - my $label; my $ln; - my $has_file; my $xrefs; my $space; + my @labels; + my $label; print STDERR "Opening $file\n" if ($debug > 1); open IN, $file; @@ -88,28 +94,13 @@ sub parse_abi { parse_error($file, $ln, "What '$what' doesn't have a description", "") if ($what && !$data{$what}->{description}); $what = $content; + $label = $content; $new_what = 1; } + push @labels, [($content, $label)]; $tag = $new_tag; - if ($has_file) { - $label = "abi_" . $content . " "; - $label =~ tr/A-Z/a-z/; - - # Convert special chars to "_" - $label =~s/[\x00-\x2f]+/_/g; - $label =~s/[\x3a-\x40]+/_/g; - $label =~s/[\x7b-\xff]+/_/g; - $label =~ s,_+,_,g; - $label =~ s,_$,,; - - $data{$what}->{label} .= $label; - - # Escape special chars from content - $content =~s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g; - - $xrefs .= "- :ref:`$content <$label>`\n\n"; - } + push @{$data{$nametag}->{xrefs}}, [($content, $label)] if ($data{$nametag}->{what}); next; } @@ -117,6 +108,9 @@ sub parse_abi { $tag = $new_tag; if ($new_what) { + @{$data{$what}->{label}} = @labels if ($data{$nametag}->{what}); + @labels = (); + $label = ""; $new_what = 0; $data{$what}->{type} = $type; @@ -145,15 +139,8 @@ sub parse_abi { } # Store any contents before tags at the database - if (!$tag) { - next if (/^\n/); - - my $my_what = "File $name"; - $data{$my_what}->{what} = "File $name"; - $data{$my_what}->{type} = "File"; - $data{$my_what}->{file} = $name; - $data{$my_what}->{description} .= $_; - $has_file = 1; + if (!$tag && $data{$nametag}->{what}) { + $data{$nametag}->{description} .= $_; next; } @@ -192,12 +179,8 @@ sub parse_abi { # Everything else is error parse_error($file, $ln, "Unexpected line:", $_); } + $data{$nametag}->{description} =~ s/^\n+//; close IN; - - if ($has_file) { - my $my_what = "File $name"; - $data{$my_what}->{xrefs} = $xrefs; - } } # Outputs the output on ReST format @@ -212,11 +195,22 @@ sub output_rest { my $bar = $w; $bar =~ s/./-/g; - if ($data{$what}->{label}) { - my @labels = split(/\s/, $data{$what}->{label}); - foreach my $label (@labels) { - printf ".. _%s:\n\n", $label; - } + foreach my $p (@{$data{$what}->{label}}) { + my ($content, $label) = @{$p}; + $label = "abi_" . $label . " "; + $label =~ tr/A-Z/a-z/; + + # Convert special chars to "_" + $label =~s/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff])/_/g; + $label =~ s,_+,_,g; + $label =~ s,_$,,; + + $data{$what}->{label} .= $label; + + printf ".. _%s:\n\n", $label; + + # only one label is enough + last; } print "$w\n$bar\n\n"; @@ -243,10 +237,28 @@ sub output_rest { print "$desc\n\n"; } } else { - print "DESCRIPTION MISSING for $what\n\n"; + print "DESCRIPTION MISSING for $what\n\n" if (!$data{$what}->{is_file}); } - printf "Has the following ABI:\n\n%s", $data{$what}->{xrefs} if ($data{$what}->{xrefs}); + if ($data{$what}->{xrefs}) { + printf "Has the following ABI:\n\n"; + + foreach my $p(@{$data{$what}->{xrefs}}) { + my ($content, $label) = @{$p}; + $label = "abi_" . $label . " "; + $label =~ tr/A-Z/a-z/; + + # Convert special chars to "_" + $label =~s/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff])/_/g; + $label =~ s,_+,_,g; + $label =~ s,_$,,; + + # Escape special chars from content + $content =~s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g; + + print "- :ref:`$content <$label>`\n\n"; + } + } } } From 33e3e9913e22481fd90fa0c50d4a04dded0ee1e1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:22:59 -0300 Subject: [PATCH 071/102] scripts/get_abi.pl: add support for searching for ABI symbols Change its syntax to allow switching between ReST output mode and a new search mode, with allows to seek for ABI symbols using regex. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 112 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 9 deletions(-) diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index f84d321a72bb..ecf6b91df7c4 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -9,9 +9,11 @@ use Fcntl ':mode'; my $help; my $man; my $debug; +my $prefix="Documentation/ABI"; GetOptions( "debug|d+" => \$debug, + "dir=s" => \$prefix, 'help|?' => \$help, man => \$man ) or pod2usage(2); @@ -19,9 +21,12 @@ GetOptions( pod2usage(1) if $help; pod2usage(-exitstatus => 0, -verbose => 2) if $man; -pod2usage(2) if (scalar @ARGV != 1); +pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2); -my ($prefix) = @ARGV; +my ($cmd, $arg) = @ARGV; + +pod2usage(2) if ($cmd ne "search" && $cmd ne "rest"); +pod2usage(2) if ($cmd eq "search" && !$arg); require Data::Dumper if ($debug); @@ -53,6 +58,7 @@ sub parse_abi { $data{$nametag}->{what} = "File $name"; $data{$nametag}->{type} = "File"; $data{$nametag}->{file} = $name; + $data{$nametag}->{filepath} = $file; $data{$nametag}->{is_file} = 1; my $type = $file; @@ -115,6 +121,7 @@ sub parse_abi { $data{$what}->{type} = $type; $data{$what}->{file} = $name; + $data{$what}->{filepath} = $file; print STDERR "\twhat: $what\n" if ($debug > 1); } @@ -183,7 +190,9 @@ sub parse_abi { close IN; } -# Outputs the output on ReST format +# +# Outputs the book on ReST format +# sub output_rest { foreach my $what (sort keys %data) { my $type = $data{$what}->{type}; @@ -262,6 +271,45 @@ sub output_rest { } } +# +# Searches for ABI symbols +# +sub search_symbols { + foreach my $what (sort keys %data) { + next if (!($what =~ m/($arg)/)); + + my $type = $data{$what}->{type}; + next if ($type eq "File"); + + my $file = $data{$what}->{filepath}; + + my $bar = $what; + $bar =~ s/./-/g; + + print "\n$what\n$bar\n\n"; + + my $kernelversion = $data{$what}->{kernelversion}; + my $contact = $data{$what}->{contact}; + my $users = $data{$what}->{users}; + my $date = $data{$what}->{date}; + my $desc = $data{$what}->{description}; + $kernelversion =~ s/^\s+//; + $contact =~ s/^\s+//; + $users =~ s/^\s+//; + $users =~ s/\n//g; + $date =~ s/^\s+//; + $desc =~ s/^\s+//; + + printf "Kernel version:\t\t%s\n", $kernelversion if ($kernelversion); + printf "Date:\t\t\t%s\n", $date if ($date); + printf "Contact:\t\t%s\n", $contact if ($contact); + printf "Users:\t\t\t%s\n", $users if ($users); + print "Defined on file:\t$file\n\n"; + print "Description:\n\n$desc"; + } +} + + # # Parses all ABI files located at $prefix dir # @@ -270,9 +318,13 @@ find({wanted =>\&parse_abi, no_chdir => 1}, $prefix); print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); # -# Outputs an ReST file with the ABI contents +# Handles the command # -output_rest +if ($cmd eq "rest") { + output_rest; +} else { + search_symbols; +} __END__ @@ -283,12 +335,27 @@ abi_book.pl - parse the Linux ABI files and produce a ReST book. =head1 SYNOPSIS -B [--debug] ] +B [--debug] [] + +Where can be: + +=over 8 + +B [SEARCH_REGEX] - search for [SEARCH_REGEX] inside ABI + +B - output the ABI in ReST markup language + +=back =head1 OPTIONS =over 8 +=item B<--dir> + +Changes the location of the ABI search. By default, it uses +the Documentation/ABI directory. + =item B<--debug> Put the script in verbose mode, useful for debugging. Can be called multiple @@ -306,8 +373,35 @@ Prints the manual page and exits. =head1 DESCRIPTION -Parse the Linux ABI files from ABI DIR (usually located at Documentation/ABI) -and produce a ReST book containing the Linux ABI. +Parse the Linux ABI files from ABI DIR (usually located at Documentation/ABI), +allowing to search for ABI symbols or to produce a ReST book containing +the Linux ABI documentation. + +=head1 EXAMPLES + +Search for all stable symbols with the word "usb": + +=over 8 + +$ scripts/get_abi.pl search usb --dir Documentation/ABI/stable + +=back + +Search for all symbols that match the regex expression "usb.*cap": + +=over 8 + +$ scripts/get_abi.pl search usb.*cap + +=back + +Output all obsoleted symbols in ReST format + +=over 8 + +$ scripts/get_abi.pl rest --dir Documentation/ABI/obsolete + +=back =head1 BUGS @@ -315,7 +409,7 @@ Report bugs to Mauro Carvalho Chehab =head1 COPYRIGHT -Copyright (c) 2016 by Mauro Carvalho Chehab . +Copyright (c) 2016-2017 by Mauro Carvalho Chehab . License GPLv2: GNU GPL version 2 . From 45f965179560f26227d87641da0d055d5751f49f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:23:00 -0300 Subject: [PATCH 072/102] scripts/get_abi.pl: represent what in tables Several entries at the ABI have multiple What: with the same description. Instead of showing those symbols as sections, let's show them as tables. That makes easier to read on the final output, and avoid too much recursion at Sphinx parsing. We need to put file references at the end, as we don't want non-file tables to be mangled with other entries. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index ecf6b91df7c4..7d454e359d25 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -193,16 +193,19 @@ sub parse_abi { # # Outputs the book on ReST format # + sub output_rest { - foreach my $what (sort keys %data) { + foreach my $what (sort { + ($data{$a}->{type} eq "File") cmp ($data{$b}->{type} eq "File") || + $a cmp $b + } keys %data) { my $type = $data{$what}->{type}; my $file = $data{$what}->{file}; + my $filepath = $data{$what}->{filepath}; my $w = $what; $w =~ s/([\(\)\_\-\*\=\^\~\\])/\\$1/g; - my $bar = $w; - $bar =~ s/./-/g; foreach my $p (@{$data{$what}->{label}}) { my ($content, $label) = @{$p}; @@ -222,9 +225,37 @@ sub output_rest { last; } - print "$w\n$bar\n\n"; - print "- defined on file $file (type: $type)\n\n" if ($type ne "File"); + $filepath =~ s,.*/(.*/.*),\1,;; + $filepath =~ s,[/\-],_,g;; + my $fileref = "abi_file_".$filepath; + + if ($type eq "File") { + my $bar = $w; + $bar =~ s/./-/g; + + print ".. _$fileref:\n\n"; + print "$w\n$bar\n\n"; + } else { + my @names = split /\s*,\s*/,$w; + + my $len = 0; + + foreach my $name (@names) { + $len = length($name) if (length($name) > $len); + } + + print "What:\n\n"; + + print "+-" . "-" x $len . "-+\n"; + foreach my $name (@names) { + printf "| %s", $name . " " x ($len - length($name)) . " |\n"; + print "+-" . "-" x $len . "-+\n"; + } + print "\n"; + } + + print "Defined on file :ref:`$file <$fileref>`\n\n" if ($type ne "File"); my $desc = $data{$what}->{description}; $desc =~ s/^\s+//; From 7d7ea8d2409fca0796f87676e489ed4ac0690a1b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:23:01 -0300 Subject: [PATCH 073/102] scripts/get_abi.pl: fix parse issues with some files A few files are failing to parse: Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats Documentation/ABI/testing/sysfs-class-pktcdvd Documentation/ABI/testing/sysfs-bus-nfit On all three files, the problem is that there is a ":" character at the initial file description. Improve the parse in order to handle those special cases. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 7d454e359d25..116f0c33c16d 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -87,7 +87,7 @@ sub parse_abi { # New "tag" is actually part of # description. Don't consider it a tag $new_tag = ""; - } else { + } elsif ($tag ne "") { parse_error($file, $ln, "tag '$tag' is invalid", $_); } } @@ -110,7 +110,7 @@ sub parse_abi { next; } - if ($new_tag) { + if ($tag ne "" && $new_tag) { $tag = $new_tag; if ($new_what) { From 2e7ce05593b39f0a947819ca8b73f2185f372f12 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:23:02 -0300 Subject: [PATCH 074/102] scripts/get_abi.pl: avoid creating duplicate names The file the Documentation/ABI/testing/sysfs-class-power has voltage_min, voltage_max and voltage_now symbols duplicated. They are defined first for "General Properties" and then for "USB Properties". This cause those warnings: get_abi.pl rest --dir $srctree/Documentation/ABI/testing:26933: WARNING: Duplicate explicit target name: "abi_sys_class_power_supply_supply_name_voltage_max". get_abi.pl rest --dir $srctree/Documentation/ABI/testing:26968: WARNING: Duplicate explicit target name: "abi_sys_class_power_supply_supply_name_voltage_min". get_abi.pl rest --dir $srctree/Documentation/ABI/testing:27008: WARNING: Duplicate explicit target name: "abi_sys_class_power_supply_supply_name_voltage_now". And, as the references are not valid, it will also generate warnings about links to undefined references. Fix it by storing labels into a hash table and, when a duplicated one is found, appending random characters at the end. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 116f0c33c16d..329ace635ac2 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -194,6 +194,8 @@ sub parse_abi { # Outputs the book on ReST format # +my %labels; + sub output_rest { foreach my $what (sort { ($data{$a}->{type} eq "File") cmp ($data{$b}->{type} eq "File") || @@ -217,6 +219,13 @@ sub output_rest { $label =~ s,_+,_,g; $label =~ s,_$,,; + # Avoid duplicated labels + while (defined($labels{$label})) { + my @chars = ("A".."Z", "a".."z"); + $label .= $chars[rand @chars]; + } + $labels{$label} = 1; + $data{$what}->{label} .= $label; printf ".. _%s:\n\n", $label; From 2c0700e7afa40330f2d21defe2a7bffcb0eecb1e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:23:03 -0300 Subject: [PATCH 075/102] scripts/get_abi.pl: add a handler for invalid "where" tag The ABI README file doesn't provide any meaning for a Where: tag. Yet, a few ABI symbols use it. So, make the parser handle it, emitting a warning. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 329ace635ac2..c5038a0a7313 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -92,6 +92,12 @@ sub parse_abi { } } + # Invalid, but it is a common mistake + if ($new_tag eq "where") { + parse_error($file, $ln, "tag 'Where' is invalid. Should be 'What:' instead", $_); + $new_tag = "what"; + } + if ($new_tag =~ m/what/) { $space = ""; if ($tag =~ m/what/) { From 7ce7b89bf565b4e86d37fd32577272e98d3359cd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:23:04 -0300 Subject: [PATCH 076/102] scripts/get_abi.pl: add a validate command Sometimes, we just want the parser to retrieve all symbols from ABI, in order to check for parsing errors. So, add a new "validate" command. While here, update the man/help pages. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index c5038a0a7313..774e9b809ead 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -25,7 +25,7 @@ pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2); my ($cmd, $arg) = @ARGV; -pod2usage(2) if ($cmd ne "search" && $cmd ne "rest"); +pod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate"); pod2usage(2) if ($cmd eq "search" && !$arg); require Data::Dumper if ($debug); @@ -82,7 +82,7 @@ sub parse_abi { my $sep = $2; my $content = $3; - if (!($new_tag =~ m/(what|date|kernelversion|contact|description|users)/)) { + if (!($new_tag =~ m/(what|where|date|kernelversion|contact|description|users)/)) { if ($tag eq "description") { # New "tag" is actually part of # description. Don't consider it a tag @@ -368,7 +368,7 @@ print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); # if ($cmd eq "rest") { output_rest; -} else { +} elsif ($cmd eq "search") { search_symbols; } @@ -381,7 +381,7 @@ abi_book.pl - parse the Linux ABI files and produce a ReST book. =head1 SYNOPSIS -B [--debug] [] +B [--debug] [--man] [--help] [--dir=] [] Where can be: @@ -389,7 +389,9 @@ Where can be: B [SEARCH_REGEX] - search for [SEARCH_REGEX] inside ABI -B - output the ABI in ReST markup language +B - output the ABI in ReST markup language + +B - validate the ABI contents =back @@ -451,11 +453,11 @@ $ scripts/get_abi.pl rest --dir Documentation/ABI/obsolete =head1 BUGS -Report bugs to Mauro Carvalho Chehab +Report bugs to Mauro Carvalho Chehab =head1 COPYRIGHT -Copyright (c) 2016-2017 by Mauro Carvalho Chehab . +Copyright (c) 2016-2019 by Mauro Carvalho Chehab . License GPLv2: GNU GPL version 2 . From ecb351f1c4475d11ce6b4fa443fe71764027d409 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jun 2019 14:23:10 -0300 Subject: [PATCH 077/102] doc: ABI scripts: add a SPDX header file released under GPL v2. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 774e9b809ead..c738cb795514 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -1,4 +1,5 @@ #!/usr/bin/perl +# SPDX-License-Identifier: GPL-2.0 use strict; use Pod::Usage; From 4056e79faa2dc8352634b594991b4b210d724e6f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Jun 2019 06:54:25 -0300 Subject: [PATCH 078/102] ABI: sysfs-driver-mlxreg-io: fix the what fields The author of this file should be given an award for creativity: the What: fields on this file technically fulfills the description at README. Yet, the way it is, it can't be parsed on a script, and if someone would try to do something like: grep hwmon*/jtag_enable It wouldn't find anything. Fix the What fields in a way that it can be parseable by a script and other search tools. Signed-off-by: Mauro Carvalho Chehab Acked-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- .../ABI/stable/sysfs-driver-mlxreg-io | 45 ++++++++----------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/Documentation/ABI/stable/sysfs-driver-mlxreg-io b/Documentation/ABI/stable/sysfs-driver-mlxreg-io index 156319fc5b80..3544968f43cc 100644 --- a/Documentation/ABI/stable/sysfs-driver-mlxreg-io +++ b/Documentation/ABI/stable/sysfs-driver-mlxreg-io @@ -1,5 +1,4 @@ -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - asic_health +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/asic_health Date: June 2018 KernelVersion: 4.19 @@ -9,9 +8,8 @@ Description: This file shows ASIC health status. The possible values are: The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - cpld1_version - cpld2_version +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld1_version +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld2_version Date: June 2018 KernelVersion: 4.19 Contact: Vadim Pasternak @@ -20,8 +18,7 @@ Description: These files show with which CPLD versions have been burned The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - fan_dir +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/fan_dir Date: December 2018 KernelVersion: 5.0 @@ -32,8 +29,7 @@ Description: This file shows the system fans direction: The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - jtag_enable +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/jtag_enable Date: November 2018 KernelVersion: 5.0 @@ -43,8 +39,7 @@ Description: These files show with which CPLD versions have been burned The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - jtag_enable +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/jtag_enable Date: November 2018 KernelVersion: 5.0 @@ -87,16 +82,15 @@ Description: These files allow asserting system power cycling, switching The files are write only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - reset_aux_pwr_or_ref - reset_asic_thermal - reset_hotswap_or_halt - reset_hotswap_or_wd - reset_fw_reset - reset_long_pb - reset_main_pwr_fail - reset_short_pb - reset_sw_reset +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_aux_pwr_or_ref +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_asic_thermal +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_hotswap_or_halt +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_hotswap_or_wd +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_fw_reset +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_long_pb +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_main_pwr_fail +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_short_pb +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_sw_reset Date: June 2018 KernelVersion: 4.19 Contact: Vadim Pasternak @@ -110,11 +104,10 @@ Description: These files show the system reset cause, as following: power The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - reset_comex_pwr_fail - reset_from_comex - reset_system - reset_voltmon_upgrade_fail +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_comex_pwr_fail +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_from_comex +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_system +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_voltmon_upgrade_fail Date: November 2018 KernelVersion: 5.0 From 65bbdd49b4722a09901469e57497850311c017dc Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 14 Jun 2019 10:43:11 +0100 Subject: [PATCH 079/102] lkdtm: remove redundant initialization of ret The variable ret is being initialized with the value -EINVAL however this value is never read and ret is being re-assigned later on. Hence the initialization is redundant and can be removed. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- drivers/misc/lkdtm/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index bae3b3763f3e..d416359daf06 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -387,7 +387,7 @@ static int __init lkdtm_module_init(void) { struct crashpoint *crashpoint = NULL; const struct crashtype *crashtype = NULL; - int ret = -EINVAL; + int ret; int i; /* Neither or both of these need to be set */ From 209de31034522fae53f789f52c9461c557011d70 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Fri, 14 Jun 2019 18:53:56 +0100 Subject: [PATCH 080/102] staging: most-core: Use bus_find_device_by_name Use bus_find_device_by_name() helper instead of writing our own helper. Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: Christian Gromm Cc: "Gustavo A. R. Silva" Cc: Colin Ian King Signed-off-by: Suzuki K Poulose Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/core.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c index 86a8545c8d97..b9841adb7181 100644 --- a/drivers/staging/most/core.c +++ b/drivers/staging/most/core.c @@ -561,13 +561,6 @@ static int split_string(char *buf, char **a, char **b, char **c, char **d) return 0; } -static int match_bus_dev(struct device *dev, void *data) -{ - char *mdev_name = data; - - return !strcmp(dev_name(dev), mdev_name); -} - /** * get_channel - get pointer to channel * @mdev: name of the device interface @@ -579,7 +572,7 @@ static struct most_channel *get_channel(char *mdev, char *mdev_ch) struct most_interface *iface; struct most_channel *c, *tmp; - dev = bus_find_device(&mc.bus, NULL, mdev, match_bus_dev); + dev = bus_find_device_by_name(&mc.bus, NULL, mdev); if (!dev) return NULL; iface = to_most_interface(dev); From 29d14b668d2f2e7b692525ee3f69bf12b06be0f0 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Fri, 14 Jun 2019 18:53:57 +0100 Subject: [PATCH 081/102] mfd: Remove unused helper syscon_regmap_lookup_by_pdevname Nobody uses the exported helper syscon_regmap_lookup_by_pdevname, to lookup a device by name. Let us remove it. Suggested-by: Arnd Bergman Cc: Arnd Bergman Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Signed-off-by: Suzuki K Poulose Signed-off-by: Greg Kroah-Hartman --- drivers/mfd/syscon.c | 21 --------------------- include/linux/mfd/syscon.h | 6 ------ 2 files changed, 27 deletions(-) diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 8ce1e41d632c..b65e585fc8c6 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -190,27 +190,6 @@ struct regmap *syscon_regmap_lookup_by_compatible(const char *s) } EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible); -static int syscon_match_pdevname(struct device *dev, void *data) -{ - return !strcmp(dev_name(dev), (const char *)data); -} - -struct regmap *syscon_regmap_lookup_by_pdevname(const char *s) -{ - struct device *dev; - struct syscon *syscon; - - dev = driver_find_device(&syscon_driver.driver, NULL, (void *)s, - syscon_match_pdevname); - if (!dev) - return ERR_PTR(-EPROBE_DEFER); - - syscon = dev_get_drvdata(dev); - - return syscon->regmap; -} -EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_pdevname); - struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np, const char *property) { diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h index f0273c9e972b..8cfda0554381 100644 --- a/include/linux/mfd/syscon.h +++ b/include/linux/mfd/syscon.h @@ -19,7 +19,6 @@ struct device_node; #ifdef CONFIG_MFD_SYSCON extern struct regmap *syscon_node_to_regmap(struct device_node *np); extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s); -extern struct regmap *syscon_regmap_lookup_by_pdevname(const char *s); extern struct regmap *syscon_regmap_lookup_by_phandle( struct device_node *np, const char *property); @@ -34,11 +33,6 @@ static inline struct regmap *syscon_regmap_lookup_by_compatible(const char *s) return ERR_PTR(-ENOTSUPP); } -static inline struct regmap *syscon_regmap_lookup_by_pdevname(const char *s) -{ - return ERR_PTR(-ENOTSUPP); -} - static inline struct regmap *syscon_regmap_lookup_by_phandle( struct device_node *np, const char *property) From e6374f6b2e9c9f9a7cf5418157ad7f30f3abd70e Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Fri, 14 Jun 2019 18:53:58 +0100 Subject: [PATCH 082/102] acpi: utils: Cleanup acpi_dev_match_cb The prototype of bus_find_device() will be unified with that of class_find_device() subsequently, but for this purpose the callback functions passed to it need to take (const void *) as the second argument. Consequently, they cannot modify the memory pointed to by that argument which currently is not the case for acpi_dev_match_cb(). However, acpi_dev_match_cb() really need not modify the "match" object passed to it, because acpi_dev_get_first_match_dev() which uses it via bus_find_device() can easily convert the result of bus_find_device() into the pointer to return. For this reason, update acpi_dev_match_cb() to avoid the redundant memory updates. Cc: Len Brown Cc: linux-acpi@vger.kernel.org Signed-off-by: Suzuki K Poulose Reviewed-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/utils.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 7def63ab00c0..1391b63cadfd 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -725,8 +725,6 @@ bool acpi_dev_found(const char *hid) EXPORT_SYMBOL(acpi_dev_found); struct acpi_dev_match_info { - const char *dev_name; - struct acpi_device *adev; struct acpi_device_id hid[2]; const char *uid; s64 hrv; @@ -746,9 +744,6 @@ static int acpi_dev_match_cb(struct device *dev, void *data) strcmp(adev->pnp.unique_id, match->uid))) return 0; - match->dev_name = acpi_dev_name(adev); - match->adev = adev; - if (match->hrv == -1) return 1; @@ -818,7 +813,7 @@ acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv) match.hrv = hrv; dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); - return dev ? match.adev : NULL; + return dev ? to_acpi_device(dev) : NULL; } EXPORT_SYMBOL(acpi_dev_get_first_match_dev); From 418e3ea157efb0eb2c6dd412a8d5f052477c7f5a Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Fri, 14 Jun 2019 18:53:59 +0100 Subject: [PATCH 083/102] bus_find_device: Unify the match callback with class_find_device There is an arbitrary difference between the prototypes of bus_find_device() and class_find_device() preventing their callers from passing the same pair of data and match() arguments to both of them, which is the const qualifier used in the prototype of class_find_device(). If that qualifier is also used in the bus_find_device() prototype, it will be possible to pass the same match() callback function to both bus_find_device() and class_find_device(), which will allow some optimizations to be made in order to avoid code duplication going forward. Also with that, constify the "data" parameter as it is passed as a const to the match function. For this reason, change the prototype of bus_find_device() to match the prototype of class_find_device() and adjust its callers to use the const qualifier in accordance with the new prototype of it. Cc: Alexander Shishkin Cc: Andrew Lunn Cc: Andreas Noever Cc: Arnd Bergmann Cc: Bjorn Helgaas Cc: Corey Minyard Cc: Christian Borntraeger Cc: David Kershner Cc: "David S. Miller" Cc: David Airlie Cc: Felipe Balbi Cc: Frank Rowand Cc: Grygorii Strashko Cc: Harald Freudenberger Cc: Hartmut Knaack Cc: Heiko Stuebner Cc: Jason Gunthorpe Cc: Jonathan Cameron Cc: "James E.J. Bottomley" Cc: Len Brown Cc: Mark Brown Cc: Michael Ellerman Cc: Michael Jamet Cc: "Martin K. Petersen" Cc: Peter Oberparleiter Cc: Sebastian Ott Cc: Srinivas Kandagatla Cc: Yehezkel Bernat Cc: rafael@kernel.org Acked-by: Corey Minyard Acked-by: David Kershner Acked-by: Mark Brown Acked-by: Rafael J. Wysocki Acked-by: Srinivas Kandagatla Acked-by: Wolfram Sang # for the I2C parts Acked-by: Rob Herring Signed-off-by: Suzuki K Poulose Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/platforms/pseries/ibmebus.c | 4 ++-- drivers/acpi/acpi_lpss.c | 4 ++-- drivers/acpi/sleep.c | 2 +- drivers/acpi/utils.c | 4 ++-- drivers/base/bus.c | 6 +++--- drivers/base/devcon.c | 2 +- drivers/char/ipmi/ipmi_si_platform.c | 2 +- drivers/firmware/efi/dev-path-parser.c | 4 ++-- drivers/gpu/drm/drm_mipi_dsi.c | 2 +- drivers/hwtracing/coresight/coresight.c | 6 +++--- drivers/hwtracing/coresight/of_coresight.c | 2 +- drivers/hwtracing/intel_th/core.c | 5 ++--- drivers/i2c/i2c-core-acpi.c | 4 ++-- drivers/i2c/i2c-core-of.c | 4 ++-- drivers/iio/inkern.c | 2 +- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 2 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 2 +- drivers/net/ethernet/ti/cpsw-phy-sel.c | 4 ++-- drivers/net/ethernet/ti/davinci_emac.c | 2 +- drivers/net/ethernet/toshiba/tc35815.c | 4 ++-- drivers/nvmem/core.c | 2 +- drivers/of/of_mdio.c | 2 +- drivers/of/platform.c | 2 +- drivers/pci/probe.c | 2 +- drivers/pci/search.c | 4 ++-- drivers/s390/cio/css.c | 4 ++-- drivers/s390/cio/device.c | 4 ++-- drivers/s390/cio/scm.c | 4 ++-- drivers/s390/crypto/ap_bus.c | 8 ++++---- drivers/scsi/scsi_proc.c | 2 +- drivers/spi/spi.c | 4 ++-- drivers/thunderbolt/switch.c | 4 ++-- drivers/usb/core/devio.c | 4 ++-- drivers/usb/core/usb.c | 4 ++-- drivers/usb/phy/phy-am335x-control.c | 4 ++-- drivers/usb/phy/phy-isp1301.c | 4 ++-- drivers/visorbus/visorbus_main.c | 4 ++-- include/linux/device.h | 4 ++-- sound/soc/rockchip/rk3399_gru_sound.c | 2 +- 39 files changed, 67 insertions(+), 68 deletions(-) diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c index 84e8ec4011ba..b91eb0929ed1 100644 --- a/arch/powerpc/platforms/pseries/ibmebus.c +++ b/arch/powerpc/platforms/pseries/ibmebus.c @@ -147,13 +147,13 @@ static const struct dma_map_ops ibmebus_dma_ops = { .unmap_page = ibmebus_unmap_page, }; -static int ibmebus_match_path(struct device *dev, void *data) +static int ibmebus_match_path(struct device *dev, const void *data) { struct device_node *dn = to_platform_device(dev)->dev.of_node; return (of_find_node_by_path(data) == dn); } -static int ibmebus_match_node(struct device *dev, void *data) +static int ibmebus_match_node(struct device *dev, const void *data) { return to_platform_device(dev)->dev.of_node == data; } diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index cf768608437e..dc2ca78748a2 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -511,10 +511,10 @@ struct hid_uid { const char *uid; }; -static int match_hid_uid(struct device *dev, void *data) +static int match_hid_uid(struct device *dev, const void *data) { struct acpi_device *adev = ACPI_COMPANION(dev); - struct hid_uid *id = data; + const struct hid_uid *id = data; if (!adev) return 0; diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index a34deccd7317..fcf4386ecc78 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -454,7 +454,7 @@ static int acpi_pm_prepare(void) return error; } -static int find_powerf_dev(struct device *dev, void *data) +static int find_powerf_dev(struct device *dev, const void *data) { struct acpi_device *device = to_acpi_device(dev); const char *hid = acpi_device_hid(device); diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 1391b63cadfd..e3974a8f8fd4 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -730,10 +730,10 @@ struct acpi_dev_match_info { s64 hrv; }; -static int acpi_dev_match_cb(struct device *dev, void *data) +static int acpi_dev_match_cb(struct device *dev, const void *data) { struct acpi_device *adev = to_acpi_device(dev); - struct acpi_dev_match_info *match = data; + const struct acpi_dev_match_info *match = data; unsigned long long hrv; acpi_status status; diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 0a58e969f8b7..df3cac739813 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -323,8 +323,8 @@ EXPORT_SYMBOL_GPL(bus_for_each_dev); * return to the caller and not iterate over any more devices. */ struct device *bus_find_device(struct bus_type *bus, - struct device *start, void *data, - int (*match)(struct device *dev, void *data)) + struct device *start, const void *data, + int (*match)(struct device *dev, const void *data)) { struct klist_iter i; struct device *dev; @@ -342,7 +342,7 @@ struct device *bus_find_device(struct bus_type *bus, } EXPORT_SYMBOL_GPL(bus_find_device); -static int match_name(struct device *dev, void *data) +static int match_name(struct device *dev, const void *data) { const char *name = data; diff --git a/drivers/base/devcon.c b/drivers/base/devcon.c index 04db9ae235e4..ac026d5fc672 100644 --- a/drivers/base/devcon.c +++ b/drivers/base/devcon.c @@ -107,7 +107,7 @@ static struct bus_type *generic_match_buses[] = { NULL, }; -static int device_fwnode_match(struct device *dev, void *fwnode) +static int device_fwnode_match(struct device *dev, const void *fwnode) { return dev_fwnode(dev) == fwnode; } diff --git a/drivers/char/ipmi/ipmi_si_platform.c b/drivers/char/ipmi/ipmi_si_platform.c index f2a91c4d8cab..fd94c4238449 100644 --- a/drivers/char/ipmi/ipmi_si_platform.c +++ b/drivers/char/ipmi/ipmi_si_platform.c @@ -426,7 +426,7 @@ static int ipmi_remove(struct platform_device *pdev) return ipmi_si_remove_by_dev(&pdev->dev); } -static int pdev_match_name(struct device *dev, void *data) +static int pdev_match_name(struct device *dev, const void *data) { struct platform_device *pdev = to_platform_device(dev); const char *name = data; diff --git a/drivers/firmware/efi/dev-path-parser.c b/drivers/firmware/efi/dev-path-parser.c index 85ec99f97841..20123384271c 100644 --- a/drivers/firmware/efi/dev-path-parser.c +++ b/drivers/firmware/efi/dev-path-parser.c @@ -17,9 +17,9 @@ struct acpi_hid_uid { char uid[11]; /* UINT_MAX + null byte */ }; -static int __init match_acpi_dev(struct device *dev, void *data) +static int __init match_acpi_dev(struct device *dev, const void *data) { - struct acpi_hid_uid hid_uid = *(struct acpi_hid_uid *)data; + struct acpi_hid_uid hid_uid = *(const struct acpi_hid_uid *)data; struct acpi_device *adev = to_acpi_device(dev); if (acpi_match_device_ids(adev, hid_uid.hid)) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 80b75501f5c6..ad19df0686c9 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -93,7 +93,7 @@ static struct bus_type mipi_dsi_bus_type = { .pm = &mipi_dsi_device_pm_ops, }; -static int of_device_match(struct device *dev, void *data) +static int of_device_match(struct device *dev, const void *data) { return dev->of_node == data; } diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 4b130281236a..b67ab6a09587 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -498,9 +498,9 @@ struct coresight_device *coresight_get_sink(struct list_head *path) return csdev; } -static int coresight_enabled_sink(struct device *dev, void *data) +static int coresight_enabled_sink(struct device *dev, const void *data) { - bool *reset = data; + const bool *reset = data; struct coresight_device *csdev = to_coresight_device(dev); if ((csdev->type == CORESIGHT_DEV_TYPE_SINK || @@ -544,7 +544,7 @@ struct coresight_device *coresight_get_enabled_sink(bool deactivate) return dev ? to_coresight_device(dev) : NULL; } -static int coresight_sink_by_id(struct device *dev, void *data) +static int coresight_sink_by_id(struct device *dev, const void *data) { struct coresight_device *csdev = to_coresight_device(dev); unsigned long hash; diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 7045930fc958..3fc200ec1c03 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -18,7 +18,7 @@ #include -static int of_dev_node_match(struct device *dev, void *data) +static int of_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data; } diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 033dce563c99..55922896d862 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -789,10 +789,9 @@ static int intel_th_populate(struct intel_th *th) return 0; } -static int match_devt(struct device *dev, void *data) +static int match_devt(struct device *dev, const void *data) { - dev_t devt = (dev_t)(unsigned long)data; - + dev_t devt = (dev_t)(unsigned long)(void *)data; return dev->devt == devt; } diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index d84095591e45..8af35f114821 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -318,7 +318,7 @@ u32 i2c_acpi_find_bus_speed(struct device *dev) } EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed); -static int i2c_acpi_find_match_adapter(struct device *dev, void *data) +static int i2c_acpi_find_match_adapter(struct device *dev, const void *data) { struct i2c_adapter *adapter = i2c_verify_adapter(dev); @@ -328,7 +328,7 @@ static int i2c_acpi_find_match_adapter(struct device *dev, void *data) return ACPI_HANDLE(dev) == (acpi_handle)data; } -static int i2c_acpi_find_match_device(struct device *dev, void *data) +static int i2c_acpi_find_match_device(struct device *dev, const void *data) { return ACPI_COMPANION(dev) == data; } diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c index 406e5f695a7e..2eb59a260ad4 100644 --- a/drivers/i2c/i2c-core-of.c +++ b/drivers/i2c/i2c-core-of.c @@ -112,12 +112,12 @@ void of_i2c_register_devices(struct i2c_adapter *adap) of_node_put(bus); } -static int of_dev_node_match(struct device *dev, void *data) +static int of_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data; } -static int of_dev_or_parent_node_match(struct device *dev, void *data) +static int of_dev_or_parent_node_match(struct device *dev, const void *data) { if (dev->of_node == data) return 1; diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 4a5eff3f18bc..c46fb59d92cb 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -93,7 +93,7 @@ static const struct iio_chan_spec #ifdef CONFIG_OF -static int iio_dev_node_match(struct device *dev, void *data) +static int iio_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data && dev->type == &iio_device_type; } diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 4c5d0f160c10..fd90b05849c8 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -4497,7 +4497,7 @@ static const struct acpi_device_id hns_roce_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, hns_roce_acpi_match); -static int hns_roce_node_match(struct device *dev, void *fwnode) +static int hns_roce_node_match(struct device *dev, const void *fwnode) { return dev->fwnode == fwnode; } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c index 09c16d88172e..bb6586d0e5af 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c @@ -754,7 +754,7 @@ struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev) return (void *)misc_op; } -static int hns_dsaf_dev_match(struct device *dev, void *fwnode) +static int hns_dsaf_dev_match(struct device *dev, const void *fwnode) { return dev->fwnode == fwnode; } diff --git a/drivers/net/ethernet/ti/cpsw-phy-sel.c b/drivers/net/ethernet/ti/cpsw-phy-sel.c index 48e0924259f5..4e184eecc8e1 100644 --- a/drivers/net/ethernet/ti/cpsw-phy-sel.c +++ b/drivers/net/ethernet/ti/cpsw-phy-sel.c @@ -151,9 +151,9 @@ static void cpsw_gmii_sel_dra7xx(struct cpsw_phy_sel_priv *priv, } static struct platform_driver cpsw_phy_sel_driver; -static int match(struct device *dev, void *data) +static int match(struct device *dev, const void *data) { - struct device_node *node = (struct device_node *)data; + const struct device_node *node = (const struct device_node *)data; return dev->of_node == node && dev->driver == &cpsw_phy_sel_driver.driver; } diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 4bf65cab79e6..57d131a04db3 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1371,7 +1371,7 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) return -EOPNOTSUPP; } -static int match_first_device(struct device *dev, void *data) +static int match_first_device(struct device *dev, const void *data) { if (dev->parent && dev->parent->of_node) return of_device_is_compatible(dev->parent->of_node, diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c index c50a9772f4af..8479a440527b 100644 --- a/drivers/net/ethernet/toshiba/tc35815.c +++ b/drivers/net/ethernet/toshiba/tc35815.c @@ -694,10 +694,10 @@ err_out: * should provide a "tc35815-mac" device with a MAC address in its * platform_data. */ -static int tc35815_mac_match(struct device *dev, void *data) +static int tc35815_mac_match(struct device *dev, const void *data) { struct platform_device *plat_dev = to_platform_device(dev); - struct pci_dev *pci_dev = data; + const struct pci_dev *pci_dev = data; unsigned int id = pci_dev->irq; return !strcmp(plat_dev->name, "tc35815-mac") && plat_dev->id == id; } diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index c7892c3da91f..ac5d945be88a 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -76,7 +76,7 @@ static struct bus_type nvmem_bus_type = { .name = "nvmem", }; -static int of_nvmem_match(struct device *dev, void *nvmem_np) +static int of_nvmem_match(struct device *dev, const void *nvmem_np) { return dev->of_node == nvmem_np; } diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index de6157357e26..dfe12948c834 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -282,7 +282,7 @@ unregister: EXPORT_SYMBOL(of_mdiobus_register); /* Helper function for of_phy_find_device */ -static int of_phy_match(struct device *dev, void *phy_np) +static int of_phy_match(struct device *dev, const void *phy_np) { return dev->of_node == phy_np; } diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 04ad312fd85b..008d79e33c2d 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -37,7 +37,7 @@ static const struct of_device_id of_skipped_node_table[] = { {} /* Empty terminated list */ }; -static int of_dev_node_match(struct device *dev, void *data) +static int of_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 0e8e2c186f50..f9ef7ad3f75d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -64,7 +64,7 @@ static struct resource *get_pci_domain_busn_res(int domain_nr) return &r->res; } -static int find_anything(struct device *dev, void *data) +static int find_anything(struct device *dev, const void *data) { return 1; } diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 5c7922612733..7f4e65872b8d 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -236,10 +236,10 @@ struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, } EXPORT_SYMBOL(pci_get_domain_bus_and_slot); -static int match_pci_dev_by_id(struct device *dev, void *data) +static int match_pci_dev_by_id(struct device *dev, const void *data) { struct pci_dev *pdev = to_pci_dev(dev); - struct pci_device_id *id = data; + const struct pci_device_id *id = data; if (pci_match_one_device(id, pdev)) return 1; diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index aea502922646..a2c97830efe0 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -434,10 +434,10 @@ static int css_probe_device(struct subchannel_id schid, struct schib *schib) } static int -check_subchannel(struct device * dev, void * data) +check_subchannel(struct device *dev, const void *data) { struct subchannel *sch; - struct subchannel_id *schid = data; + struct subchannel_id *schid = (void *)data; sch = to_subchannel(dev); return schid_equal(&sch->schid, schid); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 1540229a37bb..d32f373e5bc7 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -642,10 +642,10 @@ static int ccw_device_add(struct ccw_device *cdev) return device_add(dev); } -static int match_dev_id(struct device *dev, void *data) +static int match_dev_id(struct device *dev, const void *data) { struct ccw_device *cdev = to_ccwdev(dev); - struct ccw_dev_id *dev_id = data; + struct ccw_dev_id *dev_id = (void *)data; return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); } diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c index 6bca1d5455d4..9f26d4310bb3 100644 --- a/drivers/s390/cio/scm.c +++ b/drivers/s390/cio/scm.c @@ -174,10 +174,10 @@ out: kobject_uevent(&scmdev->dev.kobj, KOBJ_CHANGE); } -static int check_address(struct device *dev, void *data) +static int check_address(struct device *dev, const void *data) { struct scm_device *scmdev = to_scm_dev(dev); - struct sale *sale = data; + const struct sale *sale = data; return scmdev->address == sale->sa; } diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index b9fc502c58c2..b7902b643ec8 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1356,16 +1356,16 @@ static int ap_get_compatible_type(ap_qid_t qid, int rawtype, unsigned int func) * Helper function to be used with bus_find_dev * matches for the card device with the given id */ -static int __match_card_device_with_id(struct device *dev, void *data) +static int __match_card_device_with_id(struct device *dev, const void *data) { - return is_card_dev(dev) && to_ap_card(dev)->id == (int)(long) data; + return is_card_dev(dev) && to_ap_card(dev)->id == (int)(long)(void *) data; } /* * Helper function to be used with bus_find_dev * matches for the queue device with a given qid */ -static int __match_queue_device_with_qid(struct device *dev, void *data) +static int __match_queue_device_with_qid(struct device *dev, const void *data) { return is_queue_dev(dev) && to_ap_queue(dev)->qid == (int)(long) data; } @@ -1374,7 +1374,7 @@ static int __match_queue_device_with_qid(struct device *dev, void *data) * Helper function to be used with bus_find_dev * matches any queue device with given queue id */ -static int __match_queue_device_with_queue_id(struct device *dev, void *data) +static int __match_queue_device_with_queue_id(struct device *dev, const void *data) { return is_queue_dev(dev) && AP_QID_QUEUE(to_ap_queue(dev)->qid) == (int)(long) data; diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index 7f0ceb65c3f3..c074631086a4 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -372,7 +372,7 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, return err; } -static int always_match(struct device *dev, void *data) +static int always_match(struct device *dev, const void *data) { return 1; } diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 5e75944ad5d1..3da1121f7572 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3538,7 +3538,7 @@ EXPORT_SYMBOL_GPL(spi_write_then_read); /*-------------------------------------------------------------------------*/ #if IS_ENABLED(CONFIG_OF) -static int __spi_of_device_match(struct device *dev, void *data) +static int __spi_of_device_match(struct device *dev, const void *data) { return dev->of_node == data; } @@ -3639,7 +3639,7 @@ static int spi_acpi_controller_match(struct device *dev, const void *data) return ACPI_COMPANION(dev->parent) == data; } -static int spi_acpi_device_match(struct device *dev, void *data) +static int spi_acpi_device_match(struct device *dev, const void *data) { return ACPI_COMPANION(dev) == data; } diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index c1b016574fb4..c9a7e4a779cd 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -1946,10 +1946,10 @@ struct tb_sw_lookup { u64 route; }; -static int tb_switch_match(struct device *dev, void *data) +static int tb_switch_match(struct device *dev, const void *data) { struct tb_switch *sw = tb_to_switch(dev); - struct tb_sw_lookup *lookup = data; + const struct tb_sw_lookup *lookup = data; if (!sw) return 0; diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index fa783531ee88..7bd7de7273a3 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -947,9 +947,9 @@ error: return ret; } -static int match_devt(struct device *dev, void *data) +static int match_devt(struct device *dev, const void *data) { - return dev->devt == (dev_t) (unsigned long) data; + return dev->devt == (dev_t)(unsigned long)(void *)data; } static struct usb_device *usbdev_lookup_by_devt(dev_t devt) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 7fcb9f782931..1678e305e037 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -325,9 +325,9 @@ struct find_interface_arg { struct device_driver *drv; }; -static int __find_interface(struct device *dev, void *data) +static int __find_interface(struct device *dev, const void *data) { - struct find_interface_arg *arg = data; + const struct find_interface_arg *arg = data; struct usb_interface *intf; if (!is_usb_interface(dev)) diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index a3cb25cb74f8..d16dfc320faa 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -118,9 +118,9 @@ static const struct of_device_id omap_control_usb_id_table[] = { MODULE_DEVICE_TABLE(of, omap_control_usb_id_table); static struct platform_driver am335x_control_driver; -static int match(struct device *dev, void *data) +static int match(struct device *dev, const void *data) { - struct device_node *node = (struct device_node *)data; + const struct device_node *node = (const struct device_node *)data; return dev->of_node == node && dev->driver == &am335x_control_driver.driver; } diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c index 93b7d6a30aad..6cf6fbd39237 100644 --- a/drivers/usb/phy/phy-isp1301.c +++ b/drivers/usb/phy/phy-isp1301.c @@ -142,9 +142,9 @@ static struct i2c_driver isp1301_driver = { module_i2c_driver(isp1301_driver); -static int match(struct device *dev, void *data) +static int match(struct device *dev, const void *data) { - struct device_node *node = (struct device_node *)data; + const struct device_node *node = (const struct device_node *)data; return (dev->of_node == node) && (dev->driver == &isp1301_driver.driver); } diff --git a/drivers/visorbus/visorbus_main.c b/drivers/visorbus/visorbus_main.c index 0b2434cc4ecd..152fd29f04f2 100644 --- a/drivers/visorbus/visorbus_main.c +++ b/drivers/visorbus/visorbus_main.c @@ -171,10 +171,10 @@ struct visor_busdev { u32 dev_no; }; -static int match_visorbus_dev_by_id(struct device *dev, void *data) +static int match_visorbus_dev_by_id(struct device *dev, const void *data) { struct visor_device *vdev = to_visor_device(dev); - struct visor_busdev *id = data; + const struct visor_busdev *id = data; if (vdev->chipset_bus_no == id->bus_no && vdev->chipset_dev_no == id->dev_no) diff --git a/include/linux/device.h b/include/linux/device.h index e85264fb6616..cbbdcadc660e 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -166,8 +166,8 @@ void subsys_dev_iter_exit(struct subsys_dev_iter *iter); int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, int (*fn)(struct device *dev, void *data)); struct device *bus_find_device(struct bus_type *bus, struct device *start, - void *data, - int (*match)(struct device *dev, void *data)); + const void *data, + int (*match)(struct device *dev, const void *data)); struct device *bus_find_device_by_name(struct bus_type *bus, struct device *start, const char *name); diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c index 3d0cc6e90d7b..c04c9ed185b7 100644 --- a/sound/soc/rockchip/rk3399_gru_sound.c +++ b/sound/soc/rockchip/rk3399_gru_sound.c @@ -405,7 +405,7 @@ static const struct dailink_match_data dailink_match[] = { }, }; -static int of_dev_node_match(struct device *dev, void *data) +static int of_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data; } From 92ce7e83b4e5c86687d748ba53cb755acdce1256 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Fri, 14 Jun 2019 18:54:00 +0100 Subject: [PATCH 084/102] driver_find_device: Unify the match function with class_find_device() The driver_find_device() accepts a match function pointer to filter the devices for lookup, similar to bus/class_find_device(). However, there is a minor difference in the prototype for the match parameter for driver_find_device() with the now unified version accepted by {bus/class}_find_device(), where it doesn't accept a "const" qualifier for the data argument. This prevents us from reusing the generic match functions for driver_find_device(). For this reason, change the prototype of the driver_find_device() to make the "match" parameter in line with {bus/class}_find_device() and adjust its callers to use the const qualifier. Also, we could now promote the "data" parameter to const as we pass it down as a const parameter to the match functions. Cc: Corey Minyard Cc: Russell King Cc: Thierry Reding Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: Will Deacon Cc: Joerg Roedel Cc: Peter Oberparleiter Cc: Sebastian Ott Cc: David Airlie Cc: Daniel Vetter Cc: Nehal Shah Cc: Shyam Sundar S K Cc: Lee Jones Cc: Christian Borntraeger Signed-off-by: Suzuki K Poulose Signed-off-by: Greg Kroah-Hartman --- drivers/amba/tegra-ahb.c | 4 ++-- drivers/base/driver.c | 4 ++-- drivers/char/ipmi/ipmi_msghandler.c | 8 ++++---- drivers/gpu/drm/tegra/dc.c | 4 ++-- drivers/i2c/busses/i2c-amd-mp2-pci.c | 2 +- drivers/iommu/arm-smmu-v3.c | 2 +- drivers/iommu/arm-smmu.c | 2 +- drivers/mfd/altera-sysmgr.c | 4 ++-- drivers/s390/cio/ccwgroup.c | 4 ++-- drivers/s390/cio/chsc_sch.c | 2 +- drivers/s390/cio/device.c | 2 +- include/linux/device.h | 4 ++-- 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c index 3751d811be39..42175a67ba0e 100644 --- a/drivers/amba/tegra-ahb.c +++ b/drivers/amba/tegra-ahb.c @@ -143,10 +143,10 @@ static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset) } #ifdef CONFIG_TEGRA_IOMMU_SMMU -static int tegra_ahb_match_by_smmu(struct device *dev, void *data) +static int tegra_ahb_match_by_smmu(struct device *dev, const void *data) { struct tegra_ahb *ahb = dev_get_drvdata(dev); - struct device_node *dn = data; + const struct device_node *dn = data; return (ahb->dev->of_node == dn) ? 1 : 0; } diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 857c8f1b876e..4e5ca632f35e 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -73,8 +73,8 @@ EXPORT_SYMBOL_GPL(driver_for_each_device); * return to the caller and not iterate over any more devices. */ struct device *driver_find_device(struct device_driver *drv, - struct device *start, void *data, - int (*match)(struct device *dev, void *data)) + struct device *start, const void *data, + int (*match)(struct device *dev, const void *data)) { struct klist_iter i; struct device *dev; diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 1dc10740fc0f..6707659cffd6 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -2819,9 +2819,9 @@ static const struct device_type bmc_device_type = { .groups = bmc_dev_attr_groups, }; -static int __find_bmc_guid(struct device *dev, void *data) +static int __find_bmc_guid(struct device *dev, const void *data) { - guid_t *guid = data; + const guid_t *guid = data; struct bmc_device *bmc; int rv; @@ -2857,9 +2857,9 @@ struct prod_dev_id { unsigned char device_id; }; -static int __find_bmc_prod_dev_id(struct device *dev, void *data) +static int __find_bmc_prod_dev_id(struct device *dev, const void *data) { - struct prod_dev_id *cid = data; + const struct prod_dev_id *cid = data; struct bmc_device *bmc; int rv; diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 607a6ea17ecc..52109a63e797 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -2375,10 +2375,10 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc) return 0; } -static int tegra_dc_match_by_pipe(struct device *dev, void *data) +static int tegra_dc_match_by_pipe(struct device *dev, const void *data) { struct tegra_dc *dc = dev_get_drvdata(dev); - unsigned int pipe = (unsigned long)data; + unsigned int pipe = (unsigned long)(void *)data; return dc->pipe == pipe; } diff --git a/drivers/i2c/busses/i2c-amd-mp2-pci.c b/drivers/i2c/busses/i2c-amd-mp2-pci.c index 455e1f36a2a3..c7fe3b44a860 100644 --- a/drivers/i2c/busses/i2c-amd-mp2-pci.c +++ b/drivers/i2c/busses/i2c-amd-mp2-pci.c @@ -457,7 +457,7 @@ static struct pci_driver amd_mp2_pci_driver = { }; module_pci_driver(amd_mp2_pci_driver); -static int amd_mp2_device_match(struct device *dev, void *data) +static int amd_mp2_device_match(struct device *dev, const void *data) { return 1; } diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 4d5a694f02c2..d787856f9dcf 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2023,7 +2023,7 @@ arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) static struct platform_driver arm_smmu_driver; -static int arm_smmu_match_node(struct device *dev, void *data) +static int arm_smmu_match_node(struct device *dev, const void *data) { return dev->fwnode == data; } diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 5e54cc0a28b3..4ce429b74655 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1431,7 +1431,7 @@ static bool arm_smmu_capable(enum iommu_cap cap) } } -static int arm_smmu_match_node(struct device *dev, void *data) +static int arm_smmu_match_node(struct device *dev, const void *data) { return dev->fwnode == data; } diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c index 8976f82785bb..2ee14d8a6d31 100644 --- a/drivers/mfd/altera-sysmgr.c +++ b/drivers/mfd/altera-sysmgr.c @@ -92,9 +92,9 @@ static struct regmap_config altr_sysmgr_regmap_cfg = { * Matching function used by driver_find_device(). * Return: True if match is found, otherwise false. */ -static int sysmgr_match_phandle(struct device *dev, void *data) +static int sysmgr_match_phandle(struct device *dev, const void *data) { - return dev->of_node == (struct device_node *)data; + return dev->of_node == (const struct device_node *)data; } /** diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 4ebf6d4fc66c..ea17615789c9 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -581,7 +581,7 @@ int ccwgroup_driver_register(struct ccwgroup_driver *cdriver) } EXPORT_SYMBOL(ccwgroup_driver_register); -static int __ccwgroup_match_all(struct device *dev, void *data) +static int __ccwgroup_match_all(struct device *dev, const void *data) { return 1; } @@ -608,7 +608,7 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) } EXPORT_SYMBOL(ccwgroup_driver_unregister); -static int __ccwgroupdev_check_busid(struct device *dev, void *id) +static int __ccwgroupdev_check_busid(struct device *dev, const void *id) { char *bus_id = id; diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 8d9f36625ba5..8f080d3fd380 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -203,7 +203,7 @@ static void chsc_cleanup_sch_driver(void) static DEFINE_SPINLOCK(chsc_lock); -static int chsc_subchannel_match_next_free(struct device *dev, void *data) +static int chsc_subchannel_match_next_free(struct device *dev, const void *data) { struct subchannel *sch = to_subchannel(dev); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index d32f373e5bc7..f27536ba58eb 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1653,7 +1653,7 @@ EXPORT_SYMBOL_GPL(ccw_device_force_console); * get ccw_device matching the busid, but only if owned by cdrv */ static int -__ccwdev_check_busid(struct device *dev, void *id) +__ccwdev_check_busid(struct device *dev, const void *id) { char *bus_id; diff --git a/include/linux/device.h b/include/linux/device.h index cbbdcadc660e..4d7c88131a4d 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -336,8 +336,8 @@ extern int __must_check driver_for_each_device(struct device_driver *drv, int (*fn)(struct device *dev, void *)); struct device *driver_find_device(struct device_driver *drv, - struct device *start, void *data, - int (*match)(struct device *dev, void *data)); + struct device *start, const void *data, + int (*match)(struct device *dev, const void *data)); void driver_deferred_probe_add(struct device *dev); int driver_deferred_probe_check_state(struct device *dev); From 65b66682344a15ba2069d4dd8d0cc39cc3aed7e9 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Fri, 14 Jun 2019 18:54:01 +0100 Subject: [PATCH 085/102] drivers: Add generic helper to match by of_node Add a helper to match device by the of_node. This will be later used to provide wrappers to the device iterators for {bus/class/driver}_find_device(). Convert other users to reuse this new helper. Cc: Alan Tull Cc: Andrew Lunn Cc: Daniel Vetter Cc: David Airlie Cc: "David S. Miller" Cc: devicetree@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: Florian Fainelli Cc: Frank Rowand Cc: Greg Kroah-Hartman Cc: Heiner Kallweit Cc: Jiri Slaby Cc: Jonathan Hunter Cc: Lee Jones Cc: Liam Girdwood Cc: linux-fpga@vger.kernel.org Cc: linux-i2c@vger.kernel.org Cc: linux-spi@vger.kernel.org Cc: Maarten Lankhorst Cc: Mark Brown Cc: Mathieu Poirier Cc: Maxime Ripard Cc: Moritz Fischer Cc: Peter Rosin Cc: Rob Herring Cc: Srinivas Kandagatla Cc: Thierry Reding Cc: Thor Thayer Cc: Wolfram Sang Cc: "Rafael J. Wysocki" Cc: Greg Kroah-Hartman Cc: Ulf Hansson Cc: Joe Perches Signed-off-by: Suzuki K Poulose Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 6 ++++++ drivers/fpga/of-fpga-region.c | 7 +------ include/linux/device.h | 2 ++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index fd7511e04e62..92119080474c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -3328,3 +3328,9 @@ void device_set_of_node_from_dev(struct device *dev, const struct device *dev2) dev->of_node_reused = true; } EXPORT_SYMBOL_GPL(device_set_of_node_from_dev); + +int device_match_of_node(struct device *dev, const void *np) +{ + return dev->of_node == np; +} +EXPORT_SYMBOL_GPL(device_match_of_node); diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c index 75f64abf9c81..e405309baadc 100644 --- a/drivers/fpga/of-fpga-region.c +++ b/drivers/fpga/of-fpga-region.c @@ -22,11 +22,6 @@ static const struct of_device_id fpga_region_of_match[] = { }; MODULE_DEVICE_TABLE(of, fpga_region_of_match); -static int fpga_region_of_node_match(struct device *dev, const void *data) -{ - return dev->of_node == data; -} - /** * of_fpga_region_find - find FPGA region * @np: device node of FPGA Region @@ -37,7 +32,7 @@ static int fpga_region_of_node_match(struct device *dev, const void *data) */ static struct fpga_region *of_fpga_region_find(struct device_node *np) { - return fpga_region_class_find(NULL, np, fpga_region_of_node_match); + return fpga_region_class_find(NULL, np, device_match_of_node); } /** diff --git a/include/linux/device.h b/include/linux/device.h index 4d7c88131a4d..709308560d32 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -163,6 +163,8 @@ void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter); void subsys_dev_iter_exit(struct subsys_dev_iter *iter); +int device_match_of_node(struct device *dev, const void *np); + int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, int (*fn)(struct device *dev, void *data)); struct device *bus_find_device(struct bus_type *bus, struct device *start, From fb59b7824da884e042f44dad9c713f221ded93c9 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 26 Jun 2019 09:46:53 +0100 Subject: [PATCH 086/102] drivers: s390/cio: Fix compilation warning about const qualifiers Update __ccwdev_check_busid() and __ccwgroupdev_check_busid() to use "const" qualifiers to fix the compiler warning. Reported-by: kbuild test robot Cc: gregkh@linuxfoundation.org Cc: devel@driverdev.osuosl.org Signed-off-by: Suzuki K Poulose Signed-off-by: Greg Kroah-Hartman --- drivers/s390/cio/ccwgroup.c | 2 +- drivers/s390/cio/device.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index ea17615789c9..c522e9313c50 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -610,7 +610,7 @@ EXPORT_SYMBOL(ccwgroup_driver_unregister); static int __ccwgroupdev_check_busid(struct device *dev, const void *id) { - char *bus_id = id; + const char *bus_id = id; return (strcmp(bus_id, dev_name(dev)) == 0); } diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index f27536ba58eb..113248227137 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1655,9 +1655,7 @@ EXPORT_SYMBOL_GPL(ccw_device_force_console); static int __ccwdev_check_busid(struct device *dev, const void *id) { - char *bus_id; - - bus_id = id; + const char *bus_id = id; return (strcmp(bus_id, dev_name(dev)) == 0); } From 43e23b6c0b0151e308acbd6530bb80e2d2e53161 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 3 Jul 2019 09:16:53 +0200 Subject: [PATCH 087/102] debugfs: log errors when something goes wrong As it is not recommended that debugfs calls be checked, it was pointed out that major errors should still be logged somewhere so that developers and users have a chance to figure out what went wrong. To help with this, error logging has been added to the debugfs core so that it is not needed to be present in every individual file that calls debugfs. Reported-by: Mark Brown Reported-by: Takashi Iwai Reviewed-by: Mark Brown Reviewed-by: Takashi Iwai Reviewed-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20190703071653.2799-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index acef14ad53db..c3638ac81cb6 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -2,8 +2,9 @@ /* * inode.c - part of debugfs, a tiny little debug file system * - * Copyright (C) 2004 Greg Kroah-Hartman + * Copyright (C) 2004,2019 Greg Kroah-Hartman * Copyright (C) 2004 IBM Inc. + * Copyright (C) 2019 Linux Foundation * * debugfs is for people to use instead of /proc or /sys. * See ./Documentation/core-api/kernel-api.rst for more details. @@ -292,8 +293,10 @@ static struct dentry *start_creating(const char *name, struct dentry *parent) error = simple_pin_fs(&debug_fs_type, &debugfs_mount, &debugfs_mount_count); - if (error) + if (error) { + pr_err("Unable to pin filesystem for file '%s'\n", name); return ERR_PTR(error); + } /* If the parent is not specified, we create it in the root. * We need the root dentry to do this, which is in the super @@ -307,6 +310,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent) dentry = lookup_one_len(name, parent, strlen(name)); if (!IS_ERR(dentry) && d_really_is_positive(dentry)) { dput(dentry); + pr_err("File '%s' already present!\n", name); dentry = ERR_PTR(-EEXIST); } @@ -349,8 +353,11 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode, return dentry; inode = debugfs_get_inode(dentry->d_sb); - if (unlikely(!inode)) + if (unlikely(!inode)) { + pr_err("out of free dentries, can not create file '%s'\n", + name); return failed_creating(dentry); + } inode->i_mode = mode; inode->i_private = data; @@ -511,8 +518,11 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) return dentry; inode = debugfs_get_inode(dentry->d_sb); - if (unlikely(!inode)) + if (unlikely(!inode)) { + pr_err("out of free dentries, can not create directory '%s'\n", + name); return failed_creating(dentry); + } inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; inode->i_op = &simple_dir_inode_operations; @@ -550,8 +560,11 @@ struct dentry *debugfs_create_automount(const char *name, return dentry; inode = debugfs_get_inode(dentry->d_sb); - if (unlikely(!inode)) + if (unlikely(!inode)) { + pr_err("out of free dentries, can not create automount '%s'\n", + name); return failed_creating(dentry); + } make_empty_dir_inode(inode); inode->i_flags |= S_AUTOMOUNT; @@ -606,6 +619,8 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, inode = debugfs_get_inode(dentry->d_sb); if (unlikely(!inode)) { + pr_err("out of free dentries, can not create symlink '%s'\n", + name); kfree(link); return failed_creating(dentry); } From d03ae4778b3b61fc329615c30972074ee3496b0a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 3 Jul 2019 09:16:52 +0200 Subject: [PATCH 088/102] debugfs: provide pr_fmt() macro Use a common "debugfs: " prefix for all pr_* calls in a single place. Cc: Mark Brown Reviewed-by: Takashi Iwai Reviewed-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20190703071653.2799-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index c3638ac81cb6..7f43c8acfcbf 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -10,6 +10,8 @@ * See ./Documentation/core-api/kernel-api.rst for more details. */ +#define pr_fmt(fmt) "debugfs: " fmt + #include #include #include @@ -286,7 +288,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent) struct dentry *dentry; int error; - pr_debug("debugfs: creating file '%s'\n",name); + pr_debug("creating file '%s'\n", name); if (IS_ERR(parent)) return parent; From 352bce2ee19f9d479832c060548974da2ba51153 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 17:34:40 +0200 Subject: [PATCH 089/102] lib: 842: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Haren Myneni Cc: linux-kernel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20190612153440.GA21006@kroah.com Signed-off-by: Greg Kroah-Hartman --- lib/842/842_debugfs.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/842/842_debugfs.h b/lib/842/842_debugfs.h index 277e403e8701..4469407c3e0d 100644 --- a/lib/842/842_debugfs.h +++ b/lib/842/842_debugfs.h @@ -22,8 +22,6 @@ static int __init sw842_debugfs_create(void) return -ENODEV; sw842_debugfs_root = debugfs_create_dir(MODULE_NAME, NULL); - if (IS_ERR(sw842_debugfs_root)) - return PTR_ERR(sw842_debugfs_root); for (i = 0; i < ARRAY_SIZE(template_count); i++) { char name[32]; @@ -46,8 +44,7 @@ static int __init sw842_debugfs_create(void) static void __exit sw842_debugfs_remove(void) { - if (sw842_debugfs_root && !IS_ERR(sw842_debugfs_root)) - debugfs_remove_recursive(sw842_debugfs_root); + debugfs_remove_recursive(sw842_debugfs_root); } #endif From 15b6ff951630eb5825936f98d940c2a4596ff224 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 17:26:03 +0200 Subject: [PATCH 090/102] nfsd: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: "J. Bruce Fields" Cc: Jeff Layton Cc: linux-nfs@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20190612152603.GB18440@kroah.com Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/fault_inject.c | 12 ++---------- fs/nfsd/nfsctl.c | 5 +---- fs/nfsd/state.h | 4 ++-- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c index 84831253203d..76bee0a0d308 100644 --- a/fs/nfsd/fault_inject.c +++ b/fs/nfsd/fault_inject.c @@ -127,24 +127,16 @@ static struct nfsd_fault_inject_op inject_ops[] = { }, }; -int nfsd_fault_inject_init(void) +void nfsd_fault_inject_init(void) { unsigned int i; struct nfsd_fault_inject_op *op; umode_t mode = S_IFREG | S_IRUSR | S_IWUSR; debug_dir = debugfs_create_dir("nfsd", NULL); - if (!debug_dir) - goto fail; for (i = 0; i < ARRAY_SIZE(inject_ops); i++) { op = &inject_ops[i]; - if (!debugfs_create_file(op->file, mode, debug_dir, op, &fops_nfsd)) - goto fail; + debugfs_create_file(op->file, mode, debug_dir, op, &fops_nfsd); } - return 0; - -fail: - nfsd_fault_inject_cleanup(); - return -ENOMEM; } diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 62c58cfeb8d8..6a9de59d9633 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1291,9 +1291,7 @@ static int __init init_nfsd(void) retval = nfsd4_init_pnfs(); if (retval) goto out_free_slabs; - retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */ - if (retval) - goto out_exit_pnfs; + nfsd_fault_inject_init(); /* nfsd fault injection controls */ nfsd_stat_init(); /* Statistics */ retval = nfsd_reply_cache_init(); if (retval) @@ -1315,7 +1313,6 @@ out_free_lockd: out_free_stat: nfsd_stat_shutdown(); nfsd_fault_inject_cleanup(); -out_exit_pnfs: nfsd4_exit_pnfs(); out_free_slabs: nfsd4_free_slabs(); diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 0b74d371ed67..87f310c78e06 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -663,7 +663,7 @@ extern void nfsd4_record_grace_done(struct nfsd_net *nn); /* nfs fault injection functions */ #ifdef CONFIG_NFSD_FAULT_INJECTION -int nfsd_fault_inject_init(void); +void nfsd_fault_inject_init(void); void nfsd_fault_inject_cleanup(void); u64 nfsd_inject_print_clients(void); @@ -684,7 +684,7 @@ u64 nfsd_inject_forget_delegations(u64); u64 nfsd_inject_recall_client_delegations(struct sockaddr_storage *, size_t); u64 nfsd_inject_recall_delegations(u64); #else /* CONFIG_NFSD_FAULT_INJECTION */ -static inline int nfsd_fault_inject_init(void) { return 0; } +static inline void nfsd_fault_inject_init(void) {} static inline void nfsd_fault_inject_cleanup(void) {} #endif /* CONFIG_NFSD_FAULT_INJECTION */ From f095adba36bb7f6947135f6893b5837760961b3d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 17:22:04 +0200 Subject: [PATCH 091/102] orangefs: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Mike Marshall Cc: Martin Brandenburg Cc: devel@lists.orangefs.org Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20190612152204.GA17511@kroah.com Signed-off-by: Greg Kroah-Hartman --- fs/orangefs/orangefs-debugfs.c | 35 ++++------------------------------ 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c index 87b1a6fce628..7723f581017d 100644 --- a/fs/orangefs/orangefs-debugfs.c +++ b/fs/orangefs/orangefs-debugfs.c @@ -99,7 +99,6 @@ static char *debug_help_string; static char client_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; static char client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; -static struct dentry *help_file_dentry; static struct dentry *client_debug_dentry; static struct dentry *debug_dir; @@ -183,20 +182,9 @@ int orangefs_debugfs_init(int debug_mask) (unsigned long long)orangefs_gossip_debug_mask); debug_dir = debugfs_create_dir("orangefs", NULL); - if (!debug_dir) { - pr_info("%s: debugfs_create_dir failed.\n", __func__); - goto out; - } - help_file_dentry = debugfs_create_file(ORANGEFS_KMOD_DEBUG_HELP_FILE, - 0444, - debug_dir, - debug_help_string, - &debug_help_fops); - if (!help_file_dentry) { - pr_info("%s: debugfs_create_file failed.\n", __func__); - goto out; - } + debugfs_create_file(ORANGEFS_KMOD_DEBUG_HELP_FILE, 0444, debug_dir, + debug_help_string, &debug_help_fops); orangefs_debug_disabled = 0; @@ -230,17 +218,8 @@ static int orangefs_kernel_debug_init(void) pr_info("%s: overflow 1!\n", __func__); } - ret = debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, - 0444, - debug_dir, - k_buffer, - &kernel_debug_fops); - if (!ret) { - pr_info("%s: failed to create %s.\n", - __func__, - ORANGEFS_KMOD_DEBUG_FILE); - goto out; - } + debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, 0444, debug_dir, k_buffer, + &kernel_debug_fops); rc = 0; @@ -353,12 +332,6 @@ static int orangefs_client_debug_init(void) debug_dir, c_buffer, &kernel_debug_fops); - if (!client_debug_dentry) { - pr_info("%s: failed to create updated %s.\n", - __func__, - ORANGEFS_CLIENT_DEBUG_FILE); - goto out; - } rc = 0; From 702d6a834b497a7c387722bd796e0dc18bb55360 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 17:21:20 +0200 Subject: [PATCH 092/102] ubifs: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Richard Weinberger Cc: Artem Bityutskiy Cc: Adrian Hunter Cc: linux-mtd@lists.infradead.org Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20190612152120.GA17450@kroah.com Signed-off-by: Greg Kroah-Hartman --- fs/ubifs/debug.c | 167 ++++++++++++----------------------------------- fs/ubifs/debug.h | 4 +- fs/ubifs/super.c | 9 +-- 3 files changed, 45 insertions(+), 135 deletions(-) diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 3a2613038e88..57e6fcb043ca 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -2812,115 +2812,69 @@ static const struct file_operations dfs_fops = { * dbg_debugfs_init_fs - initialize debugfs for UBIFS instance. * @c: UBIFS file-system description object * - * This function creates all debugfs files for this instance of UBIFS. Returns - * zero in case of success and a negative error code in case of failure. + * This function creates all debugfs files for this instance of UBIFS. * * Note, the only reason we have not merged this function with the * 'ubifs_debugging_init()' function is because it is better to initialize * debugfs interfaces at the very end of the mount process, and remove them at * the very beginning of the mount process. */ -int dbg_debugfs_init_fs(struct ubifs_info *c) +void dbg_debugfs_init_fs(struct ubifs_info *c) { int err, n; const char *fname; - struct dentry *dent; struct ubifs_debug_info *d = c->dbg; - if (!IS_ENABLED(CONFIG_DEBUG_FS)) - return 0; - n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME, c->vi.ubi_num, c->vi.vol_id); if (n == UBIFS_DFS_DIR_LEN) { /* The array size is too small */ fname = UBIFS_DFS_DIR_NAME; - dent = ERR_PTR(-EINVAL); - goto out; + return; } fname = d->dfs_dir_name; - dent = debugfs_create_dir(fname, dfs_rootdir); - if (IS_ERR_OR_NULL(dent)) - goto out; - d->dfs_dir = dent; + d->dfs_dir = debugfs_create_dir(fname, dfs_rootdir); fname = "dump_lprops"; - dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_dump_lprops = dent; + d->dfs_dump_lprops = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, + &dfs_fops); fname = "dump_budg"; - dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_dump_budg = dent; + d->dfs_dump_budg = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, + &dfs_fops); fname = "dump_tnc"; - dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_dump_tnc = dent; + d->dfs_dump_tnc = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, + &dfs_fops); fname = "chk_general"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_chk_gen = dent; + d->dfs_chk_gen = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "chk_index"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_chk_index = dent; + d->dfs_chk_index = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "chk_orphans"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_chk_orph = dent; + d->dfs_chk_orph = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "chk_lprops"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_chk_lprops = dent; + d->dfs_chk_lprops = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "chk_fs"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_chk_fs = dent; + d->dfs_chk_fs = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "tst_recovery"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_tst_rcvry = dent; + d->dfs_tst_rcvry = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "ro_error"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_ro_error = dent; - - return 0; - -out_remove: - debugfs_remove_recursive(d->dfs_dir); -out: - err = dent ? PTR_ERR(dent) : -ENODEV; - ubifs_err(c, "cannot create \"%s\" debugfs file or directory, error %d\n", - fname, err); - return err; + d->dfs_ro_error = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); } /** @@ -2929,8 +2883,7 @@ out: */ void dbg_debugfs_exit_fs(struct ubifs_info *c) { - if (IS_ENABLED(CONFIG_DEBUG_FS)) - debugfs_remove_recursive(c->dbg->dfs_dir); + debugfs_remove_recursive(c->dbg->dfs_dir); } struct ubifs_global_debug_info ubifs_dbg; @@ -3006,75 +2959,38 @@ static const struct file_operations dfs_global_fops = { * * UBIFS uses debugfs file-system to expose various debugging knobs to * user-space. This function creates "ubifs" directory in the debugfs - * file-system. Returns zero in case of success and a negative error code in - * case of failure. + * file-system. */ -int dbg_debugfs_init(void) +void dbg_debugfs_init(void) { - int err; const char *fname; - struct dentry *dent; - - if (!IS_ENABLED(CONFIG_DEBUG_FS)) - return 0; fname = "ubifs"; - dent = debugfs_create_dir(fname, NULL); - if (IS_ERR_OR_NULL(dent)) - goto out; - dfs_rootdir = dent; + dfs_rootdir = debugfs_create_dir(fname, NULL); fname = "chk_general"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_chk_gen = dent; + dfs_chk_gen = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, + NULL, &dfs_global_fops); fname = "chk_index"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_chk_index = dent; + dfs_chk_index = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + dfs_rootdir, NULL, &dfs_global_fops); fname = "chk_orphans"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_chk_orph = dent; + dfs_chk_orph = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + dfs_rootdir, NULL, &dfs_global_fops); fname = "chk_lprops"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_chk_lprops = dent; + dfs_chk_lprops = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + dfs_rootdir, NULL, &dfs_global_fops); fname = "chk_fs"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_chk_fs = dent; + dfs_chk_fs = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, + NULL, &dfs_global_fops); fname = "tst_recovery"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_tst_rcvry = dent; - - return 0; - -out_remove: - debugfs_remove_recursive(dfs_rootdir); -out: - err = dent ? PTR_ERR(dent) : -ENODEV; - pr_err("UBIFS error (pid %d): cannot create \"%s\" debugfs file or directory, error %d\n", - current->pid, fname, err); - return err; + dfs_tst_rcvry = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + dfs_rootdir, NULL, &dfs_global_fops); } /** @@ -3082,8 +2998,7 @@ out: */ void dbg_debugfs_exit(void) { - if (IS_ENABLED(CONFIG_DEBUG_FS)) - debugfs_remove_recursive(dfs_rootdir); + debugfs_remove_recursive(dfs_rootdir); } void ubifs_assert_failed(struct ubifs_info *c, const char *expr, diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index 64c6977c189b..c6c8f1b62af5 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h @@ -309,9 +309,9 @@ int dbg_leb_unmap(struct ubifs_info *c, int lnum); int dbg_leb_map(struct ubifs_info *c, int lnum); /* Debugfs-related stuff */ -int dbg_debugfs_init(void); +void dbg_debugfs_init(void); void dbg_debugfs_exit(void); -int dbg_debugfs_init_fs(struct ubifs_info *c); +void dbg_debugfs_init_fs(struct ubifs_info *c); void dbg_debugfs_exit_fs(struct ubifs_info *c); #endif /* !__UBIFS_DEBUG_H__ */ diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 04b8ecfd3470..2429906bd681 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1477,9 +1477,7 @@ static int mount_ubifs(struct ubifs_info *c) if (err) goto out_infos; - err = dbg_debugfs_init_fs(c); - if (err) - goto out_infos; + dbg_debugfs_init_fs(c); c->mounting = 0; @@ -2364,9 +2362,7 @@ static int __init ubifs_init(void) if (err) goto out_shrinker; - err = dbg_debugfs_init(); - if (err) - goto out_compr; + dbg_debugfs_init(); err = register_filesystem(&ubifs_fs_type); if (err) { @@ -2378,7 +2374,6 @@ static int __init ubifs_init(void) out_dbg: dbg_debugfs_exit(); -out_compr: ubifs_compressors_exit(); out_shrinker: unregister_shrinker(&ubifs_shrinker_info); From 0a0762c6c604bb0ce8afe4ee052514e0208152a0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 16:56:22 +0200 Subject: [PATCH 093/102] sunrpc: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: "J. Bruce Fields" Cc: Jeff Layton Cc: Trond Myklebust Cc: Anna Schumaker Cc: linux-nfs@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20190612145622.GA18839@kroah.com Signed-off-by: Greg Kroah-Hartman --- net/sunrpc/debugfs.c | 66 ++++++++------------------------------------ 1 file changed, 11 insertions(+), 55 deletions(-) diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c index 95ebd76b132d..707d7aab1546 100644 --- a/net/sunrpc/debugfs.c +++ b/net/sunrpc/debugfs.c @@ -11,7 +11,6 @@ #include "netns.h" static struct dentry *topdir; -static struct dentry *rpc_fault_dir; static struct dentry *rpc_clnt_dir; static struct dentry *rpc_xprt_dir; @@ -125,23 +124,16 @@ rpc_clnt_debugfs_register(struct rpc_clnt *clnt) char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */ struct rpc_xprt *xprt; - /* Already registered? */ - if (clnt->cl_debugfs || !rpc_clnt_dir) - return; - len = snprintf(name, sizeof(name), "%x", clnt->cl_clid); if (len >= sizeof(name)) return; /* make the per-client dir */ clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir); - if (!clnt->cl_debugfs) - return; /* make tasks file */ - if (!debugfs_create_file("tasks", S_IFREG | 0400, clnt->cl_debugfs, - clnt, &tasks_fops)) - goto out_err; + debugfs_create_file("tasks", S_IFREG | 0400, clnt->cl_debugfs, clnt, + &tasks_fops); rcu_read_lock(); xprt = rcu_dereference(clnt->cl_xprt); @@ -157,8 +149,7 @@ rpc_clnt_debugfs_register(struct rpc_clnt *clnt) if (len >= sizeof(name)) goto out_err; - if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name)) - goto out_err; + debugfs_create_symlink("xprt", clnt->cl_debugfs, name); return; out_err: @@ -226,9 +217,6 @@ rpc_xprt_debugfs_register(struct rpc_xprt *xprt) static atomic_t cur_id; char name[9]; /* 8 hex digits + NULL term */ - if (!rpc_xprt_dir) - return; - id = (unsigned int)atomic_inc_return(&cur_id); len = snprintf(name, sizeof(name), "%x", id); @@ -237,15 +225,10 @@ rpc_xprt_debugfs_register(struct rpc_xprt *xprt) /* make the per-client dir */ xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir); - if (!xprt->debugfs) - return; /* make tasks file */ - if (!debugfs_create_file("info", S_IFREG | 0400, xprt->debugfs, - xprt, &xprt_info_fops)) { - debugfs_remove_recursive(xprt->debugfs); - xprt->debugfs = NULL; - } + debugfs_create_file("info", S_IFREG | 0400, xprt->debugfs, xprt, + &xprt_info_fops); atomic_set(&xprt->inject_disconnect, rpc_inject_disconnect); } @@ -308,28 +291,11 @@ static const struct file_operations fault_disconnect_fops = { .release = fault_release, }; -static struct dentry * -inject_fault_dir(struct dentry *topdir) -{ - struct dentry *faultdir; - - faultdir = debugfs_create_dir("inject_fault", topdir); - if (!faultdir) - return NULL; - - if (!debugfs_create_file("disconnect", S_IFREG | 0400, faultdir, - NULL, &fault_disconnect_fops)) - return NULL; - - return faultdir; -} - void __exit sunrpc_debugfs_exit(void) { debugfs_remove_recursive(topdir); topdir = NULL; - rpc_fault_dir = NULL; rpc_clnt_dir = NULL; rpc_xprt_dir = NULL; } @@ -337,26 +303,16 @@ sunrpc_debugfs_exit(void) void __init sunrpc_debugfs_init(void) { - topdir = debugfs_create_dir("sunrpc", NULL); - if (!topdir) - return; + struct dentry *rpc_fault_dir; - rpc_fault_dir = inject_fault_dir(topdir); - if (!rpc_fault_dir) - goto out_remove; + topdir = debugfs_create_dir("sunrpc", NULL); rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir); - if (!rpc_clnt_dir) - goto out_remove; rpc_xprt_dir = debugfs_create_dir("rpc_xprt", topdir); - if (!rpc_xprt_dir) - goto out_remove; - return; -out_remove: - debugfs_remove_recursive(topdir); - topdir = NULL; - rpc_fault_dir = NULL; - rpc_clnt_dir = NULL; + rpc_fault_dir = debugfs_create_dir("inject_fault", topdir); + + debugfs_create_file("disconnect", S_IFREG | 0400, rpc_fault_dir, NULL, + &fault_disconnect_fops); } From 1a829ff2a6c37187ff8020488e84ec392cb94854 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 16:55:38 +0200 Subject: [PATCH 094/102] ceph: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. This cleanup allows the return value of the functions to be made void, as no logic should care if these files succeed or not. Cc: "Yan, Zheng" Cc: Sage Weil Cc: Ilya Dryomov Cc: "David S. Miller" Cc: ceph-devel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20190612145538.GA18772@kroah.com Signed-off-by: Greg Kroah-Hartman --- fs/ceph/debugfs.c | 24 ++---------------------- fs/ceph/super.c | 4 +--- fs/ceph/super.h | 2 +- include/linux/ceph/debugfs.h | 4 ++-- net/ceph/ceph_common.c | 5 +---- net/ceph/debugfs.c | 33 ++++----------------------------- 6 files changed, 11 insertions(+), 61 deletions(-) diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index b3fc5fe26a1a..83cd41fa2b01 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -245,21 +245,17 @@ void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc) debugfs_remove(fsc->debugfs_mdsc); } -int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) +void ceph_fs_debugfs_init(struct ceph_fs_client *fsc) { char name[100]; - int err = -ENOMEM; dout("ceph_fs_debugfs_init\n"); - BUG_ON(!fsc->client->debugfs_dir); fsc->debugfs_congestion_kb = debugfs_create_file("writeback_congestion_kb", 0600, fsc->client->debugfs_dir, fsc, &congestion_kb_fops); - if (!fsc->debugfs_congestion_kb) - goto out; snprintf(name, sizeof(name), "../../bdi/%s", dev_name(fsc->sb->s_bdi->dev)); @@ -267,52 +263,36 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) debugfs_create_symlink("bdi", fsc->client->debugfs_dir, name); - if (!fsc->debugfs_bdi) - goto out; fsc->debugfs_mdsmap = debugfs_create_file("mdsmap", 0400, fsc->client->debugfs_dir, fsc, &mdsmap_show_fops); - if (!fsc->debugfs_mdsmap) - goto out; fsc->debugfs_mds_sessions = debugfs_create_file("mds_sessions", 0400, fsc->client->debugfs_dir, fsc, &mds_sessions_show_fops); - if (!fsc->debugfs_mds_sessions) - goto out; fsc->debugfs_mdsc = debugfs_create_file("mdsc", 0400, fsc->client->debugfs_dir, fsc, &mdsc_show_fops); - if (!fsc->debugfs_mdsc) - goto out; fsc->debugfs_caps = debugfs_create_file("caps", 0400, fsc->client->debugfs_dir, fsc, &caps_show_fops); - if (!fsc->debugfs_caps) - goto out; - - return 0; - -out: - ceph_fs_debugfs_cleanup(fsc); - return err; } #else /* CONFIG_DEBUG_FS */ -int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) +void ceph_fs_debugfs_init(struct ceph_fs_client *fsc) { return 0; } diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 01be7c1bc4c6..273c94b61a3d 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -951,9 +951,7 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc) dout("mount opening path %s\n", path); } - err = ceph_fs_debugfs_init(fsc); - if (err < 0) - goto out; + ceph_fs_debugfs_init(fsc); root = open_root_dentry(fsc, path, started); if (IS_ERR(root)) { diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 6edab9a750f8..ac1e17853278 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -1099,7 +1099,7 @@ extern int ceph_locks_to_pagelist(struct ceph_filelock *flocks, int num_fcntl_locks, int num_flock_locks); /* debugfs.c */ -extern int ceph_fs_debugfs_init(struct ceph_fs_client *client); +extern void ceph_fs_debugfs_init(struct ceph_fs_client *client); extern void ceph_fs_debugfs_cleanup(struct ceph_fs_client *client); /* quota.c */ diff --git a/include/linux/ceph/debugfs.h b/include/linux/ceph/debugfs.h index fa5f9b7f5dbb..cf5e840eec71 100644 --- a/include/linux/ceph/debugfs.h +++ b/include/linux/ceph/debugfs.h @@ -19,9 +19,9 @@ static const struct file_operations name##_fops = { \ }; /* debugfs.c */ -extern int ceph_debugfs_init(void); +extern void ceph_debugfs_init(void); extern void ceph_debugfs_cleanup(void); -extern int ceph_debugfs_client_init(struct ceph_client *client); +extern void ceph_debugfs_client_init(struct ceph_client *client); extern void ceph_debugfs_client_cleanup(struct ceph_client *client); #endif diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 1c811c74bfc0..4eeea4d5c3ef 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -776,9 +776,7 @@ static int __init init_ceph_lib(void) { int ret = 0; - ret = ceph_debugfs_init(); - if (ret < 0) - goto out; + ceph_debugfs_init(); ret = ceph_crypto_init(); if (ret < 0) @@ -803,7 +801,6 @@ out_crypto: ceph_crypto_shutdown(); out_debugfs: ceph_debugfs_cleanup(); -out: return ret; } diff --git a/net/ceph/debugfs.c b/net/ceph/debugfs.c index 63aef9915f75..7cb992e55475 100644 --- a/net/ceph/debugfs.c +++ b/net/ceph/debugfs.c @@ -389,12 +389,9 @@ CEPH_DEFINE_SHOW_FUNC(monc_show) CEPH_DEFINE_SHOW_FUNC(osdc_show) CEPH_DEFINE_SHOW_FUNC(client_options_show) -int __init ceph_debugfs_init(void) +void __init ceph_debugfs_init(void) { ceph_debugfs_dir = debugfs_create_dir("ceph", NULL); - if (!ceph_debugfs_dir) - return -ENOMEM; - return 0; } void ceph_debugfs_cleanup(void) @@ -402,9 +399,8 @@ void ceph_debugfs_cleanup(void) debugfs_remove(ceph_debugfs_dir); } -int ceph_debugfs_client_init(struct ceph_client *client) +void ceph_debugfs_client_init(struct ceph_client *client) { - int ret = -ENOMEM; char name[80]; snprintf(name, sizeof(name), "%pU.client%lld", &client->fsid, @@ -412,56 +408,37 @@ int ceph_debugfs_client_init(struct ceph_client *client) dout("ceph_debugfs_client_init %p %s\n", client, name); - BUG_ON(client->debugfs_dir); client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir); - if (!client->debugfs_dir) - goto out; client->monc.debugfs_file = debugfs_create_file("monc", 0400, client->debugfs_dir, client, &monc_show_fops); - if (!client->monc.debugfs_file) - goto out; client->osdc.debugfs_file = debugfs_create_file("osdc", 0400, client->debugfs_dir, client, &osdc_show_fops); - if (!client->osdc.debugfs_file) - goto out; client->debugfs_monmap = debugfs_create_file("monmap", 0400, client->debugfs_dir, client, &monmap_show_fops); - if (!client->debugfs_monmap) - goto out; client->debugfs_osdmap = debugfs_create_file("osdmap", 0400, client->debugfs_dir, client, &osdmap_show_fops); - if (!client->debugfs_osdmap) - goto out; client->debugfs_options = debugfs_create_file("client_options", 0400, client->debugfs_dir, client, &client_options_show_fops); - if (!client->debugfs_options) - goto out; - - return 0; - -out: - ceph_debugfs_client_cleanup(client); - return ret; } void ceph_debugfs_client_cleanup(struct ceph_client *client) @@ -477,18 +454,16 @@ void ceph_debugfs_client_cleanup(struct ceph_client *client) #else /* CONFIG_DEBUG_FS */ -int __init ceph_debugfs_init(void) +void __init ceph_debugfs_init(void) { - return 0; } void ceph_debugfs_cleanup(void) { } -int ceph_debugfs_client_init(struct ceph_client *client) +void ceph_debugfs_client_init(struct ceph_client *client) { - return 0; } void ceph_debugfs_client_cleanup(struct ceph_client *client) From 1be51474f99bcfdecef3f34b9a9a8cf4393fd8f9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 16:43:14 +0200 Subject: [PATCH 095/102] swiotlb: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Konrad Rzeszutek Wilk Cc: Christoph Hellwig Cc: Marek Szyprowski Cc: Robin Murphy Cc: iommu@lists.linux-foundation.org Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20190612144314.GA16803@kroah.com Signed-off-by: Greg Kroah-Hartman --- kernel/dma/swiotlb.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 13f0cb080a4d..62fa5a82a065 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -696,29 +696,12 @@ bool is_swiotlb_active(void) static int __init swiotlb_create_debugfs(void) { - struct dentry *d_swiotlb_usage; - struct dentry *ent; - - d_swiotlb_usage = debugfs_create_dir("swiotlb", NULL); - - if (!d_swiotlb_usage) - return -ENOMEM; - - ent = debugfs_create_ulong("io_tlb_nslabs", 0400, - d_swiotlb_usage, &io_tlb_nslabs); - if (!ent) - goto fail; - - ent = debugfs_create_ulong("io_tlb_used", 0400, - d_swiotlb_usage, &io_tlb_used); - if (!ent) - goto fail; + struct dentry *root; + root = debugfs_create_dir("swiotlb", NULL); + debugfs_create_ulong("io_tlb_nslabs", 0400, root, &io_tlb_nslabs); + debugfs_create_ulong("io_tlb_used", 0400, root, &io_tlb_used); return 0; - -fail: - debugfs_remove_recursive(d_swiotlb_usage); - return -ENOMEM; } late_initcall(swiotlb_create_debugfs); From 56f3364aba8866d0f7f8c965e7acf07f35679701 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 Jun 2019 17:36:13 +0200 Subject: [PATCH 096/102] lib: notifier-error-inject: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20190612153613.GA21239@kroah.com Signed-off-by: Greg Kroah-Hartman --- lib/notifier-error-inject.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/lib/notifier-error-inject.c b/lib/notifier-error-inject.c index 3d2ba7cf83f4..21016b32d313 100644 --- a/lib/notifier-error-inject.c +++ b/lib/notifier-error-inject.c @@ -59,33 +59,22 @@ struct dentry *notifier_err_inject_init(const char *name, struct dentry *parent, err_inject->nb.priority = priority; dir = debugfs_create_dir(name, parent); - if (!dir) - return ERR_PTR(-ENOMEM); actions_dir = debugfs_create_dir("actions", dir); - if (!actions_dir) - goto fail; for (action = err_inject->actions; action->name; action++) { struct dentry *action_dir; action_dir = debugfs_create_dir(action->name, actions_dir); - if (!action_dir) - goto fail; /* * Create debugfs r/w file containing action->error. If * notifier call chain is called with action->val, it will * fail with the error code */ - if (!debugfs_create_errno("error", mode, action_dir, - &action->error)) - goto fail; + debugfs_create_errno("error", mode, action_dir, &action->error); } return dir; -fail: - debugfs_remove_recursive(dir); - return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL_GPL(notifier_err_inject_init); From 0fd33116c1d8f8f9ff973c3d17280148068d77f4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 27 May 2019 14:27:03 +0200 Subject: [PATCH 097/102] arch_topology: Remove error messages on out-of-memory conditions There is no need to print error messages if kcalloc() or alloc_cpumask_var() fail, as the memory allocation core already takes care of that. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20190527122703.6303-1-geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman --- drivers/base/arch_topology.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 1739d7e1952a..8486c399ddb7 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -137,7 +137,6 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu) sizeof(*raw_capacity), GFP_KERNEL); if (!raw_capacity) { - pr_err("cpu_capacity: failed to allocate memory for raw capacities\n"); cap_parsing_failed = true; return false; } @@ -217,10 +216,8 @@ static int __init register_cpufreq_notifier(void) if (!acpi_disabled || !raw_capacity) return -EINVAL; - if (!alloc_cpumask_var(&cpus_to_visit, GFP_KERNEL)) { - pr_err("cpu_capacity: failed to allocate memory for cpus_to_visit\n"); + if (!alloc_cpumask_var(&cpus_to_visit, GFP_KERNEL)) return -ENOMEM; - } cpumask_copy(cpus_to_visit, cpu_possible_mask); From 83b44fe343b5abfcb1b2261289bd0cfcfcfd60a8 Mon Sep 17 00:00:00 2001 From: James Morse Date: Mon, 24 Jun 2019 18:36:56 +0100 Subject: [PATCH 098/102] drivers: base: cacheinfo: Ensure cpu hotplug work is done before Intel RDT The cacheinfo structures are alloced/freed by cpu online/offline callbacks. Originally these were only used by sysfs to expose the cache topology to user space. Without any in-kernel dependencies CPUHP_AP_ONLINE_DYN was an appropriate choice. resctrl has started using these structures to identify CPUs that share a cache. It updates its 'domain' structures from cpu online/offline callbacks. These depend on the cacheinfo structures (resctrl_online_cpu()->domain_add_cpu()->get_cache_id()-> get_cpu_cacheinfo()). These also run as CPUHP_AP_ONLINE_DYN. Now that there is an in-kernel dependency, move the cacheinfo work earlier so we know its done before resctrl's CPUHP_AP_ONLINE_DYN work runs. Fixes: 2264d9c74dda1 ("x86/intel_rdt: Build structures for each resource based on cache topology") Cc: Cc: Fenghua Yu Cc: Reinette Chatre Signed-off-by: James Morse Link: https://lore.kernel.org/r/20190624173656.202407-1-james.morse@arm.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/cacheinfo.c | 3 ++- include/linux/cpuhotplug.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index a7359535caf5..b444f89a2041 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -655,7 +655,8 @@ static int cacheinfo_cpu_pre_down(unsigned int cpu) static int __init cacheinfo_sysfs_init(void) { - return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "base/cacheinfo:online", + return cpuhp_setup_state(CPUHP_AP_BASE_CACHEINFO_ONLINE, + "base/cacheinfo:online", cacheinfo_cpu_online, cacheinfo_cpu_pre_down); } device_initcall(cacheinfo_sysfs_init); diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 6a381594608c..50c893f03c21 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -175,6 +175,7 @@ enum cpuhp_state { CPUHP_AP_WATCHDOG_ONLINE, CPUHP_AP_WORKQUEUE_ONLINE, CPUHP_AP_RCUTREE_ONLINE, + CPUHP_AP_BASE_CACHEINFO_ONLINE, CPUHP_AP_ONLINE_DYN, CPUHP_AP_ONLINE_DYN_END = CPUHP_AP_ONLINE_DYN + 30, CPUHP_AP_X86_HPET_ONLINE, From 62a6bc3a1e4f4ee9ae0076fa295f9af1c3725ce3 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 21 Jun 2019 17:17:25 +0200 Subject: [PATCH 099/102] driver: core: Allow subsystems to continue deferring probe Some subsystems, such as pinctrl, allow continuing to defer probe indefinitely. This is useful for devices that depend on resources provided by devices that are only probed after the init stage. One example of this can be seen on Tegra, where the DPAUX hardware contains pinmuxing controls for pins that it shares with an I2C controller. The I2C controller is typically used for communication with a monitor over HDMI (DDC). However, other instances of the I2C controller are used to access system critical components, such as a PMIC. The I2C controller driver will therefore usually be a builtin driver, whereas the DPAUX driver is part of the display driver that is loaded from a module to avoid bloating the kernel image with all of the DRM/KMS subsystem. In this particular case the pins used by this I2C/DDC controller become accessible very late in the boot process. However, since the controller is only used in conjunction with display, that's not an issue. Unfortunately the driver core currently outputs a warning message when a device fails to get the pinctrl before the end of the init stage. That can be confusing for the user because it may sound like an unwanted error occurred, whereas it's really an expected and harmless situation. In order to eliminate this warning, this patch allows callers of the driver_deferred_probe_check_state() helper to specify that they want to continue deferring probe, regardless of whether we're past the init stage or not. All of the callers of that function are updated for the new signature, but only the pinctrl subsystem passes a true value in the new persist parameter if appropriate. Signed-off-by: Thierry Reding Reviewed-by: Rafael J. Wysocki Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20190621151725.20414-1-thierry.reding@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 55 ++++++++++++++++++++++++++++++------ drivers/pinctrl/devicetree.c | 7 ++--- include/linux/device.h | 1 + 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 0df9b4461766..994a90747420 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -235,6 +235,19 @@ static int __init deferred_probe_timeout_setup(char *str) } __setup("deferred_probe_timeout=", deferred_probe_timeout_setup); +static int __driver_deferred_probe_check_state(struct device *dev) +{ + if (!initcalls_done) + return -EPROBE_DEFER; + + if (!deferred_probe_timeout) { + dev_WARN(dev, "deferred probe timeout, ignoring dependency"); + return -ETIMEDOUT; + } + + return 0; +} + /** * driver_deferred_probe_check_state() - Check deferred probe state * @dev: device to check @@ -248,14 +261,40 @@ __setup("deferred_probe_timeout=", deferred_probe_timeout_setup); */ int driver_deferred_probe_check_state(struct device *dev) { - if (initcalls_done) { - if (!deferred_probe_timeout) { - dev_WARN(dev, "deferred probe timeout, ignoring dependency"); - return -ETIMEDOUT; - } - dev_warn(dev, "ignoring dependency for device, assuming no driver"); - return -ENODEV; - } + int ret; + + ret = __driver_deferred_probe_check_state(dev); + if (ret < 0) + return ret; + + dev_warn(dev, "ignoring dependency for device, assuming no driver"); + + return -ENODEV; +} + +/** + * driver_deferred_probe_check_state_continue() - check deferred probe state + * @dev: device to check + * + * Returns -ETIMEDOUT if deferred probe debug timeout has expired, or + * -EPROBE_DEFER otherwise. + * + * Drivers or subsystems can opt-in to calling this function instead of + * directly returning -EPROBE_DEFER. + * + * This is similar to driver_deferred_probe_check_state(), but it allows the + * subsystem to keep deferring probe after built-in drivers have had a chance + * to probe. One scenario where that is useful is if built-in drivers rely on + * resources that are provided by modular drivers. + */ +int driver_deferred_probe_check_state_continue(struct device *dev) +{ + int ret; + + ret = __driver_deferred_probe_check_state(dev); + if (ret < 0) + return ret; + return -EPROBE_DEFER; } diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index f7e354f85518..88ddbb2e30de 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -112,12 +112,11 @@ static int dt_to_map_one_config(struct pinctrl *p, np_pctldev = of_get_next_parent(np_pctldev); if (!np_pctldev || of_node_is_root(np_pctldev)) { of_node_put(np_pctldev); - ret = driver_deferred_probe_check_state(p->dev); /* keep deferring if modules are enabled unless we've timed out */ - if (IS_ENABLED(CONFIG_MODULES) && !allow_default && ret == -ENODEV) - ret = -EPROBE_DEFER; + if (IS_ENABLED(CONFIG_MODULES) && !allow_default) + return driver_deferred_probe_check_state_continue(p->dev); - return ret; + return driver_deferred_probe_check_state(p->dev); } /* If we're creating a hog we can use the passed pctldev */ if (hog_pctldev && (np_pctldev == p->dev->of_node)) { diff --git a/include/linux/device.h b/include/linux/device.h index 709308560d32..ef61e2d50ecc 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -343,6 +343,7 @@ struct device *driver_find_device(struct device_driver *drv, void driver_deferred_probe_add(struct device *dev); int driver_deferred_probe_check_state(struct device *dev); +int driver_deferred_probe_check_state_continue(struct device *dev); /** * struct subsys_interface - interfaces to device functions From d71cac5971192049a3a375a2e68b63f4092bd6a1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 4 Jul 2019 08:32:10 +0200 Subject: [PATCH 100/102] ubifs: fix build warning after debugfs cleanup patch Stephen writes: After merging the driver-core tree, today's linux-next build (arm multi_v7_defconfig) produced this warning: fs/ubifs/debug.c: In function 'dbg_debugfs_init_fs': fs/ubifs/debug.c:2812:6: warning: unused variable 'err' [-Wunused-variable] int err, n; ^~~ So fix this up properly. Reported-by: Stephen Rothwell Cc: Richard Weinberger Cc: Artem Bityutskiy Cc: Adrian Hunter Cc: linux-mtd@lists.infradead.org Signed-off-by: Greg Kroah-Hartman --- fs/ubifs/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 57e6fcb043ca..baae6eceabac 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -2821,7 +2821,7 @@ static const struct file_operations dfs_fops = { */ void dbg_debugfs_init_fs(struct ubifs_info *c) { - int err, n; + int n; const char *fname; struct ubifs_debug_info *d = c->dbg; From 0979cf95d201f7e9c7c060b96795f39733d2ed6e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 4 Jul 2019 10:28:36 +0200 Subject: [PATCH 101/102] orangefs: fix build warning from debugfs cleanup patch Stephen writes: After merging the driver-core tree, today's linux-next build (x86_64 allmodconfig) produced this warning: fs/orangefs/orangefs-debugfs.c: In function 'orangefs_debugfs_init': fs/orangefs/orangefs-debugfs.c:193:1: warning: label 'out' defined but not used [-Wunused-label] out: ^~~ fs/orangefs/orangefs-debugfs.c: In function 'orangefs_kernel_debug_init': fs/orangefs/orangefs-debugfs.c:204:17: warning: unused variable 'ret' [-Wunused-variable] struct dentry *ret; ^~~ Fix this up and change the return type of the function to void as it can not fail, which cleans up some more code and variables as well. Cc: Mike Marshall Cc: Martin Brandenburg Cc: devel@lists.orangefs.org Reported-by: Stephen Rothwell Fixes: f095adba36bb ("orangefs: no need to check return value of debugfs_create functions") Signed-off-by: Greg Kroah-Hartman --- fs/orangefs/orangefs-debugfs.c | 19 ++++--------------- fs/orangefs/orangefs-debugfs.h | 2 +- fs/orangefs/orangefs-mod.c | 6 +----- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c index 7723f581017d..25543a966c48 100644 --- a/fs/orangefs/orangefs-debugfs.c +++ b/fs/orangefs/orangefs-debugfs.c @@ -64,7 +64,7 @@ struct client_debug_mask { __u64 mask2; }; -static int orangefs_kernel_debug_init(void); +static void orangefs_kernel_debug_init(void); static int orangefs_debug_help_open(struct inode *, struct file *); static void *help_start(struct seq_file *, loff_t *); @@ -150,10 +150,8 @@ static DEFINE_MUTEX(orangefs_help_file_lock); * initialize kmod debug operations, create orangefs debugfs dir and * ORANGEFS_KMOD_DEBUG_HELP_FILE. */ -int orangefs_debugfs_init(int debug_mask) +void orangefs_debugfs_init(int debug_mask) { - int rc = -ENOMEM; - /* convert input debug mask to a 64-bit unsigned integer */ orangefs_gossip_debug_mask = (unsigned long long)debug_mask; @@ -188,20 +186,15 @@ int orangefs_debugfs_init(int debug_mask) orangefs_debug_disabled = 0; - rc = orangefs_kernel_debug_init(); - -out: - - return rc; + orangefs_kernel_debug_init(); } /* * initialize the kernel-debug file. */ -static int orangefs_kernel_debug_init(void) +static void orangefs_kernel_debug_init(void) { int rc = -ENOMEM; - struct dentry *ret; char *k_buffer = NULL; gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__); @@ -221,12 +214,8 @@ static int orangefs_kernel_debug_init(void) debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, 0444, debug_dir, k_buffer, &kernel_debug_fops); - rc = 0; - out: - gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc); - return rc; } diff --git a/fs/orangefs/orangefs-debugfs.h b/fs/orangefs/orangefs-debugfs.h index 51147f9ce3d6..502f6dedccde 100644 --- a/fs/orangefs/orangefs-debugfs.h +++ b/fs/orangefs/orangefs-debugfs.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -int orangefs_debugfs_init(int); +void orangefs_debugfs_init(int); void orangefs_debugfs_cleanup(void); int orangefs_prepare_debugfs_help_string(int); int orangefs_debugfs_new_client_mask(void __user *); diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c index 4f2d7ee0d2d1..c010c1fddafc 100644 --- a/fs/orangefs/orangefs-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -129,9 +129,7 @@ static int __init orangefs_init(void) if (ret) goto cleanup_key_table; - ret = orangefs_debugfs_init(module_parm_debug_mask); - if (ret) - goto debugfs_init_failed; + orangefs_debugfs_init(module_parm_debug_mask); ret = orangefs_sysfs_init(); if (ret) @@ -161,8 +159,6 @@ cleanup_device: orangefs_dev_cleanup(); sysfs_init_failed: - -debugfs_init_failed: orangefs_debugfs_cleanup(); cleanup_key_table: From c33d442328f556460b79aba6058adb37bb555389 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 6 Jul 2019 17:42:56 +0200 Subject: [PATCH 102/102] debugfs: make error message a bit more verbose When a file/directory is already present in debugfs, and it is attempted to be created again, be more specific about what file/directory is being created and where it is trying to be created to give a bit more help to developers to figure out the problem. Cc: Stephen Rothwell Cc: Rafael J. Wysocki Cc: Mark Brown Cc: Takashi Iwai Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20190706154256.GA2683@kroah.com Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 7f43c8acfcbf..5836312269e0 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -311,8 +311,13 @@ static struct dentry *start_creating(const char *name, struct dentry *parent) inode_lock(d_inode(parent)); dentry = lookup_one_len(name, parent, strlen(name)); if (!IS_ERR(dentry) && d_really_is_positive(dentry)) { + if (d_is_dir(dentry)) + pr_err("Directory '%s' with parent '%s' already present!\n", + name, parent->d_name.name); + else + pr_err("File '%s' in directory '%s' already present!\n", + name, parent->d_name.name); dput(dentry); - pr_err("File '%s' already present!\n", name); dentry = ERR_PTR(-EEXIST); }