qmi_sensors.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #define pr_fmt(fmt) "%s:%s " fmt, KBUILD_MODNAME, __func__
  7. #include <linux/module.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/thermal.h>
  10. #include <linux/err.h>
  11. #include <linux/slab.h>
  12. #include <linux/of.h>
  13. #include <linux/soc/qcom/qmi.h>
  14. #include <linux/net.h>
  15. #include <linux/kernel.h>
  16. #include <linux/suspend.h>
  17. #include "thermal_sensor_service_v01.h"
  18. #include "qmi_sensors.h"
  19. #include "thermal_zone_internal.h"
  20. #define QMI_SENS_DRIVER "qmi-therm-sensors"
  21. #define QMI_TS_RESP_TOUT msecs_to_jiffies(100)
  22. #define QMI_FL_SIGN 0x80000000
  23. #define QMI_FL_EXP 0x7f800000
  24. #define QMI_FL_MANTISSA 0x007fffff
  25. #define QMI_FL_NORM 0x00800000
  26. #define QMI_FL_SIGN_BIT 31
  27. #define QMI_MANTISSA_MSB 23
  28. struct qmi_sensor {
  29. struct device *dev;
  30. char qmi_name[QMI_CLIENT_NAME_LENGTH];
  31. bool connection_active;
  32. struct list_head ts_node;
  33. struct thermal_zone_device *tz_dev;
  34. int32_t last_reading;
  35. int32_t high_thresh;
  36. int32_t low_thresh;
  37. struct qmi_ts_instance *ts;
  38. enum qmi_ts_sensor sens_type;
  39. struct work_struct therm_notify_work;
  40. };
  41. struct qmi_ts_instance {
  42. struct device *dev;
  43. struct qmi_handle handle;
  44. struct mutex mutex;
  45. uint32_t inst_id;
  46. struct list_head ts_sensor_list;
  47. struct work_struct svc_arrive_work;
  48. };
  49. static struct qmi_ts_instance *ts_instances;
  50. static int ts_inst_cnt;
  51. static atomic_t in_suspend;
  52. static int32_t encode_qmi(int32_t val)
  53. {
  54. uint32_t shift = 0, local_val = 0;
  55. unsigned long temp_val = 0;
  56. if (val == INT_MAX || val == INT_MIN)
  57. return 0;
  58. temp_val = val = val / 1000;
  59. if (val < 0) {
  60. temp_val *= -1;
  61. local_val |= 1 << QMI_FL_SIGN_BIT;
  62. }
  63. shift = find_last_bit(&temp_val, sizeof(temp_val) * 8);
  64. local_val |= ((shift + 127) << QMI_MANTISSA_MSB);
  65. temp_val &= ~(1 << shift);
  66. local_val |= temp_val << (QMI_MANTISSA_MSB - shift);
  67. pr_debug("inp:%d shift:%d out:%x temp_val:%x\n",
  68. val, shift, local_val, temp_val);
  69. return local_val;
  70. }
  71. static int32_t decode_qmi(int32_t float32)
  72. {
  73. int fraction, shift, mantissa, sign, exp, zeropre;
  74. mantissa = float32 & GENMASK(22, 0);
  75. sign = (float32 & BIT(31)) ? -1 : 1;
  76. exp = (float32 & ~BIT(31)) >> 23;
  77. if (!exp && !mantissa)
  78. return 0;
  79. exp -= 127;
  80. if (exp < 0) {
  81. exp = -exp;
  82. zeropre = (((BIT(23) + mantissa) * 100) >> 23) >> exp;
  83. return zeropre >= 50 ? sign : 0;
  84. }
  85. shift = 23 - exp;
  86. float32 = BIT(exp) + (mantissa >> shift);
  87. fraction = mantissa & GENMASK(shift - 1, 0);
  88. return (((fraction * 100) >> shift) >= 50) ? sign * (float32 + 1) : sign * float32;
  89. }
  90. static int qmi_sensor_pm_notify(struct notifier_block *nb,
  91. unsigned long mode, void *_unused)
  92. {
  93. switch (mode) {
  94. case PM_HIBERNATION_PREPARE:
  95. case PM_RESTORE_PREPARE:
  96. case PM_SUSPEND_PREPARE:
  97. atomic_set(&in_suspend, 1);
  98. break;
  99. case PM_POST_HIBERNATION:
  100. case PM_POST_RESTORE:
  101. case PM_POST_SUSPEND:
  102. atomic_set(&in_suspend, 0);
  103. break;
  104. default:
  105. break;
  106. }
  107. return 0;
  108. }
  109. static struct notifier_block qmi_sensor_pm_nb = {
  110. .notifier_call = qmi_sensor_pm_notify,
  111. };
  112. static void qmi_ts_thresh_notify(struct work_struct *work)
  113. {
  114. struct qmi_sensor *qmi_sens = container_of(work,
  115. struct qmi_sensor,
  116. therm_notify_work);
  117. thermal_zone_device_update(qmi_sens->tz_dev, THERMAL_TRIP_VIOLATED);
  118. };
  119. static void qmi_ts_update_temperature(struct qmi_ts_instance *ts,
  120. const struct ts_temp_report_ind_msg_v01 *ind_msg,
  121. uint8_t notify)
  122. {
  123. struct qmi_sensor *qmi_sens;
  124. list_for_each_entry(qmi_sens, &ts->ts_sensor_list,
  125. ts_node) {
  126. if ((strncasecmp(qmi_sens->qmi_name,
  127. ind_msg->sensor_id.sensor_id,
  128. QMI_TS_SENSOR_ID_LENGTH_MAX_V01)))
  129. continue;
  130. qmi_sens->last_reading =
  131. decode_qmi(ind_msg->temp) * 1000;
  132. pr_debug("sensor:%s temperature:%d\n",
  133. qmi_sens->qmi_name, qmi_sens->last_reading);
  134. if (!qmi_sens->tz_dev)
  135. return;
  136. if (notify &&
  137. ((qmi_sens->high_thresh != INT_MAX &&
  138. qmi_sens->last_reading >= qmi_sens->high_thresh) ||
  139. (qmi_sens->low_thresh != (-INT_MAX) &&
  140. qmi_sens->last_reading <= qmi_sens->low_thresh))) {
  141. pr_debug("Sensor:%s Notify. temp:%d\n",
  142. ind_msg->sensor_id.sensor_id,
  143. qmi_sens->last_reading);
  144. queue_work(system_highpri_wq,
  145. &qmi_sens->therm_notify_work);
  146. }
  147. return;
  148. }
  149. }
  150. void qmi_ts_ind_cb(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
  151. struct qmi_txn *txn, const void *decoded)
  152. {
  153. const struct ts_temp_report_ind_msg_v01 *ind_msg = decoded;
  154. uint8_t notify = 0;
  155. struct qmi_ts_instance *ts = container_of(qmi, struct qmi_ts_instance,
  156. handle);
  157. if (!txn) {
  158. pr_err("Invalid transaction\n");
  159. return;
  160. }
  161. if ((ind_msg->report_type != QMI_TS_TEMP_REPORT_CURRENT_TEMP_V01) ||
  162. ind_msg->seq_num_valid)
  163. notify = 1;
  164. if (ind_msg->temp_valid)
  165. qmi_ts_update_temperature(ts, ind_msg, notify);
  166. else
  167. pr_err("Error invalid temperature field.\n");
  168. }
  169. static int qmi_ts_request(struct qmi_sensor *qmi_sens,
  170. bool send_current_temp_report)
  171. {
  172. int ret = 0;
  173. struct ts_register_notification_temp_resp_msg_v01 resp;
  174. struct ts_register_notification_temp_req_msg_v01 req;
  175. struct qmi_ts_instance *ts = qmi_sens->ts;
  176. struct qmi_txn txn;
  177. memset(&req, 0, sizeof(req));
  178. memset(&resp, 0, sizeof(resp));
  179. strscpy(req.sensor_id.sensor_id, qmi_sens->qmi_name,
  180. QMI_TS_SENSOR_ID_LENGTH_MAX_V01);
  181. req.seq_num = 0;
  182. if (send_current_temp_report) {
  183. req.send_current_temp_report = 1;
  184. req.seq_num_valid = true;
  185. } else {
  186. req.seq_num_valid = false;
  187. req.temp_threshold_high_valid =
  188. qmi_sens->high_thresh != INT_MAX;
  189. req.temp_threshold_high =
  190. encode_qmi(qmi_sens->high_thresh);
  191. req.temp_threshold_low_valid =
  192. qmi_sens->low_thresh != (-INT_MAX);
  193. req.temp_threshold_low =
  194. encode_qmi(qmi_sens->low_thresh);
  195. pr_debug("Sensor:%s set high_trip:%d, low_trip:%d, high_valid:%d, low_valid:%d\n",
  196. qmi_sens->qmi_name,
  197. qmi_sens->high_thresh,
  198. qmi_sens->low_thresh,
  199. req.temp_threshold_high_valid,
  200. req.temp_threshold_low_valid);
  201. }
  202. mutex_lock(&ts->mutex);
  203. ret = qmi_txn_init(&ts->handle, &txn,
  204. ts_register_notification_temp_resp_msg_v01_ei, &resp);
  205. if (ret < 0) {
  206. pr_err("qmi txn init failed for %s ret:%d\n",
  207. qmi_sens->qmi_name, ret);
  208. goto qmi_send_exit;
  209. }
  210. ret = qmi_send_request(&ts->handle, NULL, &txn,
  211. QMI_TS_REGISTER_NOTIFICATION_TEMP_REQ_V01,
  212. TS_REGISTER_NOTIFICATION_TEMP_REQ_MSG_V01_MAX_MSG_LEN,
  213. ts_register_notification_temp_req_msg_v01_ei, &req);
  214. if (ret < 0) {
  215. pr_err("qmi txn send failed for %s ret:%d\n",
  216. qmi_sens->qmi_name, ret);
  217. qmi_txn_cancel(&txn);
  218. goto qmi_send_exit;
  219. }
  220. ret = qmi_txn_wait(&txn, QMI_TS_RESP_TOUT);
  221. if (ret < 0) {
  222. pr_err("qmi txn wait failed for %s ret:%d\n",
  223. qmi_sens->qmi_name, ret);
  224. goto qmi_send_exit;
  225. }
  226. if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
  227. ret = resp.resp.result;
  228. pr_err("qmi NOT success for %s ret:%d\n",
  229. qmi_sens->qmi_name, ret);
  230. goto qmi_send_exit;
  231. }
  232. ret = 0;
  233. qmi_send_exit:
  234. mutex_unlock(&ts->mutex);
  235. return ret;
  236. }
  237. static int qmi_sensor_read(struct thermal_zone_device *tz, int *temp)
  238. {
  239. struct qmi_sensor *qmi_sens = (struct qmi_sensor *)tz->devdata;
  240. if (qmi_sens->connection_active && !atomic_read(&in_suspend))
  241. qmi_ts_request(qmi_sens, true);
  242. *temp = qmi_sens->last_reading;
  243. return 0;
  244. }
  245. static int qmi_sensor_set_trips(struct thermal_zone_device *tz, int low, int high)
  246. {
  247. struct qmi_sensor *qmi_sens = (struct qmi_sensor *)tz->devdata;
  248. int ret = 0;
  249. if (qmi_sens->high_thresh == high &&
  250. qmi_sens->low_thresh == low)
  251. return ret;
  252. qmi_sens->high_thresh = high;
  253. qmi_sens->low_thresh = low;
  254. if (!qmi_sens->connection_active)
  255. return ret;
  256. ret = qmi_ts_request(qmi_sens, false);
  257. if (ret)
  258. pr_err("Sensor:%s set high trip:%d low trip:%d error%d\n",
  259. qmi_sens->qmi_name,
  260. qmi_sens->high_thresh,
  261. qmi_sens->low_thresh,
  262. ret);
  263. return ret;
  264. }
  265. static struct thermal_zone_device_ops qmi_sensor_ops = {
  266. .get_temp = qmi_sensor_read,
  267. .set_trips = qmi_sensor_set_trips,
  268. };
  269. static struct qmi_msg_handler handlers[] = {
  270. {
  271. .type = QMI_INDICATION,
  272. .msg_id = QMI_TS_TEMP_REPORT_IND_V01,
  273. .ei = ts_temp_report_ind_msg_v01_ei,
  274. .decoded_size = sizeof(struct ts_temp_report_ind_msg_v01),
  275. .fn = qmi_ts_ind_cb
  276. },
  277. {}
  278. };
  279. static int qmi_register_sensor_device(struct qmi_sensor *qmi_sens)
  280. {
  281. int ret = 0;
  282. qmi_sens->tz_dev = devm_thermal_of_zone_register(
  283. qmi_sens->dev,
  284. qmi_sens->sens_type + qmi_sens->ts->inst_id,
  285. qmi_sens, &qmi_sensor_ops);
  286. if (IS_ERR(qmi_sens->tz_dev)) {
  287. ret = PTR_ERR(qmi_sens->tz_dev);
  288. if (ret != -ENODEV)
  289. pr_err("sensor register failed for %s, ret:%d\n",
  290. qmi_sens->qmi_name, ret);
  291. qmi_sens->tz_dev = NULL;
  292. return ret;
  293. }
  294. qti_update_tz_ops(qmi_sens->tz_dev, true);
  295. pr_debug("Sensor register success for %s\n", qmi_sens->qmi_name);
  296. return 0;
  297. }
  298. static int verify_sensor_and_register(struct qmi_ts_instance *ts)
  299. {
  300. struct ts_get_sensor_list_req_msg_v01 req;
  301. struct ts_get_sensor_list_resp_msg_v01 *ts_resp;
  302. int ret = 0, i;
  303. struct qmi_txn txn;
  304. memset(&req, 0, sizeof(req));
  305. /* size of ts_resp is very high, use heap memory rather than stack */
  306. ts_resp = kzalloc(sizeof(*ts_resp), GFP_KERNEL);
  307. if (!ts_resp)
  308. return -ENOMEM;
  309. mutex_lock(&ts->mutex);
  310. ret = qmi_txn_init(&ts->handle, &txn,
  311. ts_get_sensor_list_resp_msg_v01_ei, ts_resp);
  312. if (ret < 0) {
  313. pr_err("Transaction Init error for inst_id:0x%x ret:%d\n",
  314. ts->inst_id, ret);
  315. goto reg_exit;
  316. }
  317. ret = qmi_send_request(&ts->handle, NULL, &txn,
  318. QMI_TS_GET_SENSOR_LIST_REQ_V01,
  319. TS_GET_SENSOR_LIST_REQ_MSG_V01_MAX_MSG_LEN,
  320. ts_get_sensor_list_req_msg_v01_ei,
  321. &req);
  322. if (ret < 0) {
  323. qmi_txn_cancel(&txn);
  324. goto reg_exit;
  325. }
  326. ret = qmi_txn_wait(&txn, QMI_TS_RESP_TOUT);
  327. if (ret < 0) {
  328. pr_err("Transaction wait error for inst_id:0x%x ret:%d\n",
  329. ts->inst_id, ret);
  330. goto reg_exit;
  331. }
  332. if (ts_resp->resp.result != QMI_RESULT_SUCCESS_V01) {
  333. ret = ts_resp->resp.result;
  334. pr_err("Get sensor list NOT success for inst_id:0x%x ret:%d\n",
  335. ts->inst_id, ret);
  336. goto reg_exit;
  337. }
  338. mutex_unlock(&ts->mutex);
  339. for (i = 0; i < ts_resp->sensor_list_len; i++) {
  340. struct qmi_sensor *qmi_sens = NULL;
  341. list_for_each_entry(qmi_sens, &ts->ts_sensor_list,
  342. ts_node) {
  343. if ((strncasecmp(qmi_sens->qmi_name,
  344. ts_resp->sensor_list[i].sensor_id,
  345. QMI_TS_SENSOR_ID_LENGTH_MAX_V01)))
  346. continue;
  347. qmi_sens->connection_active = true;
  348. /*
  349. * Send a temperature request notification.
  350. */
  351. qmi_ts_request(qmi_sens, true);
  352. if (!qmi_sens->tz_dev)
  353. ret = qmi_register_sensor_device(qmi_sens);
  354. break;
  355. }
  356. }
  357. /* Check and get sensor list extended */
  358. for (i = 0; ts_resp->sensor_list_ext01_valid &&
  359. (i < ts_resp->sensor_list_ext01_len); i++) {
  360. struct qmi_sensor *qmi_sens = NULL;
  361. list_for_each_entry(qmi_sens, &ts->ts_sensor_list,
  362. ts_node) {
  363. if ((strncasecmp(qmi_sens->qmi_name,
  364. ts_resp->sensor_list_ext01[i].sensor_id,
  365. QMI_TS_SENSOR_ID_LENGTH_MAX_V01)))
  366. continue;
  367. qmi_sens->connection_active = true;
  368. /*
  369. * Send a temperature request notification.
  370. */
  371. qmi_ts_request(qmi_sens, true);
  372. if (!qmi_sens->tz_dev)
  373. ret = qmi_register_sensor_device(qmi_sens);
  374. break;
  375. }
  376. }
  377. kfree(ts_resp);
  378. return ret;
  379. reg_exit:
  380. mutex_unlock(&ts->mutex);
  381. kfree(ts_resp);
  382. return ret;
  383. }
  384. static void qmi_ts_svc_arrive(struct work_struct *work)
  385. {
  386. struct qmi_ts_instance *ts = container_of(work,
  387. struct qmi_ts_instance,
  388. svc_arrive_work);
  389. verify_sensor_and_register(ts);
  390. }
  391. static void thermal_qmi_net_reset(struct qmi_handle *qmi)
  392. {
  393. struct qmi_ts_instance *ts = container_of(qmi,
  394. struct qmi_ts_instance,
  395. handle);
  396. struct qmi_sensor *qmi_sens = NULL;
  397. int ret;
  398. pr_debug("reset QMI server\n");
  399. list_for_each_entry(qmi_sens, &ts->ts_sensor_list,
  400. ts_node) {
  401. if (!qmi_sens->connection_active)
  402. continue;
  403. qmi_ts_request(qmi_sens, true);
  404. ret = qmi_ts_request(qmi_sens, false);
  405. if (ret)
  406. pr_err("Sensor:%s set high trip:%d low trip:%d err%d\n",
  407. qmi_sens->tz_dev->type,
  408. qmi_sens->high_thresh,
  409. qmi_sens->low_thresh,
  410. ret);
  411. }
  412. }
  413. static void thermal_qmi_del_server(struct qmi_handle *qmi,
  414. struct qmi_service *service)
  415. {
  416. struct qmi_ts_instance *ts = container_of(qmi,
  417. struct qmi_ts_instance,
  418. handle);
  419. struct qmi_sensor *qmi_sens = NULL;
  420. pr_debug("QMI server deleted\n");
  421. list_for_each_entry(qmi_sens, &ts->ts_sensor_list, ts_node)
  422. qmi_sens->connection_active = false;
  423. }
  424. static int thermal_qmi_new_server(struct qmi_handle *qmi,
  425. struct qmi_service *service)
  426. {
  427. struct qmi_ts_instance *ts = container_of(qmi,
  428. struct qmi_ts_instance,
  429. handle);
  430. struct sockaddr_qrtr sq = {AF_QIPCRTR, service->node, service->port};
  431. mutex_lock(&ts->mutex);
  432. kernel_connect(qmi->sock, (struct sockaddr *)&sq, sizeof(sq), 0);
  433. mutex_unlock(&ts->mutex);
  434. queue_work(system_highpri_wq, &ts->svc_arrive_work);
  435. return 0;
  436. }
  437. static struct qmi_ops thermal_qmi_event_ops = {
  438. .new_server = thermal_qmi_new_server,
  439. .del_server = thermal_qmi_del_server,
  440. .net_reset = thermal_qmi_net_reset,
  441. };
  442. static void qmi_ts_cleanup(void)
  443. {
  444. struct qmi_ts_instance *ts;
  445. struct qmi_sensor *qmi_sens, *c_next;
  446. int idx = 0;
  447. for (; idx < ts_inst_cnt; idx++) {
  448. ts = &ts_instances[idx];
  449. mutex_lock(&ts->mutex);
  450. list_for_each_entry_safe(qmi_sens, c_next,
  451. &ts->ts_sensor_list, ts_node) {
  452. qmi_sens->connection_active = false;
  453. if (qmi_sens->tz_dev) {
  454. qti_update_tz_ops(qmi_sens->tz_dev, false);
  455. qmi_sens->tz_dev = NULL;
  456. }
  457. list_del(&qmi_sens->ts_node);
  458. }
  459. qmi_handle_release(&ts->handle);
  460. mutex_unlock(&ts->mutex);
  461. }
  462. ts_inst_cnt = 0;
  463. }
  464. static int of_get_qmi_ts_platform_data(struct device *dev)
  465. {
  466. int ret = 0, i = 0, idx = 0;
  467. struct device_node *np = dev->of_node;
  468. struct device_node *subsys_np = NULL;
  469. struct qmi_ts_instance *ts;
  470. struct qmi_sensor *qmi_sens;
  471. int sens_name_max = 0, sens_idx = 0, subsys_cnt = 0;
  472. subsys_cnt = of_get_available_child_count(np);
  473. if (!subsys_cnt) {
  474. dev_err(dev, "No child node to process\n");
  475. return -EFAULT;
  476. }
  477. ts = devm_kcalloc(dev, subsys_cnt, sizeof(*ts), GFP_KERNEL);
  478. if (!ts)
  479. return -ENOMEM;
  480. for_each_available_child_of_node(np, subsys_np) {
  481. if (idx >= subsys_cnt)
  482. break;
  483. ret = of_property_read_u32(subsys_np, "qcom,instance-id",
  484. &ts[idx].inst_id);
  485. if (ret) {
  486. dev_err(dev, "error reading qcom,insance-id. ret:%d\n",
  487. ret);
  488. goto data_fetch_err;
  489. }
  490. ts[idx].dev = dev;
  491. mutex_init(&ts[idx].mutex);
  492. INIT_LIST_HEAD(&ts[idx].ts_sensor_list);
  493. INIT_WORK(&ts[idx].svc_arrive_work, qmi_ts_svc_arrive);
  494. sens_name_max = of_property_count_strings(subsys_np,
  495. "qcom,qmi-sensor-names");
  496. if (sens_name_max <= 0) {
  497. dev_err(dev, "Invalid or no sensor. err:%d\n",
  498. sens_name_max);
  499. ret = -EINVAL;
  500. goto data_fetch_err;
  501. }
  502. for (sens_idx = 0; sens_idx < sens_name_max; sens_idx++) {
  503. const char *qmi_name;
  504. qmi_sens = devm_kzalloc(dev, sizeof(*qmi_sens),
  505. GFP_KERNEL);
  506. if (!qmi_sens) {
  507. ret = -ENOMEM;
  508. goto data_fetch_err;
  509. }
  510. of_property_read_string_index(subsys_np,
  511. "qcom,qmi-sensor-names", sens_idx,
  512. &qmi_name);
  513. strscpy(qmi_sens->qmi_name, qmi_name,
  514. QMI_CLIENT_NAME_LENGTH);
  515. /* Check for supported qmi sensors */
  516. for (i = 0; i < QMI_TS_MAX_NR; i++) {
  517. if (!strcmp(sensor_clients[i],
  518. qmi_sens->qmi_name))
  519. break;
  520. }
  521. if (i >= QMI_TS_MAX_NR) {
  522. dev_err(dev, "Unknown sensor:%s\n",
  523. qmi_sens->qmi_name);
  524. ret = -EINVAL;
  525. goto data_fetch_err;
  526. }
  527. dev_dbg(dev, "QMI sensor:%s available\n", qmi_name);
  528. qmi_sens->sens_type = i;
  529. qmi_sens->ts = &ts[idx];
  530. qmi_sens->dev = dev;
  531. qmi_sens->last_reading = 0;
  532. qmi_sens->high_thresh = INT_MAX;
  533. qmi_sens->low_thresh = -INT_MAX;
  534. INIT_WORK(&qmi_sens->therm_notify_work,
  535. qmi_ts_thresh_notify);
  536. list_add(&qmi_sens->ts_node, &ts[idx].ts_sensor_list);
  537. }
  538. idx++;
  539. }
  540. ts_instances = ts;
  541. ts_inst_cnt = subsys_cnt;
  542. return 0;
  543. data_fetch_err:
  544. of_node_put(subsys_np);
  545. return ret;
  546. }
  547. static int qmi_sens_device_probe(struct platform_device *pdev)
  548. {
  549. struct device *dev = &pdev->dev;
  550. int ret = 0, idx = 0;
  551. struct qmi_ts_instance *ts;
  552. ret = of_get_qmi_ts_platform_data(dev);
  553. if (ret)
  554. goto probe_err;
  555. if (!ts_instances || !ts_inst_cnt) {
  556. dev_err(dev, "Empty ts instances\n");
  557. return -EINVAL;
  558. }
  559. for (; idx < ts_inst_cnt; idx++) {
  560. ts = &ts_instances[idx];
  561. if (list_empty(&ts->ts_sensor_list)) {
  562. ret = -ENODEV;
  563. goto probe_err;
  564. }
  565. ret = qmi_handle_init(&ts->handle,
  566. TS_GET_SENSOR_LIST_RESP_MSG_V01_MAX_MSG_LEN,
  567. &thermal_qmi_event_ops, handlers);
  568. if (ret < 0) {
  569. dev_err(dev, "QMI[0x%x] handle init failed. err:%d\n",
  570. ts->inst_id, ret);
  571. ts_inst_cnt = idx;
  572. ret = -EPROBE_DEFER;
  573. goto probe_err;
  574. }
  575. ret = qmi_add_lookup(&ts->handle, TS_SERVICE_ID_V01,
  576. TS_SERVICE_VERS_V01, ts->inst_id);
  577. if (ret < 0) {
  578. dev_err(dev, "QMI register failed for 0x%x, ret:%d\n",
  579. ts->inst_id, ret);
  580. ret = -EPROBE_DEFER;
  581. goto probe_err;
  582. }
  583. }
  584. atomic_set(&in_suspend, 0);
  585. register_pm_notifier(&qmi_sensor_pm_nb);
  586. return 0;
  587. probe_err:
  588. qmi_ts_cleanup();
  589. return ret;
  590. }
  591. static int qmi_sens_device_remove(struct platform_device *pdev)
  592. {
  593. qmi_ts_cleanup();
  594. unregister_pm_notifier(&qmi_sensor_pm_nb);
  595. return 0;
  596. }
  597. static const struct of_device_id qmi_sens_device_match[] = {
  598. {.compatible = "qcom,qmi-sensors"},
  599. {}
  600. };
  601. static struct platform_driver qmi_sens_device_driver = {
  602. .probe = qmi_sens_device_probe,
  603. .remove = qmi_sens_device_remove,
  604. .driver = {
  605. .name = QMI_SENS_DRIVER,
  606. .of_match_table = qmi_sens_device_match,
  607. },
  608. };
  609. module_platform_driver(qmi_sens_device_driver);
  610. MODULE_LICENSE("GPL");