Skip to content

Commit d1313e7

Browse files
committed
iommu/tegra-smmu: Add debugfs support
Provide clients and swgroups files in debugfs. These files show for which clients IOMMU translation is enabled and which ASID is associated with each SWGROUP. Cc: Hiroshi Doyu <[email protected]> Acked-by: Joerg Roedel <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent e660df0 commit d1313e7

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

drivers/iommu/tegra-smmu.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
#include <linux/bitops.h>
10+
#include <linux/debugfs.h>
1011
#include <linux/err.h>
1112
#include <linux/iommu.h>
1213
#include <linux/kernel.h>
@@ -31,6 +32,8 @@ struct tegra_smmu {
3132
struct mutex lock;
3233

3334
struct list_head list;
35+
36+
struct dentry *debugfs;
3437
};
3538

3639
struct tegra_smmu_as {
@@ -673,6 +676,103 @@ static void tegra_smmu_ahb_enable(void)
673676
}
674677
}
675678

679+
static int tegra_smmu_swgroups_show(struct seq_file *s, void *data)
680+
{
681+
struct tegra_smmu *smmu = s->private;
682+
unsigned int i;
683+
u32 value;
684+
685+
seq_printf(s, "swgroup enabled ASID\n");
686+
seq_printf(s, "------------------------\n");
687+
688+
for (i = 0; i < smmu->soc->num_swgroups; i++) {
689+
const struct tegra_smmu_swgroup *group = &smmu->soc->swgroups[i];
690+
const char *status;
691+
unsigned int asid;
692+
693+
value = smmu_readl(smmu, group->reg);
694+
695+
if (value & SMMU_ASID_ENABLE)
696+
status = "yes";
697+
else
698+
status = "no";
699+
700+
asid = value & SMMU_ASID_MASK;
701+
702+
seq_printf(s, "%-9s %-7s %#04x\n", group->name, status,
703+
asid);
704+
}
705+
706+
return 0;
707+
}
708+
709+
static int tegra_smmu_swgroups_open(struct inode *inode, struct file *file)
710+
{
711+
return single_open(file, tegra_smmu_swgroups_show, inode->i_private);
712+
}
713+
714+
static const struct file_operations tegra_smmu_swgroups_fops = {
715+
.open = tegra_smmu_swgroups_open,
716+
.read = seq_read,
717+
.llseek = seq_lseek,
718+
.release = single_release,
719+
};
720+
721+
static int tegra_smmu_clients_show(struct seq_file *s, void *data)
722+
{
723+
struct tegra_smmu *smmu = s->private;
724+
unsigned int i;
725+
u32 value;
726+
727+
seq_printf(s, "client enabled\n");
728+
seq_printf(s, "--------------------\n");
729+
730+
for (i = 0; i < smmu->soc->num_clients; i++) {
731+
const struct tegra_mc_client *client = &smmu->soc->clients[i];
732+
const char *status;
733+
734+
value = smmu_readl(smmu, client->smmu.reg);
735+
736+
if (value & BIT(client->smmu.bit))
737+
status = "yes";
738+
else
739+
status = "no";
740+
741+
seq_printf(s, "%-12s %s\n", client->name, status);
742+
}
743+
744+
return 0;
745+
}
746+
747+
static int tegra_smmu_clients_open(struct inode *inode, struct file *file)
748+
{
749+
return single_open(file, tegra_smmu_clients_show, inode->i_private);
750+
}
751+
752+
static const struct file_operations tegra_smmu_clients_fops = {
753+
.open = tegra_smmu_clients_open,
754+
.read = seq_read,
755+
.llseek = seq_lseek,
756+
.release = single_release,
757+
};
758+
759+
static void tegra_smmu_debugfs_init(struct tegra_smmu *smmu)
760+
{
761+
smmu->debugfs = debugfs_create_dir("smmu", NULL);
762+
if (!smmu->debugfs)
763+
return;
764+
765+
debugfs_create_file("swgroups", S_IRUGO, smmu->debugfs, smmu,
766+
&tegra_smmu_swgroups_fops);
767+
debugfs_create_file("clients", S_IRUGO, smmu->debugfs, smmu,
768+
&tegra_smmu_clients_fops);
769+
}
770+
771+
static void tegra_smmu_debugfs_exit(struct tegra_smmu *smmu)
772+
{
773+
debugfs_remove_recursive(smmu->debugfs);
774+
}
775+
676776
struct tegra_smmu *tegra_smmu_probe(struct device *dev,
677777
const struct tegra_smmu_soc *soc,
678778
struct tegra_mc *mc)
@@ -743,5 +843,14 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
743843
if (err < 0)
744844
return ERR_PTR(err);
745845

846+
if (IS_ENABLED(CONFIG_DEBUG_FS))
847+
tegra_smmu_debugfs_init(smmu);
848+
746849
return smmu;
747850
}
851+
852+
void tegra_smmu_remove(struct tegra_smmu *smmu)
853+
{
854+
if (IS_ENABLED(CONFIG_DEBUG_FS))
855+
tegra_smmu_debugfs_exit(smmu);
856+
}

include/soc/tegra/mc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,18 @@ struct tegra_smmu;
7272
struct tegra_smmu *tegra_smmu_probe(struct device *dev,
7373
const struct tegra_smmu_soc *soc,
7474
struct tegra_mc *mc);
75+
void tegra_smmu_remove(struct tegra_smmu *smmu);
7576
#else
7677
static inline struct tegra_smmu *
7778
tegra_smmu_probe(struct device *dev, const struct tegra_smmu_soc *soc,
7879
struct tegra_mc *mc)
7980
{
8081
return NULL;
8182
}
83+
84+
static inline void tegra_smmu_remove(struct tegra_smmu *smmu)
85+
{
86+
}
8287
#endif
8388

8489
struct tegra_mc_soc {

0 commit comments

Comments
 (0)