sec_battery_vote.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. #include "sec_battery_vote.h"
  2. #include <linux/slab.h>
  3. #include <linux/mutex.h>
  4. #include <linux/debugfs.h>
  5. static struct dentry *debug_root;
  6. static struct dentry *status_all;
  7. static LIST_HEAD(vote_list);
  8. static DEFINE_MUTEX(vote_lock);
  9. struct sec_voter {
  10. int enable;
  11. int value;
  12. int pri;
  13. };
  14. struct sec_vote {
  15. const char * name;
  16. int type;
  17. int num;
  18. struct sec_voter *voter;
  19. const char ** voter_name;
  20. int id;
  21. int res;
  22. int init_val;
  23. struct mutex lock;
  24. void * data;
  25. int(*cb)(void *data, int value);
  26. struct list_head list;
  27. struct dentry * root;
  28. struct dentry * status_ent;
  29. int force_set;
  30. int force_val;
  31. struct dentry * force_set_ent;
  32. };
  33. const char * none_str = "None";
  34. const char * force_str = "Force";
  35. static int select_min(struct sec_voter *voter, int max, int *id, int *res)
  36. {
  37. int i;
  38. int pri = INT_MIN;
  39. *res = INT_MAX;
  40. *id = -EINVAL;
  41. for (i = 0; i < max; i++) {
  42. if (voter[i].enable) {
  43. if (pri < voter[i].pri) {
  44. *res = voter[i].value;
  45. pri = voter[i].pri;
  46. *id = i;
  47. } else if (pri > voter[i].pri) {
  48. continue;
  49. } else if (*res > voter[i].value) {
  50. *res = voter[i].value;
  51. *id = i;
  52. }
  53. }
  54. }
  55. return 0;
  56. }
  57. static int select_max(struct sec_voter *voter, int max, int *id, int *res)
  58. {
  59. int i;
  60. int pri = INT_MIN;
  61. *res = INT_MIN;
  62. *id = -EINVAL;
  63. for (i = 0; i < max; i++) {
  64. if (voter[i].enable) {
  65. if (pri < voter[i].pri) {
  66. *res = voter[i].value;
  67. pri = voter[i].pri;
  68. *id = i;
  69. } else if (pri > voter[i].pri) {
  70. continue;
  71. } else if (*res < voter[i].value) {
  72. *res = voter[i].value;
  73. *id = i;
  74. }
  75. }
  76. }
  77. return 0;
  78. }
  79. static int select_enable(struct sec_voter * voter, int max, int * id, int * res)
  80. {
  81. int i;
  82. *res = 0;
  83. *id = -EINVAL;
  84. for (i = 0; i < max; i++) {
  85. if (voter[i].enable) {
  86. *res = voter[i].enable;
  87. *id = i;
  88. break;
  89. }
  90. }
  91. return 0;
  92. }
  93. static int select_vote_value(struct sec_vote * vote, int * id, int * res)
  94. {
  95. int ret = 0;
  96. switch (vote->type) {
  97. case SEC_VOTE_MIN:
  98. select_min(vote->voter, vote->num, id, res);
  99. if (*res == INT_MAX)
  100. *res = vote->init_val;
  101. break;
  102. case SEC_VOTE_MAX:
  103. select_max(vote->voter, vote->num, id, res);
  104. if (*res == INT_MIN)
  105. *res = vote->init_val;
  106. break;
  107. case SEC_VOTE_EN:
  108. select_enable(vote->voter, vote->num, id, res);
  109. break;
  110. default:
  111. pr_err("%s type invalid\n", __func__);
  112. ret = -EINVAL;
  113. }
  114. return ret;
  115. }
  116. int get_sec_vote(struct sec_vote * vote, const char ** name, int * value)
  117. {
  118. mutex_lock(&vote->lock);
  119. if (vote->id >= 0) {
  120. *name = vote->voter_name[vote->id];
  121. }
  122. else {
  123. *name = none_str;
  124. }
  125. *value = vote->res;
  126. mutex_unlock(&vote->lock);
  127. return 0;
  128. }
  129. EXPORT_SYMBOL(get_sec_vote);
  130. int get_sec_vote_result(struct sec_vote *vote)
  131. {
  132. int v;
  133. mutex_lock(&vote->lock);
  134. if (vote->force_set)
  135. v = vote->force_val;
  136. else
  137. v = vote->res;
  138. mutex_unlock(&vote->lock);
  139. return v;
  140. }
  141. EXPORT_SYMBOL(get_sec_vote_result);
  142. const char* get_sec_keyvoter_name(struct sec_vote *vote)
  143. {
  144. const char * str;
  145. mutex_lock(&vote->lock);
  146. if (vote->force_set)
  147. str = force_str;
  148. else
  149. str = (vote->id >= 0)?vote->voter_name[vote->id]: none_str;
  150. mutex_unlock(&vote->lock);
  151. return str;
  152. }
  153. EXPORT_SYMBOL(get_sec_keyvoter_name);
  154. int get_sec_voter_status(struct sec_vote *vote, int id, int * v)
  155. {
  156. if (id >= vote->num || id < 0)
  157. return -EINVAL;
  158. mutex_lock(&vote->lock);
  159. if (vote->type == SEC_VOTE_EN)
  160. *v = vote->voter[id].enable;
  161. else if (vote->voter[id].enable)
  162. *v = vote->voter[id].value;
  163. else
  164. *v = INT_MIN;
  165. mutex_unlock(&vote->lock);
  166. return (*v == INT_MIN) ? -EINVAL : 0;
  167. }
  168. EXPORT_SYMBOL(get_sec_voter_status);
  169. int show_sec_vote_status(char *buf, unsigned int p_size)
  170. {
  171. struct sec_vote *vote;
  172. int i, j = 0;
  173. char *type_str = "Unkonwn";
  174. if (list_empty(&vote_list)) {
  175. j += scnprintf(buf + j, p_size - j, "No vote\n");
  176. return j;
  177. }
  178. mutex_lock(&vote_lock);
  179. list_for_each_entry(vote, &vote_list, list) {
  180. mutex_lock(&vote->lock);
  181. for (i = 0; i < vote->num; i++) {
  182. if (vote->voter[i].enable) {
  183. j += scnprintf(buf + j, p_size - j, "%s: %s:\t\t\ten=%d v=%d p=%d\n",
  184. vote->name,
  185. vote->voter_name[i],
  186. vote->voter[i].enable,
  187. vote->voter[i].value,
  188. vote->voter[i].pri);
  189. }
  190. }
  191. switch (vote->type) {
  192. case SEC_VOTE_MIN:
  193. type_str = "Min";
  194. break;
  195. case SEC_VOTE_MAX:
  196. type_str = "Max";
  197. break;
  198. case SEC_VOTE_EN:
  199. type_str = "Set_any";
  200. break;
  201. default:
  202. type_str = "Invalid";
  203. }
  204. j += scnprintf(buf + j, p_size - j, "%s: INIT: v=%d\n",
  205. vote->name, vote->init_val);
  206. if (vote->force_set) {
  207. j += scnprintf(buf + j, p_size - j, "%s: voter=%s type=%s v=%d\n",
  208. vote->name, force_str, type_str, vote->force_val);
  209. } else {
  210. j += scnprintf(buf + j, p_size - j, "%s: voter=%s type=%s v=%d\n",
  211. vote->name,
  212. (vote->id >= 0) ? vote->voter_name[vote->id] : none_str,
  213. type_str, vote->res);
  214. }
  215. mutex_unlock(&vote->lock);
  216. }
  217. mutex_unlock(&vote_lock);
  218. return j;
  219. }
  220. EXPORT_SYMBOL(show_sec_vote_status);
  221. static int show_vote_clients(struct seq_file *m, void *data)
  222. {
  223. struct sec_vote *vote = m->private;
  224. int i;
  225. char *type_str = "Unkonwn";
  226. mutex_lock(&vote->lock);
  227. for (i = 0; i < vote->num; i++) {
  228. if (vote->voter[i].enable) {
  229. seq_printf(m, "%s: %s:\t\t\ten=%d v=%d p=%d\n",
  230. vote->name,
  231. vote->voter_name[i],
  232. vote->voter[i].enable,
  233. vote->voter[i].value,
  234. vote->voter[i].pri);
  235. }
  236. }
  237. switch (vote->type) {
  238. case SEC_VOTE_MIN:
  239. type_str = "Min";
  240. break;
  241. case SEC_VOTE_MAX:
  242. type_str = "Max";
  243. break;
  244. case SEC_VOTE_EN:
  245. type_str = "Set_any";
  246. break;
  247. default:
  248. type_str = "Invalid";
  249. }
  250. seq_printf(m, "%s: INIT: v=%d\n",
  251. vote->name, vote->init_val);
  252. if (vote->force_set) {
  253. seq_printf(m, "%s: voter=%s type=%s v=%d\n",
  254. vote->name, force_str, type_str, vote->force_val);
  255. } else {
  256. seq_printf(m, "%s: voter=%s type=%s v=%d\n",
  257. vote->name,
  258. (vote->id >= 0)?vote->voter_name[vote->id]: none_str,
  259. type_str, vote->res);
  260. }
  261. mutex_unlock(&vote->lock);
  262. return 0;
  263. }
  264. static int vote_status_open(struct inode *inode, struct file *file)
  265. {
  266. struct sec_vote *vote = inode->i_private;
  267. return single_open(file, show_vote_clients, vote);
  268. }
  269. static const struct file_operations vote_status_ops = {
  270. .owner = THIS_MODULE,
  271. .open = vote_status_open,
  272. .read = seq_read,
  273. .llseek = seq_lseek,
  274. .release = single_release,
  275. };
  276. static int show_all_clients(struct seq_file *m, void *data)
  277. {
  278. struct sec_vote *vote;
  279. int i;
  280. char *type_str = "Unkonwn";
  281. if (list_empty(&vote_list)) {
  282. seq_printf(m, "No vote\n");
  283. return 0;
  284. }
  285. mutex_lock(&vote_lock);
  286. list_for_each_entry(vote, &vote_list, list) {
  287. mutex_lock(&vote->lock);
  288. for (i = 0; i < vote->num; i++) {
  289. if (vote->voter[i].enable) {
  290. seq_printf(m, "%s: %s:\t\t\ten=%d v=%d p=%d\n",
  291. vote->name,
  292. vote->voter_name[i],
  293. vote->voter[i].enable,
  294. vote->voter[i].value,
  295. vote->voter[i].pri);
  296. }
  297. }
  298. switch (vote->type) {
  299. case SEC_VOTE_MIN:
  300. type_str = "Min";
  301. break;
  302. case SEC_VOTE_MAX:
  303. type_str = "Max";
  304. break;
  305. case SEC_VOTE_EN:
  306. type_str = "Set_any";
  307. break;
  308. default:
  309. type_str = "Invalid";
  310. }
  311. seq_printf(m, "%s: INIT: v=%d\n",
  312. vote->name, vote->init_val);
  313. if (vote->force_set) {
  314. seq_printf(m, "%s: voter=%s type=%s v=%d\n",
  315. vote->name, force_str, type_str, vote->force_val);
  316. } else {
  317. seq_printf(m, "%s: voter=%s type=%s v=%d\n",
  318. vote->name,
  319. (vote->id >= 0)?vote->voter_name[vote->id]: none_str,
  320. type_str, vote->res);
  321. }
  322. mutex_unlock(&vote->lock);
  323. }
  324. mutex_unlock(&vote_lock);
  325. return 0;
  326. }
  327. static int vote_status_all_open(struct inode *inode, struct file *file)
  328. {
  329. return single_open(file, show_all_clients, NULL);
  330. }
  331. static const struct file_operations vote_status_all_ops = {
  332. .owner = THIS_MODULE,
  333. .open = vote_status_all_open,
  334. .read = seq_read,
  335. .llseek = seq_lseek,
  336. .release = single_release,
  337. };
  338. static int force_get(void *data, u64 *val)
  339. {
  340. struct sec_vote *vote = data;
  341. *val = vote->force_set;
  342. return 0;
  343. }
  344. static int force_set(void *data, u64 val)
  345. {
  346. struct sec_vote *vote = data;
  347. mutex_lock(&vote->lock);
  348. vote->force_set = val;
  349. if (!vote->cb)
  350. goto out;
  351. if (vote->force_set) {
  352. vote->res = vote->cb(vote->data, vote->force_val);
  353. } else {
  354. vote->res = vote->cb(vote->data, vote->res);
  355. }
  356. out:
  357. mutex_unlock(&vote->lock);
  358. return 0;
  359. }
  360. DEFINE_SIMPLE_ATTRIBUTE(vote_force_ops, force_get, force_set, "%lld\n");
  361. struct sec_vote *find_vote(const char *name)
  362. {
  363. struct sec_vote *vote;
  364. list_for_each_entry(vote, &vote_list, list) {
  365. if (strcmp(vote->name, name) == 0) {
  366. return vote;
  367. }
  368. }
  369. return NULL;
  370. }
  371. EXPORT_SYMBOL(find_vote);
  372. struct sec_vote *sec_vote_init(const char *name, int type, int num, int init_val,
  373. const char **voter_name, int(*cb)(void *data, int value), void *data)
  374. {
  375. struct sec_vote * vote = NULL;
  376. struct sec_voter * voter = NULL;
  377. mutex_lock(&vote_lock);
  378. vote = find_vote(name);
  379. if (vote) {
  380. pr_info("%s: %s exist \n", __func__, name);
  381. goto err;
  382. }
  383. if (voter_name == NULL) {
  384. pr_info("%s: Please add voter name list \n", __func__);
  385. goto err;
  386. }
  387. vote = kzalloc(sizeof(struct sec_vote), GFP_KERNEL);
  388. if (!vote) {
  389. pr_info("%s: mem aloocate fail \n", __func__);
  390. goto err;
  391. }
  392. vote->name = name;
  393. vote->type = type;
  394. voter = kzalloc(sizeof(struct sec_voter) * num, GFP_KERNEL);
  395. if (!voter) {
  396. pr_info("%s: mem aloocate fail \n", __func__);
  397. kfree(vote);
  398. goto err;
  399. }
  400. vote->voter = voter;
  401. vote->num = num;
  402. vote->voter_name = voter_name;
  403. vote->init_val = init_val;
  404. vote->cb = cb;
  405. vote->id = -EINVAL;
  406. vote->res = -EINVAL;
  407. vote->data = data;
  408. mutex_init(&vote->lock);
  409. if (debug_root == NULL) {
  410. debug_root = debugfs_create_dir("sec-vote", NULL);
  411. if (!debug_root) {
  412. pr_err("Couldn't create debug dir\n");
  413. } else {
  414. status_all = debugfs_create_file("status_all",
  415. S_IFREG | 0444,
  416. debug_root, NULL,
  417. &vote_status_all_ops);
  418. if (!status_all) {
  419. pr_err("Couldn't create status_all dbg file \n");
  420. }
  421. }
  422. }
  423. if (debug_root)
  424. vote->root = debugfs_create_dir(name, debug_root);
  425. if (!vote->root) {
  426. pr_err("Couldn't create debug dir %s\n", name);
  427. } else {
  428. vote->status_ent = debugfs_create_file("status", S_IFREG | 0444,
  429. vote->root, vote,
  430. &vote_status_ops);
  431. if (!vote->status_ent) {
  432. pr_err("Couldn't create status dbg file for %s\n", name);
  433. }
  434. debugfs_create_u32("force_val", S_IFREG | 0644,
  435. vote->root, &(vote->force_val));
  436. vote->force_set_ent = debugfs_create_file("force_set",
  437. S_IFREG | 0444,
  438. vote->root, vote,
  439. &vote_force_ops);
  440. if (!vote->force_set_ent) {
  441. pr_err("Couldn't create force_set dbg file for %s\n", name);
  442. }
  443. }
  444. pr_info("%s: %s \n", __func__, name);
  445. list_add(&vote->list, &vote_list);
  446. mutex_unlock(&vote_lock);
  447. return vote;
  448. err:
  449. mutex_unlock(&vote_lock);
  450. return NULL;
  451. }
  452. EXPORT_SYMBOL(sec_vote_init);
  453. void sec_vote_destroy(struct sec_vote *vote)
  454. {
  455. pr_info("%s: %s\n", __func__, vote->name);
  456. list_del(&vote->list);
  457. kfree(vote->voter);
  458. debugfs_remove_recursive(vote->root);
  459. mutex_destroy(&vote->lock);
  460. kfree(vote);
  461. }
  462. EXPORT_SYMBOL(sec_vote_destroy);
  463. void change_sec_voter_pri(struct sec_vote *vote, int event, int pri)
  464. {
  465. if (event >= vote->num) {
  466. pr_info("%s id Error(%d)\n", __func__, event);
  467. return;
  468. }
  469. mutex_lock(&vote->lock);
  470. vote->voter[event].pri = pri;
  471. mutex_unlock(&vote->lock);
  472. }
  473. EXPORT_SYMBOL(change_sec_voter_pri);
  474. void _sec_vote(struct sec_vote *vote, int event, int en, int value, const char *fname, int line)
  475. {
  476. int id, res, ret;
  477. if (event >= vote->num) {
  478. pr_info("%s id Error(%d)\n", __func__, event);
  479. return;
  480. }
  481. mutex_lock(&vote->lock);
  482. pr_debug("%s, %s en: %d->%d, v: %d->%d\n", vote->name,vote->voter_name[event],
  483. vote->voter[event].enable, en, vote->voter[event].value, value);
  484. if ((vote->voter[event].enable == en) &&
  485. (((vote->voter[event].value == value) || !en)))
  486. goto out;
  487. vote->voter[event].enable = en;
  488. vote->voter[event].value = value;
  489. ret = select_vote_value(vote, &id, &res);
  490. if (ret < 0)
  491. goto out;
  492. pr_info("%s(%s:%d): %s (%s, %d) -> (%s, %d)\n", __func__, fname, line, vote->name,
  493. (vote->id >= 0) ? vote->voter_name[vote->id] : none_str, vote->res,
  494. (id >= 0) ? vote->voter_name[id] : none_str, res);
  495. if (res != vote->res) {
  496. vote->id = id;
  497. vote->res = res;
  498. if (vote->force_set)
  499. pr_err("%s skip by force_set\n", __func__);
  500. else
  501. vote->res = vote->cb(vote->data, res);
  502. } else if (!en && (vote->id == event)) {
  503. vote->id = id;
  504. }
  505. out:
  506. mutex_unlock(&vote->lock);
  507. }
  508. EXPORT_SYMBOL(_sec_vote);
  509. void sec_vote_refresh(struct sec_vote *vote)
  510. {
  511. mutex_lock(&vote->lock);
  512. if (vote->res == -EINVAL && vote->id == -EINVAL) {
  513. pr_info("%s: skip. not used before\n", __func__);
  514. } else {
  515. if (vote->force_set) {
  516. pr_info("%s: refresh (%s, %d)\n", vote->name, force_str, vote->force_val);
  517. vote->res = vote->cb(vote->data, vote->force_val);
  518. } else {
  519. int id, res, ret;
  520. ret = select_vote_value(vote, &id, &res);
  521. pr_info("%s: refresh (%s, %d, %d)\n", vote->name,
  522. (id >= 0) ? vote->voter_name[id] : none_str, res, ret);
  523. if (ret < 0)
  524. goto out;
  525. vote->res = vote->cb(vote->data, res);
  526. }
  527. }
  528. out:
  529. mutex_unlock(&vote->lock);
  530. }
  531. EXPORT_SYMBOL(sec_vote_refresh);
  532. const char *get_sec_vote_name(struct sec_vote *vote)
  533. {
  534. return vote->name;
  535. }
  536. EXPORT_SYMBOL(get_sec_vote_name);