tegra-fsicom: Implement PM ops

Initiate handshake with FSI by sending signal to NvFsiCom daemon on
system resume.

JIRA SS-3761

This patch is integrated from kernel/nvidia to kernel/nvidia-oot
https://git-master.nvidia.com/r/c/linux-nvidia/+/2720391

JIRA SS-4628
Bug 3855033

Change-Id: I08221f94248c39998df856ae3e254e02b2803985
Signed-off-by: Rahul Bedarkar <rabedarkar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2819742
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Rahul Bedarkar
2022-12-01 07:59:04 +00:00
committed by mobile promotions
parent dd109353df
commit 6a69011d7c
2 changed files with 29 additions and 11 deletions

View File

@@ -13,6 +13,7 @@
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
#include <linux/version.h> #include <linux/version.h>
#include <uapi/linux/tegra-fsicom.h> #include <uapi/linux/tegra-fsicom.h>
#include <linux/pm.h>
/* Timeout in milliseconds */ /* Timeout in milliseconds */
@@ -44,27 +45,25 @@ static struct task_struct *task;
static struct fsi_hsp *fsi_hsp_v; static struct fsi_hsp *fsi_hsp_v;
static void fsicom_send_signal(int32_t data) static void fsicom_send_signal(int sig, int32_t data)
{ {
struct siginfo info; struct siginfo info;
/*Sending signal to app */
memset(&info, 0, sizeof(struct siginfo)); memset(&info, 0, sizeof(struct siginfo));
info.si_signo = SIG_FSI_DAEMON; info.si_signo = sig;
info.si_code = SI_QUEUE; info.si_code = SI_QUEUE;
info.si_int = (u32) (unsigned long) data; info.si_int = (u32) (unsigned long) data;
if (task != NULL) {
if (send_sig_info(SIG_FSI_DAEMON, /* Sending signal to app */
(struct kernel_siginfo *)&info, task) < 0) if (task != NULL)
pr_err("Unable to send signal\n"); if (send_sig_info(sig, (struct kernel_siginfo *)&info, task) < 0)
} pr_err("Unable to send signal %d\n", sig);
} }
static void tegra_hsp_rx_notify(struct mbox_client *cl, void *msg) static void tegra_hsp_rx_notify(struct mbox_client *cl, void *msg)
{ {
fsicom_send_signal(*((uint32_t *)msg)); fsicom_send_signal(SIG_FSI_WRITE_EVENT, *((uint32_t *)msg));
} }
static void tegra_hsp_tx_empty_notify(struct mbox_client *cl, static void tegra_hsp_tx_empty_notify(struct mbox_client *cl,
@@ -72,6 +71,7 @@ static void tegra_hsp_tx_empty_notify(struct mbox_client *cl,
{ {
pr_debug("TX empty callback came\n"); pr_debug("TX empty callback came\n");
} }
static int tegra_hsp_mb_init(struct device *dev) static int tegra_hsp_mb_init(struct device *dev)
{ {
int err; int err;
@@ -243,11 +243,28 @@ static int fsicom_client_remove(struct platform_device *pdev)
return 0; return 0;
} }
static int __maybe_unused fsicom_client_suspend(struct device *dev)
{
dev_dbg(dev, "suspend called\n");
return 0;
}
static int __maybe_unused fsicom_client_resume(struct device *dev)
{
dev_dbg(dev, "resume called\n");
fsicom_send_signal(SIG_DRIVER_RESUME, 0);
return 0;
}
static SIMPLE_DEV_PM_OPS(fsicom_client_pm, fsicom_client_suspend, fsicom_client_resume);
static struct platform_driver fsicom_client = { static struct platform_driver fsicom_client = {
.driver = { .driver = {
.name = "fsicom_client", .name = "fsicom_client",
.probe_type = PROBE_PREFER_ASYNCHRONOUS, .probe_type = PROBE_PREFER_ASYNCHRONOUS,
.of_match_table = of_match_ptr(fsicom_client_dt_match), .of_match_table = of_match_ptr(fsicom_client_dt_match),
.pm = pm_ptr(&fsicom_client_pm),
}, },
.probe = fsicom_client_probe, .probe = fsicom_client_probe,
.remove = fsicom_client_remove, .remove = fsicom_client_remove,

View File

@@ -15,7 +15,8 @@ struct rw_data {
}; };
/* signal value */ /* signal value */
#define SIG_FSI_DAEMON 44 #define SIG_DRIVER_RESUME 43
#define SIG_FSI_WRITE_EVENT 44
/* ioctl call macros */ /* ioctl call macros */
#define NVMAP_SMMU_MAP _IOWR('q', 1, struct rw_data *) #define NVMAP_SMMU_MAP _IOWR('q', 1, struct rw_data *)