Squashed backup commit (no shallow-clone history issues) of xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2 branch, upstream commit 9eece662e) plus all fixes applied to get everpal_defconfig building clean against a modern (GCC 15.2.0) toolchain -- see the previous commit message on the lineage-23.2 branch (also in this repo history is not available here since this is a squashed snapshot; full incremental history lives in the local DL380 checkout and the upstream GitHub remote). Upstream: https://github.com/xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2)
736 lines
22 KiB
C
736 lines
22 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (c) 2019 - 2021 MediaTek Inc.
|
|
*/
|
|
|
|
|
|
/*******************************************************************************
|
|
* Dependency
|
|
*******************************************************************************/
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/init.h>
|
|
#include <linux/types.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/device.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/cdev.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/io.h>
|
|
#include <linux/uaccess.h>
|
|
#include <linux/printk.h>
|
|
#include <linux/version.h>
|
|
#include <linux/wait.h>
|
|
#include <conap_scp.h>
|
|
#include <linux/poll.h>
|
|
#ifdef pr_fmt
|
|
#undef pr_fmt
|
|
#endif
|
|
#define pr_fmt(fmt) "["KBUILD_MODNAME"]" fmt
|
|
|
|
/******************************************************************************
|
|
* Definition
|
|
******************************************************************************/
|
|
/* device name and major number */
|
|
#define GPS2SCP_DEVNAME "gps2scp"
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
#define GPS2SCP_DEVNAME_TEST "gps2scp_test"
|
|
#endif
|
|
/*******************************************************************************
|
|
* structure & enumeration
|
|
*******************************************************************************/
|
|
/*---------------------------------------------------------------------------*/
|
|
struct gps2scp_dev {
|
|
struct class *cls;
|
|
struct device *dev;
|
|
dev_t devno;
|
|
struct cdev chdev;
|
|
};
|
|
/* typedef unsigned char UINT8, *PUINT8, **PPUINT8; */
|
|
|
|
/******************************************************************************
|
|
* local variables
|
|
******************************************************************************/
|
|
/* static int flag; */
|
|
static struct conap_scp_drv_cb gps2scp_cb;
|
|
#define GPS2SCP_BUFFER_SIZE (1024*10)
|
|
struct gps2scp_dev *gps2scp_devobj;
|
|
static unsigned char o_buf[GPS2SCP_BUFFER_SIZE]; /* output buffer of write() */
|
|
static struct semaphore wr_mtx, rd_mtx, ring_buf_mtx;
|
|
static wait_queue_head_t GPS2SCP_wq;
|
|
#define SCP2GPS_BUFF_SIZE 1024
|
|
#define SCP2GPS_BUFF_NUM 24
|
|
#define DRV_TYPE_GPS 1
|
|
struct scp2gps_data {
|
|
int size;
|
|
unsigned int msg_id;
|
|
unsigned int data[SCP2GPS_BUFF_SIZE];
|
|
};
|
|
struct scp2gps_data_link {
|
|
int msg_read;
|
|
struct scp2gps_data data_link[SCP2GPS_BUFF_NUM];
|
|
int msg_write;
|
|
};
|
|
struct scp2gps_data_link scp2gps_data_received;
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
static unsigned char o_buf_test[GPS2SCP_BUFFER_SIZE]; /* output buffer of write() */
|
|
static struct semaphore wr_mtx_test, rd_mtx_test, ring_buf_mtx_test;
|
|
static wait_queue_head_t GPS2SCP_wq_test;
|
|
struct gps2scp_dev *gps2scp_devobj_test;
|
|
struct scp2gps_data_link scp2gps_data_received_test;
|
|
|
|
void save_scp2gps_data_test(unsigned int msg_id, unsigned int *buf, unsigned int size)
|
|
{
|
|
down(&ring_buf_mtx_test);
|
|
pr_info("save_scp2gps_data_test msg_write=%d , size=%d, msg_read =%d\n",
|
|
scp2gps_data_received_test.msg_write, size, scp2gps_data_received_test.msg_read);
|
|
memset(&scp2gps_data_received_test.data_link[scp2gps_data_received_test.msg_write], 0,
|
|
sizeof(scp2gps_data_received_test.data_link[scp2gps_data_received_test.msg_write]));
|
|
if (size < SCP2GPS_BUFF_SIZE)
|
|
memcpy(&scp2gps_data_received_test.data_link[scp2gps_data_received_test.msg_write].data[0], buf, size);
|
|
else
|
|
memcpy(&scp2gps_data_received_test.data_link[scp2gps_data_received_test.msg_write].data[0],
|
|
buf, (SCP2GPS_BUFF_SIZE - 1));
|
|
pr_info("save_scp2gps_data_test msg_write=%d , size=%d, msg_read =%d\n",
|
|
scp2gps_data_received_test.msg_write,
|
|
scp2gps_data_received_test.data_link[scp2gps_data_received_test.msg_write].size,
|
|
scp2gps_data_received_test.msg_read);
|
|
scp2gps_data_received_test.data_link[scp2gps_data_received_test.msg_write].msg_id = msg_id;
|
|
scp2gps_data_received_test.data_link[scp2gps_data_received_test.msg_write].size = size;
|
|
|
|
scp2gps_data_received_test.msg_write++;
|
|
if (scp2gps_data_received_test.msg_write >= SCP2GPS_BUFF_NUM)
|
|
scp2gps_data_received_test.msg_write = 0;
|
|
|
|
if (scp2gps_data_received_test.msg_write == scp2gps_data_received_test.msg_read) {
|
|
scp2gps_data_received_test.msg_read++;
|
|
if (scp2gps_data_received_test.msg_read >= SCP2GPS_BUFF_NUM)
|
|
scp2gps_data_received_test.msg_read = 0;
|
|
}
|
|
up(&ring_buf_mtx_test);
|
|
}
|
|
|
|
ssize_t read_scp2gps_data_test(char __user *buf, size_t count)
|
|
{
|
|
int retval;
|
|
int msg_read;
|
|
int size;
|
|
|
|
down(&ring_buf_mtx_test);
|
|
pr_info("read_scp2gps_data_test msg_write=%d , size=%d, msg_read =%d\n",
|
|
scp2gps_data_received_test.msg_write,
|
|
scp2gps_data_received_test.data_link[scp2gps_data_received_test.msg_read].size,
|
|
scp2gps_data_received_test.msg_read);
|
|
msg_read = scp2gps_data_received_test.msg_read;
|
|
size = scp2gps_data_received_test.data_link[msg_read].size;
|
|
if (size > count)
|
|
size = count;
|
|
if (msg_read != scp2gps_data_received_test.msg_write) {
|
|
/* we got something from STP driver */
|
|
if (copy_to_user(buf, scp2gps_data_received_test.data_link[msg_read].data, size)) {
|
|
pr_info("read_scp2gps_data failed,because copy_to_user error\n");
|
|
retval = -EFAULT;
|
|
up(&ring_buf_mtx_test);
|
|
} else {
|
|
retval = scp2gps_data_received_test.data_link[msg_read].size;
|
|
scp2gps_data_received_test.msg_read++;
|
|
if (scp2gps_data_received_test.msg_read >= SCP2GPS_BUFF_NUM)
|
|
scp2gps_data_received_test.msg_read = 0;
|
|
up(&ring_buf_mtx_test);
|
|
pr_info("read_scp2gps_data_test msg_write=%d , size=%d, msg_read =%d\n",
|
|
scp2gps_data_received_test.msg_write,
|
|
scp2gps_data_received_test.data_link[scp2gps_data_received_test.msg_write].size,
|
|
scp2gps_data_received_test.msg_read);
|
|
}
|
|
return retval;
|
|
}
|
|
up(&ring_buf_mtx_test);
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
void save_scp2gps_data(unsigned int msg_id, unsigned int *buf, unsigned int size)
|
|
{
|
|
down(&ring_buf_mtx);
|
|
pr_info("save_scp2gps_data msg_write=%d , size=%d, msg_read =%d\n",
|
|
scp2gps_data_received.msg_write, size, scp2gps_data_received.msg_read);
|
|
memset(&scp2gps_data_received.data_link[scp2gps_data_received.msg_write], 0,
|
|
sizeof(scp2gps_data_received.data_link[scp2gps_data_received.msg_write]));
|
|
if (size < SCP2GPS_BUFF_SIZE)
|
|
memcpy(&scp2gps_data_received.data_link[scp2gps_data_received.msg_write].data[0], buf, size);
|
|
else
|
|
memcpy(&scp2gps_data_received.data_link[scp2gps_data_received.msg_write].data[0],
|
|
buf, (SCP2GPS_BUFF_SIZE - 1));
|
|
pr_info("save_scp2gps_data msg_write=%d , size=%d, msg_read =%d\n",
|
|
scp2gps_data_received.msg_write,
|
|
scp2gps_data_received.data_link[scp2gps_data_received.msg_write].size,
|
|
scp2gps_data_received.msg_read);
|
|
scp2gps_data_received.data_link[scp2gps_data_received.msg_write].msg_id = msg_id;
|
|
scp2gps_data_received.data_link[scp2gps_data_received.msg_write].size = size;
|
|
|
|
scp2gps_data_received.msg_write++;
|
|
if (scp2gps_data_received.msg_write >= SCP2GPS_BUFF_NUM)
|
|
scp2gps_data_received.msg_write = 0;
|
|
|
|
if (scp2gps_data_received.msg_write == scp2gps_data_received.msg_read) {
|
|
scp2gps_data_received.msg_read++;
|
|
if (scp2gps_data_received.msg_read >= SCP2GPS_BUFF_NUM)
|
|
scp2gps_data_received.msg_read = 0;
|
|
}
|
|
up(&ring_buf_mtx);
|
|
}
|
|
|
|
ssize_t read_scp2gps_data(char __user *buf, size_t count)
|
|
{
|
|
int retval;
|
|
int msg_read;
|
|
int size;
|
|
|
|
down(&ring_buf_mtx);
|
|
pr_info("read_scp2gps_data msg_write=%d , size=%d, msg_read =%d\n",
|
|
scp2gps_data_received.msg_write,
|
|
scp2gps_data_received.data_link[scp2gps_data_received.msg_read].size,
|
|
scp2gps_data_received.msg_read);
|
|
msg_read = scp2gps_data_received.msg_read;
|
|
size = scp2gps_data_received.data_link[msg_read].size;
|
|
if (size > count)
|
|
size = count;
|
|
if (msg_read != scp2gps_data_received.msg_write) {
|
|
/* we got something from STP driver */
|
|
if (copy_to_user(buf, scp2gps_data_received.data_link[msg_read].data, size)) {
|
|
pr_info("read_scp2gps_data failed,because copy_to_user error\n");
|
|
retval = -EFAULT;
|
|
up(&ring_buf_mtx);
|
|
} else {
|
|
retval = scp2gps_data_received.data_link[msg_read].size;
|
|
scp2gps_data_received.msg_read++;
|
|
if (scp2gps_data_received.msg_read >= SCP2GPS_BUFF_NUM)
|
|
scp2gps_data_received.msg_read = 0;
|
|
up(&ring_buf_mtx);
|
|
pr_info("read_scp2gps_data msg_write=%d , size=%d, msg_read =%d\n",
|
|
scp2gps_data_received.msg_write,
|
|
scp2gps_data_received.data_link[scp2gps_data_received.msg_write].size,
|
|
scp2gps_data_received.msg_read);
|
|
}
|
|
return retval;
|
|
}
|
|
up(&ring_buf_mtx);
|
|
return 0;
|
|
}
|
|
void gps2scp_msg_cb(unsigned int msg_id, unsigned int *buf, unsigned int size)
|
|
{
|
|
pr_info("gps2scp_msg_cb been called, msg_id=%d,*buf=0x%p,size=%d\n", msg_id, buf, size);
|
|
if (msg_id == 0) {
|
|
save_scp2gps_data(msg_id, buf, size);
|
|
wake_up_interruptible(&GPS2SCP_wq);
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
} else if (msg_id == 1) {
|
|
save_scp2gps_data_test(msg_id, buf, size);
|
|
wake_up_interruptible(&GPS2SCP_wq_test);
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
void gps2scp_state_notify_cb(int state)
|
|
{
|
|
pr_info("gps2scp_msg_cb been called , state = %d\n", state);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
long gps2scp_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|
{
|
|
long retval = 0;
|
|
|
|
return retval;
|
|
}
|
|
|
|
long gps2scp_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|
{
|
|
return gps2scp_unlocked_ioctl(filp, cmd, arg);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*****************************************************************************/
|
|
static int gps2scp_open(struct inode *inode, struct file *file)
|
|
{
|
|
int conap_status;
|
|
|
|
conap_status = conap_scp_is_drv_ready(DRV_TYPE_GPS);
|
|
if (conap_status != 0) {
|
|
gps2scp_cb.conap_scp_msg_notify_cb = gps2scp_msg_cb;
|
|
gps2scp_cb.conap_scp_state_notify_cb = gps2scp_state_notify_cb;
|
|
conap_scp_register_drv(DRV_TYPE_GPS, &gps2scp_cb);
|
|
}
|
|
conap_status = conap_scp_is_drv_ready(DRV_TYPE_GPS);
|
|
if (conap_status == 0)
|
|
pr_info("conap ready! conap_status = %d\n", conap_status);
|
|
else
|
|
pr_info("conap not ready! conap_status = %d\n", conap_status);
|
|
|
|
pr_info("%s: gps2scp open major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid);
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
/*****************************************************************************/
|
|
static int gps2scp_close(struct inode *inode, struct file *file)
|
|
{
|
|
int conap_status;
|
|
|
|
conap_status = conap_scp_is_drv_ready(DRV_TYPE_GPS);
|
|
if (conap_status == 0)
|
|
conap_scp_unregister_drv(DRV_TYPE_GPS);
|
|
|
|
conap_status = conap_scp_is_drv_ready(DRV_TYPE_GPS);
|
|
if (conap_status == 0)
|
|
pr_info("conap unregisetr fail! conap_status = %d\n", conap_status);
|
|
else
|
|
pr_info("conap unregisetr success! conap_status = %d\n", conap_status);
|
|
|
|
memset(&scp2gps_data_received, 0, sizeof(scp2gps_data_received));
|
|
|
|
pr_info("%s: gps2scp close major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid);
|
|
return 0;
|
|
}
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
/*****************************************************************************/
|
|
static int gps2scp_open_test(struct inode *inode, struct file *file)
|
|
{
|
|
int conap_status;
|
|
|
|
conap_status = conap_scp_is_drv_ready(DRV_TYPE_GPS);
|
|
if (conap_status != 0) {
|
|
gps2scp_cb.conap_scp_msg_notify_cb = gps2scp_msg_cb;
|
|
gps2scp_cb.conap_scp_state_notify_cb = gps2scp_state_notify_cb;
|
|
conap_scp_register_drv(DRV_TYPE_GPS, &gps2scp_cb);
|
|
}
|
|
conap_status = conap_scp_is_drv_ready(DRV_TYPE_GPS);
|
|
if (conap_status == 0)
|
|
pr_info("conap ready! conap_status = %d\n", conap_status);
|
|
else
|
|
pr_info("conap not ready! conap_status = %d\n", conap_status);
|
|
|
|
pr_info("%s: gps2scp open test major %d minor %d (pid %d)\n",
|
|
__func__, imajor(inode), iminor(inode), current->pid);
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
/*****************************************************************************/
|
|
static int gps2scp_close_test(struct inode *inode, struct file *file)
|
|
{
|
|
int conap_status;
|
|
|
|
conap_status = conap_scp_is_drv_ready(DRV_TYPE_GPS);
|
|
if (conap_status == 0)
|
|
conap_scp_unregister_drv(DRV_TYPE_GPS);
|
|
|
|
conap_status = conap_scp_is_drv_ready(DRV_TYPE_GPS);
|
|
if (conap_status == 0)
|
|
pr_info("conap unregisetr fail! conap_status = %d\n", conap_status);
|
|
else
|
|
pr_info("conap unregisetr success! conap_status = %d\n", conap_status);
|
|
|
|
|
|
memset(&scp2gps_data_received_test, 0, sizeof(scp2gps_data_received));
|
|
|
|
pr_info("%s: gps2scp close test major %d minor %d (pid %d)\n",
|
|
__func__, imajor(inode), iminor(inode), current->pid);
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
static ssize_t gps2scp_read_test(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|
{
|
|
int retval;
|
|
|
|
pr_info("gps2scp read test\n");
|
|
down(&rd_mtx_test);
|
|
|
|
if (count > SCP2GPS_BUFF_SIZE)
|
|
count = SCP2GPS_BUFF_SIZE;
|
|
|
|
retval = read_scp2gps_data_test(buf, count);
|
|
|
|
if (retval == -EFAULT)
|
|
goto OUT;
|
|
|
|
OUT:
|
|
up(&rd_mtx_test);
|
|
/* pr_info("GPS_read(): retval = %d\n", retval);*/
|
|
return retval;
|
|
|
|
}
|
|
#endif
|
|
static ssize_t gps2scp_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|
{
|
|
int retval;
|
|
|
|
pr_info("gps2scp read\n");
|
|
down(&rd_mtx);
|
|
|
|
if (count > SCP2GPS_BUFF_SIZE)
|
|
count = SCP2GPS_BUFF_SIZE;
|
|
|
|
retval = read_scp2gps_data(buf, count);
|
|
|
|
if (retval == -EFAULT)
|
|
goto OUT;
|
|
|
|
OUT:
|
|
up(&rd_mtx);
|
|
/* pr_info("GPS_read(): retval = %d\n", retval);*/
|
|
return retval;
|
|
|
|
}
|
|
/******************************************************************************/
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
static ssize_t gps2scp_write_test(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
|
|
{
|
|
int retval;
|
|
int written = 0;
|
|
int msg_id = 1;
|
|
int copy_size = 0;
|
|
|
|
down(&wr_mtx_test);
|
|
pr_info("gps2scp write test\n");
|
|
if (count > 0) {
|
|
copy_size = (count < SCP2GPS_BUFF_SIZE) ? count : SCP2GPS_BUFF_SIZE;
|
|
if (copy_from_user(&o_buf_test[0], &buf[0], copy_size)) {
|
|
retval = -EFAULT;
|
|
pr_info("gps2scp_write copy_from_user failed retval=%d\n", retval);
|
|
goto out;
|
|
}
|
|
} else {
|
|
retval = -EFAULT;
|
|
pr_info("gps2scp_write target packet length:%zd is not allowed, retval = %d.\n", count, retval);
|
|
}
|
|
|
|
written = conap_scp_send_message(DRV_TYPE_GPS, msg_id, &o_buf_test[0], count);
|
|
|
|
if (written == 0) {
|
|
retval = copy_size;
|
|
pr_info("conap_scp_send_message success count= %zd\n", count);
|
|
} else {
|
|
retval = -EFAULT;
|
|
pr_info("conap_scp_send_message failed retval=%d , written=%d\n", retval, written);
|
|
}
|
|
|
|
out:
|
|
up(&wr_mtx_test);
|
|
return retval;
|
|
}
|
|
#endif
|
|
static ssize_t gps2scp_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
|
|
{
|
|
int retval;
|
|
int written = 0;
|
|
int msg_id = 0;
|
|
int copy_size = 0;
|
|
|
|
down(&wr_mtx);
|
|
pr_info("gps2scp write\n");
|
|
if (count > 0) {
|
|
copy_size = (count < SCP2GPS_BUFF_SIZE) ? count : SCP2GPS_BUFF_SIZE;
|
|
if (copy_from_user(&o_buf[0], &buf[0], copy_size)) {
|
|
retval = -EFAULT;
|
|
pr_info("gps2scp_write copy_from_user failed retval=%d\n", retval);
|
|
goto out;
|
|
}
|
|
} else {
|
|
retval = -EFAULT;
|
|
pr_info("gps2scp_write target packet length:%zd is not allowed, retval = %d.\n", count, retval);
|
|
}
|
|
|
|
written = conap_scp_send_message(DRV_TYPE_GPS, msg_id, &o_buf[0], count);
|
|
|
|
if (written == 0) {
|
|
retval = copy_size;
|
|
pr_info("conap_scp_send_message success count= %zd\n", count);
|
|
} else {
|
|
retval = -EFAULT;
|
|
pr_info("conap_scp_send_message failed retval=%d , written=%d\n", retval, written);
|
|
}
|
|
|
|
out:
|
|
up(&wr_mtx);
|
|
return retval;
|
|
}
|
|
/*****************************************************************************/
|
|
static unsigned int gps2scp_poll(struct file *file, poll_table *wait)
|
|
{
|
|
unsigned int mask;
|
|
|
|
mask = 0;
|
|
pr_info("gps2scp_poll has enter\n");
|
|
if (scp2gps_data_received.msg_read != scp2gps_data_received.msg_write) {
|
|
mask = (POLLIN | POLLRDNORM);
|
|
pr_info("gps2scp_poll already have data\n");
|
|
return mask;
|
|
}
|
|
|
|
poll_wait(file, &GPS2SCP_wq, wait);
|
|
|
|
if (scp2gps_data_received.msg_read != scp2gps_data_received.msg_write)
|
|
mask = (POLLIN | POLLRDNORM);
|
|
pr_info("gps2scp_poll been return , mask = %d\n", mask);
|
|
|
|
return mask;
|
|
}
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
static unsigned int gps2scp_test_poll(struct file *file, poll_table *wait)
|
|
{
|
|
unsigned int mask;
|
|
|
|
mask = 0;
|
|
pr_info("gps2scp_test_poll has enter\n");
|
|
if (scp2gps_data_received_test.msg_read != scp2gps_data_received_test.msg_write) {
|
|
mask = (POLLIN | POLLRDNORM);
|
|
pr_info("gps2scp_test_poll already have data\n");
|
|
return mask;
|
|
}
|
|
|
|
poll_wait(file, &GPS2SCP_wq_test, wait);
|
|
|
|
if (scp2gps_data_received_test.msg_read != scp2gps_data_received_test.msg_write)
|
|
mask = (POLLIN | POLLRDNORM);
|
|
|
|
pr_info("gps2scp_test_poll been return , mask = %d\n", mask);
|
|
|
|
return mask;
|
|
}
|
|
#endif
|
|
/* Kernel interface */
|
|
static const struct file_operations gps2scp_fops = {
|
|
.owner = THIS_MODULE,
|
|
.unlocked_ioctl = gps2scp_unlocked_ioctl,
|
|
.compat_ioctl = gps2scp_compat_ioctl,
|
|
.open = gps2scp_open,
|
|
.read = gps2scp_read,
|
|
.write = gps2scp_write,
|
|
.release = gps2scp_close,
|
|
.poll = gps2scp_poll,
|
|
};
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
static const struct file_operations gps2scp_fops_test = {
|
|
.owner = THIS_MODULE,
|
|
.unlocked_ioctl = gps2scp_unlocked_ioctl,
|
|
.compat_ioctl = gps2scp_compat_ioctl,
|
|
.open = gps2scp_open_test,
|
|
.read = gps2scp_read_test,
|
|
.write = gps2scp_write_test,
|
|
.release = gps2scp_close_test,
|
|
.poll = gps2scp_test_poll,
|
|
};
|
|
#endif
|
|
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
static int gps2scp_test_init(void)
|
|
{
|
|
int ret = 0;
|
|
int err = 0;
|
|
|
|
gps2scp_devobj_test = kzalloc(sizeof(*gps2scp_devobj_test), GFP_KERNEL);
|
|
if (gps2scp_devobj_test == NULL) {
|
|
err = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
goto err_out;
|
|
}
|
|
|
|
pr_info("Registering gps2scp test chardev\n");
|
|
ret = alloc_chrdev_region(&gps2scp_devobj_test->devno, 0, 1, GPS2SCP_DEVNAME_TEST);
|
|
if (ret) {
|
|
pr_info("alloc_chrdev_region fail: %d\n", ret);
|
|
err = -ENOMEM;
|
|
goto err_out;
|
|
} else {
|
|
pr_info("major: %d, minor: %d\n", MAJOR(gps2scp_devobj_test->devno), MINOR(gps2scp_devobj_test->devno));
|
|
}
|
|
cdev_init(&gps2scp_devobj_test->chdev, &gps2scp_fops_test);
|
|
gps2scp_devobj_test->chdev.owner = THIS_MODULE;
|
|
err = cdev_add(&gps2scp_devobj_test->chdev, gps2scp_devobj_test->devno, 1);
|
|
if (err) {
|
|
pr_info("cdev_add fail: %d\n", err);
|
|
goto err_out;
|
|
}
|
|
gps2scp_devobj_test->cls = class_create(THIS_MODULE, "gps2scp_test");
|
|
if (IS_ERR(gps2scp_devobj_test->cls)) {
|
|
pr_info("Unable to create class, err = %d\n", (int)PTR_ERR(gps2scp_devobj_test->cls));
|
|
goto err_out;
|
|
}
|
|
/* init_MUTEX(&wr_mtx); */
|
|
sema_init(&wr_mtx_test, 1);
|
|
/* init_MUTEX(&rd_mtx); */
|
|
sema_init(&rd_mtx_test, 1);
|
|
/* init_MUTEX(&ring_buf_mtx); */
|
|
sema_init(&ring_buf_mtx_test, 1);
|
|
init_waitqueue_head(&GPS2SCP_wq_test);
|
|
|
|
memset(&scp2gps_data_received_test, 0, sizeof(scp2gps_data_received_test));
|
|
|
|
gps2scp_devobj_test->dev = device_create(gps2scp_devobj_test->cls, NULL,
|
|
gps2scp_devobj_test->devno, gps2scp_devobj_test, "gps2scp_test");
|
|
pr_info("GPS2SCP test device init Done\n");
|
|
return 0;
|
|
|
|
err_out:
|
|
if (gps2scp_devobj_test != NULL) {
|
|
if (err == 0)
|
|
cdev_del(&gps2scp_devobj_test->chdev);
|
|
if (ret == 0)
|
|
unregister_chrdev_region(gps2scp_devobj_test->devno, 1);
|
|
kfree(gps2scp_devobj_test);
|
|
gps2scp_devobj_test = NULL;
|
|
}
|
|
return -1;
|
|
}
|
|
#endif
|
|
static int gps2scp_init(void)
|
|
{
|
|
int ret = 0;
|
|
int err = 0;
|
|
|
|
gps2scp_devobj = kzalloc(sizeof(*gps2scp_devobj), GFP_KERNEL);
|
|
if (gps2scp_devobj == NULL) {
|
|
err = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
goto err_out;
|
|
}
|
|
|
|
pr_info("Registering gps2scp chardev\n");
|
|
ret = alloc_chrdev_region(&gps2scp_devobj->devno, 0, 1, GPS2SCP_DEVNAME);
|
|
if (ret) {
|
|
pr_info("alloc_chrdev_region fail: %d\n", ret);
|
|
err = -ENOMEM;
|
|
goto err_out;
|
|
} else {
|
|
pr_info("major: %d, minor: %d\n", MAJOR(gps2scp_devobj->devno), MINOR(gps2scp_devobj->devno));
|
|
}
|
|
cdev_init(&gps2scp_devobj->chdev, &gps2scp_fops);
|
|
gps2scp_devobj->chdev.owner = THIS_MODULE;
|
|
err = cdev_add(&gps2scp_devobj->chdev, gps2scp_devobj->devno, 1);
|
|
if (err) {
|
|
pr_info("cdev_add fail: %d\n", err);
|
|
goto err_out;
|
|
}
|
|
gps2scp_devobj->cls = class_create(THIS_MODULE, "gps2scp");
|
|
if (IS_ERR(gps2scp_devobj->cls)) {
|
|
pr_info("Unable to create class, err = %d\n", (int)PTR_ERR(gps2scp_devobj->cls));
|
|
goto err_out;
|
|
}
|
|
/* init_MUTEX(&wr_mtx); */
|
|
sema_init(&wr_mtx, 1);
|
|
/* init_MUTEX(&rd_mtx); */
|
|
sema_init(&rd_mtx, 1);
|
|
/* init_MUTEX(&ring_buf_mtx); */
|
|
sema_init(&ring_buf_mtx, 1);
|
|
init_waitqueue_head(&GPS2SCP_wq);
|
|
|
|
memset(&scp2gps_data_received, 0, sizeof(scp2gps_data_received));
|
|
|
|
gps2scp_devobj->dev = device_create(gps2scp_devobj->cls,
|
|
NULL, gps2scp_devobj->devno, gps2scp_devobj, "gps2scp");
|
|
pr_info("GPS2SCP device init Done\n");
|
|
return 0;
|
|
|
|
err_out:
|
|
if (gps2scp_devobj != NULL) {
|
|
if (err == 0)
|
|
cdev_del(&gps2scp_devobj->chdev);
|
|
if (ret == 0)
|
|
unregister_chrdev_region(gps2scp_devobj->devno, 1);
|
|
kfree(gps2scp_devobj);
|
|
gps2scp_devobj = NULL;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
static void gps2scp_test_exit(void)
|
|
{
|
|
if (!gps2scp_devobj_test) {
|
|
pr_info("null pointer: %p\n", gps2scp_devobj_test);
|
|
return;
|
|
}
|
|
|
|
conap_scp_unregister_drv(DRV_TYPE_GPS);
|
|
|
|
pr_info("Unregistering gps2scp test chardev\n");
|
|
cdev_del(&gps2scp_devobj_test->chdev);
|
|
unregister_chrdev_region(gps2scp_devobj_test->devno, 1);
|
|
device_destroy(gps2scp_devobj_test->cls, gps2scp_devobj_test->devno);
|
|
class_destroy(gps2scp_devobj_test->cls);
|
|
kfree(gps2scp_devobj_test);
|
|
gps2scp_devobj_test = NULL;
|
|
pr_info("Done\n");
|
|
}
|
|
#endif
|
|
static void gps2scp_exit(void)
|
|
{
|
|
if (!gps2scp_devobj) {
|
|
pr_info("null pointer: %p\n", gps2scp_devobj);
|
|
return;
|
|
}
|
|
|
|
conap_scp_unregister_drv(DRV_TYPE_GPS);
|
|
|
|
pr_info("Unregistering gps2scp chardev\n");
|
|
cdev_del(&gps2scp_devobj->chdev);
|
|
unregister_chrdev_region(gps2scp_devobj->devno, 1);
|
|
device_destroy(gps2scp_devobj->cls, gps2scp_devobj->devno);
|
|
class_destroy(gps2scp_devobj->cls);
|
|
kfree(gps2scp_devobj);
|
|
gps2scp_devobj = NULL;
|
|
pr_info("Done\n");
|
|
}
|
|
|
|
int mtk_gps2scp_init(void)
|
|
{
|
|
pr_info("gps2scp init begin");
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
pr_info("gps2scp_test init begin");
|
|
gps2scp_test_init();
|
|
#endif
|
|
return gps2scp_init();
|
|
}
|
|
|
|
void mtk_gps2scp_exit(void)
|
|
{
|
|
pr_info("gps2scp exit begin");
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
pr_info("gps2scp_test exit begin");
|
|
gps2scp_exit();
|
|
#endif
|
|
return gps2scp_exit();
|
|
}
|
|
#ifdef GPS2SCP_TEST_ENABLE
|
|
int mtk_gps2scp_test_init(void)
|
|
{
|
|
pr_info("gps2scp init begin");
|
|
return gps2scp_test_init();
|
|
}
|
|
|
|
void mtk_gps2scp_test_exit(void)
|
|
{
|
|
pr_info("gps2scp exit begin");
|
|
return gps2scp_test_exit();
|
|
}
|
|
#endif
|
|
/*****************************************************************************/
|
|
module_init(mtk_gps2scp_init);
|
|
module_exit(mtk_gps2scp_exit);
|
|
/*****************************************************************************/
|
|
MODULE_AUTHOR("Tianfang li <Tianfang.Li@mediatek.com>");
|
|
MODULE_DESCRIPTION("GPS2SCP stp dev");
|
|
MODULE_LICENSE("GPL");
|
|
|
|
|