abc_motto.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /* abc_motto.c
  2. *
  3. * Abnormal Behavior Catcher MOTTO Support
  4. *
  5. * Copyright (C) 2020 Samsung Electronics
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. */
  18. #include <linux/sti/abc_common.h>
  19. extern struct device *sec_abc;
  20. #if defined(CONFIG_ARCH_QCOM)
  21. static unsigned int qet_loaded;
  22. module_param(qet_loaded, uint, 0440);
  23. #endif
  24. struct motto_event_type motto_event_type_list[] = {
  25. {MOTTO_MODULE_GPU, "gpu", "gpu_fault"},
  26. {MOTTO_MODULE_GPU, "gpu_qc", "gpu_fault"},
  27. {MOTTO_MODULE_DECON, "decon", "fence_timeout"},
  28. {MOTTO_MODULE_CAMERA, "camera", "camera_error"},
  29. {MOTTO_MODULE_CAMERA, "camera", "i2c_fail"},
  30. {MOTTO_MODULE_NPU, "npu", "npu_fw_warning"},
  31. {MOTTO_MODULE_NPU, "camera", "mipi_overflow"},
  32. // we can add more like
  33. // {MOTTO_MODULE_GPU, "gpu_qc", "gpu_new_event"}
  34. // {MOTTO_MODULE_CAMERA, "camera", "camera_new_event"},
  35. // {MOTTO_MODULE_NEW, "new", "new_something"}
  36. };
  37. static void motto_update_event(enum motto_event_module module)
  38. {
  39. struct abc_info *pinfo;
  40. struct abc_motto_data *cmotto;
  41. pinfo = dev_get_drvdata(sec_abc);
  42. cmotto = pinfo->pdata->motto_data;
  43. if (cmotto->dev_err_count[module] == 0xff) // 0xff means max value of 8bit variable dev_err_count[module]
  44. return;
  45. cmotto->dev_err_count[module]++;
  46. return;
  47. }
  48. static enum motto_event_module motto_event_to_idx(char *module_str, char *event)
  49. {
  50. int i, items = sizeof(motto_event_type_list) / sizeof(motto_event_type_list[0]);
  51. size_t module_str_len = strlen(module_str);
  52. for (i = 0; i < items; i++) {
  53. if (strlen(motto_event_type_list[i].motto_event_module_name) == module_str_len &&
  54. !strncmp(motto_event_type_list[i].motto_event_module_name, module_str, module_str_len) &&
  55. !strcmp(motto_event_type_list[i].motto_event_type_str, event))
  56. return motto_event_type_list[i].module;
  57. }
  58. return MOTTO_MODULE_NONE;
  59. }
  60. void get_motto_uevent_str(char *uevent_str)
  61. {
  62. struct abc_info *pinfo;
  63. struct abc_motto_data *cmotto;
  64. char temp[9];
  65. int i;
  66. pinfo = dev_get_drvdata(sec_abc);
  67. cmotto = pinfo->pdata->motto_data;
  68. sprintf(uevent_str,"AME=%08x", cmotto->boot_time);
  69. for (i=0;i<MOTTO_MODULE_MAX;i++)
  70. {
  71. snprintf(temp,9,"%08x", cmotto->dev_err_count[i]);
  72. strcat(uevent_str, temp);
  73. }
  74. return;
  75. }
  76. void motto_send_uevent(void)
  77. {
  78. char temp[ABC_BUFFER_MAX];
  79. char *uevent_str[3] = {0,};
  80. get_motto_uevent_str(temp);
  81. uevent_str[0] = temp;
  82. //uevent_str[1] = &timestamp[0];
  83. uevent_str[2] = NULL;
  84. kobject_uevent_env(&sec_abc->kobj, KOBJ_CHANGE, uevent_str);
  85. }
  86. void motto_send_device_info(char *module_str, char *event_type)
  87. {
  88. enum motto_event_module module = motto_event_to_idx(module_str, event_type);
  89. if (module > MOTTO_MODULE_NONE) {
  90. ABC_PRINT("%s\n", event_type);
  91. motto_update_event(module);
  92. motto_send_uevent();
  93. }
  94. }
  95. static ssize_t show_abc_motto_info(struct device *dev,
  96. struct device_attribute *attr,
  97. char *buf)
  98. {
  99. struct abc_motto_data *cmotto;
  100. struct abc_info *pinfo = dev_get_drvdata(dev);
  101. char temp[ABC_BUFFER_MAX];
  102. char retstr[ABC_BUFFER_MAX], tempcat[24];
  103. int i;
  104. get_motto_uevent_str(temp);
  105. cmotto = pinfo->pdata->motto_data;
  106. ABC_PRINT("%s\n", temp);
  107. sprintf(retstr,"%d boot %d", sec_abc_get_enabled(), cmotto->boot_time);
  108. for (i=0;i<MOTTO_MODULE_MAX;i++)
  109. {
  110. snprintf(tempcat,24,", dev%d %d", i, cmotto->dev_err_count[i]);
  111. strcat(retstr, tempcat);
  112. }
  113. ABC_PRINT("%s\n", retstr);
  114. return sprintf(buf, "%s\n", retstr);
  115. }
  116. static DEVICE_ATTR(motto_info, 0444, show_abc_motto_info, NULL);
  117. #if defined(CONFIG_ARCH_QCOM)
  118. static ssize_t show_abc_motto_motto_qet_loaded(struct device *dev,
  119. struct device_attribute *attr,
  120. char *buf)
  121. {
  122. return sprintf(buf, "%d\n", qet_loaded);
  123. }
  124. static DEVICE_ATTR(motto_qc_qet_loaded, 0444, show_abc_motto_motto_qet_loaded, NULL);
  125. #endif
  126. void motto_init(struct platform_device *pdev)
  127. {
  128. struct abc_info *pinfo;
  129. int ret = 0;
  130. pinfo = dev_get_drvdata(sec_abc);
  131. ret = device_create_file(pinfo->dev, &dev_attr_motto_info);
  132. if (ret) {
  133. pr_err("%s: Failed to create device motto_info file\n", __func__);
  134. goto err_create_abc_motto_info_sysfs;
  135. }
  136. #if defined(CONFIG_ARCH_QCOM)
  137. ret = device_create_file(pinfo->dev, &dev_attr_motto_qc_qet_loaded);
  138. if (ret) {
  139. pr_err("%s: Failed to create device motto_qc_qet_loaded file\n", __func__);
  140. goto err_create_abc_motto_info_sysfs;
  141. }
  142. #endif
  143. pinfo->pdata->motto_data = devm_kzalloc(&pdev->dev,
  144. sizeof(struct abc_motto_data), GFP_KERNEL);
  145. if (pinfo->pdata->motto_data == NULL)
  146. goto err_alloc_motto_data;
  147. return;
  148. err_alloc_motto_data:
  149. device_remove_file(pinfo->dev, &dev_attr_motto_info);
  150. err_create_abc_motto_info_sysfs:
  151. return;
  152. }
  153. void motto_send_bootcheck_info(int boot_time)
  154. {
  155. struct abc_info *pinfo;
  156. struct abc_motto_data *cmotto;
  157. ABC_PRINT("%d\n", boot_time);
  158. pinfo = dev_get_drvdata(sec_abc);
  159. cmotto = pinfo->pdata->motto_data;
  160. cmotto->boot_time = (boot_time >= 0xFF) ? 0xFF : (u32)boot_time;
  161. motto_send_uevent();
  162. }
  163. EXPORT_SYMBOL(motto_send_bootcheck_info);
  164. MODULE_DESCRIPTION("Samsung ABC Driver");
  165. MODULE_AUTHOR("Samsung Electronics");
  166. MODULE_LICENSE("GPL");