mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'drm-misc-next-2025-12-12' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next
drm-misc-next for 6.19:
UAPI Changes:
- panfrost: Add PANFROST_BO_SYNC ioctl
- panthor: Add PANTHOR_BO_SYNC ioctl
Core Changes:
- atomic: Add drm_device pointer to drm_private_obj
- bridge: Introduce drm_bridge_unplug, drm_bridge_enter, and
drm_bridge_exit
- dma-buf: Improve sg_table debugging
- dma-fence: Add new helpers, and use them when needed
- dp_mst: Avoid out-of-bounds access with VCPI==0
- gem: Reduce page table overhead with transparent huge pages
- panic: Report invalid panic modes
- sched: Add TODO entries
- ttm: Various cleanups
- vblank: Various refactoring and cleanups
- Kconfig cleanups
- Removed support for kdb
Driver Changes:
- amdxdna: Fix race conditions at suspend, Improve handling of zero
tail pointers, Fix cu_idx being overwritten during command setup
- ast: Support imported cursor buffers
-
- panthor: Enable timestamp propagation, Multiple improvements and
fixes to improve the overall robustness, notably of the scheduler.
- panels:
- panel-edp: Support for CSW MNE007QB3-1, AUO B140HAN06.4, AUO B140QAX01.H
Signed-off-by: Dave Airlie <airlied@redhat.com>
[airlied: fix mm conflict]
From: Maxime Ripard <mripard@redhat.com>
Link: https://patch.msgid.link/20251212-spectacular-agama-of-abracadabra-aaef32@penduick
This commit is contained in:
@@ -155,7 +155,12 @@ drm_gem_object_init() will create an shmfs file of the
|
||||
requested size and store it into the struct :c:type:`struct
|
||||
drm_gem_object <drm_gem_object>` filp field. The memory is
|
||||
used as either main storage for the object when the graphics hardware
|
||||
uses system memory directly or as a backing store otherwise.
|
||||
uses system memory directly or as a backing store otherwise. Drivers
|
||||
can call drm_gem_huge_mnt_create() to create, mount and use a huge
|
||||
shmem mountpoint instead of the default one ('shm_mnt'). For builds
|
||||
with CONFIG_TRANSPARENT_HUGEPAGE enabled, further calls to
|
||||
drm_gem_object_init() will let shmem allocate huge pages when
|
||||
possible.
|
||||
|
||||
Drivers are responsible for the actual physical pages allocation by
|
||||
calling shmem_read_mapping_page_gfp() for each page.
|
||||
@@ -290,15 +295,27 @@ The open and close operations must update the GEM object reference
|
||||
count. Drivers can use the drm_gem_vm_open() and drm_gem_vm_close() helper
|
||||
functions directly as open and close handlers.
|
||||
|
||||
The fault operation handler is responsible for mapping individual pages
|
||||
to userspace when a page fault occurs. Depending on the memory
|
||||
allocation scheme, drivers can allocate pages at fault time, or can
|
||||
decide to allocate memory for the GEM object at the time the object is
|
||||
created.
|
||||
The fault operation handler is responsible for mapping pages to
|
||||
userspace when a page fault occurs. Depending on the memory allocation
|
||||
scheme, drivers can allocate pages at fault time, or can decide to
|
||||
allocate memory for the GEM object at the time the object is created.
|
||||
|
||||
Drivers that want to map the GEM object upfront instead of handling page
|
||||
faults can implement their own mmap file operation handler.
|
||||
|
||||
In order to reduce page table overhead, if the internal shmem mountpoint
|
||||
"shm_mnt" is configured to use transparent huge pages (for builds with
|
||||
CONFIG_TRANSPARENT_HUGEPAGE enabled) and if the shmem backing store
|
||||
managed to allocate a huge page for a faulty address, the fault handler
|
||||
will first attempt to insert that huge page into the VMA before falling
|
||||
back to individual page insertion. mmap() user address alignment for GEM
|
||||
objects is handled by providing a custom get_unmapped_area file
|
||||
operation which forwards to the shmem backing store. For most drivers,
|
||||
which don't create a huge mountpoint by default or through a module
|
||||
parameter, transparent huge pages can be enabled by either setting the
|
||||
"transparent_hugepage_shmem" kernel parameter or the
|
||||
"/sys/kernel/mm/transparent_hugepage/shmem_enabled" sysfs knob.
|
||||
|
||||
For platforms without MMU the GEM core provides a helper method
|
||||
drm_gem_dma_get_unmapped_area(). The mmap() routines will call this to get a
|
||||
proposed address for the mapping.
|
||||
|
||||
@@ -878,6 +878,51 @@ Contact: Christian König
|
||||
|
||||
Level: Starter
|
||||
|
||||
DRM GPU Scheduler
|
||||
=================
|
||||
|
||||
Provide a universal successor for drm_sched_resubmit_jobs()
|
||||
-----------------------------------------------------------
|
||||
|
||||
drm_sched_resubmit_jobs() is deprecated. Main reason being that it leads to
|
||||
reinitializing dma_fences. See that function's docu for details. The better
|
||||
approach for valid resubmissions by amdgpu and Xe is (apparently) to figure out
|
||||
which job (and, through association: which entity) caused the hang. Then, the
|
||||
job's buffer data, together with all other jobs' buffer data currently in the
|
||||
same hardware ring, must be invalidated. This can for example be done by
|
||||
overwriting it. amdgpu currently determines which jobs are in the ring and need
|
||||
to be overwritten by keeping copies of the job. Xe obtains that information by
|
||||
directly accessing drm_sched's pending_list.
|
||||
|
||||
Tasks:
|
||||
|
||||
1. implement scheduler functionality through which the driver can obtain the
|
||||
information which *broken* jobs are currently in the hardware ring.
|
||||
2. Such infrastructure would then typically be used in
|
||||
drm_sched_backend_ops.timedout_job(). Document that.
|
||||
3. Port a driver as first user.
|
||||
4. Document the new alternative in the docu of deprecated
|
||||
drm_sched_resubmit_jobs().
|
||||
|
||||
Contact: Christian König <christian.koenig@amd.com>
|
||||
Philipp Stanner <phasta@kernel.org>
|
||||
|
||||
Level: Advanced
|
||||
|
||||
Add locking for runqueues
|
||||
-------------------------
|
||||
|
||||
There is an old FIXME by Sima in include/drm/gpu_scheduler.h. It details that
|
||||
struct drm_sched_rq is read at many places without any locks, not even with a
|
||||
READ_ONCE. At XDC 2025 no one could really tell why that is the case, whether
|
||||
locks are needed and whether they could be added. (But for real, that should
|
||||
probably be locked!). Check whether it's possible to add locks everywhere, and
|
||||
do so if yes.
|
||||
|
||||
Contact: Philipp Stanner <phasta@kernel.org>
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
Outside DRM
|
||||
===========
|
||||
|
||||
|
||||
@@ -889,34 +889,6 @@ in the virtual console layer. On resuming kernel execution, the kernel
|
||||
debugger calls kgdboc_post_exp_handler() which in turn calls
|
||||
con_debug_leave().
|
||||
|
||||
Any video driver that wants to be compatible with the kernel debugger
|
||||
and the atomic kms callbacks must implement the ``mode_set_base_atomic``,
|
||||
``fb_debug_enter`` and ``fb_debug_leave operations``. For the
|
||||
``fb_debug_enter`` and ``fb_debug_leave`` the option exists to use the
|
||||
generic drm fb helper functions or implement something custom for the
|
||||
hardware. The following example shows the initialization of the
|
||||
.mode_set_base_atomic operation in
|
||||
drivers/gpu/drm/i915/intel_display.c::
|
||||
|
||||
|
||||
static const struct drm_crtc_helper_funcs intel_helper_funcs = {
|
||||
[...]
|
||||
.mode_set_base_atomic = intel_pipe_set_base_atomic,
|
||||
[...]
|
||||
};
|
||||
|
||||
|
||||
Here is an example of how the i915 driver initializes the
|
||||
fb_debug_enter and fb_debug_leave functions to use the generic drm
|
||||
helpers in ``drivers/gpu/drm/i915/intel_fb.c``::
|
||||
|
||||
|
||||
static struct fb_ops intelfb_ops = {
|
||||
[...]
|
||||
.fb_debug_enter = drm_fb_helper_debug_enter,
|
||||
.fb_debug_leave = drm_fb_helper_debug_leave,
|
||||
[...]
|
||||
};
|
||||
|
||||
|
||||
Credits
|
||||
|
||||
@@ -39,7 +39,6 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev,
|
||||
if (!ndev->mgmt_chann)
|
||||
return -ENODEV;
|
||||
|
||||
drm_WARN_ON(&xdna->ddev, xdna->rpm_on && !mutex_is_locked(&xdna->dev_lock));
|
||||
ret = xdna_send_msg_wait(xdna, ndev->mgmt_chann, msg);
|
||||
if (ret == -ETIME) {
|
||||
xdna_mailbox_stop_channel(ndev->mgmt_chann);
|
||||
@@ -59,8 +58,15 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev,
|
||||
int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev)
|
||||
{
|
||||
DECLARE_AIE2_MSG(suspend, MSG_OP_SUSPEND);
|
||||
int ret;
|
||||
|
||||
return aie2_send_mgmt_msg_wait(ndev, &msg);
|
||||
ret = aie2_send_mgmt_msg_wait(ndev, &msg);
|
||||
if (ret) {
|
||||
XDNA_ERR(ndev->xdna, "Failed to suspend fw, ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return aie2_psp_waitmode_poll(ndev->psp_hdl);
|
||||
}
|
||||
|
||||
int aie2_resume_fw(struct amdxdna_dev_hdl *ndev)
|
||||
@@ -646,6 +652,7 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siz
|
||||
u32 cmd_len;
|
||||
void *cmd;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
if (*size < sizeof(*npu_slot) + cmd_len)
|
||||
return -EINVAL;
|
||||
@@ -654,7 +661,6 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siz
|
||||
if (npu_slot->cu_idx == INVALID_CU_IDX)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->type = EXEC_NPU_TYPE_NON_ELF;
|
||||
npu_slot->arg_cnt = cmd_len / sizeof(u32);
|
||||
memcpy(npu_slot->args, cmd, cmd_len);
|
||||
@@ -671,6 +677,7 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
||||
u32 cmd_len;
|
||||
u32 arg_sz;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
arg_sz = cmd_len - sizeof(*sn);
|
||||
if (cmd_len < sizeof(*sn) || arg_sz > MAX_NPU_ARGS_SIZE)
|
||||
@@ -683,7 +690,6 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
||||
if (npu_slot->cu_idx == INVALID_CU_IDX)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->type = EXEC_NPU_TYPE_PARTIAL_ELF;
|
||||
npu_slot->inst_buf_addr = sn->buffer;
|
||||
npu_slot->inst_size = sn->buffer_size;
|
||||
@@ -703,6 +709,7 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t
|
||||
u32 cmd_len;
|
||||
u32 arg_sz;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
arg_sz = cmd_len - sizeof(*pd);
|
||||
if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
|
||||
@@ -715,7 +722,6 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t
|
||||
if (npu_slot->cu_idx == INVALID_CU_IDX)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->type = EXEC_NPU_TYPE_PREEMPT;
|
||||
npu_slot->inst_buf_addr = pd->inst_buf;
|
||||
npu_slot->save_buf_addr = pd->save_buf;
|
||||
@@ -739,6 +745,7 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
||||
u32 cmd_len;
|
||||
u32 arg_sz;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
arg_sz = cmd_len - sizeof(*pd);
|
||||
if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
|
||||
@@ -747,7 +754,6 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
||||
if (*size < sizeof(*npu_slot) + arg_sz)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->type = EXEC_NPU_TYPE_ELF;
|
||||
npu_slot->inst_buf_addr = pd->inst_buf;
|
||||
npu_slot->save_buf_addr = pd->save_buf;
|
||||
|
||||
@@ -322,7 +322,7 @@ static int aie2_xrs_set_dft_dpm_level(struct drm_device *ddev, u32 dpm_level)
|
||||
if (ndev->pw_mode != POWER_MODE_DEFAULT || ndev->dpm_level == dpm_level)
|
||||
return 0;
|
||||
|
||||
return ndev->priv->hw_ops.set_dpm(ndev, dpm_level);
|
||||
return aie2_pm_set_dpm(ndev, dpm_level);
|
||||
}
|
||||
|
||||
static struct xrs_action_ops aie2_xrs_actions = {
|
||||
|
||||
@@ -70,6 +70,7 @@ enum psp_reg_idx {
|
||||
PSP_INTR_REG = PSP_NUM_IN_REGS,
|
||||
PSP_STATUS_REG,
|
||||
PSP_RESP_REG,
|
||||
PSP_PWAITMODE_REG,
|
||||
PSP_MAX_REGS /* Keep this at the end */
|
||||
};
|
||||
|
||||
@@ -285,11 +286,13 @@ int npu4_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level);
|
||||
/* aie2_pm.c */
|
||||
int aie2_pm_init(struct amdxdna_dev_hdl *ndev);
|
||||
int aie2_pm_set_mode(struct amdxdna_dev_hdl *ndev, enum amdxdna_power_mode_type target);
|
||||
int aie2_pm_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level);
|
||||
|
||||
/* aie2_psp.c */
|
||||
struct psp_device *aie2m_psp_create(struct drm_device *ddev, struct psp_config *conf);
|
||||
int aie2_psp_start(struct psp_device *psp);
|
||||
void aie2_psp_stop(struct psp_device *psp);
|
||||
int aie2_psp_waitmode_poll(struct psp_device *psp);
|
||||
|
||||
/* aie2_error.c */
|
||||
int aie2_error_async_events_alloc(struct amdxdna_dev_hdl *ndev);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "aie2_pci.h"
|
||||
#include "amdxdna_pci_drv.h"
|
||||
#include "amdxdna_pm.h"
|
||||
|
||||
#define AIE2_CLK_GATING_ENABLE 1
|
||||
#define AIE2_CLK_GATING_DISABLE 0
|
||||
@@ -26,6 +27,20 @@ static int aie2_pm_set_clk_gating(struct amdxdna_dev_hdl *ndev, u32 val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aie2_pm_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = amdxdna_pm_resume_get(ndev->xdna);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ndev->priv->hw_ops.set_dpm(ndev, dpm_level);
|
||||
amdxdna_pm_suspend_put(ndev->xdna);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aie2_pm_init(struct amdxdna_dev_hdl *ndev)
|
||||
{
|
||||
int ret;
|
||||
@@ -94,7 +109,7 @@ int aie2_pm_set_mode(struct amdxdna_dev_hdl *ndev, enum amdxdna_power_mode_type
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ret = ndev->priv->hw_ops.set_dpm(ndev, dpm_level);
|
||||
ret = aie2_pm_set_dpm(ndev, dpm_level);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -76,6 +76,21 @@ static int psp_exec(struct psp_device *psp, u32 *reg_vals)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aie2_psp_waitmode_poll(struct psp_device *psp)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(psp->ddev);
|
||||
u32 mode_reg;
|
||||
int ret;
|
||||
|
||||
ret = readx_poll_timeout(readl, PSP_REG(psp, PSP_PWAITMODE_REG), mode_reg,
|
||||
(mode_reg & 0x1) == 1,
|
||||
PSP_POLL_INTERVAL, PSP_POLL_TIMEOUT);
|
||||
if (ret)
|
||||
XDNA_ERR(xdna, "fw waitmode reg error, ret %d", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void aie2_psp_stop(struct psp_device *psp)
|
||||
{
|
||||
u32 reg_vals[PSP_NUM_IN_REGS] = { PSP_RELEASE_TMR, };
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include "aie2_pci.h"
|
||||
#include "amdxdna_pci_drv.h"
|
||||
#include "amdxdna_pm.h"
|
||||
|
||||
#define SMU_RESULT_OK 1
|
||||
|
||||
@@ -67,16 +66,12 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
|
||||
u32 freq;
|
||||
int ret;
|
||||
|
||||
ret = amdxdna_pm_resume_get(ndev->xdna);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = aie2_smu_exec(ndev, AIE2_SMU_SET_MPNPUCLK_FREQ,
|
||||
ndev->priv->dpm_clk_tbl[dpm_level].npuclk, &freq);
|
||||
if (ret) {
|
||||
XDNA_ERR(ndev->xdna, "Set npu clock to %d failed, ret %d\n",
|
||||
ndev->priv->dpm_clk_tbl[dpm_level].npuclk, ret);
|
||||
goto suspend_put;
|
||||
return ret;
|
||||
}
|
||||
ndev->npuclk_freq = freq;
|
||||
|
||||
@@ -85,10 +80,9 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
|
||||
if (ret) {
|
||||
XDNA_ERR(ndev->xdna, "Set h clock to %d failed, ret %d\n",
|
||||
ndev->priv->dpm_clk_tbl[dpm_level].hclk, ret);
|
||||
goto suspend_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
amdxdna_pm_suspend_put(ndev->xdna);
|
||||
ndev->hclk_freq = freq;
|
||||
ndev->dpm_level = dpm_level;
|
||||
ndev->max_tops = 2 * ndev->total_col;
|
||||
@@ -98,35 +92,26 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
|
||||
ndev->npuclk_freq, ndev->hclk_freq);
|
||||
|
||||
return 0;
|
||||
|
||||
suspend_put:
|
||||
amdxdna_pm_suspend_put(ndev->xdna);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int npu4_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = amdxdna_pm_resume_get(ndev->xdna);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = aie2_smu_exec(ndev, AIE2_SMU_SET_HARD_DPMLEVEL, dpm_level, NULL);
|
||||
if (ret) {
|
||||
XDNA_ERR(ndev->xdna, "Set hard dpm level %d failed, ret %d ",
|
||||
dpm_level, ret);
|
||||
goto suspend_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = aie2_smu_exec(ndev, AIE2_SMU_SET_SOFT_DPMLEVEL, dpm_level, NULL);
|
||||
if (ret) {
|
||||
XDNA_ERR(ndev->xdna, "Set soft dpm level %d failed, ret %d",
|
||||
dpm_level, ret);
|
||||
goto suspend_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
amdxdna_pm_suspend_put(ndev->xdna);
|
||||
ndev->npuclk_freq = ndev->priv->dpm_clk_tbl[dpm_level].npuclk;
|
||||
ndev->hclk_freq = ndev->priv->dpm_clk_tbl[dpm_level].hclk;
|
||||
ndev->dpm_level = dpm_level;
|
||||
@@ -137,10 +122,6 @@ int npu4_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
|
||||
ndev->npuclk_freq, ndev->hclk_freq);
|
||||
|
||||
return 0;
|
||||
|
||||
suspend_put:
|
||||
amdxdna_pm_suspend_put(ndev->xdna);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aie2_smu_init(struct amdxdna_dev_hdl *ndev)
|
||||
|
||||
@@ -112,22 +112,6 @@ static u32 mailbox_reg_read(struct mailbox_channel *mb_chann, u32 mbox_reg)
|
||||
return readl(ringbuf_addr);
|
||||
}
|
||||
|
||||
static int mailbox_reg_read_non_zero(struct mailbox_channel *mb_chann, u32 mbox_reg, u32 *val)
|
||||
{
|
||||
struct xdna_mailbox_res *mb_res = &mb_chann->mb->res;
|
||||
void __iomem *ringbuf_addr = mb_res->mbox_base + mbox_reg;
|
||||
int ret, value;
|
||||
|
||||
/* Poll till value is not zero */
|
||||
ret = readx_poll_timeout(readl, ringbuf_addr, value,
|
||||
value, 1 /* us */, 100);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*val = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mailbox_set_headptr(struct mailbox_channel *mb_chann, u32 headptr_val)
|
||||
{
|
||||
@@ -286,8 +270,7 @@ static int mailbox_get_msg(struct mailbox_channel *mb_chann)
|
||||
u32 start_addr;
|
||||
int ret;
|
||||
|
||||
if (mailbox_reg_read_non_zero(mb_chann, mb_chann->res[CHAN_RES_I2X].mb_tail_ptr_reg, &tail))
|
||||
return -EINVAL;
|
||||
tail = mailbox_get_tailptr(mb_chann, CHAN_RES_I2X);
|
||||
head = mb_chann->i2x_head;
|
||||
ringbuf_size = mailbox_get_ringbuf_size(mb_chann, CHAN_RES_I2X);
|
||||
start_addr = mb_chann->res[CHAN_RES_I2X].rb_start_addr;
|
||||
|
||||
@@ -101,7 +101,6 @@ struct amdxdna_dev {
|
||||
struct amdxdna_fw_ver fw_ver;
|
||||
struct rw_semaphore notifier_lock; /* for mmu notifier*/
|
||||
struct workqueue_struct *notifier_wq;
|
||||
bool rpm_on;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -15,14 +15,9 @@ int amdxdna_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev));
|
||||
int ret = -EOPNOTSUPP;
|
||||
bool rpm;
|
||||
|
||||
if (xdna->dev_info->ops->suspend) {
|
||||
rpm = xdna->rpm_on;
|
||||
xdna->rpm_on = false;
|
||||
if (xdna->dev_info->ops->suspend)
|
||||
ret = xdna->dev_info->ops->suspend(xdna);
|
||||
xdna->rpm_on = rpm;
|
||||
}
|
||||
|
||||
XDNA_DBG(xdna, "Suspend done ret %d", ret);
|
||||
return ret;
|
||||
@@ -32,14 +27,9 @@ int amdxdna_pm_resume(struct device *dev)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev));
|
||||
int ret = -EOPNOTSUPP;
|
||||
bool rpm;
|
||||
|
||||
if (xdna->dev_info->ops->resume) {
|
||||
rpm = xdna->rpm_on;
|
||||
xdna->rpm_on = false;
|
||||
if (xdna->dev_info->ops->resume)
|
||||
ret = xdna->dev_info->ops->resume(xdna);
|
||||
xdna->rpm_on = rpm;
|
||||
}
|
||||
|
||||
XDNA_DBG(xdna, "Resume done ret %d", ret);
|
||||
return ret;
|
||||
@@ -50,9 +40,6 @@ int amdxdna_pm_resume_get(struct amdxdna_dev *xdna)
|
||||
struct device *dev = xdna->ddev.dev;
|
||||
int ret;
|
||||
|
||||
if (!xdna->rpm_on)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Resume failed: %d", ret);
|
||||
@@ -66,9 +53,6 @@ void amdxdna_pm_suspend_put(struct amdxdna_dev *xdna)
|
||||
{
|
||||
struct device *dev = xdna->ddev.dev;
|
||||
|
||||
if (!xdna->rpm_on)
|
||||
return;
|
||||
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
|
||||
@@ -81,14 +65,12 @@ void amdxdna_pm_init(struct amdxdna_dev *xdna)
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_allow(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
xdna->rpm_on = true;
|
||||
}
|
||||
|
||||
void amdxdna_pm_fini(struct amdxdna_dev *xdna)
|
||||
{
|
||||
struct device *dev = xdna->ddev.dev;
|
||||
|
||||
xdna->rpm_on = false;
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_forbid(dev);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "amdxdna_pci_drv.h"
|
||||
|
||||
/* Address definition from NPU1 docs */
|
||||
#define MPNPU_PWAITMODE 0x3010034
|
||||
#define MPNPU_PUB_SEC_INTR 0x3010090
|
||||
#define MPNPU_PUB_PWRMGMT_INTR 0x3010094
|
||||
#define MPNPU_PUB_SCRATCH2 0x30100A0
|
||||
@@ -92,6 +93,7 @@ static const struct amdxdna_dev_priv npu1_dev_priv = {
|
||||
DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU1_PSP, MPNPU_PUB_SEC_INTR),
|
||||
DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU1_PSP, MPNPU_PUB_SCRATCH2),
|
||||
DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU1_PSP, MPNPU_PUB_SCRATCH3),
|
||||
DEFINE_BAR_OFFSET(PSP_PWAITMODE_REG, NPU1_PSP, MPNPU_PWAITMODE),
|
||||
},
|
||||
.smu_regs_off = {
|
||||
DEFINE_BAR_OFFSET(SMU_CMD_REG, NPU1_SMU, MPNPU_PUB_SCRATCH5),
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "amdxdna_pci_drv.h"
|
||||
|
||||
/* NPU Public Registers on MpNPUAxiXbar (refer to Diag npu_registers.h) */
|
||||
#define MPNPU_PWAITMODE 0x301003C
|
||||
#define MPNPU_PUB_SEC_INTR 0x3010060
|
||||
#define MPNPU_PUB_PWRMGMT_INTR 0x3010064
|
||||
#define MPNPU_PUB_SCRATCH0 0x301006C
|
||||
@@ -85,6 +86,7 @@ static const struct amdxdna_dev_priv npu2_dev_priv = {
|
||||
DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU2_PSP, MP0_C2PMSG_73),
|
||||
DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU2_PSP, MP0_C2PMSG_123),
|
||||
DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU2_REG, MPNPU_PUB_SCRATCH3),
|
||||
DEFINE_BAR_OFFSET(PSP_PWAITMODE_REG, NPU2_REG, MPNPU_PWAITMODE),
|
||||
},
|
||||
.smu_regs_off = {
|
||||
DEFINE_BAR_OFFSET(SMU_CMD_REG, NPU2_SMU, MP1_C2PMSG_0),
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "amdxdna_pci_drv.h"
|
||||
|
||||
/* NPU Public Registers on MpNPUAxiXbar (refer to Diag npu_registers.h) */
|
||||
#define MPNPU_PWAITMODE 0x301003C
|
||||
#define MPNPU_PUB_SEC_INTR 0x3010060
|
||||
#define MPNPU_PUB_PWRMGMT_INTR 0x3010064
|
||||
#define MPNPU_PUB_SCRATCH0 0x301006C
|
||||
@@ -116,6 +117,7 @@ static const struct amdxdna_dev_priv npu4_dev_priv = {
|
||||
DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU4_PSP, MP0_C2PMSG_73),
|
||||
DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU4_PSP, MP0_C2PMSG_123),
|
||||
DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU4_REG, MPNPU_PUB_SCRATCH3),
|
||||
DEFINE_BAR_OFFSET(PSP_PWAITMODE_REG, NPU4_REG, MPNPU_PWAITMODE),
|
||||
},
|
||||
.smu_regs_off = {
|
||||
DEFINE_BAR_OFFSET(SMU_CMD_REG, NPU4_SMU, MP1_C2PMSG_0),
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "amdxdna_pci_drv.h"
|
||||
|
||||
/* NPU Public Registers on MpNPUAxiXbar (refer to Diag npu_registers.h) */
|
||||
#define MPNPU_PWAITMODE 0x301003C
|
||||
#define MPNPU_PUB_SEC_INTR 0x3010060
|
||||
#define MPNPU_PUB_PWRMGMT_INTR 0x3010064
|
||||
#define MPNPU_PUB_SCRATCH0 0x301006C
|
||||
@@ -85,6 +86,7 @@ static const struct amdxdna_dev_priv npu5_dev_priv = {
|
||||
DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU5_PSP, MP0_C2PMSG_73),
|
||||
DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU5_PSP, MP0_C2PMSG_123),
|
||||
DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU5_REG, MPNPU_PUB_SCRATCH3),
|
||||
DEFINE_BAR_OFFSET(PSP_PWAITMODE_REG, NPU5_REG, MPNPU_PWAITMODE),
|
||||
},
|
||||
.smu_regs_off = {
|
||||
DEFINE_BAR_OFFSET(SMU_CMD_REG, NPU5_SMU, MP1_C2PMSG_0),
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "amdxdna_pci_drv.h"
|
||||
|
||||
/* NPU Public Registers on MpNPUAxiXbar (refer to Diag npu_registers.h) */
|
||||
#define MPNPU_PWAITMODE 0x301003C
|
||||
#define MPNPU_PUB_SEC_INTR 0x3010060
|
||||
#define MPNPU_PUB_PWRMGMT_INTR 0x3010064
|
||||
#define MPNPU_PUB_SCRATCH0 0x301006C
|
||||
@@ -85,6 +86,7 @@ static const struct amdxdna_dev_priv npu6_dev_priv = {
|
||||
DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU6_PSP, MP0_C2PMSG_73),
|
||||
DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU6_PSP, MP0_C2PMSG_123),
|
||||
DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU6_REG, MPNPU_PUB_SCRATCH3),
|
||||
DEFINE_BAR_OFFSET(PSP_PWAITMODE_REG, NPU6_REG, MPNPU_PWAITMODE),
|
||||
},
|
||||
.smu_regs_off = {
|
||||
DEFINE_BAR_OFFSET(SMU_CMD_REG, NPU6_SMU, MP1_C2PMSG_0),
|
||||
|
||||
@@ -55,7 +55,7 @@ config DMABUF_MOVE_NOTIFY
|
||||
config DMABUF_DEBUG
|
||||
bool "DMA-BUF debug checks"
|
||||
depends on DMA_SHARED_BUFFER
|
||||
default y if DMA_API_DEBUG
|
||||
default y if DEBUG
|
||||
help
|
||||
This option enables additional checks for DMA-BUF importers and
|
||||
exporters. Specifically it validates that importers do not peek at the
|
||||
|
||||
+61
-16
@@ -35,6 +35,12 @@
|
||||
|
||||
#include "dma-buf-sysfs-stats.h"
|
||||
|
||||
/* Wrapper to hide the sg_table page link from the importer */
|
||||
struct dma_buf_sg_table_wrapper {
|
||||
struct sg_table *original;
|
||||
struct sg_table wrapper;
|
||||
};
|
||||
|
||||
static inline int is_dma_buf_file(struct file *);
|
||||
|
||||
static DEFINE_MUTEX(dmabuf_list_mutex);
|
||||
@@ -820,21 +826,59 @@ void dma_buf_put(struct dma_buf *dmabuf)
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_put, "DMA_BUF");
|
||||
|
||||
static void mangle_sg_table(struct sg_table *sg_table)
|
||||
static int dma_buf_wrap_sg_table(struct sg_table **sg_table)
|
||||
{
|
||||
#ifdef CONFIG_DMABUF_DEBUG
|
||||
int i;
|
||||
struct scatterlist *sg;
|
||||
struct scatterlist *to_sg, *from_sg;
|
||||
struct sg_table *from = *sg_table;
|
||||
struct dma_buf_sg_table_wrapper *to;
|
||||
int i, ret;
|
||||
|
||||
/* To catch abuse of the underlying struct page by importers mix
|
||||
* up the bits, but take care to preserve the low SG_ bits to
|
||||
* not corrupt the sgt. The mixing is undone on unmap
|
||||
* before passing the sgt back to the exporter.
|
||||
if (!IS_ENABLED(CONFIG_DMABUF_DEBUG))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* To catch abuse of the underlying struct page by importers copy the
|
||||
* sg_table without copying the page_link and give only the copy back to
|
||||
* the importer.
|
||||
*/
|
||||
for_each_sgtable_sg(sg_table, sg, i)
|
||||
sg->page_link ^= ~0xffUL;
|
||||
#endif
|
||||
to = kzalloc(sizeof(*to), GFP_KERNEL);
|
||||
if (!to)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = sg_alloc_table(&to->wrapper, from->nents, GFP_KERNEL);
|
||||
if (ret)
|
||||
goto free_to;
|
||||
|
||||
to_sg = to->wrapper.sgl;
|
||||
for_each_sgtable_dma_sg(from, from_sg, i) {
|
||||
to_sg->offset = 0;
|
||||
to_sg->length = 0;
|
||||
sg_assign_page(to_sg, NULL);
|
||||
sg_dma_address(to_sg) = sg_dma_address(from_sg);
|
||||
sg_dma_len(to_sg) = sg_dma_len(from_sg);
|
||||
to_sg = sg_next(to_sg);
|
||||
}
|
||||
|
||||
to->original = from;
|
||||
*sg_table = &to->wrapper;
|
||||
return 0;
|
||||
|
||||
free_to:
|
||||
kfree(to);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dma_buf_unwrap_sg_table(struct sg_table **sg_table)
|
||||
{
|
||||
struct dma_buf_sg_table_wrapper *copy;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_DMABUF_DEBUG))
|
||||
return;
|
||||
|
||||
copy = container_of(*sg_table, typeof(*copy), wrapper);
|
||||
*sg_table = copy->original;
|
||||
sg_free_table(©->wrapper);
|
||||
kfree(copy);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
@@ -1131,10 +1175,11 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
|
||||
if (ret < 0)
|
||||
goto error_unmap;
|
||||
}
|
||||
mangle_sg_table(sg_table);
|
||||
ret = dma_buf_wrap_sg_table(&sg_table);
|
||||
if (ret)
|
||||
goto error_unmap;
|
||||
|
||||
#ifdef CONFIG_DMA_API_DEBUG
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_DMA_API_DEBUG)) {
|
||||
struct scatterlist *sg;
|
||||
u64 addr;
|
||||
int len;
|
||||
@@ -1146,10 +1191,10 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
|
||||
if (!PAGE_ALIGNED(addr) || !PAGE_ALIGNED(len)) {
|
||||
pr_debug("%s: addr %llx or len %x is not page aligned!\n",
|
||||
__func__, addr, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_DMA_API_DEBUG */
|
||||
return sg_table;
|
||||
|
||||
error_unmap:
|
||||
@@ -1213,7 +1258,7 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
|
||||
|
||||
dma_resv_assert_held(attach->dmabuf->resv);
|
||||
|
||||
mangle_sg_table(sg_table);
|
||||
dma_buf_unwrap_sg_table(&sg_table);
|
||||
attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction);
|
||||
|
||||
if (dma_buf_pin_on_map(attach))
|
||||
|
||||
+62
-38
@@ -358,11 +358,8 @@ void __dma_fence_might_wait(void)
|
||||
*
|
||||
* Unlike dma_fence_signal_timestamp(), this function must be called with
|
||||
* &dma_fence.lock held.
|
||||
*
|
||||
* Returns 0 on success and a negative error value when @fence has been
|
||||
* signalled already.
|
||||
*/
|
||||
int dma_fence_signal_timestamp_locked(struct dma_fence *fence,
|
||||
void dma_fence_signal_timestamp_locked(struct dma_fence *fence,
|
||||
ktime_t timestamp)
|
||||
{
|
||||
struct dma_fence_cb *cur, *tmp;
|
||||
@@ -372,7 +369,7 @@ int dma_fence_signal_timestamp_locked(struct dma_fence *fence,
|
||||
|
||||
if (unlikely(test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
|
||||
&fence->flags)))
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
/* Stash the cb_list before replacing it with the timestamp */
|
||||
list_replace(&fence->cb_list, &cb_list);
|
||||
@@ -385,8 +382,6 @@ int dma_fence_signal_timestamp_locked(struct dma_fence *fence,
|
||||
INIT_LIST_HEAD(&cur->node);
|
||||
cur->func(fence, cur);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_fence_signal_timestamp_locked);
|
||||
|
||||
@@ -401,23 +396,17 @@ EXPORT_SYMBOL(dma_fence_signal_timestamp_locked);
|
||||
* can only go from the unsignaled to the signaled state and not back, it will
|
||||
* only be effective the first time. Set the timestamp provided as the fence
|
||||
* signal timestamp.
|
||||
*
|
||||
* Returns 0 on success and a negative error value when @fence has been
|
||||
* signalled already.
|
||||
*/
|
||||
int dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp)
|
||||
void dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(!fence))
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(fence->lock, flags);
|
||||
ret = dma_fence_signal_timestamp_locked(fence, timestamp);
|
||||
dma_fence_signal_timestamp_locked(fence, timestamp);
|
||||
spin_unlock_irqrestore(fence->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_fence_signal_timestamp);
|
||||
|
||||
@@ -433,16 +422,57 @@ EXPORT_SYMBOL(dma_fence_signal_timestamp);
|
||||
*
|
||||
* Unlike dma_fence_signal(), this function must be called with &dma_fence.lock
|
||||
* held.
|
||||
*
|
||||
* Returns 0 on success and a negative error value when @fence has been
|
||||
* signalled already.
|
||||
*/
|
||||
int dma_fence_signal_locked(struct dma_fence *fence)
|
||||
void dma_fence_signal_locked(struct dma_fence *fence)
|
||||
{
|
||||
return dma_fence_signal_timestamp_locked(fence, ktime_get());
|
||||
dma_fence_signal_timestamp_locked(fence, ktime_get());
|
||||
}
|
||||
EXPORT_SYMBOL(dma_fence_signal_locked);
|
||||
|
||||
/**
|
||||
* dma_fence_check_and_signal_locked - signal the fence if it's not yet signaled
|
||||
* @fence: the fence to check and signal
|
||||
*
|
||||
* Checks whether a fence was signaled and signals it if it was not yet signaled.
|
||||
*
|
||||
* Unlike dma_fence_check_and_signal(), this function must be called with
|
||||
* &struct dma_fence.lock being held.
|
||||
*
|
||||
* Return: true if fence has been signaled already, false otherwise.
|
||||
*/
|
||||
bool dma_fence_check_and_signal_locked(struct dma_fence *fence)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
ret = dma_fence_test_signaled_flag(fence);
|
||||
dma_fence_signal_locked(fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_fence_check_and_signal_locked);
|
||||
|
||||
/**
|
||||
* dma_fence_check_and_signal - signal the fence if it's not yet signaled
|
||||
* @fence: the fence to check and signal
|
||||
*
|
||||
* Checks whether a fence was signaled and signals it if it was not yet signaled.
|
||||
* All this is done in a race-free manner.
|
||||
*
|
||||
* Return: true if fence has been signaled already, false otherwise.
|
||||
*/
|
||||
bool dma_fence_check_and_signal(struct dma_fence *fence)
|
||||
{
|
||||
unsigned long flags;
|
||||
bool ret;
|
||||
|
||||
spin_lock_irqsave(fence->lock, flags);
|
||||
ret = dma_fence_check_and_signal_locked(fence);
|
||||
spin_unlock_irqrestore(fence->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_fence_check_and_signal);
|
||||
|
||||
/**
|
||||
* dma_fence_signal - signal completion of a fence
|
||||
* @fence: the fence to signal
|
||||
@@ -452,28 +482,22 @@ EXPORT_SYMBOL(dma_fence_signal_locked);
|
||||
* dma_fence_add_callback(). Can be called multiple times, but since a fence
|
||||
* can only go from the unsignaled to the signaled state and not back, it will
|
||||
* only be effective the first time.
|
||||
*
|
||||
* Returns 0 on success and a negative error value when @fence has been
|
||||
* signalled already.
|
||||
*/
|
||||
int dma_fence_signal(struct dma_fence *fence)
|
||||
void dma_fence_signal(struct dma_fence *fence)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
bool tmp;
|
||||
|
||||
if (WARN_ON(!fence))
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
tmp = dma_fence_begin_signalling();
|
||||
|
||||
spin_lock_irqsave(fence->lock, flags);
|
||||
ret = dma_fence_signal_timestamp_locked(fence, ktime_get());
|
||||
dma_fence_signal_timestamp_locked(fence, ktime_get());
|
||||
spin_unlock_irqrestore(fence->lock, flags);
|
||||
|
||||
dma_fence_end_signalling(tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_fence_signal);
|
||||
|
||||
@@ -543,7 +567,7 @@ void dma_fence_release(struct kref *kref)
|
||||
trace_dma_fence_destroy(fence);
|
||||
|
||||
if (!list_empty(&fence->cb_list) &&
|
||||
!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
|
||||
!dma_fence_test_signaled_flag(fence)) {
|
||||
const char __rcu *timeline;
|
||||
const char __rcu *driver;
|
||||
unsigned long flags;
|
||||
@@ -600,7 +624,7 @@ static bool __dma_fence_enable_signaling(struct dma_fence *fence)
|
||||
was_set = test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
|
||||
&fence->flags);
|
||||
|
||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
|
||||
if (dma_fence_test_signaled_flag(fence))
|
||||
return false;
|
||||
|
||||
if (!was_set && fence->ops->enable_signaling) {
|
||||
@@ -664,7 +688,7 @@ int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb,
|
||||
if (WARN_ON(!fence || !func))
|
||||
return -EINVAL;
|
||||
|
||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
|
||||
if (dma_fence_test_signaled_flag(fence)) {
|
||||
INIT_LIST_HEAD(&cb->node);
|
||||
return -ENOENT;
|
||||
}
|
||||
@@ -781,7 +805,7 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
|
||||
|
||||
spin_lock_irqsave(fence->lock, flags);
|
||||
|
||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
|
||||
if (dma_fence_test_signaled_flag(fence))
|
||||
goto out;
|
||||
|
||||
if (intr && signal_pending(current)) {
|
||||
@@ -798,7 +822,7 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
|
||||
cb.task = current;
|
||||
list_add(&cb.base.node, &fence->cb_list);
|
||||
|
||||
while (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) && ret > 0) {
|
||||
while (!dma_fence_test_signaled_flag(fence) && ret > 0) {
|
||||
if (intr)
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
else
|
||||
@@ -830,7 +854,7 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count,
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
struct dma_fence *fence = fences[i];
|
||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
|
||||
if (dma_fence_test_signaled_flag(fence)) {
|
||||
if (idx)
|
||||
*idx = i;
|
||||
return true;
|
||||
@@ -1108,7 +1132,7 @@ const char __rcu *dma_fence_driver_name(struct dma_fence *fence)
|
||||
RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
|
||||
"RCU protection is required for safe access to returned string");
|
||||
|
||||
if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
|
||||
if (!dma_fence_test_signaled_flag(fence))
|
||||
return fence->ops->get_driver_name(fence);
|
||||
else
|
||||
return "detached-driver";
|
||||
@@ -1140,7 +1164,7 @@ const char __rcu *dma_fence_timeline_name(struct dma_fence *fence)
|
||||
RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
|
||||
"RCU protection is required for safe access to returned string");
|
||||
|
||||
if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
|
||||
if (!dma_fence_test_signaled_flag(fence))
|
||||
return fence->ops->get_timeline_name(fence);
|
||||
else
|
||||
return "signaled-timeline";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user