msm-tsens.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017-2020, 2021 The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/err.h>
  7. #include <linux/module.h>
  8. #include <linux/of.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/pm.h>
  11. #include <linux/kernel.h>
  12. #include <linux/io.h>
  13. #include <linux/slab.h>
  14. #include <linux/thermal.h>
  15. #include <linux/suspend.h>
  16. #include "tsens2xxx.h"
  17. #include "../thermal_core.h"
  18. #include "thermal_zone_internal.h"
  19. LIST_HEAD(tsens_device_list);
  20. static int tsens_get_temp(struct thermal_zone_device *tz, int *temp)
  21. {
  22. struct tsens_sensor *s = tz->devdata;
  23. struct tsens_device *tmdev = s->tmdev;
  24. return tmdev->ops->get_temp(s, temp);
  25. }
  26. static int tsens_get_zeroc_status(struct thermal_zone_device *tz, int *status)
  27. {
  28. struct tsens_sensor *s = tz->devdata;
  29. return tsens_2xxx_get_zeroc_status(s, status);
  30. }
  31. static int tsens_set_trip_temp(struct thermal_zone_device *tz, int low_temp, int high_temp)
  32. {
  33. struct tsens_sensor *s = tz->devdata;
  34. struct tsens_device *tmdev = s->tmdev;
  35. if (tmdev->ops->set_trips)
  36. return tmdev->ops->set_trips(s, low_temp, high_temp);
  37. return 0;
  38. }
  39. static int tsens_tz_change_mode(struct thermal_zone_device *tz, enum thermal_device_mode mode)
  40. {
  41. struct tsens_sensor *s = tz->devdata;
  42. return qti_tz_change_mode(s->tzd, mode);
  43. }
  44. static int tsens_init(struct tsens_device *tmdev)
  45. {
  46. return tmdev->ops->hw_init(tmdev);
  47. }
  48. static int tsens_calib(struct tsens_device *tmdev)
  49. {
  50. return tmdev->ops->calibrate(tmdev);
  51. }
  52. static int tsens_register_interrupts(struct tsens_device *tmdev)
  53. {
  54. if (tmdev->ops->interrupts_reg)
  55. return tmdev->ops->interrupts_reg(tmdev);
  56. return 0;
  57. }
  58. static int tsens_suspend(struct device *dev)
  59. {
  60. struct tsens_device *tmdev = dev_get_drvdata(dev);
  61. if (pm_suspend_via_firmware() != PM_SUSPEND_MEM)
  62. return 0;
  63. return tmdev->ops->suspend(tmdev);
  64. }
  65. static int tsens_resume(struct device *dev)
  66. {
  67. struct tsens_device *tmdev = dev_get_drvdata(dev);
  68. if (pm_suspend_via_firmware() != PM_SUSPEND_MEM)
  69. return 0;
  70. return tmdev->ops->resume(tmdev);
  71. }
  72. static int tsens_freeze(struct device *dev)
  73. {
  74. struct tsens_device *tmdev = dev_get_drvdata(dev);
  75. return tmdev->ops->suspend(tmdev);
  76. }
  77. static int tsens_restore(struct device *dev)
  78. {
  79. struct tsens_device *tmdev = dev_get_drvdata(dev);
  80. return tmdev->ops->resume(tmdev);
  81. }
  82. static const struct of_device_id tsens_table[] = {
  83. { .compatible = "qcom,msm8953-tsens",
  84. .data = &data_tsens2xxx,
  85. },
  86. { .compatible = "qcom,msmhamster-tsens",
  87. .data = &data_tsens2xxx,
  88. },
  89. { .compatible = "qcom,sdm660-tsens",
  90. .data = &data_tsens23xx,
  91. },
  92. { .compatible = "qcom,sdm630-tsens",
  93. .data = &data_tsens23xx,
  94. },
  95. { .compatible = "qcom,sm6150-tsens",
  96. .data = &data_tsens23xx,
  97. },
  98. { .compatible = "qcom,sdm845-tsens",
  99. .data = &data_tsens24xx,
  100. },
  101. { .compatible = "qcom,tsens24xx",
  102. .data = &data_tsens24xx,
  103. },
  104. { .compatible = "qcom,tsens26xx",
  105. .data = &data_tsens26xx,
  106. },
  107. {}
  108. };
  109. MODULE_DEVICE_TABLE(of, tsens_table);
  110. static struct thermal_zone_device_ops tsens_tm_thermal_zone_ops = {
  111. .get_temp = tsens_get_temp,
  112. .set_trips = tsens_set_trip_temp,
  113. .change_mode = tsens_tz_change_mode,
  114. };
  115. static struct thermal_zone_device_ops tsens_tm_min_thermal_zone_ops = {
  116. .get_temp = tsens_get_zeroc_status,
  117. };
  118. static int get_device_tree_data(struct platform_device *pdev,
  119. struct tsens_device *tmdev)
  120. {
  121. struct device_node *of_node = pdev->dev.of_node;
  122. const struct of_device_id *id;
  123. const struct tsens_data *data;
  124. int rc = 0;
  125. struct resource *res_tsens_mem;
  126. u32 zeroc_id;
  127. if (!of_match_node(tsens_table, of_node)) {
  128. pr_err("Need to read SoC specific fuse map\n");
  129. return -ENODEV;
  130. }
  131. id = of_match_node(tsens_table, of_node);
  132. if (id == NULL) {
  133. pr_err("can not find tsens_table of_node\n");
  134. return -ENODEV;
  135. }
  136. data = id->data;
  137. tmdev->ops = data->ops;
  138. tmdev->ctrl_data = data;
  139. tmdev->pdev = pdev;
  140. tmdev->dev = &pdev->dev;
  141. if (!tmdev->ops || !tmdev->ops->hw_init || !tmdev->ops->get_temp) {
  142. pr_err("Invalid ops\n");
  143. return -EINVAL;
  144. }
  145. /* TSENS register region */
  146. res_tsens_mem = platform_get_resource_byname(pdev,
  147. IORESOURCE_MEM, "tsens_srot_physical");
  148. if (!res_tsens_mem) {
  149. pr_err("Could not get tsens physical address resource\n");
  150. return -EINVAL;
  151. }
  152. tmdev->tsens_srot_addr = devm_ioremap_resource(&pdev->dev,
  153. res_tsens_mem);
  154. if (IS_ERR(tmdev->tsens_srot_addr)) {
  155. dev_err(&pdev->dev, "Failed to IO map TSENS registers.\n");
  156. return PTR_ERR(tmdev->tsens_srot_addr);
  157. }
  158. /* TSENS TM register region */
  159. res_tsens_mem = platform_get_resource_byname(pdev,
  160. IORESOURCE_MEM, "tsens_tm_physical");
  161. if (!res_tsens_mem) {
  162. pr_err("Could not get tsens physical address resource\n");
  163. return -EINVAL;
  164. }
  165. tmdev->tsens_tm_addr = devm_ioremap_resource(&pdev->dev,
  166. res_tsens_mem);
  167. if (IS_ERR(tmdev->tsens_tm_addr)) {
  168. dev_err(&pdev->dev, "Failed to IO map TSENS TM registers.\n");
  169. return PTR_ERR(tmdev->tsens_tm_addr);
  170. }
  171. tmdev->phys_addr_tm = res_tsens_mem->start;
  172. /* TSENS eeprom register region */
  173. res_tsens_mem = platform_get_resource_byname(pdev,
  174. IORESOURCE_MEM, "tsens_eeprom_physical");
  175. if (!res_tsens_mem) {
  176. pr_debug("Could not get tsens physical address resource\n");
  177. } else {
  178. tmdev->tsens_calib_addr = devm_ioremap_resource(&pdev->dev,
  179. res_tsens_mem);
  180. if (IS_ERR(tmdev->tsens_calib_addr)) {
  181. dev_err(&pdev->dev, "Failed to IO map TSENS EEPROM registers.\n");
  182. rc = PTR_ERR(tmdev->tsens_calib_addr);
  183. } else {
  184. rc = tsens_calib(tmdev);
  185. if (rc) {
  186. pr_err("Error initializing TSENS controller\n");
  187. return rc;
  188. }
  189. }
  190. }
  191. if (!of_property_read_u32(of_node, "0C-sensor-num", &zeroc_id))
  192. tmdev->zeroc_sensor_id = (int)zeroc_id;
  193. else
  194. tmdev->zeroc_sensor_id = MIN_TEMP_DEF_OFFSET;
  195. tmdev->tsens_reinit_wa =
  196. of_property_read_bool(of_node, "tsens-reinit-wa");
  197. return rc;
  198. }
  199. static int tsens_thermal_zone_register(struct tsens_device *tmdev)
  200. {
  201. int i = 0, sensor_missing = 0;
  202. for (i = 0; i < TSENS_MAX_SENSORS; i++) {
  203. tmdev->sensor[i].tmdev = tmdev;
  204. tmdev->sensor[i].hw_id = i;
  205. tmdev->sensor[i].cached_temp = INT_MIN;
  206. if (tmdev->ops->sensor_en(tmdev, i)) {
  207. tmdev->sensor[i].tzd =
  208. devm_thermal_of_zone_register(
  209. &tmdev->pdev->dev, i,
  210. &tmdev->sensor[i], &tsens_tm_thermal_zone_ops);
  211. if (IS_ERR(tmdev->sensor[i].tzd)) {
  212. pr_debug("Error registering sensor:%d\n", i);
  213. sensor_missing++;
  214. continue;
  215. }
  216. } else {
  217. pr_debug("Sensor not enabled:%d\n", i);
  218. }
  219. }
  220. if (sensor_missing == TSENS_MAX_SENSORS) {
  221. pr_err("No TSENS sensors to register?\n");
  222. return -ENODEV;
  223. }
  224. if (tmdev->zeroc_sensor_id != MIN_TEMP_DEF_OFFSET) {
  225. tmdev->zeroc.tmdev = tmdev;
  226. tmdev->zeroc.hw_id = tmdev->zeroc_sensor_id;
  227. tmdev->zeroc.tzd =
  228. devm_thermal_of_zone_register(
  229. &tmdev->pdev->dev, tmdev->zeroc_sensor_id,
  230. &tmdev->zeroc, &tsens_tm_min_thermal_zone_ops);
  231. if (IS_ERR(tmdev->zeroc.tzd))
  232. pr_err("Error registering min temp sensor\n");
  233. }
  234. return 0;
  235. }
  236. static int tsens_tm_remove(struct platform_device *pdev)
  237. {
  238. platform_set_drvdata(pdev, NULL);
  239. return 0;
  240. }
  241. static void tsens_therm_fwk_notify(struct work_struct *work)
  242. {
  243. int i, rc, temp;
  244. struct tsens_device *tmdev =
  245. container_of(work, struct tsens_device, therm_fwk_notify);
  246. TSENS_DBG(tmdev, "Controller %pK\n", &tmdev->phys_addr_tm);
  247. for (i = 0; i < TSENS_MAX_SENSORS; i++) {
  248. tmdev->sensor[i].cached_temp = INT_MIN;
  249. if (tmdev->ops->sensor_en(tmdev, i)) {
  250. rc = tsens_get_temp(tmdev->sensor[i].tzd, &temp);
  251. if (rc) {
  252. pr_err("%s: Error:%d reading temp sensor:%d\n",
  253. __func__, rc, i);
  254. continue;
  255. }
  256. TSENS_DBG(tmdev, "Calling trip_temp for sensor %d\n",
  257. i);
  258. thermal_zone_device_update(tmdev->sensor[i].tzd,
  259. THERMAL_EVENT_UNSPECIFIED);
  260. }
  261. }
  262. if (tmdev->zeroc_sensor_id != MIN_TEMP_DEF_OFFSET) {
  263. rc = tsens_get_zeroc_status(tmdev->zeroc.tzd, &temp);
  264. if (rc) {
  265. pr_err("%s: Error:%d reading temp sensor:%d\n",
  266. __func__, rc, i);
  267. return;
  268. }
  269. TSENS_DBG(tmdev, "Calling trip_temp for sensor %d\n", i);
  270. thermal_zone_device_update(tmdev->zeroc.tzd,
  271. THERMAL_EVENT_UNSPECIFIED);
  272. }
  273. }
  274. static int tsens_tm_probe(struct platform_device *pdev)
  275. {
  276. struct tsens_device *tmdev = NULL;
  277. int rc;
  278. char tsens_name[40];
  279. if (!(pdev->dev.of_node))
  280. return -ENODEV;
  281. tmdev = devm_kzalloc(&pdev->dev,
  282. sizeof(struct tsens_device) +
  283. TSENS_MAX_SENSORS *
  284. sizeof(struct tsens_sensor),
  285. GFP_KERNEL);
  286. if (tmdev == NULL)
  287. return -ENOMEM;
  288. rc = get_device_tree_data(pdev, tmdev);
  289. if (rc) {
  290. pr_err("Error reading TSENS DT\n");
  291. return rc;
  292. }
  293. rc = tsens_init(tmdev);
  294. if (rc) {
  295. pr_err("Error initializing TSENS controller\n");
  296. return rc;
  297. }
  298. snprintf(tsens_name, sizeof(tsens_name), "tsens_wq_%pa",
  299. &tmdev->phys_addr_tm);
  300. tmdev->tsens_reinit_work = alloc_workqueue(tsens_name,
  301. WQ_HIGHPRI, 0);
  302. if (!tmdev->tsens_reinit_work) {
  303. rc = -ENOMEM;
  304. return rc;
  305. }
  306. INIT_WORK(&tmdev->therm_fwk_notify, tsens_therm_fwk_notify);
  307. rc = tsens_thermal_zone_register(tmdev);
  308. if (rc) {
  309. pr_err("Error registering the thermal zone\n");
  310. return rc;
  311. }
  312. rc = tsens_register_interrupts(tmdev);
  313. if (rc < 0) {
  314. pr_err("TSENS interrupt register failed:%d\n", rc);
  315. return rc;
  316. }
  317. snprintf(tsens_name, sizeof(tsens_name), "tsens_%pa_0",
  318. &tmdev->phys_addr_tm);
  319. tmdev->ipc_log0 = ipc_log_context_create(IPC_LOGPAGES,
  320. tsens_name, 0);
  321. if (!tmdev->ipc_log0)
  322. pr_err("%s : unable to create IPC Logging 0 for tsens %pa\n",
  323. __func__, &tmdev->phys_addr_tm);
  324. snprintf(tsens_name, sizeof(tsens_name), "tsens_%pa_1",
  325. &tmdev->phys_addr_tm);
  326. tmdev->ipc_log1 = ipc_log_context_create(IPC_LOGPAGES,
  327. tsens_name, 0);
  328. if (!tmdev->ipc_log1)
  329. pr_err("%s : unable to create IPC Logging 1 for tsens %pa\n",
  330. __func__, &tmdev->phys_addr_tm);
  331. snprintf(tsens_name, sizeof(tsens_name), "tsens_%pa_2",
  332. &tmdev->phys_addr_tm);
  333. tmdev->ipc_log2 = ipc_log_context_create(IPC_LOGPAGES,
  334. tsens_name, 0);
  335. if (!tmdev->ipc_log2)
  336. pr_err("%s : unable to create IPC Logging 2 for tsens %pa\n",
  337. __func__, &tmdev->phys_addr_tm);
  338. list_add_tail(&tmdev->list, &tsens_device_list);
  339. platform_set_drvdata(pdev, tmdev);
  340. dev_set_drvdata(tmdev->dev, tmdev);
  341. return rc;
  342. }
  343. static const struct dev_pm_ops tsens_pm_ops = {
  344. .freeze = tsens_freeze,
  345. .restore = tsens_restore,
  346. .suspend = tsens_suspend,
  347. .resume = tsens_resume,
  348. };
  349. static struct platform_driver tsens_tm_driver = {
  350. .probe = tsens_tm_probe,
  351. .remove = tsens_tm_remove,
  352. .driver = {
  353. .name = "msm-tsens",
  354. .pm = &tsens_pm_ops,
  355. .of_match_table = tsens_table,
  356. },
  357. };
  358. static int __init tsens_tm_init_driver(void)
  359. {
  360. return platform_driver_register(&tsens_tm_driver);
  361. }
  362. subsys_initcall(tsens_tm_init_driver);
  363. static void __exit tsens_tm_deinit(void)
  364. {
  365. platform_driver_unregister(&tsens_tm_driver);
  366. }
  367. module_exit(tsens_tm_deinit);
  368. MODULE_ALIAS("platform:" TSENS_DRIVER_NAME);
  369. MODULE_LICENSE("GPL");