diff options
author | Giuseppe CAVALLARO <peppe.cavallaro@st.com> | 2011-11-04 08:53:19 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-01-11 23:58:40 -0500 |
commit | df16219f365f7f5a2d88a6e123251d57255cca3f (patch) | |
tree | 0eca076f1abf8a0161f8fb66e1f98b5a003c900b | |
parent | 052d81da6e6f0f8839ef6d5a46f215fc8cd99d5a (diff) |
mmc: debugfs: expose the SDCLK frq in sys ios
This patch is to expose the actual SDCLK frequency in
/sys/kernel/debug/mmcX/ios entry.
For example, if the max clk for a normal speed card is 20MHz this
is reported in /sys/kernel/debug/mmcX/ios. Unfortunately the actual
SDCLK frequency (i.e. Baseclock / divisor) is not reported at all:
for example, in that case, on Arasan HC, it should be 48/4=12 (MHz).
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r-- | drivers/mmc/core/debugfs.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 10 | ||||
-rw-r--r-- | include/linux/mmc/host.h | 2 |
3 files changed, 14 insertions, 0 deletions
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 3923880118b6..027615d3bf3e 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c | |||
@@ -57,6 +57,8 @@ static int mmc_ios_show(struct seq_file *s, void *data) | |||
57 | const char *str; | 57 | const char *str; |
58 | 58 | ||
59 | seq_printf(s, "clock:\t\t%u Hz\n", ios->clock); | 59 | seq_printf(s, "clock:\t\t%u Hz\n", ios->clock); |
60 | if (host->actual_clock) | ||
61 | seq_printf(s, "actual clock:\t%u Hz\n", host->actual_clock); | ||
60 | seq_printf(s, "vdd:\t\t%u ", ios->vdd); | 62 | seq_printf(s, "vdd:\t\t%u ", ios->vdd); |
61 | if ((1 << ios->vdd) & MMC_VDD_165_195) | 63 | if ((1 << ios->vdd) & MMC_VDD_165_195) |
62 | seq_printf(s, "(1.65 - 1.95 V)\n"); | 64 | seq_printf(s, "(1.65 - 1.95 V)\n"); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 19ed580f2cab..a7c23118dab2 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1066,12 +1066,15 @@ static void sdhci_finish_command(struct sdhci_host *host) | |||
1066 | static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | 1066 | static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) |
1067 | { | 1067 | { |
1068 | int div = 0; /* Initialized for compiler warning */ | 1068 | int div = 0; /* Initialized for compiler warning */ |
1069 | int real_div = div, clk_mul = 1; | ||
1069 | u16 clk = 0; | 1070 | u16 clk = 0; |
1070 | unsigned long timeout; | 1071 | unsigned long timeout; |
1071 | 1072 | ||
1072 | if (clock == host->clock) | 1073 | if (clock == host->clock) |
1073 | return; | 1074 | return; |
1074 | 1075 | ||
1076 | host->mmc->actual_clock = 0; | ||
1077 | |||
1075 | if (host->ops->set_clock) { | 1078 | if (host->ops->set_clock) { |
1076 | host->ops->set_clock(host, clock); | 1079 | host->ops->set_clock(host, clock); |
1077 | if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) | 1080 | if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) |
@@ -1109,6 +1112,8 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
1109 | * Control register. | 1112 | * Control register. |
1110 | */ | 1113 | */ |
1111 | clk = SDHCI_PROG_CLOCK_MODE; | 1114 | clk = SDHCI_PROG_CLOCK_MODE; |
1115 | real_div = div; | ||
1116 | clk_mul = host->clk_mul; | ||
1112 | div--; | 1117 | div--; |
1113 | } | 1118 | } |
1114 | } else { | 1119 | } else { |
@@ -1122,6 +1127,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
1122 | break; | 1127 | break; |
1123 | } | 1128 | } |
1124 | } | 1129 | } |
1130 | real_div = div; | ||
1125 | div >>= 1; | 1131 | div >>= 1; |
1126 | } | 1132 | } |
1127 | } else { | 1133 | } else { |
@@ -1130,9 +1136,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
1130 | if ((host->max_clk / div) <= clock) | 1136 | if ((host->max_clk / div) <= clock) |
1131 | break; | 1137 | break; |
1132 | } | 1138 | } |
1139 | real_div = div; | ||
1133 | div >>= 1; | 1140 | div >>= 1; |
1134 | } | 1141 | } |
1135 | 1142 | ||
1143 | if (real_div) | ||
1144 | host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div; | ||
1145 | |||
1136 | clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; | 1146 | clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; |
1137 | clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) | 1147 | clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) |
1138 | << SDHCI_DIVIDER_HI_SHIFT; | 1148 | << SDHCI_DIVIDER_HI_SHIFT; |
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index a3ac9c48e5de..cea064f73514 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -323,6 +323,8 @@ struct mmc_host { | |||
323 | struct fault_attr fail_mmc_request; | 323 | struct fault_attr fail_mmc_request; |
324 | #endif | 324 | #endif |
325 | 325 | ||
326 | unsigned int actual_clock; /* Actual HC clock rate */ | ||
327 | |||
326 | unsigned long private[0] ____cacheline_aligned; | 328 | unsigned long private[0] ____cacheline_aligned; |
327 | }; | 329 | }; |
328 | 330 | ||