thermal: tsens: Add IPC logging support for TSENS
Add IPC logging support for TSENS. Dump all TSENS registers into IPC when TSENS reset occurs without recovery by self-reset. Change-Id: I379a521ffd2a65a87bd69b6ef37c71b779345183 Signed-off-by: Jishnu Prakash <jprakash@codeaurora.org>
This commit is contained in:
parent
6e9f8d3097
commit
684df7009f
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
@ -157,6 +157,8 @@ static int get_device_tree_data(struct platform_device *pdev,
|
||||
return PTR_ERR(tmdev->tsens_tm_addr);
|
||||
}
|
||||
|
||||
tmdev->phys_addr_tm = res_tsens_mem->start;
|
||||
|
||||
/* TSENS eeprom register region */
|
||||
res_tsens_mem = platform_get_resource_byname(pdev,
|
||||
IORESOURCE_MEM, "tsens_eeprom_physical");
|
||||
@ -224,6 +226,7 @@ int tsens_tm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tsens_device *tmdev = NULL;
|
||||
int rc;
|
||||
char tsens_name[40];
|
||||
|
||||
if (!(pdev->dev.of_node))
|
||||
return -ENODEV;
|
||||
@ -260,6 +263,33 @@ int tsens_tm_probe(struct platform_device *pdev)
|
||||
return rc;
|
||||
}
|
||||
|
||||
snprintf(tsens_name, sizeof(tsens_name), "tsens_%pa_0",
|
||||
&tmdev->phys_addr_tm);
|
||||
|
||||
tmdev->ipc_log0 = ipc_log_context_create(IPC_LOGPAGES,
|
||||
tsens_name, 0);
|
||||
if (!tmdev->ipc_log0)
|
||||
pr_err("%s : unable to create IPC Logging 0 for tsens %pa\n",
|
||||
__func__, &tmdev->phys_addr_tm);
|
||||
|
||||
snprintf(tsens_name, sizeof(tsens_name), "tsens_%pa_1",
|
||||
&tmdev->phys_addr_tm);
|
||||
|
||||
tmdev->ipc_log1 = ipc_log_context_create(IPC_LOGPAGES,
|
||||
tsens_name, 0);
|
||||
if (!tmdev->ipc_log1)
|
||||
pr_err("%s : unable to create IPC Logging 1 for tsens %pa\n",
|
||||
__func__, &tmdev->phys_addr_tm);
|
||||
|
||||
snprintf(tsens_name, sizeof(tsens_name), "tsens_%pa_2",
|
||||
&tmdev->phys_addr_tm);
|
||||
|
||||
tmdev->ipc_log2 = ipc_log_context_create(IPC_LOGPAGES,
|
||||
tsens_name, 0);
|
||||
if (!tmdev->ipc_log2)
|
||||
pr_err("%s : unable to create IPC Logging 2 for tsens %pa\n",
|
||||
__func__, &tmdev->phys_addr_tm);
|
||||
|
||||
list_add_tail(&tmdev->list, &tsens_device_list);
|
||||
platform_set_drvdata(pdev, tmdev);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <asm/arch_timer.h>
|
||||
@ -244,6 +244,8 @@ static int tsens_dbg_log_temp_reads(struct tsens_device *data, u32 id,
|
||||
idx++;
|
||||
tmdev->tsens_dbg.sensor_dbg_info[sensor->hw_id].idx = idx;
|
||||
|
||||
TSENS_DBG(tmdev, "Sensor_id: %d temp: %d\n", id, *temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -291,7 +293,7 @@ static int tsens_dbg_log_bus_id_data(struct tsens_device *data,
|
||||
srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr);
|
||||
|
||||
cntrl_id = readl_relaxed(controller_id_addr);
|
||||
pr_err("Controller_id: 0x%x\n", cntrl_id);
|
||||
TSENS_DUMP(tmdev, "TSENS Controller_id: 0x%x\n", cntrl_id);
|
||||
|
||||
loop = 0;
|
||||
i = 0;
|
||||
@ -304,8 +306,11 @@ static int tsens_dbg_log_bus_id_data(struct tsens_device *data,
|
||||
r2 = readl_relaxed(debug_data_addr);
|
||||
r3 = readl_relaxed(debug_data_addr);
|
||||
r4 = readl_relaxed(debug_data_addr);
|
||||
pr_err("cntrl:%d, bus-id:%d value:0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
|
||||
|
||||
TSENS_DUMP(tmdev,
|
||||
"ctl:%d, bus-id:%d val:0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
|
||||
cntrl_id, i, debug_dump, r1, r2, r3, r4);
|
||||
|
||||
loop++;
|
||||
}
|
||||
|
||||
@ -317,8 +322,9 @@ static int tsens_dbg_log_bus_id_data(struct tsens_device *data,
|
||||
TSENS_DEBUG_CONTROL(tmdev->tsens_tm_addr));
|
||||
while (loop < TSENS_DEBUG_LOOP_COUNT) {
|
||||
debug_dump = readl_relaxed(debug_data_addr);
|
||||
pr_err("cntrl:%d, bus-id:%d with value: 0x%x\n",
|
||||
cntrl_id, i, debug_dump);
|
||||
TSENS_DUMP(tmdev,
|
||||
"cntrl:%d, bus-id:%d with value: 0x%x\n",
|
||||
cntrl_id, i, debug_dump);
|
||||
if (i == TSENS_DBG_BUS_ID_2)
|
||||
usleep_range(
|
||||
TSENS_DEBUG_BUS_ID2_MIN_CYCLE,
|
||||
@ -327,7 +333,9 @@ static int tsens_dbg_log_bus_id_data(struct tsens_device *data,
|
||||
}
|
||||
}
|
||||
|
||||
pr_err("Start of TSENS TM dump\n");
|
||||
TSENS_DUMP(tmdev, "Start of TSENS TM dump for ctr 0x%x\n",
|
||||
cntrl_id);
|
||||
|
||||
for (i = 0; i < TSENS_DEBUG_OFFSET_RANGE; i++) {
|
||||
r1 = readl_relaxed(controller_id_addr + offset);
|
||||
r2 = readl_relaxed(controller_id_addr + (offset +
|
||||
@ -337,13 +345,16 @@ static int tsens_dbg_log_bus_id_data(struct tsens_device *data,
|
||||
r4 = readl_relaxed(controller_id_addr + (offset +
|
||||
TSENS_DEBUG_OFFSET_WORD3));
|
||||
|
||||
pr_err("ctrl:%d:0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
cntrl_id, offset, r1, r2, r3, r4);
|
||||
TSENS_DUMP(tmdev,
|
||||
"ctrl:%d:0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
cntrl_id, offset, r1, r2, r3, r4);
|
||||
|
||||
offset += TSENS_DEBUG_OFFSET_ROW;
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
pr_err("Start of TSENS SROT dump\n");
|
||||
TSENS_DUMP(tmdev, "Start of TSENS SROT dump for ctr 0x%x\n",
|
||||
cntrl_id);
|
||||
for (i = 0; i < TSENS_DEBUG_OFFSET_RANGE; i++) {
|
||||
r1 = readl_relaxed(srot_addr + offset);
|
||||
r2 = readl_relaxed(srot_addr + (offset +
|
||||
@ -353,8 +364,9 @@ static int tsens_dbg_log_bus_id_data(struct tsens_device *data,
|
||||
r4 = readl_relaxed(srot_addr + (offset +
|
||||
TSENS_DEBUG_OFFSET_WORD3));
|
||||
|
||||
pr_err("ctrl:%d:0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
cntrl_id, offset, r1, r2, r3, r4);
|
||||
TSENS_DUMP(tmdev,
|
||||
"ctrl:%d:0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
cntrl_id, offset, r1, r2, r3, r4);
|
||||
offset += TSENS_DEBUG_OFFSET_ROW;
|
||||
}
|
||||
|
||||
@ -362,7 +374,8 @@ static int tsens_dbg_log_bus_id_data(struct tsens_device *data,
|
||||
while (loop < TSENS_DEBUG_LOOP_COUNT) {
|
||||
offset = TSENS_DEBUG_OFFSET_ROW *
|
||||
TSENS_DEBUG_STATUS_REG_START;
|
||||
pr_err("Start of TSENS TM dump %d\n", loop);
|
||||
TSENS_DUMP(tmdev, "Start of TSENS TM dump %d\n",
|
||||
loop);
|
||||
/* Limited dump of the registers for the temperature */
|
||||
for (i = 0; i < TSENS_DEBUG_LOOP_COUNT; i++) {
|
||||
r1 = readl_relaxed(controller_id_addr + offset);
|
||||
@ -373,8 +386,9 @@ static int tsens_dbg_log_bus_id_data(struct tsens_device *data,
|
||||
r4 = readl_relaxed(controller_id_addr +
|
||||
(offset + TSENS_DEBUG_OFFSET_WORD3));
|
||||
|
||||
pr_err("ctrl:%d:0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
cntrl_id, offset, r1, r2, r3, r4);
|
||||
TSENS_DUMP(tmdev,
|
||||
"ctrl:%d:0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
cntrl_id, offset, r1, r2, r3, r4);
|
||||
offset += TSENS_DEBUG_OFFSET_ROW;
|
||||
}
|
||||
loop++;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __QCOM_TSENS_H__
|
||||
@ -13,6 +13,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ipc_logging.h>
|
||||
|
||||
#define DEBUG_SIZE 10
|
||||
#define TSENS_MAX_SENSORS 16
|
||||
@ -29,6 +30,8 @@
|
||||
#define SLOPE_FACTOR 1000
|
||||
#define SLOPE_DEFAULT 3200
|
||||
|
||||
#define IPC_LOGPAGES 10
|
||||
|
||||
enum tsens_dbg_type {
|
||||
TSENS_DBG_POLL,
|
||||
TSENS_DBG_LOG_TEMP_READS,
|
||||
@ -42,6 +45,54 @@ enum tsens_dbg_type {
|
||||
|
||||
struct tsens_device;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#define TSENS_IPC(idx, dev, msg, args...) do { \
|
||||
if (dev) { \
|
||||
if ((idx == 0) && (dev)->ipc_log0) \
|
||||
ipc_log_string((dev)->ipc_log0, \
|
||||
"%s: " msg, __func__, args); \
|
||||
else if ((idx == 1) && (dev)->ipc_log1) \
|
||||
ipc_log_string((dev)->ipc_log1, \
|
||||
"%s: " msg, __func__, args); \
|
||||
else if ((idx == 2) && (dev)->ipc_log2) \
|
||||
ipc_log_string((dev)->ipc_log2, \
|
||||
"%s: " msg, __func__, args); \
|
||||
else \
|
||||
pr_debug("tsens: invalid logging index\n"); \
|
||||
} \
|
||||
} while (0)
|
||||
#define TSENS_DUMP(dev, msg, args...) do { \
|
||||
TSENS_IPC(2, dev, msg, args); \
|
||||
pr_info(msg, ##args); \
|
||||
} while (0)
|
||||
#define TSENS_ERR(dev, msg, args...) do { \
|
||||
pr_err(msg, ##args); \
|
||||
TSENS_IPC(1, dev, msg, args); \
|
||||
} while (0)
|
||||
#define TSENS_INFO(dev, msg, args...) do { \
|
||||
pr_info(msg, ##args); \
|
||||
TSENS_IPC(1, dev, msg, args); \
|
||||
} while (0)
|
||||
#define TSENS_DBG(dev, msg, args...) do { \
|
||||
pr_debug(msg, ##args); \
|
||||
if (dev) { \
|
||||
TSENS_IPC(0, dev, msg, args); \
|
||||
} \
|
||||
} while (0)
|
||||
#define TSENS_DBG1(dev, msg, args...) do { \
|
||||
pr_debug(msg, ##args); \
|
||||
if (dev) { \
|
||||
TSENS_IPC(1, dev, msg, args); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define TSENS_DBG1(x...) pr_debug(x)
|
||||
#define TSENS_DBG(x...) pr_debug(x)
|
||||
#define TSENS_INFO(x...) pr_info(x)
|
||||
#define TSENS_ERR(x...) pr_err(x)
|
||||
#define TSENS_DUMP(x...) pr_info(x)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_THERMAL_TSENS)
|
||||
int tsens2xxx_dbg(struct tsens_device *data, u32 id, u32 dbg_type, int *temp);
|
||||
#else
|
||||
@ -147,11 +198,16 @@ struct tsens_device {
|
||||
void __iomem *tsens_tm_addr;
|
||||
void __iomem *tsens_calib_addr;
|
||||
const struct tsens_ops *ops;
|
||||
void *ipc_log0;
|
||||
void *ipc_log1;
|
||||
void *ipc_log2;
|
||||
phys_addr_t phys_addr_tm;
|
||||
struct tsens_dbg_context tsens_dbg;
|
||||
spinlock_t tsens_crit_lock;
|
||||
spinlock_t tsens_upp_low_lock;
|
||||
const struct tsens_data *ctrl_data;
|
||||
struct tsens_mtc_sysfs mtcsys;
|
||||
int trdy_fail_ctr;
|
||||
struct tsens_sensor sensor[0];
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -88,10 +88,22 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
|
||||
code = readl_relaxed_no_log(trdy);
|
||||
if (!((code & TSENS_TM_TRDY_FIRST_ROUND_COMPLETE) >>
|
||||
TSENS_TM_TRDY_FIRST_ROUND_COMPLETE_SHIFT)) {
|
||||
pr_err("TSENS device first round not complete0x%x\n", code);
|
||||
pr_err("tsens device first round not complete0x%x, ctr is %d\n",
|
||||
code, tmdev->trdy_fail_ctr);
|
||||
tmdev->trdy_fail_ctr++;
|
||||
|
||||
if (tmdev->trdy_fail_ctr >= 50) {
|
||||
if (tmdev->ops->dbg)
|
||||
tmdev->ops->dbg(tmdev, 0,
|
||||
TSENS_DBG_LOG_BUS_ID_DATA, NULL);
|
||||
BUG();
|
||||
}
|
||||
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
tmdev->trdy_fail_ctr = 0;
|
||||
|
||||
code = readl_relaxed_no_log(sensor_addr +
|
||||
(sensor->hw_id << TSENS_STATUS_ADDR_OFFSET));
|
||||
last_temp = code & TSENS_TM_SN_LAST_TEMP_MASK;
|
||||
|
Loading…
Reference in New Issue
Block a user