exynos-linux-stable/drivers/sensorhub/brcm/ssp_debug.c
2023-02-21 00:24:41 +03:00

633 lines
19 KiB
C

/*
* Copyright (C) 2012, Samsung Electronics Co. Ltd. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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.
*
*/
#include "ssp.h"
#include <linux/fs.h>
#include <linux/sec_debug.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#define SSP_DEBUG_TIMER_SEC (5 * HZ)
#define LIMIT_RESET_CNT 40
#define LIMIT_TIMEOUT_CNT 3
#define DUMP_FILE_PATH "/data/log/MCU_DUMP"
void ssp_dump_task(struct work_struct *work)
{
#ifdef CONFIG_SENSORS_SSP_BBD
pr_err("[SSPBBD]:TODO:%s()\n", __func__);
#else
struct ssp_big *big;
struct file *dump_file;
struct ssp_msg *msg;
char *buffer;
char strFilePath[60];
struct timeval cur_time;
int iTimeTemp;
mm_segment_t fs;
int buf_len, packet_len, residue;
int index = 0, iRetTrans = 0, iRetWrite = 0;
big = container_of(work, struct ssp_big, work);
pr_err("[SSP]: %s - start ssp dumping (%d)(%d)\n",
__func__, big->data->bMcuDumpMode, big->data->uDumpCnt);
big->data->uDumpCnt++;
wake_lock(&big->data->ssp_wake_lock);
fs = get_fs();
set_fs(get_ds());
if (big->data->bMcuDumpMode == true) {
do_gettimeofday(&cur_time);
iTimeTemp = (int) cur_time.tv_sec;
sprintf(strFilePath, "%s%d.txt", DUMP_FILE_PATH, iTimeTemp);
dump_file = filp_open(strFilePath,
O_RDWR|O_CREAT|O_APPEND, 0660);
if (IS_ERR(dump_file)) {
pr_err("[SSP]: %s - Can't open dump file\n", __func__);
set_fs(fs);
iRet = PTR_ERR(dump_file);
wake_unlock(&big->data->ssp_wake_lock);
kfree(big);
return;
}
} else
dump_file = NULL;
buf_len = (big->length > DATA_PACKET_SIZE) ?
DATA_PACKET_SIZE : big->length;
buffer = kzalloc(buf_len, GFP_KERNEL);
residue = big->length;
while (residue > 0) {
packet_len = residue > DATA_PACKET_SIZE ?
DATA_PACKET_SIZE : residue;
msg = kzalloc(sizeof(*msg), GFP_KERNEL);
msg->cmd = MSG2SSP_AP_GET_BIG_DATA;
msg->length = packet_len;
msg->options = AP2HUB_READ | (index++ << SSP_INDEX);
msg->data = big->addr;
msg->buffer = buffer;
msg->free_buffer = 0;
iRetTrans = ssp_spi_sync(big->data, msg, 1000);
if (iRetTrans != SUCCESS) {
pr_err("[SSP]: %s - Fail to receive data %d (%d)\n",
__func__, iRetTrans, residue);
break;
}
if (big->data->bMcuDumpMode == true) {
iRetWrite = vfs_write(dump_file,
(char __user *) buffer,
packet_len,
&dump_file->f_pos);
if (iRetWrite < 0) {
pr_err("[SSP] %s Can't write dump to file\n",
__func__);
break;
}
}
residue -= packet_len;
}
if (big->data->bMcuDumpMode == true &&
(iRetTrans != SUCCESS || iRetWrite < 0)) {
char FAILSTRING[100];
sprintf(FAILSTRING, "FAIL OCCURRED(%d)(%d)(%d)",
iRetTrans,
iRetWrite,
big->length);
vfs_write(dump_file, (char __user *) FAILSTRING,
strlen(FAILSTRING),
&dump_file->f_pos);
}
big->data->bDumping = false;
if (big->data->bMcuDumpMode == true)
filp_close(dump_file, current->files);
set_fs(fs);
wake_unlock(&big->data->ssp_wake_lock);
kfree(buffer);
kfree(big);
pr_err("[SSP]: %s done\n", __func__);
#endif
}
void ssp_temp_task(struct work_struct *work)
{
#ifdef CONFIG_SENSORS_SSP_BBD
pr_err("[SSPBBD]:TODO:%s()\n", __func__);
#else
struct ssp_big *big;
struct ssp_msg *msg;
char *buffer;
int buf_len, packet_len, residue;
int iRet = 0, index = 0, i = 0, buffindex = 0;
big = container_of(work, struct ssp_big, work);
buf_len = big->length > DATA_PACKET_SIZE ?
DATA_PACKET_SIZE : big->length;
buffer = kzalloc(buf_len, GFP_KERNEL);
residue = big->length;
#ifdef CONFIG_SENSORS_SSP_SHTC1
mutex_lock(&big->data->bulk_temp_read_lock);
if (big->data->bulk_buffer == NULL)
big->data->bulk_buffer = kzalloc(sizeof(struct shtc1_buffer),
GFP_KERNEL);
big->data->bulk_buffer->len = big->length / 12;
#endif
while (residue > 0) {
packet_len = (residue > DATA_PACKET_SIZE) ?
DATA_PACKET_SIZE : residue;
msg = kzalloc(sizeof(*msg), GFP_KERNEL);
msg->cmd = MSG2SSP_AP_GET_BIG_DATA;
msg->length = packet_len;
msg->options = AP2HUB_READ | (index++ << SSP_INDEX);
msg->data = big->addr;
msg->buffer = buffer;
msg->free_buffer = 0;
iRet = ssp_spi_sync(big->data, msg, 1000);
if (iRet != SUCCESS) {
pr_err("[SSP]: %s - Fail to receive data %d\n",
__func__, iRet);
break;
}
/* 12 = 1 chunk size for ks79.shin
* order is thermistor Bat, thermistor PA, Temp,
* Humidity, Baro, Gyro
* each data consist of 2bytes
*/
i = 0;
while (packet_len - i >= 12) {
ssp_dbg("[SSP]: %s %d %d %d %d %d %d", __func__,
*((s16 *) (buffer + i + 0)), *((s16 *) (buffer + i + 2)),
*((s16 *) (buffer + i + 4)), *((s16 *) (buffer + i + 6)),
*((s16 *) (buffer + i + 8)), *((s16 *) (buffer + i + 10)));
#ifdef CONFIG_SENSORS_SSP_SHTC1
big->data->bulk_buffer->batt[buffindex] = *((u16 *) (buffer + i + 0));
big->data->bulk_buffer->chg[buffindex] = *((u16 *) (buffer + i + 2));
big->data->bulk_buffer->temp[buffindex] = *((s16 *) (buffer + i + 4));
big->data->bulk_buffer->humidity[buffindex] = *((u16 *) (buffer + i + 6));
big->data->bulk_buffer->baro[buffindex] = *((s16 *) (buffer + i + 8));
big->data->bulk_buffer->gyro[buffindex] = *((s16 *) (buffer + i + 10));
buffindex++;
i += 12;
#else
buffindex++;
i += 12;/* 6 ?? */
#endif
}
residue -= packet_len;
}
#ifdef CONFIG_SENSORS_SSP_SHTC1
if (iRet == SUCCESS)
report_bulk_comp_data(big->data);
mutex_unlock(&big->data->bulk_temp_read_lock);
#endif
kfree(buffer);
kfree(big);
ssp_dbg("[SSP]: %s done\n", __func__);
#endif
}
/*************************************************************************/
/* SSP Debug timer function */
/*************************************************************************/
int print_mcu_debug(char *pchRcvDataFrame, int *pDataIdx,
int iRcvDataFrameLength)
{
int iLength = 0;
#if SSP_DBG
int cur = *pDataIdx;
#endif
memcpy(&iLength, pchRcvDataFrame + *pDataIdx, sizeof(u16));
*pDataIdx += sizeof(u16);
if (iLength > iRcvDataFrameLength - *pDataIdx || iLength <= 0) {
ssp_dbg("[SSP]: MSG From MCU - invalid debug length(%d/%d/%d)\n",
iLength, iRcvDataFrameLength, cur);
return iLength ? iLength : ERROR;
}
ssp_dbg("[SSP]: MSG From MCU - %s\n", &pchRcvDataFrame[*pDataIdx]);
*pDataIdx += iLength;
return 0;
}
void reset_mcu(struct ssp_data *data)
{
func_dbg();
ssp_enable(data, false);
clean_pending_list(data);
bbd_mcu_reset(false);
data->uTimeOutCnt = 0;
data->uComFailCnt = 0;
data->mcuAbnormal = false;
}
void sync_sensor_state(struct ssp_data *data)
{
unsigned char uBuf[9] = {0,};
unsigned int uSensorCnt;
int iRet = 0;
gyro_open_calibration(data);
iRet = set_gyro_cal(data);
if (iRet < 0)
pr_err("[SSP]: %s - set_gyro_cal failed\n", __func__);
iRet = set_accel_cal(data);
if (iRet < 0)
pr_err("[SSP]: %s - set_accel_cal failed\n", __func__);
#ifdef CONFIG_SENSORS_SSP_SX9306
if (atomic64_read(&data->aSensorEnable) & (1 << GRIP_SENSOR)) {
open_grip_caldata(data);
set_grip_calibration(data, true);
}
#endif
udelay(10);
for (uSensorCnt = 0; uSensorCnt < SENSOR_MAX; uSensorCnt++) {
mutex_lock(&data->enable_mutex);
if (atomic64_read(&data->aSensorEnable) & (1ULL << uSensorCnt)) {
s32 dMsDelay =
get_msdelay(data->adDelayBuf[uSensorCnt]);
memcpy(&uBuf[0], &dMsDelay, 4);
memcpy(&uBuf[4], &data->batchLatencyBuf[uSensorCnt], 4);
uBuf[8] = data->batchOptBuf[uSensorCnt];
send_instruction(data, ADD_SENSOR, uSensorCnt, uBuf, 9);
udelay(10);
}
mutex_unlock(&data->enable_mutex);
}
if (atomic64_read(&data->aSensorEnable) & (1ULL << GYROSCOPE_SENSOR))
send_vdis_flag(data, data->IsVDIS_Enabled);
if (data->bProximityRawEnabled == true) {
s32 dMsDelay = 20;
memcpy(&uBuf[0], &dMsDelay, 4);
send_instruction(data, ADD_SENSOR, PROXIMITY_RAW, uBuf, 4);
}
set_proximity_threshold(data);
set_light_coef(data);
data->bMcuDumpMode = ssp_check_sec_dump_mode();
iRet = ssp_send_cmd(data, MSG2SSP_AP_MCU_SET_DUMPMODE,
data->bMcuDumpMode);
if (iRet < 0)
pr_err("[SSP]: %s - MSG2SSP_AP_MCU_SET_DUMPMODE failed\n",
__func__);
}
static void print_sensordata(struct ssp_data *data, unsigned int uSensor)
{
switch (uSensor) {
case ACCELEROMETER_SENSOR:
ssp_dbg("[SSP] %u : %d, %d, %d (%ums, %dms)\n", uSensor,
data->buf[uSensor].x, data->buf[uSensor].y,
data->buf[uSensor].z,
get_msdelay(data->adDelayBuf[uSensor]),
data->batchLatencyBuf[uSensor]);
break;
case GYROSCOPE_SENSOR:
#ifdef CONFIG_SENSORS_SSP_INTERRUPT_GYRO_SENSOR
case INTERRUPT_GYRO_SENSOR:
#endif
ssp_dbg("[SSP] %u : %d, %d, %d (%ums, %dms)\n", uSensor,
data->buf[uSensor].gyro.x, data->buf[uSensor].gyro.y,
data->buf[uSensor].gyro.z,
get_msdelay(data->adDelayBuf[uSensor]),
data->batchLatencyBuf[uSensor]);
break;
case GEOMAGNETIC_SENSOR:
ssp_dbg("[SSP] %u : %d, %d, %d, %d (%ums)\n", uSensor,
data->buf[uSensor].cal_x, data->buf[uSensor].cal_y,
data->buf[uSensor].cal_z, data->buf[uSensor].accuracy,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case GEOMAGNETIC_UNCALIB_SENSOR:
ssp_dbg("[SSP] %u : %d, %d, %d, %d, %d, %d (%ums)\n",
uSensor,
data->buf[uSensor].uncal_x,
data->buf[uSensor].uncal_y,
data->buf[uSensor].uncal_z,
data->buf[uSensor].offset_x,
data->buf[uSensor].offset_y,
data->buf[uSensor].offset_z,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case PRESSURE_SENSOR:
ssp_dbg("[SSP] %u : %d, %d (%ums, %dms)\n", uSensor,
data->buf[uSensor].pressure,
data->buf[uSensor].temperature,
get_msdelay(data->adDelayBuf[uSensor]),
data->batchLatencyBuf[uSensor]);
break;
case GESTURE_SENSOR:
ssp_dbg("[SSP] %u : %d, %d, %d, %d (%ums)\n", uSensor,
data->buf[uSensor].data[3], data->buf[uSensor].data[4],
data->buf[uSensor].data[5], data->buf[uSensor].data[6],
get_msdelay(data->adDelayBuf[uSensor]));
break;
case TEMPERATURE_HUMIDITY_SENSOR:
ssp_dbg("[SSP] %u : %d, %d, %d (%ums)\n", uSensor,
data->buf[uSensor].x, data->buf[uSensor].y,
data->buf[uSensor].z,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case LIGHT_SENSOR:
case UNCAL_LIGHT_SENSOR:
ssp_dbg("[SSP] %u : %u, %u, %u, %u, %u, %u (%ums)\n", uSensor,
data->buf[uSensor].r, data->buf[uSensor].g,
data->buf[uSensor].b, data->buf[uSensor].w,
data->buf[uSensor].a_time, data->buf[uSensor].a_gain,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case LIGHT_FLICKER_SENSOR:
ssp_dbg("[SSP] %u : %u, (%ums)\n", uSensor,
data->buf[uSensor].light_flicker, get_msdelay(data->adDelayBuf[uSensor]));
break;
case LIGHT_CCT_SENSOR:
ssp_dbg("[SSP] %u : %u, %u, %u, %u, %u, %u (%ums)\n", uSensor,
data->buf[uSensor].r, data->buf[uSensor].g,
data->buf[uSensor].b, data->buf[uSensor].w,
data->buf[uSensor].a_time, data->buf[uSensor].a_gain,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case PROXIMITY_SENSOR:
ssp_dbg("[SSP] %u : %d, %d (%ums)\n", uSensor,
data->buf[uSensor].prox_detect, data->buf[uSensor].prox_adc,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case PROXIMITY_POCKET:
ssp_dbg("[SSP] %u : %d, %d (%ums)\n", uSensor,
data->buf[uSensor].proximity_pocket_detect, data->buf[uSensor].proximity_pocket_adc,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case PROXIMITY_ALERT_SENSOR:
ssp_dbg("[SSP] %u : %d, %d (%ums)\n", uSensor,
data->buf[uSensor].prox_alert_detect, data->buf[uSensor].prox_alert_adc,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case STEP_DETECTOR:
ssp_dbg("[SSP] %u : %u (%ums, %dms)\n", uSensor,
data->buf[uSensor].step_det,
get_msdelay(data->adDelayBuf[uSensor]),
data->batchLatencyBuf[uSensor]);
break;
case GAME_ROTATION_VECTOR:
case ROTATION_VECTOR:
ssp_dbg("[SSP] %u : %d, %d, %d, %d, %d (%ums, %dms)\n", uSensor,
data->buf[uSensor].quat_a, data->buf[uSensor].quat_b,
data->buf[uSensor].quat_c, data->buf[uSensor].quat_d,
data->buf[uSensor].acc_rot,
get_msdelay(data->adDelayBuf[uSensor]),
data->batchLatencyBuf[uSensor]);
break;
case SIG_MOTION_SENSOR:
ssp_dbg("[SSP] %u : %u(%ums)\n", uSensor,
data->buf[uSensor].sig_motion,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case GYRO_UNCALIB_SENSOR:
ssp_dbg("[SSP] %u : %d, %d, %d, %d, %d, %d (%ums)\n", uSensor,
data->buf[uSensor].uncal_gyro.x, data->buf[uSensor].uncal_gyro.y,
data->buf[uSensor].uncal_gyro.z, data->buf[uSensor].uncal_gyro.offset_x,
data->buf[uSensor].uncal_gyro.offset_y,
data->buf[uSensor].uncal_gyro.offset_z,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case STEP_COUNTER:
ssp_dbg("[SSP] %u : %u(%ums)\n", uSensor,
data->buf[uSensor].step_diff,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case LIGHT_IR_SENSOR:
ssp_dbg("[SSP] %u : %u, %u, %u, %u, %u, %u, %u (%ums)\n", uSensor,
data->buf[uSensor].irdata,
data->buf[uSensor].ir_r, data->buf[uSensor].ir_g,
data->buf[uSensor].ir_b, data->buf[uSensor].ir_w,
data->buf[uSensor].ir_a_time, data->buf[uSensor].ir_a_gain,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case TILT_DETECTOR:
ssp_dbg("[SSP] %u : %u(%ums)\n", uSensor,
data->buf[uSensor].tilt_detector,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case PICKUP_GESTURE:
ssp_dbg("[SSP] %u : %u(%ums)\n", uSensor,
data->buf[uSensor].pickup_gesture,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case THERMISTOR_SENSOR:
ssp_dbg("[SSP] %u : %u %u (%ums)\n", uSensor,
data->buf[uSensor].thermistor_type,
data->buf[uSensor].thermistor_raw,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case ACCEL_UNCALIB_SENSOR:
ssp_dbg("[SSP] %u : %d, %d, %d, %d, %d, %d (%ums)\n", uSensor,
data->buf[uSensor].uncal_x, data->buf[uSensor].uncal_y,
data->buf[uSensor].uncal_z, data->buf[uSensor].offset_x,
data->buf[uSensor].offset_y,
data->buf[uSensor].offset_z,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case WAKE_UP_MOTION:
ssp_dbg("[SSP] %u : %d (%ums)\n", uSensor,
data->buf[uSensor].wakeup_motion,
get_msdelay(data->adDelayBuf[uSensor]));
case CALL_GESTURE:
ssp_dbg("[SSP] %u : %d (%ums)\n", uSensor,
data->buf[uSensor].call_gesture,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case MOVE_DETECTOR:
ssp_dbg("[SSP] %u : %d (%ums)\n", uSensor,
data->buf[uSensor].move_detect,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case LED_COVER_EVENT_SENSOR:
ssp_dbg("[SSP] %u : %d (%ums)\n", uSensor,
data->buf[uSensor].led_cover_event,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case AUTO_ROTATION_SENSOR:
ssp_dbg("[SSP] %u : %d (%ums)\n", uSensor,
data->buf[uSensor].auto_rotation_event,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case SAR_BACKOFF_MOTION:
ssp_dbg("[SSP] %u : %d (%ums)\n", uSensor,
data->buf[uSensor].sar_backoff_motion_event,
get_msdelay(data->adDelayBuf[uSensor]));
case POCKET_MODE_LITE:
ssp_dbg("[SSP] %u : %d %d(%ums)\n", uSensor,
data->buf[uSensor].pocket_mode_lite_t.prox,
data->buf[uSensor].pocket_mode_lite_t.lux,
get_msdelay(data->adDelayBuf[uSensor]));
break;
case BULK_SENSOR:
case GPS_SENSOR:
break;
default:
ssp_dbg("[SSP] Wrong sensorCnt: %u\n", uSensor);
break;
}
}
/*
*check_sensor_event
*- return
* true : there is no accel or light sensor event over 5sec when sensor is registered
*/
bool check_wait_event(struct ssp_data *data)
{
u64 timestamp = get_current_timestamp();
int check_sensors[2] = {ACCELEROMETER_SENSOR, LIGHT_SENSOR};
int i, sensor;
bool res = false;
int arrSize = (ANDROID_VERSION < 90000 ? 2 : 1);
for (i = 0 ; i < arrSize ; i++) { // because light sensor does not check anymore
sensor = check_sensors[i];
//the sensor is registered
if ((atomic64_read(&data->aSensorEnable) & (1 << sensor) && !(data->IsGyroselftest))
//non batching mode
&& data->IsBypassMode[sensor] == 1
//there is no sensor event over 3sec
&& data->LastSensorTimeforReset[sensor] + 7000000000ULL < timestamp) {
pr_info("[SSP] %s - sensor(%d) last = %lld, cur = %lld\n",
__func__, sensor, data->LastSensorTimeforReset[sensor], timestamp);
res = true;
data->uNoRespSensorCnt++;
}
//pr_info("[SSP]test %s - sensor(%d mode %d) last = %lld, cur = %lld\n",
//__func__,sensor,data->IsBypassMode[sensor],data->LastSensorTimeforReset[sensor],timestamp);
}
return res;
}
static void debug_work_func(struct work_struct *work)
{
unsigned int uSensorCnt;
struct ssp_data *data = container_of(work, struct ssp_data, work_debug);
ssp_dbg("[SSP]: %s(%u) - Sensor state: 0x%llx, RC: %u(%u, %u, %u), CC: %u, TC: %u NSC: %u EC: %u GPS: %s\n",
__func__, data->uIrqCnt, data->uSensorState, data->uResetCnt, data->mcuCrashedCnt, data->IsNoRespCnt,
data->resetCntGPSisOn, data->uComFailCnt, data->uTimeOutCnt, data->uNoRespSensorCnt, data->errorCount,
data->IsGpsWorking ? "true" : "false");
if(!strstr("", data->resetInfoDebug))
pr_info("[SSP]: %s(%lld, %lld)\n", data->resetInfoDebug, data->resetInfoDebugTime, get_current_timestamp());
for (uSensorCnt = 0; uSensorCnt < SENSOR_MAX; uSensorCnt++) {
if ((atomic64_read(&data->aSensorEnable) & (1ULL << uSensorCnt))
|| data->batchLatencyBuf[uSensorCnt]) {
print_sensordata(data, uSensorCnt);
if (data->indio_dev[uSensorCnt] != NULL
&& list_empty(&data->indio_dev[uSensorCnt]->buffer->buffer_list)) {
pr_err("[SSP] %u : buffer_list of iio:device%d is empty!\n",
uSensorCnt, data->indio_dev[uSensorCnt]->id);
}
}
}
if (data->resetting)
goto exit;
if (((atomic64_read(&data->aSensorEnable) & (1 << ACCELEROMETER_SENSOR))
&& (data->batchLatencyBuf[ACCELEROMETER_SENSOR] == 0)
&& (data->uIrqCnt == 0) && (data->uTimeOutCnt > 0))
|| (data->uTimeOutCnt > LIMIT_TIMEOUT_CNT)
|| (check_wait_event(data))
|| (data->mcuAbnormal == true)) {
mutex_lock(&data->ssp_enable_mutex);
pr_info("[SSP] : %s - uTimeOutCnt(%u), pending(%u)\n",
__func__, data->uTimeOutCnt,
!list_empty(&data->pending_list));
reset_mcu(data);
mutex_unlock(&data->ssp_enable_mutex);
}
exit:
data->uIrqCnt = 0;
}
static void debug_timer_func(unsigned long ptr)
{
struct ssp_data *data = (struct ssp_data *)ptr;
queue_work(data->debug_wq, &data->work_debug);
mod_timer(&data->debug_timer,
round_jiffies_up(jiffies + SSP_DEBUG_TIMER_SEC));
}
void enable_debug_timer(struct ssp_data *data)
{
mod_timer(&data->debug_timer,
round_jiffies_up(jiffies + SSP_DEBUG_TIMER_SEC));
}
void disable_debug_timer(struct ssp_data *data)
{
del_timer_sync(&data->debug_timer);
cancel_work_sync(&data->work_debug);
}
int initialize_debug_timer(struct ssp_data *data)
{
setup_timer(&data->debug_timer, debug_timer_func, (unsigned long)data);
data->debug_wq = create_singlethread_workqueue("ssp_debug_wq");
if (!data->debug_wq)
return ERROR;
INIT_WORK(&data->work_debug, debug_work_func);
return SUCCESS;
}
/* if returns true dump mode on */
unsigned int ssp_check_sec_dump_mode(void)
{
#if 0 /* def CONFIG_SEC_DEBUG */
if (sec_debug_level.en.kernel_fault == 1)
return 1;
else
return 0;
#endif
return 0;
}