| // SPDX-License-Identifier: GPL-2.0 |
| /* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ |
| |
| #include <linux/kernel.h> |
| #include <linux/debugfs.h> |
| #include <linux/stringify.h> |
| #include "cc_driver.h" |
| #include "cc_crypto_ctx.h" |
| #include "cc_debugfs.h" |
| |
| struct cc_debugfs_ctx { |
| struct dentry *dir; |
| }; |
| |
| #define CC_DEBUG_REG(_X) { \ |
| .name = __stringify(_X),\ |
| .offset = CC_REG(_X) \ |
| } |
| |
| /* |
| * This is a global var for the dentry of the |
| * debugfs ccree/ dir. It is not tied down to |
| * a specific instance of ccree, hence it is |
| * global. |
| */ |
| static struct dentry *cc_debugfs_dir; |
| |
| static struct debugfs_reg32 debug_regs[] = { |
| { .name = "SIGNATURE" }, /* Must be 0th */ |
| { .name = "VERSION" }, /* Must be 1st */ |
| CC_DEBUG_REG(HOST_IRR), |
| CC_DEBUG_REG(HOST_POWER_DOWN_EN), |
| CC_DEBUG_REG(AXIM_MON_ERR), |
| CC_DEBUG_REG(DSCRPTR_QUEUE_CONTENT), |
| CC_DEBUG_REG(HOST_IMR), |
| CC_DEBUG_REG(AXIM_CFG), |
| CC_DEBUG_REG(AXIM_CACHE_PARAMS), |
| CC_DEBUG_REG(GPR_HOST), |
| CC_DEBUG_REG(AXIM_MON_COMP), |
| }; |
| |
| int __init cc_debugfs_global_init(void) |
| { |
| cc_debugfs_dir = debugfs_create_dir("ccree", NULL); |
| |
| return !cc_debugfs_dir; |
| } |
| |
| void __exit cc_debugfs_global_fini(void) |
| { |
| debugfs_remove(cc_debugfs_dir); |
| } |
| |
| int cc_debugfs_init(struct cc_drvdata *drvdata) |
| { |
| struct device *dev = drvdata_to_dev(drvdata); |
| struct cc_debugfs_ctx *ctx; |
| struct debugfs_regset32 *regset; |
| struct dentry *file; |
| |
| debug_regs[0].offset = drvdata->sig_offset; |
| debug_regs[1].offset = drvdata->ver_offset; |
| |
| ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); |
| if (!ctx) |
| return -ENOMEM; |
| |
| regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL); |
| if (!regset) |
| return -ENOMEM; |
| |
| regset->regs = debug_regs; |
| regset->nregs = ARRAY_SIZE(debug_regs); |
| regset->base = drvdata->cc_base; |
| |
| ctx->dir = debugfs_create_dir(drvdata->plat_dev->name, cc_debugfs_dir); |
| if (!ctx->dir) |
| return -ENFILE; |
| |
| file = debugfs_create_regset32("regs", 0400, ctx->dir, regset); |
| if (!file) { |
| debugfs_remove(ctx->dir); |
| return -ENFILE; |
| } |
| |
| file = debugfs_create_bool("coherent", 0400, ctx->dir, |
| &drvdata->coherent); |
| |
| if (!file) { |
| debugfs_remove_recursive(ctx->dir); |
| return -ENFILE; |
| } |
| |
| drvdata->debugfs = ctx; |
| |
| return 0; |
| } |
| |
| void cc_debugfs_fini(struct cc_drvdata *drvdata) |
| { |
| struct cc_debugfs_ctx *ctx = (struct cc_debugfs_ctx *)drvdata->debugfs; |
| |
| debugfs_remove_recursive(ctx->dir); |
| } |