aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2011-03-14 04:52:33 -0400
committerChris Ball <cjb@laptop.org>2011-03-25 10:39:23 -0400
commit42051e8a7bce76ebd3cd201704ee2427120636e1 (patch)
treef62527fca5ea9d247faffa9bda2539d996b18068
parent4fbc5ece430bc2890edc90a112c742844130f943 (diff)
mmc: tmio: convert the SDHI MMC driver from MFD to a platform driver
On sh-mobile platforms the SDHI driver was using the tmio_mmc SD/SDIO MFD cell driver. Now that the tmio_mmc driver has been split into a core and a separate MFD glue, we can support SDHI natively without the need to emulate an MFD controller. This also allows to support systems with an on-SoC SDHI controller and a separate MFD with a TMIO core. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mfd/Kconfig14
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mmc/host/Kconfig9
-rw-r--r--drivers/mmc/host/Makefile7
-rw-r--r--drivers/mmc/host/sh_mobile_sdhi.c (renamed from drivers/mfd/sh_mobile_sdhi.c)95
-rw-r--r--drivers/mmc/host/tmio_mmc.h2
-rw-r--r--include/linux/mfd/sh_mobile_sdhi.h19
-rw-r--r--include/linux/mmc/sh_mobile_sdhi.h16
8 files changed, 68 insertions, 95 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index a9a1af49281e..38cb1d4d6843 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -60,15 +60,6 @@ config MFD_ASIC3
60 This driver supports the ASIC3 multifunction chip found on many 60 This driver supports the ASIC3 multifunction chip found on many
61 PDAs (mainly iPAQ and HTC based ones) 61 PDAs (mainly iPAQ and HTC based ones)
62 62
63config MFD_SH_MOBILE_SDHI
64 bool "Support for SuperH Mobile SDHI"
65 depends on SUPERH || ARCH_SHMOBILE
66 select MFD_CORE
67 select TMIO_MMC_DMA
68 ---help---
69 This driver supports the SDHI hardware block found in many
70 SuperH Mobile SoCs.
71
72config MFD_DAVINCI_VOICECODEC 63config MFD_DAVINCI_VOICECODEC
73 tristate 64 tristate
74 select MFD_CORE 65 select MFD_CORE
@@ -265,11 +256,6 @@ config MFD_TMIO
265 bool 256 bool
266 default n 257 default n
267 258
268config TMIO_MMC_DMA
269 bool
270 select DMA_ENGINE
271 select DMADEVICES
272
273config MFD_T7L66XB 259config MFD_T7L66XB
274 bool "Support Toshiba T7L66XB" 260 bool "Support Toshiba T7L66XB"
275 depends on ARM && HAVE_CLK 261 depends on ARM && HAVE_CLK
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 47f5709f3828..ad6c44321873 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -6,7 +6,6 @@
6obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o 6obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o
7obj-$(CONFIG_MFD_SM501) += sm501.o 7obj-$(CONFIG_MFD_SM501) += sm501.o
8obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o 8obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
9obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o
10 9
11obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o 10obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
12obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o 11obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 4d16166386ca..0b03cee91451 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -444,12 +444,19 @@ config MMC_TMIO_CORE
444 444
445config MMC_TMIO 445config MMC_TMIO
446 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" 446 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
447 depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI 447 depends on MFD_TMIO || MFD_ASIC3
448 select MMC_TMIO_CORE 448 select MMC_TMIO_CORE
449 help 449 help
450 This provides support for the SD/MMC cell found in TC6393XB, 450 This provides support for the SD/MMC cell found in TC6393XB,
451 T7L66XB and also HTC ASIC3 451 T7L66XB and also HTC ASIC3
452 452
453config MMC_SDHI
454 tristate "SH-Mobile SDHI SD/SDIO controller support"
455 select MMC_TMIO_CORE
456 help
457 This provides support for the SDHI SD/SDIO controller found in
458 SuperH and ARM SH-Mobile SoCs
459
453config MMC_CB710 460config MMC_CB710
454 tristate "ENE CB710 MMC/SD Interface support" 461 tristate "ENE CB710 MMC/SD Interface support"
455 depends on PCI 462 depends on PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 79c42dd23c0e..4f1df0aae574 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -31,8 +31,11 @@ obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o
31obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o 31obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o
32obj-$(CONFIG_MMC_TMIO_CORE) += tmio_mmc_core.o 32obj-$(CONFIG_MMC_TMIO_CORE) += tmio_mmc_core.o
33tmio_mmc_core-y := tmio_mmc_pio.o 33tmio_mmc_core-y := tmio_mmc_pio.o
34tmio_mmc_core-$(CONFIG_TMIO_MMC_DMA) += tmio_mmc_dma.o 34ifneq ($(CONFIG_MMC_SDHI),n)
35obj-$(CONFIG_MMC_CB710) += cb710-mmc.o 35tmio_mmc_core-y += tmio_mmc_dma.o
36endif
37obj-$(CONFIG_MMC_SDHI) += sh_mobile_sdhi.o
38obj-$(CONFIG_MMC_CB710) += cb710-mmc.o
36obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o 39obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o
37obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o 40obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o
38obj-$(CONFIG_MMC_DW) += dw_mmc.o 41obj-$(CONFIG_MMC_DW) += dw_mmc.o
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 53a63024bf11..cc701236d16f 100644
--- a/drivers/mfd/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -23,51 +23,30 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/mmc/host.h> 25#include <linux/mmc/host.h>
26#include <linux/mfd/core.h> 26#include <linux/mmc/sh_mobile_sdhi.h>
27#include <linux/mfd/tmio.h> 27#include <linux/mfd/tmio.h>
28#include <linux/mfd/sh_mobile_sdhi.h>
29#include <linux/sh_dma.h> 28#include <linux/sh_dma.h>
30 29
30#include "tmio_mmc.h"
31
31struct sh_mobile_sdhi { 32struct sh_mobile_sdhi {
32 struct clk *clk; 33 struct clk *clk;
33 struct tmio_mmc_data mmc_data; 34 struct tmio_mmc_data mmc_data;
34 struct mfd_cell cell_mmc;
35 struct sh_dmae_slave param_tx; 35 struct sh_dmae_slave param_tx;
36 struct sh_dmae_slave param_rx; 36 struct sh_dmae_slave param_rx;
37 struct tmio_mmc_dma dma_priv; 37 struct tmio_mmc_dma dma_priv;
38}; 38};
39 39
40static struct resource sh_mobile_sdhi_resources[] = { 40static void sh_mobile_sdhi_set_pwr(struct platform_device *pdev, int state)
41 {
42 .start = 0x000,
43 .end = 0x1ff,
44 .flags = IORESOURCE_MEM,
45 },
46 {
47 .start = 0,
48 .end = 0,
49 .flags = IORESOURCE_IRQ,
50 },
51};
52
53static struct mfd_cell sh_mobile_sdhi_cell = {
54 .name = "tmio-mmc",
55 .num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources),
56 .resources = sh_mobile_sdhi_resources,
57};
58
59static void sh_mobile_sdhi_set_pwr(struct platform_device *tmio, int state)
60{ 41{
61 struct platform_device *pdev = to_platform_device(tmio->dev.parent);
62 struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; 42 struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
63 43
64 if (p && p->set_pwr) 44 if (p && p->set_pwr)
65 p->set_pwr(pdev, state); 45 p->set_pwr(pdev, state);
66} 46}
67 47
68static int sh_mobile_sdhi_get_cd(struct platform_device *tmio) 48static int sh_mobile_sdhi_get_cd(struct platform_device *pdev)
69{ 49{
70 struct platform_device *pdev = to_platform_device(tmio->dev.parent);
71 struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; 50 struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
72 51
73 if (p && p->get_cd) 52 if (p && p->get_cd)
@@ -81,20 +60,9 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
81 struct sh_mobile_sdhi *priv; 60 struct sh_mobile_sdhi *priv;
82 struct tmio_mmc_data *mmc_data; 61 struct tmio_mmc_data *mmc_data;
83 struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; 62 struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
84 struct resource *mem; 63 struct tmio_mmc_host *host;
85 char clk_name[8]; 64 char clk_name[8];
86 int ret, irq; 65 int ret;
87
88 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
89 if (!mem)
90 dev_err(&pdev->dev, "missing MEM resource\n");
91
92 irq = platform_get_irq(pdev, 0);
93 if (irq < 0)
94 dev_err(&pdev->dev, "missing IRQ resource\n");
95
96 if (!mem || (irq < 0))
97 return -EINVAL;
98 66
99 priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL); 67 priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
100 if (priv == NULL) { 68 if (priv == NULL) {
@@ -109,8 +77,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
109 if (IS_ERR(priv->clk)) { 77 if (IS_ERR(priv->clk)) {
110 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); 78 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
111 ret = PTR_ERR(priv->clk); 79 ret = PTR_ERR(priv->clk);
112 kfree(priv); 80 goto eclkget;
113 return ret;
114 } 81 }
115 82
116 clk_enable(priv->clk); 83 clk_enable(priv->clk);
@@ -123,6 +90,15 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
123 mmc_data->flags = p->tmio_flags; 90 mmc_data->flags = p->tmio_flags;
124 mmc_data->ocr_mask = p->tmio_ocr_mask; 91 mmc_data->ocr_mask = p->tmio_ocr_mask;
125 mmc_data->capabilities |= p->tmio_caps; 92 mmc_data->capabilities |= p->tmio_caps;
93
94 if (p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) {
95 priv->param_tx.slave_id = p->dma_slave_tx;
96 priv->param_rx.slave_id = p->dma_slave_rx;
97 priv->dma_priv.chan_priv_tx = &priv->param_tx;
98 priv->dma_priv.chan_priv_rx = &priv->param_rx;
99 priv->dma_priv.alignment_shift = 1; /* 2-byte alignment */
100 mmc_data->dma = &priv->dma_priv;
101 }
126 } 102 }
127 103
128 /* 104 /*
@@ -136,36 +112,30 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
136 */ 112 */
137 mmc_data->flags |= TMIO_MMC_SDIO_IRQ; 113 mmc_data->flags |= TMIO_MMC_SDIO_IRQ;
138 114
139 if (p && p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) { 115 ret = tmio_mmc_host_probe(&host, pdev, mmc_data);
140 priv->param_tx.slave_id = p->dma_slave_tx; 116 if (ret < 0)
141 priv->param_rx.slave_id = p->dma_slave_rx; 117 goto eprobe;
142 priv->dma_priv.chan_priv_tx = &priv->param_tx;
143 priv->dma_priv.chan_priv_rx = &priv->param_rx;
144 priv->dma_priv.alignment_shift = 1; /* 2-byte alignment */
145 mmc_data->dma = &priv->dma_priv;
146 }
147 118
148 memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc)); 119 pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
149 priv->cell_mmc.mfd_data = mmc_data; 120 (unsigned long)host->ctl, host->irq);
150 121
151 platform_set_drvdata(pdev, priv); 122 return ret;
152
153 ret = mfd_add_devices(&pdev->dev, pdev->id,
154 &priv->cell_mmc, 1, mem, irq);
155 if (ret) {
156 clk_disable(priv->clk);
157 clk_put(priv->clk);
158 kfree(priv);
159 }
160 123
124eprobe:
125 clk_disable(priv->clk);
126 clk_put(priv->clk);
127eclkget:
128 kfree(priv);
161 return ret; 129 return ret;
162} 130}
163 131
164static int sh_mobile_sdhi_remove(struct platform_device *pdev) 132static int sh_mobile_sdhi_remove(struct platform_device *pdev)
165{ 133{
166 struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev); 134 struct mmc_host *mmc = platform_get_drvdata(pdev);
135 struct tmio_mmc_host *host = mmc_priv(mmc);
136 struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
167 137
168 mfd_remove_devices(&pdev->dev); 138 tmio_mmc_host_remove(host);
169 clk_disable(priv->clk); 139 clk_disable(priv->clk);
170 clk_put(priv->clk); 140 clk_put(priv->clk);
171 kfree(priv); 141 kfree(priv);
@@ -198,3 +168,4 @@ module_exit(sh_mobile_sdhi_exit);
198MODULE_DESCRIPTION("SuperH Mobile SDHI driver"); 168MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
199MODULE_AUTHOR("Magnus Damm"); 169MODULE_AUTHOR("Magnus Damm");
200MODULE_LICENSE("GPL v2"); 170MODULE_LICENSE("GPL v2");
171MODULE_ALIAS("platform:sh_mobile_sdhi");
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 8dedf0a69348..7d79b14d56aa 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -120,7 +120,7 @@ static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg,
120 local_irq_restore(*flags); 120 local_irq_restore(*flags);
121} 121}
122 122
123#ifdef CONFIG_TMIO_MMC_DMA 123#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
124void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data); 124void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data);
125void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata); 125void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata);
126void tmio_mmc_release_dma(struct tmio_mmc_host *host); 126void tmio_mmc_release_dma(struct tmio_mmc_host *host);
diff --git a/include/linux/mfd/sh_mobile_sdhi.h b/include/linux/mfd/sh_mobile_sdhi.h
index c981b959760f..10af7f901ebe 100644
--- a/include/linux/mfd/sh_mobile_sdhi.h
+++ b/include/linux/mfd/sh_mobile_sdhi.h
@@ -1,16 +1,7 @@
1#ifndef __SH_MOBILE_SDHI_H__ 1#ifndef MFD_SH_MOBILE_SDHI_H
2#define __SH_MOBILE_SDHI_H__ 2#define MFD_SH_MOBILE_SDHI_H
3 3
4#include <linux/types.h> 4/* Compatibility header - will disappear once all platforms are converted */
5#include <linux/mmc/sh_mobile_sdhi.h>
5 6
6struct sh_mobile_sdhi_info { 7#endif /* MFD_SH_MOBILE_SDHI_H */
7 int dma_slave_tx;
8 int dma_slave_rx;
9 unsigned long tmio_flags;
10 unsigned long tmio_caps;
11 u32 tmio_ocr_mask; /* available MMC voltages */
12 void (*set_pwr)(struct platform_device *pdev, int state);
13 int (*get_cd)(struct platform_device *pdev);
14};
15
16#endif /* __SH_MOBILE_SDHI_H__ */
diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
new file mode 100644
index 000000000000..c981b959760f
--- /dev/null
+++ b/include/linux/mmc/sh_mobile_sdhi.h
@@ -0,0 +1,16 @@
1#ifndef __SH_MOBILE_SDHI_H__
2#define __SH_MOBILE_SDHI_H__
3
4#include <linux/types.h>
5
6struct sh_mobile_sdhi_info {
7 int dma_slave_tx;
8 int dma_slave_rx;
9 unsigned long tmio_flags;
10 unsigned long tmio_caps;
11 u32 tmio_ocr_mask; /* available MMC voltages */
12 void (*set_pwr)(struct platform_device *pdev, int state);
13 int (*get_cd)(struct platform_device *pdev);
14};
15
16#endif /* __SH_MOBILE_SDHI_H__ */