mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-23 01:31:30 +03:00
Bug 4165184 Change-Id: Id5d570cc4e5c3364d696271b1333e47e02e17b9e Signed-off-by: Chris Dragan <kdragan@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2976924 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
78 lines
1.6 KiB
C
78 lines
1.6 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/* SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. */
|
|
|
|
#include "mods_internal.h"
|
|
|
|
#include <asm/barrier.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/cpumask.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/smp.h>
|
|
|
|
#define MAX_IPI_WFI_LOOPS 5
|
|
#define MAX_IPI_WFE_LOOPS 10
|
|
|
|
static void ipi_wfi_cpu(void *p)
|
|
{
|
|
struct MODS_SEND_IPI *p_ipi = (struct MODS_SEND_IPI *)p;
|
|
u32 i;
|
|
|
|
for (i = 0; i < p_ipi->num_loops; i++)
|
|
wfi();
|
|
}
|
|
|
|
static void ipi_wfe_cpu(void *p)
|
|
{
|
|
struct MODS_SEND_IPI *p_ipi = (struct MODS_SEND_IPI *)p;
|
|
u32 i;
|
|
|
|
for (i = 0; i < p_ipi->num_loops; i++)
|
|
wfe();
|
|
}
|
|
|
|
int esc_mods_send_ipi(struct mods_client *client, struct MODS_SEND_IPI *p)
|
|
{
|
|
LOG_ENT();
|
|
|
|
switch (p->ipi_type) {
|
|
case MODS_IPI_KICK: {
|
|
kick_all_cpus_sync();
|
|
break;
|
|
}
|
|
case MODS_IPI_WFI: {
|
|
if (p->num_loops > MAX_IPI_WFI_LOOPS) {
|
|
cl_error("num_loops %u exceed maximum limit %d for MODS_IPI_WFI\n",
|
|
p->num_loops,
|
|
MAX_IPI_WFI_LOOPS);
|
|
LOG_EXT();
|
|
return -EINVAL;
|
|
}
|
|
preempt_disable();
|
|
smp_call_function_many(cpu_online_mask, ipi_wfi_cpu, (void *)p, 1);
|
|
preempt_enable();
|
|
break;
|
|
}
|
|
case MODS_IPI_WFE: {
|
|
if (p->num_loops > MAX_IPI_WFE_LOOPS) {
|
|
cl_error("num_loops %u exceed maximum limit %d for MODS_IPI_WFE\n",
|
|
p->num_loops,
|
|
MAX_IPI_WFE_LOOPS);
|
|
LOG_EXT();
|
|
return -EINVAL;
|
|
}
|
|
preempt_disable();
|
|
smp_call_function_many(cpu_online_mask, ipi_wfe_cpu, (void *)p, 1);
|
|
preempt_enable();
|
|
break;
|
|
}
|
|
default: {
|
|
cl_error("unsupported MODS_IPI_TYPE\n");
|
|
LOG_EXT();
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
LOG_EXT();
|
|
return 0;
|
|
}
|