mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 14:19:09 -04:00
slatecom: add rpmsg glink support for slatecom_interface
Add rpmsg support for slatecom interface driver to send msm state transition commands to slate. Add Opcodes to be received on slate-ctrl channel from hal. Send TWM_ENTER, DEEP SLEEP ENTER & EXIT to slate. Mot-CRs-fixed: (CR) CVE-Fixed: CVE-2023-33085 CRs-Fixed: 3512209 Change-Id: Ic29b116da7b90e1a1d71a14b970a2a53b1b3c20f Signed-off-by: Praveen koya <pkoya@codeaurora.org> Signed-off-by: Ashutosh Verma <ashverma@motorola.com> Reviewed-on: https://gerrit.mot.com/2762749 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
f6795b4ad6
commit
32ac22edb4
7 changed files with 345 additions and 1 deletions
|
|
@ -1483,6 +1483,15 @@ config MSM_SLATECOM_INTERFACE
|
|||
from hardware. Hardware will provide access to read
|
||||
registers and read/write AHB memory in the device.
|
||||
|
||||
config MSM_SLATECOM_RPMSG
|
||||
tristate "Provide support for slate GLINK channel"
|
||||
depends on MSM_SLATECOM_INTERFACE
|
||||
help
|
||||
MSM_SLATECOM_RPMSG informs SLATECOM_INTERFACE driver if GLINK channel
|
||||
has been opened by remote processor. It doesn't maintain state machine
|
||||
and is probed when Slate opens channel and removed when the channel is
|
||||
closed by remote processor.
|
||||
|
||||
config QCOM_AOP_SET_DDR
|
||||
tristate "Sysfs to communicate with AOP using QMP protocol"
|
||||
help
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ obj-$(CONFIG_RENAME_BLOCK_DEVICE) += rename_block_device.o
|
|||
obj-$(CONFIG_QCOM_ADSP_MANUAL_VOTE) += adsp_vote_qmi.o adsp_lpm_voting_v01.o
|
||||
obj-$(CONFIG_MSM_SLATECOM) += slatecom_spi.o
|
||||
obj-$(CONFIG_MSM_SLATECOM_INTERFACE) += slatecom_interface.o
|
||||
obj-$(CONFIG_MSM_SLATECOM_RPMSG) += slatecom_rpmsg.o
|
||||
obj-$(CONFIG_QCOM_AOP_SET_DDR) += aop-set-ddr.o
|
||||
obj-$(CONFIG_CPU_V7) += idle-v7.o
|
||||
obj-$(CONFIG_DUMP_XBL_LOG) += dump_boot_log.o
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include "peripheral-loader.h"
|
||||
#include "../../misc/qseecom_kernel.h"
|
||||
//#include "pil_slate_intf.h"
|
||||
#include "slatecom_rpmsg.h"
|
||||
|
||||
#define SLATECOM "slate_com_dev"
|
||||
|
||||
|
|
@ -95,7 +95,14 @@ struct slatedaemon_priv {
|
|||
unsigned long attrs;
|
||||
u32 cmd_status;
|
||||
struct device *platform_dev;
|
||||
bool slatecom_rpmsg;
|
||||
bool slate_resp_cmplt;
|
||||
void *lhndl;
|
||||
wait_queue_head_t link_state_wait;
|
||||
char rx_buf[20];
|
||||
struct mutex glink_mutex;
|
||||
};
|
||||
static void *slatecom_intf_drv;
|
||||
|
||||
struct slate_event {
|
||||
enum slate_event_type e_type;
|
||||
|
|
@ -182,6 +189,104 @@ static int send_uevent(struct slate_event *pce)
|
|||
return kobject_uevent_env(&dev_ret->kobj, KOBJ_CHANGE, envp);
|
||||
}
|
||||
|
||||
void slatecom_intf_notify_glink_channel_state(bool state)
|
||||
{
|
||||
struct slatedaemon_priv *dev =
|
||||
container_of(slatecom_intf_drv, struct slatedaemon_priv, lhndl);
|
||||
|
||||
pr_debug("%s: slate_ctrl channel state: %d\n", __func__, state);
|
||||
dev->slatecom_rpmsg = state;
|
||||
}
|
||||
EXPORT_SYMBOL(slatecom_intf_notify_glink_channel_state);
|
||||
|
||||
void slatecom_rx_msg(void *data, int len)
|
||||
{
|
||||
struct slatedaemon_priv *dev =
|
||||
container_of(slatecom_intf_drv, struct slatedaemon_priv, lhndl);
|
||||
|
||||
dev->slate_resp_cmplt = true;
|
||||
wake_up(&dev->link_state_wait);
|
||||
memcpy(dev->rx_buf, data, len);
|
||||
}
|
||||
EXPORT_SYMBOL(slatecom_rx_msg);
|
||||
|
||||
static int slatecom_tx_msg(struct slatedaemon_priv *dev, void *msg, size_t len)
|
||||
{
|
||||
int rc = 0;
|
||||
uint8_t resp = 0;
|
||||
|
||||
mutex_lock(&dev->glink_mutex);
|
||||
if (!dev->slatecom_rpmsg) {
|
||||
pr_err("slatecom-rpmsg is not probed yet, waiting for it to be probed\n");
|
||||
goto err_ret;
|
||||
}
|
||||
rc = slatecom_rpmsg_tx_msg(msg, len);
|
||||
|
||||
/* wait for sending command to SLATE */
|
||||
rc = wait_event_timeout(dev->link_state_wait,
|
||||
(rc == 0), msecs_to_jiffies(TIMEOUT_MS));
|
||||
if (rc == 0) {
|
||||
pr_err("failed to send command to SLATE %d\n", rc);
|
||||
goto err_ret;
|
||||
}
|
||||
|
||||
/* wait for getting response from SLATE */
|
||||
rc = wait_event_timeout(dev->link_state_wait,
|
||||
dev->slate_resp_cmplt,
|
||||
msecs_to_jiffies(TIMEOUT_MS));
|
||||
if (rc == 0) {
|
||||
pr_err("failed to get SLATE response %d\n", rc);
|
||||
goto err_ret;
|
||||
}
|
||||
dev->slate_resp_cmplt = false;
|
||||
/* check SLATE response */
|
||||
resp = *(uint8_t *)dev->rx_buf;
|
||||
if (!(resp == 0x01)) {
|
||||
pr_err("Bad SLATE response\n");
|
||||
rc = -EINVAL;
|
||||
goto err_ret;
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
err_ret:
|
||||
mutex_unlock(&dev->glink_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* send_state_change_cmd send state transition event to Slate
|
||||
* and wait for the response.
|
||||
* The response is returned to the caller.
|
||||
*/
|
||||
static int send_state_change_cmd(struct slate_ui_data *ui_obj_msg)
|
||||
{
|
||||
int ret = 0;
|
||||
struct wear_header wear_header_t = {0, 0};
|
||||
struct slatedaemon_priv *dev = container_of(slatecom_intf_drv,
|
||||
struct slatedaemon_priv,
|
||||
lhndl);
|
||||
uint32_t state = ui_obj_msg->cmd;
|
||||
|
||||
switch (state) {
|
||||
case STATE_TWM_ENTER:
|
||||
wear_header_t.opcode = GMI_WEAR_MGR_ENTER_TWM;
|
||||
break;
|
||||
case STATE_DS_ENTER:
|
||||
wear_header_t.opcode = GMI_WEAR_MGR_ENTER_TRACKER_DS;
|
||||
break;
|
||||
case STATE_DS_EXIT:
|
||||
wear_header_t.opcode = GMI_WEAR_MGR_EXIT_TRACKER_DS;
|
||||
break;
|
||||
default:
|
||||
pr_err("Invalid MSM State transtion cmd\n");
|
||||
break;
|
||||
}
|
||||
ret = slatecom_tx_msg(dev, &wear_header_t.opcode, sizeof(wear_header_t.opcode));
|
||||
if (ret < 0)
|
||||
pr_err("MSM State transtion event cmd failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int slatecom_char_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -382,6 +487,16 @@ static long slate_com_ioctl(struct file *filp,
|
|||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case DEVICE_STATE_TRANSITION:
|
||||
if (copy_from_user(&ui_obj_msg, (void __user *)arg,
|
||||
sizeof(ui_obj_msg))) {
|
||||
pr_err("The copy from user failed for state transition cmd\n");
|
||||
ret = -EFAULT;
|
||||
}
|
||||
ret = send_state_change_cmd(&ui_obj_msg);
|
||||
if (ret < 0)
|
||||
pr_err("device state transition cmd failed\n");
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,80 @@ void set_slate_dsp_state(bool status);
|
|||
* Set slate bt state
|
||||
*/
|
||||
void set_slate_bt_state(bool status);
|
||||
void slatecom_intf_notify_glink_channel_state(bool state);
|
||||
void slatecom_rx_msg(void *data, int len);
|
||||
|
||||
/*
|
||||
* WM header type - generic header structure
|
||||
*/
|
||||
struct wear_header {
|
||||
uint32_t opcode;
|
||||
uint32_t payload_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* Opcodes to be received on slate-control channel.
|
||||
*/
|
||||
enum WMSlateCtrlChnlOpcode {
|
||||
/*
|
||||
* Command to slate to enter TWM mode
|
||||
*/
|
||||
GMI_WEAR_MGR_ENTER_TWM = 1,
|
||||
|
||||
/*
|
||||
* Notification to slate about Modem Processor Sub System
|
||||
* is down due to a subsystem reset.
|
||||
*/
|
||||
GMI_WEAR_MGR_SSR_MPSS_DOWN_NOTIFICATION = 2,
|
||||
|
||||
/*
|
||||
* Notification to slate about Modem Processor Sub System
|
||||
* being brought up after a subsystem reset.
|
||||
*/
|
||||
GMI_WEAR_MGR_SSR_MPSS_UP_NOTIFICATION = 3,
|
||||
|
||||
/*
|
||||
* Notification to slate about ADSP Sub System
|
||||
* is down due to a subsystem reset.
|
||||
*/
|
||||
GMI_WEAR_MGR_SSR_ADSP_DOWN_INDICATION = 8,
|
||||
|
||||
/*
|
||||
* Notification to slate about Modem Processor
|
||||
* Sub System being brought up after a subsystem reset.
|
||||
*/
|
||||
GMI_WEAR_MGR_SSR_ADSP_UP_INDICATION = 9,
|
||||
|
||||
/*
|
||||
* Notification to MSM for generic wakeup in tracker mode
|
||||
*/
|
||||
GMI_WEAR_MGR_WAKE_UP_NO_REASON = 10,
|
||||
|
||||
/*
|
||||
* Notification to Slate About Entry to Tracker-DS
|
||||
*/
|
||||
GMI_WEAR_MGR_ENTER_TRACKER_DS = 11,
|
||||
|
||||
/*
|
||||
* Notification to Slate About Entry to Tracker-DS
|
||||
*/
|
||||
GMI_WEAR_MGR_EXIT_TRACKER_DS = 12,
|
||||
|
||||
/*
|
||||
* Notification to Slate About Time-sync update
|
||||
*/
|
||||
GMI_WEAR_MGR_TIME_SYNC_UPDATE = 13, /* payload struct: wear_time_sync_t*/
|
||||
|
||||
/*
|
||||
* Notification to Slate About Timeval UTC
|
||||
*/
|
||||
GMI_WEAR_MGR_TIMEVAL_UTC = 14, /* payload struct: wear_timeval_utc_t*/
|
||||
|
||||
/*
|
||||
* Notification to Slate About Daylight saving time
|
||||
*/
|
||||
GMI_WEAR_MGR_DST = 15, /* payload struct: wear_dst_t*/
|
||||
|
||||
};
|
||||
#endif /* SLATECOM_INTERFACE_H */
|
||||
|
||||
|
|
|
|||
101
drivers/soc/qcom/slatecom_rpmsg.c
Normal file
101
drivers/soc/qcom/slatecom_rpmsg.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include "slatecom_rpmsg.h"
|
||||
|
||||
static struct slatecom_rpmsg_dev *pdev;
|
||||
|
||||
int slatecom_rpmsg_tx_msg(void *msg, size_t len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (pdev == NULL || !pdev->chnl_state)
|
||||
pr_err("pmsg_device is null, channel is closed\n");
|
||||
|
||||
pdev->message = msg;
|
||||
pdev->message_length = len;
|
||||
if (pdev->message) {
|
||||
ret = rpmsg_send(pdev->channel, pdev->message, pdev->message_length);
|
||||
if (ret)
|
||||
pr_err("rpmsg_send failed: %d\n", ret);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(slatecom_rpmsg_tx_msg);
|
||||
|
||||
static int slatecom_rpmsg_probe(struct rpmsg_device *rpdev)
|
||||
{
|
||||
int ret = 0;
|
||||
void *msg = NULL;
|
||||
|
||||
pdev = devm_kzalloc(&rpdev->dev, sizeof(*pdev), GFP_KERNEL);
|
||||
if (!pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
pdev->channel = rpdev->ept;
|
||||
pdev->dev = &rpdev->dev;
|
||||
if (pdev->channel == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
pdev->chnl_state = true;
|
||||
dev_set_drvdata(&rpdev->dev, pdev);
|
||||
|
||||
/* send a callback to slatecom-interface driver*/
|
||||
slatecom_intf_notify_glink_channel_state(true);
|
||||
if (pdev->message == NULL)
|
||||
ret = slatecom_rpmsg_tx_msg(msg, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void slatecom_rpmsg_remove(struct rpmsg_device *rpdev)
|
||||
{
|
||||
pdev->chnl_state = false;
|
||||
pdev->message = NULL;
|
||||
dev_dbg(&rpdev->dev, "rpmsg client driver is removed\n");
|
||||
slatecom_intf_notify_glink_channel_state(false);
|
||||
dev_set_drvdata(&rpdev->dev, NULL);
|
||||
}
|
||||
|
||||
static int slatecom_rpmsg_cb(struct rpmsg_device *rpdev,
|
||||
void *data, int len, void *priv, u32 src)
|
||||
{
|
||||
struct slatecom_rpmsg_dev *dev =
|
||||
dev_get_drvdata(&rpdev->dev);
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
slatecom_rx_msg(data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rpmsg_device_id rpmsg_driver_slatecom_id_table[] = {
|
||||
{ "SLATECOM_CTRL" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_slatecom_id_table);
|
||||
|
||||
static const struct of_device_id rpmsg_driver_slatecom_of_match[] = {
|
||||
{ .compatible = "qcom,slatecom-rpmsg" },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct rpmsg_driver rpmsg_slatecom_client = {
|
||||
.id_table = rpmsg_driver_slatecom_id_table,
|
||||
.probe = slatecom_rpmsg_probe,
|
||||
.callback = slatecom_rpmsg_cb,
|
||||
.remove = slatecom_rpmsg_remove,
|
||||
.drv = {
|
||||
.name = "qcom,slatecom_rpmsg",
|
||||
.of_match_table = rpmsg_driver_slatecom_of_match,
|
||||
},
|
||||
};
|
||||
module_rpmsg_driver(rpmsg_slatecom_client);
|
||||
|
||||
MODULE_DESCRIPTION("Interface Driver for SLATECOM and RPMSG");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
31
drivers/soc/qcom/slatecom_rpmsg.h
Normal file
31
drivers/soc/qcom/slatecom_rpmsg.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef SLATECOMRPMSG_H
|
||||
#define SLATECOMRPMSG_H
|
||||
|
||||
#include <linux/rpmsg.h>
|
||||
#include "slatecom_interface.h"
|
||||
|
||||
#define TIMEOUT_MS 2000
|
||||
|
||||
struct slatecom_rpmsg_dev {
|
||||
struct rpmsg_endpoint *channel;
|
||||
struct device *dev;
|
||||
bool chnl_state;
|
||||
void *message;
|
||||
size_t message_length;
|
||||
};
|
||||
|
||||
|
||||
#if IS_ENABLED(CONFIG_MSM_SLATECOM_RPMSG)
|
||||
int slatecom_rpmsg_tx_msg(void *msg, size_t len);
|
||||
#else
|
||||
static inline int slatecom_rpmsg_tx_msg(void *msg, size_t len)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
#define SLATECOM_ADSP_DOWN2_SLATE 10
|
||||
#define SLATECOM_SLATE_WEAR_LOAD 11
|
||||
#define SLATECOM_SLATE_WEAR_UNLOAD 12
|
||||
#define SLATECOM_DEVICE_STATE_TRANSITION 13
|
||||
#define EXCHANGE_CODE 'V'
|
||||
|
||||
struct slate_ui_data {
|
||||
|
|
@ -47,6 +48,15 @@ enum slate_event_type {
|
|||
SLATE_BT_READY,
|
||||
};
|
||||
|
||||
enum device_state_transition {
|
||||
STATE_TWM_ENTER = 1,
|
||||
STATE_TWM_EXIT,
|
||||
STATE_DS_ENTER,
|
||||
STATE_DS_EXIT,
|
||||
STATE_S2D_ENTER,
|
||||
STATE_S2D_EXIT,
|
||||
};
|
||||
|
||||
#define REG_READ \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_REG_READ, \
|
||||
struct slate_ui_data)
|
||||
|
|
@ -86,6 +96,9 @@ enum slate_event_type {
|
|||
#define SLATE_ADSP_DOWN2_SLATE_DONE \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_ADSP_DOWN2_SLATE, \
|
||||
struct slate_ui_data)
|
||||
#define DEVICE_STATE_TRANSITION \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_DEVICE_STATE_TRANSITION, \
|
||||
struct slate_ui_data)
|
||||
|
||||
#endif /* LINUX_SLATECOM_INTERFACE_H */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue