summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRama Krishna Phani A <rphani@codeaurora.org>2016-12-15 19:48:44 +0530
committerRama Krishna Phani A <rphani@codeaurora.org>2016-12-21 10:41:51 +0530
commit74e699a210d3ad1ddee1b65d8020bcf3cdcb08fb (patch)
treedc3921c6aa96f293fce1cbfd227b26881fd9c3f4
parente9a8a791daa5f3b662aafbd8b433b1594a12aae8 (diff)
thermal: tsens: Update critical interrupt functionality for Tsens
Critical interrupt can also get triggerred by FSM health monitoring logic. Add support to handle this case as well. Program cycle completion monitoring logic registers. Change-Id: Ibf74e3cbdb8a7b54cfb93334de6992eda553e7e5 Signed-off-by: Rama Krishna Phani A <rphani@codeaurora.org>
-rw-r--r--drivers/thermal/msm-tsens.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/thermal/msm-tsens.c b/drivers/thermal/msm-tsens.c
index 0a9e561268b6..243b3229f53e 100644
--- a/drivers/thermal/msm-tsens.c
+++ b/drivers/thermal/msm-tsens.c
@@ -84,6 +84,8 @@
/* TSENS_TM registers for 8996 */
#define TSENS_TM_INT_EN(n) ((n) + 0x1004)
+#define TSENS_TM_CRITICAL_WD_BARK BIT(31)
+#define TSENS_TM_CRITICAL_CYCLE_MONITOR BIT(30)
#define TSENS_TM_CRITICAL_INT_EN BIT(2)
#define TSENS_TM_UPPER_INT_EN BIT(1)
#define TSENS_TM_LOWER_INT_EN BIT(0)
@@ -854,6 +856,7 @@ struct tsens_tm_device {
int tsens_upper_irq_cnt;
int tsens_lower_irq_cnt;
int tsens_critical_irq_cnt;
+ int tsens_critical_wd_cnt;
struct delayed_work tsens_critical_poll_test;
struct completion tsens_rslt_completion;
struct tsens_mtc_sysfs mtcsys;
@@ -2398,7 +2401,9 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
void __iomem *sensor_status_addr;
void __iomem *sensor_int_mask_addr;
void __iomem *sensor_critical_addr;
+ void __iomem *wd_critical_addr;
int sensor_sw_id = -EINVAL, rc = 0;
+ int wd_mask;
tm->crit_set = false;
sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_addr);
@@ -2406,6 +2411,30 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
TSENS_TM_CRITICAL_INT_MASK(tm->tsens_addr);
sensor_critical_addr =
TSENS_TM_SN_CRITICAL_THRESHOLD(tm->tsens_addr);
+ wd_critical_addr =
+ TSENS_TM_CRITICAL_INT_STATUS(tm->tsens_addr);
+
+ if (tm->wd_bark) {
+ wd_mask = readl_relaxed(wd_critical_addr);
+ /*
+ * Check whether the reason for critical interrupt is
+ * because of watchdog
+ */
+ if (wd_mask & TSENS_TM_CRITICAL_WD_BARK) {
+ /*
+ * Clear watchdog interrupt and
+ * increment global wd count
+ */
+ writel_relaxed(wd_mask | TSENS_TM_CRITICAL_WD_BARK,
+ (TSENS_TM_CRITICAL_INT_CLEAR
+ (tm->tsens_addr)));
+ writel_relaxed(wd_mask & ~(TSENS_TM_CRITICAL_WD_BARK),
+ (TSENS_TM_CRITICAL_INT_CLEAR
+ (tm->tsens_addr)));
+ tm->tsens_critical_wd_cnt++;
+ return IRQ_HANDLED;
+ }
+ }
for (i = 0; i < tm->tsens_num_sensor; i++) {
bool critical_thr = false;
@@ -2670,7 +2699,9 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
static int tsens_hw_init(struct tsens_tm_device *tmdev)
{
void __iomem *srot_addr;
+ void __iomem *sensor_int_mask_addr;
unsigned int srot_val;
+ int crit_mask;
if (!tmdev) {
pr_err("Invalid tsens device\n");
@@ -2684,6 +2715,18 @@ static int tsens_hw_init(struct tsens_tm_device *tmdev)
pr_err("TSENS device is not enabled\n");
return -ENODEV;
}
+
+ if (tmdev->cycle_compltn_monitor) {
+ sensor_int_mask_addr =
+ TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_addr);
+ crit_mask = readl_relaxed(sensor_int_mask_addr);
+ writel_relaxed(
+ crit_mask | tmdev->cycle_compltn_monitor_val,
+ (TSENS_TM_CRITICAL_INT_MASK
+ (tmdev->tsens_addr)));
+ /*Update critical cycle monitoring*/
+ mb();
+ }
writel_relaxed(TSENS_TM_CRITICAL_INT_EN |
TSENS_TM_UPPER_INT_EN | TSENS_TM_LOWER_INT_EN,
TSENS_TM_INT_EN(tmdev->tsens_addr));