qpnp-pbs.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /* Copyright (c) 2017, 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. #define pr_fmt(fmt) "PBS: %s: " fmt, __func__
  13. #include <linux/delay.h>
  14. #include <linux/module.h>
  15. #include <linux/slab.h>
  16. #include <linux/spmi.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/regmap.h>
  19. #include <linux/err.h>
  20. #include <linux/of.h>
  21. #include <linux/qpnp/qpnp-pbs.h>
  22. #define QPNP_PBS_DEV_NAME "qcom,qpnp-pbs"
  23. #define PBS_CLIENT_TRIG_CTL 0x42
  24. #define PBS_CLIENT_SW_TRIG_BIT BIT(7)
  25. #define PBS_CLIENT_SCRATCH1 0x50
  26. #define PBS_CLIENT_SCRATCH2 0x51
  27. static LIST_HEAD(pbs_dev_list);
  28. static DEFINE_MUTEX(pbs_list_lock);
  29. struct qpnp_pbs {
  30. struct platform_device *pdev;
  31. struct device *dev;
  32. struct device_node *dev_node;
  33. struct regmap *regmap;
  34. struct mutex pbs_lock;
  35. struct list_head link;
  36. u32 base;
  37. };
  38. static int qpnp_pbs_read(struct qpnp_pbs *pbs, u32 address,
  39. u8 *val, int count)
  40. {
  41. int rc = 0;
  42. struct platform_device *pdev = pbs->pdev;
  43. rc = regmap_bulk_read(pbs->regmap, address, val, count);
  44. if (rc)
  45. pr_err("Failed to read address=0x%02x sid=0x%02x rc=%d\n",
  46. address, to_spmi_device(pdev->dev.parent)->usid, rc);
  47. return rc;
  48. }
  49. static int qpnp_pbs_write(struct qpnp_pbs *pbs, u16 address,
  50. u8 *val, int count)
  51. {
  52. int rc = 0;
  53. struct platform_device *pdev = pbs->pdev;
  54. rc = regmap_bulk_write(pbs->regmap, address, val, count);
  55. if (rc < 0)
  56. pr_err("Failed to write address =0x%02x sid=0x%02x rc=%d\n",
  57. address, to_spmi_device(pdev->dev.parent)->usid, rc);
  58. else
  59. pr_debug("Wrote 0x%02X to addr 0x%04x\n", *val, address);
  60. return rc;
  61. }
  62. static int qpnp_pbs_masked_write(struct qpnp_pbs *pbs, u16 address,
  63. u8 mask, u8 val)
  64. {
  65. int rc;
  66. rc = regmap_update_bits(pbs->regmap, address, mask, val);
  67. if (rc < 0)
  68. pr_err("Failed to write address 0x%04X, rc = %d\n",
  69. address, rc);
  70. else
  71. pr_debug("Wrote 0x%02X to addr 0x%04X\n",
  72. val, address);
  73. return rc;
  74. }
  75. static struct qpnp_pbs *get_pbs_client_node(struct device_node *dev_node)
  76. {
  77. struct qpnp_pbs *pbs;
  78. mutex_lock(&pbs_list_lock);
  79. list_for_each_entry(pbs, &pbs_dev_list, link) {
  80. if (dev_node == pbs->dev_node) {
  81. mutex_unlock(&pbs_list_lock);
  82. return pbs;
  83. }
  84. }
  85. mutex_unlock(&pbs_list_lock);
  86. return ERR_PTR(-EINVAL);
  87. }
  88. static int qpnp_pbs_wait_for_ack(struct qpnp_pbs *pbs, u8 bit_pos)
  89. {
  90. int rc = 0;
  91. u16 retries = 2000, dly = 1000;
  92. u8 val;
  93. while (retries--) {
  94. rc = qpnp_pbs_read(pbs, pbs->base +
  95. PBS_CLIENT_SCRATCH2, &val, 1);
  96. if (rc < 0) {
  97. pr_err("Failed to read register %x rc = %d\n",
  98. PBS_CLIENT_SCRATCH2, rc);
  99. return rc;
  100. }
  101. if (val == 0xFF) {
  102. /* PBS error - clear SCRATCH2 register */
  103. rc = qpnp_pbs_write(pbs, pbs->base +
  104. PBS_CLIENT_SCRATCH2, 0, 1);
  105. if (rc < 0) {
  106. pr_err("Failed to clear register %x rc=%d\n",
  107. PBS_CLIENT_SCRATCH2, rc);
  108. return rc;
  109. }
  110. pr_err("NACK from PBS for bit %d\n", bit_pos);
  111. return -EINVAL;
  112. }
  113. if (val & BIT(bit_pos)) {
  114. pr_debug("PBS sequence for bit %d executed!\n",
  115. bit_pos);
  116. break;
  117. }
  118. usleep_range(dly, dly + 100);
  119. }
  120. if (!retries) {
  121. pr_err("Timeout for PBS ACK/NACK for bit %d\n", bit_pos);
  122. return -ETIMEDOUT;
  123. }
  124. return 0;
  125. }
  126. /**
  127. * qpnp_pbs_trigger_event - Trigger the PBS RAM sequence
  128. *
  129. * Returns = 0 If the PBS RAM sequence executed successfully.
  130. *
  131. * Returns < 0 for errors.
  132. *
  133. * This function is used to trigger the PBS RAM sequence to be
  134. * executed by the client driver.
  135. *
  136. * The PBS trigger sequence involves
  137. * 1. setting the PBS sequence bit in PBS_CLIENT_SCRATCH1
  138. * 2. Initiating the SW PBS trigger
  139. * 3. Checking the equivalent bit in PBS_CLIENT_SCRATCH2 for the
  140. * completion of the sequence.
  141. * 4. If PBS_CLIENT_SCRATCH2 == 0xFF, the PBS sequence failed to execute
  142. */
  143. int qpnp_pbs_trigger_event(struct device_node *dev_node, u8 bitmap)
  144. {
  145. struct qpnp_pbs *pbs;
  146. int rc = 0;
  147. u16 bit_pos = 0;
  148. u8 val, mask = 0;
  149. if (!dev_node)
  150. return -EINVAL;
  151. if (!bitmap) {
  152. pr_err("Invalid bitmap passed by client\n");
  153. return -EINVAL;
  154. }
  155. pbs = get_pbs_client_node(dev_node);
  156. if (IS_ERR_OR_NULL(pbs)) {
  157. pr_err("Unable to find the PBS dev_node\n");
  158. return -EINVAL;
  159. }
  160. mutex_lock(&pbs->pbs_lock);
  161. rc = qpnp_pbs_read(pbs, pbs->base + PBS_CLIENT_SCRATCH2, &val, 1);
  162. if (rc < 0) {
  163. pr_err("read register %x failed rc = %d\n",
  164. PBS_CLIENT_SCRATCH2, rc);
  165. goto out;
  166. }
  167. if (val == 0xFF) {
  168. /* PBS error - clear SCRATCH2 register */
  169. rc = qpnp_pbs_write(pbs, pbs->base + PBS_CLIENT_SCRATCH2, 0, 1);
  170. if (rc < 0) {
  171. pr_err("Failed to clear register %x rc=%d\n",
  172. PBS_CLIENT_SCRATCH2, rc);
  173. goto out;
  174. }
  175. }
  176. for (bit_pos = 0; bit_pos < 8; bit_pos++) {
  177. if (bitmap & BIT(bit_pos)) {
  178. /*
  179. * Clear the PBS sequence bit position in
  180. * PBS_CLIENT_SCRATCH2 mask register.
  181. */
  182. rc = qpnp_pbs_masked_write(pbs, pbs->base +
  183. PBS_CLIENT_SCRATCH2, BIT(bit_pos), 0);
  184. if (rc < 0) {
  185. pr_err("Failed to clear %x reg bit rc=%d\n",
  186. PBS_CLIENT_SCRATCH2, rc);
  187. goto error;
  188. }
  189. /*
  190. * Set the PBS sequence bit position in
  191. * PBS_CLIENT_SCRATCH1 register.
  192. */
  193. val = mask = BIT(bit_pos);
  194. rc = qpnp_pbs_masked_write(pbs, pbs->base +
  195. PBS_CLIENT_SCRATCH1, mask, val);
  196. if (rc < 0) {
  197. pr_err("Failed to set %x reg bit rc=%d\n",
  198. PBS_CLIENT_SCRATCH1, rc);
  199. goto error;
  200. }
  201. /* Initiate the SW trigger */
  202. val = mask = PBS_CLIENT_SW_TRIG_BIT;
  203. rc = qpnp_pbs_masked_write(pbs, pbs->base +
  204. PBS_CLIENT_TRIG_CTL, mask, val);
  205. if (rc < 0) {
  206. pr_err("Failed to write register %x rc=%d\n",
  207. PBS_CLIENT_TRIG_CTL, rc);
  208. goto error;
  209. }
  210. rc = qpnp_pbs_wait_for_ack(pbs, bit_pos);
  211. if (rc < 0) {
  212. pr_err("Error during wait_for_ack\n");
  213. goto error;
  214. }
  215. /*
  216. * Clear the PBS sequence bit position in
  217. * PBS_CLIENT_SCRATCH1 register.
  218. */
  219. rc = qpnp_pbs_masked_write(pbs, pbs->base +
  220. PBS_CLIENT_SCRATCH1, BIT(bit_pos), 0);
  221. if (rc < 0) {
  222. pr_err("Failed to clear %x reg bit rc=%d\n",
  223. PBS_CLIENT_SCRATCH1, rc);
  224. goto error;
  225. }
  226. /*
  227. * Clear the PBS sequence bit position in
  228. * PBS_CLIENT_SCRATCH2 mask register.
  229. */
  230. rc = qpnp_pbs_masked_write(pbs, pbs->base +
  231. PBS_CLIENT_SCRATCH2, BIT(bit_pos), 0);
  232. if (rc < 0) {
  233. pr_err("Failed to clear %x reg bit rc=%d\n",
  234. PBS_CLIENT_SCRATCH2, rc);
  235. goto error;
  236. }
  237. }
  238. }
  239. error:
  240. /* Clear all the requested bitmap */
  241. rc = qpnp_pbs_masked_write(pbs, pbs->base + PBS_CLIENT_SCRATCH1,
  242. bitmap, 0);
  243. if (rc < 0)
  244. pr_err("Failed to clear %x reg bit rc=%d\n",
  245. PBS_CLIENT_SCRATCH1, rc);
  246. out:
  247. mutex_unlock(&pbs->pbs_lock);
  248. return rc;
  249. }
  250. EXPORT_SYMBOL(qpnp_pbs_trigger_event);
  251. static int qpnp_pbs_probe(struct platform_device *pdev)
  252. {
  253. int rc = 0;
  254. u32 val = 0;
  255. struct qpnp_pbs *pbs;
  256. pbs = devm_kzalloc(&pdev->dev, sizeof(*pbs), GFP_KERNEL);
  257. if (!pbs)
  258. return -ENOMEM;
  259. pbs->pdev = pdev;
  260. pbs->dev = &pdev->dev;
  261. pbs->dev_node = pdev->dev.of_node;
  262. pbs->regmap = dev_get_regmap(pdev->dev.parent, NULL);
  263. if (!pbs->regmap) {
  264. dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
  265. return -EINVAL;
  266. }
  267. rc = of_property_read_u32(pdev->dev.of_node, "reg", &val);
  268. if (rc < 0) {
  269. dev_err(&pdev->dev,
  270. "Couldn't find reg in node = %s rc = %d\n",
  271. pdev->dev.of_node->full_name, rc);
  272. return rc;
  273. }
  274. pbs->base = val;
  275. mutex_init(&pbs->pbs_lock);
  276. dev_set_drvdata(&pdev->dev, pbs);
  277. mutex_lock(&pbs_list_lock);
  278. list_add(&pbs->link, &pbs_dev_list);
  279. mutex_unlock(&pbs_list_lock);
  280. return 0;
  281. }
  282. static const struct of_device_id qpnp_pbs_match_table[] = {
  283. { .compatible = QPNP_PBS_DEV_NAME },
  284. {}
  285. };
  286. static struct platform_driver qpnp_pbs_driver = {
  287. .driver = {
  288. .name = QPNP_PBS_DEV_NAME,
  289. .owner = THIS_MODULE,
  290. .of_match_table = qpnp_pbs_match_table,
  291. },
  292. .probe = qpnp_pbs_probe,
  293. };
  294. static int __init qpnp_pbs_init(void)
  295. {
  296. return platform_driver_register(&qpnp_pbs_driver);
  297. }
  298. arch_initcall(qpnp_pbs_init);
  299. static void __exit qpnp_pbs_exit(void)
  300. {
  301. return platform_driver_unregister(&qpnp_pbs_driver);
  302. }
  303. module_exit(qpnp_pbs_exit);
  304. MODULE_DESCRIPTION("QPNP PBS DRIVER");
  305. MODULE_LICENSE("GPL v2");
  306. MODULE_ALIAS("platform:" QPNP_PBS_DEV_NAME);