mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 14:19:09 -04:00
slatecom_interface: add slatecom_interface driver
slatecom_interface driver is use for communication from slate PIL and slatecom spi to userspace. Changes are ported from bgcom_interface driver. Change-Id: I92379ca3d691a17f8e6507f1135f2ab340a9a8ae Signed-off-by: Ajit Kumar <kajit@codeaurora.org>
This commit is contained in:
parent
a3d4f5d5c3
commit
8f6d9d8de0
5 changed files with 752 additions and 0 deletions
|
|
@ -1210,5 +1210,14 @@ config MSM_SLATECOM
|
|||
This handle the interrupts raised by BG and notify the G-link with
|
||||
interrupt event and event data.
|
||||
|
||||
config MSM_SLATECOM_INTERFACE
|
||||
tristate "Driver support for Slate Communication"
|
||||
depends on MSM_SLATECOM
|
||||
help
|
||||
Create a slate_com_dev device node for user space communication.
|
||||
Single user space client can open device node for communication
|
||||
from hardware. Hardware will provide access to read
|
||||
registers and read/write AHB memory in the device.
|
||||
|
||||
source "drivers/soc/qcom/icnss2/Kconfig"
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -109,3 +109,4 @@ obj-$(CONFIG_QCOM_QFPROM_SYS) += qfprom-sys.o
|
|||
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
|
||||
|
|
|
|||
626
drivers/soc/qcom/slatecom_interface.c
Normal file
626
drivers/soc/qcom/slatecom_interface.c
Normal file
|
|
@ -0,0 +1,626 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#define pr_fmt(msg) "slatecom_dev:" msg
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <soc/qcom/subsystem_restart.h>
|
||||
#include <soc/qcom/subsystem_notif.h>
|
||||
#include "slatecom.h"
|
||||
#include "linux/slatecom_interface.h"
|
||||
#include "slatecom_interface.h"
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <asm/dma.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include "peripheral-loader.h"
|
||||
#include "../../misc/qseecom_kernel.h"
|
||||
//#include "pil_slate_intf.h"
|
||||
|
||||
#define SLATECOM "slate_com_dev"
|
||||
|
||||
#define SLATEDAEMON_LDO09_LPM_VTG 0
|
||||
#define SLATEDAEMON_LDO09_NPM_VTG 10000
|
||||
|
||||
#define SLATEDAEMON_LDO03_LPM_VTG 0
|
||||
#define SLATEDAEMON_LDO03_NPM_VTG 10000
|
||||
|
||||
#define MPPS_DOWN_EVENT_TO_SLATE_TIMEOUT 3000
|
||||
#define ADSP_DOWN_EVENT_TO_SLATE_TIMEOUT 3000
|
||||
#define MAX_APP_NAME_SIZE 100
|
||||
|
||||
/*pil_slate_intf.h*/
|
||||
#define RESULT_SUCCESS 0
|
||||
#define RESULT_FAILURE -1
|
||||
|
||||
/* tzapp command list.*/
|
||||
enum slate_tz_commands {
|
||||
SLATEPIL_RAMDUMP,
|
||||
SLATEPIL_IMAGE_LOAD,
|
||||
SLATEPIL_AUTH_MDT,
|
||||
SLATEPIL_DLOAD_CONT,
|
||||
SLATEPIL_GET_SLATE_VERSION,
|
||||
SLATEPIL_TWM_DATA,
|
||||
};
|
||||
|
||||
/* tzapp slate request.*/
|
||||
struct tzapp_slate_req {
|
||||
uint8_t tzapp_slate_cmd;
|
||||
uint8_t padding[3];
|
||||
phys_addr_t address_fw;
|
||||
size_t size_fw;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
/* tzapp slate response.*/
|
||||
struct tzapp_slate_rsp {
|
||||
uint32_t tzapp_slate_cmd;
|
||||
uint32_t slate_info_len;
|
||||
int32_t status;
|
||||
uint32_t slate_info[100];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
enum {
|
||||
SSR_DOMAIN_SLATE,
|
||||
SSR_DOMAIN_MODEM,
|
||||
SSR_DOMAIN_ADSP,
|
||||
SSR_DOMAIN_MAX,
|
||||
};
|
||||
|
||||
struct slatedaemon_priv {
|
||||
void *pil_h;
|
||||
struct qseecom_handle *qseecom_handle;
|
||||
int app_status;
|
||||
unsigned long attrs;
|
||||
u32 cmd_status;
|
||||
struct device *platform_dev;
|
||||
};
|
||||
|
||||
struct slate_event {
|
||||
enum slate_event_type e_type;
|
||||
};
|
||||
|
||||
struct service_info {
|
||||
const char name[32];
|
||||
int domain_id;
|
||||
void *handle;
|
||||
struct notifier_block *nb;
|
||||
};
|
||||
|
||||
static char *ssr_domains[] = {
|
||||
"slate-wear",
|
||||
"modem",
|
||||
"adsp",
|
||||
};
|
||||
|
||||
static struct slatedaemon_priv *dev;
|
||||
static unsigned int slatereset_gpio;
|
||||
static DEFINE_MUTEX(slate_char_mutex);
|
||||
static struct cdev slate_cdev;
|
||||
static struct class *slate_class;
|
||||
struct device *dev_ret;
|
||||
static dev_t slate_dev;
|
||||
static int device_open;
|
||||
static void *handle;
|
||||
static bool twm_exit;
|
||||
static bool slate_app_running;
|
||||
static struct slatecom_open_config_type config_type;
|
||||
static DECLARE_COMPLETION(slate_modem_down_wait);
|
||||
static DECLARE_COMPLETION(slate_adsp_down_wait);
|
||||
|
||||
/**
|
||||
* send_uevent(): send events to user space
|
||||
* pce : ssr event handle value
|
||||
* Return: 0 on success, standard Linux error code on error
|
||||
*
|
||||
* It adds pce value to event and broadcasts to user space.
|
||||
*/
|
||||
static int send_uevent(struct slate_event *pce)
|
||||
{
|
||||
char event_string[32];
|
||||
char *envp[2] = { event_string, NULL };
|
||||
|
||||
snprintf(event_string, ARRAY_SIZE(event_string),
|
||||
"SLATE_EVENT=%d", pce->e_type);
|
||||
return kobject_uevent_env(&dev_ret->kobj, KOBJ_CHANGE, envp);
|
||||
}
|
||||
|
||||
static int slatecom_char_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&slate_char_mutex);
|
||||
if (device_open == 1) {
|
||||
pr_err("device is already open\n");
|
||||
mutex_unlock(&slate_char_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
device_open++;
|
||||
handle = slatecom_open(&config_type);
|
||||
mutex_unlock(&slate_char_mutex);
|
||||
if (IS_ERR(handle)) {
|
||||
device_open = 0;
|
||||
ret = PTR_ERR(handle);
|
||||
handle = NULL;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int slatechar_read_cmd(struct slate_ui_data *fui_obj_msg,
|
||||
unsigned int type)
|
||||
{
|
||||
void *read_buf;
|
||||
int ret;
|
||||
void __user *result = (void *)
|
||||
(uintptr_t)fui_obj_msg->result;
|
||||
|
||||
read_buf = kmalloc_array(fui_obj_msg->num_of_words, sizeof(uint32_t),
|
||||
GFP_KERNEL);
|
||||
if (read_buf == NULL)
|
||||
return -ENOMEM;
|
||||
switch (type) {
|
||||
case REG_READ:
|
||||
ret = slatecom_reg_read(handle, fui_obj_msg->cmd,
|
||||
fui_obj_msg->num_of_words,
|
||||
read_buf);
|
||||
break;
|
||||
case AHB_READ:
|
||||
ret = slatecom_ahb_read(handle,
|
||||
fui_obj_msg->slate_address,
|
||||
fui_obj_msg->num_of_words,
|
||||
read_buf);
|
||||
break;
|
||||
}
|
||||
if (!ret && copy_to_user(result, read_buf,
|
||||
fui_obj_msg->num_of_words * sizeof(uint32_t))) {
|
||||
pr_err("copy to user failed\n");
|
||||
ret = -EFAULT;
|
||||
}
|
||||
kfree(read_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int slatechar_write_cmd(struct slate_ui_data *fui_obj_msg, unsigned int type)
|
||||
{
|
||||
void *write_buf;
|
||||
int ret = -EINVAL;
|
||||
void __user *write = (void *)
|
||||
(uintptr_t)fui_obj_msg->write;
|
||||
|
||||
write_buf = kmalloc_array(fui_obj_msg->num_of_words, sizeof(uint32_t),
|
||||
GFP_KERNEL);
|
||||
if (write_buf == NULL)
|
||||
return -ENOMEM;
|
||||
write_buf = memdup_user(write,
|
||||
fui_obj_msg->num_of_words * sizeof(uint32_t));
|
||||
if (IS_ERR(write_buf)) {
|
||||
ret = PTR_ERR(write_buf);
|
||||
kfree(write_buf);
|
||||
return ret;
|
||||
}
|
||||
switch (type) {
|
||||
case REG_WRITE:
|
||||
ret = slatecom_reg_write(handle, fui_obj_msg->cmd,
|
||||
fui_obj_msg->num_of_words,
|
||||
write_buf);
|
||||
break;
|
||||
case AHB_WRITE:
|
||||
ret = slatecom_ahb_write(handle,
|
||||
fui_obj_msg->slate_address,
|
||||
fui_obj_msg->num_of_words,
|
||||
write_buf);
|
||||
break;
|
||||
}
|
||||
kfree(write_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int slate_soft_reset(void)
|
||||
{
|
||||
pr_debug("do SLATE reset using gpio %d\n", slatereset_gpio);
|
||||
if (!gpio_is_valid(slatereset_gpio)) {
|
||||
pr_err("gpio %d is not valid\n", slatereset_gpio);
|
||||
return -ENXIO;
|
||||
}
|
||||
if (gpio_direction_output(slatereset_gpio, 1))
|
||||
pr_err("gpio %d direction not set\n", slatereset_gpio);
|
||||
|
||||
/* Sleep for 50ms for hardware to detect signal as high */
|
||||
msleep(50);
|
||||
|
||||
gpio_set_value(slatereset_gpio, 0);
|
||||
|
||||
/* Sleep for 50ms for hardware to detect signal as high */
|
||||
msleep(50);
|
||||
gpio_set_value(slatereset_gpio, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(slate_soft_reset);
|
||||
|
||||
static int modem_down2_slate(void)
|
||||
{
|
||||
complete(&slate_modem_down_wait);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adsp_down2_slate(void)
|
||||
{
|
||||
complete(&slate_adsp_down_wait);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long slate_com_ioctl(struct file *filp,
|
||||
unsigned int ui_slatecom_cmd, unsigned long arg)
|
||||
{
|
||||
int ret;
|
||||
struct slate_ui_data ui_obj_msg;
|
||||
|
||||
switch (ui_slatecom_cmd) {
|
||||
case REG_READ:
|
||||
case AHB_READ:
|
||||
if (copy_from_user(&ui_obj_msg, (void __user *) arg,
|
||||
sizeof(ui_obj_msg))) {
|
||||
pr_err("The copy from user failed\n");
|
||||
ret = -EFAULT;
|
||||
}
|
||||
ret = slatechar_read_cmd(&ui_obj_msg,
|
||||
ui_slatecom_cmd);
|
||||
if (ret < 0)
|
||||
pr_err("slatechar_read_cmd failed\n");
|
||||
break;
|
||||
case AHB_WRITE:
|
||||
case REG_WRITE:
|
||||
if (copy_from_user(&ui_obj_msg, (void __user *) arg,
|
||||
sizeof(ui_obj_msg))) {
|
||||
pr_err("The copy from user failed\n");
|
||||
ret = -EFAULT;
|
||||
}
|
||||
ret = slatechar_write_cmd(&ui_obj_msg, ui_slatecom_cmd);
|
||||
if (ret < 0)
|
||||
pr_err("slatechar_write_cmd failed\n");
|
||||
break;
|
||||
case SET_SPI_FREE:
|
||||
ret = slatecom_set_spi_state(SLATECOM_SPI_FREE);
|
||||
break;
|
||||
case SET_SPI_BUSY:
|
||||
ret = slatecom_set_spi_state(SLATECOM_SPI_BUSY);
|
||||
break;
|
||||
case SLATE_SOFT_RESET:
|
||||
ret = slate_soft_reset();
|
||||
break;
|
||||
case SLATE_MODEM_DOWN2_SLATE_DONE:
|
||||
ret = modem_down2_slate();
|
||||
break;
|
||||
case SLATE_ADSP_DOWN2_SLATE_DONE:
|
||||
ret = adsp_down2_slate();
|
||||
break;
|
||||
case SLATE_TWM_EXIT:
|
||||
twm_exit = true;
|
||||
ret = 0;
|
||||
break;
|
||||
case SLATE_APP_RUNNING:
|
||||
slate_app_running = true;
|
||||
ret = 0;
|
||||
break;
|
||||
case SLATE_WEAR_LOAD:
|
||||
ret = 0;
|
||||
if (dev->pil_h) {
|
||||
pr_err("slate-wear is already loaded\n");
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
dev->pil_h = subsystem_get_with_fwname("slate-wear", "slate-wear");
|
||||
if (!dev->pil_h) {
|
||||
pr_err("failed to load slate-wear\n");
|
||||
ret = -EFAULT;
|
||||
}
|
||||
break;
|
||||
case SLATE_WEAR_UNLOAD:
|
||||
if (dev->pil_h) {
|
||||
subsystem_put(dev->pil_h);
|
||||
dev->pil_h = NULL;
|
||||
slate_soft_reset();
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int slatecom_char_close(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&slate_char_mutex);
|
||||
ret = slatecom_close(&handle);
|
||||
device_open = 0;
|
||||
mutex_unlock(&slate_char_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int slate_daemon_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node;
|
||||
|
||||
node = pdev->dev.of_node;
|
||||
|
||||
dev = kzalloc(sizeof(struct slatedaemon_priv), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
dev->platform_dev = &pdev->dev;
|
||||
pr_info("%s success\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id slate_daemon_of_match[] = {
|
||||
{ .compatible = "qcom,slate-daemon", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, slate_daemon_of_match);
|
||||
|
||||
static struct platform_driver slate_daemon_driver = {
|
||||
.probe = slate_daemon_probe,
|
||||
.driver = {
|
||||
.name = "slate-daemon",
|
||||
.of_match_table = slate_daemon_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct file_operations fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = slatecom_char_open,
|
||||
.release = slatecom_char_close,
|
||||
.unlocked_ioctl = slate_com_ioctl,
|
||||
};
|
||||
|
||||
/**
|
||||
*ssr_slate_cb(): callback function is called
|
||||
*by ssr framework when SLATE goes down, up and during ramdump
|
||||
*collection. It handles SLATE shutdown and power up events.
|
||||
*/
|
||||
static int ssr_slate_cb(struct notifier_block *this,
|
||||
unsigned long opcode, void *data)
|
||||
{
|
||||
struct slate_event slatee;
|
||||
|
||||
switch (opcode) {
|
||||
case SUBSYS_BEFORE_SHUTDOWN:
|
||||
pr_debug("Slate before shutdown\n");
|
||||
slatee.e_type = SLATE_BEFORE_POWER_DOWN;
|
||||
slatecom_slatedown_handler();
|
||||
slatecom_set_spi_state(SLATECOM_SPI_BUSY);
|
||||
send_uevent(&slatee);
|
||||
break;
|
||||
case SUBSYS_AFTER_SHUTDOWN:
|
||||
pr_debug("Slate after shutdown\n");
|
||||
slatee.e_type = SLATE_AFTER_POWER_DOWN;
|
||||
slatecom_slatedown_handler();
|
||||
send_uevent(&slatee);
|
||||
break;
|
||||
case SUBSYS_BEFORE_POWERUP:
|
||||
pr_debug("Slate before powerup\n");
|
||||
slatee.e_type = SLATE_BEFORE_POWER_UP;
|
||||
slatecom_slatedown_handler();
|
||||
send_uevent(&slatee);
|
||||
break;
|
||||
case SUBSYS_AFTER_POWERUP:
|
||||
pr_debug("Slate after powerup\n");
|
||||
slatecom_set_spi_state(SLATECOM_SPI_FREE);
|
||||
send_uevent(&slatee);
|
||||
break;
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/**
|
||||
*ssr_modem_cb(): callback function is called
|
||||
*by ssr framework when modem goes down, up and during ramdump
|
||||
*collection. It handles modem shutdown and power up events.
|
||||
*/
|
||||
static int ssr_modem_cb(struct notifier_block *this,
|
||||
unsigned long opcode, void *data)
|
||||
{
|
||||
struct slate_event modeme;
|
||||
int ret;
|
||||
|
||||
switch (opcode) {
|
||||
case SUBSYS_BEFORE_SHUTDOWN:
|
||||
modeme.e_type = MODEM_BEFORE_POWER_DOWN;
|
||||
reinit_completion(&slate_modem_down_wait);
|
||||
send_uevent(&modeme);
|
||||
ret = wait_for_completion_timeout(&slate_modem_down_wait,
|
||||
msecs_to_jiffies(MPPS_DOWN_EVENT_TO_SLATE_TIMEOUT));
|
||||
if (!ret)
|
||||
pr_err("Time out on modem down event\n");
|
||||
break;
|
||||
case SUBSYS_AFTER_POWERUP:
|
||||
modeme.e_type = MODEM_AFTER_POWER_UP;
|
||||
send_uevent(&modeme);
|
||||
break;
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int ssr_adsp_cb(struct notifier_block *this,
|
||||
unsigned long opcode, void *data)
|
||||
{
|
||||
struct slate_event adspe;
|
||||
int ret;
|
||||
|
||||
switch (opcode) {
|
||||
case SUBSYS_BEFORE_SHUTDOWN:
|
||||
adspe.e_type = ADSP_BEFORE_POWER_DOWN;
|
||||
reinit_completion(&slate_adsp_down_wait);
|
||||
send_uevent(&adspe);
|
||||
ret = wait_for_completion_timeout(&slate_adsp_down_wait,
|
||||
msecs_to_jiffies(ADSP_DOWN_EVENT_TO_SLATE_TIMEOUT));
|
||||
if (!ret)
|
||||
pr_err("Time out on adsp down event\n");
|
||||
break;
|
||||
case SUBSYS_AFTER_POWERUP:
|
||||
adspe.e_type = ADSP_AFTER_POWER_UP;
|
||||
send_uevent(&adspe);
|
||||
break;
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
bool is_twm_exit(void)
|
||||
{
|
||||
if (twm_exit) {
|
||||
twm_exit = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(is_twm_exit);
|
||||
|
||||
bool is_slate_running(void)
|
||||
{
|
||||
if (slate_app_running) {
|
||||
slate_app_running = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(is_slate_running);
|
||||
|
||||
static struct notifier_block ssr_modem_nb = {
|
||||
.notifier_call = ssr_modem_cb,
|
||||
.priority = 0,
|
||||
};
|
||||
|
||||
static struct notifier_block ssr_adsp_nb = {
|
||||
.notifier_call = ssr_adsp_cb,
|
||||
.priority = 0,
|
||||
};
|
||||
|
||||
static struct notifier_block ssr_slate_nb = {
|
||||
.notifier_call = ssr_slate_cb,
|
||||
.priority = 0,
|
||||
};
|
||||
|
||||
static struct service_info service_data[3] = {
|
||||
{
|
||||
.name = "SSR_SLATE",
|
||||
.domain_id = SSR_DOMAIN_SLATE,
|
||||
.nb = &ssr_slate_nb,
|
||||
.handle = NULL,
|
||||
},
|
||||
{
|
||||
.name = "SSR_MODEM",
|
||||
.domain_id = SSR_DOMAIN_MODEM,
|
||||
.nb = &ssr_modem_nb,
|
||||
.handle = NULL,
|
||||
},
|
||||
{
|
||||
.name = "SSR_ADSP",
|
||||
.domain_id = SSR_DOMAIN_ADSP,
|
||||
.nb = &ssr_adsp_nb,
|
||||
.handle = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* ssr_register checks that domain id should be in range and register
|
||||
* SSR framework for value at domain id.
|
||||
*/
|
||||
static void ssr_register(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(service_data); i++) {
|
||||
if ((service_data[i].domain_id < 0) ||
|
||||
(service_data[i].domain_id >= SSR_DOMAIN_MAX)) {
|
||||
pr_err("Invalid service ID = %d\n",
|
||||
service_data[i].domain_id);
|
||||
} else {
|
||||
service_data[i].handle =
|
||||
subsys_notif_register_notifier(
|
||||
ssr_domains[service_data[i].domain_id],
|
||||
service_data[i].nb);
|
||||
if (IS_ERR_OR_NULL(service_data[i].handle)) {
|
||||
pr_err("subsys register failed for id = %d\n",
|
||||
service_data[i].domain_id);
|
||||
service_data[i].handle = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int __init init_slate_com_dev(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = alloc_chrdev_region(&slate_dev, 0, 1, SLATECOM);
|
||||
if (ret < 0) {
|
||||
pr_err("failed with error %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
cdev_init(&slate_cdev, &fops);
|
||||
|
||||
ret = cdev_add(&slate_cdev, slate_dev, 1);
|
||||
if (ret < 0) {
|
||||
unregister_chrdev_region(slate_dev, 1);
|
||||
pr_err("device registration failed\n");
|
||||
return ret;
|
||||
}
|
||||
slate_class = class_create(THIS_MODULE, SLATECOM);
|
||||
if (IS_ERR_OR_NULL(slate_class)) {
|
||||
cdev_del(&slate_cdev);
|
||||
unregister_chrdev_region(slate_dev, 1);
|
||||
pr_err("class creation failed\n");
|
||||
return PTR_ERR(slate_class);
|
||||
}
|
||||
|
||||
dev_ret = device_create(slate_class, NULL, slate_dev, NULL, SLATECOM);
|
||||
if (IS_ERR_OR_NULL(dev_ret)) {
|
||||
class_destroy(slate_class);
|
||||
cdev_del(&slate_cdev);
|
||||
unregister_chrdev_region(slate_dev, 1);
|
||||
pr_err("device create failed\n");
|
||||
return PTR_ERR(dev_ret);
|
||||
}
|
||||
|
||||
if (platform_driver_register(&slate_daemon_driver))
|
||||
pr_err("%s: failed to register slate-daemon register\n", __func__);
|
||||
|
||||
ssr_register();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit exit_slate_com_dev(void)
|
||||
{
|
||||
device_destroy(slate_class, slate_dev);
|
||||
class_destroy(slate_class);
|
||||
cdev_del(&slate_cdev);
|
||||
unregister_chrdev_region(slate_dev, 1);
|
||||
platform_driver_unregister(&slate_daemon_driver);
|
||||
}
|
||||
|
||||
module_init(init_slate_com_dev);
|
||||
module_exit(exit_slate_com_dev);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
29
drivers/soc/qcom/slatecom_interface.h
Normal file
29
drivers/soc/qcom/slatecom_interface.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef SLATECOM_INTERFACE_H
|
||||
#define SLATECOM_INTERFACE_H
|
||||
|
||||
/*
|
||||
* slate_soft_reset() - soft reset Blackghost
|
||||
* Return 0 on success or -Ve on error
|
||||
*/
|
||||
int slate_soft_reset(void);
|
||||
|
||||
/*
|
||||
* is_twm_exit()
|
||||
* Return true if device is booting up on TWM exit.
|
||||
* value is auto cleared once read.
|
||||
*/
|
||||
bool is_twm_exit(void);
|
||||
|
||||
/*
|
||||
* is_slate_running()
|
||||
* Return true if slate is running.
|
||||
* value is auto cleared once read.
|
||||
*/
|
||||
bool is_slate_running(void);
|
||||
|
||||
#endif /* SLATECOM_INTERFACE_H */
|
||||
|
||||
87
include/uapi/linux/slatecom_interface.h
Normal file
87
include/uapi/linux/slatecom_interface.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef LINUX_SLATECOM_INTERFACE_H
|
||||
#define LINUX_SLATECOM_INTERFACE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define SLATECOM_REG_READ 0
|
||||
#define SLATECOM_AHB_READ 1
|
||||
#define SLATECOM_AHB_WRITE 2
|
||||
#define SLATECOM_SET_SPI_FREE 3
|
||||
#define SLATECOM_SET_SPI_BUSY 4
|
||||
#define SLATECOM_REG_WRITE 5
|
||||
#define SLATECOM_SOFT_RESET 6
|
||||
#define SLATECOM_MODEM_DOWN2_SLATE 7
|
||||
#define SLATECOM_TWM_EXIT 8
|
||||
#define SLATECOM_SLATE_APP_RUNNING 9
|
||||
#define SLATECOM_ADSP_DOWN2_SLATE 10
|
||||
#define SLATECOM_SLATE_WEAR_LOAD 11
|
||||
#define SLATECOM_SLATE_WEAR_UNLOAD 12
|
||||
#define EXCHANGE_CODE 'V'
|
||||
|
||||
struct slate_ui_data {
|
||||
__u64 __user write;
|
||||
__u64 __user result;
|
||||
__u32 slate_address;
|
||||
__u32 cmd;
|
||||
__u32 num_of_words;
|
||||
__u8 __user *buffer;
|
||||
};
|
||||
|
||||
enum slate_event_type {
|
||||
SLATE_BEFORE_POWER_DOWN = 1,
|
||||
SLATE_AFTER_POWER_DOWN,
|
||||
SLATE_BEFORE_POWER_UP,
|
||||
SLATE_AFTER_POWER_UP,
|
||||
MODEM_BEFORE_POWER_DOWN,
|
||||
MODEM_AFTER_POWER_UP,
|
||||
ADSP_BEFORE_POWER_DOWN,
|
||||
ADSP_AFTER_POWER_UP,
|
||||
TWM_SLATE_AFTER_POWER_UP,
|
||||
};
|
||||
|
||||
#define REG_READ \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_REG_READ, \
|
||||
struct slate_ui_data)
|
||||
#define AHB_READ \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_AHB_READ, \
|
||||
struct slate_ui_data)
|
||||
#define AHB_WRITE \
|
||||
_IOW(EXCHANGE_CODE, SLATECOM_AHB_WRITE, \
|
||||
struct slate_ui_data)
|
||||
#define SET_SPI_FREE \
|
||||
_IOR(EXCHANGE_CODE, SLATECOM_SET_SPI_FREE, \
|
||||
struct slate_ui_data)
|
||||
#define SET_SPI_BUSY \
|
||||
_IOR(EXCHANGE_CODE, SLATECOM_SET_SPI_BUSY, \
|
||||
struct slate_ui_data)
|
||||
#define REG_WRITE \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_REG_WRITE, \
|
||||
struct slate_ui_data)
|
||||
#define SLATE_SOFT_RESET \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_SOFT_RESET, \
|
||||
struct slate_ui_data)
|
||||
#define SLATE_TWM_EXIT \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_TWM_EXIT, \
|
||||
struct slate_ui_data)
|
||||
#define SLATE_APP_RUNNING \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_SLATE_APP_RUNNING, \
|
||||
struct slate_ui_data)
|
||||
#define SLATE_MODEM_DOWN2_SLATE_DONE \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_MODEM_DOWN2_SLATE, \
|
||||
struct slate_ui_data)
|
||||
#define SLATE_WEAR_LOAD \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_SLATE_WEAR_LOAD, \
|
||||
struct slate_ui_data)
|
||||
#define SLATE_WEAR_UNLOAD \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_SLATE_WEAR_UNLOAD, \
|
||||
struct slate_ui_data)
|
||||
#define SLATE_ADSP_DOWN2_SLATE_DONE \
|
||||
_IOWR(EXCHANGE_CODE, SLATECOM_ADSP_DOWN2_SLATE, \
|
||||
struct slate_ui_data)
|
||||
|
||||
#endif /* LINUX_SLATECOM_INTERFACE_H */
|
||||
|
||||
Loading…
Reference in a new issue