pmic-voter.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015-2017, 2019-2020, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/debugfs.h>
  7. #include <linux/spinlock.h>
  8. #include <linux/errno.h>
  9. #include <linux/bitops.h>
  10. #include <linux/printk.h>
  11. #include <linux/slab.h>
  12. #include <linux/string.h>
  13. #include <linux/pmic-voter.h>
  14. #define NUM_MAX_CLIENTS 32
  15. #define DEBUG_FORCE_CLIENT "DEBUG_FORCE_CLIENT"
  16. static DEFINE_SPINLOCK(votable_list_slock);
  17. static LIST_HEAD(votable_list);
  18. static struct dentry *debug_root;
  19. struct client_vote {
  20. bool enabled;
  21. int value;
  22. };
  23. struct votable {
  24. const char *name;
  25. const char *override_client;
  26. struct list_head list;
  27. struct client_vote votes[NUM_MAX_CLIENTS];
  28. int num_clients;
  29. int type;
  30. int effective_client_id;
  31. int effective_result;
  32. int override_result;
  33. struct mutex vote_lock;
  34. void *data;
  35. int (*callback)(struct votable *votable,
  36. void *data,
  37. int effective_result,
  38. const char *effective_client);
  39. char *client_strs[NUM_MAX_CLIENTS];
  40. bool voted_on;
  41. struct dentry *root;
  42. struct dentry *status_ent;
  43. u32 force_val;
  44. struct dentry *force_val_ent;
  45. bool force_active;
  46. struct dentry *force_active_ent;
  47. };
  48. /**
  49. * vote_set_any()
  50. * @votable: votable object
  51. * @client_id: client number of the latest voter
  52. * @eff_res: sets 0 or 1 based on the voting
  53. * @eff_id: Always returns the client_id argument
  54. *
  55. * Note that for SET_ANY voter, the value is always same as enabled. There is
  56. * no idea of a voter abstaining from the election. Hence there is never a
  57. * situation when the effective_id will be invalid, during election.
  58. *
  59. * Context:
  60. * Must be called with the votable->lock held
  61. */
  62. static void vote_set_any(struct votable *votable, int client_id,
  63. int *eff_res, int *eff_id)
  64. {
  65. int i;
  66. *eff_res = 0;
  67. for (i = 0; i < votable->num_clients && votable->client_strs[i]; i++)
  68. *eff_res |= votable->votes[i].enabled;
  69. *eff_id = client_id;
  70. }
  71. /**
  72. * vote_min() -
  73. * @votable: votable object
  74. * @client_id: client number of the latest voter
  75. * @eff_res: sets this to the min. of all the values amongst enabled voters.
  76. * If there is no enabled client, this is set to INT_MAX
  77. * @eff_id: sets this to the client id that has the min value amongst all
  78. * the enabled clients. If there is no enabled client, sets this
  79. * to -EINVAL
  80. *
  81. * Context:
  82. * Must be called with the votable->lock held
  83. */
  84. static void vote_min(struct votable *votable, int client_id,
  85. int *eff_res, int *eff_id)
  86. {
  87. int i;
  88. *eff_res = INT_MAX;
  89. *eff_id = -EINVAL;
  90. for (i = 0; i < votable->num_clients && votable->client_strs[i]; i++) {
  91. if (votable->votes[i].enabled
  92. && *eff_res > votable->votes[i].value) {
  93. *eff_res = votable->votes[i].value;
  94. *eff_id = i;
  95. }
  96. }
  97. if (*eff_id == -EINVAL)
  98. *eff_res = -EINVAL;
  99. }
  100. /**
  101. * vote_max() -
  102. * @votable: votable object
  103. * @client_id: client number of the latest voter
  104. * @eff_res: sets this to the max. of all the values amongst enabled voters.
  105. * If there is no enabled client, this is set to -EINVAL
  106. * @eff_id: sets this to the client id that has the max value amongst all
  107. * the enabled clients. If there is no enabled client, sets this to
  108. * -EINVAL
  109. *
  110. * Context:
  111. * Must be called with the votable->lock held
  112. */
  113. static void vote_max(struct votable *votable, int client_id,
  114. int *eff_res, int *eff_id)
  115. {
  116. int i;
  117. *eff_res = INT_MIN;
  118. *eff_id = -EINVAL;
  119. for (i = 0; i < votable->num_clients && votable->client_strs[i]; i++) {
  120. if (votable->votes[i].enabled &&
  121. *eff_res < votable->votes[i].value) {
  122. *eff_res = votable->votes[i].value;
  123. *eff_id = i;
  124. }
  125. }
  126. if (*eff_id == -EINVAL)
  127. *eff_res = -EINVAL;
  128. }
  129. static int get_client_id(struct votable *votable, const char *client_str)
  130. {
  131. int i;
  132. for (i = 0; i < votable->num_clients; i++) {
  133. if (votable->client_strs[i]
  134. && (strcmp(votable->client_strs[i], client_str) == 0))
  135. return i;
  136. }
  137. /* new client */
  138. for (i = 0; i < votable->num_clients; i++) {
  139. if (!votable->client_strs[i]) {
  140. votable->client_strs[i]
  141. = kstrdup(client_str, GFP_KERNEL);
  142. if (!votable->client_strs[i])
  143. return -ENOMEM;
  144. return i;
  145. }
  146. }
  147. return -EINVAL;
  148. }
  149. static char *get_client_str(struct votable *votable, int client_id)
  150. {
  151. if (!votable || (client_id == -EINVAL))
  152. return NULL;
  153. return votable->client_strs[client_id];
  154. }
  155. void lock_votable(struct votable *votable)
  156. {
  157. mutex_lock(&votable->vote_lock);
  158. }
  159. EXPORT_SYMBOL_GPL(lock_votable);
  160. void unlock_votable(struct votable *votable)
  161. {
  162. mutex_unlock(&votable->vote_lock);
  163. }
  164. EXPORT_SYMBOL_GPL(unlock_votable);
  165. /**
  166. * is_override_vote_enabled() -
  167. * is_override_vote_enabled_locked() -
  168. * The unlocked and locked variants of getting whether override
  169. vote is enabled.
  170. * @votable: the votable object
  171. *
  172. * Returns:
  173. * True if the client's vote is enabled; false otherwise.
  174. */
  175. bool is_override_vote_enabled_locked(struct votable *votable)
  176. {
  177. if (!votable)
  178. return false;
  179. return votable->override_result != -EINVAL;
  180. }
  181. EXPORT_SYMBOL_GPL(is_override_vote_enabled_locked);
  182. bool is_override_vote_enabled(struct votable *votable)
  183. {
  184. bool enable;
  185. if (!votable)
  186. return false;
  187. lock_votable(votable);
  188. enable = is_override_vote_enabled_locked(votable);
  189. unlock_votable(votable);
  190. return enable;
  191. }
  192. EXPORT_SYMBOL_GPL(is_override_vote_enabled);
  193. /**
  194. * is_client_vote_enabled() -
  195. * is_client_vote_enabled_locked() -
  196. * The unlocked and locked variants of getting whether a client's
  197. vote is enabled.
  198. * @votable: the votable object
  199. * @client_str: client of interest
  200. *
  201. * Returns:
  202. * True if the client's vote is enabled; false otherwise.
  203. */
  204. bool is_client_vote_enabled_locked(struct votable *votable,
  205. const char *client_str)
  206. {
  207. int client_id;
  208. if (!votable || !client_str)
  209. return false;
  210. client_id = get_client_id(votable, client_str);
  211. if (client_id < 0)
  212. return false;
  213. return votable->votes[client_id].enabled;
  214. }
  215. EXPORT_SYMBOL_GPL(is_client_vote_enabled_locked);
  216. bool is_client_vote_enabled(struct votable *votable, const char *client_str)
  217. {
  218. bool enabled;
  219. if (!votable || !client_str)
  220. return false;
  221. lock_votable(votable);
  222. enabled = is_client_vote_enabled_locked(votable, client_str);
  223. unlock_votable(votable);
  224. return enabled;
  225. }
  226. EXPORT_SYMBOL_GPL(is_client_vote_enabled);
  227. /**
  228. * get_client_vote() -
  229. * get_client_vote_locked() -
  230. * The unlocked and locked variants of getting a client's voted
  231. * value.
  232. * @votable: the votable object
  233. * @client_str: client of interest
  234. *
  235. * Returns:
  236. * The value the client voted for. -EINVAL is returned if the client
  237. * is not enabled or the client is not found.
  238. */
  239. int get_client_vote_locked(struct votable *votable, const char *client_str)
  240. {
  241. int client_id;
  242. if (!votable || !client_str)
  243. return -EINVAL;
  244. client_id = get_client_id(votable, client_str);
  245. if (client_id < 0)
  246. return -EINVAL;
  247. if ((votable->type != VOTE_SET_ANY)
  248. && !votable->votes[client_id].enabled)
  249. return -EINVAL;
  250. return votable->votes[client_id].value;
  251. }
  252. EXPORT_SYMBOL_GPL(get_client_vote_locked);
  253. int get_client_vote(struct votable *votable, const char *client_str)
  254. {
  255. int value;
  256. if (!votable || !client_str)
  257. return -EINVAL;
  258. lock_votable(votable);
  259. value = get_client_vote_locked(votable, client_str);
  260. unlock_votable(votable);
  261. return value;
  262. }
  263. EXPORT_SYMBOL_GPL(get_client_vote);
  264. /**
  265. * get_effective_result() -
  266. * get_effective_result_locked() -
  267. * The unlocked and locked variants of getting the effective value
  268. * amongst all the enabled voters.
  269. *
  270. * @votable: the votable object
  271. *
  272. * Returns:
  273. * The effective result.
  274. * For MIN and MAX votable, returns -EINVAL when the votable
  275. * object has been created but no clients have casted their votes or
  276. * the last enabled client disables its vote.
  277. * For SET_ANY votable it returns 0 when no clients have casted their votes
  278. * because for SET_ANY there is no concept of abstaining from election. The
  279. * votes for all the clients of SET_ANY votable is defaulted to false.
  280. */
  281. int get_effective_result_locked(struct votable *votable)
  282. {
  283. if (!votable)
  284. return -EINVAL;
  285. if (votable->force_active)
  286. return votable->force_val;
  287. if (votable->override_result != -EINVAL)
  288. return votable->override_result;
  289. return votable->effective_result;
  290. }
  291. EXPORT_SYMBOL_GPL(get_effective_result_locked);
  292. int get_effective_result(struct votable *votable)
  293. {
  294. int value;
  295. if (!votable)
  296. return -EINVAL;
  297. lock_votable(votable);
  298. value = get_effective_result_locked(votable);
  299. unlock_votable(votable);
  300. return value;
  301. }
  302. EXPORT_SYMBOL_GPL(get_effective_result);
  303. /**
  304. * get_effective_client() -
  305. * get_effective_client_locked() -
  306. * The unlocked and locked variants of getting the effective client
  307. * amongst all the enabled voters.
  308. *
  309. * @votable: the votable object
  310. *
  311. * Returns:
  312. * The effective client.
  313. * For MIN and MAX votable, returns NULL when the votable
  314. * object has been created but no clients have casted their votes or
  315. * the last enabled client disables its vote.
  316. * For SET_ANY votable it returns NULL too when no clients have casted
  317. * their votes. But for SET_ANY since there is no concept of abstaining
  318. * from election, the only client that casts a vote or the client that
  319. * caused the result to change is returned.
  320. */
  321. const char *get_effective_client_locked(struct votable *votable)
  322. {
  323. if (!votable)
  324. return NULL;
  325. if (votable->force_active)
  326. return DEBUG_FORCE_CLIENT;
  327. if (votable->override_result != -EINVAL)
  328. return votable->override_client;
  329. return get_client_str(votable, votable->effective_client_id);
  330. }
  331. EXPORT_SYMBOL_GPL(get_effective_client_locked);
  332. const char *get_effective_client(struct votable *votable)
  333. {
  334. const char *client_str;
  335. if (!votable)
  336. return NULL;
  337. lock_votable(votable);
  338. client_str = get_effective_client_locked(votable);
  339. unlock_votable(votable);
  340. return client_str;
  341. }
  342. EXPORT_SYMBOL_GPL(get_effective_client);
  343. /**
  344. * vote() -
  345. *
  346. * @votable: the votable object
  347. * @client_str: the voting client
  348. * @enabled: This provides a means for the client to exclude himself from
  349. * election. This clients val (the next argument) will be
  350. * considered only when he has enabled his participation.
  351. * Note that this takes a differnt meaning for SET_ANY type, as
  352. * there is no concept of abstaining from participation.
  353. * Enabled is treated as the boolean value the client is voting.
  354. * @val: The vote value. This is ignored for SET_ANY votable types.
  355. * For MIN, MAX votable types this value is used as the
  356. * clients vote value when the enabled is true, this value is
  357. * ignored if enabled is false.
  358. *
  359. * The callback is called only when there is a change in the election results or
  360. * if it is the first time someone is voting.
  361. *
  362. * Returns:
  363. * The return from the callback when present and needs to be called
  364. * or zero.
  365. */
  366. int vote(struct votable *votable, const char *client_str, bool enabled, int val)
  367. {
  368. int effective_id = -EINVAL;
  369. int effective_result;
  370. int client_id;
  371. int rc = 0;
  372. bool similar_vote = false;
  373. if (!votable || !client_str)
  374. return -EINVAL;
  375. lock_votable(votable);
  376. client_id = get_client_id(votable, client_str);
  377. if (client_id < 0) {
  378. rc = client_id;
  379. goto out;
  380. }
  381. /*
  382. * for SET_ANY the val is to be ignored, set it
  383. * to enabled so that the election still works based on
  384. * value regardless of the type
  385. */
  386. if (votable->type == VOTE_SET_ANY)
  387. val = enabled;
  388. if ((votable->votes[client_id].enabled == enabled) &&
  389. (votable->votes[client_id].value == val)) {
  390. pr_debug("%s: %s,%d same voting %s of val=%d\n",
  391. votable->name,
  392. client_str, client_id,
  393. enabled ? "on" : "off",
  394. val);
  395. similar_vote = true;
  396. }
  397. votable->votes[client_id].enabled = enabled;
  398. votable->votes[client_id].value = val;
  399. if (similar_vote && votable->voted_on) {
  400. pr_debug("%s: %s,%d Ignoring similar voting %s of val=%d\n",
  401. votable->name,
  402. client_str, client_id, enabled ? "on" : "off", val);
  403. goto out;
  404. }
  405. pr_debug("%s: %s,%d voting %s of val=%d\n",
  406. votable->name,
  407. client_str, client_id, enabled ? "on" : "off", val);
  408. switch (votable->type) {
  409. case VOTE_MIN:
  410. vote_min(votable, client_id, &effective_result, &effective_id);
  411. break;
  412. case VOTE_MAX:
  413. vote_max(votable, client_id, &effective_result, &effective_id);
  414. break;
  415. case VOTE_SET_ANY:
  416. vote_set_any(votable, client_id,
  417. &effective_result, &effective_id);
  418. break;
  419. default:
  420. return -EINVAL;
  421. }
  422. /*
  423. * Note that the callback is called with a NULL string and -EINVAL
  424. * result when there are no enabled votes
  425. */
  426. if (!votable->voted_on
  427. || (effective_result != votable->effective_result)) {
  428. votable->effective_client_id = effective_id;
  429. votable->effective_result = effective_result;
  430. pr_debug("%s: effective voting is now %d voted by %s,%d\n",
  431. votable->name, effective_result,
  432. get_client_str(votable, effective_id),
  433. effective_id);
  434. if (votable->callback && !votable->force_active
  435. && (votable->override_result == -EINVAL))
  436. rc = votable->callback(votable, votable->data,
  437. effective_result,
  438. get_client_str(votable, effective_id));
  439. }
  440. votable->voted_on = true;
  441. out:
  442. unlock_votable(votable);
  443. return rc;
  444. }
  445. EXPORT_SYMBOL_GPL(vote);
  446. /**
  447. * vote_override() -
  448. *
  449. * @votable: The votable object
  450. * @override_client: The voting client that will override other client's
  451. * votes, that are already present. When force_active
  452. * and override votes are set on a votable, force_active's
  453. * client will have the higher priority and it's vote will
  454. * be the effective one.
  455. * @enabled: This provides a means for the override client to exclude
  456. * itself from election. This client's vote
  457. * (the next argument) will be considered only when
  458. * it has enabled its participation. When this is
  459. * set true, this will force a value on a MIN/MAX votable
  460. * irrespective of its current value.
  461. * @val: The vote value. This will be effective only if enabled
  462. * is set true.
  463. * Returns:
  464. * The result of vote. 0 is returned if the vote
  465. * is successfully set by the overriding client, when enabled is set.
  466. */
  467. int vote_override(struct votable *votable, const char *override_client,
  468. bool enabled, int val)
  469. {
  470. int rc = 0;
  471. if (!votable || !override_client)
  472. return -EINVAL;
  473. lock_votable(votable);
  474. if (votable->force_active) {
  475. votable->override_result = enabled ? val : -EINVAL;
  476. goto out;
  477. }
  478. if (enabled) {
  479. rc = votable->callback(votable, votable->data,
  480. val, override_client);
  481. if (!rc) {
  482. votable->override_client = override_client;
  483. votable->override_result = val;
  484. }
  485. } else {
  486. rc = votable->callback(votable, votable->data,
  487. votable->effective_result,
  488. get_client_str(votable, votable->effective_client_id));
  489. votable->override_result = -EINVAL;
  490. }
  491. out:
  492. unlock_votable(votable);
  493. return rc;
  494. }
  495. EXPORT_SYMBOL_GPL(vote_override);
  496. int rerun_election(struct votable *votable)
  497. {
  498. int rc = 0;
  499. int effective_result;
  500. if (!votable)
  501. return -EINVAL;
  502. lock_votable(votable);
  503. effective_result = get_effective_result_locked(votable);
  504. if (votable->callback)
  505. rc = votable->callback(votable,
  506. votable->data,
  507. effective_result,
  508. get_client_str(votable, votable->effective_client_id));
  509. unlock_votable(votable);
  510. return rc;
  511. }
  512. EXPORT_SYMBOL_GPL(rerun_election);
  513. struct votable *find_votable(const char *name)
  514. {
  515. unsigned long flags;
  516. struct votable *v;
  517. bool found = false;
  518. if (!name)
  519. return NULL;
  520. spin_lock_irqsave(&votable_list_slock, flags);
  521. if (list_empty(&votable_list))
  522. goto out;
  523. list_for_each_entry(v, &votable_list, list) {
  524. if (strcmp(v->name, name) == 0) {
  525. found = true;
  526. break;
  527. }
  528. }
  529. out:
  530. spin_unlock_irqrestore(&votable_list_slock, flags);
  531. if (found)
  532. return v;
  533. else
  534. return NULL;
  535. }
  536. EXPORT_SYMBOL_GPL(find_votable);
  537. static int force_active_get(void *data, u64 *val)
  538. {
  539. struct votable *votable = data;
  540. *val = votable->force_active;
  541. return 0;
  542. }
  543. static int force_active_set(void *data, u64 val)
  544. {
  545. struct votable *votable = data;
  546. int rc = 0;
  547. int effective_result;
  548. const char *client;
  549. lock_votable(votable);
  550. votable->force_active = !!val;
  551. if (!votable->callback)
  552. goto out;
  553. if (votable->force_active) {
  554. rc = votable->callback(votable, votable->data,
  555. votable->force_val,
  556. DEBUG_FORCE_CLIENT);
  557. } else {
  558. if (votable->override_result != -EINVAL) {
  559. effective_result = votable->override_result;
  560. client = votable->override_client;
  561. } else {
  562. effective_result = votable->effective_result;
  563. client = get_client_str(votable,
  564. votable->effective_client_id);
  565. }
  566. rc = votable->callback(votable, votable->data, effective_result,
  567. client);
  568. }
  569. out:
  570. unlock_votable(votable);
  571. return rc;
  572. }
  573. DEFINE_DEBUGFS_ATTRIBUTE(votable_force_ops, force_active_get, force_active_set,
  574. "%lld\n");
  575. static int show_votable_clients(struct seq_file *m, void *data)
  576. {
  577. struct votable *votable = m->private;
  578. int i;
  579. char *type_str = "Unkonwn";
  580. const char *effective_client_str;
  581. lock_votable(votable);
  582. for (i = 0; i < votable->num_clients; i++) {
  583. if (votable->client_strs[i]) {
  584. seq_printf(m, "%s: %s:\t\t\ten=%d v=%d\n",
  585. votable->name,
  586. votable->client_strs[i],
  587. votable->votes[i].enabled,
  588. votable->votes[i].value);
  589. }
  590. }
  591. switch (votable->type) {
  592. case VOTE_MIN:
  593. type_str = "Min";
  594. break;
  595. case VOTE_MAX:
  596. type_str = "Max";
  597. break;
  598. case VOTE_SET_ANY:
  599. type_str = "Set_any";
  600. break;
  601. }
  602. effective_client_str = get_effective_client_locked(votable);
  603. seq_printf(m, "%s: effective=%s type=%s v=%d\n",
  604. votable->name,
  605. effective_client_str ? effective_client_str : "none",
  606. type_str,
  607. get_effective_result_locked(votable));
  608. unlock_votable(votable);
  609. return 0;
  610. }
  611. static int votable_status_open(struct inode *inode, struct file *file)
  612. {
  613. struct votable *votable = inode->i_private;
  614. return single_open(file, show_votable_clients, votable);
  615. }
  616. static const struct file_operations votable_status_ops = {
  617. .owner = THIS_MODULE,
  618. .open = votable_status_open,
  619. .read = seq_read,
  620. .llseek = seq_lseek,
  621. .release = single_release,
  622. };
  623. struct votable *create_votable(const char *name,
  624. int votable_type,
  625. int (*callback)(struct votable *votable,
  626. void *data,
  627. int effective_result,
  628. const char *effective_client),
  629. void *data)
  630. {
  631. struct votable *votable;
  632. unsigned long flags;
  633. if (!name)
  634. return ERR_PTR(-EINVAL);
  635. votable = find_votable(name);
  636. if (votable)
  637. return ERR_PTR(-EEXIST);
  638. if (debug_root == NULL) {
  639. debug_root = debugfs_create_dir("pmic-votable", NULL);
  640. if (!debug_root) {
  641. pr_err("Couldn't create debug dir\n");
  642. return ERR_PTR(-ENOMEM);
  643. }
  644. }
  645. if (votable_type >= NUM_VOTABLE_TYPES) {
  646. pr_err("Invalid votable_type specified for voter\n");
  647. return ERR_PTR(-EINVAL);
  648. }
  649. votable = kzalloc(sizeof(struct votable), GFP_KERNEL);
  650. if (!votable)
  651. return ERR_PTR(-ENOMEM);
  652. votable->name = kstrdup(name, GFP_KERNEL);
  653. if (!votable->name) {
  654. kfree(votable);
  655. return ERR_PTR(-ENOMEM);
  656. }
  657. votable->num_clients = NUM_MAX_CLIENTS;
  658. votable->callback = callback;
  659. votable->type = votable_type;
  660. votable->data = data;
  661. votable->override_result = -EINVAL;
  662. mutex_init(&votable->vote_lock);
  663. /*
  664. * Because effective_result and client states are invalid
  665. * before the first vote, initialize them to -EINVAL
  666. */
  667. votable->effective_result = -EINVAL;
  668. if (votable->type == VOTE_SET_ANY)
  669. votable->effective_result = 0;
  670. votable->effective_client_id = -EINVAL;
  671. spin_lock_irqsave(&votable_list_slock, flags);
  672. list_add(&votable->list, &votable_list);
  673. spin_unlock_irqrestore(&votable_list_slock, flags);
  674. votable->root = debugfs_create_dir(name, debug_root);
  675. if (!votable->root) {
  676. pr_err("Couldn't create debug dir %s\n", name);
  677. kfree(votable->name);
  678. kfree(votable);
  679. return ERR_PTR(-ENOMEM);
  680. }
  681. votable->status_ent = debugfs_create_file("status", S_IFREG | 0444,
  682. votable->root, votable,
  683. &votable_status_ops);
  684. if (!votable->status_ent) {
  685. pr_err("Couldn't create status dbg file for %s\n", name);
  686. debugfs_remove_recursive(votable->root);
  687. kfree(votable->name);
  688. kfree(votable);
  689. return ERR_PTR(-EEXIST);
  690. }
  691. debugfs_create_u32("force_val",
  692. S_IFREG | 0644,
  693. votable->root,
  694. &(votable->force_val));
  695. votable->force_active_ent = debugfs_create_file("force_active",
  696. S_IFREG | 0444,
  697. votable->root, votable,
  698. &votable_force_ops);
  699. if (!votable->force_active_ent) {
  700. pr_err("Couldn't create force_active dbg file for %s\n", name);
  701. debugfs_remove_recursive(votable->root);
  702. kfree(votable->name);
  703. kfree(votable);
  704. return ERR_PTR(-EEXIST);
  705. }
  706. return votable;
  707. }
  708. EXPORT_SYMBOL_GPL(create_votable);
  709. void destroy_votable(struct votable *votable)
  710. {
  711. unsigned long flags;
  712. int i;
  713. if (!votable)
  714. return;
  715. spin_lock_irqsave(&votable_list_slock, flags);
  716. list_del(&votable->list);
  717. spin_unlock_irqrestore(&votable_list_slock, flags);
  718. debugfs_remove_recursive(votable->root);
  719. for (i = 0; i < votable->num_clients && votable->client_strs[i]; i++)
  720. kfree(votable->client_strs[i]);
  721. kfree(votable->name);
  722. kfree(votable);
  723. }
  724. EXPORT_SYMBOL_GPL(destroy_votable);