debugfs.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Debugfs support for hosts and cards
  4. *
  5. * Copyright (C) 2008 Atmel Corporation
  6. */
  7. #include <linux/moduleparam.h>
  8. #include <linux/export.h>
  9. #include <linux/debugfs.h>
  10. #include <linux/fs.h>
  11. #include <linux/seq_file.h>
  12. #include <linux/slab.h>
  13. #include <linux/stat.h>
  14. #include <linux/fault-inject.h>
  15. #include <linux/time.h>
  16. #include <linux/mmc/card.h>
  17. #include <linux/mmc/host.h>
  18. #include <linux/mmc/mmc.h>
  19. #include <linux/mmc/sd.h>
  20. #include "core.h"
  21. #include "card.h"
  22. #include "host.h"
  23. #include "mmc_ops.h"
  24. #ifdef CONFIG_FAIL_MMC_REQUEST
  25. static DECLARE_FAULT_ATTR(fail_default_attr);
  26. static char *fail_request;
  27. module_param(fail_request, charp, 0);
  28. MODULE_PARM_DESC(fail_request, "default fault injection attributes");
  29. #endif /* CONFIG_FAIL_MMC_REQUEST */
  30. /* The debugfs functions are optimized away when CONFIG_DEBUG_FS isn't set. */
  31. static int mmc_ios_show(struct seq_file *s, void *data)
  32. {
  33. static const char *vdd_str[] = {
  34. [8] = "2.0",
  35. [9] = "2.1",
  36. [10] = "2.2",
  37. [11] = "2.3",
  38. [12] = "2.4",
  39. [13] = "2.5",
  40. [14] = "2.6",
  41. [15] = "2.7",
  42. [16] = "2.8",
  43. [17] = "2.9",
  44. [18] = "3.0",
  45. [19] = "3.1",
  46. [20] = "3.2",
  47. [21] = "3.3",
  48. [22] = "3.4",
  49. [23] = "3.5",
  50. [24] = "3.6",
  51. };
  52. struct mmc_host *host = s->private;
  53. struct mmc_ios *ios = &host->ios;
  54. const char *str;
  55. seq_printf(s, "clock:\t\t%u Hz\n", ios->clock);
  56. if (host->actual_clock)
  57. seq_printf(s, "actual clock:\t%u Hz\n", host->actual_clock);
  58. seq_printf(s, "vdd:\t\t%u ", ios->vdd);
  59. if ((1 << ios->vdd) & MMC_VDD_165_195)
  60. seq_printf(s, "(1.65 - 1.95 V)\n");
  61. else if (ios->vdd < (ARRAY_SIZE(vdd_str) - 1)
  62. && vdd_str[ios->vdd] && vdd_str[ios->vdd + 1])
  63. seq_printf(s, "(%s ~ %s V)\n", vdd_str[ios->vdd],
  64. vdd_str[ios->vdd + 1]);
  65. else
  66. seq_printf(s, "(invalid)\n");
  67. switch (ios->bus_mode) {
  68. case MMC_BUSMODE_OPENDRAIN:
  69. str = "open drain";
  70. break;
  71. case MMC_BUSMODE_PUSHPULL:
  72. str = "push-pull";
  73. break;
  74. default:
  75. str = "invalid";
  76. break;
  77. }
  78. seq_printf(s, "bus mode:\t%u (%s)\n", ios->bus_mode, str);
  79. switch (ios->chip_select) {
  80. case MMC_CS_DONTCARE:
  81. str = "don't care";
  82. break;
  83. case MMC_CS_HIGH:
  84. str = "active high";
  85. break;
  86. case MMC_CS_LOW:
  87. str = "active low";
  88. break;
  89. default:
  90. str = "invalid";
  91. break;
  92. }
  93. seq_printf(s, "chip select:\t%u (%s)\n", ios->chip_select, str);
  94. switch (ios->power_mode) {
  95. case MMC_POWER_OFF:
  96. str = "off";
  97. break;
  98. case MMC_POWER_UP:
  99. str = "up";
  100. break;
  101. case MMC_POWER_ON:
  102. str = "on";
  103. break;
  104. default:
  105. str = "invalid";
  106. break;
  107. }
  108. seq_printf(s, "power mode:\t%u (%s)\n", ios->power_mode, str);
  109. seq_printf(s, "bus width:\t%u (%u bits)\n",
  110. ios->bus_width, 1 << ios->bus_width);
  111. switch (ios->timing) {
  112. case MMC_TIMING_LEGACY:
  113. str = "legacy";
  114. break;
  115. case MMC_TIMING_MMC_HS:
  116. str = "mmc high-speed";
  117. break;
  118. case MMC_TIMING_SD_HS:
  119. str = "sd high-speed";
  120. break;
  121. case MMC_TIMING_UHS_SDR12:
  122. str = "sd uhs SDR12";
  123. break;
  124. case MMC_TIMING_UHS_SDR25:
  125. str = "sd uhs SDR25";
  126. break;
  127. case MMC_TIMING_UHS_SDR50:
  128. str = "sd uhs SDR50";
  129. break;
  130. case MMC_TIMING_UHS_SDR104:
  131. str = "sd uhs SDR104";
  132. break;
  133. case MMC_TIMING_UHS_DDR50:
  134. str = "sd uhs DDR50";
  135. break;
  136. case MMC_TIMING_MMC_DDR52:
  137. str = "mmc DDR52";
  138. break;
  139. case MMC_TIMING_MMC_HS200:
  140. str = "mmc HS200";
  141. break;
  142. case MMC_TIMING_MMC_HS400:
  143. str = mmc_card_hs400es(host->card) ?
  144. "mmc HS400 enhanced strobe" : "mmc HS400";
  145. break;
  146. default:
  147. str = "invalid";
  148. break;
  149. }
  150. seq_printf(s, "timing spec:\t%u (%s)\n", ios->timing, str);
  151. switch (ios->signal_voltage) {
  152. case MMC_SIGNAL_VOLTAGE_330:
  153. str = "3.30 V";
  154. break;
  155. case MMC_SIGNAL_VOLTAGE_180:
  156. str = "1.80 V";
  157. break;
  158. case MMC_SIGNAL_VOLTAGE_120:
  159. str = "1.20 V";
  160. break;
  161. default:
  162. str = "invalid";
  163. break;
  164. }
  165. seq_printf(s, "signal voltage:\t%u (%s)\n", ios->signal_voltage, str);
  166. switch (ios->drv_type) {
  167. case MMC_SET_DRIVER_TYPE_A:
  168. str = "driver type A";
  169. break;
  170. case MMC_SET_DRIVER_TYPE_B:
  171. str = "driver type B";
  172. break;
  173. case MMC_SET_DRIVER_TYPE_C:
  174. str = "driver type C";
  175. break;
  176. case MMC_SET_DRIVER_TYPE_D:
  177. str = "driver type D";
  178. break;
  179. default:
  180. str = "invalid";
  181. break;
  182. }
  183. seq_printf(s, "driver type:\t%u (%s)\n", ios->drv_type, str);
  184. return 0;
  185. }
  186. DEFINE_SHOW_ATTRIBUTE(mmc_ios);
  187. static int mmc_clock_opt_get(void *data, u64 *val)
  188. {
  189. struct mmc_host *host = data;
  190. *val = host->ios.clock;
  191. return 0;
  192. }
  193. static int mmc_clock_opt_set(void *data, u64 val)
  194. {
  195. struct mmc_host *host = data;
  196. /* We need this check due to input value is u64 */
  197. if (val != 0 && (val > host->f_max || val < host->f_min))
  198. return -EINVAL;
  199. mmc_claim_host(host);
  200. mmc_set_clock(host, (unsigned int) val);
  201. mmc_release_host(host);
  202. return 0;
  203. }
  204. DEFINE_DEBUGFS_ATTRIBUTE(mmc_clock_fops, mmc_clock_opt_get, mmc_clock_opt_set,
  205. "%llu\n");
  206. static int mmc_err_state_get(void *data, u64 *val)
  207. {
  208. struct mmc_host *host = data;
  209. int i;
  210. if (!host)
  211. return -EINVAL;
  212. *val = 0;
  213. for (i = 0; i < MMC_ERR_MAX; i++) {
  214. if (host->err_stats[i]) {
  215. *val = 1;
  216. break;
  217. }
  218. }
  219. return 0;
  220. }
  221. DEFINE_DEBUGFS_ATTRIBUTE(mmc_err_state, mmc_err_state_get, NULL, "%llu\n");
  222. static int mmc_err_stats_show(struct seq_file *file, void *data)
  223. {
  224. struct mmc_host *host = file->private;
  225. const char *desc[MMC_ERR_MAX] = {
  226. [MMC_ERR_CMD_TIMEOUT] = "Command Timeout Occurred",
  227. [MMC_ERR_CMD_CRC] = "Command CRC Errors Occurred",
  228. [MMC_ERR_DAT_TIMEOUT] = "Data Timeout Occurred",
  229. [MMC_ERR_DAT_CRC] = "Data CRC Errors Occurred",
  230. [MMC_ERR_AUTO_CMD] = "Auto-Cmd Error Occurred",
  231. [MMC_ERR_ADMA] = "ADMA Error Occurred",
  232. [MMC_ERR_TUNING] = "Tuning Error Occurred",
  233. [MMC_ERR_CMDQ_RED] = "CMDQ RED Errors",
  234. [MMC_ERR_CMDQ_GCE] = "CMDQ GCE Errors",
  235. [MMC_ERR_CMDQ_ICCE] = "CMDQ ICCE Errors",
  236. [MMC_ERR_REQ_TIMEOUT] = "Request Timedout",
  237. [MMC_ERR_CMDQ_REQ_TIMEOUT] = "CMDQ Request Timedout",
  238. [MMC_ERR_ICE_CFG] = "ICE Config Errors",
  239. [MMC_ERR_CTRL_TIMEOUT] = "Controller Timedout errors",
  240. [MMC_ERR_UNEXPECTED_IRQ] = "Unexpected IRQ errors",
  241. };
  242. int i;
  243. for (i = 0; i < MMC_ERR_MAX; i++) {
  244. if (desc[i])
  245. seq_printf(file, "# %s:\t %d\n",
  246. desc[i], host->err_stats[i]);
  247. }
  248. return 0;
  249. }
  250. static int mmc_err_stats_open(struct inode *inode, struct file *file)
  251. {
  252. return single_open(file, mmc_err_stats_show, inode->i_private);
  253. }
  254. static ssize_t mmc_err_stats_write(struct file *filp, const char __user *ubuf,
  255. size_t cnt, loff_t *ppos)
  256. {
  257. struct mmc_host *host = filp->f_mapping->host->i_private;
  258. pr_debug("%s: Resetting MMC error statistics\n", __func__);
  259. memset(host->err_stats, 0, sizeof(host->err_stats));
  260. return cnt;
  261. }
  262. static const struct file_operations mmc_err_stats_fops = {
  263. .open = mmc_err_stats_open,
  264. .read = seq_read,
  265. .write = mmc_err_stats_write,
  266. .release = single_release,
  267. };
  268. static int mmc_caps_get(void *data, u64 *val)
  269. {
  270. *val = *(u32 *)data;
  271. return 0;
  272. }
  273. static int mmc_caps_set(void *data, u64 val)
  274. {
  275. u32 *caps = data;
  276. u32 diff = *caps ^ val;
  277. u32 allowed = MMC_CAP_AGGRESSIVE_PM |
  278. MMC_CAP_SD_HIGHSPEED |
  279. MMC_CAP_MMC_HIGHSPEED |
  280. MMC_CAP_UHS |
  281. MMC_CAP_DDR |
  282. MMC_CAP_4_BIT_DATA |
  283. MMC_CAP_8_BIT_DATA |
  284. MMC_CAP_CMD23;
  285. if (diff & ~allowed)
  286. return -EINVAL;
  287. *caps = val;
  288. return 0;
  289. }
  290. static int mmc_caps2_set(void *data, u64 val)
  291. {
  292. u32 allowed = MMC_CAP2_HSX00_1_8V |
  293. MMC_CAP2_HSX00_1_2V |
  294. MMC_CAP2_CQE |
  295. MMC_CAP2_CQE_DCMD;
  296. u32 *caps = data;
  297. u32 diff = *caps ^ val;
  298. if (diff & ~allowed)
  299. return -EINVAL;
  300. *caps = val;
  301. return 0;
  302. }
  303. DEFINE_DEBUGFS_ATTRIBUTE(mmc_caps_fops, mmc_caps_get, mmc_caps_set,
  304. "0x%08llx\n");
  305. DEFINE_DEBUGFS_ATTRIBUTE(mmc_caps2_fops, mmc_caps_get, mmc_caps2_set,
  306. "0x%08llx\n");
  307. void mmc_add_host_debugfs(struct mmc_host *host)
  308. {
  309. struct dentry *root;
  310. root = debugfs_create_dir(mmc_hostname(host), NULL);
  311. host->debugfs_root = root;
  312. debugfs_create_file("ios", 0400, root, host, &mmc_ios_fops);
  313. debugfs_create_file("caps", 0600, root, &host->caps, &mmc_caps_fops);
  314. debugfs_create_file("caps2", 0600, root, &host->caps2,
  315. &mmc_caps2_fops);
  316. debugfs_create_file_unsafe("clock", 0600, root, host,
  317. &mmc_clock_fops);
  318. debugfs_create_file_unsafe("err_state", 0600, root, host,
  319. &mmc_err_state);
  320. debugfs_create_file("err_stats", 0600, root, host,
  321. &mmc_err_stats_fops);
  322. #ifdef CONFIG_FAIL_MMC_REQUEST
  323. if (fail_request)
  324. setup_fault_attr(&fail_default_attr, fail_request);
  325. host->fail_mmc_request = fail_default_attr;
  326. fault_create_debugfs_attr("fail_mmc_request", root,
  327. &host->fail_mmc_request);
  328. #endif
  329. }
  330. void mmc_remove_host_debugfs(struct mmc_host *host)
  331. {
  332. debugfs_remove_recursive(host->debugfs_root);
  333. }
  334. void mmc_add_card_debugfs(struct mmc_card *card)
  335. {
  336. struct mmc_host *host = card->host;
  337. struct dentry *root;
  338. if (!host->debugfs_root)
  339. return;
  340. root = debugfs_create_dir(mmc_card_id(card), host->debugfs_root);
  341. card->debugfs_root = root;
  342. debugfs_create_x32("state", 0400, root, &card->state);
  343. debugfs_create_x32("quirks", 0400, root, &card->quirks);
  344. }
  345. void mmc_remove_card_debugfs(struct mmc_card *card)
  346. {
  347. debugfs_remove_recursive(card->debugfs_root);
  348. card->debugfs_root = NULL;
  349. }