mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
misc: mods: add IPI ioctls
* Added ioctl for triggering IPIs * Added handler to invoke ASM wfe,wfi commands or NOP Change-Id: I907b6a27f3a7f3ff5b507e9f91066d8695dadbb4 Signed-off-by: Ian Grissom <igrissom@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2730675 Reviewed-by: Chris Dragan <kdragan@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
Laxman Dewangan
parent
e01a6e01a0
commit
83d81ef365
@@ -18,6 +18,7 @@ mods-$(CONFIG_TEGRA_NVADSP) += mods_adsp.o
|
|||||||
mods-$(CONFIG_COMMON_CLK) += mods_clock.o
|
mods-$(CONFIG_COMMON_CLK) += mods_clock.o
|
||||||
mods-$(CONFIG_DEBUG_FS) += mods_debugfs.o
|
mods-$(CONFIG_DEBUG_FS) += mods_debugfs.o
|
||||||
mods-$(CONFIG_DMA_ENGINE) += mods_dma.o
|
mods-$(CONFIG_DMA_ENGINE) += mods_dma.o
|
||||||
|
mods-$(CONFIG_ARCH_TEGRA) += mods_ipi.o
|
||||||
mods-$(CONFIG_NET) += mods_netdevice.o
|
mods-$(CONFIG_NET) += mods_netdevice.o
|
||||||
mods-$(CONFIG_ARCH_TEGRA) += mods_oist.o
|
mods-$(CONFIG_ARCH_TEGRA) += mods_oist.o
|
||||||
mods-$(CONFIG_OPTEE) += mods_optee.o
|
mods-$(CONFIG_OPTEE) += mods_optee.o
|
||||||
|
|||||||
@@ -739,4 +739,8 @@ int smmu_driver_init(void);
|
|||||||
void smmu_driver_exit(void);
|
void smmu_driver_exit(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MODS_HAS_TEGRA)
|
||||||
|
int esc_mods_send_ipi(struct mods_client *client, struct MODS_SEND_IPI *p);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _MODS_INTERNAL_H_ */
|
#endif /* _MODS_INTERNAL_H_ */
|
||||||
|
|||||||
94
drivers/misc/mods/mods_ipi.c
Normal file
94
drivers/misc/mods/mods_ipi.c
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* This file is part of NVIDIA MODS kernel driver.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
*
|
||||||
|
* NVIDIA MODS kernel driver is free software: you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* NVIDIA MODS kernel driver is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NVIDIA MODS kernel driver.
|
||||||
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
@@ -2604,6 +2604,11 @@ static long mods_krnl_ioctl(struct file *fp,
|
|||||||
MODS_IOCTL(MODS_ESC_OIST_STATUS,
|
MODS_IOCTL(MODS_ESC_OIST_STATUS,
|
||||||
esc_mods_oist_status, MODS_TEGRA_OIST_STATUS);
|
esc_mods_oist_status, MODS_TEGRA_OIST_STATUS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MODS_ESC_MODS_SEND_IPI:
|
||||||
|
MODS_IOCTL(MODS_ESC_MODS_SEND_IPI,
|
||||||
|
esc_mods_send_ipi, MODS_SEND_IPI);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case MODS_ESC_ACQUIRE_ACCESS_TOKEN:
|
case MODS_ESC_ACQUIRE_ACCESS_TOKEN:
|
||||||
|
|||||||
@@ -1858,6 +1858,23 @@ struct MODS_TEGRA_OIST_STATUS {
|
|||||||
__u64 smc_status;
|
__u64 smc_status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MODS_IPI_TYPE {
|
||||||
|
MODS_IPI_KICK,
|
||||||
|
MODS_IPI_WFI,
|
||||||
|
MODS_IPI_WFE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Used by MODS_ESC_MODS_SEND_IPI ioctl.
|
||||||
|
*
|
||||||
|
* Available only on Tegra.
|
||||||
|
*/
|
||||||
|
struct MODS_SEND_IPI {
|
||||||
|
/* IN */
|
||||||
|
__u32 ipi_type;
|
||||||
|
/* IN */
|
||||||
|
__u32 num_loops;
|
||||||
|
};
|
||||||
|
|
||||||
#define MODS_IOMMU_MAP_CONTIGUOUS 1
|
#define MODS_IOMMU_MAP_CONTIGUOUS 1
|
||||||
|
|
||||||
#define MODS_MAX_PROP_NAME_LEN 64
|
#define MODS_MAX_PROP_NAME_LEN 64
|
||||||
@@ -2097,5 +2114,6 @@ struct MODS_PROXIMITY_TO_NUMA_NODE {
|
|||||||
#define MODS_ESC_INVOKE_OPTEE_TA MODSIO(WR, 141, MODS_OPTEE_PARAMS)
|
#define MODS_ESC_INVOKE_OPTEE_TA MODSIO(WR, 141, MODS_OPTEE_PARAMS)
|
||||||
#define MODS_ESC_READ_DEV_PROPERTY MODSIO(WR, 142, MODS_READ_DEV_PROPERTY)
|
#define MODS_ESC_READ_DEV_PROPERTY MODSIO(WR, 142, MODS_READ_DEV_PROPERTY)
|
||||||
#define MODS_ESC_PROXIMITY_TO_NUMA_NODE MODSIO(WR, 143, MODS_PROXIMITY_TO_NUMA_NODE)
|
#define MODS_ESC_PROXIMITY_TO_NUMA_NODE MODSIO(WR, 143, MODS_PROXIMITY_TO_NUMA_NODE)
|
||||||
|
#define MODS_ESC_MODS_SEND_IPI MODSIO(W, 144, MODS_SEND_IPI)
|
||||||
|
|
||||||
#endif /* _UAPI_MODS_H_ */
|
#endif /* _UAPI_MODS_H_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user