Loading drivers/media/platform/msm/npu/npu_dev.c +92 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,18 @@ static ssize_t npu_show_perf_mode_override(struct device *dev, static ssize_t npu_store_perf_mode_override(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t npu_show_fw_unload_delay_ms(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t npu_store_fw_unload_delay_ms(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t npu_show_fw_state(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t npu_store_fw_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static void npu_suspend_devbw(struct npu_device *npu_dev); static void npu_resume_devbw(struct npu_device *npu_dev); static bool npu_is_post_clock(const char *clk_name); Loading Loading @@ -166,11 +178,16 @@ static DEVICE_ATTR(caps, 0444, npu_show_capabilities, NULL); static DEVICE_ATTR(pwr, 0644, npu_show_pwr_state, npu_store_pwr_state); static DEVICE_ATTR(perf_mode_override, 0644, npu_show_perf_mode_override, npu_store_perf_mode_override); static DEVICE_ATTR(fw_unload_delay_ms, 0644, npu_show_fw_unload_delay_ms, npu_store_fw_unload_delay_ms); static DEVICE_ATTR(fw_state, 0644, npu_show_fw_state, npu_store_fw_state); static struct attribute *npu_fs_attrs[] = { &dev_attr_caps.attr, &dev_attr_pwr.attr, &dev_attr_perf_mode_override.attr, &dev_attr_fw_state.attr, &dev_attr_fw_unload_delay_ms.attr, NULL }; Loading Loading @@ -307,6 +324,81 @@ static ssize_t npu_store_perf_mode_override(struct device *dev, return count; } /* ------------------------------------------------------------------------- * SysFS - Delayed FW unload * ------------------------------------------------------------------------- */ static ssize_t npu_show_fw_unload_delay_ms(struct device *dev, struct device_attribute *attr, char *buf) { struct npu_device *npu_dev = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%d\n", npu_dev->host_ctx.fw_unload_delay_ms); } static ssize_t npu_store_fw_unload_delay_ms(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct npu_device *npu_dev = dev_get_drvdata(dev); uint32_t val; int rc; rc = kstrtou32(buf, 10, &val); if (rc) { pr_err("Invalid input for fw unload delay setting\n"); return -EINVAL; } npu_dev->host_ctx.fw_unload_delay_ms = val; pr_debug("setting fw_unload_delay_ms to %d\n", val); return count; } /* ------------------------------------------------------------------------- * SysFS - firmware state * ------------------------------------------------------------------------- */ static ssize_t npu_show_fw_state(struct device *dev, struct device_attribute *attr, char *buf) { struct npu_device *npu_dev = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%s\n", (npu_dev->host_ctx.fw_state == FW_ENABLED) ? "on" : "off"); } static ssize_t npu_store_fw_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct npu_device *npu_dev = dev_get_drvdata(dev); bool enable = false; int rc; if (strtobool(buf, &enable) < 0) return -EINVAL; if (enable) { pr_debug("%s: fw init\n", __func__); rc = fw_init(npu_dev); if (rc) { pr_err("fw init failed\n"); return rc; } } else { pr_debug("%s: fw deinit\n", __func__); fw_deinit(npu_dev, false, true); } return count; } /* ------------------------------------------------------------------------- * Power Related * ------------------------------------------------------------------------- Loading drivers/media/platform/msm/npu/npu_hw_access.c +1 −20 Original line number Diff line number Diff line /* Copyright (c) 2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -378,25 +378,6 @@ void npu_mem_unmap(struct npu_client *client, int buf_hdl, uint64_t addr) npu_free_npu_ion_buffer(client, buf_hdl); } /* ------------------------------------------------------------------------- * Functions - Work Queue * ------------------------------------------------------------------------- */ void npu_destroy_wq(struct workqueue_struct *wq) { destroy_workqueue(wq); } struct workqueue_struct *npu_create_wq(struct npu_host_ctx *host_ctx, const char *name, wq_hdlr_fn hdlr, struct work_struct *irq_work) { struct workqueue_struct *wq = create_workqueue(name); INIT_WORK(irq_work, hdlr); return wq; } /* ------------------------------------------------------------------------- * Functions - Features * ------------------------------------------------------------------------- Loading drivers/media/platform/msm/npu/npu_hw_access.h +1 −5 Original line number Diff line number Diff line /* Copyright (c) 2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -78,10 +78,6 @@ void npu_interrupt_ack(struct npu_device *npu_dev, uint32_t intr_num); int32_t npu_interrupt_raise_m0(struct npu_device *npu_dev); int32_t npu_interrupt_raise_dsp(struct npu_device *npu_dev); struct workqueue_struct *npu_create_wq(struct npu_host_ctx *host_ctx, const char *name, wq_hdlr_fn hdlr, struct work_struct *irq_work); void npu_destroy_wq(struct workqueue_struct *wq); uint8_t npu_hw_clk_gating_enabled(void); uint8_t npu_hw_log_enabled(void); Loading drivers/media/platform/msm/npu/npu_mgr.c +65 −7 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ * ------------------------------------------------------------------------- */ static void host_irq_wq(struct work_struct *work); static void fw_deinit_wq(struct work_struct *work); static void turn_off_fw_logging(struct npu_device *npu_dev); static int wait_for_status_ready(struct npu_device *npu_dev, uint32_t status_reg, uint32_t status_bits); Loading @@ -65,6 +66,9 @@ static int npu_send_misc_cmd(struct npu_device *npu_dev, uint32_t q_idx, static int npu_queue_event(struct npu_client *client, struct npu_kevent *evt); static int npu_notify_dsp(struct npu_device *npu_dev, bool pwr_up); static int npu_notify_aop(struct npu_device *npu_dev, bool on); static void npu_destroy_wq(struct npu_host_ctx *host_ctx); static struct workqueue_struct *npu_create_wq(struct npu_host_ctx *host_ctx, const char *name); /* ------------------------------------------------------------------------- * Function Definitions - Init / Deinit Loading @@ -74,7 +78,8 @@ int fw_init(struct npu_device *npu_dev) { uint32_t reg_val; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; int ret = 0, retry_cnt = 3; bool need_retry; mutex_lock(&host_ctx->lock); if (host_ctx->fw_state == FW_ENABLED) { Loading @@ -83,6 +88,8 @@ int fw_init(struct npu_device *npu_dev) return 0; } retry: need_retry = false; npu_notify_aop(npu_dev, true); if (npu_enable_core_power(npu_dev)) { Loading Loading @@ -139,14 +146,19 @@ int fw_init(struct npu_device *npu_dev) REGW(npu_dev, REG_NPU_HOST_CTRL_STATUS, reg_val); /* Initialize the host side IPC */ npu_host_ipc_pre_init(npu_dev); ret = npu_host_ipc_pre_init(npu_dev); if (ret) { pr_err("npu_host_ipc_pre_init failed %d\n", ret); goto enable_post_clk_fail; } /* Keep reading ctrl status until NPU is ready */ pr_debug("waiting for status ready from fw\n"); if (wait_for_status_ready(npu_dev, REG_NPU_FW_CTRL_STATUS, FW_CTRL_STATUS_MAIN_THREAD_READY_BIT)) { FW_CTRL_STATUS_MAIN_THREAD_READY_VAL)) { ret = -EPERM; need_retry = true; goto wait_fw_ready_fail; } Loading Loading @@ -183,7 +195,13 @@ int fw_init(struct npu_device *npu_dev) enable_sys_cache_fail: npu_disable_core_power(npu_dev); enable_pw_fail: npu_notify_aop(npu_dev, false); host_ctx->fw_state = FW_DISABLED; if (need_retry && (retry_cnt > 0)) { retry_cnt--; pr_warn("retry fw init %d\n", retry_cnt); goto retry; } mutex_unlock(&host_ctx->lock); return ret; } Loading Loading @@ -284,8 +302,7 @@ int npu_host_init(struct npu_device *npu_dev) mutex_init(&host_ctx->lock); atomic_set(&host_ctx->ipc_trans_id, 1); host_ctx->wq = npu_create_wq(host_ctx, "irq_hdl", host_irq_wq, &host_ctx->irq_work); host_ctx->wq = npu_create_wq(host_ctx, "npu_wq"); if (!host_ctx->wq) sts = -EPERM; Loading @@ -296,7 +313,7 @@ void npu_host_deinit(struct npu_device *npu_dev) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; npu_destroy_wq(host_ctx->wq); npu_destroy_wq(host_ctx); mutex_destroy(&host_ctx->lock); } Loading Loading @@ -383,6 +400,40 @@ static void host_irq_wq(struct work_struct *work) host_session_msg_hdlr(npu_dev); } static void fw_deinit_wq(struct work_struct *work) { struct npu_host_ctx *host_ctx; struct npu_device *npu_dev; pr_debug("%s: deinit fw\n", __func__); host_ctx = container_of(work, struct npu_host_ctx, fw_deinit_work.work); npu_dev = container_of(host_ctx, struct npu_device, host_ctx); if (atomic_read(&host_ctx->fw_deinit_work_cnt) == 0) return; do { fw_deinit(npu_dev, false, true); } while (!atomic_dec_and_test(&host_ctx->fw_deinit_work_cnt)); } static void npu_destroy_wq(struct npu_host_ctx *host_ctx) { flush_delayed_work(&host_ctx->fw_deinit_work); destroy_workqueue(host_ctx->wq); } static struct workqueue_struct *npu_create_wq(struct npu_host_ctx *host_ctx, const char *name) { struct workqueue_struct *wq = create_workqueue(name); INIT_WORK(&host_ctx->irq_work, host_irq_wq); INIT_DELAYED_WORK(&host_ctx->fw_deinit_work, fw_deinit_wq); return wq; } static void turn_off_fw_logging(struct npu_device *npu_dev) { struct ipc_cmd_log_state_pkt log_packet; Loading Loading @@ -1419,7 +1470,14 @@ int32_t npu_host_unload_network(struct npu_client *client, if (ret) pr_err("network unload failed to set power level\n"); mutex_unlock(&host_ctx->lock); if (host_ctx->fw_unload_delay_ms) { flush_delayed_work(&host_ctx->fw_deinit_work); atomic_inc(&host_ctx->fw_deinit_work_cnt); queue_delayed_work(host_ctx->wq, &host_ctx->fw_deinit_work, msecs_to_jiffies(host_ctx->fw_unload_delay_ms)); } else { fw_deinit(npu_dev, false, true); } return ret; } Loading drivers/media/platform/msm/npu/npu_mgr.h +4 −1 Original line number Diff line number Diff line /* Copyright (c) 2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -78,6 +78,8 @@ struct npu_host_ctx { int32_t fw_ref_cnt; int32_t power_vote_num; struct work_struct irq_work; struct delayed_work fw_deinit_work; atomic_t fw_deinit_work_cnt; struct workqueue_struct *wq; struct completion loopback_done; struct completion fw_deinit_done; Loading @@ -86,6 +88,7 @@ struct npu_host_ctx { bool sys_cache_disable; uint32_t fw_dbg_mode; uint32_t exec_flags_override; uint32_t fw_unload_delay_ms; atomic_t ipc_trans_id; atomic_t network_exeute_cnt; Loading Loading
drivers/media/platform/msm/npu/npu_dev.c +92 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,18 @@ static ssize_t npu_show_perf_mode_override(struct device *dev, static ssize_t npu_store_perf_mode_override(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t npu_show_fw_unload_delay_ms(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t npu_store_fw_unload_delay_ms(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t npu_show_fw_state(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t npu_store_fw_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static void npu_suspend_devbw(struct npu_device *npu_dev); static void npu_resume_devbw(struct npu_device *npu_dev); static bool npu_is_post_clock(const char *clk_name); Loading Loading @@ -166,11 +178,16 @@ static DEVICE_ATTR(caps, 0444, npu_show_capabilities, NULL); static DEVICE_ATTR(pwr, 0644, npu_show_pwr_state, npu_store_pwr_state); static DEVICE_ATTR(perf_mode_override, 0644, npu_show_perf_mode_override, npu_store_perf_mode_override); static DEVICE_ATTR(fw_unload_delay_ms, 0644, npu_show_fw_unload_delay_ms, npu_store_fw_unload_delay_ms); static DEVICE_ATTR(fw_state, 0644, npu_show_fw_state, npu_store_fw_state); static struct attribute *npu_fs_attrs[] = { &dev_attr_caps.attr, &dev_attr_pwr.attr, &dev_attr_perf_mode_override.attr, &dev_attr_fw_state.attr, &dev_attr_fw_unload_delay_ms.attr, NULL }; Loading Loading @@ -307,6 +324,81 @@ static ssize_t npu_store_perf_mode_override(struct device *dev, return count; } /* ------------------------------------------------------------------------- * SysFS - Delayed FW unload * ------------------------------------------------------------------------- */ static ssize_t npu_show_fw_unload_delay_ms(struct device *dev, struct device_attribute *attr, char *buf) { struct npu_device *npu_dev = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%d\n", npu_dev->host_ctx.fw_unload_delay_ms); } static ssize_t npu_store_fw_unload_delay_ms(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct npu_device *npu_dev = dev_get_drvdata(dev); uint32_t val; int rc; rc = kstrtou32(buf, 10, &val); if (rc) { pr_err("Invalid input for fw unload delay setting\n"); return -EINVAL; } npu_dev->host_ctx.fw_unload_delay_ms = val; pr_debug("setting fw_unload_delay_ms to %d\n", val); return count; } /* ------------------------------------------------------------------------- * SysFS - firmware state * ------------------------------------------------------------------------- */ static ssize_t npu_show_fw_state(struct device *dev, struct device_attribute *attr, char *buf) { struct npu_device *npu_dev = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%s\n", (npu_dev->host_ctx.fw_state == FW_ENABLED) ? "on" : "off"); } static ssize_t npu_store_fw_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct npu_device *npu_dev = dev_get_drvdata(dev); bool enable = false; int rc; if (strtobool(buf, &enable) < 0) return -EINVAL; if (enable) { pr_debug("%s: fw init\n", __func__); rc = fw_init(npu_dev); if (rc) { pr_err("fw init failed\n"); return rc; } } else { pr_debug("%s: fw deinit\n", __func__); fw_deinit(npu_dev, false, true); } return count; } /* ------------------------------------------------------------------------- * Power Related * ------------------------------------------------------------------------- Loading
drivers/media/platform/msm/npu/npu_hw_access.c +1 −20 Original line number Diff line number Diff line /* Copyright (c) 2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -378,25 +378,6 @@ void npu_mem_unmap(struct npu_client *client, int buf_hdl, uint64_t addr) npu_free_npu_ion_buffer(client, buf_hdl); } /* ------------------------------------------------------------------------- * Functions - Work Queue * ------------------------------------------------------------------------- */ void npu_destroy_wq(struct workqueue_struct *wq) { destroy_workqueue(wq); } struct workqueue_struct *npu_create_wq(struct npu_host_ctx *host_ctx, const char *name, wq_hdlr_fn hdlr, struct work_struct *irq_work) { struct workqueue_struct *wq = create_workqueue(name); INIT_WORK(irq_work, hdlr); return wq; } /* ------------------------------------------------------------------------- * Functions - Features * ------------------------------------------------------------------------- Loading
drivers/media/platform/msm/npu/npu_hw_access.h +1 −5 Original line number Diff line number Diff line /* Copyright (c) 2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -78,10 +78,6 @@ void npu_interrupt_ack(struct npu_device *npu_dev, uint32_t intr_num); int32_t npu_interrupt_raise_m0(struct npu_device *npu_dev); int32_t npu_interrupt_raise_dsp(struct npu_device *npu_dev); struct workqueue_struct *npu_create_wq(struct npu_host_ctx *host_ctx, const char *name, wq_hdlr_fn hdlr, struct work_struct *irq_work); void npu_destroy_wq(struct workqueue_struct *wq); uint8_t npu_hw_clk_gating_enabled(void); uint8_t npu_hw_log_enabled(void); Loading
drivers/media/platform/msm/npu/npu_mgr.c +65 −7 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ * ------------------------------------------------------------------------- */ static void host_irq_wq(struct work_struct *work); static void fw_deinit_wq(struct work_struct *work); static void turn_off_fw_logging(struct npu_device *npu_dev); static int wait_for_status_ready(struct npu_device *npu_dev, uint32_t status_reg, uint32_t status_bits); Loading @@ -65,6 +66,9 @@ static int npu_send_misc_cmd(struct npu_device *npu_dev, uint32_t q_idx, static int npu_queue_event(struct npu_client *client, struct npu_kevent *evt); static int npu_notify_dsp(struct npu_device *npu_dev, bool pwr_up); static int npu_notify_aop(struct npu_device *npu_dev, bool on); static void npu_destroy_wq(struct npu_host_ctx *host_ctx); static struct workqueue_struct *npu_create_wq(struct npu_host_ctx *host_ctx, const char *name); /* ------------------------------------------------------------------------- * Function Definitions - Init / Deinit Loading @@ -74,7 +78,8 @@ int fw_init(struct npu_device *npu_dev) { uint32_t reg_val; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; int ret = 0, retry_cnt = 3; bool need_retry; mutex_lock(&host_ctx->lock); if (host_ctx->fw_state == FW_ENABLED) { Loading @@ -83,6 +88,8 @@ int fw_init(struct npu_device *npu_dev) return 0; } retry: need_retry = false; npu_notify_aop(npu_dev, true); if (npu_enable_core_power(npu_dev)) { Loading Loading @@ -139,14 +146,19 @@ int fw_init(struct npu_device *npu_dev) REGW(npu_dev, REG_NPU_HOST_CTRL_STATUS, reg_val); /* Initialize the host side IPC */ npu_host_ipc_pre_init(npu_dev); ret = npu_host_ipc_pre_init(npu_dev); if (ret) { pr_err("npu_host_ipc_pre_init failed %d\n", ret); goto enable_post_clk_fail; } /* Keep reading ctrl status until NPU is ready */ pr_debug("waiting for status ready from fw\n"); if (wait_for_status_ready(npu_dev, REG_NPU_FW_CTRL_STATUS, FW_CTRL_STATUS_MAIN_THREAD_READY_BIT)) { FW_CTRL_STATUS_MAIN_THREAD_READY_VAL)) { ret = -EPERM; need_retry = true; goto wait_fw_ready_fail; } Loading Loading @@ -183,7 +195,13 @@ int fw_init(struct npu_device *npu_dev) enable_sys_cache_fail: npu_disable_core_power(npu_dev); enable_pw_fail: npu_notify_aop(npu_dev, false); host_ctx->fw_state = FW_DISABLED; if (need_retry && (retry_cnt > 0)) { retry_cnt--; pr_warn("retry fw init %d\n", retry_cnt); goto retry; } mutex_unlock(&host_ctx->lock); return ret; } Loading Loading @@ -284,8 +302,7 @@ int npu_host_init(struct npu_device *npu_dev) mutex_init(&host_ctx->lock); atomic_set(&host_ctx->ipc_trans_id, 1); host_ctx->wq = npu_create_wq(host_ctx, "irq_hdl", host_irq_wq, &host_ctx->irq_work); host_ctx->wq = npu_create_wq(host_ctx, "npu_wq"); if (!host_ctx->wq) sts = -EPERM; Loading @@ -296,7 +313,7 @@ void npu_host_deinit(struct npu_device *npu_dev) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; npu_destroy_wq(host_ctx->wq); npu_destroy_wq(host_ctx); mutex_destroy(&host_ctx->lock); } Loading Loading @@ -383,6 +400,40 @@ static void host_irq_wq(struct work_struct *work) host_session_msg_hdlr(npu_dev); } static void fw_deinit_wq(struct work_struct *work) { struct npu_host_ctx *host_ctx; struct npu_device *npu_dev; pr_debug("%s: deinit fw\n", __func__); host_ctx = container_of(work, struct npu_host_ctx, fw_deinit_work.work); npu_dev = container_of(host_ctx, struct npu_device, host_ctx); if (atomic_read(&host_ctx->fw_deinit_work_cnt) == 0) return; do { fw_deinit(npu_dev, false, true); } while (!atomic_dec_and_test(&host_ctx->fw_deinit_work_cnt)); } static void npu_destroy_wq(struct npu_host_ctx *host_ctx) { flush_delayed_work(&host_ctx->fw_deinit_work); destroy_workqueue(host_ctx->wq); } static struct workqueue_struct *npu_create_wq(struct npu_host_ctx *host_ctx, const char *name) { struct workqueue_struct *wq = create_workqueue(name); INIT_WORK(&host_ctx->irq_work, host_irq_wq); INIT_DELAYED_WORK(&host_ctx->fw_deinit_work, fw_deinit_wq); return wq; } static void turn_off_fw_logging(struct npu_device *npu_dev) { struct ipc_cmd_log_state_pkt log_packet; Loading Loading @@ -1419,7 +1470,14 @@ int32_t npu_host_unload_network(struct npu_client *client, if (ret) pr_err("network unload failed to set power level\n"); mutex_unlock(&host_ctx->lock); if (host_ctx->fw_unload_delay_ms) { flush_delayed_work(&host_ctx->fw_deinit_work); atomic_inc(&host_ctx->fw_deinit_work_cnt); queue_delayed_work(host_ctx->wq, &host_ctx->fw_deinit_work, msecs_to_jiffies(host_ctx->fw_unload_delay_ms)); } else { fw_deinit(npu_dev, false, true); } return ret; } Loading
drivers/media/platform/msm/npu/npu_mgr.h +4 −1 Original line number Diff line number Diff line /* Copyright (c) 2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -78,6 +78,8 @@ struct npu_host_ctx { int32_t fw_ref_cnt; int32_t power_vote_num; struct work_struct irq_work; struct delayed_work fw_deinit_work; atomic_t fw_deinit_work_cnt; struct workqueue_struct *wq; struct completion loopback_done; struct completion fw_deinit_done; Loading @@ -86,6 +88,7 @@ struct npu_host_ctx { bool sys_cache_disable; uint32_t fw_dbg_mode; uint32_t exec_flags_override; uint32_t fw_unload_delay_ms; atomic_t ipc_trans_id; atomic_t network_exeute_cnt; Loading