mt_spm_fs.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/kobject.h>
  4. #include <linux/sysfs.h>
  5. #include <linux/string.h>
  6. #include "mt_spm_internal.h"
  7. #include "mt_sleep.h"
  8. /*
  9. * Macro and Inline
  10. */
  11. #define DEFINE_ATTR_RO(_name) \
  12. static struct kobj_attribute _name##_attr = { \
  13. .attr = { \
  14. .name = #_name, \
  15. .mode = 0444, \
  16. }, \
  17. .show = _name##_show, \
  18. }
  19. #define DEFINE_ATTR_RW(_name) \
  20. static struct kobj_attribute _name##_attr = { \
  21. .attr = { \
  22. .name = #_name, \
  23. .mode = 0644, \
  24. }, \
  25. .show = _name##_show, \
  26. .store = _name##_store, \
  27. }
  28. #define __ATTR_OF(_name) (&_name##_attr.attr)
  29. /*
  30. * xxx_pcm_show Function
  31. */
  32. static ssize_t show_pcm_desc(const struct pcm_desc *pcmdesc, char *buf)
  33. {
  34. char *p = buf;
  35. p += sprintf(p, "version = %s\n", pcmdesc->version);
  36. p += sprintf(p, "base = 0x%p\n", pcmdesc->base);
  37. p += sprintf(p, "size = %u\n", pcmdesc->size);
  38. p += sprintf(p, "sess = %u\n", pcmdesc->sess);
  39. p += sprintf(p, "replace = %u\n", pcmdesc->replace);
  40. p += sprintf(p, "vec0 = 0x%x\n", pcmdesc->vec0);
  41. p += sprintf(p, "vec1 = 0x%x\n", pcmdesc->vec1);
  42. p += sprintf(p, "vec2 = 0x%x\n", pcmdesc->vec2);
  43. p += sprintf(p, "vec3 = 0x%x\n", pcmdesc->vec3);
  44. p += sprintf(p, "vec4 = 0x%x\n", pcmdesc->vec4);
  45. p += sprintf(p, "vec5 = 0x%x\n", pcmdesc->vec5);
  46. p += sprintf(p, "vec6 = 0x%x\n", pcmdesc->vec6);
  47. p += sprintf(p, "vec7 = 0x%x\n", pcmdesc->vec7);
  48. BUG_ON(p - buf >= PAGE_SIZE);
  49. return p - buf;
  50. }
  51. static ssize_t suspend_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  52. {
  53. return show_pcm_desc(__spm_suspend.pcmdesc, buf);
  54. }
  55. static ssize_t dpidle_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  56. {
  57. #if defined(CONFIG_ARCH_MT6580)
  58. return 0; /* TODO */
  59. #else
  60. return show_pcm_desc(__spm_dpidle.pcmdesc, buf);
  61. #endif
  62. }
  63. static ssize_t sodi_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  64. {
  65. return show_pcm_desc(__spm_sodi.pcmdesc, buf);
  66. }
  67. static ssize_t talking_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  68. {
  69. /* For bring up */
  70. #if 0
  71. return show_pcm_desc(__spm_talking.pcmdesc, buf);
  72. #else
  73. return 0;
  74. #endif
  75. }
  76. static ssize_t ddrdfs_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  77. {
  78. /* For bring up */
  79. #if 0
  80. return show_pcm_desc(__spm_ddrdfs.pcmdesc, buf);
  81. #else
  82. return 0;
  83. #endif
  84. }
  85. #if defined(SPM_VCORE_EN)
  86. static ssize_t vcorefs_pcm_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  87. {
  88. return show_pcm_desc(__spm_vcore_dvfs.pcmdesc, buf);
  89. }
  90. #endif
  91. /*
  92. * xxx_ctrl_show Function
  93. */
  94. static ssize_t show_pwr_ctrl(const struct pwr_ctrl *pwrctrl, char *buf)
  95. {
  96. char *p = buf;
  97. p += sprintf(p, "pcm_flags = 0x%x\n", pwrctrl->pcm_flags);
  98. p += sprintf(p, "pcm_flags_cust = 0x%x\n", pwrctrl->pcm_flags_cust);
  99. p += sprintf(p, "pcm_reserve = 0x%x\n", pwrctrl->pcm_reserve);
  100. p += sprintf(p, "timer_val = 0x%x\n", pwrctrl->timer_val);
  101. p += sprintf(p, "timer_val_cust = 0x%x\n", pwrctrl->timer_val_cust);
  102. p += sprintf(p, "wake_src = 0x%x\n", pwrctrl->wake_src);
  103. p += sprintf(p, "wake_src_cust = 0x%x\n", pwrctrl->wake_src_cust);
  104. p += sprintf(p, "wake_src_md32 = 0x%x\n", pwrctrl->wake_src_md32);
  105. p += sprintf(p, "r0_ctrl_en = %u\n", pwrctrl->r0_ctrl_en);
  106. p += sprintf(p, "r7_ctrl_en = %u\n", pwrctrl->r7_ctrl_en);
  107. p += sprintf(p, "infra_dcm_lock = %u\n", pwrctrl->infra_dcm_lock);
  108. p += sprintf(p, "pcm_apsrc_req = %u\n", pwrctrl->pcm_apsrc_req);
  109. p += sprintf(p, "pcm_f26m_req = %u\n", pwrctrl->pcm_f26m_req);
  110. p += sprintf(p, "mcusys_idle_mask = %u\n", pwrctrl->mcusys_idle_mask);
  111. p += sprintf(p, "ca15top_idle_mask = %u\n", pwrctrl->ca15top_idle_mask);
  112. p += sprintf(p, "ca7top_idle_mask = %u\n", pwrctrl->ca7top_idle_mask);
  113. p += sprintf(p, "wfi_op = %u\n", pwrctrl->wfi_op);
  114. p += sprintf(p, "ca15_wfi0_en = %u\n", pwrctrl->ca15_wfi0_en);
  115. p += sprintf(p, "ca15_wfi1_en = %u\n", pwrctrl->ca15_wfi1_en);
  116. p += sprintf(p, "ca15_wfi2_en = %u\n", pwrctrl->ca15_wfi2_en);
  117. p += sprintf(p, "ca15_wfi3_en = %u\n", pwrctrl->ca15_wfi3_en);
  118. p += sprintf(p, "ca7_wfi0_en = %u\n", pwrctrl->ca7_wfi0_en);
  119. p += sprintf(p, "ca7_wfi1_en = %u\n", pwrctrl->ca7_wfi1_en);
  120. p += sprintf(p, "ca7_wfi2_en = %u\n", pwrctrl->ca7_wfi2_en);
  121. p += sprintf(p, "ca7_wfi3_en = %u\n", pwrctrl->ca7_wfi3_en);
  122. p += sprintf(p, "md1_req_mask = %u\n", pwrctrl->md1_req_mask);
  123. p += sprintf(p, "md2_req_mask = %u\n", pwrctrl->md2_req_mask);
  124. p += sprintf(p, "md_apsrc_sel = %u\n", pwrctrl->md_apsrc_sel);
  125. p += sprintf(p, "md2_apsrc_sel = %u\n", pwrctrl->md2_apsrc_sel);
  126. p += sprintf(p, "gce_req_mask = %u\n", pwrctrl->gce_req_mask);
  127. p += sprintf(p, "ccif0_to_ap_mask = %u\n", pwrctrl->ccif0_to_ap_mask);
  128. p += sprintf(p, "ccif0_to_md_mask = %u\n", pwrctrl->ccif0_to_md_mask);
  129. p += sprintf(p, "ccif1_to_ap_mask = %u\n", pwrctrl->ccif1_to_ap_mask);
  130. p += sprintf(p, "ccif1_to_md_mask = %u\n", pwrctrl->ccif1_to_md_mask);
  131. p += sprintf(p, "lte_mask = %u\n", pwrctrl->lte_mask);
  132. p += sprintf(p, "ccifmd_md1_event_mask = %u\n", pwrctrl->ccifmd_md1_event_mask);
  133. p += sprintf(p, "ccifmd_md2_event_mask = %u\n", pwrctrl->ccifmd_md2_event_mask);
  134. p += sprintf(p, "conn_mask = %u\n", pwrctrl->conn_mask);
  135. p += sprintf(p, "disp_req_mask = %u\n", pwrctrl->disp_req_mask);
  136. p += sprintf(p, "mfg_req_mask = %u\n", pwrctrl->mfg_req_mask);
  137. p += sprintf(p, "dsi0_ddr_en_mask = %u\n", pwrctrl->dsi0_ddr_en_mask);
  138. p += sprintf(p, "dsi1_ddr_en_mask = %u\n", pwrctrl->dsi1_ddr_en_mask);
  139. p += sprintf(p, "dpi_ddr_en_mask = %u\n", pwrctrl->dpi_ddr_en_mask);
  140. p += sprintf(p, "isp0_ddr_en_mask = %u\n", pwrctrl->isp0_ddr_en_mask);
  141. p += sprintf(p, "isp1_ddr_en_mask = %u\n", pwrctrl->isp1_ddr_en_mask);
  142. p += sprintf(p, "md32_req_mask = %u\n", pwrctrl->md32_req_mask);
  143. p += sprintf(p, "syspwreq_mask = %u\n", pwrctrl->syspwreq_mask);
  144. p += sprintf(p, "srclkenai_mask = %u\n", pwrctrl->srclkenai_mask);
  145. p += sprintf(p, "param1 = 0x%x\n", pwrctrl->param1);
  146. p += sprintf(p, "param2 = 0x%x\n", pwrctrl->param2);
  147. p += sprintf(p, "param3 = 0x%x\n", pwrctrl->param3);
  148. BUG_ON(p - buf >= PAGE_SIZE);
  149. return p - buf;
  150. }
  151. static ssize_t suspend_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  152. {
  153. return show_pwr_ctrl(__spm_suspend.pwrctrl, buf);
  154. }
  155. static ssize_t dpidle_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  156. {
  157. #if defined(CONFIG_ARCH_MT6580)
  158. return 0; /* TODO */
  159. #else
  160. return show_pwr_ctrl(__spm_dpidle.pwrctrl, buf);
  161. #endif
  162. }
  163. static ssize_t sodi_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  164. {
  165. return show_pwr_ctrl(__spm_sodi.pwrctrl, buf);
  166. }
  167. static ssize_t talking_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  168. {
  169. /* for bring up */
  170. #if 0
  171. return show_pwr_ctrl(__spm_talking.pwrctrl, buf);
  172. #else
  173. return 0;
  174. #endif
  175. }
  176. static ssize_t ddrdfs_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  177. {
  178. /* for bring up */
  179. #if 0
  180. return show_pwr_ctrl(__spm_ddrdfs.pwrctrl, buf);
  181. #else
  182. return 0;
  183. #endif
  184. }
  185. #if defined(SPM_VCORE_EN)
  186. static ssize_t vcorefs_ctrl_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  187. {
  188. return show_pwr_ctrl(__spm_vcore_dvfs.pwrctrl, buf);
  189. }
  190. #endif
  191. /*
  192. * xxx_ctrl_store Function
  193. */
  194. static ssize_t store_pwr_ctrl(struct pwr_ctrl *pwrctrl, const char *buf, size_t count)
  195. {
  196. u32 val;
  197. char cmd[32];
  198. if (sscanf(buf, "%31s %x", cmd, &val) != 2)
  199. return -EPERM;
  200. spm_debug("pwr_ctrl: cmd = %s, val = 0x%x\n", cmd, val);
  201. if (!strcmp(cmd, "pcm_flags"))
  202. pwrctrl->pcm_flags = val;
  203. else if (!strcmp(cmd, "pcm_flags_cust"))
  204. pwrctrl->pcm_flags_cust = val;
  205. else if (!strcmp(cmd, "pcm_reserve"))
  206. pwrctrl->pcm_reserve = val;
  207. else if (!strcmp(cmd, "timer_val"))
  208. pwrctrl->timer_val = val;
  209. else if (!strcmp(cmd, "timer_val_cust"))
  210. pwrctrl->timer_val_cust = val;
  211. else if (!strcmp(cmd, "wake_src"))
  212. pwrctrl->wake_src = val;
  213. else if (!strcmp(cmd, "wake_src_cust"))
  214. pwrctrl->wake_src_cust = val;
  215. else if (!strcmp(cmd, "wake_src_md32"))
  216. pwrctrl->wake_src_md32 = val;
  217. else if (!strcmp(cmd, "r0_ctrl_en"))
  218. pwrctrl->r0_ctrl_en = val;
  219. else if (!strcmp(cmd, "r7_ctrl_en"))
  220. pwrctrl->r7_ctrl_en = val;
  221. else if (!strcmp(cmd, "infra_dcm_lock"))
  222. pwrctrl->infra_dcm_lock = val;
  223. else if (!strcmp(cmd, "pcm_apsrc_req"))
  224. pwrctrl->pcm_apsrc_req = val;
  225. else if (!strcmp(cmd, "pcm_f26m_req"))
  226. pwrctrl->pcm_f26m_req = val;
  227. else if (!strcmp(cmd, "mcusys_idle_mask"))
  228. pwrctrl->mcusys_idle_mask = val;
  229. else if (!strcmp(cmd, "ca15top_idle_mask"))
  230. pwrctrl->ca15top_idle_mask = val;
  231. else if (!strcmp(cmd, "ca7top_idle_mask"))
  232. pwrctrl->ca7top_idle_mask = val;
  233. else if (!strcmp(cmd, "wfi_op"))
  234. pwrctrl->wfi_op = val;
  235. else if (!strcmp(cmd, "ca15_wfi0_en"))
  236. pwrctrl->ca15_wfi0_en = val;
  237. else if (!strcmp(cmd, "ca15_wfi1_en"))
  238. pwrctrl->ca15_wfi1_en = val;
  239. else if (!strcmp(cmd, "ca15_wfi2_en"))
  240. pwrctrl->ca15_wfi2_en = val;
  241. else if (!strcmp(cmd, "ca15_wfi3_en"))
  242. pwrctrl->ca15_wfi3_en = val;
  243. else if (!strcmp(cmd, "ca7_wfi0_en"))
  244. pwrctrl->ca7_wfi0_en = val;
  245. else if (!strcmp(cmd, "ca7_wfi1_en"))
  246. pwrctrl->ca7_wfi1_en = val;
  247. else if (!strcmp(cmd, "ca7_wfi2_en"))
  248. pwrctrl->ca7_wfi2_en = val;
  249. else if (!strcmp(cmd, "ca7_wfi3_en"))
  250. pwrctrl->ca7_wfi3_en = val;
  251. else if (!strcmp(cmd, "md1_req_mask"))
  252. pwrctrl->md1_req_mask = val;
  253. else if (!strcmp(cmd, "md2_req_mask"))
  254. pwrctrl->md2_req_mask = val;
  255. else if (!strcmp(cmd, "md_apsrc_sel"))
  256. pwrctrl->md_apsrc_sel = val;
  257. else if (!strcmp(cmd, "md2_apsrc_sel"))
  258. pwrctrl->md2_apsrc_sel = val;
  259. else if (!strcmp(cmd, "gce_req_mask"))
  260. pwrctrl->gce_req_mask = val;
  261. else if (!strcmp(cmd, "ccif0_to_ap_mask"))
  262. pwrctrl->ccif0_to_ap_mask = val;
  263. else if (!strcmp(cmd, "ccif0_to_md_mask"))
  264. pwrctrl->ccif0_to_md_mask = val;
  265. else if (!strcmp(cmd, "ccif1_to_ap_mask"))
  266. pwrctrl->ccif1_to_ap_mask = val;
  267. else if (!strcmp(cmd, "ccif1_to_md_mask"))
  268. pwrctrl->ccif1_to_md_mask = val;
  269. else if (!strcmp(cmd, "lte_mask"))
  270. pwrctrl->lte_mask = val;
  271. else if (!strcmp(cmd, "ccifmd_md1_event_mask"))
  272. pwrctrl->ccifmd_md1_event_mask = val;
  273. else if (!strcmp(cmd, "ccifmd_md2_event_mask"))
  274. pwrctrl->ccifmd_md2_event_mask = val;
  275. else if (!strcmp(cmd, "conn_mask"))
  276. pwrctrl->conn_mask = val;
  277. else if (!strcmp(cmd, "disp_req_mask"))
  278. pwrctrl->disp_req_mask = val;
  279. else if (!strcmp(cmd, "mfg_req_mask"))
  280. pwrctrl->mfg_req_mask = val;
  281. else if (!strcmp(cmd, "dsi0_ddr_en_mask"))
  282. pwrctrl->dsi0_ddr_en_mask = val;
  283. else if (!strcmp(cmd, "dsi1_ddr_en_mask"))
  284. pwrctrl->dsi1_ddr_en_mask = val;
  285. else if (!strcmp(cmd, "dpi_ddr_en_mask"))
  286. pwrctrl->dpi_ddr_en_mask = val;
  287. else if (!strcmp(cmd, "isp0_ddr_en_mask"))
  288. pwrctrl->isp0_ddr_en_mask = val;
  289. else if (!strcmp(cmd, "isp1_ddr_en_mask"))
  290. pwrctrl->isp1_ddr_en_mask = val;
  291. else if (!strcmp(cmd, "md32_req_mask"))
  292. pwrctrl->md32_req_mask = val;
  293. else if (!strcmp(cmd, "syspwreq_mask"))
  294. pwrctrl->syspwreq_mask = val;
  295. else if (!strcmp(cmd, "srclkenai_mask"))
  296. pwrctrl->srclkenai_mask = val;
  297. else if (!strcmp(cmd, "param1"))
  298. pwrctrl->param1 = val;
  299. else if (!strcmp(cmd, "param2"))
  300. pwrctrl->param2 = val;
  301. else if (!strcmp(cmd, "param3"))
  302. pwrctrl->param3 = val;
  303. else
  304. return -EINVAL;
  305. return count;
  306. }
  307. static ssize_t suspend_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  308. const char *buf, size_t count)
  309. {
  310. return store_pwr_ctrl(__spm_suspend.pwrctrl, buf, count);
  311. }
  312. static ssize_t dpidle_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  313. const char *buf, size_t count)
  314. {
  315. #if defined(CONFIG_ARCH_MT6580)
  316. return 0; /* TODO */
  317. #else
  318. return store_pwr_ctrl(__spm_dpidle.pwrctrl, buf, count);
  319. #endif
  320. }
  321. static ssize_t sodi_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  322. const char *buf, size_t count)
  323. {
  324. return store_pwr_ctrl(__spm_sodi.pwrctrl, buf, count);
  325. }
  326. static ssize_t talking_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  327. const char *buf, size_t count)
  328. {
  329. /* for bring up */
  330. #if 0
  331. return store_pwr_ctrl(__spm_talking.pwrctrl, buf, count);
  332. #else
  333. return 0;
  334. #endif
  335. }
  336. static ssize_t ddrdfs_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  337. const char *buf, size_t count)
  338. {
  339. /* for bring up */
  340. #if 0
  341. return store_pwr_ctrl(__spm_ddrdfs.pwrctrl, buf, count);
  342. #else
  343. return 0;
  344. #endif
  345. }
  346. #if defined(SPM_VCORE_EN)
  347. static ssize_t vcorefs_ctrl_store(struct kobject *kobj, struct kobj_attribute *attr,
  348. const char *buf, size_t count)
  349. {
  350. return store_pwr_ctrl(__spm_vcore_dvfs.pwrctrl, buf, count);
  351. }
  352. #endif
  353. /*
  354. * ddren_debug_xxx Function
  355. */
  356. static ssize_t ddren_debug_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  357. {
  358. char *p = buf;
  359. p += sprintf(p, "PCM_REG13_DATA = 0x%x\n", spm_read(SPM_PCM_REG13_DATA));
  360. p += sprintf(p, "AP_STANBY_CON = 0x%x\n", spm_read(SPM_AP_STANBY_CON));
  361. p += sprintf(p, "PCM_DEBUG_CON = 0x%x\n", spm_read(SPM_PCM_DEBUG_CON));
  362. p += sprintf(p, "PCM_PASR_DPD_2 = 0x%x\n", spm_read(SPM_PCM_PASR_DPD_2));
  363. BUG_ON(p - buf >= PAGE_SIZE);
  364. return p - buf;
  365. }
  366. static ssize_t ddren_debug_store(struct kobject *kobj, struct kobj_attribute *attr,
  367. const char *buf, size_t count)
  368. {
  369. u32 val, con;
  370. char cmd[32];
  371. unsigned long flags;
  372. if (sscanf(buf, "%31s %x", cmd, &val) != 2)
  373. return -EPERM;
  374. spm_debug("ddren_debug: cmd = %s, val = 0x%x\n", cmd, val);
  375. if (!strcmp(cmd, "ddr_en_sel")) {
  376. spin_lock_irqsave(&__spm_lock, flags);
  377. con = spm_read(SPM_AP_STANBY_CON) & ~(1U << 22);
  378. spm_write(SPM_AP_STANBY_CON, con | (!!val << 22));
  379. spin_unlock_irqrestore(&__spm_lock, flags);
  380. } else if (!strcmp(cmd, "md_ddr_en_out")) {
  381. spin_lock_irqsave(&__spm_lock, flags);
  382. __spm_dbgout_md_ddr_en(val);
  383. spin_unlock_irqrestore(&__spm_lock, flags);
  384. } else if (!strcmp(cmd, "mm_ddr_en_mask")) {
  385. spin_lock_irqsave(&__spm_lock, flags);
  386. spm_write(SPM_PCM_PASR_DPD_2, ~val & 0x1f);
  387. spin_unlock_irqrestore(&__spm_lock, flags);
  388. } else {
  389. return -EINVAL;
  390. }
  391. return count;
  392. }
  393. /*
  394. * golden_dump_xxx Function
  395. */
  396. static ssize_t golden_dump_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  397. {
  398. char *p = buf;
  399. #if !defined(CONFIG_ARCH_MT6580)
  400. spm_golden_setting_cmp(1);
  401. #endif
  402. BUG_ON(p - buf >= PAGE_SIZE);
  403. return p - buf;
  404. }
  405. /*
  406. * auto_suspend_resume_xxx Function
  407. */
  408. static ssize_t auto_suspend_resume_show(struct kobject *kobj, struct kobj_attribute *attr,
  409. char *buf)
  410. {
  411. #if defined(CONFIG_ARCH_MT6580)
  412. return 0; /* TODO */
  413. #else
  414. char *p = buf;
  415. u8 i;
  416. p += sprintf(p, "auto_suspend_resume:%d times\n", 10);
  417. for (i = 0; i < 10; i++) {
  418. p += sprintf(p, "[%d]wakeup:0x%x,timer:0x%x,r13:0x%x,event=0x%x,flag=0x%x\n",
  419. __spm_suspend.wakestatus[i].log_index,
  420. __spm_suspend.wakestatus[i].r12,
  421. __spm_suspend.wakestatus[i].timer_out,
  422. __spm_suspend.wakestatus[i].r13,
  423. __spm_suspend.wakestatus[i].event_reg,
  424. __spm_suspend.wakestatus[i].debug_flag);
  425. if (0x90100000 != __spm_suspend.wakestatus[i].event_reg)
  426. p += sprintf(p, "SLEEP_ABORT\n");
  427. else if (0x1f != (__spm_suspend.wakestatus[i].debug_flag & 0x1F))
  428. p += sprintf(p, "NOT_DEEP_SLEEP\n");
  429. else
  430. p += sprintf(p, "SLEEP_PASS\n");
  431. }
  432. slp_set_auto_suspend_wakelock(0);
  433. BUG_ON(p - buf >= PAGE_SIZE);
  434. return p - buf;
  435. #endif
  436. }
  437. /* FIXME: early porting */
  438. #if 1
  439. void __attribute__ ((weak)) slp_create_auto_suspend_resume_thread(void)
  440. {
  441. }
  442. void __attribute__ ((weak)) slp_start_auto_suspend_resume_timer(u32 sec)
  443. {
  444. }
  445. void __attribute__ ((weak)) slp_set_auto_suspend_wakelock(bool lock)
  446. {
  447. }
  448. #endif
  449. static ssize_t auto_suspend_resume_store(struct kobject *kobj, struct kobj_attribute *attr,
  450. const char *buf, size_t count)
  451. {
  452. #if defined(CONFIG_ARCH_MT6580)
  453. return 0; /* TODO */
  454. #else
  455. u32 val, pcm_sec;
  456. if (sscanf(buf, "%d %d", &val, &pcm_sec) != 2) {
  457. spm_debug("auto_suspend_resume parameter fail\n");
  458. return -EPERM;
  459. }
  460. spm_debug("auto_suspend_resume val = %d, pcm_sec = %d\n", val, pcm_sec);
  461. __spm_suspend.pwrctrl->timer_val_cust = pcm_sec * 32768;
  462. slp_create_auto_suspend_resume_thread();
  463. slp_start_auto_suspend_resume_timer(val);
  464. return count;
  465. #endif
  466. }
  467. /*
  468. * Init Function
  469. */
  470. DEFINE_ATTR_RO(suspend_pcm);
  471. DEFINE_ATTR_RO(dpidle_pcm);
  472. DEFINE_ATTR_RO(sodi_pcm);
  473. DEFINE_ATTR_RO(talking_pcm);
  474. DEFINE_ATTR_RO(ddrdfs_pcm);
  475. #if defined(SPM_VCORE_EN)
  476. DEFINE_ATTR_RO(vcorefs_pcm);
  477. #endif
  478. DEFINE_ATTR_RW(suspend_ctrl);
  479. DEFINE_ATTR_RW(dpidle_ctrl);
  480. DEFINE_ATTR_RW(sodi_ctrl);
  481. DEFINE_ATTR_RW(talking_ctrl);
  482. DEFINE_ATTR_RW(ddrdfs_ctrl);
  483. #if defined(SPM_VCORE_EN)
  484. DEFINE_ATTR_RW(vcorefs_ctrl);
  485. #endif
  486. DEFINE_ATTR_RW(ddren_debug);
  487. DEFINE_ATTR_RO(golden_dump);
  488. DEFINE_ATTR_RW(auto_suspend_resume);
  489. static struct attribute *spm_attrs[] = {
  490. /* for spm_lp_scen.pcmdesc */
  491. __ATTR_OF(suspend_pcm),
  492. __ATTR_OF(dpidle_pcm),
  493. __ATTR_OF(sodi_pcm),
  494. __ATTR_OF(talking_pcm),
  495. __ATTR_OF(ddrdfs_pcm),
  496. #if defined(SPM_VCORE_EN)
  497. __ATTR_OF(vcorefs_pcm),
  498. #endif
  499. /* for spm_lp_scen.pwrctrl */
  500. __ATTR_OF(suspend_ctrl),
  501. __ATTR_OF(dpidle_ctrl),
  502. __ATTR_OF(sodi_ctrl),
  503. __ATTR_OF(talking_ctrl),
  504. __ATTR_OF(ddrdfs_ctrl),
  505. #if defined(SPM_VCORE_EN)
  506. __ATTR_OF(vcorefs_ctrl),
  507. #endif
  508. /* other debug interface */
  509. __ATTR_OF(ddren_debug),
  510. __ATTR_OF(golden_dump),
  511. __ATTR_OF(auto_suspend_resume),
  512. /* must */
  513. NULL,
  514. };
  515. static struct attribute_group spm_attr_group = {
  516. .name = "spm",
  517. .attrs = spm_attrs,
  518. };
  519. int spm_fs_init(void)
  520. {
  521. int r;
  522. /* create /sys/power/spm/xxx */
  523. r = sysfs_create_group(power_kobj, &spm_attr_group);
  524. if (r)
  525. spm_err("FAILED TO CREATE /sys/power/spm (%d)\n", r);
  526. return r;
  527. }
  528. MODULE_DESCRIPTION("SPM-FS Driver v0.1");