tsens2xxx.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include <linux/module.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/slab.h>
  16. #include <linux/err.h>
  17. #include <linux/of.h>
  18. #include <linux/vmalloc.h>
  19. #include "tsens.h"
  20. #include "thermal_core.h"
  21. #define TSENS_DRIVER_NAME "msm-tsens"
  22. #define TSENS_TM_INT_EN(n) ((n) + 0x4)
  23. #define TSENS_TM_CRITICAL_INT_STATUS(n) ((n) + 0x14)
  24. #define TSENS_TM_CRITICAL_INT_CLEAR(n) ((n) + 0x18)
  25. #define TSENS_TM_CRITICAL_INT_MASK(n) ((n) + 0x1c)
  26. #define TSENS_TM_CRITICAL_WD_BARK BIT(31)
  27. #define TSENS_TM_CRITICAL_CYCLE_MONITOR BIT(30)
  28. #define TSENS_TM_CRITICAL_INT_EN BIT(2)
  29. #define TSENS_TM_UPPER_INT_EN BIT(1)
  30. #define TSENS_TM_LOWER_INT_EN BIT(0)
  31. #define TSENS_TM_UPPER_LOWER_INT_DISABLE 0xffffffff
  32. #define TSENS_TM_SN_UPPER_LOWER_THRESHOLD(n) ((n) + 0x20)
  33. #define TSENS_TM_SN_ADDR_OFFSET 0x4
  34. #define TSENS_TM_UPPER_THRESHOLD_SET(n) ((n) << 12)
  35. #define TSENS_TM_UPPER_THRESHOLD_VALUE_SHIFT(n) ((n) >> 12)
  36. #define TSENS_TM_LOWER_THRESHOLD_VALUE(n) ((n) & 0xfff)
  37. #define TSENS_TM_UPPER_THRESHOLD_VALUE(n) (((n) & 0xfff000) >> 12)
  38. #define TSENS_TM_UPPER_THRESHOLD_MASK 0xfff000
  39. #define TSENS_TM_LOWER_THRESHOLD_MASK 0xfff
  40. #define TSENS_TM_UPPER_THRESHOLD_SHIFT 12
  41. #define TSENS_TM_SN_CRITICAL_THRESHOLD(n) ((n) + 0x60)
  42. #define TSENS_STATUS_ADDR_OFFSET 2
  43. #define TSENS_TM_UPPER_INT_MASK(n) (((n) & 0xffff0000) >> 16)
  44. #define TSENS_TM_LOWER_INT_MASK(n) ((n) & 0xffff)
  45. #define TSENS_TM_UPPER_LOWER_INT_STATUS(n) ((n) + 0x8)
  46. #define TSENS_TM_UPPER_LOWER_INT_CLEAR(n) ((n) + 0xc)
  47. #define TSENS_TM_UPPER_LOWER_INT_MASK(n) ((n) + 0x10)
  48. #define TSENS_TM_UPPER_INT_SET(n) (1 << (n + 16))
  49. #define TSENS_TM_SN_CRITICAL_THRESHOLD_MASK 0xfff
  50. #define TSENS_TM_SN_STATUS_VALID_BIT BIT(21)
  51. #define TSENS_TM_SN_STATUS_CRITICAL_STATUS BIT(19)
  52. #define TSENS_TM_SN_STATUS_UPPER_STATUS BIT(18)
  53. #define TSENS_TM_SN_STATUS_LOWER_STATUS BIT(17)
  54. #define TSENS_TM_SN_LAST_TEMP_MASK 0xfff
  55. #define TSENS_TM_CODE_BIT_MASK 0xfff
  56. #define TSENS_TM_CODE_SIGN_BIT 0x800
  57. #define TSENS_TM_SCALE_DECI_MILLIDEG 100
  58. #define TSENS_DEBUG_WDOG_TRIGGER_COUNT 5
  59. #define TSENS_TM_WATCHDOG_LOG(n) ((n) + 0x13c)
  60. #define TSENS_EN BIT(0)
  61. #define TSENS_CTRL_SENSOR_EN_MASK(n) ((n >> 3) & 0xffff)
  62. #define TSENS_TM_TRDY(n) ((n) + 0xe4)
  63. #define TSENS_TM_TRDY_FIRST_ROUND_COMPLETE BIT(3)
  64. #define TSENS_TM_TRDY_FIRST_ROUND_COMPLETE_SHIFT 3
  65. static void msm_tsens_convert_temp(int last_temp, int *temp)
  66. {
  67. int code_mask = ~TSENS_TM_CODE_BIT_MASK;
  68. if (last_temp & TSENS_TM_CODE_SIGN_BIT) {
  69. /* Sign extension for negative value */
  70. last_temp |= code_mask;
  71. }
  72. *temp = last_temp * TSENS_TM_SCALE_DECI_MILLIDEG;
  73. }
  74. static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
  75. {
  76. struct tsens_device *tmdev = NULL;
  77. unsigned int code;
  78. void __iomem *sensor_addr, *trdy;
  79. int last_temp = 0, last_temp2 = 0, last_temp3 = 0;
  80. if (!sensor)
  81. return -EINVAL;
  82. tmdev = sensor->tmdev;
  83. sensor_addr = TSENS_TM_SN_STATUS(tmdev->tsens_tm_addr);
  84. trdy = TSENS_TM_TRDY(tmdev->tsens_tm_addr);
  85. code = readl_relaxed_no_log(trdy);
  86. if (!((code & TSENS_TM_TRDY_FIRST_ROUND_COMPLETE) >>
  87. TSENS_TM_TRDY_FIRST_ROUND_COMPLETE_SHIFT)) {
  88. pr_err("TSENS device first round not complete0x%x\n", code);
  89. return -ENODATA;
  90. }
  91. code = readl_relaxed_no_log(sensor_addr +
  92. (sensor->hw_id << TSENS_STATUS_ADDR_OFFSET));
  93. last_temp = code & TSENS_TM_SN_LAST_TEMP_MASK;
  94. if (code & TSENS_TM_SN_STATUS_VALID_BIT) {
  95. msm_tsens_convert_temp(last_temp, temp);
  96. goto dbg;
  97. }
  98. code = readl_relaxed_no_log(sensor_addr +
  99. (sensor->hw_id << TSENS_STATUS_ADDR_OFFSET));
  100. last_temp2 = code & TSENS_TM_SN_LAST_TEMP_MASK;
  101. if (code & TSENS_TM_SN_STATUS_VALID_BIT) {
  102. last_temp = last_temp2;
  103. msm_tsens_convert_temp(last_temp, temp);
  104. goto dbg;
  105. }
  106. code = readl_relaxed_no_log(sensor_addr +
  107. (sensor->hw_id <<
  108. TSENS_STATUS_ADDR_OFFSET));
  109. last_temp3 = code & TSENS_TM_SN_LAST_TEMP_MASK;
  110. if (code & TSENS_TM_SN_STATUS_VALID_BIT) {
  111. last_temp = last_temp3;
  112. msm_tsens_convert_temp(last_temp, temp);
  113. goto dbg;
  114. }
  115. if (last_temp == last_temp2)
  116. last_temp = last_temp2;
  117. else if (last_temp2 == last_temp3)
  118. last_temp = last_temp3;
  119. msm_tsens_convert_temp(last_temp, temp);
  120. dbg:
  121. if (tmdev->ops->dbg)
  122. tmdev->ops->dbg(tmdev, (u32) sensor->hw_id,
  123. TSENS_DBG_LOG_TEMP_READS, temp);
  124. return 0;
  125. }
  126. static int tsens_tm_activate_trip_type(struct tsens_sensor *tm_sensor,
  127. int trip, enum thermal_trip_activation_mode mode)
  128. {
  129. struct tsens_device *tmdev = NULL;
  130. unsigned int reg_cntl, mask;
  131. int rc = 0;
  132. /* clear the interrupt and unmask */
  133. if (!tm_sensor || trip < 0)
  134. return -EINVAL;
  135. tmdev = tm_sensor->tmdev;
  136. if (!tmdev)
  137. return -EINVAL;
  138. mask = (tm_sensor->hw_id);
  139. switch (trip) {
  140. case THERMAL_TRIP_CRITICAL:
  141. tmdev->sensor[tm_sensor->hw_id].
  142. thr_state.crit_th_state = mode;
  143. reg_cntl = readl_relaxed(TSENS_TM_CRITICAL_INT_MASK
  144. (tmdev->tsens_tm_addr));
  145. if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
  146. writel_relaxed(reg_cntl | (1 << mask),
  147. (TSENS_TM_CRITICAL_INT_MASK
  148. (tmdev->tsens_tm_addr)));
  149. else
  150. writel_relaxed(reg_cntl & ~(1 << mask),
  151. (TSENS_TM_CRITICAL_INT_MASK
  152. (tmdev->tsens_tm_addr)));
  153. break;
  154. case THERMAL_TRIP_CONFIGURABLE_HI:
  155. tmdev->sensor[tm_sensor->hw_id].
  156. thr_state.high_th_state = mode;
  157. reg_cntl = readl_relaxed(TSENS_TM_UPPER_LOWER_INT_MASK
  158. (tmdev->tsens_tm_addr));
  159. if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
  160. writel_relaxed(reg_cntl |
  161. (TSENS_TM_UPPER_INT_SET(mask)),
  162. (TSENS_TM_UPPER_LOWER_INT_MASK
  163. (tmdev->tsens_tm_addr)));
  164. else
  165. writel_relaxed(reg_cntl &
  166. ~(TSENS_TM_UPPER_INT_SET(mask)),
  167. (TSENS_TM_UPPER_LOWER_INT_MASK
  168. (tmdev->tsens_tm_addr)));
  169. break;
  170. case THERMAL_TRIP_CONFIGURABLE_LOW:
  171. tmdev->sensor[tm_sensor->hw_id].
  172. thr_state.low_th_state = mode;
  173. reg_cntl = readl_relaxed(TSENS_TM_UPPER_LOWER_INT_MASK
  174. (tmdev->tsens_tm_addr));
  175. if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
  176. writel_relaxed(reg_cntl | (1 << mask),
  177. (TSENS_TM_UPPER_LOWER_INT_MASK
  178. (tmdev->tsens_tm_addr)));
  179. else
  180. writel_relaxed(reg_cntl & ~(1 << mask),
  181. (TSENS_TM_UPPER_LOWER_INT_MASK
  182. (tmdev->tsens_tm_addr)));
  183. break;
  184. default:
  185. rc = -EINVAL;
  186. }
  187. /* Activate and enable the respective trip threshold setting */
  188. mb();
  189. return rc;
  190. }
  191. static int tsens2xxx_set_trip_temp(struct tsens_sensor *tm_sensor,
  192. int low_temp, int high_temp)
  193. {
  194. unsigned int reg_cntl;
  195. unsigned long flags;
  196. struct tsens_device *tmdev = NULL;
  197. int rc = 0;
  198. if (!tm_sensor)
  199. return -EINVAL;
  200. tmdev = tm_sensor->tmdev;
  201. if (!tmdev)
  202. return -EINVAL;
  203. spin_lock_irqsave(&tmdev->tsens_upp_low_lock, flags);
  204. if (high_temp != INT_MAX) {
  205. tmdev->sensor[tm_sensor->hw_id].
  206. thr_state.high_temp = high_temp;
  207. reg_cntl = readl_relaxed((TSENS_TM_SN_UPPER_LOWER_THRESHOLD
  208. (tmdev->tsens_tm_addr)) +
  209. (tm_sensor->hw_id *
  210. TSENS_TM_SN_ADDR_OFFSET));
  211. high_temp /= TSENS_TM_SCALE_DECI_MILLIDEG;
  212. high_temp = TSENS_TM_UPPER_THRESHOLD_SET(high_temp);
  213. high_temp &= TSENS_TM_UPPER_THRESHOLD_MASK;
  214. reg_cntl &= ~TSENS_TM_UPPER_THRESHOLD_MASK;
  215. writel_relaxed(reg_cntl | high_temp,
  216. (TSENS_TM_SN_UPPER_LOWER_THRESHOLD
  217. (tmdev->tsens_tm_addr) +
  218. (tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
  219. }
  220. if (low_temp != INT_MIN) {
  221. tmdev->sensor[tm_sensor->hw_id].
  222. thr_state.low_temp = low_temp;
  223. reg_cntl = readl_relaxed((TSENS_TM_SN_UPPER_LOWER_THRESHOLD
  224. (tmdev->tsens_tm_addr)) +
  225. (tm_sensor->hw_id *
  226. TSENS_TM_SN_ADDR_OFFSET));
  227. low_temp /= TSENS_TM_SCALE_DECI_MILLIDEG;
  228. low_temp &= TSENS_TM_LOWER_THRESHOLD_MASK;
  229. reg_cntl &= ~TSENS_TM_LOWER_THRESHOLD_MASK;
  230. writel_relaxed(reg_cntl | low_temp,
  231. (TSENS_TM_SN_UPPER_LOWER_THRESHOLD
  232. (tmdev->tsens_tm_addr) +
  233. (tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
  234. }
  235. /* Set trip temperature thresholds */
  236. mb();
  237. if (high_temp != INT_MAX) {
  238. rc = tsens_tm_activate_trip_type(tm_sensor,
  239. THERMAL_TRIP_CONFIGURABLE_HI,
  240. THERMAL_TRIP_ACTIVATION_ENABLED);
  241. if (rc) {
  242. pr_err("trip high enable error :%d\n", rc);
  243. goto fail;
  244. }
  245. } else {
  246. rc = tsens_tm_activate_trip_type(tm_sensor,
  247. THERMAL_TRIP_CONFIGURABLE_HI,
  248. THERMAL_TRIP_ACTIVATION_DISABLED);
  249. if (rc) {
  250. pr_err("trip high disable error :%d\n", rc);
  251. goto fail;
  252. }
  253. }
  254. if (low_temp != INT_MIN) {
  255. rc = tsens_tm_activate_trip_type(tm_sensor,
  256. THERMAL_TRIP_CONFIGURABLE_LOW,
  257. THERMAL_TRIP_ACTIVATION_ENABLED);
  258. if (rc) {
  259. pr_err("trip low enable activation error :%d\n", rc);
  260. goto fail;
  261. }
  262. } else {
  263. rc = tsens_tm_activate_trip_type(tm_sensor,
  264. THERMAL_TRIP_CONFIGURABLE_LOW,
  265. THERMAL_TRIP_ACTIVATION_DISABLED);
  266. if (rc) {
  267. pr_err("trip low disable error :%d\n", rc);
  268. goto fail;
  269. }
  270. }
  271. fail:
  272. spin_unlock_irqrestore(&tmdev->tsens_upp_low_lock, flags);
  273. return rc;
  274. }
  275. static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
  276. {
  277. struct tsens_device *tm = data;
  278. unsigned int i, status, wd_log, wd_mask;
  279. unsigned long flags;
  280. void __iomem *sensor_status_addr, *sensor_int_mask_addr;
  281. void __iomem *sensor_critical_addr;
  282. void __iomem *wd_critical_addr, *wd_log_addr;
  283. sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_tm_addr);
  284. sensor_int_mask_addr =
  285. TSENS_TM_CRITICAL_INT_MASK(tm->tsens_tm_addr);
  286. sensor_critical_addr =
  287. TSENS_TM_SN_CRITICAL_THRESHOLD(tm->tsens_tm_addr);
  288. wd_critical_addr =
  289. TSENS_TM_CRITICAL_INT_STATUS(tm->tsens_tm_addr);
  290. wd_log_addr = TSENS_TM_WATCHDOG_LOG(tm->tsens_tm_addr);
  291. if (tm->ctrl_data->wd_bark) {
  292. wd_mask = readl_relaxed(wd_critical_addr);
  293. if (wd_mask & TSENS_TM_CRITICAL_WD_BARK) {
  294. /*
  295. * Clear watchdog interrupt and
  296. * increment global wd count
  297. */
  298. writel_relaxed(wd_mask | TSENS_TM_CRITICAL_WD_BARK,
  299. (TSENS_TM_CRITICAL_INT_CLEAR
  300. (tm->tsens_tm_addr)));
  301. writel_relaxed(wd_mask & ~(TSENS_TM_CRITICAL_WD_BARK),
  302. (TSENS_TM_CRITICAL_INT_CLEAR
  303. (tm->tsens_tm_addr)));
  304. wd_log = readl_relaxed(wd_log_addr);
  305. if (wd_log >= TSENS_DEBUG_WDOG_TRIGGER_COUNT) {
  306. pr_err("Watchdog count:%d\n", wd_log);
  307. if (tm->ops->dbg)
  308. tm->ops->dbg(tm, 0,
  309. TSENS_DBG_LOG_BUS_ID_DATA, NULL);
  310. BUG();
  311. }
  312. return IRQ_HANDLED;
  313. }
  314. }
  315. for (i = 0; i < TSENS_MAX_SENSORS; i++) {
  316. int int_mask, int_mask_val;
  317. u32 addr_offset;
  318. if (IS_ERR(tm->sensor[i].tzd))
  319. continue;
  320. spin_lock_irqsave(&tm->tsens_crit_lock, flags);
  321. addr_offset = tm->sensor[i].hw_id *
  322. TSENS_TM_SN_ADDR_OFFSET;
  323. status = readl_relaxed(sensor_status_addr + addr_offset);
  324. int_mask = readl_relaxed(sensor_int_mask_addr);
  325. if ((status & TSENS_TM_SN_STATUS_CRITICAL_STATUS) &&
  326. !(int_mask & (1 << tm->sensor[i].hw_id))) {
  327. int_mask = readl_relaxed(sensor_int_mask_addr);
  328. int_mask_val = (1 << tm->sensor[i].hw_id);
  329. /* Mask the corresponding interrupt for the sensors */
  330. writel_relaxed(int_mask | int_mask_val,
  331. TSENS_TM_CRITICAL_INT_MASK(
  332. tm->tsens_tm_addr));
  333. /* Clear the corresponding sensors interrupt */
  334. writel_relaxed(int_mask_val,
  335. TSENS_TM_CRITICAL_INT_CLEAR
  336. (tm->tsens_tm_addr));
  337. writel_relaxed(0,
  338. TSENS_TM_CRITICAL_INT_CLEAR(
  339. tm->tsens_tm_addr));
  340. tm->sensor[i].thr_state.
  341. crit_th_state = THERMAL_DEVICE_DISABLED;
  342. }
  343. spin_unlock_irqrestore(&tm->tsens_crit_lock, flags);
  344. }
  345. /* Mask critical interrupt */
  346. mb();
  347. return IRQ_HANDLED;
  348. }
  349. static irqreturn_t tsens_tm_irq_thread(int irq, void *data)
  350. {
  351. struct tsens_device *tm = data;
  352. unsigned int i, status, threshold, temp;
  353. unsigned long flags;
  354. void __iomem *sensor_status_addr;
  355. void __iomem *sensor_int_mask_addr;
  356. void __iomem *sensor_upper_lower_addr;
  357. u32 addr_offset = 0;
  358. sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_tm_addr);
  359. sensor_int_mask_addr =
  360. TSENS_TM_UPPER_LOWER_INT_MASK(tm->tsens_tm_addr);
  361. sensor_upper_lower_addr =
  362. TSENS_TM_SN_UPPER_LOWER_THRESHOLD(tm->tsens_tm_addr);
  363. for (i = 0; i < TSENS_MAX_SENSORS; i++) {
  364. bool upper_thr = false, lower_thr = false;
  365. int int_mask, int_mask_val = 0, rc;
  366. if (IS_ERR(tm->sensor[i].tzd))
  367. continue;
  368. rc = tsens2xxx_get_temp(&tm->sensor[i], &temp);
  369. if (rc) {
  370. pr_debug("Error:%d reading temp sensor:%d\n", rc, i);
  371. continue;
  372. }
  373. spin_lock_irqsave(&tm->tsens_upp_low_lock, flags);
  374. addr_offset = tm->sensor[i].hw_id *
  375. TSENS_TM_SN_ADDR_OFFSET;
  376. status = readl_relaxed(sensor_status_addr + addr_offset);
  377. threshold = readl_relaxed(sensor_upper_lower_addr +
  378. addr_offset);
  379. int_mask = readl_relaxed(sensor_int_mask_addr);
  380. if ((status & TSENS_TM_SN_STATUS_UPPER_STATUS) &&
  381. !(int_mask &
  382. (1 << (tm->sensor[i].hw_id + 16)))) {
  383. int_mask = readl_relaxed(sensor_int_mask_addr);
  384. int_mask_val = TSENS_TM_UPPER_INT_SET(
  385. tm->sensor[i].hw_id);
  386. /* Mask the corresponding interrupt for the sensors */
  387. writel_relaxed(int_mask | int_mask_val,
  388. TSENS_TM_UPPER_LOWER_INT_MASK(
  389. tm->tsens_tm_addr));
  390. /* Clear the corresponding sensors interrupt */
  391. writel_relaxed(int_mask_val,
  392. TSENS_TM_UPPER_LOWER_INT_CLEAR(
  393. tm->tsens_tm_addr));
  394. writel_relaxed(0,
  395. TSENS_TM_UPPER_LOWER_INT_CLEAR(
  396. tm->tsens_tm_addr));
  397. if (TSENS_TM_UPPER_THRESHOLD_VALUE(threshold) >
  398. (temp/TSENS_TM_SCALE_DECI_MILLIDEG)) {
  399. pr_debug("Re-arm high threshold\n");
  400. rc = tsens_tm_activate_trip_type(
  401. &tm->sensor[i],
  402. THERMAL_TRIP_CONFIGURABLE_HI,
  403. THERMAL_TRIP_ACTIVATION_ENABLED);
  404. if (rc)
  405. pr_err("high rearm failed:%d\n", rc);
  406. } else {
  407. upper_thr = true;
  408. tm->sensor[i].thr_state.
  409. high_th_state = THERMAL_DEVICE_DISABLED;
  410. }
  411. }
  412. if ((status & TSENS_TM_SN_STATUS_LOWER_STATUS) &&
  413. !(int_mask &
  414. (1 << tm->sensor[i].hw_id))) {
  415. int_mask = readl_relaxed(sensor_int_mask_addr);
  416. int_mask_val = (1 << tm->sensor[i].hw_id);
  417. /* Mask the corresponding interrupt for the sensors */
  418. writel_relaxed(int_mask | int_mask_val,
  419. TSENS_TM_UPPER_LOWER_INT_MASK(
  420. tm->tsens_tm_addr));
  421. /* Clear the corresponding sensors interrupt */
  422. writel_relaxed(int_mask_val,
  423. TSENS_TM_UPPER_LOWER_INT_CLEAR(
  424. tm->tsens_tm_addr));
  425. writel_relaxed(0,
  426. TSENS_TM_UPPER_LOWER_INT_CLEAR(
  427. tm->tsens_tm_addr));
  428. if (TSENS_TM_LOWER_THRESHOLD_VALUE(threshold)
  429. < (temp/TSENS_TM_SCALE_DECI_MILLIDEG)) {
  430. pr_debug("Re-arm low threshold\n");
  431. rc = tsens_tm_activate_trip_type(
  432. &tm->sensor[i],
  433. THERMAL_TRIP_CONFIGURABLE_LOW,
  434. THERMAL_TRIP_ACTIVATION_ENABLED);
  435. if (rc)
  436. pr_err("low rearm failed:%d\n", rc);
  437. } else {
  438. lower_thr = true;
  439. tm->sensor[i].thr_state.
  440. low_th_state = THERMAL_DEVICE_DISABLED;
  441. }
  442. }
  443. spin_unlock_irqrestore(&tm->tsens_upp_low_lock, flags);
  444. if (upper_thr || lower_thr) {
  445. /* Use id for multiple controllers */
  446. pr_debug("sensor:%d trigger temp (%d degC)\n",
  447. tm->sensor[i].hw_id, temp);
  448. of_thermal_handle_trip_temp(tm->sensor[i].tzd, temp);
  449. }
  450. }
  451. /* Disable monitoring sensor trip threshold for triggered sensor */
  452. mb();
  453. if (tm->ops->dbg)
  454. tm->ops->dbg(tm, 0, TSENS_DBG_LOG_INTERRUPT_TIMESTAMP, NULL);
  455. return IRQ_HANDLED;
  456. }
  457. static int tsens2xxx_hw_sensor_en(struct tsens_device *tmdev,
  458. u32 sensor_id)
  459. {
  460. void __iomem *srot_addr;
  461. unsigned int srot_val, sensor_en;
  462. srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4);
  463. srot_val = readl_relaxed(srot_addr);
  464. srot_val = TSENS_CTRL_SENSOR_EN_MASK(srot_val);
  465. sensor_en = ((1 << sensor_id) & srot_val);
  466. return sensor_en;
  467. }
  468. static int tsens2xxx_hw_init(struct tsens_device *tmdev)
  469. {
  470. void __iomem *srot_addr;
  471. void __iomem *sensor_int_mask_addr;
  472. unsigned int srot_val, crit_mask, crit_val;
  473. void __iomem *int_mask_addr;
  474. srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4);
  475. srot_val = readl_relaxed(srot_addr);
  476. if (!(srot_val & TSENS_EN)) {
  477. pr_err("TSENS device is not enabled\n");
  478. return -ENODEV;
  479. }
  480. if (tmdev->ctrl_data->cycle_monitor) {
  481. sensor_int_mask_addr =
  482. TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr);
  483. crit_mask = readl_relaxed(sensor_int_mask_addr);
  484. crit_val = TSENS_TM_CRITICAL_CYCLE_MONITOR;
  485. if (tmdev->ctrl_data->cycle_compltn_monitor_mask)
  486. writel_relaxed((crit_mask | crit_val),
  487. (TSENS_TM_CRITICAL_INT_MASK
  488. (tmdev->tsens_tm_addr)));
  489. else
  490. writel_relaxed((crit_mask & ~crit_val),
  491. (TSENS_TM_CRITICAL_INT_MASK
  492. (tmdev->tsens_tm_addr)));
  493. /*Update critical cycle monitoring*/
  494. mb();
  495. }
  496. if (tmdev->ctrl_data->wd_bark) {
  497. sensor_int_mask_addr =
  498. TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr);
  499. crit_mask = readl_relaxed(sensor_int_mask_addr);
  500. crit_val = TSENS_TM_CRITICAL_WD_BARK;
  501. if (tmdev->ctrl_data->wd_bark_mask)
  502. writel_relaxed((crit_mask | crit_val),
  503. (TSENS_TM_CRITICAL_INT_MASK
  504. (tmdev->tsens_tm_addr)));
  505. else
  506. writel_relaxed((crit_mask & ~crit_val),
  507. (TSENS_TM_CRITICAL_INT_MASK
  508. (tmdev->tsens_tm_addr)));
  509. /*Update watchdog monitoring*/
  510. mb();
  511. }
  512. int_mask_addr = TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_tm_addr);
  513. writel_relaxed(TSENS_TM_UPPER_LOWER_INT_DISABLE, int_mask_addr);
  514. writel_relaxed(TSENS_TM_CRITICAL_INT_EN |
  515. TSENS_TM_UPPER_INT_EN | TSENS_TM_LOWER_INT_EN,
  516. TSENS_TM_INT_EN(tmdev->tsens_tm_addr));
  517. spin_lock_init(&tmdev->tsens_crit_lock);
  518. spin_lock_init(&tmdev->tsens_upp_low_lock);
  519. if (tmdev->ctrl_data->mtc) {
  520. if (tmdev->ops->dbg)
  521. tmdev->ops->dbg(tmdev, 0, TSENS_DBG_MTC_DATA, NULL);
  522. }
  523. return 0;
  524. }
  525. static const struct tsens_irqs tsens2xxx_irqs[] = {
  526. { "tsens-upper-lower", tsens_tm_irq_thread},
  527. { "tsens-critical", tsens_tm_critical_irq_thread},
  528. };
  529. static int tsens2xxx_register_interrupts(struct tsens_device *tmdev)
  530. {
  531. struct platform_device *pdev;
  532. int i, rc;
  533. if (!tmdev)
  534. return -EINVAL;
  535. pdev = tmdev->pdev;
  536. for (i = 0; i < ARRAY_SIZE(tsens2xxx_irqs); i++) {
  537. int irq;
  538. irq = platform_get_irq_byname(pdev, tsens2xxx_irqs[i].name);
  539. if (irq < 0) {
  540. dev_err(&pdev->dev, "failed to get irq %s\n",
  541. tsens2xxx_irqs[i].name);
  542. return irq;
  543. }
  544. rc = devm_request_threaded_irq(&pdev->dev, irq, NULL,
  545. tsens2xxx_irqs[i].handler,
  546. IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
  547. tsens2xxx_irqs[i].name, tmdev);
  548. if (rc) {
  549. dev_err(&pdev->dev, "failed to get irq %s\n",
  550. tsens2xxx_irqs[i].name);
  551. return rc;
  552. }
  553. enable_irq_wake(irq);
  554. }
  555. return 0;
  556. }
  557. static const struct tsens_ops ops_tsens2xxx = {
  558. .hw_init = tsens2xxx_hw_init,
  559. .get_temp = tsens2xxx_get_temp,
  560. .set_trips = tsens2xxx_set_trip_temp,
  561. .interrupts_reg = tsens2xxx_register_interrupts,
  562. .dbg = tsens2xxx_dbg,
  563. .sensor_en = tsens2xxx_hw_sensor_en,
  564. };
  565. const struct tsens_data data_tsens2xxx = {
  566. .cycle_monitor = false,
  567. .cycle_compltn_monitor_mask = 1,
  568. .wd_bark = false,
  569. .wd_bark_mask = 1,
  570. .ops = &ops_tsens2xxx,
  571. .mtc = true,
  572. };
  573. const struct tsens_data data_tsens23xx = {
  574. .cycle_monitor = true,
  575. .cycle_compltn_monitor_mask = 1,
  576. .wd_bark = true,
  577. .wd_bark_mask = 1,
  578. .ops = &ops_tsens2xxx,
  579. .mtc = false,
  580. };
  581. const struct tsens_data data_tsens24xx = {
  582. .cycle_monitor = true,
  583. .cycle_compltn_monitor_mask = 1,
  584. .wd_bark = true,
  585. /* Enable Watchdog monitoring by unmasking */
  586. .wd_bark_mask = 0,
  587. .ops = &ops_tsens2xxx,
  588. .mtc = false,
  589. };