diff options
| -rw-r--r-- | drivers/mmc/core/bus.c | 8 | ||||
| -rw-r--r-- | drivers/mmc/core/core.h | 3 | ||||
| -rw-r--r-- | drivers/mmc/core/debugfs.c | 61 | ||||
| -rw-r--r-- | include/linux/mmc/card.h | 2 |
4 files changed, 74 insertions, 0 deletions
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index fd95b18e988b..0d9b2d6f9ebf 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
| @@ -252,6 +252,10 @@ int mmc_add_card(struct mmc_card *card) | |||
| 252 | if (ret) | 252 | if (ret) |
| 253 | return ret; | 253 | return ret; |
| 254 | 254 | ||
| 255 | #ifdef CONFIG_DEBUG_FS | ||
| 256 | mmc_add_card_debugfs(card); | ||
| 257 | #endif | ||
| 258 | |||
| 255 | mmc_card_set_present(card); | 259 | mmc_card_set_present(card); |
| 256 | 260 | ||
| 257 | return 0; | 261 | return 0; |
| @@ -263,6 +267,10 @@ int mmc_add_card(struct mmc_card *card) | |||
| 263 | */ | 267 | */ |
| 264 | void mmc_remove_card(struct mmc_card *card) | 268 | void mmc_remove_card(struct mmc_card *card) |
| 265 | { | 269 | { |
| 270 | #ifdef CONFIG_DEBUG_FS | ||
| 271 | mmc_remove_card_debugfs(card); | ||
| 272 | #endif | ||
| 273 | |||
| 266 | if (mmc_card_present(card)) { | 274 | if (mmc_card_present(card)) { |
| 267 | if (mmc_host_is_spi(card->host)) { | 275 | if (mmc_host_is_spi(card->host)) { |
| 268 | printk(KERN_INFO "%s: SPI card removed\n", | 276 | printk(KERN_INFO "%s: SPI card removed\n", |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 745da9881aa7..c819effa1032 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
| @@ -56,5 +56,8 @@ extern int use_spi_crc; | |||
| 56 | void mmc_add_host_debugfs(struct mmc_host *host); | 56 | void mmc_add_host_debugfs(struct mmc_host *host); |
| 57 | void mmc_remove_host_debugfs(struct mmc_host *host); | 57 | void mmc_remove_host_debugfs(struct mmc_host *host); |
| 58 | 58 | ||
| 59 | void mmc_add_card_debugfs(struct mmc_card *card); | ||
| 60 | void mmc_remove_card_debugfs(struct mmc_card *card); | ||
| 61 | |||
| 59 | #endif | 62 | #endif |
| 60 | 63 | ||
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 133c6e51f26b..1237bb4c722b 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c | |||
| @@ -12,9 +12,11 @@ | |||
| 12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
| 13 | #include <linux/stat.h> | 13 | #include <linux/stat.h> |
| 14 | 14 | ||
| 15 | #include <linux/mmc/card.h> | ||
| 15 | #include <linux/mmc/host.h> | 16 | #include <linux/mmc/host.h> |
| 16 | 17 | ||
| 17 | #include "core.h" | 18 | #include "core.h" |
| 19 | #include "mmc_ops.h" | ||
| 18 | 20 | ||
| 19 | /* The debugfs functions are optimized away when CONFIG_DEBUG_FS isn't set. */ | 21 | /* The debugfs functions are optimized away when CONFIG_DEBUG_FS isn't set. */ |
| 20 | static int mmc_ios_show(struct seq_file *s, void *data) | 22 | static int mmc_ios_show(struct seq_file *s, void *data) |
| @@ -162,3 +164,62 @@ void mmc_remove_host_debugfs(struct mmc_host *host) | |||
| 162 | { | 164 | { |
| 163 | debugfs_remove_recursive(host->debugfs_root); | 165 | debugfs_remove_recursive(host->debugfs_root); |
| 164 | } | 166 | } |
| 167 | |||
| 168 | static int mmc_dbg_card_status_get(void *data, u64 *val) | ||
| 169 | { | ||
| 170 | struct mmc_card *card = data; | ||
| 171 | u32 status; | ||
| 172 | int ret; | ||
| 173 | |||
| 174 | mmc_claim_host(card->host); | ||
| 175 | |||
| 176 | ret = mmc_send_status(data, &status); | ||
| 177 | if (!ret) | ||
| 178 | *val = status; | ||
| 179 | |||
| 180 | mmc_release_host(card->host); | ||
| 181 | |||
| 182 | return ret; | ||
| 183 | } | ||
| 184 | DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get, | ||
| 185 | NULL, "%08llx\n"); | ||
| 186 | |||
| 187 | void mmc_add_card_debugfs(struct mmc_card *card) | ||
| 188 | { | ||
| 189 | struct mmc_host *host = card->host; | ||
| 190 | struct dentry *root; | ||
| 191 | |||
| 192 | if (!host->debugfs_root) | ||
| 193 | return; | ||
| 194 | |||
| 195 | root = debugfs_create_dir(mmc_card_id(card), host->debugfs_root); | ||
| 196 | if (IS_ERR(root)) | ||
| 197 | /* Don't complain -- debugfs just isn't enabled */ | ||
| 198 | return; | ||
| 199 | if (!root) | ||
| 200 | /* Complain -- debugfs is enabled, but it failed to | ||
| 201 | * create the directory. */ | ||
| 202 | goto err; | ||
| 203 | |||
| 204 | card->debugfs_root = root; | ||
| 205 | |||
| 206 | if (!debugfs_create_x32("state", S_IRUSR, root, &card->state)) | ||
| 207 | goto err; | ||
| 208 | |||
| 209 | if (mmc_card_mmc(card) || mmc_card_sd(card)) | ||
| 210 | if (!debugfs_create_file("status", S_IRUSR, root, card, | ||
| 211 | &mmc_dbg_card_status_fops)) | ||
| 212 | goto err; | ||
| 213 | |||
| 214 | return; | ||
| 215 | |||
| 216 | err: | ||
| 217 | debugfs_remove_recursive(root); | ||
| 218 | card->debugfs_root = NULL; | ||
| 219 | dev_err(&card->dev, "failed to initialize debugfs\n"); | ||
| 220 | } | ||
| 221 | |||
| 222 | void mmc_remove_card_debugfs(struct mmc_card *card) | ||
| 223 | { | ||
| 224 | debugfs_remove_recursive(card->debugfs_root); | ||
| 225 | } | ||
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 0d508ac17d64..ee6e822d5994 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
| @@ -111,6 +111,8 @@ struct mmc_card { | |||
| 111 | unsigned num_info; /* number of info strings */ | 111 | unsigned num_info; /* number of info strings */ |
| 112 | const char **info; /* info strings */ | 112 | const char **info; /* info strings */ |
| 113 | struct sdio_func_tuple *tuples; /* unknown common tuples */ | 113 | struct sdio_func_tuple *tuples; /* unknown common tuples */ |
| 114 | |||
| 115 | struct dentry *debugfs_root; | ||
| 114 | }; | 116 | }; |
| 115 | 117 | ||
| 116 | #define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC) | 118 | #define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC) |
