<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<p style="font-family:Arial;font-size:10pt;color:#0000FF;margin:5pt;" align="Left">
[AMD Official Use Only]<br>
</p>
<br>
<div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of Candice Li <candice.li@amd.com><br>
<b>Sent:</b> Monday, April 18, 2022 11:09 AM<br>
<b>To:</b> amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Cc:</b> Li, Candice <Candice.Li@amd.com>; Clements, John <John.Clements@amd.com><br>
<b>Subject:</b> [PATCH 2/2] drm/amdgpu: Add debugfs TA load/unload/invoke support</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt" class="elementToProof">
<div class="PlainText elementToProof">Add debugfs support to load/unload/invoke TA in runtime.<br>
<br>
Signed-off-by: John Clements <john.clements@amd.com><br>
Signed-off-by: Candice Li <candice.li@amd.com><br>
---<br>
 drivers/gpu/drm/amd/amdgpu/Makefile         |   2 +-<br>
 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c |   2 +<br>
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c  | 312 ++++++++++++++++++++<br>
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.h  |  30 ++<br>
 4 files changed, 345 insertions(+), 1 deletion(-)<br>
 create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c<br>
 create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.h<br>
<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile<br>
index 7d7af43a258f83..b525f9be9326f4 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/Makefile<br>
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile<br>
@@ -58,7 +58,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \<br>
         amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \<br>
         amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \<br>
         amdgpu_fw_attestation.o amdgpu_securedisplay.o \<br>
-       amdgpu_eeprom.o amdgpu_mca.o<br>
+       amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o<br>
 <br>
 amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o<br>
 <br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c<br>
index 13e4d8f9b87449..eedb12f6b8a32d 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c<br>
@@ -38,6 +38,7 @@<br>
 #include "amdgpu_umr.h"<br>
 <br>
 #include "amdgpu_reset.h"<br>
+#include "amdgpu_psp_ta.h"<br>
 <br>
 #if defined(CONFIG_DEBUG_FS)<br>
 <br>
@@ -1767,6 +1768,7 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)<br>
                 DRM_ERROR("registering register debugfs failed (%d).\n", r);<br>
 <br>
         amdgpu_debugfs_firmware_init(adev);<br>
+       amdgpu_ta_if_debugfs_init(adev);<br>
 <br>
 #if defined(CONFIG_DRM_AMD_DC)<br>
         if (amdgpu_device_has_dc_support(adev))<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c<br>
new file mode 100644<br>
index 00000000000000..916bf3f6fce0d4<br>
--- /dev/null<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c<br>
@@ -0,0 +1,312 @@<br>
+/*<br>
+ * Copyright 2022 Advanced Micro Devices, Inc.<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice shall be included in<br>
+ * all copies or substantial portions of the Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR<br>
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,<br>
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR<br>
+ * OTHER DEALINGS IN THE SOFTWARE.<br>
+ *<br>
+ */<br>
+<br>
+#include "amdgpu.h"<br>
+#include "amdgpu_psp_ta.h"<br>
+<br>
+static const char *TA_IF_FS_NAME = "ta_if";<br>
+<br>
+struct dentry *dir;<br>
+struct dentry *ta_load_debugfs_dentry;<br>
+struct dentry *ta_unload_debugfs_dentry;<br>
+struct dentry *ta_invoke_debugfs_dentry;</div>
<div class="PlainText elementToProof"><br>
</div>
<div class="PlainText elementToProof"><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0);">[kevin]:</span></div>
<div class="PlainText elementToProof"><br>
</div>
<div class="PlainText elementToProof"><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0);">make
 above variable as static is better for this case, but it seems it is not used in this patch? </span></div>
<div class="PlainText elementToProof"><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0);">if
 so, you will get a "defined but not used" error, when turn on build option " -Werror=unused-variable".</span></div>
<div class="PlainText elementToProof"><br>
</div>
<div class="PlainText elementToProof"></div>
</span><span style="font-size: 11pt; font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0);" class="elementToProof">Please
 don't mind this prompt.</span><span style="font-size:11pt" class="elementToProof">
<div><br>
</div>
<div class="PlainText elementToProof"><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0);">Best
 Regards,</span></div>
<div class="PlainText elementToProof"><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0);">Kevin</span><br>
+<br>
+static ssize_t ta_if_load_debugfs_read(struct file *fp, char *buf, size_t len, loff_t *off);<br>
+static ssize_t ta_if_unload_debugfs_read(struct file *fp, char *buf, size_t len, loff_t *off);<br>
+static ssize_t ta_if_invoke_debugfs_read(struct file *fp, char *buf, size_t len, loff_t *off);<br>
+<br>
+<br>
+static uint32_t get_bin_version(const uint8_t *bin)<br>
+{<br>
+       const struct common_firmware_header *hdr =<br>
+                            (const struct common_firmware_header *)bin;<br>
+<br>
+       return hdr->ucode_version;<br>
+}<br>
+<br>
+static uint32_t get_shared_buf_size(uint32_t shared_buf_len)<br>
+{<br>
+       return (shared_buf_len % PAGE_SIZE) ?<br>
+                            (shared_buf_len/PAGE_SIZE + 1) * PAGE_SIZE :<br>
+                            shared_buf_len;</div>
<div class="PlainText elementToProof">[kevin]:</div>
<div class="PlainText elementToProof">
<ol>
<li><span>the above code can be replaced with "ALIGN" macro..</span></li><li style="display:block"></li><li style="display:block"> #define ALIGN(x, a)>---->-------__ALIGN_KERNEL((x), (a)</li></ol>
<ol start="2">
<li>do you forget to add some lock resource to protect/cover multi process case?</li><li style="display:block">e.g: process#1 exec load_ta() and process#2 exec unload_ta()</li></ol>
<div><br>
</div>
<div></div>
</div>
<div class="PlainText elementToProof">and why not use write operation instead of read (load/unload/invoke)
<span style="background-color:rgb(255, 255, 255);display:inline !important">? </span>this seems more reasonable.</div>
<div class="PlainText elementToProof">
<div><br>
</div>
</div>
<div class="PlainText elementToProof">Best Regards,</div>
<div class="PlainText elementToProof">Kevin</div>
<div class="PlainText elementToProof"><br>
</div>
<div class="PlainText elementToProof">+}<br>
+<br>
+static void prep_ta_mem_context(struct psp_context *psp,<br>
+                                            struct ta_context *context,<br>
+                                            uint8_t *shared_buf,<br>
+                                            uint32_t shared_buf_len)<br>
+{<br>
+       context->mem_context.shared_mem_size = get_shared_buf_size(shared_buf_len);<br>
+       psp_ta_init_shared_buf(psp, &context->mem_context);<br>
+<br>
+       memcpy((void *)context->mem_context.shared_buf, shared_buf, shared_buf_len);<br>
+}<br>
+<br>
+static bool is_ta_type_valid(enum ta_type_id ta_type)<br>
+{<br>
+       bool ret = false;<br>
+<br>
+       switch (ta_type) {<br>
+       case TA_TYPE_RAS:<br>
+               ret = true;<br>
+               break;<br>
+       default:<br>
+               break;<br>
+       }<br>
+<br>
+       return ret;<br>
+}<br>
+<br>
+static const struct file_operations ta_load_debugfs_fops = {<br>
+       .read   = ta_if_load_debugfs_read,<br>
+       .llseek = default_llseek,<br>
+       .owner  = THIS_MODULE<br>
+};<br>
+<br>
+static const struct file_operations ta_unload_debugfs_fops = {<br>
+       .read   = ta_if_unload_debugfs_read,<br>
+       .llseek = default_llseek,<br>
+       .owner  = THIS_MODULE<br>
+};<br>
+<br>
+static const struct file_operations ta_invoke_debugfs_fops = {<br>
+       .read   = ta_if_invoke_debugfs_read,<br>
+       .llseek = default_llseek,<br>
+       .owner  = THIS_MODULE<br>
+};<br>
+<br>
+<br>
+/**<br>
+ * DOC: AMDGPU TA debugfs interfaces<br>
+ *<br>
+ * Three debugfs interfaces can be opened by a program to<br>
+ * load/invoke/unload TA,<br>
+ *<br>
+ * - /sys/kernel/debug/dri/<N>/ta_if/ta_load<br>
+ * - /sys/kernel/debug/dri/<N>/ta_if/ta_invoke<br>
+ * - /sys/kernel/debug/dri/<N>/ta_if/ta_unload<br>
+ *<br>
+ * How to use the interfaces in a program?<br>
+ *<br>
+ * A program needs to provide transmit buffer to the interfaces<br>
+ * and will receive buffer from the interfaces below,<br>
+ *<br>
+ * - For TA load debugfs interface:<br>
+ *   Transmit buffer:<br>
+ *    - TA type (4bytes)<br>
+ *    - TA bin length (4bytes)<br>
+ *    - TA bin<br>
+ *   Receive buffer:<br>
+ *    - TA ID (4bytes)<br>
+ *<br>
+ * - For TA invoke debugfs interface:<br>
+ *   Transmit buffer:<br>
+ *    - TA ID (4bytes)<br>
+ *    - TA CMD ID (4bytes)<br>
+ *    - TA shard buf length (4bytes)<br>
+ *    - TA shared buf<br>
+ *   Receive buffer:<br>
+ *    - TA shared buf<br>
+ *<br>
+ * - For TA unload debugfs interface:<br>
+ *   Transmit buffer:<br>
+ *    - TA ID (4bytes)<br>
+ */<br>
+<br>
+static ssize_t ta_if_load_debugfs_read(struct file *fp, char *buf, size_t len, loff_t *off)<br>
+{<br>
+       uint32_t ta_type    = 0;<br>
+       uint32_t ta_bin_len = 0;<br>
+       uint8_t  *ta_bin    = NULL;<br>
+       uint32_t copy_pos   = 0;<br>
+       int      ret        = 0;<br>
+<br>
+       struct amdgpu_device *adev   = (struct amdgpu_device *)file_inode(fp)->i_private;<br>
+       struct psp_context   *psp    = &adev->psp;<br>
+       struct ta_context    context = {0};<br>
+<br>
+       if ((fp == NULL) || (buf == NULL))<br>
+               return -EINVAL;<br>
+<br>
+       ret = copy_from_user((void *)&ta_type, &buf[copy_pos], sizeof(uint32_t));<br>
+       if (ret || (!is_ta_type_valid(ta_type)))<br>
+               return -EINVAL;<br>
+<br>
+       copy_pos += sizeof(uint32_t);<br>
+<br>
+       ret = copy_from_user((void *)&ta_bin_len, &buf[copy_pos], sizeof(uint32_t));<br>
+       if (ret)<br>
+               return -EINVAL;<br>
+<br>
+       copy_pos += sizeof(uint32_t);<br>
+<br>
+       ta_bin = kzalloc(ta_bin_len, GFP_KERNEL);<br>
+       if (!ta_bin)<br>
+               ret = -ENOMEM;<br>
+       ret = copy_from_user((void *)ta_bin, &buf[copy_pos], ta_bin_len);<br>
+       if (ret)<br>
+               goto err_free_bin;<br>
+<br>
+       ret = psp_ras_terminate(psp);<br>
+       if (ret) {<br>
+               dev_err(adev->dev, "Failed to unload embedded RAS TA\n");<br>
+               goto err_free_bin;<br>
+       }<br>
+<br>
+       context.ta_type             = ta_type;<br>
+       context.ta_load_type        = GFX_CMD_ID_LOAD_TA;<br>
+       context.bin_desc.fw_version = get_bin_version(ta_bin);<br>
+       context.bin_desc.size_bytes = ta_bin_len;<br>
+       context.bin_desc.start_addr = ta_bin;<br>
+<br>
+       ret = psp_ta_load(psp, &context);<br>
+<br>
+       if (ret || context.resp_status) {<br>
+               dev_err(adev->dev, "TA load via debugfs failed (%d) status %d\n",<br>
+                        ret, context.resp_status);<br>
+               goto err_free_bin;<br>
+       }<br>
+<br>
+       context.initialized = true;<br>
+       ret = copy_to_user((char *)buf, (void *)&context.session_id, sizeof(uint32_t));<br>
+<br>
+err_free_bin:<br>
+       kfree(ta_bin);<br>
+<br>
+       return ret;<br>
+}<br>
+<br>
+static ssize_t ta_if_unload_debugfs_read(struct file *fp, char *buf, size_t len, loff_t *off)<br>
+{<br>
+       uint32_t ta_id  = 0;<br>
+       int      ret    = 0;<br>
+<br>
+       struct amdgpu_device *adev   = (struct amdgpu_device *)file_inode(fp)->i_private;<br>
+       struct psp_context   *psp    = &adev->psp;<br>
+       struct ta_context    context = {0};<br>
+<br>
+       if ((fp == NULL) || (buf == NULL))<br>
+               return -1;<br>
+<br>
+       ret = copy_from_user((void *)&ta_id, buf, sizeof(uint32_t));<br>
+       if (ret)<br>
+               return -EINVAL;<br>
+<br>
+       context.session_id = ta_id;<br>
+<br>
+       ret = psp_ta_unload(psp, &context);<br>
+       if (!ret)<br>
+               context.initialized = false;<br>
+<br>
+       return ret;<br>
+}<br>
+<br>
</div>
<div class="PlainText elementToProof">+static ssize_t ta_if_invoke_debugfs_read(struct file *fp, char *buf, size_t len, loff_t *<span style="background-color:rgb(255, 255, 255);display:inline !important"><span style="background-color:rgb(255, 255, 255);display:inline !important"><span style="background-color:rgb(255, 255, 255);display:inline !important"><span style="background-color:rgb(255, 255, 255);display:inline !important">off</span></span></span></span>)<br>
</div>
<div class="PlainText elementToProof">+{<br>
+       uint32_t ta_id          = 0;<br>
+       uint32_t cmd_id         = 0;<br>
+       uint32_t shared_buf_len = 0;<br>
+       uint8_t  *shared_buf    = NULL;<br>
+       uint32_t copy_pos       = 0;<br>
+       int      ret            = 0;<br>
+<br>
+       struct amdgpu_device *adev   = (struct amdgpu_device *)file_inode(fp)->i_private;<br>
+       struct psp_context   *psp    = &adev->psp;<br>
+       struct ta_context    context = {0};<br>
+<br>
+       if ((fp == NULL) || (buf == NULL))<br>
+               return -EINVAL;</div>
<div class="PlainText elementToProof"><br>
</div>
<div class="PlainText elementToProof"><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0);">[kevin]:</span></div>
<div class="PlainText elementToProof"><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0);"><span style="background-color:rgb(255, 255, 255);display:inline !important"> 
  “if ((fp == NULL)<span> ..."</span></span><br>
</span></div>
<div class="PlainText elementToProof"><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0);"> 
  </span><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0);">The linux kernel will
 automatically create struct file instance when you open the file, even if you do not provide a callback function (in fops)</span></div>
<div class="PlainText elementToProof">
<div><br>
</div>
</div>
<div class="PlainText elementToProof">[kevin]:</div>
<div class="PlainText elementToProof"><br>
</div>
<div class="PlainText elementToProof">      you should add some check here to avoid that the user buf is overflow.</div>
<div class="PlainText elementToProof"></div>
      e.g: If the length of the user buf is less than that required, an error should be returned directly
<div><br>
</div>
<div class="PlainText elementToProof">+<br>
+       ret = copy_from_user((void *)&ta_id, &buf[copy_pos], sizeof(uint32_t));<br>
+       if (ret)<br>
+               return -EINVAL;<br>
+       copy_pos += sizeof(uint32_t);<br>
+<br>
+       ret = copy_from_user((void *)&cmd_id, &buf[copy_pos], sizeof(uint32_t));<br>
+       if (ret)<br>
+               return -EINVAL;<br>
+       copy_pos += sizeof(uint32_t);<br>
+<br>
+       ret = copy_from_user((void *)&shared_buf_len, &buf[copy_pos], sizeof(uint32_t));<br>
+       if (ret)<br>
+               return -EINVAL;<br>
+       copy_pos += sizeof(uint32_t);<br>
+<br>
+       shared_buf = kzalloc(shared_buf_len, GFP_KERNEL);<br>
+       if (!shared_buf)<br>
+               ret = -ENOMEM;<br>
+       ret = copy_from_user((void *)shared_buf, &buf[copy_pos], shared_buf_len);<br>
+       if (ret)<br>
+               goto err_free_shared_buf;<br>
+<br>
+       context.session_id = ta_id;<br>
+<br>
+       prep_ta_mem_context(psp, &context, shared_buf, shared_buf_len);<br>
+<br>
+       ret = psp_ta_invoke_indirect(psp, cmd_id, &context);<br>
+<br>
+       if (ret || context.resp_status) {<br>
+               dev_err(adev->dev, "TA invoke via debugfs failed (%d) status %d\n",<br>
+                        ret, context.resp_status);<br>
+               goto err_free_ta_shared_buf;<br>
+       }<br>
+<br>
+       ret = copy_to_user((char *)buf, context.mem_context.shared_buf, shared_buf_len);<br>
+<br>
+err_free_ta_shared_buf:<br>
+       psp_ta_free_shared_buf(&context.mem_context);<br>
+<br>
+err_free_shared_buf:<br>
+       kfree(shared_buf);<br>
+<br>
+       return ret;<br>
+}<br>
+<br>
+static struct dentry *amdgpu_ta_if_debugfs_create(struct amdgpu_device *adev)<br>
+{<br>
+       struct drm_minor *minor = adev_to_drm(adev)->primary;<br>
+<br>
+       dir = debugfs_create_dir(TA_IF_FS_NAME, minor->debugfs_root);<br>
+<br>
+       ta_load_debugfs_dentry = debugfs_create_file("ta_load", 0400, dir, adev,<br>
+                                                    &ta_load_debugfs_fops);<br>
+<br>
+       ta_unload_debugfs_dentry = debugfs_create_file("ta_unload", 0400, dir,<br>
+                                                    adev, &ta_unload_debugfs_fops);<br>
+<br>
+       ta_invoke_debugfs_dentry = debugfs_create_file("ta_invoke", 0400, dir,<br>
+                                                    adev, &ta_invoke_debugfs_fops);<br>
+       return dir;<br>
+}<br>
+<br>
+void amdgpu_ta_if_debugfs_init(struct amdgpu_device *adev)<br>
+{<br>
+#if defined(CONFIG_DEBUG_FS)<br>
+       dir = amdgpu_ta_if_debugfs_create(adev);<br>
+#endif<br>
+}<br>
+<br>
+void amdgpu_ta_if_debugfs_remove(void)<br>
+{<br>
+       debugfs_remove_recursive(dir);<br>
+}<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.h<br>
new file mode 100644<br>
index 00000000000000..883f89d57616d0<br>
--- /dev/null<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.h<br>
@@ -0,0 +1,30 @@<br>
+/*<br>
+ * Copyright 2022 Advanced Micro Devices, Inc.<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice shall be included in<br>
+ * all copies or substantial portions of the Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR<br>
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,<br>
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR<br>
+ * OTHER DEALINGS IN THE SOFTWARE.<br>
+ *<br>
+ */<br>
+<br>
+#ifndef __AMDGPU_PSP_TA_H__<br>
+#define __AMDGPU_PSP_TA_H__<br>
+<br>
+void amdgpu_ta_if_debugfs_init(struct amdgpu_device *adev);<br>
+void amdgpu_ta_if_debugfs_remove(void);<br>
+<br>
+#endif<br>
-- <br>
2.17.1<br>
<br>
</div>
</span></font></div>
</div>
</body>
</html>