aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-14 16:46:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-14 16:46:57 -0400
commit2625b10d8c37656cf410a464ed95942b3abbd1f6 (patch)
treef02fc44aaed07dceed2566b3fdf4dc64b786cb89
parent489f7ab6c18cdd64a2d444e056d60a0e722f4ad7 (diff)
parent7f72134c32eb64c77d1fb35123ba8bf815bf797c (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc: (25 commits) atmel-mci: add MCI2 register definitions atmel-mci: Integrate AT91 specific definition in header file tmio_mmc: allow compilation for ASIC3 mmc_block: do not DMA to stack sdhci: Print ADMA status and pointer on debug tmio_mmc: fix clock setup tmio_mmc: map SD control registers after enabling the MFD cell tmio_mmc: correct probe return value for num_resources != 3 tmio_mmc: don't use set_irq_type tmio_mmc: add bus_shift support MFD,mmc: tmio_mmc: make HCLK configurable mmc_spi: don't use EINVAL for possible transmission errors cb710: more cleanup for the DEBUG case. sdhci: platform driver for SDHCI mxcmmc: remove frequency workaround cb710: handle DEBUG define in Makefile cb710: add missing parenthesis cb710: fix printk format string mmc: Driver for CB710/720 memory card reader (MMC part) pxamci: add regulator support. ...
-rw-r--r--MAINTAINERS9
-rw-r--r--drivers/mfd/t7l66xb.c5
-rw-r--r--drivers/mfd/tc6387xb.c5
-rw-r--r--drivers/mfd/tc6393xb.c5
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/cb710/Kconfig25
-rw-r--r--drivers/misc/cb710/Makefile8
-rw-r--r--drivers/misc/cb710/core.c357
-rw-r--r--drivers/misc/cb710/debug.c119
-rw-r--r--drivers/misc/cb710/sgbuf2.c150
-rw-r--r--drivers/mmc/card/block.c16
-rw-r--r--drivers/mmc/core/core.c107
-rw-r--r--drivers/mmc/host/Kconfig28
-rw-r--r--drivers/mmc/host/Makefile5
-rw-r--r--drivers/mmc/host/atmel-mci-regs.h33
-rw-r--r--drivers/mmc/host/cb710-mmc.c804
-rw-r--r--drivers/mmc/host/cb710-mmc.h104
-rw-r--r--drivers/mmc/host/mmc_spi.c23
-rw-r--r--drivers/mmc/host/mxcmmc.c2
-rw-r--r--drivers/mmc/host/omap.c3
-rw-r--r--drivers/mmc/host/pxamci.c46
-rw-r--r--drivers/mmc/host/sdhci-pltfm.c168
-rw-r--r--drivers/mmc/host/sdhci.c58
-rw-r--r--drivers/mmc/host/sdhci.h2
-rw-r--r--drivers/mmc/host/tmio_mmc.c180
-rw-r--r--drivers/mmc/host/tmio_mmc.h77
-rw-r--r--include/linux/cb710.h231
-rw-r--r--include/linux/mfd/tmio.h7
-rw-r--r--include/linux/pci_ids.h1
30 files changed, 2377 insertions, 203 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 9e28c5c16602..a1fe87ad4832 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2112,6 +2112,15 @@ W: http://sourceforge.net/projects/lpfcxxxx
2112S: Supported 2112S: Supported
2113F: drivers/scsi/lpfc/ 2113F: drivers/scsi/lpfc/
2114 2114
2115ENE CB710 FLASH CARD READER DRIVER
2116P: Michał Mirosław
2117M: mirq-linux@rere.qmqm.pl
2118L: linux-kernel@vger.kernel.org
2119S: Maintained
2120F: drivers/misc/cb710/
2121F: drivers/mmc/host/cb710-mmc.*
2122F: include/linux/cb710.h
2123
2115EPSON 1355 FRAMEBUFFER DRIVER 2124EPSON 1355 FRAMEBUFFER DRIVER
2116P: Christopher Hoover 2125P: Christopher Hoover
2117M: ch@murgatroid.com 2126M: ch@murgatroid.com
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index e9f4323dd2cb..875f7a875734 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -108,6 +108,10 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc)
108 108
109/*--------------------------------------------------------------------------*/ 109/*--------------------------------------------------------------------------*/
110 110
111static const struct tmio_mmc_data t7166xb_mmc_data = {
112 .hclk = 24000000,
113};
114
111static const struct resource t7l66xb_mmc_resources[] = { 115static const struct resource t7l66xb_mmc_resources[] = {
112 { 116 {
113 .start = 0x800, 117 .start = 0x800,
@@ -149,6 +153,7 @@ static struct mfd_cell t7l66xb_cells[] = {
149 .name = "tmio-mmc", 153 .name = "tmio-mmc",
150 .enable = t7l66xb_mmc_enable, 154 .enable = t7l66xb_mmc_enable,
151 .disable = t7l66xb_mmc_disable, 155 .disable = t7l66xb_mmc_disable,
156 .driver_data = &t7166xb_mmc_data,
152 .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources), 157 .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources),
153 .resources = t7l66xb_mmc_resources, 158 .resources = t7l66xb_mmc_resources,
154 }, 159 },
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index 43222c12fec1..c3993ac20542 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -75,6 +75,10 @@ static int tc6387xb_mmc_disable(struct platform_device *mmc)
75 75
76/*--------------------------------------------------------------------------*/ 76/*--------------------------------------------------------------------------*/
77 77
78const static struct tmio_mmc_data tc6387xb_mmc_data = {
79 .hclk = 24000000,
80};
81
78static struct resource tc6387xb_mmc_resources[] = { 82static struct resource tc6387xb_mmc_resources[] = {
79 { 83 {
80 .start = 0x800, 84 .start = 0x800,
@@ -98,6 +102,7 @@ static struct mfd_cell tc6387xb_cells[] = {
98 .name = "tmio-mmc", 102 .name = "tmio-mmc",
99 .enable = tc6387xb_mmc_enable, 103 .enable = tc6387xb_mmc_enable,
100 .disable = tc6387xb_mmc_disable, 104 .disable = tc6387xb_mmc_disable,
105 .driver_data = &tc6387xb_mmc_data,
101 .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources), 106 .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources),
102 .resources = tc6387xb_mmc_resources, 107 .resources = tc6387xb_mmc_resources,
103 }, 108 },
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index 77a12fc8045e..9d2abb5d6e2c 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -136,6 +136,10 @@ static int tc6393xb_nand_enable(struct platform_device *nand)
136 return 0; 136 return 0;
137} 137}
138 138
139const static struct tmio_mmc_data tc6393xb_mmc_data = {
140 .hclk = 24000000,
141};
142
139static struct resource __devinitdata tc6393xb_nand_resources[] = { 143static struct resource __devinitdata tc6393xb_nand_resources[] = {
140 { 144 {
141 .start = 0x1000, 145 .start = 0x1000,
@@ -351,6 +355,7 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = {
351 }, 355 },
352 [TC6393XB_CELL_MMC] = { 356 [TC6393XB_CELL_MMC] = {
353 .name = "tmio-mmc", 357 .name = "tmio-mmc",
358 .driver_data = &tc6393xb_mmc_data,
354 .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), 359 .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
355 .resources = tc6393xb_mmc_resources, 360 .resources = tc6393xb_mmc_resources,
356 }, 361 },
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 6d1ac180f6ee..68ab39d7cb35 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -235,5 +235,6 @@ config ISL29003
235 235
236source "drivers/misc/c2port/Kconfig" 236source "drivers/misc/c2port/Kconfig"
237source "drivers/misc/eeprom/Kconfig" 237source "drivers/misc/eeprom/Kconfig"
238source "drivers/misc/cb710/Kconfig"
238 239
239endif # MISC_DEVICES 240endif # MISC_DEVICES
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 7871f05dcb9b..36f733cd60e6 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_HP_ILO) += hpilo.o
21obj-$(CONFIG_ISL29003) += isl29003.o 21obj-$(CONFIG_ISL29003) += isl29003.o
22obj-$(CONFIG_C2PORT) += c2port/ 22obj-$(CONFIG_C2PORT) += c2port/
23obj-y += eeprom/ 23obj-y += eeprom/
24obj-y += cb710/
diff --git a/drivers/misc/cb710/Kconfig b/drivers/misc/cb710/Kconfig
new file mode 100644
index 000000000000..22429b8b1068
--- /dev/null
+++ b/drivers/misc/cb710/Kconfig
@@ -0,0 +1,25 @@
1config CB710_CORE
2 tristate "ENE CB710/720 Flash memory card reader support"
3 depends on PCI
4 help
5 This option enables support for PCI ENE CB710/720 Flash memory card
6 reader found in some laptops (ie. some versions of HP Compaq nx9500).
7
8 You will also have to select some flash card format drivers (MMC/SD,
9 MemoryStick).
10
11 This driver can also be built as a module. If so, the module
12 will be called cb710.
13
14config CB710_DEBUG
15 bool "Enable driver debugging"
16 depends on CB710_CORE != n
17 default n
18 help
19 This is an option for use by developers; most people should
20 say N here. This adds a lot of debugging output to dmesg.
21
22config CB710_DEBUG_ASSUMPTIONS
23 bool
24 depends on CB710_CORE != n
25 default y
diff --git a/drivers/misc/cb710/Makefile b/drivers/misc/cb710/Makefile
new file mode 100644
index 000000000000..7b80cbf1a609
--- /dev/null
+++ b/drivers/misc/cb710/Makefile
@@ -0,0 +1,8 @@
1ifeq ($(CONFIG_CB710_DEBUG),y)
2 EXTRA_CFLAGS += -DDEBUG
3endif
4
5obj-$(CONFIG_CB710_CORE) += cb710.o
6
7cb710-y := core.o sgbuf2.o
8cb710-$(CONFIG_CB710_DEBUG) += debug.o
diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c
new file mode 100644
index 000000000000..b14eab0f2ba5
--- /dev/null
+++ b/drivers/misc/cb710/core.c
@@ -0,0 +1,357 @@
1/*
2 * cb710/core.c
3 *
4 * Copyright by Michał Mirosław, 2008-2009
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/pci.h>
14#include <linux/spinlock.h>
15#include <linux/idr.h>
16#include <linux/cb710.h>
17
18static DEFINE_IDA(cb710_ida);
19static DEFINE_SPINLOCK(cb710_ida_lock);
20
21void cb710_pci_update_config_reg(struct pci_dev *pdev,
22 int reg, uint32_t mask, uint32_t xor)
23{
24 u32 rval;
25
26 pci_read_config_dword(pdev, reg, &rval);
27 rval = (rval & mask) ^ xor;
28 pci_write_config_dword(pdev, reg, rval);
29}
30EXPORT_SYMBOL_GPL(cb710_pci_update_config_reg);
31
32/* Some magic writes based on Windows driver init code */
33static int __devinit cb710_pci_configure(struct pci_dev *pdev)
34{
35 unsigned int devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
36 struct pci_dev *pdev0 = pci_get_slot(pdev->bus, devfn);
37 u32 val;
38
39 cb710_pci_update_config_reg(pdev, 0x48,
40 ~0x000000FF, 0x0000003F);
41
42 pci_read_config_dword(pdev, 0x48, &val);
43 if (val & 0x80000000)
44 return 0;
45
46 if (!pdev0)
47 return -ENODEV;
48
49 if (pdev0->vendor == PCI_VENDOR_ID_ENE
50 && pdev0->device == PCI_DEVICE_ID_ENE_720) {
51 cb710_pci_update_config_reg(pdev0, 0x8C,
52 ~0x00F00000, 0x00100000);
53 cb710_pci_update_config_reg(pdev0, 0xB0,
54 ~0x08000000, 0x08000000);
55 }
56
57 cb710_pci_update_config_reg(pdev0, 0x8C,
58 ~0x00000F00, 0x00000200);
59 cb710_pci_update_config_reg(pdev0, 0x90,
60 ~0x00060000, 0x00040000);
61
62 pci_dev_put(pdev0);
63
64 return 0;
65}
66
67static irqreturn_t cb710_irq_handler(int irq, void *data)
68{
69 struct cb710_chip *chip = data;
70 struct cb710_slot *slot = &chip->slot[0];
71 irqreturn_t handled = IRQ_NONE;
72 unsigned nr;
73
74 spin_lock(&chip->irq_lock); /* incl. smp_rmb() */
75
76 for (nr = chip->slots; nr; ++slot, --nr) {
77 cb710_irq_handler_t handler_func = slot->irq_handler;
78 if (handler_func && handler_func(slot))
79 handled = IRQ_HANDLED;
80 }
81
82 spin_unlock(&chip->irq_lock);
83
84 return handled;
85}
86
87static void cb710_release_slot(struct device *dev)
88{
89#ifdef CONFIG_CB710_DEBUG_ASSUMPTIONS
90 struct cb710_slot *slot = cb710_pdev_to_slot(to_platform_device(dev));
91 struct cb710_chip *chip = cb710_slot_to_chip(slot);
92
93 /* slot struct can be freed now */
94 atomic_dec(&chip->slot_refs_count);
95#endif
96}
97
98static int __devinit cb710_register_slot(struct cb710_chip *chip,
99 unsigned slot_mask, unsigned io_offset, const char *name)
100{
101 int nr = chip->slots;
102 struct cb710_slot *slot = &chip->slot[nr];
103 int err;
104
105 dev_dbg(cb710_chip_dev(chip),
106 "register: %s.%d; slot %d; mask %d; IO offset: 0x%02X\n",
107 name, chip->platform_id, nr, slot_mask, io_offset);
108
109 /* slot->irq_handler == NULL here; this needs to be
110 * seen before platform_device_register() */
111 ++chip->slots;
112 smp_wmb();
113
114 slot->iobase = chip->iobase + io_offset;
115 slot->pdev.name = name;
116 slot->pdev.id = chip->platform_id;
117 slot->pdev.dev.parent = &chip->pdev->dev;
118 slot->pdev.dev.release = cb710_release_slot;
119
120 err = platform_device_register(&slot->pdev);
121
122#ifdef CONFIG_CB710_DEBUG_ASSUMPTIONS
123 atomic_inc(&chip->slot_refs_count);
124#endif
125
126 if (err) {
127 /* device_initialize() called from platform_device_register()
128 * wants this on error path */
129 platform_device_put(&slot->pdev);
130
131 /* slot->irq_handler == NULL here anyway, so no lock needed */
132 --chip->slots;
133 return err;
134 }
135
136 chip->slot_mask |= slot_mask;
137
138 return 0;
139}
140
141static void cb710_unregister_slot(struct cb710_chip *chip,
142 unsigned slot_mask)
143{
144 int nr = chip->slots - 1;
145
146 if (!(chip->slot_mask & slot_mask))
147 return;
148
149 platform_device_unregister(&chip->slot[nr].pdev);
150
151 /* complementary to spin_unlock() in cb710_set_irq_handler() */
152 smp_rmb();
153 BUG_ON(chip->slot[nr].irq_handler != NULL);
154
155 /* slot->irq_handler == NULL here, so no lock needed */
156 --chip->slots;
157 chip->slot_mask &= ~slot_mask;
158}
159
160void cb710_set_irq_handler(struct cb710_slot *slot,
161 cb710_irq_handler_t handler)
162{
163 struct cb710_chip *chip = cb710_slot_to_chip(slot);
164 unsigned long flags;
165
166 spin_lock_irqsave(&chip->irq_lock, flags);
167 slot->irq_handler = handler;
168 spin_unlock_irqrestore(&chip->irq_lock, flags);
169}
170EXPORT_SYMBOL_GPL(cb710_set_irq_handler);
171
172#ifdef CONFIG_PM
173
174static int cb710_suspend(struct pci_dev *pdev, pm_message_t state)
175{
176 struct cb710_chip *chip = pci_get_drvdata(pdev);
177
178 free_irq(pdev->irq, chip);
179 pci_save_state(pdev);
180 pci_disable_device(pdev);
181 if (state.event & PM_EVENT_SLEEP)
182 pci_set_power_state(pdev, PCI_D3cold);
183 return 0;
184}
185
186static int cb710_resume(struct pci_dev *pdev)
187{
188 struct cb710_chip *chip = pci_get_drvdata(pdev);
189 int err;
190
191 pci_set_power_state(pdev, PCI_D0);
192 pci_restore_state(pdev);
193 err = pcim_enable_device(pdev);
194 if (err)
195 return err;
196
197 return devm_request_irq(&pdev->dev, pdev->irq,
198 cb710_irq_handler, IRQF_SHARED, KBUILD_MODNAME, chip);
199}
200
201#endif /* CONFIG_PM */
202
203static int __devinit cb710_probe(struct pci_dev *pdev,
204 const struct pci_device_id *ent)
205{
206 struct cb710_chip *chip;
207 unsigned long flags;
208 u32 val;
209 int err;
210 int n = 0;
211
212 err = cb710_pci_configure(pdev);
213 if (err)
214 return err;
215
216 /* this is actually magic... */
217 pci_read_config_dword(pdev, 0x48, &val);
218 if (!(val & 0x80000000)) {
219 pci_write_config_dword(pdev, 0x48, val|0x71000000);
220 pci_read_config_dword(pdev, 0x48, &val);
221 }
222
223 dev_dbg(&pdev->dev, "PCI config[0x48] = 0x%08X\n", val);
224 if (!(val & 0x70000000))
225 return -ENODEV;
226 val = (val >> 28) & 7;
227 if (val & CB710_SLOT_MMC)
228 ++n;
229 if (val & CB710_SLOT_MS)
230 ++n;
231 if (val & CB710_SLOT_SM)
232 ++n;
233
234 chip = devm_kzalloc(&pdev->dev,
235 sizeof(*chip) + n * sizeof(*chip->slot), GFP_KERNEL);
236 if (!chip)
237 return -ENOMEM;
238
239 err = pcim_enable_device(pdev);
240 if (err)
241 return err;
242
243 err = pcim_iomap_regions(pdev, 0x0001, KBUILD_MODNAME);
244 if (err)
245 return err;
246
247 chip->pdev = pdev;
248 chip->iobase = pcim_iomap_table(pdev)[0];
249
250 pci_set_drvdata(pdev, chip);
251
252 err = devm_request_irq(&pdev->dev, pdev->irq,
253 cb710_irq_handler, IRQF_SHARED, KBUILD_MODNAME, chip);
254 if (err)
255 return err;
256
257 do {
258 if (!ida_pre_get(&cb710_ida, GFP_KERNEL))
259 return -ENOMEM;
260
261 spin_lock_irqsave(&cb710_ida_lock, flags);
262 err = ida_get_new(&cb710_ida, &chip->platform_id);
263 spin_unlock_irqrestore(&cb710_ida_lock, flags);
264
265 if (err && err != -EAGAIN)
266 return err;
267 } while (err);
268
269
270 dev_info(&pdev->dev, "id %d, IO 0x%p, IRQ %d\n",
271 chip->platform_id, chip->iobase, pdev->irq);
272
273 if (val & CB710_SLOT_MMC) { /* MMC/SD slot */
274 err = cb710_register_slot(chip,
275 CB710_SLOT_MMC, 0x00, "cb710-mmc");
276 if (err)
277 return err;
278 }
279
280 if (val & CB710_SLOT_MS) { /* MemoryStick slot */
281 err = cb710_register_slot(chip,
282 CB710_SLOT_MS, 0x40, "cb710-ms");
283 if (err)
284 goto unreg_mmc;
285 }
286
287 if (val & CB710_SLOT_SM) { /* SmartMedia slot */
288 err = cb710_register_slot(chip,
289 CB710_SLOT_SM, 0x60, "cb710-sm");
290 if (err)
291 goto unreg_ms;
292 }
293
294 return 0;
295unreg_ms:
296 cb710_unregister_slot(chip, CB710_SLOT_MS);
297unreg_mmc:
298 cb710_unregister_slot(chip, CB710_SLOT_MMC);
299
300#ifdef CONFIG_CB710_DEBUG_ASSUMPTIONS
301 BUG_ON(atomic_read(&chip->slot_refs_count) != 0);
302#endif
303 return err;
304}
305
306static void __devexit cb710_remove_one(struct pci_dev *pdev)
307{
308 struct cb710_chip *chip = pci_get_drvdata(pdev);
309 unsigned long flags;
310
311 cb710_unregister_slot(chip, CB710_SLOT_SM);
312 cb710_unregister_slot(chip, CB710_SLOT_MS);
313 cb710_unregister_slot(chip, CB710_SLOT_MMC);
314#ifdef CONFIG_CB710_DEBUG_ASSUMPTIONS
315 BUG_ON(atomic_read(&chip->slot_refs_count) != 0);
316#endif
317
318 spin_lock_irqsave(&cb710_ida_lock, flags);
319 ida_remove(&cb710_ida, chip->platform_id);
320 spin_unlock_irqrestore(&cb710_ida_lock, flags);
321}
322
323static const struct pci_device_id cb710_pci_tbl[] = {
324 { PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_CB710_FLASH,
325 PCI_ANY_ID, PCI_ANY_ID, },
326 { 0, }
327};
328
329static struct pci_driver cb710_driver = {
330 .name = KBUILD_MODNAME,
331 .id_table = cb710_pci_tbl,
332 .probe = cb710_probe,
333 .remove = __devexit_p(cb710_remove_one),
334#ifdef CONFIG_PM
335 .suspend = cb710_suspend,
336 .resume = cb710_resume,
337#endif
338};
339
340static int __init cb710_init_module(void)
341{
342 return pci_register_driver(&cb710_driver);
343}
344
345static void __exit cb710_cleanup_module(void)
346{
347 pci_unregister_driver(&cb710_driver);
348 ida_destroy(&cb710_ida);
349}
350
351module_init(cb710_init_module);
352module_exit(cb710_cleanup_module);
353
354MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>");
355MODULE_DESCRIPTION("ENE CB710 memory card reader driver");
356MODULE_LICENSE("GPL");
357MODULE_DEVICE_TABLE(pci, cb710_pci_tbl);
diff --git a/drivers/misc/cb710/debug.c b/drivers/misc/cb710/debug.c
new file mode 100644
index 000000000000..02358d086e03
--- /dev/null
+++ b/drivers/misc/cb710/debug.c
@@ -0,0 +1,119 @@
1/*
2 * cb710/debug.c
3 *
4 * Copyright by Michał Mirosław, 2008-2009
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/cb710.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/slab.h>
14
15#define CB710_REG_COUNT 0x80
16
17static const u16 allow[CB710_REG_COUNT/16] = {
18 0xFFF0, 0xFFFF, 0xFFFF, 0xFFFF,
19 0xFFF0, 0xFFFF, 0xFFFF, 0xFFFF,
20};
21static const char *const prefix[ARRAY_SIZE(allow)] = {
22 "MMC", "MMC", "MMC", "MMC",
23 "MS?", "MS?", "SM?", "SM?"
24};
25
26static inline int allow_reg_read(unsigned block, unsigned offset, unsigned bits)
27{
28 unsigned mask = (1 << bits/8) - 1;
29 offset *= bits/8;
30 return ((allow[block] >> offset) & mask) == mask;
31}
32
33#define CB710_READ_REGS_TEMPLATE(t) \
34static void cb710_read_regs_##t(void __iomem *iobase, \
35 u##t *reg, unsigned select) \
36{ \
37 unsigned i, j; \
38 \
39 for (i = 0; i < ARRAY_SIZE(allow); ++i, reg += 16/(t/8)) { \
40 if (!(select & (1 << i))) \
41 continue; \
42 \
43 for (j = 0; j < 0x10/(t/8); ++j) { \
44 if (!allow_reg_read(i, j, t)) \
45 continue; \
46 reg[j] = ioread##t(iobase \
47 + (i << 4) + (j * (t/8))); \
48 } \
49 } \
50}
51
52static const char cb710_regf_8[] = "%02X";
53static const char cb710_regf_16[] = "%04X";
54static const char cb710_regf_32[] = "%08X";
55static const char cb710_xes[] = "xxxxxxxx";
56
57#define CB710_DUMP_REGS_TEMPLATE(t) \
58static void cb710_dump_regs_##t(struct device *dev, \
59 const u##t *reg, unsigned select) \
60{ \
61 const char *const xp = &cb710_xes[8 - t/4]; \
62 const char *const format = cb710_regf_##t; \
63 \
64 char msg[100], *p; \
65 unsigned i, j; \
66 \
67 for (i = 0; i < ARRAY_SIZE(allow); ++i, reg += 16/(t/8)) { \
68 if (!(select & (1 << i))) \
69 continue; \
70 p = msg; \
71 for (j = 0; j < 0x10/(t/8); ++j) { \
72 *p++ = ' '; \
73 if (j == 8/(t/8)) \
74 *p++ = ' '; \
75 if (allow_reg_read(i, j, t)) \
76 p += sprintf(p, format, reg[j]); \
77 else \
78 p += sprintf(p, "%s", xp); \
79 } \
80 dev_dbg(dev, "%s 0x%02X %s\n", prefix[i], i << 4, msg); \
81 } \
82}
83
84#define CB710_READ_AND_DUMP_REGS_TEMPLATE(t) \
85static void cb710_read_and_dump_regs_##t(struct cb710_chip *chip, \
86 unsigned select) \
87{ \
88 u##t regs[CB710_REG_COUNT/sizeof(u##t)]; \
89 \
90 memset(&regs, 0, sizeof(regs)); \
91 cb710_read_regs_##t(chip->iobase, regs, select); \
92 cb710_dump_regs_##t(cb710_chip_dev(chip), regs, select); \
93}
94
95#define CB710_REG_ACCESS_TEMPLATES(t) \
96 CB710_READ_REGS_TEMPLATE(t) \
97 CB710_DUMP_REGS_TEMPLATE(t) \
98 CB710_READ_AND_DUMP_REGS_TEMPLATE(t)
99
100CB710_REG_ACCESS_TEMPLATES(8)
101CB710_REG_ACCESS_TEMPLATES(16)
102CB710_REG_ACCESS_TEMPLATES(32)
103
104void cb710_dump_regs(struct cb710_chip *chip, unsigned select)
105{
106 if (!(select & CB710_DUMP_REGS_MASK))
107 select = CB710_DUMP_REGS_ALL;
108 if (!(select & CB710_DUMP_ACCESS_MASK))
109 select |= CB710_DUMP_ACCESS_8;
110
111 if (select & CB710_DUMP_ACCESS_32)
112 cb710_read_and_dump_regs_32(chip, select);
113 if (select & CB710_DUMP_ACCESS_16)
114 cb710_read_and_dump_regs_16(chip, select);
115 if (select & CB710_DUMP_ACCESS_8)
116 cb710_read_and_dump_regs_8(chip, select);
117}
118EXPORT_SYMBOL_GPL(cb710_dump_regs);
119
diff --git a/drivers/misc/cb710/sgbuf2.c b/drivers/misc/cb710/sgbuf2.c
new file mode 100644
index 000000000000..d38a7acdb6ec
--- /dev/null
+++ b/drivers/misc/cb710/sgbuf2.c
@@ -0,0 +1,150 @@
1/*
2 * cb710/sgbuf2.c
3 *
4 * Copyright by Michał Mirosław, 2008-2009
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/cb710.h>
13
14static bool sg_dwiter_next(struct sg_mapping_iter *miter)
15{
16 if (sg_miter_next(miter)) {
17 miter->consumed = 0;
18 return true;
19 } else
20 return false;
21}
22
23static bool sg_dwiter_is_at_end(struct sg_mapping_iter *miter)
24{
25 return miter->length == miter->consumed && !sg_dwiter_next(miter);
26}
27
28static uint32_t sg_dwiter_read_buffer(struct sg_mapping_iter *miter)
29{
30 size_t len, left = 4;
31 uint32_t data;
32 void *addr = &data;
33
34 do {
35 len = min(miter->length - miter->consumed, left);
36 memcpy(addr, miter->addr + miter->consumed, len);
37 miter->consumed += len;
38 left -= len;
39 if (!left)
40 return data;
41 addr += len;
42 } while (sg_dwiter_next(miter));
43
44 memset(addr, 0, left);
45 return data;
46}
47
48static inline bool needs_unaligned_copy(const void *ptr)
49{
50#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
51 return false;
52#else
53 return ((ptr - NULL) & 3) != 0;
54#endif
55}
56
57static bool sg_dwiter_get_next_block(struct sg_mapping_iter *miter, uint32_t **ptr)
58{
59 size_t len;
60
61 if (sg_dwiter_is_at_end(miter))
62 return true;
63
64 len = miter->length - miter->consumed;
65
66 if (likely(len >= 4 && !needs_unaligned_copy(
67 miter->addr + miter->consumed))) {
68 *ptr = miter->addr + miter->consumed;
69 miter->consumed += 4;
70 return true;
71 }
72
73 return false;
74}
75
76/**
77 * cb710_sg_dwiter_read_next_block() - get next 32-bit word from sg buffer
78 * @miter: sg mapping iterator used for reading
79 *
80 * Description:
81 * Returns 32-bit word starting at byte pointed to by @miter@
82 * handling any alignment issues. Bytes past the buffer's end
83 * are not accessed (read) but are returned as zeroes. @miter@
84 * is advanced by 4 bytes or to the end of buffer whichever is
85 * closer.
86 *
87 * Context:
88 * Same requirements as in sg_miter_next().
89 *
90 * Returns:
91 * 32-bit word just read.
92 */
93uint32_t cb710_sg_dwiter_read_next_block(struct sg_mapping_iter *miter)
94{
95 uint32_t *ptr = NULL;
96
97 if (likely(sg_dwiter_get_next_block(miter, &ptr)))
98 return ptr ? *ptr : 0;
99
100 return sg_dwiter_read_buffer(miter);
101}
102EXPORT_SYMBOL_GPL(cb710_sg_dwiter_read_next_block);
103
104static void sg_dwiter_write_slow(struct sg_mapping_iter *miter, uint32_t data)
105{
106 size_t len, left = 4;
107 void *addr = &data;
108
109 do {
110 len = min(miter->length - miter->consumed, left);
111 memcpy(miter->addr, addr, len);
112 miter->consumed += len;
113 left -= len;
114 if (!left)
115 return;
116 addr += len;
117 flush_kernel_dcache_page(miter->page);
118 } while (sg_dwiter_next(miter));
119}
120
121/**
122 * cb710_sg_dwiter_write_next_block() - write next 32-bit word to sg buffer
123 * @miter: sg mapping iterator used for writing
124 *
125 * Description:
126 * Writes 32-bit word starting at byte pointed to by @miter@
127 * handling any alignment issues. Bytes which would be written
128 * past the buffer's end are silently discarded. @miter@ is
129 * advanced by 4 bytes or to the end of buffer whichever is closer.
130 *
131 * Context:
132 * Same requirements as in sg_miter_next().
133 */
134void cb710_sg_dwiter_write_next_block(struct sg_mapping_iter *miter, uint32_t data)
135{
136 uint32_t *ptr = NULL;
137
138 if (likely(sg_dwiter_get_next_block(miter, &ptr))) {
139 if (ptr)
140 *ptr = data;
141 else
142 return;
143 } else
144 sg_dwiter_write_slow(miter, data);
145
146 if (miter->length == miter->consumed)
147 flush_kernel_dcache_page(miter->page);
148}
149EXPORT_SYMBOL_GPL(cb710_sg_dwiter_write_next_block);
150
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 98ffc41eaf2c..adc205c49fbf 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -147,7 +147,8 @@ struct mmc_blk_request {
147static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) 147static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
148{ 148{
149 int err; 149 int err;
150 __be32 blocks; 150 u32 result;
151 __be32 *blocks;
151 152
152 struct mmc_request mrq; 153 struct mmc_request mrq;
153 struct mmc_command cmd; 154 struct mmc_command cmd;
@@ -199,14 +200,21 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
199 mrq.cmd = &cmd; 200 mrq.cmd = &cmd;
200 mrq.data = &data; 201 mrq.data = &data;
201 202
202 sg_init_one(&sg, &blocks, 4); 203 blocks = kmalloc(4, GFP_KERNEL);
204 if (!blocks)
205 return (u32)-1;
206
207 sg_init_one(&sg, blocks, 4);
203 208
204 mmc_wait_for_req(card->host, &mrq); 209 mmc_wait_for_req(card->host, &mrq);
205 210
211 result = ntohl(*blocks);
212 kfree(blocks);
213
206 if (cmd.error || data.error) 214 if (cmd.error || data.error)
207 return (u32)-1; 215 result = (u32)-1;
208 216
209 return ntohl(blocks); 217 return result;
210} 218}
211 219
212static u32 get_card_status(struct mmc_card *card, struct request *req) 220static u32 get_card_status(struct mmc_card *card, struct request *req)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 264911732756..d84c880fac84 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -708,7 +708,13 @@ static void mmc_power_up(struct mmc_host *host)
708 */ 708 */
709 mmc_delay(10); 709 mmc_delay(10);
710 710
711 host->ios.clock = host->f_min; 711 if (host->f_min > 400000) {
712 pr_warning("%s: Minimum clock frequency too high for "
713 "identification mode\n", mmc_hostname(host));
714 host->ios.clock = host->f_min;
715 } else
716 host->ios.clock = 400000;
717
712 host->ios.power_mode = MMC_POWER_ON; 718 host->ios.power_mode = MMC_POWER_ON;
713 mmc_set_ios(host); 719 mmc_set_ios(host);
714 720
@@ -855,61 +861,72 @@ void mmc_rescan(struct work_struct *work)
855 861
856 mmc_bus_get(host); 862 mmc_bus_get(host);
857 863
858 if (host->bus_ops == NULL) { 864 /* if there is a card registered, check whether it is still present */
859 /* 865 if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
860 * Only we can add a new handler, so it's safe to 866 host->bus_ops->detect(host);
861 * release the lock here. 867
862 */ 868 mmc_bus_put(host);
869
870
871 mmc_bus_get(host);
872
873 /* if there still is a card present, stop here */
874 if (host->bus_ops != NULL) {
863 mmc_bus_put(host); 875 mmc_bus_put(host);
876 goto out;
877 }
864 878
865 if (host->ops->get_cd && host->ops->get_cd(host) == 0) 879 /* detect a newly inserted card */
866 goto out;
867 880
868 mmc_claim_host(host); 881 /*
882 * Only we can add a new handler, so it's safe to
883 * release the lock here.
884 */
885 mmc_bus_put(host);
869 886
870 mmc_power_up(host); 887 if (host->ops->get_cd && host->ops->get_cd(host) == 0)
871 mmc_go_idle(host); 888 goto out;
872 889
873 mmc_send_if_cond(host, host->ocr_avail); 890 mmc_claim_host(host);
874 891
875 /* 892 mmc_power_up(host);
876 * First we search for SDIO... 893 mmc_go_idle(host);
877 */
878 err = mmc_send_io_op_cond(host, 0, &ocr);
879 if (!err) {
880 if (mmc_attach_sdio(host, ocr))
881 mmc_power_off(host);
882 goto out;
883 }
884 894
885 /* 895 mmc_send_if_cond(host, host->ocr_avail);
886 * ...then normal SD...
887 */
888 err = mmc_send_app_op_cond(host, 0, &ocr);
889 if (!err) {
890 if (mmc_attach_sd(host, ocr))
891 mmc_power_off(host);
892 goto out;
893 }
894 896
895 /* 897 /*
896 * ...and finally MMC. 898 * First we search for SDIO...
897 */ 899 */
898 err = mmc_send_op_cond(host, 0, &ocr); 900 err = mmc_send_io_op_cond(host, 0, &ocr);
899 if (!err) { 901 if (!err) {
900 if (mmc_attach_mmc(host, ocr)) 902 if (mmc_attach_sdio(host, ocr))
901 mmc_power_off(host); 903 mmc_power_off(host);
902 goto out; 904 goto out;
903 } 905 }
904 906
905 mmc_release_host(host); 907 /*
906 mmc_power_off(host); 908 * ...then normal SD...
907 } else { 909 */
908 if (host->bus_ops->detect && !host->bus_dead) 910 err = mmc_send_app_op_cond(host, 0, &ocr);
909 host->bus_ops->detect(host); 911 if (!err) {
912 if (mmc_attach_sd(host, ocr))
913 mmc_power_off(host);
914 goto out;
915 }
910 916
911 mmc_bus_put(host); 917 /*
918 * ...and finally MMC.
919 */
920 err = mmc_send_op_cond(host, 0, &ocr);
921 if (!err) {
922 if (mmc_attach_mmc(host, ocr))
923 mmc_power_off(host);
924 goto out;
912 } 925 }
926
927 mmc_release_host(host);
928 mmc_power_off(host);
929
913out: 930out:
914 if (host->caps & MMC_CAP_NEEDS_POLL) 931 if (host->caps & MMC_CAP_NEEDS_POLL)
915 mmc_schedule_delayed_work(&host->detect, HZ); 932 mmc_schedule_delayed_work(&host->detect, HZ);
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 3eb87bda14f3..40111a6d8d5b 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -83,6 +83,17 @@ config MMC_SDHCI_OF
83 83
84 If unsure, say N. 84 If unsure, say N.
85 85
86config MMC_SDHCI_PLTFM
87 tristate "SDHCI support on the platform specific bus"
88 depends on MMC_SDHCI
89 help
90 This selects the platform specific bus support for Secure Digital Host
91 Controller Interface.
92
93 If you have a controller with this interface, say Y or M here.
94
95 If unsure, say N.
96
86config MMC_OMAP 97config MMC_OMAP
87 tristate "TI OMAP Multimedia Card Interface support" 98 tristate "TI OMAP Multimedia Card Interface support"
88 depends on ARCH_OMAP 99 depends on ARCH_OMAP
@@ -237,7 +248,20 @@ config MMC_SDRICOH_CS
237 248
238config MMC_TMIO 249config MMC_TMIO
239 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" 250 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
240 depends on MFD_TMIO 251 depends on MFD_TMIO || MFD_ASIC3
241 help 252 help
242 This provides support for the SD/MMC cell found in TC6393XB, 253 This provides support for the SD/MMC cell found in TC6393XB,
243 T7L66XB and also ipaq ASIC3 254 T7L66XB and also HTC ASIC3
255
256config MMC_CB710
257 tristate "ENE CB710 MMC/SD Interface support"
258 depends on PCI
259 select CB710_CORE
260 help
261 This option enables support for MMC/SD part of ENE CB710/720 Flash
262 memory card reader found in some laptops (ie. some versions of
263 HP Compaq nx9500).
264
265 This driver can also be built as a module. If so, the module
266 will be called cb710-mmc.
267
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 970a997620e1..79da397c5fea 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_MMC_SDHCI) += sdhci.o
14obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o 14obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
15obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o 15obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
16obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o 16obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o
17obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
17obj-$(CONFIG_MMC_WBSD) += wbsd.o 18obj-$(CONFIG_MMC_WBSD) += wbsd.o
18obj-$(CONFIG_MMC_AU1X) += au1xmmc.o 19obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
19obj-$(CONFIG_MMC_OMAP) += omap.o 20obj-$(CONFIG_MMC_OMAP) += omap.o
@@ -29,4 +30,8 @@ endif
29obj-$(CONFIG_MMC_S3C) += s3cmci.o 30obj-$(CONFIG_MMC_S3C) += s3cmci.o
30obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o 31obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o
31obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o 32obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o
33obj-$(CONFIG_MMC_CB710) += cb710-mmc.o
32 34
35ifeq ($(CONFIG_CB710_DEBUG),y)
36 CFLAGS-cb710-mmc += -DDEBUG
37endif
diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h
index b58364ed6bba..fc8a0fe7c5c5 100644
--- a/drivers/mmc/host/atmel-mci-regs.h
+++ b/drivers/mmc/host/atmel-mci-regs.h
@@ -7,6 +7,12 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10
11/*
12 * Superset of MCI IP registers integrated in Atmel AVR32 and AT91 Processors
13 * Registers and bitfields marked with [2] are only available in MCI2
14 */
15
10#ifndef __DRIVERS_MMC_ATMEL_MCI_H__ 16#ifndef __DRIVERS_MMC_ATMEL_MCI_H__
11#define __DRIVERS_MMC_ATMEL_MCI_H__ 17#define __DRIVERS_MMC_ATMEL_MCI_H__
12 18
@@ -14,11 +20,17 @@
14#define MCI_CR 0x0000 /* Control */ 20#define MCI_CR 0x0000 /* Control */
15# define MCI_CR_MCIEN ( 1 << 0) /* MCI Enable */ 21# define MCI_CR_MCIEN ( 1 << 0) /* MCI Enable */
16# define MCI_CR_MCIDIS ( 1 << 1) /* MCI Disable */ 22# define MCI_CR_MCIDIS ( 1 << 1) /* MCI Disable */
23# define MCI_CR_PWSEN ( 1 << 2) /* Power Save Enable */
24# define MCI_CR_PWSDIS ( 1 << 3) /* Power Save Disable */
17# define MCI_CR_SWRST ( 1 << 7) /* Software Reset */ 25# define MCI_CR_SWRST ( 1 << 7) /* Software Reset */
18#define MCI_MR 0x0004 /* Mode */ 26#define MCI_MR 0x0004 /* Mode */
19# define MCI_MR_CLKDIV(x) ((x) << 0) /* Clock Divider */ 27# define MCI_MR_CLKDIV(x) ((x) << 0) /* Clock Divider */
28# define MCI_MR_PWSDIV(x) ((x) << 8) /* Power Saving Divider */
20# define MCI_MR_RDPROOF ( 1 << 11) /* Read Proof */ 29# define MCI_MR_RDPROOF ( 1 << 11) /* Read Proof */
21# define MCI_MR_WRPROOF ( 1 << 12) /* Write Proof */ 30# define MCI_MR_WRPROOF ( 1 << 12) /* Write Proof */
31# define MCI_MR_PDCFBYTE ( 1 << 13) /* Force Byte Transfer */
32# define MCI_MR_PDCPADV ( 1 << 14) /* Padding Value */
33# define MCI_MR_PDCMODE ( 1 << 15) /* PDC-oriented Mode */
22#define MCI_DTOR 0x0008 /* Data Timeout */ 34#define MCI_DTOR 0x0008 /* Data Timeout */
23# define MCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */ 35# define MCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */
24# define MCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */ 36# define MCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */
@@ -28,6 +40,7 @@
28# define MCI_SDCSEL_MASK ( 3 << 0) 40# define MCI_SDCSEL_MASK ( 3 << 0)
29# define MCI_SDCBUS_1BIT ( 0 << 6) /* 1-bit data bus */ 41# define MCI_SDCBUS_1BIT ( 0 << 6) /* 1-bit data bus */
30# define MCI_SDCBUS_4BIT ( 2 << 6) /* 4-bit data bus */ 42# define MCI_SDCBUS_4BIT ( 2 << 6) /* 4-bit data bus */
43# define MCI_SDCBUS_8BIT ( 3 << 6) /* 8-bit data bus[2] */
31# define MCI_SDCBUS_MASK ( 3 << 6) 44# define MCI_SDCBUS_MASK ( 3 << 6)
32#define MCI_ARGR 0x0010 /* Command Argument */ 45#define MCI_ARGR 0x0010 /* Command Argument */
33#define MCI_CMDR 0x0014 /* Command */ 46#define MCI_CMDR 0x0014 /* Command */
@@ -56,6 +69,9 @@
56#define MCI_BLKR 0x0018 /* Block */ 69#define MCI_BLKR 0x0018 /* Block */
57# define MCI_BCNT(x) ((x) << 0) /* Data Block Count */ 70# define MCI_BCNT(x) ((x) << 0) /* Data Block Count */
58# define MCI_BLKLEN(x) ((x) << 16) /* Data Block Length */ 71# define MCI_BLKLEN(x) ((x) << 16) /* Data Block Length */
72#define MCI_CSTOR 0x001c /* Completion Signal Timeout[2] */
73# define MCI_CSTOCYC(x) ((x) << 0) /* CST cycles */
74# define MCI_CSTOMUL(x) ((x) << 4) /* CST multiplier */
59#define MCI_RSPR 0x0020 /* Response 0 */ 75#define MCI_RSPR 0x0020 /* Response 0 */
60#define MCI_RSPR1 0x0024 /* Response 1 */ 76#define MCI_RSPR1 0x0024 /* Response 1 */
61#define MCI_RSPR2 0x0028 /* Response 2 */ 77#define MCI_RSPR2 0x0028 /* Response 2 */
@@ -83,7 +99,24 @@
83# define MCI_DTOE ( 1 << 22) /* Data Time-Out Error */ 99# define MCI_DTOE ( 1 << 22) /* Data Time-Out Error */
84# define MCI_OVRE ( 1 << 30) /* RX Overrun Error */ 100# define MCI_OVRE ( 1 << 30) /* RX Overrun Error */
85# define MCI_UNRE ( 1 << 31) /* TX Underrun Error */ 101# define MCI_UNRE ( 1 << 31) /* TX Underrun Error */
102#define MCI_DMA 0x0050 /* DMA Configuration[2] */
103# define MCI_DMA_OFFSET(x) ((x) << 0) /* DMA Write Buffer Offset */
104# define MCI_DMA_CHKSIZE(x) ((x) << 4) /* DMA Channel Read and Write Chunk Size */
105# define MCI_DMAEN ( 1 << 8) /* DMA Hardware Handshaking Enable */
106#define MCI_CFG 0x0054 /* Configuration[2] */
107# define MCI_CFG_FIFOMODE_1DATA ( 1 << 0) /* MCI Internal FIFO control mode */
108# define MCI_CFG_FERRCTRL_COR ( 1 << 4) /* Flow Error flag reset control mode */
109# define MCI_CFG_HSMODE ( 1 << 8) /* High Speed Mode */
110# define MCI_CFG_LSYNC ( 1 << 12) /* Synchronize on the last block */
111#define MCI_WPMR 0x00e4 /* Write Protection Mode[2] */
112# define MCI_WP_EN ( 1 << 0) /* WP Enable */
113# define MCI_WP_KEY (0x4d4349 << 8) /* WP Key */
114#define MCI_WPSR 0x00e8 /* Write Protection Status[2] */
115# define MCI_GET_WP_VS(x) ((x) & 0x0f)
116# define MCI_GET_WP_VSRC(x) (((x) >> 8) & 0xffff)
117#define MCI_FIFO_APERTURE 0x0200 /* FIFO Aperture[2] */
86 118
119/* This is not including the FIFO Aperture on MCI2 */
87#define MCI_REGS_SIZE 0x100 120#define MCI_REGS_SIZE 0x100
88 121
89/* Register access macros */ 122/* Register access macros */
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c
new file mode 100644
index 000000000000..11efefb1af51
--- /dev/null
+++ b/drivers/mmc/host/cb710-mmc.c
@@ -0,0 +1,804 @@
1/*
2 * cb710/mmc.c
3 *
4 * Copyright by Michał Mirosław, 2008-2009
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/pci.h>
14#include <linux/delay.h>
15#include "cb710-mmc.h"
16
17static const u8 cb710_clock_divider_log2[8] = {
18/* 1, 2, 4, 8, 16, 32, 128, 512 */
19 0, 1, 2, 3, 4, 5, 7, 9
20};
21#define CB710_MAX_DIVIDER_IDX \
22 (ARRAY_SIZE(cb710_clock_divider_log2) - 1)
23
24static const u8 cb710_src_freq_mhz[16] = {
25 33, 10, 20, 25, 30, 35, 40, 45,
26 50, 55, 60, 65, 70, 75, 80, 85
27};
28
29static void cb710_mmc_set_clock(struct mmc_host *mmc, int hz)
30{
31 struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
32 struct pci_dev *pdev = cb710_slot_to_chip(slot)->pdev;
33 u32 src_freq_idx;
34 u32 divider_idx;
35 int src_hz;
36
37 /* this is magic, unverifiable for me, unless I get
38 * MMC card with cables connected to bus signals */
39 pci_read_config_dword(pdev, 0x48, &src_freq_idx);
40 src_freq_idx = (src_freq_idx >> 16) & 0xF;
41 src_hz = cb710_src_freq_mhz[src_freq_idx] * 1000000;
42
43 for (divider_idx = 0; divider_idx < CB710_MAX_DIVIDER_IDX; ++divider_idx) {
44 if (hz >= src_hz >> cb710_clock_divider_log2[divider_idx])
45 break;
46 }
47
48 if (src_freq_idx)
49 divider_idx |= 0x8;
50
51 cb710_pci_update_config_reg(pdev, 0x40, ~0xF0000000, divider_idx << 28);
52
53 dev_dbg(cb710_slot_dev(slot),
54 "clock set to %d Hz, wanted %d Hz; flag = %d\n",
55 src_hz >> cb710_clock_divider_log2[divider_idx & 7],
56 hz, (divider_idx & 8) != 0);
57}
58
59static void __cb710_mmc_enable_irq(struct cb710_slot *slot,
60 unsigned short enable, unsigned short mask)
61{
62 /* clear global IE
63 * - it gets set later if any interrupt sources are enabled */
64 mask |= CB710_MMC_IE_IRQ_ENABLE;
65
66 /* look like interrupt is fired whenever
67 * WORD[0x0C] & WORD[0x10] != 0;
68 * -> bit 15 port 0x0C seems to be global interrupt enable
69 */
70
71 enable = (cb710_read_port_16(slot, CB710_MMC_IRQ_ENABLE_PORT)
72 & ~mask) | enable;
73
74 if (enable)
75 enable |= CB710_MMC_IE_IRQ_ENABLE;
76
77 cb710_write_port_16(slot, CB710_MMC_IRQ_ENABLE_PORT, enable);
78}
79
80static void cb710_mmc_enable_irq(struct cb710_slot *slot,
81 unsigned short enable, unsigned short mask)
82{
83 struct cb710_mmc_reader *reader = mmc_priv(cb710_slot_to_mmc(slot));
84 unsigned long flags;
85
86 spin_lock_irqsave(&reader->irq_lock, flags);
87 /* this is the only thing irq_lock protects */
88 __cb710_mmc_enable_irq(slot, enable, mask);
89 spin_unlock_irqrestore(&reader->irq_lock, flags);
90}
91
92static void cb710_mmc_reset_events(struct cb710_slot *slot)
93{
94 cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT, 0xFF);
95 cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT, 0xFF);
96 cb710_write_port_8(slot, CB710_MMC_STATUS2_PORT, 0xFF);
97}
98
99static int cb710_mmc_is_card_inserted(struct cb710_slot *slot)
100{
101 return cb710_read_port_8(slot, CB710_MMC_STATUS3_PORT)
102 & CB710_MMC_S3_CARD_DETECTED;
103}
104
105static void cb710_mmc_enable_4bit_data(struct cb710_slot *slot, int enable)
106{
107 dev_dbg(cb710_slot_dev(slot), "configuring %d-data-line%s mode\n",
108 enable ? 4 : 1, enable ? "s" : "");
109 if (enable)
110 cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT,
111 CB710_MMC_C1_4BIT_DATA_BUS, 0);
112 else
113 cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT,
114 0, CB710_MMC_C1_4BIT_DATA_BUS);
115}
116
117static int cb710_check_event(struct cb710_slot *slot, u8 what)
118{
119 u16 status;
120
121 status = cb710_read_port_16(slot, CB710_MMC_STATUS_PORT);
122
123 if (status & CB710_MMC_S0_FIFO_UNDERFLOW) {
124 /* it is just a guess, so log it */
125 dev_dbg(cb710_slot_dev(slot),
126 "CHECK : ignoring bit 6 in status %04X\n", status);
127 cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT,
128 CB710_MMC_S0_FIFO_UNDERFLOW);
129 status &= ~CB710_MMC_S0_FIFO_UNDERFLOW;
130 }
131
132 if (status & CB710_MMC_STATUS_ERROR_EVENTS) {
133 dev_dbg(cb710_slot_dev(slot),
134 "CHECK : returning EIO on status %04X\n", status);
135 cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT, status & 0xFF);
136 cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT,
137 CB710_MMC_S1_RESET);
138 return -EIO;
139 }
140
141 /* 'what' is a bit in MMC_STATUS1 */
142 if ((status >> 8) & what) {
143 cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT, what);
144 return 1;
145 }
146
147 return 0;
148}
149
150static int cb710_wait_for_event(struct cb710_slot *slot, u8 what)
151{
152 int err = 0;
153 unsigned limit = 2000000; /* FIXME: real timeout */
154
155#ifdef CONFIG_CB710_DEBUG
156 u32 e, x;
157 e = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
158#endif
159
160 while (!(err = cb710_check_event(slot, what))) {
161 if (!--limit) {
162 cb710_dump_regs(cb710_slot_to_chip(slot),
163 CB710_DUMP_REGS_MMC);
164 err = -ETIMEDOUT;
165 break;
166 }
167 udelay(1);
168 }
169
170#ifdef CONFIG_CB710_DEBUG
171 x = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
172
173 limit = 2000000 - limit;
174 if (limit > 100)
175 dev_dbg(cb710_slot_dev(slot),
176 "WAIT10: waited %d loops, what %d, entry val %08X, exit val %08X\n",
177 limit, what, e, x);
178#endif
179 return err < 0 ? err : 0;
180}
181
182
183static int cb710_wait_while_busy(struct cb710_slot *slot, uint8_t mask)
184{
185 unsigned limit = 500000; /* FIXME: real timeout */
186 int err = 0;
187
188#ifdef CONFIG_CB710_DEBUG
189 u32 e, x;
190 e = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
191#endif
192
193 while (cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT) & mask) {
194 if (!--limit) {
195 cb710_dump_regs(cb710_slot_to_chip(slot),
196 CB710_DUMP_REGS_MMC);
197 err = -ETIMEDOUT;
198 break;
199 }
200 udelay(1);
201 }
202
203#ifdef CONFIG_CB710_DEBUG
204 x = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
205
206 limit = 500000 - limit;
207 if (limit > 100)
208 dev_dbg(cb710_slot_dev(slot),
209 "WAIT12: waited %d loops, mask %02X, entry val %08X, exit val %08X\n",
210 limit, mask, e, x);
211#endif
212 return 0;
213}
214
215static void cb710_mmc_set_transfer_size(struct cb710_slot *slot,
216 size_t count, size_t blocksize)
217{
218 cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
219 cb710_write_port_32(slot, CB710_MMC_TRANSFER_SIZE_PORT,
220 ((count - 1) << 16)|(blocksize - 1));
221
222 dev_vdbg(cb710_slot_dev(slot), "set up for %zu block%s of %zu bytes\n",
223 count, count == 1 ? "" : "s", blocksize);
224}
225
226static void cb710_mmc_fifo_hack(struct cb710_slot *slot)
227{
228 /* without this, received data is prepended with 8-bytes of zeroes */
229 u32 r1, r2;
230 int ok = 0;
231
232 r1 = cb710_read_port_32(slot, CB710_MMC_DATA_PORT);
233 r2 = cb710_read_port_32(slot, CB710_MMC_DATA_PORT);
234 if (cb710_read_port_8(slot, CB710_MMC_STATUS0_PORT)
235 & CB710_MMC_S0_FIFO_UNDERFLOW) {
236 cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT,
237 CB710_MMC_S0_FIFO_UNDERFLOW);
238 ok = 1;
239 }
240
241 dev_dbg(cb710_slot_dev(slot),
242 "FIFO-read-hack: expected STATUS0 bit was %s\n",
243 ok ? "set." : "NOT SET!");
244 dev_dbg(cb710_slot_dev(slot),
245 "FIFO-read-hack: dwords ignored: %08X %08X - %s\n",
246 r1, r2, (r1|r2) ? "BAD (NOT ZERO)!" : "ok");
247}
248
249static int cb710_mmc_receive_pio(struct cb710_slot *slot,
250 struct sg_mapping_iter *miter, size_t dw_count)
251{
252 if (!(cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT) & CB710_MMC_S2_FIFO_READY)) {
253 int err = cb710_wait_for_event(slot,
254 CB710_MMC_S1_PIO_TRANSFER_DONE);
255 if (err)
256 return err;
257 }
258
259 cb710_sg_dwiter_write_from_io(miter,
260 slot->iobase + CB710_MMC_DATA_PORT, dw_count);
261
262 return 0;
263}
264
265static bool cb710_is_transfer_size_supported(struct mmc_data *data)
266{
267 return !(data->blksz & 15 && (data->blocks != 1 || data->blksz != 8));
268}
269
270static int cb710_mmc_receive(struct cb710_slot *slot, struct mmc_data *data)
271{
272 struct sg_mapping_iter miter;
273 size_t len, blocks = data->blocks;
274 int err = 0;
275
276 /* TODO: I don't know how/if the hardware handles non-16B-boundary blocks
277 * except single 8B block */
278 if (unlikely(data->blksz & 15 && (data->blocks != 1 || data->blksz != 8)))
279 return -EINVAL;
280
281 sg_miter_start(&miter, data->sg, data->sg_len, 0);
282
283 cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT,
284 15, CB710_MMC_C2_READ_PIO_SIZE_MASK);
285
286 cb710_mmc_fifo_hack(slot);
287
288 while (blocks-- > 0) {
289 len = data->blksz;
290
291 while (len >= 16) {
292 err = cb710_mmc_receive_pio(slot, &miter, 4);
293 if (err)
294 goto out;
295 len -= 16;
296 }
297
298 if (!len)
299 continue;
300
301 cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT,
302 len - 1, CB710_MMC_C2_READ_PIO_SIZE_MASK);
303
304 len = (len >= 8) ? 4 : 2;
305 err = cb710_mmc_receive_pio(slot, &miter, len);
306 if (err)
307 goto out;
308 }
309out:
310 cb710_sg_miter_stop_writing(&miter);
311 return err;
312}
313
314static int cb710_mmc_send(struct cb710_slot *slot, struct mmc_data *data)
315{
316 struct sg_mapping_iter miter;
317 size_t len, blocks = data->blocks;
318 int err = 0;
319
320 /* TODO: I don't know how/if the hardware handles multiple
321 * non-16B-boundary blocks */
322 if (unlikely(data->blocks > 1 && data->blksz & 15))
323 return -EINVAL;
324
325 sg_miter_start(&miter, data->sg, data->sg_len, 0);
326
327 cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT,
328 0, CB710_MMC_C2_READ_PIO_SIZE_MASK);
329
330 while (blocks-- > 0) {
331 len = (data->blksz + 15) >> 4;
332 do {
333 if (!(cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT)
334 & CB710_MMC_S2_FIFO_EMPTY)) {
335 err = cb710_wait_for_event(slot,
336 CB710_MMC_S1_PIO_TRANSFER_DONE);
337 if (err)
338 goto out;
339 }
340 cb710_sg_dwiter_read_to_io(&miter,
341 slot->iobase + CB710_MMC_DATA_PORT, 4);
342 } while (--len);
343 }
344out:
345 sg_miter_stop(&miter);
346 return err;
347}
348
349static u16 cb710_encode_cmd_flags(struct cb710_mmc_reader *reader,
350 struct mmc_command *cmd)
351{
352 unsigned int flags = cmd->flags;
353 u16 cb_flags = 0;
354
355 /* Windows driver returned 0 for commands for which no response
356 * is expected. It happened that there were only two such commands
357 * used: MMC_GO_IDLE_STATE and MMC_GO_INACTIVE_STATE so it might
358 * as well be a bug in that driver.
359 *
360 * Original driver set bit 14 for MMC/SD application
361 * commands. There's no difference 'on the wire' and
362 * it apparently works without it anyway.
363 */
364
365 switch (flags & MMC_CMD_MASK) {
366 case MMC_CMD_AC: cb_flags = CB710_MMC_CMD_AC; break;
367 case MMC_CMD_ADTC: cb_flags = CB710_MMC_CMD_ADTC; break;
368 case MMC_CMD_BC: cb_flags = CB710_MMC_CMD_BC; break;
369 case MMC_CMD_BCR: cb_flags = CB710_MMC_CMD_BCR; break;
370 }
371
372 if (flags & MMC_RSP_BUSY)
373 cb_flags |= CB710_MMC_RSP_BUSY;
374
375 cb_flags |= cmd->opcode << CB710_MMC_CMD_CODE_SHIFT;
376
377 if (cmd->data && (cmd->data->flags & MMC_DATA_READ))
378 cb_flags |= CB710_MMC_DATA_READ;
379
380 if (flags & MMC_RSP_PRESENT) {
381 /* Windows driver set 01 at bits 4,3 except for
382 * MMC_SET_BLOCKLEN where it set 10. Maybe the
383 * hardware can do something special about this
384 * command? The original driver looks buggy/incomplete
385 * anyway so we ignore this for now.
386 *
387 * I assume that 00 here means no response is expected.
388 */
389 cb_flags |= CB710_MMC_RSP_PRESENT;
390
391 if (flags & MMC_RSP_136)
392 cb_flags |= CB710_MMC_RSP_136;
393 if (!(flags & MMC_RSP_CRC))
394 cb_flags |= CB710_MMC_RSP_NO_CRC;
395 }
396
397 return cb_flags;
398}
399
400static void cb710_receive_response(struct cb710_slot *slot,
401 struct mmc_command *cmd)
402{
403 unsigned rsp_opcode, wanted_opcode;
404
405 /* Looks like final byte with CRC is always stripped (same as SDHCI) */
406 if (cmd->flags & MMC_RSP_136) {
407 u32 resp[4];
408
409 resp[0] = cb710_read_port_32(slot, CB710_MMC_RESPONSE3_PORT);
410 resp[1] = cb710_read_port_32(slot, CB710_MMC_RESPONSE2_PORT);
411 resp[2] = cb710_read_port_32(slot, CB710_MMC_RESPONSE1_PORT);
412 resp[3] = cb710_read_port_32(slot, CB710_MMC_RESPONSE0_PORT);
413 rsp_opcode = resp[0] >> 24;
414
415 cmd->resp[0] = (resp[0] << 8)|(resp[1] >> 24);
416 cmd->resp[1] = (resp[1] << 8)|(resp[2] >> 24);
417 cmd->resp[2] = (resp[2] << 8)|(resp[3] >> 24);
418 cmd->resp[3] = (resp[3] << 8);
419 } else {
420 rsp_opcode = cb710_read_port_32(slot, CB710_MMC_RESPONSE1_PORT) & 0x3F;
421 cmd->resp[0] = cb710_read_port_32(slot, CB710_MMC_RESPONSE0_PORT);
422 }
423
424 wanted_opcode = (cmd->flags & MMC_RSP_OPCODE) ? cmd->opcode : 0x3F;
425 if (rsp_opcode != wanted_opcode)
426 cmd->error = -EILSEQ;
427}
428
429static int cb710_mmc_transfer_data(struct cb710_slot *slot,
430 struct mmc_data *data)
431{
432 int error, to;
433
434 if (data->flags & MMC_DATA_READ)
435 error = cb710_mmc_receive(slot, data);
436 else
437 error = cb710_mmc_send(slot, data);
438
439 to = cb710_wait_for_event(slot, CB710_MMC_S1_DATA_TRANSFER_DONE);
440 if (!error)
441 error = to;
442
443 if (!error)
444 data->bytes_xfered = data->blksz * data->blocks;
445 return error;
446}
447
448static int cb710_mmc_command(struct mmc_host *mmc, struct mmc_command *cmd)
449{
450 struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
451 struct cb710_mmc_reader *reader = mmc_priv(mmc);
452 struct mmc_data *data = cmd->data;
453
454 u16 cb_cmd = cb710_encode_cmd_flags(reader, cmd);
455 dev_dbg(cb710_slot_dev(slot), "cmd request: 0x%04X\n", cb_cmd);
456
457 if (data) {
458 if (!cb710_is_transfer_size_supported(data)) {
459 data->error = -EINVAL;
460 return -1;
461 }
462 cb710_mmc_set_transfer_size(slot, data->blocks, data->blksz);
463 }
464
465 cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20|CB710_MMC_S2_BUSY_10);
466 cb710_write_port_16(slot, CB710_MMC_CMD_TYPE_PORT, cb_cmd);
467 cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
468 cb710_write_port_32(slot, CB710_MMC_CMD_PARAM_PORT, cmd->arg);
469 cb710_mmc_reset_events(slot);
470 cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
471 cb710_modify_port_8(slot, CB710_MMC_CONFIG0_PORT, 0x01, 0);
472
473 cmd->error = cb710_wait_for_event(slot, CB710_MMC_S1_COMMAND_SENT);
474 if (cmd->error)
475 return -1;
476
477 if (cmd->flags & MMC_RSP_PRESENT) {
478 cb710_receive_response(slot, cmd);
479 if (cmd->error)
480 return -1;
481 }
482
483 if (data)
484 data->error = cb710_mmc_transfer_data(slot, data);
485 return 0;
486}
487
488static void cb710_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
489{
490 struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
491 struct cb710_mmc_reader *reader = mmc_priv(mmc);
492
493 WARN_ON(reader->mrq != NULL);
494
495 reader->mrq = mrq;
496 cb710_mmc_enable_irq(slot, CB710_MMC_IE_TEST_MASK, 0);
497
498 if (cb710_mmc_is_card_inserted(slot)) {
499 if (!cb710_mmc_command(mmc, mrq->cmd) && mrq->stop)
500 cb710_mmc_command(mmc, mrq->stop);
501 mdelay(1);
502 } else {
503 mrq->cmd->error = -ENOMEDIUM;
504 }
505
506 tasklet_schedule(&reader->finish_req_tasklet);
507}
508
509static int cb710_mmc_powerup(struct cb710_slot *slot)
510{
511#ifdef CONFIG_CB710_DEBUG
512 struct cb710_chip *chip = cb710_slot_to_chip(slot);
513#endif
514 int err;
515
516 /* a lot of magic; see comment in cb710_mmc_set_clock() */
517 dev_dbg(cb710_slot_dev(slot), "bus powerup\n");
518 cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
519 err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
520 if (unlikely(err))
521 return err;
522 cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0x80, 0);
523 cb710_modify_port_8(slot, CB710_MMC_CONFIG3_PORT, 0x80, 0);
524 cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
525 mdelay(1);
526 dev_dbg(cb710_slot_dev(slot), "after delay 1\n");
527 cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
528 err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
529 if (unlikely(err))
530 return err;
531 cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0x09, 0);
532 cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
533 mdelay(1);
534 dev_dbg(cb710_slot_dev(slot), "after delay 2\n");
535 cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
536 err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
537 if (unlikely(err))
538 return err;
539 cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0, 0x08);
540 cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
541 mdelay(2);
542 dev_dbg(cb710_slot_dev(slot), "after delay 3\n");
543 cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
544 cb710_modify_port_8(slot, CB710_MMC_CONFIG0_PORT, 0x06, 0);
545 cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0x70, 0);
546 cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT, 0x80, 0);
547 cb710_modify_port_8(slot, CB710_MMC_CONFIG3_PORT, 0x03, 0);
548 cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
549 err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
550 if (unlikely(err))
551 return err;
552 /* This port behaves weird: quick byte reads of 0x08,0x09 return
553 * 0xFF,0x00 after writing 0xFFFF to 0x08; it works correctly when
554 * read/written from userspace... What am I missing here?
555 * (it doesn't depend on write-to-read delay) */
556 cb710_write_port_16(slot, CB710_MMC_CONFIGB_PORT, 0xFFFF);
557 cb710_modify_port_8(slot, CB710_MMC_CONFIG0_PORT, 0x06, 0);
558 cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
559 dev_dbg(cb710_slot_dev(slot), "bus powerup finished\n");
560
561 return cb710_check_event(slot, 0);
562}
563
564static void cb710_mmc_powerdown(struct cb710_slot *slot)
565{
566 cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0, 0x81);
567 cb710_modify_port_8(slot, CB710_MMC_CONFIG3_PORT, 0, 0x80);
568}
569
570static void cb710_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
571{
572 struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
573 struct cb710_mmc_reader *reader = mmc_priv(mmc);
574 int err;
575
576 cb710_mmc_set_clock(mmc, ios->clock);
577
578 if (!cb710_mmc_is_card_inserted(slot)) {
579 dev_dbg(cb710_slot_dev(slot),
580 "no card inserted - ignoring bus powerup request\n");
581 ios->power_mode = MMC_POWER_OFF;
582 }
583
584 if (ios->power_mode != reader->last_power_mode)
585 switch (ios->power_mode) {
586 case MMC_POWER_ON:
587 err = cb710_mmc_powerup(slot);
588 if (err) {
589 dev_warn(cb710_slot_dev(slot),
590 "powerup failed (%d)- retrying\n", err);
591 cb710_mmc_powerdown(slot);
592 udelay(1);
593 err = cb710_mmc_powerup(slot);
594 if (err)
595 dev_warn(cb710_slot_dev(slot),
596 "powerup retry failed (%d) - expect errors\n",
597 err);
598 }
599 reader->last_power_mode = MMC_POWER_ON;
600 break;
601 case MMC_POWER_OFF:
602 cb710_mmc_powerdown(slot);
603 reader->last_power_mode = MMC_POWER_OFF;
604 break;
605 case MMC_POWER_UP:
606 default:
607 /* ignore */;
608 }
609
610 cb710_mmc_enable_4bit_data(slot, ios->bus_width != MMC_BUS_WIDTH_1);
611
612 cb710_mmc_enable_irq(slot, CB710_MMC_IE_TEST_MASK, 0);
613}
614
615static int cb710_mmc_get_ro(struct mmc_host *mmc)
616{
617 struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
618
619 return cb710_read_port_8(slot, CB710_MMC_STATUS3_PORT)
620 & CB710_MMC_S3_WRITE_PROTECTED;
621}
622
623static int cb710_mmc_irq_handler(struct cb710_slot *slot)
624{
625 struct mmc_host *mmc = cb710_slot_to_mmc(slot);
626 struct cb710_mmc_reader *reader = mmc_priv(mmc);
627 u32 status, config1, config2, irqen;
628
629 status = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
630 irqen = cb710_read_port_32(slot, CB710_MMC_IRQ_ENABLE_PORT);
631 config2 = cb710_read_port_32(slot, CB710_MMC_CONFIGB_PORT);
632 config1 = cb710_read_port_32(slot, CB710_MMC_CONFIG_PORT);
633
634 dev_dbg(cb710_slot_dev(slot), "interrupt; status: %08X, "
635 "ie: %08X, c2: %08X, c1: %08X\n",
636 status, irqen, config2, config1);
637
638 if (status & (CB710_MMC_S1_CARD_CHANGED << 8)) {
639 /* ack the event */
640 cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT,
641 CB710_MMC_S1_CARD_CHANGED);
642 if ((irqen & CB710_MMC_IE_CISTATUS_MASK)
643 == CB710_MMC_IE_CISTATUS_MASK)
644 mmc_detect_change(mmc, HZ/5);
645 } else {
646 dev_dbg(cb710_slot_dev(slot), "unknown interrupt (test)\n");
647 spin_lock(&reader->irq_lock);
648 __cb710_mmc_enable_irq(slot, 0, CB710_MMC_IE_TEST_MASK);
649 spin_unlock(&reader->irq_lock);
650 }
651
652 return 1;
653}
654
655static void cb710_mmc_finish_request_tasklet(unsigned long data)
656{
657 struct mmc_host *mmc = (void *)data;
658 struct cb710_mmc_reader *reader = mmc_priv(mmc);
659 struct mmc_request *mrq = reader->mrq;
660
661 reader->mrq = NULL;
662 mmc_request_done(mmc, mrq);
663}
664
665static const struct mmc_host_ops cb710_mmc_host = {
666 .request = cb710_mmc_request,
667 .set_ios = cb710_mmc_set_ios,
668 .get_ro = cb710_mmc_get_ro
669};
670
671#ifdef CONFIG_PM
672
673static int cb710_mmc_suspend(struct platform_device *pdev, pm_message_t state)
674{
675 struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
676 struct mmc_host *mmc = cb710_slot_to_mmc(slot);
677 int err;
678
679 err = mmc_suspend_host(mmc, state);
680 if (err)
681 return err;
682
683 cb710_mmc_enable_irq(slot, 0, ~0);
684 return 0;
685}
686
687static int cb710_mmc_resume(struct platform_device *pdev)
688{
689 struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
690 struct mmc_host *mmc = cb710_slot_to_mmc(slot);
691
692 cb710_mmc_enable_irq(slot, 0, ~0);
693
694 return mmc_resume_host(mmc);
695}
696
697#endif /* CONFIG_PM */
698
699static int __devinit cb710_mmc_init(struct platform_device *pdev)
700{
701 struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
702 struct cb710_chip *chip = cb710_slot_to_chip(slot);
703 struct mmc_host *mmc;
704 struct cb710_mmc_reader *reader;
705 int err;
706 u32 val;
707
708 mmc = mmc_alloc_host(sizeof(*reader), cb710_slot_dev(slot));
709 if (!mmc)
710 return -ENOMEM;
711
712 dev_set_drvdata(&pdev->dev, mmc);
713
714 /* harmless (maybe) magic */
715 pci_read_config_dword(chip->pdev, 0x48, &val);
716 val = cb710_src_freq_mhz[(val >> 16) & 0xF];
717 dev_dbg(cb710_slot_dev(slot), "source frequency: %dMHz\n", val);
718 val *= 1000000;
719
720 mmc->ops = &cb710_mmc_host;
721 mmc->f_max = val;
722 mmc->f_min = val >> cb710_clock_divider_log2[CB710_MAX_DIVIDER_IDX];
723 mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
724 mmc->caps = MMC_CAP_4_BIT_DATA;
725
726 reader = mmc_priv(mmc);
727
728 tasklet_init(&reader->finish_req_tasklet,
729 cb710_mmc_finish_request_tasklet, (unsigned long)mmc);
730 spin_lock_init(&reader->irq_lock);
731 cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
732
733 cb710_mmc_enable_irq(slot, 0, ~0);
734 cb710_set_irq_handler(slot, cb710_mmc_irq_handler);
735
736 err = mmc_add_host(mmc);
737 if (unlikely(err))
738 goto err_free_mmc;
739
740 dev_dbg(cb710_slot_dev(slot), "mmc_hostname is %s\n",
741 mmc_hostname(mmc));
742
743 cb710_mmc_enable_irq(slot, CB710_MMC_IE_CARD_INSERTION_STATUS, 0);
744
745 return 0;
746
747err_free_mmc:
748 dev_dbg(cb710_slot_dev(slot), "mmc_add_host() failed: %d\n", err);
749
750 mmc_free_host(mmc);
751 return err;
752}
753
754static int __devexit cb710_mmc_exit(struct platform_device *pdev)
755{
756 struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
757 struct mmc_host *mmc = cb710_slot_to_mmc(slot);
758 struct cb710_mmc_reader *reader = mmc_priv(mmc);
759
760 cb710_mmc_enable_irq(slot, 0, CB710_MMC_IE_CARD_INSERTION_STATUS);
761
762 mmc_remove_host(mmc);
763
764 /* IRQs should be disabled now, but let's stay on the safe side */
765 cb710_mmc_enable_irq(slot, 0, ~0);
766 cb710_set_irq_handler(slot, NULL);
767
768 /* clear config ports - just in case */
769 cb710_write_port_32(slot, CB710_MMC_CONFIG_PORT, 0);
770 cb710_write_port_16(slot, CB710_MMC_CONFIGB_PORT, 0);
771
772 tasklet_kill(&reader->finish_req_tasklet);
773
774 mmc_free_host(mmc);
775 return 0;
776}
777
778static struct platform_driver cb710_mmc_driver = {
779 .driver.name = "cb710-mmc",
780 .probe = cb710_mmc_init,
781 .remove = __devexit_p(cb710_mmc_exit),
782#ifdef CONFIG_PM
783 .suspend = cb710_mmc_suspend,
784 .resume = cb710_mmc_resume,
785#endif
786};
787
788static int __init cb710_mmc_init_module(void)
789{
790 return platform_driver_register(&cb710_mmc_driver);
791}
792
793static void __exit cb710_mmc_cleanup_module(void)
794{
795 platform_driver_unregister(&cb710_mmc_driver);
796}
797
798module_init(cb710_mmc_init_module);
799module_exit(cb710_mmc_cleanup_module);
800
801MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>");
802MODULE_DESCRIPTION("ENE CB710 memory card reader driver - MMC/SD part");
803MODULE_LICENSE("GPL");
804MODULE_ALIAS("platform:cb710-mmc");
diff --git a/drivers/mmc/host/cb710-mmc.h b/drivers/mmc/host/cb710-mmc.h
new file mode 100644
index 000000000000..e845c776bdd7
--- /dev/null
+++ b/drivers/mmc/host/cb710-mmc.h
@@ -0,0 +1,104 @@
1/*
2 * cb710/cb710-mmc.h
3 *
4 * Copyright by Michał Mirosław, 2008-2009
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef LINUX_CB710_MMC_H
11#define LINUX_CB710_MMC_H
12
13#include <linux/cb710.h>
14
15/* per-MMC-reader structure */
16struct cb710_mmc_reader {
17 struct tasklet_struct finish_req_tasklet;
18 struct mmc_request *mrq;
19 spinlock_t irq_lock;
20 unsigned char last_power_mode;
21};
22
23/* some device struct walking */
24
25static inline struct mmc_host *cb710_slot_to_mmc(struct cb710_slot *slot)
26{
27 return dev_get_drvdata(&slot->pdev.dev);
28}
29
30static inline struct cb710_slot *cb710_mmc_to_slot(struct mmc_host *mmc)
31{
32 struct platform_device *pdev = container_of(mmc_dev(mmc),
33 struct platform_device, dev);
34 return cb710_pdev_to_slot(pdev);
35}
36
37/* registers (this might be all wrong ;) */
38
39#define CB710_MMC_DATA_PORT 0x00
40
41#define CB710_MMC_CONFIG_PORT 0x04
42#define CB710_MMC_CONFIG0_PORT 0x04
43#define CB710_MMC_CONFIG1_PORT 0x05
44#define CB710_MMC_C1_4BIT_DATA_BUS 0x40
45#define CB710_MMC_CONFIG2_PORT 0x06
46#define CB710_MMC_C2_READ_PIO_SIZE_MASK 0x0F /* N-1 */
47#define CB710_MMC_CONFIG3_PORT 0x07
48
49#define CB710_MMC_CONFIGB_PORT 0x08
50
51#define CB710_MMC_IRQ_ENABLE_PORT 0x0C
52#define CB710_MMC_IE_TEST_MASK 0x00BF
53#define CB710_MMC_IE_CARD_INSERTION_STATUS 0x1000
54#define CB710_MMC_IE_IRQ_ENABLE 0x8000
55#define CB710_MMC_IE_CISTATUS_MASK \
56 (CB710_MMC_IE_CARD_INSERTION_STATUS|CB710_MMC_IE_IRQ_ENABLE)
57
58#define CB710_MMC_STATUS_PORT 0x10
59#define CB710_MMC_STATUS_ERROR_EVENTS 0x60FF
60#define CB710_MMC_STATUS0_PORT 0x10
61#define CB710_MMC_S0_FIFO_UNDERFLOW 0x40
62#define CB710_MMC_STATUS1_PORT 0x11
63#define CB710_MMC_S1_COMMAND_SENT 0x01
64#define CB710_MMC_S1_DATA_TRANSFER_DONE 0x02
65#define CB710_MMC_S1_PIO_TRANSFER_DONE 0x04
66#define CB710_MMC_S1_CARD_CHANGED 0x10
67#define CB710_MMC_S1_RESET 0x20
68#define CB710_MMC_STATUS2_PORT 0x12
69#define CB710_MMC_S2_FIFO_READY 0x01
70#define CB710_MMC_S2_FIFO_EMPTY 0x02
71#define CB710_MMC_S2_BUSY_10 0x10
72#define CB710_MMC_S2_BUSY_20 0x20
73#define CB710_MMC_STATUS3_PORT 0x13
74#define CB710_MMC_S3_CARD_DETECTED 0x02
75#define CB710_MMC_S3_WRITE_PROTECTED 0x04
76
77#define CB710_MMC_CMD_TYPE_PORT 0x14
78#define CB710_MMC_RSP_TYPE_MASK 0x0007
79#define CB710_MMC_RSP_R1 (0)
80#define CB710_MMC_RSP_136 (5)
81#define CB710_MMC_RSP_NO_CRC (2)
82#define CB710_MMC_RSP_PRESENT_MASK 0x0018
83#define CB710_MMC_RSP_NONE (0 << 3)
84#define CB710_MMC_RSP_PRESENT (1 << 3)
85#define CB710_MMC_RSP_PRESENT_X (2 << 3)
86#define CB710_MMC_CMD_TYPE_MASK 0x0060
87#define CB710_MMC_CMD_BC (0 << 5)
88#define CB710_MMC_CMD_BCR (1 << 5)
89#define CB710_MMC_CMD_AC (2 << 5)
90#define CB710_MMC_CMD_ADTC (3 << 5)
91#define CB710_MMC_DATA_READ 0x0080
92#define CB710_MMC_CMD_CODE_MASK 0x3F00
93#define CB710_MMC_CMD_CODE_SHIFT 8
94#define CB710_MMC_IS_APP_CMD 0x4000
95#define CB710_MMC_RSP_BUSY 0x8000
96
97#define CB710_MMC_CMD_PARAM_PORT 0x18
98#define CB710_MMC_TRANSFER_SIZE_PORT 0x1C
99#define CB710_MMC_RESPONSE0_PORT 0x20
100#define CB710_MMC_RESPONSE1_PORT 0x24
101#define CB710_MMC_RESPONSE2_PORT 0x28
102#define CB710_MMC_RESPONSE3_PORT 0x2C
103
104#endif /* LINUX_CB710_MMC_H */
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index f48349d18c92..240608cc7ae9 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -97,6 +97,14 @@
97 */ 97 */
98#define r1b_timeout (HZ * 3) 98#define r1b_timeout (HZ * 3)
99 99
100/* One of the critical speed parameters is the amount of data which may
101 * be transfered in one command. If this value is too low, the SD card
102 * controller has to do multiple partial block writes (argggh!). With
103 * today (2008) SD cards there is little speed gain if we transfer more
104 * than 64 KBytes at a time. So use this value until there is any indication
105 * that we should do more here.
106 */
107#define MMC_SPI_BLOCKSATONCE 128
100 108
101/****************************************************************************/ 109/****************************************************************************/
102 110
@@ -327,15 +335,16 @@ checkstatus:
327 335
328 /* Status byte: the entire seven-bit R1 response. */ 336 /* Status byte: the entire seven-bit R1 response. */
329 if (cmd->resp[0] != 0) { 337 if (cmd->resp[0] != 0) {
330 if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS 338 if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS)
331 | R1_SPI_ILLEGAL_COMMAND)
332 & cmd->resp[0]) 339 & cmd->resp[0])
333 value = -EINVAL; 340 value = -EFAULT; /* Bad address */
341 else if (R1_SPI_ILLEGAL_COMMAND & cmd->resp[0])
342 value = -ENOSYS; /* Function not implemented */
334 else if (R1_SPI_COM_CRC & cmd->resp[0]) 343 else if (R1_SPI_COM_CRC & cmd->resp[0])
335 value = -EILSEQ; 344 value = -EILSEQ; /* Illegal byte sequence */
336 else if ((R1_SPI_ERASE_SEQ | R1_SPI_ERASE_RESET) 345 else if ((R1_SPI_ERASE_SEQ | R1_SPI_ERASE_RESET)
337 & cmd->resp[0]) 346 & cmd->resp[0])
338 value = -EIO; 347 value = -EIO; /* I/O error */
339 /* else R1_SPI_IDLE, "it's resetting" */ 348 /* else R1_SPI_IDLE, "it's resetting" */
340 } 349 }
341 350
@@ -1366,6 +1375,10 @@ static int mmc_spi_probe(struct spi_device *spi)
1366 1375
1367 mmc->ops = &mmc_spi_ops; 1376 mmc->ops = &mmc_spi_ops;
1368 mmc->max_blk_size = MMC_SPI_BLOCKSIZE; 1377 mmc->max_blk_size = MMC_SPI_BLOCKSIZE;
1378 mmc->max_hw_segs = MMC_SPI_BLOCKSATONCE;
1379 mmc->max_phys_segs = MMC_SPI_BLOCKSATONCE;
1380 mmc->max_req_size = MMC_SPI_BLOCKSATONCE * MMC_SPI_BLOCKSIZE;
1381 mmc->max_blk_count = MMC_SPI_BLOCKSATONCE;
1369 1382
1370 mmc->caps = MMC_CAP_SPI; 1383 mmc->caps = MMC_CAP_SPI;
1371 1384
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index f4cbe473670e..bc14bb1b0579 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -746,8 +746,6 @@ static int mxcmci_probe(struct platform_device *pdev)
746 } 746 }
747 747
748 mmc->f_min = clk_get_rate(host->clk) >> 16; 748 mmc->f_min = clk_get_rate(host->clk) >> 16;
749 if (mmc->f_min < 400000)
750 mmc->f_min = 400000;
751 mmc->f_max = clk_get_rate(host->clk) >> 1; 749 mmc->f_max = clk_get_rate(host->clk) >> 1;
752 750
753 /* recommended in data sheet */ 751 /* recommended in data sheet */
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index dceb5ee3bda0..e7a331de5733 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1593,7 +1593,6 @@ static int mmc_omap_resume(struct platform_device *pdev)
1593#endif 1593#endif
1594 1594
1595static struct platform_driver mmc_omap_driver = { 1595static struct platform_driver mmc_omap_driver = {
1596 .probe = mmc_omap_probe,
1597 .remove = mmc_omap_remove, 1596 .remove = mmc_omap_remove,
1598 .suspend = mmc_omap_suspend, 1597 .suspend = mmc_omap_suspend,
1599 .resume = mmc_omap_resume, 1598 .resume = mmc_omap_resume,
@@ -1605,7 +1604,7 @@ static struct platform_driver mmc_omap_driver = {
1605 1604
1606static int __init mmc_omap_init(void) 1605static int __init mmc_omap_init(void)
1607{ 1606{
1608 return platform_driver_register(&mmc_omap_driver); 1607 return platform_driver_probe(&mmc_omap_driver, mmc_omap_probe);
1609} 1608}
1610 1609
1611static void __exit mmc_omap_exit(void) 1610static void __exit mmc_omap_exit(void)
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 430095725f9f..d7d7109ef47e 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -27,6 +27,7 @@
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/mmc/host.h> 28#include <linux/mmc/host.h>
29#include <linux/io.h> 29#include <linux/io.h>
30#include <linux/regulator/consumer.h>
30 31
31#include <asm/sizes.h> 32#include <asm/sizes.h>
32 33
@@ -67,8 +68,42 @@ struct pxamci_host {
67 unsigned int dma_dir; 68 unsigned int dma_dir;
68 unsigned int dma_drcmrrx; 69 unsigned int dma_drcmrrx;
69 unsigned int dma_drcmrtx; 70 unsigned int dma_drcmrtx;
71
72 struct regulator *vcc;
70}; 73};
71 74
75static inline void pxamci_init_ocr(struct pxamci_host *host)
76{
77#ifdef CONFIG_REGULATOR
78 host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc");
79
80 if (IS_ERR(host->vcc))
81 host->vcc = NULL;
82 else {
83 host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc);
84 if (host->pdata && host->pdata->ocr_mask)
85 dev_warn(mmc_dev(host->mmc),
86 "ocr_mask/setpower will not be used\n");
87 }
88#endif
89 if (host->vcc == NULL) {
90 /* fall-back to platform data */
91 host->mmc->ocr_avail = host->pdata ?
92 host->pdata->ocr_mask :
93 MMC_VDD_32_33 | MMC_VDD_33_34;
94 }
95}
96
97static inline void pxamci_set_power(struct pxamci_host *host, unsigned int vdd)
98{
99#ifdef CONFIG_REGULATOR
100 if (host->vcc)
101 mmc_regulator_set_ocr(host->vcc, vdd);
102#endif
103 if (!host->vcc && host->pdata && host->pdata->setpower)
104 host->pdata->setpower(mmc_dev(host->mmc), vdd);
105}
106
72static void pxamci_stop_clock(struct pxamci_host *host) 107static void pxamci_stop_clock(struct pxamci_host *host)
73{ 108{
74 if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { 109 if (readl(host->base + MMC_STAT) & STAT_CLK_EN) {
@@ -438,8 +473,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
438 if (host->power_mode != ios->power_mode) { 473 if (host->power_mode != ios->power_mode) {
439 host->power_mode = ios->power_mode; 474 host->power_mode = ios->power_mode;
440 475
441 if (host->pdata && host->pdata->setpower) 476 pxamci_set_power(host, ios->vdd);
442 host->pdata->setpower(mmc_dev(mmc), ios->vdd);
443 477
444 if (ios->power_mode == MMC_POWER_ON) 478 if (ios->power_mode == MMC_POWER_ON)
445 host->cmdat |= CMDAT_INIT; 479 host->cmdat |= CMDAT_INIT;
@@ -562,9 +596,8 @@ static int pxamci_probe(struct platform_device *pdev)
562 mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000 596 mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000
563 : host->clkrate; 597 : host->clkrate;
564 598
565 mmc->ocr_avail = host->pdata ? 599 pxamci_init_ocr(host);
566 host->pdata->ocr_mask : 600
567 MMC_VDD_32_33|MMC_VDD_33_34;
568 mmc->caps = 0; 601 mmc->caps = 0;
569 host->cmdat = 0; 602 host->cmdat = 0;
570 if (!cpu_is_pxa25x()) { 603 if (!cpu_is_pxa25x()) {
@@ -661,6 +694,9 @@ static int pxamci_remove(struct platform_device *pdev)
661 if (mmc) { 694 if (mmc) {
662 struct pxamci_host *host = mmc_priv(mmc); 695 struct pxamci_host *host = mmc_priv(mmc);
663 696
697 if (host->vcc)
698 regulator_put(host->vcc);
699
664 if (host->pdata && host->pdata->exit) 700 if (host->pdata && host->pdata->exit)
665 host->pdata->exit(&pdev->dev, mmc); 701 host->pdata->exit(&pdev->dev, mmc);
666 702
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
new file mode 100644
index 000000000000..297f40ae6ad5
--- /dev/null
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -0,0 +1,168 @@
1/*
2 * sdhci-pltfm.c Support for SDHCI platform devices
3 * Copyright (c) 2009 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19/* Supports:
20 * SDHCI platform devices
21 *
22 * Inspired by sdhci-pci.c, by Pierre Ossman
23 */
24
25#include <linux/delay.h>
26#include <linux/highmem.h>
27#include <linux/platform_device.h>
28
29#include <linux/mmc/host.h>
30
31#include <linux/io.h>
32
33#include "sdhci.h"
34
35/*****************************************************************************\
36 * *
37 * SDHCI core callbacks *
38 * *
39\*****************************************************************************/
40
41static struct sdhci_ops sdhci_pltfm_ops = {
42};
43
44/*****************************************************************************\
45 * *
46 * Device probing/removal *
47 * *
48\*****************************************************************************/
49
50static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
51{
52 struct sdhci_host *host;
53 struct resource *iomem;
54 int ret;
55
56 BUG_ON(pdev == NULL);
57
58 iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
59 if (!iomem) {
60 ret = -ENOMEM;
61 goto err;
62 }
63
64 if (resource_size(iomem) != 0x100)
65 dev_err(&pdev->dev, "Invalid iomem size. You may "
66 "experience problems.\n");
67
68 if (pdev->dev.parent)
69 host = sdhci_alloc_host(pdev->dev.parent, 0);
70 else
71 host = sdhci_alloc_host(&pdev->dev, 0);
72
73 if (IS_ERR(host)) {
74 ret = PTR_ERR(host);
75 goto err;
76 }
77
78 host->hw_name = "platform";
79 host->ops = &sdhci_pltfm_ops;
80 host->irq = platform_get_irq(pdev, 0);
81
82 if (!request_mem_region(iomem->start, resource_size(iomem),
83 mmc_hostname(host->mmc))) {
84 dev_err(&pdev->dev, "cannot request region\n");
85 ret = -EBUSY;
86 goto err_request;
87 }
88
89 host->ioaddr = ioremap(iomem->start, resource_size(iomem));
90 if (!host->ioaddr) {
91 dev_err(&pdev->dev, "failed to remap registers\n");
92 ret = -ENOMEM;
93 goto err_remap;
94 }
95
96 ret = sdhci_add_host(host);
97 if (ret)
98 goto err_add_host;
99
100 platform_set_drvdata(pdev, host);
101
102 return 0;
103
104err_add_host:
105 iounmap(host->ioaddr);
106err_remap:
107 release_mem_region(iomem->start, resource_size(iomem));
108err_request:
109 sdhci_free_host(host);
110err:
111 printk(KERN_ERR"Probing of sdhci-pltfm failed: %d\n", ret);
112 return ret;
113}
114
115static int __devexit sdhci_pltfm_remove(struct platform_device *pdev)
116{
117 struct sdhci_host *host = platform_get_drvdata(pdev);
118 struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
119 int dead;
120 u32 scratch;
121
122 dead = 0;
123 scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
124 if (scratch == (u32)-1)
125 dead = 1;
126
127 sdhci_remove_host(host, dead);
128 iounmap(host->ioaddr);
129 release_mem_region(iomem->start, resource_size(iomem));
130 sdhci_free_host(host);
131 platform_set_drvdata(pdev, NULL);
132
133 return 0;
134}
135
136static struct platform_driver sdhci_pltfm_driver = {
137 .driver = {
138 .name = "sdhci",
139 .owner = THIS_MODULE,
140 },
141 .probe = sdhci_pltfm_probe,
142 .remove = __devexit_p(sdhci_pltfm_remove),
143};
144
145/*****************************************************************************\
146 * *
147 * Driver init/exit *
148 * *
149\*****************************************************************************/
150
151static int __init sdhci_drv_init(void)
152{
153 return platform_driver_register(&sdhci_pltfm_driver);
154}
155
156static void __exit sdhci_drv_exit(void)
157{
158 platform_driver_unregister(&sdhci_pltfm_driver);
159}
160
161module_init(sdhci_drv_init);
162module_exit(sdhci_drv_exit);
163
164MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
165MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
166MODULE_LICENSE("GPL v2");
167MODULE_ALIAS("platform:sdhci");
168
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9234be2226e7..35789c6edc19 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -78,6 +78,11 @@ static void sdhci_dumpregs(struct sdhci_host *host)
78 sdhci_readl(host, SDHCI_CAPABILITIES), 78 sdhci_readl(host, SDHCI_CAPABILITIES),
79 sdhci_readl(host, SDHCI_MAX_CURRENT)); 79 sdhci_readl(host, SDHCI_MAX_CURRENT));
80 80
81 if (host->flags & SDHCI_USE_ADMA)
82 printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
83 readl(host->ioaddr + SDHCI_ADMA_ERROR),
84 readl(host->ioaddr + SDHCI_ADMA_ADDRESS));
85
81 printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); 86 printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
82} 87}
83 88
@@ -1005,12 +1010,34 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
1005{ 1010{
1006 u8 pwr; 1011 u8 pwr;
1007 1012
1008 if (host->power == power) 1013 if (power == (unsigned short)-1)
1014 pwr = 0;
1015 else {
1016 switch (1 << power) {
1017 case MMC_VDD_165_195:
1018 pwr = SDHCI_POWER_180;
1019 break;
1020 case MMC_VDD_29_30:
1021 case MMC_VDD_30_31:
1022 pwr = SDHCI_POWER_300;
1023 break;
1024 case MMC_VDD_32_33:
1025 case MMC_VDD_33_34:
1026 pwr = SDHCI_POWER_330;
1027 break;
1028 default:
1029 BUG();
1030 }
1031 }
1032
1033 if (host->pwr == pwr)
1009 return; 1034 return;
1010 1035
1011 if (power == (unsigned short)-1) { 1036 host->pwr = pwr;
1037
1038 if (pwr == 0) {
1012 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 1039 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1013 goto out; 1040 return;
1014 } 1041 }
1015 1042
1016 /* 1043 /*
@@ -1020,35 +1047,16 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
1020 if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) 1047 if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
1021 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 1048 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1022 1049
1023 pwr = SDHCI_POWER_ON;
1024
1025 switch (1 << power) {
1026 case MMC_VDD_165_195:
1027 pwr |= SDHCI_POWER_180;
1028 break;
1029 case MMC_VDD_29_30:
1030 case MMC_VDD_30_31:
1031 pwr |= SDHCI_POWER_300;
1032 break;
1033 case MMC_VDD_32_33:
1034 case MMC_VDD_33_34:
1035 pwr |= SDHCI_POWER_330;
1036 break;
1037 default:
1038 BUG();
1039 }
1040
1041 /* 1050 /*
1042 * At least the Marvell CaFe chip gets confused if we set the voltage 1051 * At least the Marvell CaFe chip gets confused if we set the voltage
1043 * and set turn on power at the same time, so set the voltage first. 1052 * and set turn on power at the same time, so set the voltage first.
1044 */ 1053 */
1045 if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)) 1054 if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
1046 sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL); 1055 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1047 1056
1048 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1057 pwr |= SDHCI_POWER_ON;
1049 1058
1050out: 1059 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1051 host->power = power;
1052} 1060}
1053 1061
1054/*****************************************************************************\ 1062/*****************************************************************************\
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 65c6f996bbd3..2de08349c3ca 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -255,7 +255,7 @@ struct sdhci_host {
255 unsigned int timeout_clk; /* Timeout freq (KHz) */ 255 unsigned int timeout_clk; /* Timeout freq (KHz) */
256 256
257 unsigned int clock; /* Current clock (MHz) */ 257 unsigned int clock; /* Current clock (MHz) */
258 unsigned short power; /* Current voltage */ 258 u8 pwr; /* Current voltage */
259 259
260 struct mmc_request *mrq; /* Current request */ 260 struct mmc_request *mrq; /* Current request */
261 struct mmc_command *cmd; /* Current command */ 261 struct mmc_command *cmd; /* Current command */
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index 63fbd5b7d312..91991b460c45 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -10,7 +10,7 @@
10 * 10 *
11 * Driver for the MMC / SD / SDIO cell found in: 11 * Driver for the MMC / SD / SDIO cell found in:
12 * 12 *
13 * TC6393XB TC6391XB TC6387XB T7L66XB 13 * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3
14 * 14 *
15 * This driver draws mainly on scattered spec sheets, Reverse engineering 15 * This driver draws mainly on scattered spec sheets, Reverse engineering
16 * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit 16 * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit
@@ -35,69 +35,47 @@
35 35
36#include "tmio_mmc.h" 36#include "tmio_mmc.h"
37 37
38/*
39 * Fixme - documentation conflicts on what the clock values are for the
40 * various dividers.
41 * One document I have says that its a divisor of a 24MHz clock, another 33.
42 * This probably depends on HCLK for a given platform, so we may need to
43 * require HCLK be passed to us from the MFD core.
44 *
45 */
46
47static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) 38static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock)
48{ 39{
49 void __iomem *cnf = host->cnf;
50 void __iomem *ctl = host->ctl;
51 u32 clk = 0, clock; 40 u32 clk = 0, clock;
52 41
53 if (new_clock) { 42 if (new_clock) {
54 for (clock = 46875, clk = 0x100; new_clock >= (clock<<1); ) { 43 for (clock = host->mmc->f_min, clk = 0x80000080;
44 new_clock >= (clock<<1); clk >>= 1)
55 clock <<= 1; 45 clock <<= 1;
56 clk >>= 1;
57 }
58 if (clk & 0x1)
59 clk = 0x20000;
60
61 clk >>= 2;
62 tmio_iowrite8((clk & 0x8000) ? 0 : 1, cnf + CNF_SD_CLK_MODE);
63 clk |= 0x100; 46 clk |= 0x100;
64 } 47 }
65 48
66 tmio_iowrite16(clk, ctl + CTL_SD_CARD_CLK_CTL); 49 sd_config_write8(host, CNF_SD_CLK_MODE, clk >> 22);
50 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff);
67} 51}
68 52
69static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) 53static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
70{ 54{
71 void __iomem *ctl = host->ctl; 55 sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
72
73 tmio_iowrite16(0x0000, ctl + CTL_CLK_AND_WAIT_CTL);
74 msleep(10); 56 msleep(10);
75 tmio_iowrite16(tmio_ioread16(ctl + CTL_SD_CARD_CLK_CTL) & ~0x0100, 57 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~0x0100 &
76 ctl + CTL_SD_CARD_CLK_CTL); 58 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
77 msleep(10); 59 msleep(10);
78} 60}
79 61
80static void tmio_mmc_clk_start(struct tmio_mmc_host *host) 62static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
81{ 63{
82 void __iomem *ctl = host->ctl; 64 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 |
83 65 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
84 tmio_iowrite16(tmio_ioread16(ctl + CTL_SD_CARD_CLK_CTL) | 0x0100,
85 ctl + CTL_SD_CARD_CLK_CTL);
86 msleep(10); 66 msleep(10);
87 tmio_iowrite16(0x0100, ctl + CTL_CLK_AND_WAIT_CTL); 67 sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
88 msleep(10); 68 msleep(10);
89} 69}
90 70
91static void reset(struct tmio_mmc_host *host) 71static void reset(struct tmio_mmc_host *host)
92{ 72{
93 void __iomem *ctl = host->ctl;
94
95 /* FIXME - should we set stop clock reg here */ 73 /* FIXME - should we set stop clock reg here */
96 tmio_iowrite16(0x0000, ctl + CTL_RESET_SD); 74 sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
97 tmio_iowrite16(0x0000, ctl + CTL_RESET_SDIO); 75 sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
98 msleep(10); 76 msleep(10);
99 tmio_iowrite16(0x0001, ctl + CTL_RESET_SD); 77 sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
100 tmio_iowrite16(0x0001, ctl + CTL_RESET_SDIO); 78 sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001);
101 msleep(10); 79 msleep(10);
102} 80}
103 81
@@ -129,13 +107,12 @@ tmio_mmc_finish_request(struct tmio_mmc_host *host)
129static int 107static int
130tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) 108tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd)
131{ 109{
132 void __iomem *ctl = host->ctl;
133 struct mmc_data *data = host->data; 110 struct mmc_data *data = host->data;
134 int c = cmd->opcode; 111 int c = cmd->opcode;
135 112
136 /* Command 12 is handled by hardware */ 113 /* Command 12 is handled by hardware */
137 if (cmd->opcode == 12 && !cmd->arg) { 114 if (cmd->opcode == 12 && !cmd->arg) {
138 tmio_iowrite16(0x001, ctl + CTL_STOP_INTERNAL_ACTION); 115 sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001);
139 return 0; 116 return 0;
140 } 117 }
141 118
@@ -160,18 +137,18 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd)
160 if (data) { 137 if (data) {
161 c |= DATA_PRESENT; 138 c |= DATA_PRESENT;
162 if (data->blocks > 1) { 139 if (data->blocks > 1) {
163 tmio_iowrite16(0x100, ctl + CTL_STOP_INTERNAL_ACTION); 140 sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x100);
164 c |= TRANSFER_MULTI; 141 c |= TRANSFER_MULTI;
165 } 142 }
166 if (data->flags & MMC_DATA_READ) 143 if (data->flags & MMC_DATA_READ)
167 c |= TRANSFER_READ; 144 c |= TRANSFER_READ;
168 } 145 }
169 146
170 enable_mmc_irqs(ctl, TMIO_MASK_CMD); 147 enable_mmc_irqs(host, TMIO_MASK_CMD);
171 148
172 /* Fire off the command */ 149 /* Fire off the command */
173 tmio_iowrite32(cmd->arg, ctl + CTL_ARG_REG); 150 sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg);
174 tmio_iowrite16(c, ctl + CTL_SD_CMD); 151 sd_ctrl_write16(host, CTL_SD_CMD, c);
175 152
176 return 0; 153 return 0;
177} 154}
@@ -183,7 +160,6 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd)
183 */ 160 */
184static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) 161static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
185{ 162{
186 void __iomem *ctl = host->ctl;
187 struct mmc_data *data = host->data; 163 struct mmc_data *data = host->data;
188 unsigned short *buf; 164 unsigned short *buf;
189 unsigned int count; 165 unsigned int count;
@@ -206,9 +182,9 @@ static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
206 182
207 /* Transfer the data */ 183 /* Transfer the data */
208 if (data->flags & MMC_DATA_READ) 184 if (data->flags & MMC_DATA_READ)
209 tmio_ioread16_rep(ctl + CTL_SD_DATA_PORT, buf, count >> 1); 185 sd_ctrl_read16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
210 else 186 else
211 tmio_iowrite16_rep(ctl + CTL_SD_DATA_PORT, buf, count >> 1); 187 sd_ctrl_write16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
212 188
213 host->sg_off += count; 189 host->sg_off += count;
214 190
@@ -222,7 +198,6 @@ static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
222 198
223static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) 199static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host)
224{ 200{
225 void __iomem *ctl = host->ctl;
226 struct mmc_data *data = host->data; 201 struct mmc_data *data = host->data;
227 struct mmc_command *stop; 202 struct mmc_command *stop;
228 203
@@ -251,13 +226,13 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host)
251 */ 226 */
252 227
253 if (data->flags & MMC_DATA_READ) 228 if (data->flags & MMC_DATA_READ)
254 disable_mmc_irqs(ctl, TMIO_MASK_READOP); 229 disable_mmc_irqs(host, TMIO_MASK_READOP);
255 else 230 else
256 disable_mmc_irqs(ctl, TMIO_MASK_WRITEOP); 231 disable_mmc_irqs(host, TMIO_MASK_WRITEOP);
257 232
258 if (stop) { 233 if (stop) {
259 if (stop->opcode == 12 && !stop->arg) 234 if (stop->opcode == 12 && !stop->arg)
260 tmio_iowrite16(0x000, ctl + CTL_STOP_INTERNAL_ACTION); 235 sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000);
261 else 236 else
262 BUG(); 237 BUG();
263 } 238 }
@@ -268,9 +243,8 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host)
268static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, 243static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
269 unsigned int stat) 244 unsigned int stat)
270{ 245{
271 void __iomem *ctl = host->ctl, *addr;
272 struct mmc_command *cmd = host->cmd; 246 struct mmc_command *cmd = host->cmd;
273 int i; 247 int i, addr;
274 248
275 if (!host->cmd) { 249 if (!host->cmd) {
276 pr_debug("Spurious CMD irq\n"); 250 pr_debug("Spurious CMD irq\n");
@@ -284,8 +258,8 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
284 * modify the order of the response for short response command types. 258 * modify the order of the response for short response command types.
285 */ 259 */
286 260
287 for (i = 3, addr = ctl + CTL_RESPONSE ; i >= 0 ; i--, addr += 4) 261 for (i = 3, addr = CTL_RESPONSE ; i >= 0 ; i--, addr += 4)
288 cmd->resp[i] = tmio_ioread32(addr); 262 cmd->resp[i] = sd_ctrl_read32(host, addr);
289 263
290 if (cmd->flags & MMC_RSP_136) { 264 if (cmd->flags & MMC_RSP_136) {
291 cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24); 265 cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24);
@@ -307,9 +281,9 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
307 */ 281 */
308 if (host->data && !cmd->error) { 282 if (host->data && !cmd->error) {
309 if (host->data->flags & MMC_DATA_READ) 283 if (host->data->flags & MMC_DATA_READ)
310 enable_mmc_irqs(ctl, TMIO_MASK_READOP); 284 enable_mmc_irqs(host, TMIO_MASK_READOP);
311 else 285 else
312 enable_mmc_irqs(ctl, TMIO_MASK_WRITEOP); 286 enable_mmc_irqs(host, TMIO_MASK_WRITEOP);
313 } else { 287 } else {
314 tmio_mmc_finish_request(host); 288 tmio_mmc_finish_request(host);
315 } 289 }
@@ -321,20 +295,19 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
321static irqreturn_t tmio_mmc_irq(int irq, void *devid) 295static irqreturn_t tmio_mmc_irq(int irq, void *devid)
322{ 296{
323 struct tmio_mmc_host *host = devid; 297 struct tmio_mmc_host *host = devid;
324 void __iomem *ctl = host->ctl;
325 unsigned int ireg, irq_mask, status; 298 unsigned int ireg, irq_mask, status;
326 299
327 pr_debug("MMC IRQ begin\n"); 300 pr_debug("MMC IRQ begin\n");
328 301
329 status = tmio_ioread32(ctl + CTL_STATUS); 302 status = sd_ctrl_read32(host, CTL_STATUS);
330 irq_mask = tmio_ioread32(ctl + CTL_IRQ_MASK); 303 irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
331 ireg = status & TMIO_MASK_IRQ & ~irq_mask; 304 ireg = status & TMIO_MASK_IRQ & ~irq_mask;
332 305
333 pr_debug_status(status); 306 pr_debug_status(status);
334 pr_debug_status(ireg); 307 pr_debug_status(ireg);
335 308
336 if (!ireg) { 309 if (!ireg) {
337 disable_mmc_irqs(ctl, status & ~irq_mask); 310 disable_mmc_irqs(host, status & ~irq_mask);
338 311
339 pr_debug("tmio_mmc: Spurious irq, disabling! " 312 pr_debug("tmio_mmc: Spurious irq, disabling! "
340 "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); 313 "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
@@ -346,7 +319,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid)
346 while (ireg) { 319 while (ireg) {
347 /* Card insert / remove attempts */ 320 /* Card insert / remove attempts */
348 if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { 321 if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
349 ack_mmc_irqs(ctl, TMIO_STAT_CARD_INSERT | 322 ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
350 TMIO_STAT_CARD_REMOVE); 323 TMIO_STAT_CARD_REMOVE);
351 mmc_detect_change(host->mmc, 0); 324 mmc_detect_change(host->mmc, 0);
352 } 325 }
@@ -358,25 +331,25 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid)
358 331
359 /* Command completion */ 332 /* Command completion */
360 if (ireg & TMIO_MASK_CMD) { 333 if (ireg & TMIO_MASK_CMD) {
361 ack_mmc_irqs(ctl, TMIO_MASK_CMD); 334 ack_mmc_irqs(host, TMIO_MASK_CMD);
362 tmio_mmc_cmd_irq(host, status); 335 tmio_mmc_cmd_irq(host, status);
363 } 336 }
364 337
365 /* Data transfer */ 338 /* Data transfer */
366 if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { 339 if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
367 ack_mmc_irqs(ctl, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); 340 ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
368 tmio_mmc_pio_irq(host); 341 tmio_mmc_pio_irq(host);
369 } 342 }
370 343
371 /* Data transfer completion */ 344 /* Data transfer completion */
372 if (ireg & TMIO_STAT_DATAEND) { 345 if (ireg & TMIO_STAT_DATAEND) {
373 ack_mmc_irqs(ctl, TMIO_STAT_DATAEND); 346 ack_mmc_irqs(host, TMIO_STAT_DATAEND);
374 tmio_mmc_data_irq(host); 347 tmio_mmc_data_irq(host);
375 } 348 }
376 349
377 /* Check status - keep going until we've handled it all */ 350 /* Check status - keep going until we've handled it all */
378 status = tmio_ioread32(ctl + CTL_STATUS); 351 status = sd_ctrl_read32(host, CTL_STATUS);
379 irq_mask = tmio_ioread32(ctl + CTL_IRQ_MASK); 352 irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
380 ireg = status & TMIO_MASK_IRQ & ~irq_mask; 353 ireg = status & TMIO_MASK_IRQ & ~irq_mask;
381 354
382 pr_debug("Status at end of loop: %08x\n", status); 355 pr_debug("Status at end of loop: %08x\n", status);
@@ -391,8 +364,6 @@ out:
391static int tmio_mmc_start_data(struct tmio_mmc_host *host, 364static int tmio_mmc_start_data(struct tmio_mmc_host *host,
392 struct mmc_data *data) 365 struct mmc_data *data)
393{ 366{
394 void __iomem *ctl = host->ctl;
395
396 pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", 367 pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n",
397 data->blksz, data->blocks); 368 data->blksz, data->blocks);
398 369
@@ -407,8 +378,8 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host,
407 host->data = data; 378 host->data = data;
408 379
409 /* Set transfer length / blocksize */ 380 /* Set transfer length / blocksize */
410 tmio_iowrite16(data->blksz, ctl + CTL_SD_XFER_LEN); 381 sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz);
411 tmio_iowrite16(data->blocks, ctl + CTL_XFER_BLK_COUNT); 382 sd_ctrl_write16(host, CTL_XFER_BLK_COUNT, data->blocks);
412 383
413 return 0; 384 return 0;
414} 385}
@@ -449,8 +420,6 @@ fail:
449static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 420static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
450{ 421{
451 struct tmio_mmc_host *host = mmc_priv(mmc); 422 struct tmio_mmc_host *host = mmc_priv(mmc);
452 void __iomem *cnf = host->cnf;
453 void __iomem *ctl = host->ctl;
454 423
455 if (ios->clock) 424 if (ios->clock)
456 tmio_mmc_set_clock(host, ios->clock); 425 tmio_mmc_set_clock(host, ios->clock);
@@ -458,12 +427,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
458 /* Power sequence - OFF -> ON -> UP */ 427 /* Power sequence - OFF -> ON -> UP */
459 switch (ios->power_mode) { 428 switch (ios->power_mode) {
460 case MMC_POWER_OFF: /* power down SD bus */ 429 case MMC_POWER_OFF: /* power down SD bus */
461 tmio_iowrite8(0x00, cnf + CNF_PWR_CTL_2); 430 sd_config_write8(host, CNF_PWR_CTL_2, 0x00);
462 tmio_mmc_clk_stop(host); 431 tmio_mmc_clk_stop(host);
463 break; 432 break;
464 case MMC_POWER_ON: /* power up SD bus */ 433 case MMC_POWER_ON: /* power up SD bus */
465 434
466 tmio_iowrite8(0x02, cnf + CNF_PWR_CTL_2); 435 sd_config_write8(host, CNF_PWR_CTL_2, 0x02);
467 break; 436 break;
468 case MMC_POWER_UP: /* start bus clock */ 437 case MMC_POWER_UP: /* start bus clock */
469 tmio_mmc_clk_start(host); 438 tmio_mmc_clk_start(host);
@@ -472,10 +441,10 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
472 441
473 switch (ios->bus_width) { 442 switch (ios->bus_width) {
474 case MMC_BUS_WIDTH_1: 443 case MMC_BUS_WIDTH_1:
475 tmio_iowrite16(0x80e0, ctl + CTL_SD_MEM_CARD_OPT); 444 sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
476 break; 445 break;
477 case MMC_BUS_WIDTH_4: 446 case MMC_BUS_WIDTH_4:
478 tmio_iowrite16(0x00e0, ctl + CTL_SD_MEM_CARD_OPT); 447 sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0);
479 break; 448 break;
480 } 449 }
481 450
@@ -486,9 +455,8 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
486static int tmio_mmc_get_ro(struct mmc_host *mmc) 455static int tmio_mmc_get_ro(struct mmc_host *mmc)
487{ 456{
488 struct tmio_mmc_host *host = mmc_priv(mmc); 457 struct tmio_mmc_host *host = mmc_priv(mmc);
489 void __iomem *ctl = host->ctl;
490 458
491 return (tmio_ioread16(ctl + CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1; 459 return (sd_ctrl_read16(host, CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1;
492} 460}
493 461
494static struct mmc_host_ops tmio_mmc_ops = { 462static struct mmc_host_ops tmio_mmc_ops = {
@@ -518,13 +486,8 @@ static int tmio_mmc_resume(struct platform_device *dev)
518 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 486 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
519 struct mmc_host *mmc = platform_get_drvdata(dev); 487 struct mmc_host *mmc = platform_get_drvdata(dev);
520 struct tmio_mmc_host *host = mmc_priv(mmc); 488 struct tmio_mmc_host *host = mmc_priv(mmc);
521 void __iomem *cnf = host->cnf;
522 int ret = 0; 489 int ret = 0;
523 490
524 /* Enable the MMC/SD Control registers */
525 tmio_iowrite16(SDCREN, cnf + CNF_CMD);
526 tmio_iowrite32(dev->resource[0].start & 0xfffe, cnf + CNF_CTL_BASE);
527
528 /* Tell the MFD core we are ready to be enabled */ 491 /* Tell the MFD core we are ready to be enabled */
529 if (cell->enable) { 492 if (cell->enable) {
530 ret = cell->enable(dev); 493 ret = cell->enable(dev);
@@ -532,6 +495,11 @@ static int tmio_mmc_resume(struct platform_device *dev)
532 goto out; 495 goto out;
533 } 496 }
534 497
498 /* Enable the MMC/SD Control registers */
499 sd_config_write16(host, CNF_CMD, SDCREN);
500 sd_config_write32(host, CNF_CTL_BASE,
501 (dev->resource[0].start >> host->bus_shift) & 0xfffe);
502
535 mmc_resume_host(mmc); 503 mmc_resume_host(mmc);
536 504
537out: 505out:
@@ -545,20 +513,25 @@ out:
545static int __devinit tmio_mmc_probe(struct platform_device *dev) 513static int __devinit tmio_mmc_probe(struct platform_device *dev)
546{ 514{
547 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 515 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
516 struct tmio_mmc_data *pdata;
548 struct resource *res_ctl, *res_cnf; 517 struct resource *res_ctl, *res_cnf;
549 struct tmio_mmc_host *host; 518 struct tmio_mmc_host *host;
550 struct mmc_host *mmc; 519 struct mmc_host *mmc;
551 int ret = -ENOMEM; 520 int ret = -EINVAL;
552 521
553 if (dev->num_resources != 3) 522 if (dev->num_resources != 3)
554 goto out; 523 goto out;
555 524
556 res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); 525 res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0);
557 res_cnf = platform_get_resource(dev, IORESOURCE_MEM, 1); 526 res_cnf = platform_get_resource(dev, IORESOURCE_MEM, 1);
558 if (!res_ctl || !res_cnf) { 527 if (!res_ctl || !res_cnf)
559 ret = -EINVAL;
560 goto out; 528 goto out;
561 } 529
530 pdata = cell->driver_data;
531 if (!pdata || !pdata->hclk)
532 goto out;
533
534 ret = -ENOMEM;
562 535
563 mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev); 536 mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev);
564 if (!mmc) 537 if (!mmc)
@@ -568,6 +541,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
568 host->mmc = mmc; 541 host->mmc = mmc;
569 platform_set_drvdata(dev, mmc); 542 platform_set_drvdata(dev, mmc);
570 543
544 /* SD control register space size is 0x200, 0x400 for bus_shift=1 */
545 host->bus_shift = resource_size(res_ctl) >> 10;
546
571 host->ctl = ioremap(res_ctl->start, resource_size(res_ctl)); 547 host->ctl = ioremap(res_ctl->start, resource_size(res_ctl));
572 if (!host->ctl) 548 if (!host->ctl)
573 goto host_free; 549 goto host_free;
@@ -578,15 +554,10 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
578 554
579 mmc->ops = &tmio_mmc_ops; 555 mmc->ops = &tmio_mmc_ops;
580 mmc->caps = MMC_CAP_4_BIT_DATA; 556 mmc->caps = MMC_CAP_4_BIT_DATA;
581 mmc->f_min = 46875; /* 24000000 / 512 */ 557 mmc->f_max = pdata->hclk;
582 mmc->f_max = 24000000; 558 mmc->f_min = mmc->f_max / 512;
583 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 559 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
584 560
585 /* Enable the MMC/SD Control registers */
586 tmio_iowrite16(SDCREN, host->cnf + CNF_CMD);
587 tmio_iowrite32(dev->resource[0].start & 0xfffe,
588 host->cnf + CNF_CTL_BASE);
589
590 /* Tell the MFD core we are ready to be enabled */ 561 /* Tell the MFD core we are ready to be enabled */
591 if (cell->enable) { 562 if (cell->enable) {
592 ret = cell->enable(dev); 563 ret = cell->enable(dev);
@@ -594,14 +565,19 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
594 goto unmap_cnf; 565 goto unmap_cnf;
595 } 566 }
596 567
568 /* Enable the MMC/SD Control registers */
569 sd_config_write16(host, CNF_CMD, SDCREN);
570 sd_config_write32(host, CNF_CTL_BASE,
571 (dev->resource[0].start >> host->bus_shift) & 0xfffe);
572
597 /* Disable SD power during suspend */ 573 /* Disable SD power during suspend */
598 tmio_iowrite8(0x01, host->cnf + CNF_PWR_CTL_3); 574 sd_config_write8(host, CNF_PWR_CTL_3, 0x01);
599 575
600 /* The below is required but why? FIXME */ 576 /* The below is required but why? FIXME */
601 tmio_iowrite8(0x1f, host->cnf + CNF_STOP_CLK_CTL); 577 sd_config_write8(host, CNF_STOP_CLK_CTL, 0x1f);
602 578
603 /* Power down SD bus*/ 579 /* Power down SD bus*/
604 tmio_iowrite8(0x0, host->cnf + CNF_PWR_CTL_2); 580 sd_config_write8(host, CNF_PWR_CTL_2, 0x00);
605 581
606 tmio_mmc_clk_stop(host); 582 tmio_mmc_clk_stop(host);
607 reset(host); 583 reset(host);
@@ -612,22 +588,20 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
612 else 588 else
613 goto unmap_cnf; 589 goto unmap_cnf;
614 590
615 disable_mmc_irqs(host->ctl, TMIO_MASK_ALL); 591 disable_mmc_irqs(host, TMIO_MASK_ALL);
616 592
617 ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED, "tmio-mmc", 593 ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED |
618 host); 594 IRQF_TRIGGER_FALLING, "tmio-mmc", host);
619 if (ret) 595 if (ret)
620 goto unmap_cnf; 596 goto unmap_cnf;
621 597
622 set_irq_type(host->irq, IRQ_TYPE_EDGE_FALLING);
623
624 mmc_add_host(mmc); 598 mmc_add_host(mmc);
625 599
626 printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), 600 printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
627 (unsigned long)host->ctl, host->irq); 601 (unsigned long)host->ctl, host->irq);
628 602
629 /* Unmask the IRQs we want to know about */ 603 /* Unmask the IRQs we want to know about */
630 enable_mmc_irqs(host->ctl, TMIO_MASK_IRQ); 604 enable_mmc_irqs(host, TMIO_MASK_IRQ);
631 605
632 return 0; 606 return 0;
633 607
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 9c831ab2ece6..9fa998594974 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -83,34 +83,36 @@
83 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) 83 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
84#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) 84#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
85 85
86#define enable_mmc_irqs(ctl, i) \ 86
87#define enable_mmc_irqs(host, i) \
87 do { \ 88 do { \
88 u32 mask;\ 89 u32 mask;\
89 mask = tmio_ioread32((ctl) + CTL_IRQ_MASK); \ 90 mask = sd_ctrl_read32((host), CTL_IRQ_MASK); \
90 mask &= ~((i) & TMIO_MASK_IRQ); \ 91 mask &= ~((i) & TMIO_MASK_IRQ); \
91 tmio_iowrite32(mask, (ctl) + CTL_IRQ_MASK); \ 92 sd_ctrl_write32((host), CTL_IRQ_MASK, mask); \
92 } while (0) 93 } while (0)
93 94
94#define disable_mmc_irqs(ctl, i) \ 95#define disable_mmc_irqs(host, i) \
95 do { \ 96 do { \
96 u32 mask;\ 97 u32 mask;\
97 mask = tmio_ioread32((ctl) + CTL_IRQ_MASK); \ 98 mask = sd_ctrl_read32((host), CTL_IRQ_MASK); \
98 mask |= ((i) & TMIO_MASK_IRQ); \ 99 mask |= ((i) & TMIO_MASK_IRQ); \
99 tmio_iowrite32(mask, (ctl) + CTL_IRQ_MASK); \ 100 sd_ctrl_write32((host), CTL_IRQ_MASK, mask); \
100 } while (0) 101 } while (0)
101 102
102#define ack_mmc_irqs(ctl, i) \ 103#define ack_mmc_irqs(host, i) \
103 do { \ 104 do { \
104 u32 mask;\ 105 u32 mask;\
105 mask = tmio_ioread32((ctl) + CTL_STATUS); \ 106 mask = sd_ctrl_read32((host), CTL_STATUS); \
106 mask &= ~((i) & TMIO_MASK_IRQ); \ 107 mask &= ~((i) & TMIO_MASK_IRQ); \
107 tmio_iowrite32(mask, (ctl) + CTL_STATUS); \ 108 sd_ctrl_write32((host), CTL_STATUS, mask); \
108 } while (0) 109 } while (0)
109 110
110 111
111struct tmio_mmc_host { 112struct tmio_mmc_host {
112 void __iomem *cnf; 113 void __iomem *cnf;
113 void __iomem *ctl; 114 void __iomem *ctl;
115 unsigned long bus_shift;
114 struct mmc_command *cmd; 116 struct mmc_command *cmd;
115 struct mmc_request *mrq; 117 struct mmc_request *mrq;
116 struct mmc_data *data; 118 struct mmc_data *data;
@@ -123,6 +125,63 @@ struct tmio_mmc_host {
123 unsigned int sg_off; 125 unsigned int sg_off;
124}; 126};
125 127
128#include <linux/io.h>
129
130static inline u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr)
131{
132 return readw(host->ctl + (addr << host->bus_shift));
133}
134
135static inline void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr,
136 u16 *buf, int count)
137{
138 readsw(host->ctl + (addr << host->bus_shift), buf, count);
139}
140
141static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr)
142{
143 return readw(host->ctl + (addr << host->bus_shift)) |
144 readw(host->ctl + ((addr + 2) << host->bus_shift)) << 16;
145}
146
147static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr,
148 u16 val)
149{
150 writew(val, host->ctl + (addr << host->bus_shift));
151}
152
153static inline void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr,
154 u16 *buf, int count)
155{
156 writesw(host->ctl + (addr << host->bus_shift), buf, count);
157}
158
159static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr,
160 u32 val)
161{
162 writew(val, host->ctl + (addr << host->bus_shift));
163 writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift));
164}
165
166static inline void sd_config_write8(struct tmio_mmc_host *host, int addr,
167 u8 val)
168{
169 writeb(val, host->cnf + (addr << host->bus_shift));
170}
171
172static inline void sd_config_write16(struct tmio_mmc_host *host, int addr,
173 u16 val)
174{
175 writew(val, host->cnf + (addr << host->bus_shift));
176}
177
178static inline void sd_config_write32(struct tmio_mmc_host *host, int addr,
179 u32 val)
180{
181 writew(val, host->cnf + (addr << host->bus_shift));
182 writew(val >> 16, host->cnf + ((addr + 2) << host->bus_shift));
183}
184
126#include <linux/scatterlist.h> 185#include <linux/scatterlist.h>
127#include <linux/blkdev.h> 186#include <linux/blkdev.h>
128 187
diff --git a/include/linux/cb710.h b/include/linux/cb710.h
new file mode 100644
index 000000000000..63bc9a4d2926
--- /dev/null
+++ b/include/linux/cb710.h
@@ -0,0 +1,231 @@
1/*
2 * cb710/cb710.h
3 *
4 * Copyright by Michał Mirosław, 2008-2009
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef LINUX_CB710_DRIVER_H
11#define LINUX_CB710_DRIVER_H
12
13#include <linux/io.h>
14#include <linux/interrupt.h>
15#include <linux/spinlock.h>
16#include <linux/pci.h>
17#include <linux/platform_device.h>
18#include <linux/mmc/host.h>
19
20struct cb710_slot;
21
22typedef int (*cb710_irq_handler_t)(struct cb710_slot *);
23
24/* per-virtual-slot structure */
25struct cb710_slot {
26 struct platform_device pdev;
27 void __iomem *iobase;
28 cb710_irq_handler_t irq_handler;
29};
30
31/* per-device structure */
32struct cb710_chip {
33 struct pci_dev *pdev;
34 void __iomem *iobase;
35 unsigned platform_id;
36#ifdef CONFIG_CB710_DEBUG_ASSUMPTIONS
37 atomic_t slot_refs_count;
38#endif
39 unsigned slot_mask;
40 unsigned slots;
41 spinlock_t irq_lock;
42 struct cb710_slot slot[0];
43};
44
45/* NOTE: cb710_chip.slots is modified only during device init/exit and
46 * they are all serialized wrt themselves */
47
48/* cb710_chip.slot_mask values */
49#define CB710_SLOT_MMC 1
50#define CB710_SLOT_MS 2
51#define CB710_SLOT_SM 4
52
53/* slot port accessors - so the logic is more clear in the code */
54#define CB710_PORT_ACCESSORS(t) \
55static inline void cb710_write_port_##t(struct cb710_slot *slot, \
56 unsigned port, u##t value) \
57{ \
58 iowrite##t(value, slot->iobase + port); \
59} \
60 \
61static inline u##t cb710_read_port_##t(struct cb710_slot *slot, \
62 unsigned port) \
63{ \
64 return ioread##t(slot->iobase + port); \
65} \
66 \
67static inline void cb710_modify_port_##t(struct cb710_slot *slot, \
68 unsigned port, u##t set, u##t clear) \
69{ \
70 iowrite##t( \
71 (ioread##t(slot->iobase + port) & ~clear)|set, \
72 slot->iobase + port); \
73}
74
75CB710_PORT_ACCESSORS(8)
76CB710_PORT_ACCESSORS(16)
77CB710_PORT_ACCESSORS(32)
78
79void cb710_pci_update_config_reg(struct pci_dev *pdev,
80 int reg, uint32_t and, uint32_t xor);
81void cb710_set_irq_handler(struct cb710_slot *slot,
82 cb710_irq_handler_t handler);
83
84/* some device struct walking */
85
86static inline struct cb710_slot *cb710_pdev_to_slot(
87 struct platform_device *pdev)
88{
89 return container_of(pdev, struct cb710_slot, pdev);
90}
91
92static inline struct cb710_chip *cb710_slot_to_chip(struct cb710_slot *slot)
93{
94 return dev_get_drvdata(slot->pdev.dev.parent);
95}
96
97static inline struct device *cb710_slot_dev(struct cb710_slot *slot)
98{
99 return &slot->pdev.dev;
100}
101
102static inline struct device *cb710_chip_dev(struct cb710_chip *chip)
103{
104 return &chip->pdev->dev;
105}
106
107/* debugging aids */
108
109#ifdef CONFIG_CB710_DEBUG
110void cb710_dump_regs(struct cb710_chip *chip, unsigned dump);
111#else
112#define cb710_dump_regs(c, d) do {} while (0)
113#endif
114
115#define CB710_DUMP_REGS_MMC 0x0F
116#define CB710_DUMP_REGS_MS 0x30
117#define CB710_DUMP_REGS_SM 0xC0
118#define CB710_DUMP_REGS_ALL 0xFF
119#define CB710_DUMP_REGS_MASK 0xFF
120
121#define CB710_DUMP_ACCESS_8 0x100
122#define CB710_DUMP_ACCESS_16 0x200
123#define CB710_DUMP_ACCESS_32 0x400
124#define CB710_DUMP_ACCESS_ALL 0x700
125#define CB710_DUMP_ACCESS_MASK 0x700
126
127#endif /* LINUX_CB710_DRIVER_H */
128/*
129 * cb710/sgbuf2.h
130 *
131 * Copyright by Michał Mirosław, 2008-2009
132 *
133 * This program is free software; you can redistribute it and/or modify
134 * it under the terms of the GNU General Public License version 2 as
135 * published by the Free Software Foundation.
136 */
137#ifndef LINUX_CB710_SG_H
138#define LINUX_CB710_SG_H
139
140#include <linux/highmem.h>
141#include <linux/scatterlist.h>
142
143/**
144 * cb710_sg_miter_stop_writing - stop mapping iteration after writing
145 * @miter: sg mapping iter to be stopped
146 *
147 * Description:
148 * Stops mapping iterator @miter. @miter should have been started
149 * started using sg_miter_start(). A stopped iteration can be
150 * resumed by calling sg_miter_next() on it. This is useful when
151 * resources (kmap) need to be released during iteration.
152 *
153 * This is a convenience wrapper that will be optimized out for arches
154 * that don't need flush_kernel_dcache_page().
155 *
156 * Context:
157 * IRQ disabled if the SG_MITER_ATOMIC is set. Don't care otherwise.
158 */
159static inline void cb710_sg_miter_stop_writing(struct sg_mapping_iter *miter)
160{
161 if (miter->page)
162 flush_kernel_dcache_page(miter->page);
163 sg_miter_stop(miter);
164}
165
166/*
167 * 32-bit PIO mapping sg iterator
168 *
169 * Hides scatterlist access issues - fragment boundaries, alignment, page
170 * mapping - for drivers using 32-bit-word-at-a-time-PIO (ie. PCI devices
171 * without DMA support).
172 *
173 * Best-case reading (transfer from device):
174 * sg_miter_start();
175 * cb710_sg_dwiter_write_from_io();
176 * cb710_sg_miter_stop_writing();
177 *
178 * Best-case writing (transfer to device):
179 * sg_miter_start();
180 * cb710_sg_dwiter_read_to_io();
181 * sg_miter_stop();
182 */
183
184uint32_t cb710_sg_dwiter_read_next_block(struct sg_mapping_iter *miter);
185void cb710_sg_dwiter_write_next_block(struct sg_mapping_iter *miter, uint32_t data);
186
187/**
188 * cb710_sg_dwiter_write_from_io - transfer data to mapped buffer from 32-bit IO port
189 * @miter: sg mapping iter
190 * @port: PIO port - IO or MMIO address
191 * @count: number of 32-bit words to transfer
192 *
193 * Description:
194 * Reads @count 32-bit words from register @port and stores it in
195 * buffer iterated by @miter. Data that would overflow the buffer
196 * is silently ignored. Iterator is advanced by 4*@count bytes
197 * or to the buffer's end whichever is closer.
198 *
199 * Context:
200 * IRQ disabled if the SG_MITER_ATOMIC is set. Don't care otherwise.
201 */
202static inline void cb710_sg_dwiter_write_from_io(struct sg_mapping_iter *miter,
203 void __iomem *port, size_t count)
204{
205 while (count-- > 0)
206 cb710_sg_dwiter_write_next_block(miter, ioread32(port));
207}
208
209/**
210 * cb710_sg_dwiter_read_to_io - transfer data to 32-bit IO port from mapped buffer
211 * @miter: sg mapping iter
212 * @port: PIO port - IO or MMIO address
213 * @count: number of 32-bit words to transfer
214 *
215 * Description:
216 * Writes @count 32-bit words to register @port from buffer iterated
217 * through @miter. If buffer ends before @count words are written
218 * missing data is replaced by zeroes. @miter is advanced by 4*@count
219 * bytes or to the buffer's end whichever is closer.
220 *
221 * Context:
222 * IRQ disabled if the SG_MITER_ATOMIC is set. Don't care otherwise.
223 */
224static inline void cb710_sg_dwiter_read_to_io(struct sg_mapping_iter *miter,
225 void __iomem *port, size_t count)
226{
227 while (count-- > 0)
228 iowrite32(cb710_sg_dwiter_read_next_block(miter), port);
229}
230
231#endif /* LINUX_CB710_SG_H */
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index 516d955ab8a1..c377118884e6 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -19,6 +19,13 @@
19 } while (0) 19 } while (0)
20 20
21/* 21/*
22 * data for the MMC controller
23 */
24struct tmio_mmc_data {
25 unsigned int hclk;
26};
27
28/*
22 * data for the NAND controller 29 * data for the NAND controller
23 */ 30 */
24struct tmio_nand_data { 31struct tmio_nand_data {
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 19f8e6d1a4d2..9f36e1cdbf01 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2127,6 +2127,7 @@
2127#define PCI_VENDOR_ID_MAINPINE 0x1522 2127#define PCI_VENDOR_ID_MAINPINE 0x1522
2128#define PCI_DEVICE_ID_MAINPINE_PBRIDGE 0x0100 2128#define PCI_DEVICE_ID_MAINPINE_PBRIDGE 0x0100
2129#define PCI_VENDOR_ID_ENE 0x1524 2129#define PCI_VENDOR_ID_ENE 0x1524
2130#define PCI_DEVICE_ID_ENE_CB710_FLASH 0x0510
2130#define PCI_DEVICE_ID_ENE_CB712_SD 0x0550 2131#define PCI_DEVICE_ID_ENE_CB712_SD 0x0550
2131#define PCI_DEVICE_ID_ENE_CB712_SD_2 0x0551 2132#define PCI_DEVICE_ID_ENE_CB712_SD_2 0x0551
2132#define PCI_DEVICE_ID_ENE_CB714_SD 0x0750 2133#define PCI_DEVICE_ID_ENE_CB714_SD 0x0750