cam_debug_util.c 6.2 KB

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