summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiddartha Mohanadoss <smohanad@codeaurora.org>2015-08-22 12:52:14 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:16:05 -0700
commit75003eedd686fc44afb740b47c789bde72d644b6 (patch)
tree770f44b2892ace40b8d599d73dcdd027d6d5ccb0
parent4318bd3cd61a656e5e0654d63c58886b70e64d12 (diff)
thermal: tsens: Modify tsens_poll
Add support to log the last 10 instances when the tsens monitoring threshold test gets to run and handles completion interrupt or in polling mode. In addition clear the status before enabling the interrupt mask for threshold monitoring and reduce the timed wait completion during polling mode. Change-Id: I75a376b209f15d33cdfe3e43806db0f0cf45538e Signed-off-by: Siddartha Mohanadoss <smohanad@codeaurora.org>
-rw-r--r--drivers/thermal/msm-tsens.c111
1 files changed, 82 insertions, 29 deletions
diff --git a/drivers/thermal/msm-tsens.c b/drivers/thermal/msm-tsens.c
index 9d7f697960bf..ed5fd1fe8ce3 100644
--- a/drivers/thermal/msm-tsens.c
+++ b/drivers/thermal/msm-tsens.c
@@ -708,8 +708,9 @@
/* debug defines */
#define TSENS_DBG_BUS_ID_0 0
#define TSENS_DBG_BUS_ID_1 1
+#define TSENS_DBG_BUS_ID_2 2
#define TSENS_DBG_BUS_ID_15 15
-#define TSENS_DEBUG_LOOP_COUNT_ID_0 30
+#define TSENS_DEBUG_LOOP_COUNT_ID_0 2
#define TSENS_DEBUG_LOOP_COUNT 5
#define TSENS_DEBUG_STATUS_REG_START 10
#define TSENS_DEBUG_OFFSET_RANGE 16
@@ -720,10 +721,14 @@
#define TSENS_DEBUG_DECIDEGC -400
#define TSENS_DEBUG_MIN_CYCLE 63000
#define TSENS_DEBUG_MAX_CYCLE 64000
+#define TSENS_DEBUG_POLL_MIN 200000
+#define TSENS_DEBUG_POLL_MAX 210000
+#define TSENS_DEBUG_BUS_ID2_MIN_CYCLE 50
+#define TSENS_DEBUG_BUS_ID2_MAX_CYCLE 51
#define TSENS_DEBUG_ID_MASK_1_4 0xffffffe1
-static uint32_t tsens_sec_to_msec_value = 3000;
-static uint32_t tsens_completion_timeout_hz = 2 * HZ;
+static uint32_t tsens_sec_to_msec_value = 1000;
+static uint32_t tsens_completion_timeout_hz = HZ/2;
static uint32_t tsens_poll_check = 1;
enum tsens_calib_fuse_map_type {
@@ -850,12 +855,13 @@ struct tsens_tm_device {
spinlock_t tsens_crit_lock;
spinlock_t tsens_upp_low_lock;
bool crit_set;
- unsigned long long crit_timestamp_last_run;
- unsigned long long crit_timestamp_last_interrupt_handled;
- unsigned long long crit_timestamp_last_poll_request;
+ struct tsens_dbg_counter crit_timestamp_last_run;
+ struct tsens_dbg_counter crit_timestamp_last_interrupt_handled;
+ struct tsens_dbg_counter crit_timestamp_last_poll_request;
u64 qtimer_val_detection_start;
u64 qtimer_val_last_detection_interrupt;
u64 qtimer_val_last_polling_check;
+ bool tsens_critical_poll;
struct tsens_tm_device_sensor sensor[0];
};
@@ -1945,8 +1951,8 @@ static void tsens_poll(struct work_struct *work)
struct tsens_tm_device *tmdev = container_of(work,
struct tsens_tm_device, tsens_critical_poll_test.work);
unsigned int reg_cntl, mask, rc = 0, debug_dump, i = 0, loop = 0;
- unsigned int debug_id = 0;
- uint32_t r1, r2, r3, r4, offset = 0;
+ unsigned int debug_id = 0, cntrl_id = 0;
+ uint32_t r1, r2, r3, r4, offset = 0, idx = 0;
unsigned long temp, flags;
unsigned int status, int_mask, int_mask_val;
void __iomem *srot_addr;
@@ -1979,17 +1985,51 @@ static void tsens_poll(struct work_struct *work)
(TSENS_TM_SN_CRITICAL_THRESHOLD(tmdev->tsens_addr) +
(mask * TSENS_SN_ADDR_OFFSET)));
- tmdev->crit_timestamp_last_run = sched_clock();
- tmdev->qtimer_val_detection_start = arch_counter_get_cntvct();
+ /* debug */
+ idx = tmdev->crit_timestamp_last_run.idx;
+ tmdev->crit_timestamp_last_run.time_stmp[idx%10] = sched_clock();
+ tmdev->crit_timestamp_last_run.idx++;
+ tmdev->qtimer_val_detection_start = arch_counter_get_cntpct();
spin_lock_irqsave(&tmdev->tsens_crit_lock, flags);
+ /* Clear the sensor0 critical status */
+ int_mask_val = 1;
+ writel_relaxed(int_mask_val,
+ TSENS_TM_CRITICAL_INT_CLEAR(tmdev->tsens_addr));
+ writel_relaxed(0,
+ TSENS_TM_CRITICAL_INT_CLEAR(
+ tmdev->tsens_addr));
+ /* Clear the status */
+ mb();
tmdev->crit_set = true;
- reg_cntl = readl_relaxed(TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_addr));
- writel_relaxed(reg_cntl & ~(1 << mask),
+ if (!tmdev->tsens_critical_poll) {
+ reg_cntl = readl_relaxed(
+ TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_addr));
+ writel_relaxed(reg_cntl & ~(1 << mask),
(TSENS_TM_CRITICAL_INT_MASK
(tmdev->tsens_addr)));
+ /* Enable the critical int mask */
+ mb();
+ }
spin_unlock_irqrestore(&tmdev->tsens_crit_lock, flags);
+ if (tmdev->tsens_critical_poll) {
+ usleep_range(TSENS_DEBUG_POLL_MIN,
+ TSENS_DEBUG_POLL_MAX);
+ sensor_status_addr = TSENS_TM_SN_STATUS(tmdev->tsens_addr);
+
+ spin_lock_irqsave(&tmdev->tsens_crit_lock, flags);
+ status = readl_relaxed(sensor_status_addr);
+ spin_unlock_irqrestore(&tmdev->tsens_crit_lock, flags);
+
+ if (status & TSENS_TM_SN_STATUS_CRITICAL_STATUS)
+ goto re_schedule;
+ else {
+ pr_err("status:0x%x\n", status);
+ goto debug_start;
+ }
+ }
+
rc = wait_for_completion_timeout(
&tmdev->tsens_rslt_completion,
tsens_completion_timeout_hz);
@@ -2012,7 +2052,10 @@ static void tsens_poll(struct work_struct *work)
tmdev->crit_set = false;
spin_unlock_irqrestore(&tmdev->tsens_crit_lock, flags);
- tmdev->crit_timestamp_last_poll_request = sched_clock();
+ idx = tmdev->crit_timestamp_last_poll_request.idx;
+ tmdev->crit_timestamp_last_poll_request.time_stmp[idx%10] =
+ sched_clock();
+ tmdev->crit_timestamp_last_poll_request.idx++;
tmdev->qtimer_val_last_polling_check =
arch_counter_get_cntvct();
if (status & TSENS_TM_SN_STATUS_CRITICAL_STATUS) {
@@ -2032,11 +2075,14 @@ static void tsens_poll(struct work_struct *work)
tmdev->tsens_addr));
spin_unlock_irqrestore(&tmdev->tsens_crit_lock, flags);
+ /* Clear critical status */
+ mb();
goto re_schedule;
}
- debug_dump = readl_relaxed(controller_id_addr);
- pr_err("Controller_id: 0x%x\n", debug_dump);
+debug_start:
+ cntrl_id = readl_relaxed(controller_id_addr);
+ pr_err("Controller_id: 0x%x\n", cntrl_id);
loop = 0;
i = 0;
@@ -2049,8 +2095,8 @@ static void tsens_poll(struct work_struct *work)
r2 = readl_relaxed(debug_data_addr);
r3 = readl_relaxed(debug_data_addr);
r4 = readl_relaxed(debug_data_addr);
- pr_err("bus-id:%d value:0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
- i, debug_dump, r1, r2, r3, r4);
+ pr_err("cntrl:%d, bus-id:%d value:0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
+ cntrl_id, i, debug_dump, r1, r2, r3, r4);
loop++;
}
@@ -2062,8 +2108,12 @@ static void tsens_poll(struct work_struct *work)
TSENS_DEBUG_CONTROL(tmdev->tsens_addr));
while (loop < TSENS_DEBUG_LOOP_COUNT) {
debug_dump = readl_relaxed(debug_data_addr);
- pr_err("bus-id:%d with value: 0x%x\n",
- i, debug_dump);
+ pr_err("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,
+ TSENS_DEBUG_BUS_ID2_MAX_CYCLE);
loop++;
}
}
@@ -2078,8 +2128,8 @@ static void tsens_poll(struct work_struct *work)
r4 = readl_relaxed(controller_id_addr + (offset +
TSENS_DEBUG_OFFSET_WORD3));
- pr_err("0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- offset, r1, r2, r3, r4);
+ pr_err("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;
}
@@ -2094,8 +2144,8 @@ static void tsens_poll(struct work_struct *work)
r4 = readl_relaxed(srot_addr + (offset +
TSENS_DEBUG_OFFSET_WORD3));
- pr_err("0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- offset, r1, r2, r3, r4);
+ pr_err("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;
}
@@ -2114,15 +2164,14 @@ static void tsens_poll(struct work_struct *work)
r4 = readl_relaxed(controller_id_addr +
(offset + TSENS_DEBUG_OFFSET_WORD3));
- pr_err("0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- offset, r1, r2, r3, r4);
+ pr_err("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++;
usleep_range(TSENS_DEBUG_MIN_CYCLE,
TSENS_DEBUG_MAX_CYCLE);
}
-
BUG();
}
@@ -2326,7 +2375,7 @@ static struct thermal_zone_device_ops tsens_tm_thermal_zone_ops = {
static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
{
struct tsens_tm_device *tm = data;
- unsigned int i, status;
+ unsigned int i, status, idx = 0;
unsigned long flags;
void __iomem *sensor_status_addr;
void __iomem *sensor_int_mask_addr;
@@ -2388,8 +2437,11 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
}
}
- tm->crit_timestamp_last_interrupt_handled = sched_clock();
- tm->qtimer_val_last_detection_interrupt = arch_counter_get_cntvct();
+ idx = tm->crit_timestamp_last_interrupt_handled.idx;
+ tm->crit_timestamp_last_interrupt_handled.dbg_count[idx%10]++;
+ tm->crit_timestamp_last_interrupt_handled.time_stmp[idx%10] =
+ sched_clock();
+ tm->qtimer_val_last_detection_interrupt = arch_counter_get_cntpct();
complete(&tm->tsens_rslt_completion);
/* Mask critical interrupt */
@@ -5702,6 +5754,7 @@ static int tsens_thermal_zone_register(struct tsens_tm_device *tmdev)
schedule_delayed_work(&tmdev->tsens_critical_poll_test,
msecs_to_jiffies(tsens_sec_to_msec_value));
init_completion(&tmdev->tsens_rslt_completion);
+ tmdev->tsens_critical_poll = true;
}
} else {
rc = request_threaded_irq(tmdev->tsens_irq, NULL,