diff options
author | Shawn Guo <shawn.guo@freescale.com> | 2011-06-01 22:57:50 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2011-07-20 17:20:49 -0400 |
commit | f0de836923186e1fc0acb65299c2f2089c7992af (patch) | |
tree | 4cfaf194295559500dee84646af4ded4ba94faf9 /drivers/mmc/host/sdhci-pltfm.c | |
parent | 100e918610b7487fa18db97b3879cd8d1fdd5974 (diff) |
mmc: sdhci: change sdhci-pltfm into a module
There are a couple of problems left from the sdhci pltfm and OF
consolidation changes.
* When building more than one sdhci-pltfm based drivers in the same
image, linker will give multiple definition error on the sdhci-pltfm
helper functions. For example right now, building sdhci-of-esdhc
and sdhci-of-hlwd together is a valid combination from Kconfig view.
* With the current build method, there is error with building the
drivers as module, but module installation fails with modprobe.
The patch fixes above problems by changing sdhci-pltfm into a module.
To avoid EXPORT_SYMBOL on so many big endian IO accessors, it moves
these accessors into sdhci-pltfm.h as the 'static inline' functions.
As a result, sdhci.h needs to be included in sdhci-pltfm.h, and in
turn can be removed from individual drivers which already include
sdhci-pltfm.h.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/sdhci-pltfm.c')
-rw-r--r-- | drivers/mmc/host/sdhci-pltfm.c | 82 |
1 files changed, 24 insertions, 58 deletions
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 041b0e2a898e..71c0ce1f6db0 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c | |||
@@ -33,69 +33,11 @@ | |||
33 | #ifdef CONFIG_PPC | 33 | #ifdef CONFIG_PPC |
34 | #include <asm/machdep.h> | 34 | #include <asm/machdep.h> |
35 | #endif | 35 | #endif |
36 | #include "sdhci.h" | ||
37 | #include "sdhci-pltfm.h" | 36 | #include "sdhci-pltfm.h" |
38 | 37 | ||
39 | static struct sdhci_ops sdhci_pltfm_ops = { | 38 | static struct sdhci_ops sdhci_pltfm_ops = { |
40 | }; | 39 | }; |
41 | 40 | ||
42 | #ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER | ||
43 | /* | ||
44 | * These accessors are designed for big endian hosts doing I/O to | ||
45 | * little endian controllers incorporating a 32-bit hardware byte swapper. | ||
46 | */ | ||
47 | u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg) | ||
48 | { | ||
49 | return in_be32(host->ioaddr + reg); | ||
50 | } | ||
51 | |||
52 | u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg) | ||
53 | { | ||
54 | return in_be16(host->ioaddr + (reg ^ 0x2)); | ||
55 | } | ||
56 | |||
57 | u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg) | ||
58 | { | ||
59 | return in_8(host->ioaddr + (reg ^ 0x3)); | ||
60 | } | ||
61 | |||
62 | void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg) | ||
63 | { | ||
64 | out_be32(host->ioaddr + reg, val); | ||
65 | } | ||
66 | |||
67 | void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg) | ||
68 | { | ||
69 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
70 | int base = reg & ~0x3; | ||
71 | int shift = (reg & 0x2) * 8; | ||
72 | |||
73 | switch (reg) { | ||
74 | case SDHCI_TRANSFER_MODE: | ||
75 | /* | ||
76 | * Postpone this write, we must do it together with a | ||
77 | * command write that is down below. | ||
78 | */ | ||
79 | pltfm_host->xfer_mode_shadow = val; | ||
80 | return; | ||
81 | case SDHCI_COMMAND: | ||
82 | sdhci_be32bs_writel(host, | ||
83 | val << 16 | pltfm_host->xfer_mode_shadow, | ||
84 | SDHCI_TRANSFER_MODE); | ||
85 | return; | ||
86 | } | ||
87 | clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); | ||
88 | } | ||
89 | |||
90 | void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg) | ||
91 | { | ||
92 | int base = reg & ~0x3; | ||
93 | int shift = (reg & 0x3) * 8; | ||
94 | |||
95 | clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); | ||
96 | } | ||
97 | #endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */ | ||
98 | |||
99 | #ifdef CONFIG_OF | 41 | #ifdef CONFIG_OF |
100 | static bool sdhci_of_wp_inverted(struct device_node *np) | 42 | static bool sdhci_of_wp_inverted(struct device_node *np) |
101 | { | 43 | { |
@@ -136,6 +78,7 @@ void sdhci_get_of_property(struct platform_device *pdev) | |||
136 | #else | 78 | #else |
137 | void sdhci_get_of_property(struct platform_device *pdev) {} | 79 | void sdhci_get_of_property(struct platform_device *pdev) {} |
138 | #endif /* CONFIG_OF */ | 80 | #endif /* CONFIG_OF */ |
81 | EXPORT_SYMBOL_GPL(sdhci_get_of_property); | ||
139 | 82 | ||
140 | struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, | 83 | struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, |
141 | struct sdhci_pltfm_data *pdata) | 84 | struct sdhci_pltfm_data *pdata) |
@@ -202,6 +145,7 @@ err: | |||
202 | dev_err(&pdev->dev, "%s failed %d\n", __func__, ret); | 145 | dev_err(&pdev->dev, "%s failed %d\n", __func__, ret); |
203 | return ERR_PTR(ret); | 146 | return ERR_PTR(ret); |
204 | } | 147 | } |
148 | EXPORT_SYMBOL_GPL(sdhci_pltfm_init); | ||
205 | 149 | ||
206 | void sdhci_pltfm_free(struct platform_device *pdev) | 150 | void sdhci_pltfm_free(struct platform_device *pdev) |
207 | { | 151 | { |
@@ -213,6 +157,7 @@ void sdhci_pltfm_free(struct platform_device *pdev) | |||
213 | sdhci_free_host(host); | 157 | sdhci_free_host(host); |
214 | platform_set_drvdata(pdev, NULL); | 158 | platform_set_drvdata(pdev, NULL); |
215 | } | 159 | } |
160 | EXPORT_SYMBOL_GPL(sdhci_pltfm_free); | ||
216 | 161 | ||
217 | int sdhci_pltfm_register(struct platform_device *pdev, | 162 | int sdhci_pltfm_register(struct platform_device *pdev, |
218 | struct sdhci_pltfm_data *pdata) | 163 | struct sdhci_pltfm_data *pdata) |
@@ -232,6 +177,7 @@ int sdhci_pltfm_register(struct platform_device *pdev, | |||
232 | 177 | ||
233 | return ret; | 178 | return ret; |
234 | } | 179 | } |
180 | EXPORT_SYMBOL_GPL(sdhci_pltfm_register); | ||
235 | 181 | ||
236 | int sdhci_pltfm_unregister(struct platform_device *pdev) | 182 | int sdhci_pltfm_unregister(struct platform_device *pdev) |
237 | { | 183 | { |
@@ -243,6 +189,7 @@ int sdhci_pltfm_unregister(struct platform_device *pdev) | |||
243 | 189 | ||
244 | return 0; | 190 | return 0; |
245 | } | 191 | } |
192 | EXPORT_SYMBOL_GPL(sdhci_pltfm_unregister); | ||
246 | 193 | ||
247 | #ifdef CONFIG_PM | 194 | #ifdef CONFIG_PM |
248 | int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state) | 195 | int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state) |
@@ -251,6 +198,7 @@ int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state) | |||
251 | 198 | ||
252 | return sdhci_suspend_host(host, state); | 199 | return sdhci_suspend_host(host, state); |
253 | } | 200 | } |
201 | EXPORT_SYMBOL_GPL(sdhci_pltfm_suspend); | ||
254 | 202 | ||
255 | int sdhci_pltfm_resume(struct platform_device *dev) | 203 | int sdhci_pltfm_resume(struct platform_device *dev) |
256 | { | 204 | { |
@@ -258,4 +206,22 @@ int sdhci_pltfm_resume(struct platform_device *dev) | |||
258 | 206 | ||
259 | return sdhci_resume_host(host); | 207 | return sdhci_resume_host(host); |
260 | } | 208 | } |
209 | EXPORT_SYMBOL_GPL(sdhci_pltfm_resume); | ||
261 | #endif /* CONFIG_PM */ | 210 | #endif /* CONFIG_PM */ |
211 | |||
212 | static int __init sdhci_pltfm_drv_init(void) | ||
213 | { | ||
214 | pr_info("sdhci-pltfm: SDHCI platform and OF driver helper\n"); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | module_init(sdhci_pltfm_drv_init); | ||
219 | |||
220 | static void __exit sdhci_pltfm_drv_exit(void) | ||
221 | { | ||
222 | } | ||
223 | module_exit(sdhci_pltfm_drv_exit); | ||
224 | |||
225 | MODULE_DESCRIPTION("SDHCI platform and OF driver helper"); | ||
226 | MODULE_AUTHOR("Intel Corporation"); | ||
227 | MODULE_LICENSE("GPL v2"); | ||