diff --git a/drivers/firmware/tegra/Kconfig b/drivers/firmware/tegra/Kconfig index 91f2320c0d0f..3a9162706439 100644 --- a/drivers/firmware/tegra/Kconfig +++ b/drivers/firmware/tegra/Kconfig @@ -2,7 +2,7 @@ menu "Tegra firmware driver" config TEGRA_IVC - bool "Tegra IVC protocol" if COMPILE_TEST + bool depends on ARCH_TEGRA help IVC (Inter-VM Communication) protocol is part of the IPC diff --git a/drivers/firmware/tegra/bpmp-debugfs.c b/drivers/firmware/tegra/bpmp-debugfs.c index 4221fed70ad4..33c6300af964 100644 --- a/drivers/firmware/tegra/bpmp-debugfs.c +++ b/drivers/firmware/tegra/bpmp-debugfs.c @@ -2,6 +2,8 @@ /* * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. */ + +#include #include #include #include @@ -468,7 +470,7 @@ static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp, dentry = debugfs_create_file(name, mode, parent, bpmp, &bpmp_debug_fops); if (IS_ERR(dentry)) { - err = -ENOMEM; + err = PTR_ERR(dentry); goto out; } } @@ -719,7 +721,7 @@ static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf, if (t & DEBUGFS_S_ISDIR) { dentry = debugfs_create_dir(name, parent); if (IS_ERR(dentry)) - return -ENOMEM; + return PTR_ERR(dentry); err = bpmp_populate_dir(bpmp, seqbuf, dentry, depth+1); if (err < 0) return err; @@ -732,7 +734,7 @@ static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf, parent, bpmp, &debugfs_fops); if (IS_ERR(dentry)) - return -ENOMEM; + return PTR_ERR(dentry); } } @@ -769,9 +771,21 @@ static int bpmp_populate_debugfs_shmem(struct tegra_bpmp *bpmp) return err; } +static DEFINE_MUTEX(bpmp_debugfs_root_lock); +static struct dentry *bpmp_debugfs_root; + +static struct dentry *bpmp_debugfs_get_root(void) +{ + guard(mutex)(&bpmp_debugfs_root_lock); + if (!bpmp_debugfs_root) + bpmp_debugfs_root = debugfs_create_dir("bpmp", NULL); + return bpmp_debugfs_root; +} + int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp) { - struct dentry *root; + struct dentry *root, *d; + char name[32]; bool inband; int err; @@ -780,13 +794,24 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp) if (!inband && !tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS)) return 0; - root = debugfs_create_dir("bpmp", NULL); + root = bpmp_debugfs_get_root(); if (IS_ERR(root)) - return -ENOMEM; + return PTR_ERR(root); - bpmp->debugfs_mirror = debugfs_create_dir("debug", root); + if (dev_to_node(bpmp->dev) == NUMA_NO_NODE) { + d = root; + } else { + snprintf(name, sizeof(name), "%d-bpmp", dev_to_node(bpmp->dev)); + d = debugfs_create_dir(name, root); + if (IS_ERR(d)) { + err = PTR_ERR(d); + goto out; + } + } + + bpmp->debugfs_mirror = debugfs_create_dir("debug", d); if (IS_ERR(bpmp->debugfs_mirror)) { - err = -ENOMEM; + err = PTR_ERR(bpmp->debugfs_mirror); goto out; } @@ -797,8 +822,18 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp) err = bpmp_populate_debugfs_shmem(bpmp); out: - if (err < 0) - debugfs_remove_recursive(root); + if (err < 0) { + if (!IS_ERR(d)) + debugfs_remove_recursive(d); + + guard(mutex)(&bpmp_debugfs_root_lock); + if (root == d) { + bpmp_debugfs_root = NULL; + } else if (simple_empty(root)) { + debugfs_remove(root); + bpmp_debugfs_root = NULL; + } + } return err; }