cam_debug_util.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/io.h>
  7. #include <linux/slab.h>
  8. #include <linux/module.h>
  9. #include <linux/debugfs.h>
  10. #include "cam_trace.h"
  11. #include "cam_debug_util.h"
  12. unsigned long long debug_mdl;
  13. module_param(debug_mdl, ullong, 0644);
  14. /* 0x0 - only logs, 0x1 - only trace, 0x2 - logs + trace */
  15. uint debug_type;
  16. module_param(debug_type, uint, 0644);
  17. uint debug_priority;
  18. module_param(debug_priority, uint, 0644);
  19. uint debug_drv;
  20. module_param(debug_drv, uint, 0644);
  21. uint debug_bypass_drivers;
  22. module_param(debug_bypass_drivers, uint, 0644);
  23. struct camera_debug_settings cam_debug;
  24. struct dentry *cam_debugfs_root;
  25. void cam_debugfs_init(void)
  26. {
  27. struct dentry *tmp;
  28. if (!cam_debugfs_available()) {
  29. cam_debugfs_root = NULL;
  30. CAM_DBG(CAM_UTIL, "debugfs not available");
  31. return;
  32. }
  33. if (cam_debugfs_root) {
  34. CAM_WARN(CAM_UTIL, "already created debugfs root");
  35. return;
  36. }
  37. tmp = debugfs_create_dir("camera", NULL);
  38. if (IS_ERR_VALUE(tmp)) {
  39. CAM_ERR(CAM_UTIL, "failed to create debugfs root folder (rc=%d)", PTR_ERR(tmp));
  40. return;
  41. }
  42. cam_debugfs_root = tmp;
  43. CAM_DBG(CAM_UTIL, "successfully created debugfs root");
  44. }
  45. void cam_debugfs_deinit(void)
  46. {
  47. if (!cam_debugfs_available())
  48. return;
  49. debugfs_remove_recursive(cam_debugfs_root);
  50. cam_debugfs_root = NULL;
  51. }
  52. int cam_debugfs_create_subdir(const char *name, struct dentry **subdir)
  53. {
  54. struct dentry *tmp;
  55. if (!cam_debugfs_root) {
  56. CAM_WARN(CAM_UTIL, "debugfs root not created");
  57. *subdir = NULL;
  58. return -ENODEV;
  59. }
  60. if (!subdir) {
  61. CAM_ERR(CAM_UTIL, "invalid subdir pointer %pK", subdir);
  62. return -EINVAL;
  63. }
  64. tmp = debugfs_create_dir(name, cam_debugfs_root);
  65. if (IS_ERR_VALUE(tmp)) {
  66. CAM_ERR(CAM_UTIL, "failed to create debugfs subdir (name=%s, rc=%d)", name,
  67. PTR_ERR(tmp));
  68. return PTR_ERR(tmp);
  69. }
  70. *subdir = tmp;
  71. return 0;
  72. }
  73. int cam_debugfs_lookup_subdir(const char *name, struct dentry **subdir)
  74. {
  75. if (!cam_debugfs_root) {
  76. CAM_WARN(CAM_UTIL, "debugfs root not created");
  77. *subdir = NULL;
  78. return -ENODEV;
  79. }
  80. if (!subdir) {
  81. CAM_ERR(CAM_UTIL, "invalid subdir pointer %pK", subdir);
  82. return -EINVAL;
  83. }
  84. *subdir = debugfs_lookup(name, cam_debugfs_root);
  85. return (*subdir) ? 0 : -ENOENT;
  86. }
  87. const struct camera_debug_settings *cam_debug_get_settings(void)
  88. {
  89. return &cam_debug;
  90. }
  91. static int cam_debug_parse_cpas_settings(const char *setting, u64 value)
  92. {
  93. if (!strcmp(setting, "camnoc_bw")) {
  94. cam_debug.cpas_settings.camnoc_bw = value;
  95. } else if (!strcmp(setting, "mnoc_hf_0_ab_bw")) {
  96. cam_debug.cpas_settings.mnoc_hf_0_ab_bw = value;
  97. } else if (!strcmp(setting, "mnoc_hf_0_ib_bw")) {
  98. cam_debug.cpas_settings.mnoc_hf_0_ib_bw = value;
  99. } else if (!strcmp(setting, "mnoc_hf_1_ab_bw")) {
  100. cam_debug.cpas_settings.mnoc_hf_1_ab_bw = value;
  101. } else if (!strcmp(setting, "mnoc_hf_1_ib_bw")) {
  102. cam_debug.cpas_settings.mnoc_hf_1_ib_bw = value;
  103. } else if (!strcmp(setting, "mnoc_sf_0_ab_bw")) {
  104. cam_debug.cpas_settings.mnoc_sf_0_ab_bw = value;
  105. } else if (!strcmp(setting, "mnoc_sf_0_ib_bw")) {
  106. cam_debug.cpas_settings.mnoc_sf_0_ib_bw = value;
  107. } else if (!strcmp(setting, "mnoc_sf_1_ab_bw")) {
  108. cam_debug.cpas_settings.mnoc_sf_1_ab_bw = value;
  109. } else if (!strcmp(setting, "mnoc_sf_1_ib_bw")) {
  110. cam_debug.cpas_settings.mnoc_sf_1_ib_bw = value;
  111. } else if (!strcmp(setting, "mnoc_sf_icp_ab_bw")) {
  112. cam_debug.cpas_settings.mnoc_sf_icp_ab_bw = value;
  113. } else if (!strcmp(setting, "mnoc_sf_icp_ib_bw")) {
  114. cam_debug.cpas_settings.mnoc_sf_icp_ib_bw = value;
  115. } else if (!strcmp(setting, "cam_ife_0_drv_ab_high_bw")) {
  116. cam_debug.cpas_settings.cam_ife_0_drv_ab_high_bw = value;
  117. } else if (!strcmp(setting, "cam_ife_0_drv_ib_high_bw")) {
  118. cam_debug.cpas_settings.cam_ife_0_drv_ib_high_bw = value;
  119. } else if (!strcmp(setting, "cam_ife_1_drv_ab_high_bw")) {
  120. cam_debug.cpas_settings.cam_ife_1_drv_ab_high_bw = value;
  121. } else if (!strcmp(setting, "cam_ife_1_drv_ib_high_bw")) {
  122. cam_debug.cpas_settings.cam_ife_1_drv_ib_high_bw = value;
  123. } else if (!strcmp(setting, "cam_ife_2_drv_ab_high_bw")) {
  124. cam_debug.cpas_settings.cam_ife_2_drv_ab_high_bw = value;
  125. } else if (!strcmp(setting, "cam_ife_2_drv_ib_high_bw")) {
  126. cam_debug.cpas_settings.cam_ife_2_drv_ib_high_bw = value;
  127. } else if (!strcmp(setting, "cam_ife_0_drv_ab_low_bw")) {
  128. cam_debug.cpas_settings.cam_ife_0_drv_ab_low_bw = value;
  129. } else if (!strcmp(setting, "cam_ife_0_drv_ib_low_bw")) {
  130. cam_debug.cpas_settings.cam_ife_0_drv_ib_low_bw = value;
  131. } else if (!strcmp(setting, "cam_ife_1_drv_ab_low_bw")) {
  132. cam_debug.cpas_settings.cam_ife_1_drv_ab_low_bw = value;
  133. } else if (!strcmp(setting, "cam_ife_1_drv_ib_low_bw")) {
  134. cam_debug.cpas_settings.cam_ife_1_drv_ib_low_bw = value;
  135. } else if (!strcmp(setting, "cam_ife_2_drv_ab_low_bw")) {
  136. cam_debug.cpas_settings.cam_ife_2_drv_ab_low_bw = value;
  137. } else if (!strcmp(setting, "cam_ife_2_drv_ib_low_bw")) {
  138. cam_debug.cpas_settings.cam_ife_2_drv_ib_low_bw = value;
  139. } else if (!strcmp(setting, "cam_ife_0_drv_low_set_zero")) {
  140. cam_debug.cpas_settings.cam_ife_0_drv_low_set_zero = value;
  141. } else if (!strcmp(setting, "cam_ife_1_drv_low_set_zero")) {
  142. cam_debug.cpas_settings.cam_ife_1_drv_low_set_zero = value;
  143. } else if (!strcmp(setting, "cam_ife_2_drv_low_set_zero")) {
  144. cam_debug.cpas_settings.cam_ife_2_drv_low_set_zero = value;
  145. } else {
  146. CAM_ERR(CAM_UTIL, "Unsupported cpas sysfs entry");
  147. return -EINVAL;
  148. }
  149. cam_debug.cpas_settings.is_updated = true;
  150. return 0;
  151. }
  152. ssize_t cam_debug_sysfs_node_store(struct device *dev,
  153. struct device_attribute *attr, const char *buf, size_t count)
  154. {
  155. int rc = 0;
  156. char *local_buf = NULL, *local_buf_temp = NULL;
  157. char *driver;
  158. char *setting = NULL;
  159. char *value_str = NULL;
  160. u64 value;
  161. CAM_INFO(CAM_UTIL, "Sysfs debug attr name:[%s] buf:[%s] bytes:[%d]",
  162. attr->attr.name, buf, count);
  163. local_buf = kmemdup(buf, (count + sizeof(char)), GFP_KERNEL);
  164. local_buf_temp = local_buf;
  165. driver = strsep(&local_buf, "#");
  166. if (!driver) {
  167. CAM_ERR(CAM_UTIL,
  168. "Invalid input driver name buf:[%s], count:%d",
  169. buf, count);
  170. goto error;
  171. }
  172. setting = strsep(&local_buf, "=");
  173. if (!setting) {
  174. CAM_ERR(CAM_UTIL, "Invalid input setting buf:[%s], count:%d",
  175. buf, count);
  176. goto error;
  177. }
  178. value_str = strsep(&local_buf, "=");
  179. if (!value_str) {
  180. CAM_ERR(CAM_UTIL, "Invalid input value buf:[%s], count:%d",
  181. buf, count);
  182. goto error;
  183. }
  184. rc = kstrtou64(value_str, 0, &value);
  185. if (rc < 0) {
  186. CAM_ERR(CAM_UTIL, "Error converting value:[%s], buf:[%s]",
  187. value_str, buf);
  188. goto error;
  189. }
  190. CAM_INFO(CAM_UTIL,
  191. "Processing sysfs store for driver:[%s], setting:[%s], value:[%llu]",
  192. driver, setting, value);
  193. if (!strcmp(driver, "cpas")) {
  194. rc = cam_debug_parse_cpas_settings(setting, value);
  195. if (rc)
  196. goto error;
  197. } else {
  198. CAM_ERR(CAM_UTIL, "Unsupported driver in camera debug node");
  199. goto error;
  200. }
  201. kfree(local_buf_temp);
  202. return count;
  203. error:
  204. kfree(local_buf_temp);
  205. return -EPERM;
  206. }
  207. static inline void __cam_print_to_buffer(char *buf, const size_t buf_size, size_t *len,
  208. unsigned int tag, enum cam_debug_module_id module_id, const char *fmt, va_list args)
  209. {
  210. size_t buf_len = *len;
  211. buf_len += scnprintf(buf + buf_len, (buf_size - buf_len), "\n%-8s: %s:\t",
  212. CAM_LOG_TAG_NAME(tag), CAM_DBG_MOD_NAME(module_id));
  213. buf_len += vscnprintf(buf + buf_len, (buf_size - buf_len), fmt, args);
  214. *len = buf_len;
  215. }
  216. void cam_print_to_buffer(char *buf, const size_t buf_size, size_t *len, unsigned int tag,
  217. unsigned long long module_id, const char *fmt, ...)
  218. {
  219. va_list args;
  220. va_start(args, fmt);
  221. __cam_print_to_buffer(buf, buf_size, len, tag, module_id, fmt, args);
  222. va_end(args);
  223. }
  224. static void __cam_print_log(int type, const char *fmt, ...)
  225. {
  226. va_list args1, args2, args;
  227. va_start(args, fmt);
  228. va_copy(args1, args);
  229. va_copy(args2, args1);
  230. if ((type & CAM_PRINT_LOG) && (debug_type != 1))
  231. vprintk(fmt, args1);
  232. if ((type & CAM_PRINT_TRACE) && (debug_type != 0)) {
  233. /* skip the first character which is used by printk to identify the log level */
  234. trace_cam_log_debug(fmt + sizeof(KERN_INFO) - 1, &args2);
  235. }
  236. va_end(args2);
  237. va_end(args1);
  238. va_end(args);
  239. }
  240. void cam_print_log(int type, int module, int tag, const char *func,
  241. int line, const char *fmt, ...)
  242. {
  243. char buf[CAM_LOG_BUF_LEN] = {0,};
  244. va_list args;
  245. if (!type)
  246. return;
  247. va_start(args, fmt);
  248. vscnprintf(buf, CAM_LOG_BUF_LEN, fmt, args);
  249. __cam_print_log(type, __CAM_LOG_FMT,
  250. CAM_LOG_TAG_NAME(tag), CAM_DBG_MOD_NAME(module), func,
  251. line, buf);
  252. va_end(args);
  253. }