diff options
Diffstat (limited to 'drivers/mmc/host')
29 files changed, 3218 insertions, 786 deletions
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 432ae8358c86..2e13b94769fd 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -44,6 +44,19 @@ config MMC_SDHCI_IO_ACCESSORS | |||
44 | This is silent Kconfig symbol that is selected by the drivers that | 44 | This is silent Kconfig symbol that is selected by the drivers that |
45 | need to overwrite SDHCI IO memory accessors. | 45 | need to overwrite SDHCI IO memory accessors. |
46 | 46 | ||
47 | config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER | ||
48 | bool | ||
49 | select MMC_SDHCI_IO_ACCESSORS | ||
50 | help | ||
51 | This option is selected by drivers running on big endian hosts | ||
52 | and performing I/O to a SDHCI controller through a bus that | ||
53 | implements a hardware byte swapper using a 32-bit datum. | ||
54 | This endian mapping mode is called "data invariance" and | ||
55 | has the effect of scrambling the addresses and formats of data | ||
56 | accessed in sizes other than the datum size. | ||
57 | |||
58 | This is the case for the Freescale eSDHC and Nintendo Wii SDHCI. | ||
59 | |||
47 | config MMC_SDHCI_PCI | 60 | config MMC_SDHCI_PCI |
48 | tristate "SDHCI support on PCI bus" | 61 | tristate "SDHCI support on PCI bus" |
49 | depends on MMC_SDHCI && PCI | 62 | depends on MMC_SDHCI && PCI |
@@ -56,30 +69,44 @@ config MMC_SDHCI_PCI | |||
56 | If unsure, say N. | 69 | If unsure, say N. |
57 | 70 | ||
58 | config MMC_RICOH_MMC | 71 | config MMC_RICOH_MMC |
59 | tristate "Ricoh MMC Controller Disabler (EXPERIMENTAL)" | 72 | bool "Ricoh MMC Controller Disabler (EXPERIMENTAL)" |
60 | depends on MMC_SDHCI_PCI | 73 | depends on MMC_SDHCI_PCI |
61 | help | 74 | help |
62 | This selects the disabler for the Ricoh MMC Controller. This | 75 | This adds a pci quirk to disable Ricoh MMC Controller. This |
63 | proprietary controller is unnecessary because the SDHCI driver | 76 | proprietary controller is unnecessary because the SDHCI driver |
64 | supports MMC cards on the SD controller, but if it is not | 77 | supports MMC cards on the SD controller, but if it is not |
65 | disabled, it will steal the MMC cards away - rendering them | 78 | disabled, it will steal the MMC cards away - rendering them |
66 | useless. It is safe to select this driver even if you don't | 79 | useless. It is safe to select this even if you don't |
67 | have a Ricoh based card reader. | 80 | have a Ricoh based card reader. |
68 | 81 | ||
69 | |||
70 | To compile this driver as a module, choose M here: | ||
71 | the module will be called ricoh_mmc. | ||
72 | |||
73 | If unsure, say Y. | 82 | If unsure, say Y. |
74 | 83 | ||
75 | config MMC_SDHCI_OF | 84 | config MMC_SDHCI_OF |
76 | tristate "SDHCI support on OpenFirmware platforms" | 85 | tristate "SDHCI support on OpenFirmware platforms" |
77 | depends on MMC_SDHCI && PPC_OF | 86 | depends on MMC_SDHCI && PPC_OF |
78 | select MMC_SDHCI_IO_ACCESSORS | ||
79 | help | 87 | help |
80 | This selects the OF support for Secure Digital Host Controller | 88 | This selects the OF support for Secure Digital Host Controller |
81 | Interfaces. So far, only the Freescale eSDHC controller is known | 89 | Interfaces. |
82 | to exist on OF platforms. | 90 | |
91 | If unsure, say N. | ||
92 | |||
93 | config MMC_SDHCI_OF_ESDHC | ||
94 | bool "SDHCI OF support for the Freescale eSDHC controller" | ||
95 | depends on MMC_SDHCI_OF | ||
96 | select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER | ||
97 | help | ||
98 | This selects the Freescale eSDHC controller support. | ||
99 | |||
100 | If unsure, say N. | ||
101 | |||
102 | config MMC_SDHCI_OF_HLWD | ||
103 | bool "SDHCI OF support for the Nintendo Wii SDHCI controllers" | ||
104 | depends on MMC_SDHCI_OF | ||
105 | select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER | ||
106 | help | ||
107 | This selects the Secure Digital Host Controller Interface (SDHCI) | ||
108 | found in the "Hollywood" chipset of the Nintendo Wii video game | ||
109 | console. | ||
83 | 110 | ||
84 | If unsure, say N. | 111 | If unsure, say N. |
85 | 112 | ||
@@ -162,6 +189,7 @@ config MMC_AU1X | |||
162 | 189 | ||
163 | choice | 190 | choice |
164 | prompt "Atmel SD/MMC Driver" | 191 | prompt "Atmel SD/MMC Driver" |
192 | depends on AVR32 || ARCH_AT91 | ||
165 | default MMC_ATMELMCI if AVR32 | 193 | default MMC_ATMELMCI if AVR32 |
166 | help | 194 | help |
167 | Choose which driver to use for the Atmel MCI Silicon | 195 | Choose which driver to use for the Atmel MCI Silicon |
@@ -251,6 +279,14 @@ config MMC_MVSDIO | |||
251 | To compile this driver as a module, choose M here: the | 279 | To compile this driver as a module, choose M here: the |
252 | module will be called mvsdio. | 280 | module will be called mvsdio. |
253 | 281 | ||
282 | config MMC_DAVINCI | ||
283 | tristate "TI DAVINCI Multimedia Card Interface support" | ||
284 | depends on ARCH_DAVINCI | ||
285 | help | ||
286 | This selects the TI DAVINCI Multimedia card Interface. | ||
287 | If you have an DAVINCI board with a Multimedia Card slot, | ||
288 | say Y or M here. If unsure, say N. | ||
289 | |||
254 | config MMC_SPI | 290 | config MMC_SPI |
255 | tristate "MMC/SD/SDIO over SPI" | 291 | tristate "MMC/SD/SDIO over SPI" |
256 | depends on SPI_MASTER && !HIGHMEM && HAS_DMA | 292 | depends on SPI_MASTER && !HIGHMEM && HAS_DMA |
@@ -329,7 +365,7 @@ config MMC_SDRICOH_CS | |||
329 | 365 | ||
330 | config MMC_TMIO | 366 | config MMC_TMIO |
331 | tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" | 367 | tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" |
332 | depends on MFD_TMIO || MFD_ASIC3 | 368 | depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI |
333 | help | 369 | help |
334 | This provides support for the SD/MMC cell found in TC6393XB, | 370 | This provides support for the SD/MMC cell found in TC6393XB, |
335 | T7L66XB and also HTC ASIC3 | 371 | T7L66XB and also HTC ASIC3 |
@@ -357,3 +393,22 @@ config MMC_VIA_SDMMC | |||
357 | If you have a controller with this interface, say Y or M here. | 393 | If you have a controller with this interface, say Y or M here. |
358 | 394 | ||
359 | If unsure, say N. | 395 | If unsure, say N. |
396 | |||
397 | config SDH_BFIN | ||
398 | tristate "Blackfin Secure Digital Host support" | ||
399 | depends on (BF54x && !BF544) || (BF51x && !BF512) | ||
400 | help | ||
401 | If you say yes here you will get support for the Blackfin on-chip | ||
402 | Secure Digital Host interface. This includes support for MMC and | ||
403 | SD cards. | ||
404 | |||
405 | To compile this driver as a module, choose M here: the | ||
406 | module will be called bfin_sdh. | ||
407 | |||
408 | If unsure, say N. | ||
409 | |||
410 | config SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND | ||
411 | bool "Blackfin EZkit Missing SDH_CMD Pull Up Resistor Workaround" | ||
412 | depends on SDH_BFIN | ||
413 | help | ||
414 | If you say yes here SD-Cards may work on the EZkit. | ||
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index abcb0400e06d..f4803977dfce 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -12,8 +12,6 @@ obj-$(CONFIG_MMC_IMX) += imxmmc.o | |||
12 | obj-$(CONFIG_MMC_MXC) += mxcmmc.o | 12 | obj-$(CONFIG_MMC_MXC) += mxcmmc.o |
13 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | 13 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o |
14 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o | 14 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o |
15 | obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o | ||
16 | obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o | ||
17 | obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o | 15 | obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o |
18 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o | 16 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o |
19 | obj-$(CONFIG_MMC_WBSD) += wbsd.o | 17 | obj-$(CONFIG_MMC_WBSD) += wbsd.o |
@@ -25,6 +23,7 @@ obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o | |||
25 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o | 23 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o |
26 | obj-$(CONFIG_MMC_MSM7X00A) += msm_sdcc.o | 24 | obj-$(CONFIG_MMC_MSM7X00A) += msm_sdcc.o |
27 | obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o | 25 | obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o |
26 | obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o | ||
28 | obj-$(CONFIG_MMC_SPI) += mmc_spi.o | 27 | obj-$(CONFIG_MMC_SPI) += mmc_spi.o |
29 | ifeq ($(CONFIG_OF),y) | 28 | ifeq ($(CONFIG_OF),y) |
30 | obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o | 29 | obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o |
@@ -34,6 +33,12 @@ obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o | |||
34 | obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o | 33 | obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o |
35 | obj-$(CONFIG_MMC_CB710) += cb710-mmc.o | 34 | obj-$(CONFIG_MMC_CB710) += cb710-mmc.o |
36 | obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o | 35 | obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o |
36 | obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o | ||
37 | |||
38 | obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o | ||
39 | sdhci-of-y := sdhci-of-core.o | ||
40 | sdhci-of-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o | ||
41 | sdhci-of-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o | ||
37 | 42 | ||
38 | ifeq ($(CONFIG_CB710_DEBUG),y) | 43 | ifeq ($(CONFIG_CB710_DEBUG),y) |
39 | CFLAGS-cb710-mmc += -DDEBUG | 44 | CFLAGS-cb710-mmc += -DDEBUG |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 63924e0c7ea9..336d9f553f3e 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -65,6 +65,7 @@ | |||
65 | #include <linux/dma-mapping.h> | 65 | #include <linux/dma-mapping.h> |
66 | #include <linux/clk.h> | 66 | #include <linux/clk.h> |
67 | #include <linux/atmel_pdc.h> | 67 | #include <linux/atmel_pdc.h> |
68 | #include <linux/gfp.h> | ||
68 | 69 | ||
69 | #include <linux/mmc/host.h> | 70 | #include <linux/mmc/host.h> |
70 | 71 | ||
@@ -78,6 +79,17 @@ | |||
78 | 79 | ||
79 | #define DRIVER_NAME "at91_mci" | 80 | #define DRIVER_NAME "at91_mci" |
80 | 81 | ||
82 | static inline int at91mci_is_mci1rev2xx(void) | ||
83 | { | ||
84 | return ( cpu_is_at91sam9260() | ||
85 | || cpu_is_at91sam9263() | ||
86 | || cpu_is_at91cap9() | ||
87 | || cpu_is_at91sam9rl() | ||
88 | || cpu_is_at91sam9g10() | ||
89 | || cpu_is_at91sam9g20() | ||
90 | ); | ||
91 | } | ||
92 | |||
81 | #define FL_SENT_COMMAND (1 << 0) | 93 | #define FL_SENT_COMMAND (1 << 0) |
82 | #define FL_SENT_STOP (1 << 1) | 94 | #define FL_SENT_STOP (1 << 1) |
83 | 95 | ||
@@ -88,6 +100,10 @@ | |||
88 | #define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) | 100 | #define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) |
89 | #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) | 101 | #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) |
90 | 102 | ||
103 | #define MCI_BLKSIZE 512 | ||
104 | #define MCI_MAXBLKSIZE 4095 | ||
105 | #define MCI_BLKATONCE 256 | ||
106 | #define MCI_BUFSIZE (MCI_BLKSIZE * MCI_BLKATONCE) | ||
91 | 107 | ||
92 | /* | 108 | /* |
93 | * Low level type for this driver | 109 | * Low level type for this driver |
@@ -200,8 +216,8 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
200 | size = data->blksz * data->blocks; | 216 | size = data->blksz * data->blocks; |
201 | len = data->sg_len; | 217 | len = data->sg_len; |
202 | 218 | ||
203 | /* AT91SAM926[0/3] Data Write Operation and number of bytes erratum */ | 219 | /* MCI1 rev2xx Data Write Operation and number of bytes erratum */ |
204 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | 220 | if (at91mci_is_mci1rev2xx()) |
205 | if (host->total_length == 12) | 221 | if (host->total_length == 12) |
206 | memset(dmabuf, 0, 12); | 222 | memset(dmabuf, 0, 12); |
207 | 223 | ||
@@ -227,8 +243,10 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
227 | for (index = 0; index < (amount / 4); index++) | 243 | for (index = 0; index < (amount / 4); index++) |
228 | *dmabuf++ = swab32(sgbuffer[index]); | 244 | *dmabuf++ = swab32(sgbuffer[index]); |
229 | } else { | 245 | } else { |
230 | memcpy(dmabuf, sgbuffer, amount); | 246 | char *tmpv = (char *)dmabuf; |
231 | dmabuf += amount; | 247 | memcpy(tmpv, sgbuffer, amount); |
248 | tmpv += amount; | ||
249 | dmabuf = (unsigned *)tmpv; | ||
232 | } | 250 | } |
233 | 251 | ||
234 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | 252 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); |
@@ -245,80 +263,14 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
245 | } | 263 | } |
246 | 264 | ||
247 | /* | 265 | /* |
248 | * Prepare a dma read | ||
249 | */ | ||
250 | static void at91_mci_pre_dma_read(struct at91mci_host *host) | ||
251 | { | ||
252 | int i; | ||
253 | struct scatterlist *sg; | ||
254 | struct mmc_command *cmd; | ||
255 | struct mmc_data *data; | ||
256 | |||
257 | pr_debug("pre dma read\n"); | ||
258 | |||
259 | cmd = host->cmd; | ||
260 | if (!cmd) { | ||
261 | pr_debug("no command\n"); | ||
262 | return; | ||
263 | } | ||
264 | |||
265 | data = cmd->data; | ||
266 | if (!data) { | ||
267 | pr_debug("no data\n"); | ||
268 | return; | ||
269 | } | ||
270 | |||
271 | for (i = 0; i < 2; i++) { | ||
272 | /* nothing left to transfer */ | ||
273 | if (host->transfer_index >= data->sg_len) { | ||
274 | pr_debug("Nothing left to transfer (index = %d)\n", host->transfer_index); | ||
275 | break; | ||
276 | } | ||
277 | |||
278 | /* Check to see if this needs filling */ | ||
279 | if (i == 0) { | ||
280 | if (at91_mci_read(host, ATMEL_PDC_RCR) != 0) { | ||
281 | pr_debug("Transfer active in current\n"); | ||
282 | continue; | ||
283 | } | ||
284 | } | ||
285 | else { | ||
286 | if (at91_mci_read(host, ATMEL_PDC_RNCR) != 0) { | ||
287 | pr_debug("Transfer active in next\n"); | ||
288 | continue; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | /* Setup the next transfer */ | ||
293 | pr_debug("Using transfer index %d\n", host->transfer_index); | ||
294 | |||
295 | sg = &data->sg[host->transfer_index++]; | ||
296 | pr_debug("sg = %p\n", sg); | ||
297 | |||
298 | sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE); | ||
299 | |||
300 | pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length); | ||
301 | |||
302 | if (i == 0) { | ||
303 | at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address); | ||
304 | at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4); | ||
305 | } | ||
306 | else { | ||
307 | at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address); | ||
308 | at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | pr_debug("pre dma read done\n"); | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * Handle after a dma read | 266 | * Handle after a dma read |
317 | */ | 267 | */ |
318 | static void at91_mci_post_dma_read(struct at91mci_host *host) | 268 | static void at91_mci_post_dma_read(struct at91mci_host *host) |
319 | { | 269 | { |
320 | struct mmc_command *cmd; | 270 | struct mmc_command *cmd; |
321 | struct mmc_data *data; | 271 | struct mmc_data *data; |
272 | unsigned int len, i, size; | ||
273 | unsigned *dmabuf = host->buffer; | ||
322 | 274 | ||
323 | pr_debug("post dma read\n"); | 275 | pr_debug("post dma read\n"); |
324 | 276 | ||
@@ -334,42 +286,39 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) | |||
334 | return; | 286 | return; |
335 | } | 287 | } |
336 | 288 | ||
337 | while (host->in_use_index < host->transfer_index) { | 289 | size = data->blksz * data->blocks; |
338 | struct scatterlist *sg; | 290 | len = data->sg_len; |
339 | 291 | ||
340 | pr_debug("finishing index %d\n", host->in_use_index); | 292 | at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX); |
293 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); | ||
341 | 294 | ||
342 | sg = &data->sg[host->in_use_index++]; | 295 | for (i = 0; i < len; i++) { |
296 | struct scatterlist *sg; | ||
297 | int amount; | ||
298 | unsigned int *sgbuffer; | ||
343 | 299 | ||
344 | pr_debug("Unmapping page %08X\n", sg->dma_address); | 300 | sg = &data->sg[i]; |
345 | 301 | ||
346 | dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE); | 302 | sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; |
303 | amount = min(size, sg->length); | ||
304 | size -= amount; | ||
347 | 305 | ||
348 | if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ | 306 | if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ |
349 | unsigned int *buffer; | ||
350 | int index; | 307 | int index; |
351 | 308 | for (index = 0; index < (amount / 4); index++) | |
352 | /* Swap the contents of the buffer */ | 309 | sgbuffer[index] = swab32(*dmabuf++); |
353 | buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 310 | } else { |
354 | pr_debug("buffer = %p, length = %d\n", buffer, sg->length); | 311 | char *tmpv = (char *)dmabuf; |
355 | 312 | memcpy(sgbuffer, tmpv, amount); | |
356 | for (index = 0; index < (sg->length / 4); index++) | 313 | tmpv += amount; |
357 | buffer[index] = swab32(buffer[index]); | 314 | dmabuf = (unsigned *)tmpv; |
358 | |||
359 | kunmap_atomic(buffer, KM_BIO_SRC_IRQ); | ||
360 | } | 315 | } |
361 | 316 | ||
362 | flush_dcache_page(sg_page(sg)); | 317 | flush_kernel_dcache_page(sg_page(sg)); |
363 | 318 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | |
364 | data->bytes_xfered += sg->length; | 319 | data->bytes_xfered += amount; |
365 | } | 320 | if (size == 0) |
366 | 321 | break; | |
367 | /* Is there another transfer to trigger? */ | ||
368 | if (host->transfer_index < data->sg_len) | ||
369 | at91_mci_pre_dma_read(host); | ||
370 | else { | ||
371 | at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX); | ||
372 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); | ||
373 | } | 322 | } |
374 | 323 | ||
375 | pr_debug("post dma read done\n"); | 324 | pr_debug("post dma read done\n"); |
@@ -461,7 +410,7 @@ static void at91_mci_enable(struct at91mci_host *host) | |||
461 | at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); | 410 | at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); |
462 | mr = AT91_MCI_PDCMODE | 0x34a; | 411 | mr = AT91_MCI_PDCMODE | 0x34a; |
463 | 412 | ||
464 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | 413 | if (at91mci_is_mci1rev2xx()) |
465 | mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF; | 414 | mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF; |
466 | 415 | ||
467 | at91_mci_write(host, AT91_MCI_MR, mr); | 416 | at91_mci_write(host, AT91_MCI_MR, mr); |
@@ -602,10 +551,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command | |||
602 | /* | 551 | /* |
603 | * Handle a read | 552 | * Handle a read |
604 | */ | 553 | */ |
605 | host->buffer = NULL; | ||
606 | host->total_length = 0; | 554 | host->total_length = 0; |
607 | 555 | ||
608 | at91_mci_pre_dma_read(host); | 556 | at91_mci_write(host, ATMEL_PDC_RPR, host->physical_address); |
557 | at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? | ||
558 | (blocks * block_length) : (blocks * block_length) / 4); | ||
559 | at91_mci_write(host, ATMEL_PDC_RNPR, 0); | ||
560 | at91_mci_write(host, ATMEL_PDC_RNCR, 0); | ||
561 | |||
609 | ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; | 562 | ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; |
610 | } | 563 | } |
611 | else { | 564 | else { |
@@ -614,27 +567,15 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command | |||
614 | */ | 567 | */ |
615 | host->total_length = block_length * blocks; | 568 | host->total_length = block_length * blocks; |
616 | /* | 569 | /* |
617 | * AT91SAM926[0/3] Data Write Operation and | 570 | * MCI1 rev2xx Data Write Operation and |
618 | * number of bytes erratum | 571 | * number of bytes erratum |
619 | */ | 572 | */ |
620 | if (cpu_is_at91sam9260 () || cpu_is_at91sam9263()) | 573 | if (at91mci_is_mci1rev2xx()) |
621 | if (host->total_length < 12) | 574 | if (host->total_length < 12) |
622 | host->total_length = 12; | 575 | host->total_length = 12; |
623 | 576 | ||
624 | host->buffer = kmalloc(host->total_length, GFP_KERNEL); | ||
625 | if (!host->buffer) { | ||
626 | pr_debug("Can't alloc tx buffer\n"); | ||
627 | cmd->error = -ENOMEM; | ||
628 | mmc_request_done(host->mmc, host->request); | ||
629 | return; | ||
630 | } | ||
631 | |||
632 | at91_mci_sg_to_dma(host, data); | 577 | at91_mci_sg_to_dma(host, data); |
633 | 578 | ||
634 | host->physical_address = dma_map_single(NULL, | ||
635 | host->buffer, host->total_length, | ||
636 | DMA_TO_DEVICE); | ||
637 | |||
638 | pr_debug("Transmitting %d bytes\n", host->total_length); | 579 | pr_debug("Transmitting %d bytes\n", host->total_length); |
639 | 580 | ||
640 | at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); | 581 | at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); |
@@ -701,14 +642,6 @@ static void at91_mci_completed_command(struct at91mci_host *host, unsigned int s | |||
701 | cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2)); | 642 | cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2)); |
702 | cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3)); | 643 | cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3)); |
703 | 644 | ||
704 | if (host->buffer) { | ||
705 | dma_unmap_single(NULL, | ||
706 | host->physical_address, host->total_length, | ||
707 | DMA_TO_DEVICE); | ||
708 | kfree(host->buffer); | ||
709 | host->buffer = NULL; | ||
710 | } | ||
711 | |||
712 | pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n", | 645 | pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n", |
713 | status, at91_mci_read(host, AT91_MCI_SR), | 646 | status, at91_mci_read(host, AT91_MCI_SR), |
714 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | 647 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); |
@@ -754,7 +687,8 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
754 | host->request = mrq; | 687 | host->request = mrq; |
755 | host->flags = 0; | 688 | host->flags = 0; |
756 | 689 | ||
757 | mod_timer(&host->timer, jiffies + HZ); | 690 | /* more than 1s timeout needed with slow SD cards */ |
691 | mod_timer(&host->timer, jiffies + msecs_to_jiffies(2000)); | ||
758 | 692 | ||
759 | at91_mci_process_next(host); | 693 | at91_mci_process_next(host); |
760 | } | 694 | } |
@@ -942,7 +876,8 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host) | |||
942 | pr_debug("****** Resetting SD-card bus width ******\n"); | 876 | pr_debug("****** Resetting SD-card bus width ******\n"); |
943 | at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); | 877 | at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); |
944 | } | 878 | } |
945 | mmc_detect_change(host->mmc, msecs_to_jiffies(100)); | 879 | /* 0.5s needed because of early card detect switch firing */ |
880 | mmc_detect_change(host->mmc, msecs_to_jiffies(500)); | ||
946 | } | 881 | } |
947 | return IRQ_HANDLED; | 882 | return IRQ_HANDLED; |
948 | } | 883 | } |
@@ -1006,24 +941,42 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
1006 | mmc->f_min = 375000; | 941 | mmc->f_min = 375000; |
1007 | mmc->f_max = 25000000; | 942 | mmc->f_max = 25000000; |
1008 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 943 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
1009 | mmc->caps = MMC_CAP_SDIO_IRQ; | 944 | mmc->caps = 0; |
1010 | 945 | ||
1011 | mmc->max_blk_size = 4095; | 946 | mmc->max_blk_size = MCI_MAXBLKSIZE; |
1012 | mmc->max_blk_count = mmc->max_req_size; | 947 | mmc->max_blk_count = MCI_BLKATONCE; |
948 | mmc->max_req_size = MCI_BUFSIZE; | ||
949 | mmc->max_phys_segs = MCI_BLKATONCE; | ||
950 | mmc->max_hw_segs = MCI_BLKATONCE; | ||
951 | mmc->max_seg_size = MCI_BUFSIZE; | ||
1013 | 952 | ||
1014 | host = mmc_priv(mmc); | 953 | host = mmc_priv(mmc); |
1015 | host->mmc = mmc; | 954 | host->mmc = mmc; |
1016 | host->buffer = NULL; | ||
1017 | host->bus_mode = 0; | 955 | host->bus_mode = 0; |
1018 | host->board = pdev->dev.platform_data; | 956 | host->board = pdev->dev.platform_data; |
1019 | if (host->board->wire4) { | 957 | if (host->board->wire4) { |
1020 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | 958 | if (at91mci_is_mci1rev2xx()) |
1021 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 959 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
1022 | else | 960 | else |
1023 | dev_warn(&pdev->dev, "4 wire bus mode not supported" | 961 | dev_warn(&pdev->dev, "4 wire bus mode not supported" |
1024 | " - using 1 wire\n"); | 962 | " - using 1 wire\n"); |
1025 | } | 963 | } |
1026 | 964 | ||
965 | host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE, | ||
966 | &host->physical_address, GFP_KERNEL); | ||
967 | if (!host->buffer) { | ||
968 | ret = -ENOMEM; | ||
969 | dev_err(&pdev->dev, "Can't allocate transmit buffer\n"); | ||
970 | goto fail5; | ||
971 | } | ||
972 | |||
973 | /* Add SDIO capability when available */ | ||
974 | if (at91mci_is_mci1rev2xx()) { | ||
975 | /* at91mci MCI1 rev2xx sdio interrupt erratum */ | ||
976 | if (host->board->wire4 || !host->board->slot_b) | ||
977 | mmc->caps |= MMC_CAP_SDIO_IRQ; | ||
978 | } | ||
979 | |||
1027 | /* | 980 | /* |
1028 | * Reserve GPIOs ... board init code makes sure these pins are set | 981 | * Reserve GPIOs ... board init code makes sure these pins are set |
1029 | * up as GPIOs with the right direction (input, except for vcc) | 982 | * up as GPIOs with the right direction (input, except for vcc) |
@@ -1032,7 +985,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
1032 | ret = gpio_request(host->board->det_pin, "mmc_detect"); | 985 | ret = gpio_request(host->board->det_pin, "mmc_detect"); |
1033 | if (ret < 0) { | 986 | if (ret < 0) { |
1034 | dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); | 987 | dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); |
1035 | goto fail5; | 988 | goto fail4b; |
1036 | } | 989 | } |
1037 | } | 990 | } |
1038 | if (host->board->wp_pin) { | 991 | if (host->board->wp_pin) { |
@@ -1132,6 +1085,10 @@ fail3: | |||
1132 | fail4: | 1085 | fail4: |
1133 | if (host->board->det_pin) | 1086 | if (host->board->det_pin) |
1134 | gpio_free(host->board->det_pin); | 1087 | gpio_free(host->board->det_pin); |
1088 | fail4b: | ||
1089 | if (host->buffer) | ||
1090 | dma_free_coherent(&pdev->dev, MCI_BUFSIZE, | ||
1091 | host->buffer, host->physical_address); | ||
1135 | fail5: | 1092 | fail5: |
1136 | mmc_free_host(mmc); | 1093 | mmc_free_host(mmc); |
1137 | fail6: | 1094 | fail6: |
@@ -1154,6 +1111,10 @@ static int __exit at91_mci_remove(struct platform_device *pdev) | |||
1154 | 1111 | ||
1155 | host = mmc_priv(mmc); | 1112 | host = mmc_priv(mmc); |
1156 | 1113 | ||
1114 | if (host->buffer) | ||
1115 | dma_free_coherent(&pdev->dev, MCI_BUFSIZE, | ||
1116 | host->buffer, host->physical_address); | ||
1117 | |||
1157 | if (host->board->det_pin) { | 1118 | if (host->board->det_pin) { |
1158 | if (device_can_wakeup(&pdev->dev)) | 1119 | if (device_can_wakeup(&pdev->dev)) |
1159 | free_irq(gpio_to_irq(host->board->det_pin), host); | 1120 | free_irq(gpio_to_irq(host->board->det_pin), host); |
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index fc25586b7ee1..fb279f4ed8b3 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -22,9 +22,12 @@ | |||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/scatterlist.h> | 23 | #include <linux/scatterlist.h> |
24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
25 | #include <linux/slab.h> | ||
25 | #include <linux/stat.h> | 26 | #include <linux/stat.h> |
26 | 27 | ||
27 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
29 | |||
30 | #include <mach/atmel-mci.h> | ||
28 | #include <linux/atmel-mci.h> | 31 | #include <linux/atmel-mci.h> |
29 | 32 | ||
30 | #include <asm/io.h> | 33 | #include <asm/io.h> |
@@ -92,6 +95,7 @@ struct atmel_mci_dma { | |||
92 | * @need_clock_update: Update the clock rate before the next request. | 95 | * @need_clock_update: Update the clock rate before the next request. |
93 | * @need_reset: Reset controller before next request. | 96 | * @need_reset: Reset controller before next request. |
94 | * @mode_reg: Value of the MR register. | 97 | * @mode_reg: Value of the MR register. |
98 | * @cfg_reg: Value of the CFG register. | ||
95 | * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus | 99 | * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus |
96 | * rate and timeout calculations. | 100 | * rate and timeout calculations. |
97 | * @mapbase: Physical address of the MMIO registers. | 101 | * @mapbase: Physical address of the MMIO registers. |
@@ -155,6 +159,7 @@ struct atmel_mci { | |||
155 | bool need_clock_update; | 159 | bool need_clock_update; |
156 | bool need_reset; | 160 | bool need_reset; |
157 | u32 mode_reg; | 161 | u32 mode_reg; |
162 | u32 cfg_reg; | ||
158 | unsigned long bus_hz; | 163 | unsigned long bus_hz; |
159 | unsigned long mapbase; | 164 | unsigned long mapbase; |
160 | struct clk *mck; | 165 | struct clk *mck; |
@@ -223,6 +228,19 @@ static bool mci_has_rwproof(void) | |||
223 | } | 228 | } |
224 | 229 | ||
225 | /* | 230 | /* |
231 | * The new MCI2 module isn't 100% compatible with the old MCI module, | ||
232 | * and it has a few nice features which we want to use... | ||
233 | */ | ||
234 | static inline bool atmci_is_mci2(void) | ||
235 | { | ||
236 | if (cpu_is_at91sam9g45()) | ||
237 | return true; | ||
238 | |||
239 | return false; | ||
240 | } | ||
241 | |||
242 | |||
243 | /* | ||
226 | * The debugfs stuff below is mostly optimized away when | 244 | * The debugfs stuff below is mostly optimized away when |
227 | * CONFIG_DEBUG_FS is not set. | 245 | * CONFIG_DEBUG_FS is not set. |
228 | */ | 246 | */ |
@@ -248,7 +266,7 @@ static int atmci_req_show(struct seq_file *s, void *v) | |||
248 | "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", | 266 | "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", |
249 | cmd->opcode, cmd->arg, cmd->flags, | 267 | cmd->opcode, cmd->arg, cmd->flags, |
250 | cmd->resp[0], cmd->resp[1], cmd->resp[2], | 268 | cmd->resp[0], cmd->resp[1], cmd->resp[2], |
251 | cmd->resp[2], cmd->error); | 269 | cmd->resp[3], cmd->error); |
252 | if (data) | 270 | if (data) |
253 | seq_printf(s, "DATA %u / %u * %u flg %x err %d\n", | 271 | seq_printf(s, "DATA %u / %u * %u flg %x err %d\n", |
254 | data->bytes_xfered, data->blocks, | 272 | data->bytes_xfered, data->blocks, |
@@ -258,7 +276,7 @@ static int atmci_req_show(struct seq_file *s, void *v) | |||
258 | "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", | 276 | "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", |
259 | stop->opcode, stop->arg, stop->flags, | 277 | stop->opcode, stop->arg, stop->flags, |
260 | stop->resp[0], stop->resp[1], stop->resp[2], | 278 | stop->resp[0], stop->resp[1], stop->resp[2], |
261 | stop->resp[2], stop->error); | 279 | stop->resp[3], stop->error); |
262 | } | 280 | } |
263 | 281 | ||
264 | spin_unlock_bh(&slot->host->lock); | 282 | spin_unlock_bh(&slot->host->lock); |
@@ -357,12 +375,33 @@ static int atmci_regs_show(struct seq_file *s, void *v) | |||
357 | buf[MCI_BLKR / 4], | 375 | buf[MCI_BLKR / 4], |
358 | buf[MCI_BLKR / 4] & 0xffff, | 376 | buf[MCI_BLKR / 4] & 0xffff, |
359 | (buf[MCI_BLKR / 4] >> 16) & 0xffff); | 377 | (buf[MCI_BLKR / 4] >> 16) & 0xffff); |
378 | if (atmci_is_mci2()) | ||
379 | seq_printf(s, "CSTOR:\t0x%08x\n", buf[MCI_CSTOR / 4]); | ||
360 | 380 | ||
361 | /* Don't read RSPR and RDR; it will consume the data there */ | 381 | /* Don't read RSPR and RDR; it will consume the data there */ |
362 | 382 | ||
363 | atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]); | 383 | atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]); |
364 | atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]); | 384 | atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]); |
365 | 385 | ||
386 | if (atmci_is_mci2()) { | ||
387 | u32 val; | ||
388 | |||
389 | val = buf[MCI_DMA / 4]; | ||
390 | seq_printf(s, "DMA:\t0x%08x OFFSET=%u CHKSIZE=%u%s\n", | ||
391 | val, val & 3, | ||
392 | ((val >> 4) & 3) ? | ||
393 | 1 << (((val >> 4) & 3) + 1) : 1, | ||
394 | val & MCI_DMAEN ? " DMAEN" : ""); | ||
395 | |||
396 | val = buf[MCI_CFG / 4]; | ||
397 | seq_printf(s, "CFG:\t0x%08x%s%s%s%s\n", | ||
398 | val, | ||
399 | val & MCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "", | ||
400 | val & MCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "", | ||
401 | val & MCI_CFG_HSMODE ? " HSMODE" : "", | ||
402 | val & MCI_CFG_LSYNC ? " LSYNC" : ""); | ||
403 | } | ||
404 | |||
366 | kfree(buf); | 405 | kfree(buf); |
367 | 406 | ||
368 | return 0; | 407 | return 0; |
@@ -530,9 +569,10 @@ static void atmci_dma_cleanup(struct atmel_mci *host) | |||
530 | { | 569 | { |
531 | struct mmc_data *data = host->data; | 570 | struct mmc_data *data = host->data; |
532 | 571 | ||
533 | dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, | 572 | if (data) |
534 | ((data->flags & MMC_DATA_WRITE) | 573 | dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, |
535 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); | 574 | ((data->flags & MMC_DATA_WRITE) |
575 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); | ||
536 | } | 576 | } |
537 | 577 | ||
538 | static void atmci_stop_dma(struct atmel_mci *host) | 578 | static void atmci_stop_dma(struct atmel_mci *host) |
@@ -557,6 +597,10 @@ static void atmci_dma_complete(void *arg) | |||
557 | 597 | ||
558 | dev_vdbg(&host->pdev->dev, "DMA complete\n"); | 598 | dev_vdbg(&host->pdev->dev, "DMA complete\n"); |
559 | 599 | ||
600 | if (atmci_is_mci2()) | ||
601 | /* Disable DMA hardware handshaking on MCI */ | ||
602 | mci_writel(host, DMA, mci_readl(host, DMA) & ~MCI_DMAEN); | ||
603 | |||
560 | atmci_dma_cleanup(host); | 604 | atmci_dma_cleanup(host); |
561 | 605 | ||
562 | /* | 606 | /* |
@@ -592,7 +636,7 @@ static void atmci_dma_complete(void *arg) | |||
592 | } | 636 | } |
593 | 637 | ||
594 | static int | 638 | static int |
595 | atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) | 639 | atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) |
596 | { | 640 | { |
597 | struct dma_chan *chan; | 641 | struct dma_chan *chan; |
598 | struct dma_async_tx_descriptor *desc; | 642 | struct dma_async_tx_descriptor *desc; |
@@ -624,6 +668,9 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) | |||
624 | if (!chan) | 668 | if (!chan) |
625 | return -ENODEV; | 669 | return -ENODEV; |
626 | 670 | ||
671 | if (atmci_is_mci2()) | ||
672 | mci_writel(host, DMA, MCI_DMA_CHKSIZE(3) | MCI_DMAEN); | ||
673 | |||
627 | if (data->flags & MMC_DATA_READ) | 674 | if (data->flags & MMC_DATA_READ) |
628 | direction = DMA_FROM_DEVICE; | 675 | direction = DMA_FROM_DEVICE; |
629 | else | 676 | else |
@@ -641,10 +688,6 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) | |||
641 | host->dma.data_desc = desc; | 688 | host->dma.data_desc = desc; |
642 | desc->callback = atmci_dma_complete; | 689 | desc->callback = atmci_dma_complete; |
643 | desc->callback_param = host; | 690 | desc->callback_param = host; |
644 | desc->tx_submit(desc); | ||
645 | |||
646 | /* Go! */ | ||
647 | chan->device->device_issue_pending(chan); | ||
648 | 691 | ||
649 | return 0; | 692 | return 0; |
650 | unmap_exit: | 693 | unmap_exit: |
@@ -652,13 +695,26 @@ unmap_exit: | |||
652 | return -ENOMEM; | 695 | return -ENOMEM; |
653 | } | 696 | } |
654 | 697 | ||
698 | static void atmci_submit_data(struct atmel_mci *host) | ||
699 | { | ||
700 | struct dma_chan *chan = host->data_chan; | ||
701 | struct dma_async_tx_descriptor *desc = host->dma.data_desc; | ||
702 | |||
703 | if (chan) { | ||
704 | desc->tx_submit(desc); | ||
705 | chan->device->device_issue_pending(chan); | ||
706 | } | ||
707 | } | ||
708 | |||
655 | #else /* CONFIG_MMC_ATMELMCI_DMA */ | 709 | #else /* CONFIG_MMC_ATMELMCI_DMA */ |
656 | 710 | ||
657 | static int atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) | 711 | static int atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) |
658 | { | 712 | { |
659 | return -ENOSYS; | 713 | return -ENOSYS; |
660 | } | 714 | } |
661 | 715 | ||
716 | static void atmci_submit_data(struct atmel_mci *host) {} | ||
717 | |||
662 | static void atmci_stop_dma(struct atmel_mci *host) | 718 | static void atmci_stop_dma(struct atmel_mci *host) |
663 | { | 719 | { |
664 | /* Data transfer was stopped by the interrupt handler */ | 720 | /* Data transfer was stopped by the interrupt handler */ |
@@ -672,7 +728,7 @@ static void atmci_stop_dma(struct atmel_mci *host) | |||
672 | * Returns a mask of interrupt flags to be enabled after the whole | 728 | * Returns a mask of interrupt flags to be enabled after the whole |
673 | * request has been prepared. | 729 | * request has been prepared. |
674 | */ | 730 | */ |
675 | static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data) | 731 | static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data) |
676 | { | 732 | { |
677 | u32 iflags; | 733 | u32 iflags; |
678 | 734 | ||
@@ -683,7 +739,7 @@ static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data) | |||
683 | host->data = data; | 739 | host->data = data; |
684 | 740 | ||
685 | iflags = ATMCI_DATA_ERROR_FLAGS; | 741 | iflags = ATMCI_DATA_ERROR_FLAGS; |
686 | if (atmci_submit_data_dma(host, data)) { | 742 | if (atmci_prepare_data_dma(host, data)) { |
687 | host->data_chan = NULL; | 743 | host->data_chan = NULL; |
688 | 744 | ||
689 | /* | 745 | /* |
@@ -729,6 +785,8 @@ static void atmci_start_request(struct atmel_mci *host, | |||
729 | mci_writel(host, CR, MCI_CR_SWRST); | 785 | mci_writel(host, CR, MCI_CR_SWRST); |
730 | mci_writel(host, CR, MCI_CR_MCIEN); | 786 | mci_writel(host, CR, MCI_CR_MCIEN); |
731 | mci_writel(host, MR, host->mode_reg); | 787 | mci_writel(host, MR, host->mode_reg); |
788 | if (atmci_is_mci2()) | ||
789 | mci_writel(host, CFG, host->cfg_reg); | ||
732 | host->need_reset = false; | 790 | host->need_reset = false; |
733 | } | 791 | } |
734 | mci_writel(host, SDCR, slot->sdc_reg); | 792 | mci_writel(host, SDCR, slot->sdc_reg); |
@@ -744,6 +802,7 @@ static void atmci_start_request(struct atmel_mci *host, | |||
744 | while (!(mci_readl(host, SR) & MCI_CMDRDY)) | 802 | while (!(mci_readl(host, SR) & MCI_CMDRDY)) |
745 | cpu_relax(); | 803 | cpu_relax(); |
746 | } | 804 | } |
805 | iflags = 0; | ||
747 | data = mrq->data; | 806 | data = mrq->data; |
748 | if (data) { | 807 | if (data) { |
749 | atmci_set_timeout(host, slot, data); | 808 | atmci_set_timeout(host, slot, data); |
@@ -753,15 +812,17 @@ static void atmci_start_request(struct atmel_mci *host, | |||
753 | | MCI_BLKLEN(data->blksz)); | 812 | | MCI_BLKLEN(data->blksz)); |
754 | dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n", | 813 | dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n", |
755 | MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz)); | 814 | MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz)); |
815 | |||
816 | iflags |= atmci_prepare_data(host, data); | ||
756 | } | 817 | } |
757 | 818 | ||
758 | iflags = MCI_CMDRDY; | 819 | iflags |= MCI_CMDRDY; |
759 | cmd = mrq->cmd; | 820 | cmd = mrq->cmd; |
760 | cmdflags = atmci_prepare_command(slot->mmc, cmd); | 821 | cmdflags = atmci_prepare_command(slot->mmc, cmd); |
761 | atmci_start_command(host, cmd, cmdflags); | 822 | atmci_start_command(host, cmd, cmdflags); |
762 | 823 | ||
763 | if (data) | 824 | if (data) |
764 | iflags |= atmci_submit_data(host, data); | 825 | atmci_submit_data(host); |
765 | 826 | ||
766 | if (mrq->stop) { | 827 | if (mrq->stop) { |
767 | host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop); | 828 | host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop); |
@@ -857,6 +918,8 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
857 | clk_enable(host->mck); | 918 | clk_enable(host->mck); |
858 | mci_writel(host, CR, MCI_CR_SWRST); | 919 | mci_writel(host, CR, MCI_CR_SWRST); |
859 | mci_writel(host, CR, MCI_CR_MCIEN); | 920 | mci_writel(host, CR, MCI_CR_MCIEN); |
921 | if (atmci_is_mci2()) | ||
922 | mci_writel(host, CFG, host->cfg_reg); | ||
860 | } | 923 | } |
861 | 924 | ||
862 | /* | 925 | /* |
@@ -1037,8 +1100,8 @@ static void atmci_command_complete(struct atmel_mci *host, | |||
1037 | "command error: status=0x%08x\n", status); | 1100 | "command error: status=0x%08x\n", status); |
1038 | 1101 | ||
1039 | if (cmd->data) { | 1102 | if (cmd->data) { |
1040 | host->data = NULL; | ||
1041 | atmci_stop_dma(host); | 1103 | atmci_stop_dma(host); |
1104 | host->data = NULL; | ||
1042 | mci_writel(host, IDR, MCI_NOTBUSY | 1105 | mci_writel(host, IDR, MCI_NOTBUSY |
1043 | | MCI_TXRDY | MCI_RXRDY | 1106 | | MCI_TXRDY | MCI_RXRDY |
1044 | | ATMCI_DATA_ERROR_FLAGS); | 1107 | | ATMCI_DATA_ERROR_FLAGS); |
@@ -1095,6 +1158,8 @@ static void atmci_detect_change(unsigned long data) | |||
1095 | mci_writel(host, CR, MCI_CR_SWRST); | 1158 | mci_writel(host, CR, MCI_CR_SWRST); |
1096 | mci_writel(host, CR, MCI_CR_MCIEN); | 1159 | mci_writel(host, CR, MCI_CR_MCIEN); |
1097 | mci_writel(host, MR, host->mode_reg); | 1160 | mci_writel(host, MR, host->mode_reg); |
1161 | if (atmci_is_mci2()) | ||
1162 | mci_writel(host, CFG, host->cfg_reg); | ||
1098 | 1163 | ||
1099 | host->data = NULL; | 1164 | host->data = NULL; |
1100 | host->cmd = NULL; | 1165 | host->cmd = NULL; |
@@ -1229,6 +1294,7 @@ static void atmci_tasklet_func(unsigned long priv) | |||
1229 | } else { | 1294 | } else { |
1230 | data->bytes_xfered = data->blocks * data->blksz; | 1295 | data->bytes_xfered = data->blocks * data->blksz; |
1231 | data->error = 0; | 1296 | data->error = 0; |
1297 | mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS); | ||
1232 | } | 1298 | } |
1233 | 1299 | ||
1234 | if (!data->stop) { | 1300 | if (!data->stop) { |
@@ -1584,14 +1650,47 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot, | |||
1584 | #ifdef CONFIG_MMC_ATMELMCI_DMA | 1650 | #ifdef CONFIG_MMC_ATMELMCI_DMA |
1585 | static bool filter(struct dma_chan *chan, void *slave) | 1651 | static bool filter(struct dma_chan *chan, void *slave) |
1586 | { | 1652 | { |
1587 | struct dw_dma_slave *dws = slave; | 1653 | struct mci_dma_data *sl = slave; |
1588 | 1654 | ||
1589 | if (dws->dma_dev == chan->device->dev) { | 1655 | if (sl && find_slave_dev(sl) == chan->device->dev) { |
1590 | chan->private = dws; | 1656 | chan->private = slave_data_ptr(sl); |
1591 | return true; | 1657 | return true; |
1592 | } else | 1658 | } else { |
1593 | return false; | 1659 | return false; |
1660 | } | ||
1594 | } | 1661 | } |
1662 | |||
1663 | static void atmci_configure_dma(struct atmel_mci *host) | ||
1664 | { | ||
1665 | struct mci_platform_data *pdata; | ||
1666 | |||
1667 | if (host == NULL) | ||
1668 | return; | ||
1669 | |||
1670 | pdata = host->pdev->dev.platform_data; | ||
1671 | |||
1672 | if (pdata && find_slave_dev(pdata->dma_slave)) { | ||
1673 | dma_cap_mask_t mask; | ||
1674 | |||
1675 | setup_dma_addr(pdata->dma_slave, | ||
1676 | host->mapbase + MCI_TDR, | ||
1677 | host->mapbase + MCI_RDR); | ||
1678 | |||
1679 | /* Try to grab a DMA channel */ | ||
1680 | dma_cap_zero(mask); | ||
1681 | dma_cap_set(DMA_SLAVE, mask); | ||
1682 | host->dma.chan = | ||
1683 | dma_request_channel(mask, filter, pdata->dma_slave); | ||
1684 | } | ||
1685 | if (!host->dma.chan) | ||
1686 | dev_notice(&host->pdev->dev, "DMA not available, using PIO\n"); | ||
1687 | else | ||
1688 | dev_info(&host->pdev->dev, | ||
1689 | "Using %s for DMA transfers\n", | ||
1690 | dma_chan_name(host->dma.chan)); | ||
1691 | } | ||
1692 | #else | ||
1693 | static void atmci_configure_dma(struct atmel_mci *host) {} | ||
1595 | #endif | 1694 | #endif |
1596 | 1695 | ||
1597 | static int __init atmci_probe(struct platform_device *pdev) | 1696 | static int __init atmci_probe(struct platform_device *pdev) |
@@ -1645,22 +1744,7 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
1645 | if (ret) | 1744 | if (ret) |
1646 | goto err_request_irq; | 1745 | goto err_request_irq; |
1647 | 1746 | ||
1648 | #ifdef CONFIG_MMC_ATMELMCI_DMA | 1747 | atmci_configure_dma(host); |
1649 | if (pdata->dma_slave.dma_dev) { | ||
1650 | struct dw_dma_slave *dws = &pdata->dma_slave; | ||
1651 | dma_cap_mask_t mask; | ||
1652 | |||
1653 | dws->tx_reg = regs->start + MCI_TDR; | ||
1654 | dws->rx_reg = regs->start + MCI_RDR; | ||
1655 | |||
1656 | /* Try to grab a DMA channel */ | ||
1657 | dma_cap_zero(mask); | ||
1658 | dma_cap_set(DMA_SLAVE, mask); | ||
1659 | host->dma.chan = dma_request_channel(mask, filter, dws); | ||
1660 | } | ||
1661 | if (!host->dma.chan) | ||
1662 | dev_notice(&pdev->dev, "DMA not available, using PIO\n"); | ||
1663 | #endif /* CONFIG_MMC_ATMELMCI_DMA */ | ||
1664 | 1748 | ||
1665 | platform_set_drvdata(pdev, host); | 1749 | platform_set_drvdata(pdev, host); |
1666 | 1750 | ||
@@ -1669,13 +1753,13 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
1669 | ret = -ENODEV; | 1753 | ret = -ENODEV; |
1670 | if (pdata->slot[0].bus_width) { | 1754 | if (pdata->slot[0].bus_width) { |
1671 | ret = atmci_init_slot(host, &pdata->slot[0], | 1755 | ret = atmci_init_slot(host, &pdata->slot[0], |
1672 | MCI_SDCSEL_SLOT_A, 0); | 1756 | 0, MCI_SDCSEL_SLOT_A); |
1673 | if (!ret) | 1757 | if (!ret) |
1674 | nr_slots++; | 1758 | nr_slots++; |
1675 | } | 1759 | } |
1676 | if (pdata->slot[1].bus_width) { | 1760 | if (pdata->slot[1].bus_width) { |
1677 | ret = atmci_init_slot(host, &pdata->slot[1], | 1761 | ret = atmci_init_slot(host, &pdata->slot[1], |
1678 | MCI_SDCSEL_SLOT_B, 1); | 1762 | 1, MCI_SDCSEL_SLOT_B); |
1679 | if (!ret) | 1763 | if (!ret) |
1680 | nr_slots++; | 1764 | nr_slots++; |
1681 | } | 1765 | } |
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index d3f55615c099..f5834449400e 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/scatterlist.h> | 41 | #include <linux/scatterlist.h> |
42 | #include <linux/leds.h> | 42 | #include <linux/leds.h> |
43 | #include <linux/mmc/host.h> | 43 | #include <linux/mmc/host.h> |
44 | #include <linux/slab.h> | ||
44 | 45 | ||
45 | #include <asm/io.h> | 46 | #include <asm/io.h> |
46 | #include <asm/mach-au1x00/au1000.h> | 47 | #include <asm/mach-au1x00/au1000.h> |
@@ -650,11 +651,11 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host, | |||
650 | flags = DDMA_FLAGS_IE; | 651 | flags = DDMA_FLAGS_IE; |
651 | 652 | ||
652 | if (host->flags & HOST_F_XMIT) { | 653 | if (host->flags & HOST_F_XMIT) { |
653 | ret = au1xxx_dbdma_put_source_flags(channel, | 654 | ret = au1xxx_dbdma_put_source(channel, |
654 | (void *)sg_virt(sg), len, flags); | 655 | sg_phys(sg), len, flags); |
655 | } else { | 656 | } else { |
656 | ret = au1xxx_dbdma_put_dest_flags(channel, | 657 | ret = au1xxx_dbdma_put_dest(channel, |
657 | (void *)sg_virt(sg), len, flags); | 658 | sg_phys(sg), len, flags); |
658 | } | 659 | } |
659 | 660 | ||
660 | if (!ret) | 661 | if (!ret) |
@@ -1017,6 +1018,10 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) | |||
1017 | } else | 1018 | } else |
1018 | mmc->caps |= MMC_CAP_NEEDS_POLL; | 1019 | mmc->caps |= MMC_CAP_NEEDS_POLL; |
1019 | 1020 | ||
1021 | /* platform may not be able to use all advertised caps */ | ||
1022 | if (host->platdata) | ||
1023 | mmc->caps &= ~(host->platdata->mask_host_caps); | ||
1024 | |||
1020 | tasklet_init(&host->data_task, au1xmmc_tasklet_data, | 1025 | tasklet_init(&host->data_task, au1xmmc_tasklet_data, |
1021 | (unsigned long)host); | 1026 | (unsigned long)host); |
1022 | 1027 | ||
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c new file mode 100644 index 000000000000..6919e844072c --- /dev/null +++ b/drivers/mmc/host/bfin_sdh.c | |||
@@ -0,0 +1,644 @@ | |||
1 | /* | ||
2 | * bfin_sdh.c - Analog Devices Blackfin SDH Controller | ||
3 | * | ||
4 | * Copyright (C) 2007-2009 Analog Device Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #define DRIVER_NAME "bfin-sdh" | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/ioport.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/mmc/host.h> | ||
19 | #include <linux/proc_fs.h> | ||
20 | #include <linux/gfp.h> | ||
21 | |||
22 | #include <asm/cacheflush.h> | ||
23 | #include <asm/dma.h> | ||
24 | #include <asm/portmux.h> | ||
25 | #include <asm/bfin_sdh.h> | ||
26 | |||
27 | #if defined(CONFIG_BF51x) | ||
28 | #define bfin_read_SDH_PWR_CTL bfin_read_RSI_PWR_CTL | ||
29 | #define bfin_write_SDH_PWR_CTL bfin_write_RSI_PWR_CTL | ||
30 | #define bfin_read_SDH_CLK_CTL bfin_read_RSI_CLK_CTL | ||
31 | #define bfin_write_SDH_CLK_CTL bfin_write_RSI_CLK_CTL | ||
32 | #define bfin_write_SDH_ARGUMENT bfin_write_RSI_ARGUMENT | ||
33 | #define bfin_write_SDH_COMMAND bfin_write_RSI_COMMAND | ||
34 | #define bfin_write_SDH_DATA_TIMER bfin_write_RSI_DATA_TIMER | ||
35 | #define bfin_read_SDH_RESPONSE0 bfin_read_RSI_RESPONSE0 | ||
36 | #define bfin_read_SDH_RESPONSE1 bfin_read_RSI_RESPONSE1 | ||
37 | #define bfin_read_SDH_RESPONSE2 bfin_read_RSI_RESPONSE2 | ||
38 | #define bfin_read_SDH_RESPONSE3 bfin_read_RSI_RESPONSE3 | ||
39 | #define bfin_write_SDH_DATA_LGTH bfin_write_RSI_DATA_LGTH | ||
40 | #define bfin_read_SDH_DATA_CTL bfin_read_RSI_DATA_CTL | ||
41 | #define bfin_write_SDH_DATA_CTL bfin_write_RSI_DATA_CTL | ||
42 | #define bfin_read_SDH_DATA_CNT bfin_read_RSI_DATA_CNT | ||
43 | #define bfin_write_SDH_STATUS_CLR bfin_write_RSI_STATUS_CLR | ||
44 | #define bfin_read_SDH_E_STATUS bfin_read_RSI_E_STATUS | ||
45 | #define bfin_write_SDH_E_STATUS bfin_write_RSI_E_STATUS | ||
46 | #define bfin_read_SDH_STATUS bfin_read_RSI_STATUS | ||
47 | #define bfin_write_SDH_MASK0 bfin_write_RSI_MASK0 | ||
48 | #define bfin_read_SDH_CFG bfin_read_RSI_CFG | ||
49 | #define bfin_write_SDH_CFG bfin_write_RSI_CFG | ||
50 | #endif | ||
51 | |||
52 | struct dma_desc_array { | ||
53 | unsigned long start_addr; | ||
54 | unsigned short cfg; | ||
55 | unsigned short x_count; | ||
56 | short x_modify; | ||
57 | } __packed; | ||
58 | |||
59 | struct sdh_host { | ||
60 | struct mmc_host *mmc; | ||
61 | spinlock_t lock; | ||
62 | struct resource *res; | ||
63 | void __iomem *base; | ||
64 | int irq; | ||
65 | int stat_irq; | ||
66 | int dma_ch; | ||
67 | int dma_dir; | ||
68 | struct dma_desc_array *sg_cpu; | ||
69 | dma_addr_t sg_dma; | ||
70 | int dma_len; | ||
71 | |||
72 | unsigned int imask; | ||
73 | unsigned int power_mode; | ||
74 | unsigned int clk_div; | ||
75 | |||
76 | struct mmc_request *mrq; | ||
77 | struct mmc_command *cmd; | ||
78 | struct mmc_data *data; | ||
79 | }; | ||
80 | |||
81 | static struct bfin_sd_host *get_sdh_data(struct platform_device *pdev) | ||
82 | { | ||
83 | return pdev->dev.platform_data; | ||
84 | } | ||
85 | |||
86 | static void sdh_stop_clock(struct sdh_host *host) | ||
87 | { | ||
88 | bfin_write_SDH_CLK_CTL(bfin_read_SDH_CLK_CTL() & ~CLK_E); | ||
89 | SSYNC(); | ||
90 | } | ||
91 | |||
92 | static void sdh_enable_stat_irq(struct sdh_host *host, unsigned int mask) | ||
93 | { | ||
94 | unsigned long flags; | ||
95 | |||
96 | spin_lock_irqsave(&host->lock, flags); | ||
97 | host->imask |= mask; | ||
98 | bfin_write_SDH_MASK0(mask); | ||
99 | SSYNC(); | ||
100 | spin_unlock_irqrestore(&host->lock, flags); | ||
101 | } | ||
102 | |||
103 | static void sdh_disable_stat_irq(struct sdh_host *host, unsigned int mask) | ||
104 | { | ||
105 | unsigned long flags; | ||
106 | |||
107 | spin_lock_irqsave(&host->lock, flags); | ||
108 | host->imask &= ~mask; | ||
109 | bfin_write_SDH_MASK0(host->imask); | ||
110 | SSYNC(); | ||
111 | spin_unlock_irqrestore(&host->lock, flags); | ||
112 | } | ||
113 | |||
114 | static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data) | ||
115 | { | ||
116 | unsigned int length; | ||
117 | unsigned int data_ctl; | ||
118 | unsigned int dma_cfg; | ||
119 | unsigned int cycle_ns, timeout; | ||
120 | |||
121 | dev_dbg(mmc_dev(host->mmc), "%s enter flags: 0x%x\n", __func__, data->flags); | ||
122 | host->data = data; | ||
123 | data_ctl = 0; | ||
124 | dma_cfg = 0; | ||
125 | |||
126 | length = data->blksz * data->blocks; | ||
127 | bfin_write_SDH_DATA_LGTH(length); | ||
128 | |||
129 | if (data->flags & MMC_DATA_STREAM) | ||
130 | data_ctl |= DTX_MODE; | ||
131 | |||
132 | if (data->flags & MMC_DATA_READ) | ||
133 | data_ctl |= DTX_DIR; | ||
134 | /* Only supports power-of-2 block size */ | ||
135 | if (data->blksz & (data->blksz - 1)) | ||
136 | return -EINVAL; | ||
137 | data_ctl |= ((ffs(data->blksz) - 1) << 4); | ||
138 | |||
139 | bfin_write_SDH_DATA_CTL(data_ctl); | ||
140 | /* the time of a host clock period in ns */ | ||
141 | cycle_ns = 1000000000 / (get_sclk() / (2 * (host->clk_div + 1))); | ||
142 | timeout = data->timeout_ns / cycle_ns; | ||
143 | timeout += data->timeout_clks; | ||
144 | bfin_write_SDH_DATA_TIMER(timeout); | ||
145 | SSYNC(); | ||
146 | |||
147 | if (data->flags & MMC_DATA_READ) { | ||
148 | host->dma_dir = DMA_FROM_DEVICE; | ||
149 | dma_cfg |= WNR; | ||
150 | } else | ||
151 | host->dma_dir = DMA_TO_DEVICE; | ||
152 | |||
153 | sdh_enable_stat_irq(host, (DAT_CRC_FAIL | DAT_TIME_OUT | DAT_END)); | ||
154 | host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir); | ||
155 | #if defined(CONFIG_BF54x) | ||
156 | dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN; | ||
157 | { | ||
158 | struct scatterlist *sg; | ||
159 | int i; | ||
160 | for_each_sg(data->sg, sg, host->dma_len, i) { | ||
161 | host->sg_cpu[i].start_addr = sg_dma_address(sg); | ||
162 | host->sg_cpu[i].cfg = dma_cfg; | ||
163 | host->sg_cpu[i].x_count = sg_dma_len(sg) / 4; | ||
164 | host->sg_cpu[i].x_modify = 4; | ||
165 | dev_dbg(mmc_dev(host->mmc), "%d: start_addr:0x%lx, " | ||
166 | "cfg:0x%x, x_count:0x%x, x_modify:0x%x\n", | ||
167 | i, host->sg_cpu[i].start_addr, | ||
168 | host->sg_cpu[i].cfg, host->sg_cpu[i].x_count, | ||
169 | host->sg_cpu[i].x_modify); | ||
170 | } | ||
171 | } | ||
172 | flush_dcache_range((unsigned int)host->sg_cpu, | ||
173 | (unsigned int)host->sg_cpu + | ||
174 | host->dma_len * sizeof(struct dma_desc_array)); | ||
175 | /* Set the last descriptor to stop mode */ | ||
176 | host->sg_cpu[host->dma_len - 1].cfg &= ~(DMAFLOW | NDSIZE); | ||
177 | host->sg_cpu[host->dma_len - 1].cfg |= DI_EN; | ||
178 | |||
179 | set_dma_curr_desc_addr(host->dma_ch, (unsigned long *)host->sg_dma); | ||
180 | set_dma_x_count(host->dma_ch, 0); | ||
181 | set_dma_x_modify(host->dma_ch, 0); | ||
182 | set_dma_config(host->dma_ch, dma_cfg); | ||
183 | #elif defined(CONFIG_BF51x) | ||
184 | /* RSI DMA doesn't work in array mode */ | ||
185 | dma_cfg |= WDSIZE_32 | DMAEN; | ||
186 | set_dma_start_addr(host->dma_ch, sg_dma_address(&data->sg[0])); | ||
187 | set_dma_x_count(host->dma_ch, length / 4); | ||
188 | set_dma_x_modify(host->dma_ch, 4); | ||
189 | set_dma_config(host->dma_ch, dma_cfg); | ||
190 | #endif | ||
191 | bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E); | ||
192 | |||
193 | SSYNC(); | ||
194 | |||
195 | dev_dbg(mmc_dev(host->mmc), "%s exit\n", __func__); | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static void sdh_start_cmd(struct sdh_host *host, struct mmc_command *cmd) | ||
200 | { | ||
201 | unsigned int sdh_cmd; | ||
202 | unsigned int stat_mask; | ||
203 | |||
204 | dev_dbg(mmc_dev(host->mmc), "%s enter cmd: 0x%p\n", __func__, cmd); | ||
205 | WARN_ON(host->cmd != NULL); | ||
206 | host->cmd = cmd; | ||
207 | |||
208 | sdh_cmd = 0; | ||
209 | stat_mask = 0; | ||
210 | |||
211 | sdh_cmd |= cmd->opcode; | ||
212 | |||
213 | if (cmd->flags & MMC_RSP_PRESENT) { | ||
214 | sdh_cmd |= CMD_RSP; | ||
215 | stat_mask |= CMD_RESP_END; | ||
216 | } else { | ||
217 | stat_mask |= CMD_SENT; | ||
218 | } | ||
219 | |||
220 | if (cmd->flags & MMC_RSP_136) | ||
221 | sdh_cmd |= CMD_L_RSP; | ||
222 | |||
223 | stat_mask |= CMD_CRC_FAIL | CMD_TIME_OUT; | ||
224 | |||
225 | sdh_enable_stat_irq(host, stat_mask); | ||
226 | |||
227 | bfin_write_SDH_ARGUMENT(cmd->arg); | ||
228 | bfin_write_SDH_COMMAND(sdh_cmd | CMD_E); | ||
229 | bfin_write_SDH_CLK_CTL(bfin_read_SDH_CLK_CTL() | CLK_E); | ||
230 | SSYNC(); | ||
231 | } | ||
232 | |||
233 | static void sdh_finish_request(struct sdh_host *host, struct mmc_request *mrq) | ||
234 | { | ||
235 | dev_dbg(mmc_dev(host->mmc), "%s enter\n", __func__); | ||
236 | host->mrq = NULL; | ||
237 | host->cmd = NULL; | ||
238 | host->data = NULL; | ||
239 | mmc_request_done(host->mmc, mrq); | ||
240 | } | ||
241 | |||
242 | static int sdh_cmd_done(struct sdh_host *host, unsigned int stat) | ||
243 | { | ||
244 | struct mmc_command *cmd = host->cmd; | ||
245 | int ret = 0; | ||
246 | |||
247 | dev_dbg(mmc_dev(host->mmc), "%s enter cmd: %p\n", __func__, cmd); | ||
248 | if (!cmd) | ||
249 | return 0; | ||
250 | |||
251 | host->cmd = NULL; | ||
252 | |||
253 | if (cmd->flags & MMC_RSP_PRESENT) { | ||
254 | cmd->resp[0] = bfin_read_SDH_RESPONSE0(); | ||
255 | if (cmd->flags & MMC_RSP_136) { | ||
256 | cmd->resp[1] = bfin_read_SDH_RESPONSE1(); | ||
257 | cmd->resp[2] = bfin_read_SDH_RESPONSE2(); | ||
258 | cmd->resp[3] = bfin_read_SDH_RESPONSE3(); | ||
259 | } | ||
260 | } | ||
261 | if (stat & CMD_TIME_OUT) | ||
262 | cmd->error = -ETIMEDOUT; | ||
263 | else if (stat & CMD_CRC_FAIL && cmd->flags & MMC_RSP_CRC) | ||
264 | cmd->error = -EILSEQ; | ||
265 | |||
266 | sdh_disable_stat_irq(host, (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | CMD_CRC_FAIL)); | ||
267 | |||
268 | if (host->data && !cmd->error) { | ||
269 | if (host->data->flags & MMC_DATA_WRITE) { | ||
270 | ret = sdh_setup_data(host, host->data); | ||
271 | if (ret) | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | sdh_enable_stat_irq(host, DAT_END | RX_OVERRUN | TX_UNDERRUN | DAT_TIME_OUT); | ||
276 | } else | ||
277 | sdh_finish_request(host, host->mrq); | ||
278 | |||
279 | return 1; | ||
280 | } | ||
281 | |||
282 | static int sdh_data_done(struct sdh_host *host, unsigned int stat) | ||
283 | { | ||
284 | struct mmc_data *data = host->data; | ||
285 | |||
286 | dev_dbg(mmc_dev(host->mmc), "%s enter stat: 0x%x\n", __func__, stat); | ||
287 | if (!data) | ||
288 | return 0; | ||
289 | |||
290 | disable_dma(host->dma_ch); | ||
291 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, | ||
292 | host->dma_dir); | ||
293 | |||
294 | if (stat & DAT_TIME_OUT) | ||
295 | data->error = -ETIMEDOUT; | ||
296 | else if (stat & DAT_CRC_FAIL) | ||
297 | data->error = -EILSEQ; | ||
298 | else if (stat & (RX_OVERRUN | TX_UNDERRUN)) | ||
299 | data->error = -EIO; | ||
300 | |||
301 | if (!data->error) | ||
302 | data->bytes_xfered = data->blocks * data->blksz; | ||
303 | else | ||
304 | data->bytes_xfered = 0; | ||
305 | |||
306 | sdh_disable_stat_irq(host, DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN); | ||
307 | bfin_write_SDH_STATUS_CLR(DAT_END_STAT | DAT_TIMEOUT_STAT | \ | ||
308 | DAT_CRC_FAIL_STAT | DAT_BLK_END_STAT | RX_OVERRUN | TX_UNDERRUN); | ||
309 | bfin_write_SDH_DATA_CTL(0); | ||
310 | SSYNC(); | ||
311 | |||
312 | host->data = NULL; | ||
313 | if (host->mrq->stop) { | ||
314 | sdh_stop_clock(host); | ||
315 | sdh_start_cmd(host, host->mrq->stop); | ||
316 | } else { | ||
317 | sdh_finish_request(host, host->mrq); | ||
318 | } | ||
319 | |||
320 | return 1; | ||
321 | } | ||
322 | |||
323 | static void sdh_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||
324 | { | ||
325 | struct sdh_host *host = mmc_priv(mmc); | ||
326 | int ret = 0; | ||
327 | |||
328 | dev_dbg(mmc_dev(host->mmc), "%s enter, mrp:%p, cmd:%p\n", __func__, mrq, mrq->cmd); | ||
329 | WARN_ON(host->mrq != NULL); | ||
330 | |||
331 | host->mrq = mrq; | ||
332 | host->data = mrq->data; | ||
333 | |||
334 | if (mrq->data && mrq->data->flags & MMC_DATA_READ) { | ||
335 | ret = sdh_setup_data(host, mrq->data); | ||
336 | if (ret) | ||
337 | return; | ||
338 | } | ||
339 | |||
340 | sdh_start_cmd(host, mrq->cmd); | ||
341 | } | ||
342 | |||
343 | static void sdh_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
344 | { | ||
345 | struct sdh_host *host; | ||
346 | unsigned long flags; | ||
347 | u16 clk_ctl = 0; | ||
348 | u16 pwr_ctl = 0; | ||
349 | u16 cfg; | ||
350 | host = mmc_priv(mmc); | ||
351 | |||
352 | spin_lock_irqsave(&host->lock, flags); | ||
353 | if (ios->clock) { | ||
354 | unsigned long sys_clk, ios_clk; | ||
355 | unsigned char clk_div; | ||
356 | ios_clk = 2 * ios->clock; | ||
357 | sys_clk = get_sclk(); | ||
358 | clk_div = sys_clk / ios_clk; | ||
359 | if (sys_clk % ios_clk == 0) | ||
360 | clk_div -= 1; | ||
361 | clk_div = min_t(unsigned char, clk_div, 0xFF); | ||
362 | clk_ctl |= clk_div; | ||
363 | clk_ctl |= CLK_E; | ||
364 | host->clk_div = clk_div; | ||
365 | } else | ||
366 | sdh_stop_clock(host); | ||
367 | |||
368 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) | ||
369 | #ifdef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND | ||
370 | pwr_ctl |= ROD_CTL; | ||
371 | #else | ||
372 | pwr_ctl |= SD_CMD_OD | ROD_CTL; | ||
373 | #endif | ||
374 | |||
375 | if (ios->bus_width == MMC_BUS_WIDTH_4) { | ||
376 | cfg = bfin_read_SDH_CFG(); | ||
377 | cfg &= ~PD_SDDAT3; | ||
378 | cfg |= PUP_SDDAT3; | ||
379 | /* Enable 4 bit SDIO */ | ||
380 | cfg |= (SD4E | MWE); | ||
381 | bfin_write_SDH_CFG(cfg); | ||
382 | clk_ctl |= WIDE_BUS; | ||
383 | } else { | ||
384 | cfg = bfin_read_SDH_CFG(); | ||
385 | cfg |= MWE; | ||
386 | bfin_write_SDH_CFG(cfg); | ||
387 | } | ||
388 | |||
389 | bfin_write_SDH_CLK_CTL(clk_ctl); | ||
390 | |||
391 | host->power_mode = ios->power_mode; | ||
392 | if (ios->power_mode == MMC_POWER_ON) | ||
393 | pwr_ctl |= PWR_ON; | ||
394 | |||
395 | bfin_write_SDH_PWR_CTL(pwr_ctl); | ||
396 | SSYNC(); | ||
397 | |||
398 | spin_unlock_irqrestore(&host->lock, flags); | ||
399 | |||
400 | dev_dbg(mmc_dev(host->mmc), "SDH: clk_div = 0x%x actual clock:%ld expected clock:%d\n", | ||
401 | host->clk_div, | ||
402 | host->clk_div ? get_sclk() / (2 * (host->clk_div + 1)) : 0, | ||
403 | ios->clock); | ||
404 | } | ||
405 | |||
406 | static const struct mmc_host_ops sdh_ops = { | ||
407 | .request = sdh_request, | ||
408 | .set_ios = sdh_set_ios, | ||
409 | }; | ||
410 | |||
411 | static irqreturn_t sdh_dma_irq(int irq, void *devid) | ||
412 | { | ||
413 | struct sdh_host *host = devid; | ||
414 | |||
415 | dev_dbg(mmc_dev(host->mmc), "%s enter, irq_stat: 0x%04x\n", __func__, | ||
416 | get_dma_curr_irqstat(host->dma_ch)); | ||
417 | clear_dma_irqstat(host->dma_ch); | ||
418 | SSYNC(); | ||
419 | |||
420 | return IRQ_HANDLED; | ||
421 | } | ||
422 | |||
423 | static irqreturn_t sdh_stat_irq(int irq, void *devid) | ||
424 | { | ||
425 | struct sdh_host *host = devid; | ||
426 | unsigned int status; | ||
427 | int handled = 0; | ||
428 | |||
429 | dev_dbg(mmc_dev(host->mmc), "%s enter\n", __func__); | ||
430 | status = bfin_read_SDH_E_STATUS(); | ||
431 | if (status & SD_CARD_DET) { | ||
432 | mmc_detect_change(host->mmc, 0); | ||
433 | bfin_write_SDH_E_STATUS(SD_CARD_DET); | ||
434 | } | ||
435 | status = bfin_read_SDH_STATUS(); | ||
436 | if (status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | CMD_CRC_FAIL)) { | ||
437 | handled |= sdh_cmd_done(host, status); | ||
438 | bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT | \ | ||
439 | CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT); | ||
440 | SSYNC(); | ||
441 | } | ||
442 | |||
443 | status = bfin_read_SDH_STATUS(); | ||
444 | if (status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN)) | ||
445 | handled |= sdh_data_done(host, status); | ||
446 | |||
447 | dev_dbg(mmc_dev(host->mmc), "%s exit\n\n", __func__); | ||
448 | |||
449 | return IRQ_RETVAL(handled); | ||
450 | } | ||
451 | |||
452 | static int __devinit sdh_probe(struct platform_device *pdev) | ||
453 | { | ||
454 | struct mmc_host *mmc; | ||
455 | struct sdh_host *host; | ||
456 | struct bfin_sd_host *drv_data = get_sdh_data(pdev); | ||
457 | int ret; | ||
458 | |||
459 | if (!drv_data) { | ||
460 | dev_err(&pdev->dev, "missing platform driver data\n"); | ||
461 | ret = -EINVAL; | ||
462 | goto out; | ||
463 | } | ||
464 | |||
465 | mmc = mmc_alloc_host(sizeof(*mmc), &pdev->dev); | ||
466 | if (!mmc) { | ||
467 | ret = -ENOMEM; | ||
468 | goto out; | ||
469 | } | ||
470 | |||
471 | mmc->ops = &sdh_ops; | ||
472 | mmc->max_phys_segs = 32; | ||
473 | mmc->max_seg_size = 1 << 16; | ||
474 | mmc->max_blk_size = 1 << 11; | ||
475 | mmc->max_blk_count = 1 << 11; | ||
476 | mmc->max_req_size = PAGE_SIZE; | ||
477 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
478 | mmc->f_max = get_sclk(); | ||
479 | mmc->f_min = mmc->f_max >> 9; | ||
480 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NEEDS_POLL; | ||
481 | host = mmc_priv(mmc); | ||
482 | host->mmc = mmc; | ||
483 | |||
484 | spin_lock_init(&host->lock); | ||
485 | host->irq = drv_data->irq_int0; | ||
486 | host->dma_ch = drv_data->dma_chan; | ||
487 | |||
488 | ret = request_dma(host->dma_ch, DRIVER_NAME "DMA"); | ||
489 | if (ret) { | ||
490 | dev_err(&pdev->dev, "unable to request DMA channel\n"); | ||
491 | goto out1; | ||
492 | } | ||
493 | |||
494 | ret = set_dma_callback(host->dma_ch, sdh_dma_irq, host); | ||
495 | if (ret) { | ||
496 | dev_err(&pdev->dev, "unable to request DMA irq\n"); | ||
497 | goto out2; | ||
498 | } | ||
499 | |||
500 | host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); | ||
501 | if (host->sg_cpu == NULL) { | ||
502 | ret = -ENOMEM; | ||
503 | goto out2; | ||
504 | } | ||
505 | |||
506 | platform_set_drvdata(pdev, mmc); | ||
507 | mmc_add_host(mmc); | ||
508 | |||
509 | ret = request_irq(host->irq, sdh_stat_irq, 0, "SDH Status IRQ", host); | ||
510 | if (ret) { | ||
511 | dev_err(&pdev->dev, "unable to request status irq\n"); | ||
512 | goto out3; | ||
513 | } | ||
514 | |||
515 | ret = peripheral_request_list(drv_data->pin_req, DRIVER_NAME); | ||
516 | if (ret) { | ||
517 | dev_err(&pdev->dev, "unable to request peripheral pins\n"); | ||
518 | goto out4; | ||
519 | } | ||
520 | #if defined(CONFIG_BF54x) | ||
521 | /* Secure Digital Host shares DMA with Nand controller */ | ||
522 | bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1); | ||
523 | #endif | ||
524 | |||
525 | bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN); | ||
526 | SSYNC(); | ||
527 | |||
528 | /* Disable card inserting detection pin. set MMC_CAP_NEES_POLL, and | ||
529 | * mmc stack will do the detection. | ||
530 | */ | ||
531 | bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3)); | ||
532 | SSYNC(); | ||
533 | |||
534 | return 0; | ||
535 | |||
536 | out4: | ||
537 | free_irq(host->irq, host); | ||
538 | out3: | ||
539 | mmc_remove_host(mmc); | ||
540 | dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); | ||
541 | out2: | ||
542 | free_dma(host->dma_ch); | ||
543 | out1: | ||
544 | mmc_free_host(mmc); | ||
545 | out: | ||
546 | return ret; | ||
547 | } | ||
548 | |||
549 | static int __devexit sdh_remove(struct platform_device *pdev) | ||
550 | { | ||
551 | struct mmc_host *mmc = platform_get_drvdata(pdev); | ||
552 | |||
553 | platform_set_drvdata(pdev, NULL); | ||
554 | |||
555 | if (mmc) { | ||
556 | struct sdh_host *host = mmc_priv(mmc); | ||
557 | |||
558 | mmc_remove_host(mmc); | ||
559 | |||
560 | sdh_stop_clock(host); | ||
561 | free_irq(host->irq, host); | ||
562 | free_dma(host->dma_ch); | ||
563 | dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); | ||
564 | |||
565 | mmc_free_host(mmc); | ||
566 | } | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | #ifdef CONFIG_PM | ||
572 | static int sdh_suspend(struct platform_device *dev, pm_message_t state) | ||
573 | { | ||
574 | struct mmc_host *mmc = platform_get_drvdata(dev); | ||
575 | struct bfin_sd_host *drv_data = get_sdh_data(dev); | ||
576 | int ret = 0; | ||
577 | |||
578 | if (mmc) | ||
579 | ret = mmc_suspend_host(mmc, state); | ||
580 | |||
581 | bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() & ~PWR_ON); | ||
582 | peripheral_free_list(drv_data->pin_req); | ||
583 | |||
584 | return ret; | ||
585 | } | ||
586 | |||
587 | static int sdh_resume(struct platform_device *dev) | ||
588 | { | ||
589 | struct mmc_host *mmc = platform_get_drvdata(dev); | ||
590 | struct bfin_sd_host *drv_data = get_sdh_data(dev); | ||
591 | int ret = 0; | ||
592 | |||
593 | ret = peripheral_request_list(drv_data->pin_req, DRIVER_NAME); | ||
594 | if (ret) { | ||
595 | dev_err(&dev->dev, "unable to request peripheral pins\n"); | ||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() | PWR_ON); | ||
600 | #if defined(CONFIG_BF54x) | ||
601 | /* Secure Digital Host shares DMA with Nand controller */ | ||
602 | bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1); | ||
603 | #endif | ||
604 | bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN); | ||
605 | SSYNC(); | ||
606 | |||
607 | bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3)); | ||
608 | SSYNC(); | ||
609 | |||
610 | if (mmc) | ||
611 | ret = mmc_resume_host(mmc); | ||
612 | |||
613 | return ret; | ||
614 | } | ||
615 | #else | ||
616 | # define sdh_suspend NULL | ||
617 | # define sdh_resume NULL | ||
618 | #endif | ||
619 | |||
620 | static struct platform_driver sdh_driver = { | ||
621 | .probe = sdh_probe, | ||
622 | .remove = __devexit_p(sdh_remove), | ||
623 | .suspend = sdh_suspend, | ||
624 | .resume = sdh_resume, | ||
625 | .driver = { | ||
626 | .name = DRIVER_NAME, | ||
627 | }, | ||
628 | }; | ||
629 | |||
630 | static int __init sdh_init(void) | ||
631 | { | ||
632 | return platform_driver_register(&sdh_driver); | ||
633 | } | ||
634 | module_init(sdh_init); | ||
635 | |||
636 | static void __exit sdh_exit(void) | ||
637 | { | ||
638 | platform_driver_unregister(&sdh_driver); | ||
639 | } | ||
640 | module_exit(sdh_exit); | ||
641 | |||
642 | MODULE_DESCRIPTION("Blackfin Secure Digital Host Driver"); | ||
643 | MODULE_AUTHOR("Cliff Cai, Roy Huang"); | ||
644 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c index 4e72964a7b43..92a324f7417c 100644 --- a/drivers/mmc/host/cb710-mmc.c +++ b/drivers/mmc/host/cb710-mmc.c | |||
@@ -9,7 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/slab.h> | ||
13 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
14 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
15 | #include "cb710-mmc.h" | 14 | #include "cb710-mmc.h" |
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c new file mode 100644 index 000000000000..3bd0ba294e9d --- /dev/null +++ b/drivers/mmc/host/davinci_mmc.c | |||
@@ -0,0 +1,1374 @@ | |||
1 | /* | ||
2 | * davinci_mmc.c - TI DaVinci MMC/SD/SDIO driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Texas Instruments. | ||
5 | * Original author: Purushotam Kumar | ||
6 | * Copyright (C) 2009 David Brownell | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/clk.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/cpufreq.h> | ||
29 | #include <linux/mmc/host.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/irq.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/dma-mapping.h> | ||
34 | #include <linux/mmc/mmc.h> | ||
35 | |||
36 | #include <mach/mmc.h> | ||
37 | #include <mach/edma.h> | ||
38 | |||
39 | /* | ||
40 | * Register Definitions | ||
41 | */ | ||
42 | #define DAVINCI_MMCCTL 0x00 /* Control Register */ | ||
43 | #define DAVINCI_MMCCLK 0x04 /* Memory Clock Control Register */ | ||
44 | #define DAVINCI_MMCST0 0x08 /* Status Register 0 */ | ||
45 | #define DAVINCI_MMCST1 0x0C /* Status Register 1 */ | ||
46 | #define DAVINCI_MMCIM 0x10 /* Interrupt Mask Register */ | ||
47 | #define DAVINCI_MMCTOR 0x14 /* Response Time-Out Register */ | ||
48 | #define DAVINCI_MMCTOD 0x18 /* Data Read Time-Out Register */ | ||
49 | #define DAVINCI_MMCBLEN 0x1C /* Block Length Register */ | ||
50 | #define DAVINCI_MMCNBLK 0x20 /* Number of Blocks Register */ | ||
51 | #define DAVINCI_MMCNBLC 0x24 /* Number of Blocks Counter Register */ | ||
52 | #define DAVINCI_MMCDRR 0x28 /* Data Receive Register */ | ||
53 | #define DAVINCI_MMCDXR 0x2C /* Data Transmit Register */ | ||
54 | #define DAVINCI_MMCCMD 0x30 /* Command Register */ | ||
55 | #define DAVINCI_MMCARGHL 0x34 /* Argument Register */ | ||
56 | #define DAVINCI_MMCRSP01 0x38 /* Response Register 0 and 1 */ | ||
57 | #define DAVINCI_MMCRSP23 0x3C /* Response Register 0 and 1 */ | ||
58 | #define DAVINCI_MMCRSP45 0x40 /* Response Register 0 and 1 */ | ||
59 | #define DAVINCI_MMCRSP67 0x44 /* Response Register 0 and 1 */ | ||
60 | #define DAVINCI_MMCDRSP 0x48 /* Data Response Register */ | ||
61 | #define DAVINCI_MMCETOK 0x4C | ||
62 | #define DAVINCI_MMCCIDX 0x50 /* Command Index Register */ | ||
63 | #define DAVINCI_MMCCKC 0x54 | ||
64 | #define DAVINCI_MMCTORC 0x58 | ||
65 | #define DAVINCI_MMCTODC 0x5C | ||
66 | #define DAVINCI_MMCBLNC 0x60 | ||
67 | #define DAVINCI_SDIOCTL 0x64 | ||
68 | #define DAVINCI_SDIOST0 0x68 | ||
69 | #define DAVINCI_SDIOEN 0x6C | ||
70 | #define DAVINCI_SDIOST 0x70 | ||
71 | #define DAVINCI_MMCFIFOCTL 0x74 /* FIFO Control Register */ | ||
72 | |||
73 | /* DAVINCI_MMCCTL definitions */ | ||
74 | #define MMCCTL_DATRST (1 << 0) | ||
75 | #define MMCCTL_CMDRST (1 << 1) | ||
76 | #define MMCCTL_WIDTH_8_BIT (1 << 8) | ||
77 | #define MMCCTL_WIDTH_4_BIT (1 << 2) | ||
78 | #define MMCCTL_DATEG_DISABLED (0 << 6) | ||
79 | #define MMCCTL_DATEG_RISING (1 << 6) | ||
80 | #define MMCCTL_DATEG_FALLING (2 << 6) | ||
81 | #define MMCCTL_DATEG_BOTH (3 << 6) | ||
82 | #define MMCCTL_PERMDR_LE (0 << 9) | ||
83 | #define MMCCTL_PERMDR_BE (1 << 9) | ||
84 | #define MMCCTL_PERMDX_LE (0 << 10) | ||
85 | #define MMCCTL_PERMDX_BE (1 << 10) | ||
86 | |||
87 | /* DAVINCI_MMCCLK definitions */ | ||
88 | #define MMCCLK_CLKEN (1 << 8) | ||
89 | #define MMCCLK_CLKRT_MASK (0xFF << 0) | ||
90 | |||
91 | /* IRQ bit definitions, for DAVINCI_MMCST0 and DAVINCI_MMCIM */ | ||
92 | #define MMCST0_DATDNE BIT(0) /* data done */ | ||
93 | #define MMCST0_BSYDNE BIT(1) /* busy done */ | ||
94 | #define MMCST0_RSPDNE BIT(2) /* command done */ | ||
95 | #define MMCST0_TOUTRD BIT(3) /* data read timeout */ | ||
96 | #define MMCST0_TOUTRS BIT(4) /* command response timeout */ | ||
97 | #define MMCST0_CRCWR BIT(5) /* data write CRC error */ | ||
98 | #define MMCST0_CRCRD BIT(6) /* data read CRC error */ | ||
99 | #define MMCST0_CRCRS BIT(7) /* command response CRC error */ | ||
100 | #define MMCST0_DXRDY BIT(9) /* data transmit ready (fifo empty) */ | ||
101 | #define MMCST0_DRRDY BIT(10) /* data receive ready (data in fifo)*/ | ||
102 | #define MMCST0_DATED BIT(11) /* DAT3 edge detect */ | ||
103 | #define MMCST0_TRNDNE BIT(12) /* transfer done */ | ||
104 | |||
105 | /* DAVINCI_MMCST1 definitions */ | ||
106 | #define MMCST1_BUSY (1 << 0) | ||
107 | |||
108 | /* DAVINCI_MMCCMD definitions */ | ||
109 | #define MMCCMD_CMD_MASK (0x3F << 0) | ||
110 | #define MMCCMD_PPLEN (1 << 7) | ||
111 | #define MMCCMD_BSYEXP (1 << 8) | ||
112 | #define MMCCMD_RSPFMT_MASK (3 << 9) | ||
113 | #define MMCCMD_RSPFMT_NONE (0 << 9) | ||
114 | #define MMCCMD_RSPFMT_R1456 (1 << 9) | ||
115 | #define MMCCMD_RSPFMT_R2 (2 << 9) | ||
116 | #define MMCCMD_RSPFMT_R3 (3 << 9) | ||
117 | #define MMCCMD_DTRW (1 << 11) | ||
118 | #define MMCCMD_STRMTP (1 << 12) | ||
119 | #define MMCCMD_WDATX (1 << 13) | ||
120 | #define MMCCMD_INITCK (1 << 14) | ||
121 | #define MMCCMD_DCLR (1 << 15) | ||
122 | #define MMCCMD_DMATRIG (1 << 16) | ||
123 | |||
124 | /* DAVINCI_MMCFIFOCTL definitions */ | ||
125 | #define MMCFIFOCTL_FIFORST (1 << 0) | ||
126 | #define MMCFIFOCTL_FIFODIR_WR (1 << 1) | ||
127 | #define MMCFIFOCTL_FIFODIR_RD (0 << 1) | ||
128 | #define MMCFIFOCTL_FIFOLEV (1 << 2) /* 0 = 128 bits, 1 = 256 bits */ | ||
129 | #define MMCFIFOCTL_ACCWD_4 (0 << 3) /* access width of 4 bytes */ | ||
130 | #define MMCFIFOCTL_ACCWD_3 (1 << 3) /* access width of 3 bytes */ | ||
131 | #define MMCFIFOCTL_ACCWD_2 (2 << 3) /* access width of 2 bytes */ | ||
132 | #define MMCFIFOCTL_ACCWD_1 (3 << 3) /* access width of 1 byte */ | ||
133 | |||
134 | |||
135 | /* MMCSD Init clock in Hz in opendrain mode */ | ||
136 | #define MMCSD_INIT_CLOCK 200000 | ||
137 | |||
138 | /* | ||
139 | * One scatterlist dma "segment" is at most MAX_CCNT rw_threshold units, | ||
140 | * and we handle up to NR_SG segments. MMC_BLOCK_BOUNCE kicks in only | ||
141 | * for drivers with max_hw_segs == 1, making the segments bigger (64KB) | ||
142 | * than the page or two that's otherwise typical. NR_SG == 16 gives at | ||
143 | * least the same throughput boost, using EDMA transfer linkage instead | ||
144 | * of spending CPU time copying pages. | ||
145 | */ | ||
146 | #define MAX_CCNT ((1 << 16) - 1) | ||
147 | |||
148 | #define NR_SG 16 | ||
149 | |||
150 | static unsigned rw_threshold = 32; | ||
151 | module_param(rw_threshold, uint, S_IRUGO); | ||
152 | MODULE_PARM_DESC(rw_threshold, | ||
153 | "Read/Write threshold. Default = 32"); | ||
154 | |||
155 | static unsigned __initdata use_dma = 1; | ||
156 | module_param(use_dma, uint, 0); | ||
157 | MODULE_PARM_DESC(use_dma, "Whether to use DMA or not. Default = 1"); | ||
158 | |||
159 | struct mmc_davinci_host { | ||
160 | struct mmc_command *cmd; | ||
161 | struct mmc_data *data; | ||
162 | struct mmc_host *mmc; | ||
163 | struct clk *clk; | ||
164 | unsigned int mmc_input_clk; | ||
165 | void __iomem *base; | ||
166 | struct resource *mem_res; | ||
167 | int irq; | ||
168 | unsigned char bus_mode; | ||
169 | |||
170 | #define DAVINCI_MMC_DATADIR_NONE 0 | ||
171 | #define DAVINCI_MMC_DATADIR_READ 1 | ||
172 | #define DAVINCI_MMC_DATADIR_WRITE 2 | ||
173 | unsigned char data_dir; | ||
174 | |||
175 | /* buffer is used during PIO of one scatterlist segment, and | ||
176 | * is updated along with buffer_bytes_left. bytes_left applies | ||
177 | * to all N blocks of the PIO transfer. | ||
178 | */ | ||
179 | u8 *buffer; | ||
180 | u32 buffer_bytes_left; | ||
181 | u32 bytes_left; | ||
182 | |||
183 | u32 rxdma, txdma; | ||
184 | bool use_dma; | ||
185 | bool do_dma; | ||
186 | |||
187 | /* Scatterlist DMA uses one or more parameter RAM entries: | ||
188 | * the main one (associated with rxdma or txdma) plus zero or | ||
189 | * more links. The entries for a given transfer differ only | ||
190 | * by memory buffer (address, length) and link field. | ||
191 | */ | ||
192 | struct edmacc_param tx_template; | ||
193 | struct edmacc_param rx_template; | ||
194 | unsigned n_link; | ||
195 | u32 links[NR_SG - 1]; | ||
196 | |||
197 | /* For PIO we walk scatterlists one segment at a time. */ | ||
198 | unsigned int sg_len; | ||
199 | struct scatterlist *sg; | ||
200 | |||
201 | /* Version of the MMC/SD controller */ | ||
202 | u8 version; | ||
203 | /* for ns in one cycle calculation */ | ||
204 | unsigned ns_in_one_cycle; | ||
205 | #ifdef CONFIG_CPU_FREQ | ||
206 | struct notifier_block freq_transition; | ||
207 | #endif | ||
208 | }; | ||
209 | |||
210 | |||
211 | /* PIO only */ | ||
212 | static void mmc_davinci_sg_to_buf(struct mmc_davinci_host *host) | ||
213 | { | ||
214 | host->buffer_bytes_left = sg_dma_len(host->sg); | ||
215 | host->buffer = sg_virt(host->sg); | ||
216 | if (host->buffer_bytes_left > host->bytes_left) | ||
217 | host->buffer_bytes_left = host->bytes_left; | ||
218 | } | ||
219 | |||
220 | static void davinci_fifo_data_trans(struct mmc_davinci_host *host, | ||
221 | unsigned int n) | ||
222 | { | ||
223 | u8 *p; | ||
224 | unsigned int i; | ||
225 | |||
226 | if (host->buffer_bytes_left == 0) { | ||
227 | host->sg = sg_next(host->data->sg); | ||
228 | mmc_davinci_sg_to_buf(host); | ||
229 | } | ||
230 | |||
231 | p = host->buffer; | ||
232 | if (n > host->buffer_bytes_left) | ||
233 | n = host->buffer_bytes_left; | ||
234 | host->buffer_bytes_left -= n; | ||
235 | host->bytes_left -= n; | ||
236 | |||
237 | /* NOTE: we never transfer more than rw_threshold bytes | ||
238 | * to/from the fifo here; there's no I/O overlap. | ||
239 | * This also assumes that access width( i.e. ACCWD) is 4 bytes | ||
240 | */ | ||
241 | if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) { | ||
242 | for (i = 0; i < (n >> 2); i++) { | ||
243 | writel(*((u32 *)p), host->base + DAVINCI_MMCDXR); | ||
244 | p = p + 4; | ||
245 | } | ||
246 | if (n & 3) { | ||
247 | iowrite8_rep(host->base + DAVINCI_MMCDXR, p, (n & 3)); | ||
248 | p = p + (n & 3); | ||
249 | } | ||
250 | } else { | ||
251 | for (i = 0; i < (n >> 2); i++) { | ||
252 | *((u32 *)p) = readl(host->base + DAVINCI_MMCDRR); | ||
253 | p = p + 4; | ||
254 | } | ||
255 | if (n & 3) { | ||
256 | ioread8_rep(host->base + DAVINCI_MMCDRR, p, (n & 3)); | ||
257 | p = p + (n & 3); | ||
258 | } | ||
259 | } | ||
260 | host->buffer = p; | ||
261 | } | ||
262 | |||
263 | static void mmc_davinci_start_command(struct mmc_davinci_host *host, | ||
264 | struct mmc_command *cmd) | ||
265 | { | ||
266 | u32 cmd_reg = 0; | ||
267 | u32 im_val; | ||
268 | |||
269 | dev_dbg(mmc_dev(host->mmc), "CMD%d, arg 0x%08x%s\n", | ||
270 | cmd->opcode, cmd->arg, | ||
271 | ({ char *s; | ||
272 | switch (mmc_resp_type(cmd)) { | ||
273 | case MMC_RSP_R1: | ||
274 | s = ", R1/R5/R6/R7 response"; | ||
275 | break; | ||
276 | case MMC_RSP_R1B: | ||
277 | s = ", R1b response"; | ||
278 | break; | ||
279 | case MMC_RSP_R2: | ||
280 | s = ", R2 response"; | ||
281 | break; | ||
282 | case MMC_RSP_R3: | ||
283 | s = ", R3/R4 response"; | ||
284 | break; | ||
285 | default: | ||
286 | s = ", (R? response)"; | ||
287 | break; | ||
288 | }; s; })); | ||
289 | host->cmd = cmd; | ||
290 | |||
291 | switch (mmc_resp_type(cmd)) { | ||
292 | case MMC_RSP_R1B: | ||
293 | /* There's some spec confusion about when R1B is | ||
294 | * allowed, but if the card doesn't issue a BUSY | ||
295 | * then it's harmless for us to allow it. | ||
296 | */ | ||
297 | cmd_reg |= MMCCMD_BSYEXP; | ||
298 | /* FALLTHROUGH */ | ||
299 | case MMC_RSP_R1: /* 48 bits, CRC */ | ||
300 | cmd_reg |= MMCCMD_RSPFMT_R1456; | ||
301 | break; | ||
302 | case MMC_RSP_R2: /* 136 bits, CRC */ | ||
303 | cmd_reg |= MMCCMD_RSPFMT_R2; | ||
304 | break; | ||
305 | case MMC_RSP_R3: /* 48 bits, no CRC */ | ||
306 | cmd_reg |= MMCCMD_RSPFMT_R3; | ||
307 | break; | ||
308 | default: | ||
309 | cmd_reg |= MMCCMD_RSPFMT_NONE; | ||
310 | dev_dbg(mmc_dev(host->mmc), "unknown resp_type %04x\n", | ||
311 | mmc_resp_type(cmd)); | ||
312 | break; | ||
313 | } | ||
314 | |||
315 | /* Set command index */ | ||
316 | cmd_reg |= cmd->opcode; | ||
317 | |||
318 | /* Enable EDMA transfer triggers */ | ||
319 | if (host->do_dma) | ||
320 | cmd_reg |= MMCCMD_DMATRIG; | ||
321 | |||
322 | if (host->version == MMC_CTLR_VERSION_2 && host->data != NULL && | ||
323 | host->data_dir == DAVINCI_MMC_DATADIR_READ) | ||
324 | cmd_reg |= MMCCMD_DMATRIG; | ||
325 | |||
326 | /* Setting whether command involves data transfer or not */ | ||
327 | if (cmd->data) | ||
328 | cmd_reg |= MMCCMD_WDATX; | ||
329 | |||
330 | /* Setting whether stream or block transfer */ | ||
331 | if (cmd->flags & MMC_DATA_STREAM) | ||
332 | cmd_reg |= MMCCMD_STRMTP; | ||
333 | |||
334 | /* Setting whether data read or write */ | ||
335 | if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) | ||
336 | cmd_reg |= MMCCMD_DTRW; | ||
337 | |||
338 | if (host->bus_mode == MMC_BUSMODE_PUSHPULL) | ||
339 | cmd_reg |= MMCCMD_PPLEN; | ||
340 | |||
341 | /* set Command timeout */ | ||
342 | writel(0x1FFF, host->base + DAVINCI_MMCTOR); | ||
343 | |||
344 | /* Enable interrupt (calculate here, defer until FIFO is stuffed). */ | ||
345 | im_val = MMCST0_RSPDNE | MMCST0_CRCRS | MMCST0_TOUTRS; | ||
346 | if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) { | ||
347 | im_val |= MMCST0_DATDNE | MMCST0_CRCWR; | ||
348 | |||
349 | if (!host->do_dma) | ||
350 | im_val |= MMCST0_DXRDY; | ||
351 | } else if (host->data_dir == DAVINCI_MMC_DATADIR_READ) { | ||
352 | im_val |= MMCST0_DATDNE | MMCST0_CRCRD | MMCST0_TOUTRD; | ||
353 | |||
354 | if (!host->do_dma) | ||
355 | im_val |= MMCST0_DRRDY; | ||
356 | } | ||
357 | |||
358 | /* | ||
359 | * Before non-DMA WRITE commands the controller needs priming: | ||
360 | * FIFO should be populated with 32 bytes i.e. whatever is the FIFO size | ||
361 | */ | ||
362 | if (!host->do_dma && (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)) | ||
363 | davinci_fifo_data_trans(host, rw_threshold); | ||
364 | |||
365 | writel(cmd->arg, host->base + DAVINCI_MMCARGHL); | ||
366 | writel(cmd_reg, host->base + DAVINCI_MMCCMD); | ||
367 | writel(im_val, host->base + DAVINCI_MMCIM); | ||
368 | } | ||
369 | |||
370 | /*----------------------------------------------------------------------*/ | ||
371 | |||
372 | /* DMA infrastructure */ | ||
373 | |||
374 | static void davinci_abort_dma(struct mmc_davinci_host *host) | ||
375 | { | ||
376 | int sync_dev; | ||
377 | |||
378 | if (host->data_dir == DAVINCI_MMC_DATADIR_READ) | ||
379 | sync_dev = host->rxdma; | ||
380 | else | ||
381 | sync_dev = host->txdma; | ||
382 | |||
383 | edma_stop(sync_dev); | ||
384 | edma_clean_channel(sync_dev); | ||
385 | } | ||
386 | |||
387 | static void | ||
388 | mmc_davinci_xfer_done(struct mmc_davinci_host *host, struct mmc_data *data); | ||
389 | |||
390 | static void mmc_davinci_dma_cb(unsigned channel, u16 ch_status, void *data) | ||
391 | { | ||
392 | if (DMA_COMPLETE != ch_status) { | ||
393 | struct mmc_davinci_host *host = data; | ||
394 | |||
395 | /* Currently means: DMA Event Missed, or "null" transfer | ||
396 | * request was seen. In the future, TC errors (like bad | ||
397 | * addresses) might be presented too. | ||
398 | */ | ||
399 | dev_warn(mmc_dev(host->mmc), "DMA %s error\n", | ||
400 | (host->data->flags & MMC_DATA_WRITE) | ||
401 | ? "write" : "read"); | ||
402 | host->data->error = -EIO; | ||
403 | mmc_davinci_xfer_done(host, host->data); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | /* Set up tx or rx template, to be modified and updated later */ | ||
408 | static void __init mmc_davinci_dma_setup(struct mmc_davinci_host *host, | ||
409 | bool tx, struct edmacc_param *template) | ||
410 | { | ||
411 | unsigned sync_dev; | ||
412 | const u16 acnt = 4; | ||
413 | const u16 bcnt = rw_threshold >> 2; | ||
414 | const u16 ccnt = 0; | ||
415 | u32 src_port = 0; | ||
416 | u32 dst_port = 0; | ||
417 | s16 src_bidx, dst_bidx; | ||
418 | s16 src_cidx, dst_cidx; | ||
419 | |||
420 | /* | ||
421 | * A-B Sync transfer: each DMA request is for one "frame" of | ||
422 | * rw_threshold bytes, broken into "acnt"-size chunks repeated | ||
423 | * "bcnt" times. Each segment needs "ccnt" such frames; since | ||
424 | * we tell the block layer our mmc->max_seg_size limit, we can | ||
425 | * trust (later) that it's within bounds. | ||
426 | * | ||
427 | * The FIFOs are read/written in 4-byte chunks (acnt == 4) and | ||
428 | * EDMA will optimize memory operations to use larger bursts. | ||
429 | */ | ||
430 | if (tx) { | ||
431 | sync_dev = host->txdma; | ||
432 | |||
433 | /* src_prt, ccnt, and link to be set up later */ | ||
434 | src_bidx = acnt; | ||
435 | src_cidx = acnt * bcnt; | ||
436 | |||
437 | dst_port = host->mem_res->start + DAVINCI_MMCDXR; | ||
438 | dst_bidx = 0; | ||
439 | dst_cidx = 0; | ||
440 | } else { | ||
441 | sync_dev = host->rxdma; | ||
442 | |||
443 | src_port = host->mem_res->start + DAVINCI_MMCDRR; | ||
444 | src_bidx = 0; | ||
445 | src_cidx = 0; | ||
446 | |||
447 | /* dst_prt, ccnt, and link to be set up later */ | ||
448 | dst_bidx = acnt; | ||
449 | dst_cidx = acnt * bcnt; | ||
450 | } | ||
451 | |||
452 | /* | ||
453 | * We can't use FIFO mode for the FIFOs because MMC FIFO addresses | ||
454 | * are not 256-bit (32-byte) aligned. So we use INCR, and the W8BIT | ||
455 | * parameter is ignored. | ||
456 | */ | ||
457 | edma_set_src(sync_dev, src_port, INCR, W8BIT); | ||
458 | edma_set_dest(sync_dev, dst_port, INCR, W8BIT); | ||
459 | |||
460 | edma_set_src_index(sync_dev, src_bidx, src_cidx); | ||
461 | edma_set_dest_index(sync_dev, dst_bidx, dst_cidx); | ||
462 | |||
463 | edma_set_transfer_params(sync_dev, acnt, bcnt, ccnt, 8, ABSYNC); | ||
464 | |||
465 | edma_read_slot(sync_dev, template); | ||
466 | |||
467 | /* don't bother with irqs or chaining */ | ||
468 | template->opt |= EDMA_CHAN_SLOT(sync_dev) << 12; | ||
469 | } | ||
470 | |||
471 | static void mmc_davinci_send_dma_request(struct mmc_davinci_host *host, | ||
472 | struct mmc_data *data) | ||
473 | { | ||
474 | struct edmacc_param *template; | ||
475 | int channel, slot; | ||
476 | unsigned link; | ||
477 | struct scatterlist *sg; | ||
478 | unsigned sg_len; | ||
479 | unsigned bytes_left = host->bytes_left; | ||
480 | const unsigned shift = ffs(rw_threshold) - 1;; | ||
481 | |||
482 | if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) { | ||
483 | template = &host->tx_template; | ||
484 | channel = host->txdma; | ||
485 | } else { | ||
486 | template = &host->rx_template; | ||
487 | channel = host->rxdma; | ||
488 | } | ||
489 | |||
490 | /* We know sg_len and ccnt will never be out of range because | ||
491 | * we told the mmc layer which in turn tells the block layer | ||
492 | * to ensure that it only hands us one scatterlist segment | ||
493 | * per EDMA PARAM entry. Update the PARAM | ||
494 | * entries needed for each segment of this scatterlist. | ||
495 | */ | ||
496 | for (slot = channel, link = 0, sg = data->sg, sg_len = host->sg_len; | ||
497 | sg_len-- != 0 && bytes_left; | ||
498 | sg = sg_next(sg), slot = host->links[link++]) { | ||
499 | u32 buf = sg_dma_address(sg); | ||
500 | unsigned count = sg_dma_len(sg); | ||
501 | |||
502 | template->link_bcntrld = sg_len | ||
503 | ? (EDMA_CHAN_SLOT(host->links[link]) << 5) | ||
504 | : 0xffff; | ||
505 | |||
506 | if (count > bytes_left) | ||
507 | count = bytes_left; | ||
508 | bytes_left -= count; | ||
509 | |||
510 | if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) | ||
511 | template->src = buf; | ||
512 | else | ||
513 | template->dst = buf; | ||
514 | template->ccnt = count >> shift; | ||
515 | |||
516 | edma_write_slot(slot, template); | ||
517 | } | ||
518 | |||
519 | if (host->version == MMC_CTLR_VERSION_2) | ||
520 | edma_clear_event(channel); | ||
521 | |||
522 | edma_start(channel); | ||
523 | } | ||
524 | |||
525 | static int mmc_davinci_start_dma_transfer(struct mmc_davinci_host *host, | ||
526 | struct mmc_data *data) | ||
527 | { | ||
528 | int i; | ||
529 | int mask = rw_threshold - 1; | ||
530 | |||
531 | host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, | ||
532 | ((data->flags & MMC_DATA_WRITE) | ||
533 | ? DMA_TO_DEVICE | ||
534 | : DMA_FROM_DEVICE)); | ||
535 | |||
536 | /* no individual DMA segment should need a partial FIFO */ | ||
537 | for (i = 0; i < host->sg_len; i++) { | ||
538 | if (sg_dma_len(data->sg + i) & mask) { | ||
539 | dma_unmap_sg(mmc_dev(host->mmc), | ||
540 | data->sg, data->sg_len, | ||
541 | (data->flags & MMC_DATA_WRITE) | ||
542 | ? DMA_TO_DEVICE | ||
543 | : DMA_FROM_DEVICE); | ||
544 | return -1; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | host->do_dma = 1; | ||
549 | mmc_davinci_send_dma_request(host, data); | ||
550 | |||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | static void __init_or_module | ||
555 | davinci_release_dma_channels(struct mmc_davinci_host *host) | ||
556 | { | ||
557 | unsigned i; | ||
558 | |||
559 | if (!host->use_dma) | ||
560 | return; | ||
561 | |||
562 | for (i = 0; i < host->n_link; i++) | ||
563 | edma_free_slot(host->links[i]); | ||
564 | |||
565 | edma_free_channel(host->txdma); | ||
566 | edma_free_channel(host->rxdma); | ||
567 | } | ||
568 | |||
569 | static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host) | ||
570 | { | ||
571 | int r, i; | ||
572 | |||
573 | /* Acquire master DMA write channel */ | ||
574 | r = edma_alloc_channel(host->txdma, mmc_davinci_dma_cb, host, | ||
575 | EVENTQ_DEFAULT); | ||
576 | if (r < 0) { | ||
577 | dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n", | ||
578 | "tx", r); | ||
579 | return r; | ||
580 | } | ||
581 | mmc_davinci_dma_setup(host, true, &host->tx_template); | ||
582 | |||
583 | /* Acquire master DMA read channel */ | ||
584 | r = edma_alloc_channel(host->rxdma, mmc_davinci_dma_cb, host, | ||
585 | EVENTQ_DEFAULT); | ||
586 | if (r < 0) { | ||
587 | dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n", | ||
588 | "rx", r); | ||
589 | goto free_master_write; | ||
590 | } | ||
591 | mmc_davinci_dma_setup(host, false, &host->rx_template); | ||
592 | |||
593 | /* Allocate parameter RAM slots, which will later be bound to a | ||
594 | * channel as needed to handle a scatterlist. | ||
595 | */ | ||
596 | for (i = 0; i < ARRAY_SIZE(host->links); i++) { | ||
597 | r = edma_alloc_slot(EDMA_CTLR(host->txdma), EDMA_SLOT_ANY); | ||
598 | if (r < 0) { | ||
599 | dev_dbg(mmc_dev(host->mmc), "dma PaRAM alloc --> %d\n", | ||
600 | r); | ||
601 | break; | ||
602 | } | ||
603 | host->links[i] = r; | ||
604 | } | ||
605 | host->n_link = i; | ||
606 | |||
607 | return 0; | ||
608 | |||
609 | free_master_write: | ||
610 | edma_free_channel(host->txdma); | ||
611 | |||
612 | return r; | ||
613 | } | ||
614 | |||
615 | /*----------------------------------------------------------------------*/ | ||
616 | |||
617 | static void | ||
618 | mmc_davinci_prepare_data(struct mmc_davinci_host *host, struct mmc_request *req) | ||
619 | { | ||
620 | int fifo_lev = (rw_threshold == 32) ? MMCFIFOCTL_FIFOLEV : 0; | ||
621 | int timeout; | ||
622 | struct mmc_data *data = req->data; | ||
623 | |||
624 | if (host->version == MMC_CTLR_VERSION_2) | ||
625 | fifo_lev = (rw_threshold == 64) ? MMCFIFOCTL_FIFOLEV : 0; | ||
626 | |||
627 | host->data = data; | ||
628 | if (data == NULL) { | ||
629 | host->data_dir = DAVINCI_MMC_DATADIR_NONE; | ||
630 | writel(0, host->base + DAVINCI_MMCBLEN); | ||
631 | writel(0, host->base + DAVINCI_MMCNBLK); | ||
632 | return; | ||
633 | } | ||
634 | |||
635 | dev_dbg(mmc_dev(host->mmc), "%s %s, %d blocks of %d bytes\n", | ||
636 | (data->flags & MMC_DATA_STREAM) ? "stream" : "block", | ||
637 | (data->flags & MMC_DATA_WRITE) ? "write" : "read", | ||
638 | data->blocks, data->blksz); | ||
639 | dev_dbg(mmc_dev(host->mmc), " DTO %d cycles + %d ns\n", | ||
640 | data->timeout_clks, data->timeout_ns); | ||
641 | timeout = data->timeout_clks + | ||
642 | (data->timeout_ns / host->ns_in_one_cycle); | ||
643 | if (timeout > 0xffff) | ||
644 | timeout = 0xffff; | ||
645 | |||
646 | writel(timeout, host->base + DAVINCI_MMCTOD); | ||
647 | writel(data->blocks, host->base + DAVINCI_MMCNBLK); | ||
648 | writel(data->blksz, host->base + DAVINCI_MMCBLEN); | ||
649 | |||
650 | /* Configure the FIFO */ | ||
651 | switch (data->flags & MMC_DATA_WRITE) { | ||
652 | case MMC_DATA_WRITE: | ||
653 | host->data_dir = DAVINCI_MMC_DATADIR_WRITE; | ||
654 | writel(fifo_lev | MMCFIFOCTL_FIFODIR_WR | MMCFIFOCTL_FIFORST, | ||
655 | host->base + DAVINCI_MMCFIFOCTL); | ||
656 | writel(fifo_lev | MMCFIFOCTL_FIFODIR_WR, | ||
657 | host->base + DAVINCI_MMCFIFOCTL); | ||
658 | break; | ||
659 | |||
660 | default: | ||
661 | host->data_dir = DAVINCI_MMC_DATADIR_READ; | ||
662 | writel(fifo_lev | MMCFIFOCTL_FIFODIR_RD | MMCFIFOCTL_FIFORST, | ||
663 | host->base + DAVINCI_MMCFIFOCTL); | ||
664 | writel(fifo_lev | MMCFIFOCTL_FIFODIR_RD, | ||
665 | host->base + DAVINCI_MMCFIFOCTL); | ||
666 | break; | ||
667 | } | ||
668 | |||
669 | host->buffer = NULL; | ||
670 | host->bytes_left = data->blocks * data->blksz; | ||
671 | |||
672 | /* For now we try to use DMA whenever we won't need partial FIFO | ||
673 | * reads or writes, either for the whole transfer (as tested here) | ||
674 | * or for any individual scatterlist segment (tested when we call | ||
675 | * start_dma_transfer). | ||
676 | * | ||
677 | * While we *could* change that, unusual block sizes are rarely | ||
678 | * used. The occasional fallback to PIO should't hurt. | ||
679 | */ | ||
680 | if (host->use_dma && (host->bytes_left & (rw_threshold - 1)) == 0 | ||
681 | && mmc_davinci_start_dma_transfer(host, data) == 0) { | ||
682 | /* zero this to ensure we take no PIO paths */ | ||
683 | host->bytes_left = 0; | ||
684 | } else { | ||
685 | /* Revert to CPU Copy */ | ||
686 | host->sg_len = data->sg_len; | ||
687 | host->sg = host->data->sg; | ||
688 | mmc_davinci_sg_to_buf(host); | ||
689 | } | ||
690 | } | ||
691 | |||
692 | static void mmc_davinci_request(struct mmc_host *mmc, struct mmc_request *req) | ||
693 | { | ||
694 | struct mmc_davinci_host *host = mmc_priv(mmc); | ||
695 | unsigned long timeout = jiffies + msecs_to_jiffies(900); | ||
696 | u32 mmcst1 = 0; | ||
697 | |||
698 | /* Card may still be sending BUSY after a previous operation, | ||
699 | * typically some kind of write. If so, we can't proceed yet. | ||
700 | */ | ||
701 | while (time_before(jiffies, timeout)) { | ||
702 | mmcst1 = readl(host->base + DAVINCI_MMCST1); | ||
703 | if (!(mmcst1 & MMCST1_BUSY)) | ||
704 | break; | ||
705 | cpu_relax(); | ||
706 | } | ||
707 | if (mmcst1 & MMCST1_BUSY) { | ||
708 | dev_err(mmc_dev(host->mmc), "still BUSY? bad ... \n"); | ||
709 | req->cmd->error = -ETIMEDOUT; | ||
710 | mmc_request_done(mmc, req); | ||
711 | return; | ||
712 | } | ||
713 | |||
714 | host->do_dma = 0; | ||
715 | mmc_davinci_prepare_data(host, req); | ||
716 | mmc_davinci_start_command(host, req->cmd); | ||
717 | } | ||
718 | |||
719 | static unsigned int calculate_freq_for_card(struct mmc_davinci_host *host, | ||
720 | unsigned int mmc_req_freq) | ||
721 | { | ||
722 | unsigned int mmc_freq = 0, mmc_pclk = 0, mmc_push_pull_divisor = 0; | ||
723 | |||
724 | mmc_pclk = host->mmc_input_clk; | ||
725 | if (mmc_req_freq && mmc_pclk > (2 * mmc_req_freq)) | ||
726 | mmc_push_pull_divisor = ((unsigned int)mmc_pclk | ||
727 | / (2 * mmc_req_freq)) - 1; | ||
728 | else | ||
729 | mmc_push_pull_divisor = 0; | ||
730 | |||
731 | mmc_freq = (unsigned int)mmc_pclk | ||
732 | / (2 * (mmc_push_pull_divisor + 1)); | ||
733 | |||
734 | if (mmc_freq > mmc_req_freq) | ||
735 | mmc_push_pull_divisor = mmc_push_pull_divisor + 1; | ||
736 | /* Convert ns to clock cycles */ | ||
737 | if (mmc_req_freq <= 400000) | ||
738 | host->ns_in_one_cycle = (1000000) / (((mmc_pclk | ||
739 | / (2 * (mmc_push_pull_divisor + 1)))/1000)); | ||
740 | else | ||
741 | host->ns_in_one_cycle = (1000000) / (((mmc_pclk | ||
742 | / (2 * (mmc_push_pull_divisor + 1)))/1000000)); | ||
743 | |||
744 | return mmc_push_pull_divisor; | ||
745 | } | ||
746 | |||
747 | static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios) | ||
748 | { | ||
749 | unsigned int open_drain_freq = 0, mmc_pclk = 0; | ||
750 | unsigned int mmc_push_pull_freq = 0; | ||
751 | struct mmc_davinci_host *host = mmc_priv(mmc); | ||
752 | |||
753 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { | ||
754 | u32 temp; | ||
755 | |||
756 | /* Ignoring the init clock value passed for fixing the inter | ||
757 | * operability with different cards. | ||
758 | */ | ||
759 | open_drain_freq = ((unsigned int)mmc_pclk | ||
760 | / (2 * MMCSD_INIT_CLOCK)) - 1; | ||
761 | |||
762 | if (open_drain_freq > 0xFF) | ||
763 | open_drain_freq = 0xFF; | ||
764 | |||
765 | temp = readl(host->base + DAVINCI_MMCCLK) & ~MMCCLK_CLKRT_MASK; | ||
766 | temp |= open_drain_freq; | ||
767 | writel(temp, host->base + DAVINCI_MMCCLK); | ||
768 | |||
769 | /* Convert ns to clock cycles */ | ||
770 | host->ns_in_one_cycle = (1000000) / (MMCSD_INIT_CLOCK/1000); | ||
771 | } else { | ||
772 | u32 temp; | ||
773 | mmc_push_pull_freq = calculate_freq_for_card(host, ios->clock); | ||
774 | |||
775 | if (mmc_push_pull_freq > 0xFF) | ||
776 | mmc_push_pull_freq = 0xFF; | ||
777 | |||
778 | temp = readl(host->base + DAVINCI_MMCCLK) & ~MMCCLK_CLKEN; | ||
779 | writel(temp, host->base + DAVINCI_MMCCLK); | ||
780 | |||
781 | udelay(10); | ||
782 | |||
783 | temp = readl(host->base + DAVINCI_MMCCLK) & ~MMCCLK_CLKRT_MASK; | ||
784 | temp |= mmc_push_pull_freq; | ||
785 | writel(temp, host->base + DAVINCI_MMCCLK); | ||
786 | |||
787 | writel(temp | MMCCLK_CLKEN, host->base + DAVINCI_MMCCLK); | ||
788 | |||
789 | udelay(10); | ||
790 | } | ||
791 | } | ||
792 | |||
793 | static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
794 | { | ||
795 | struct mmc_davinci_host *host = mmc_priv(mmc); | ||
796 | |||
797 | dev_dbg(mmc_dev(host->mmc), | ||
798 | "clock %dHz busmode %d powermode %d Vdd %04x\n", | ||
799 | ios->clock, ios->bus_mode, ios->power_mode, | ||
800 | ios->vdd); | ||
801 | |||
802 | switch (ios->bus_width) { | ||
803 | case MMC_BUS_WIDTH_8: | ||
804 | dev_dbg(mmc_dev(host->mmc), "Enabling 8 bit mode\n"); | ||
805 | writel((readl(host->base + DAVINCI_MMCCTL) & | ||
806 | ~MMCCTL_WIDTH_4_BIT) | MMCCTL_WIDTH_8_BIT, | ||
807 | host->base + DAVINCI_MMCCTL); | ||
808 | break; | ||
809 | case MMC_BUS_WIDTH_4: | ||
810 | dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n"); | ||
811 | if (host->version == MMC_CTLR_VERSION_2) | ||
812 | writel((readl(host->base + DAVINCI_MMCCTL) & | ||
813 | ~MMCCTL_WIDTH_8_BIT) | MMCCTL_WIDTH_4_BIT, | ||
814 | host->base + DAVINCI_MMCCTL); | ||
815 | else | ||
816 | writel(readl(host->base + DAVINCI_MMCCTL) | | ||
817 | MMCCTL_WIDTH_4_BIT, | ||
818 | host->base + DAVINCI_MMCCTL); | ||
819 | break; | ||
820 | case MMC_BUS_WIDTH_1: | ||
821 | dev_dbg(mmc_dev(host->mmc), "Enabling 1 bit mode\n"); | ||
822 | if (host->version == MMC_CTLR_VERSION_2) | ||
823 | writel(readl(host->base + DAVINCI_MMCCTL) & | ||
824 | ~(MMCCTL_WIDTH_8_BIT | MMCCTL_WIDTH_4_BIT), | ||
825 | host->base + DAVINCI_MMCCTL); | ||
826 | else | ||
827 | writel(readl(host->base + DAVINCI_MMCCTL) & | ||
828 | ~MMCCTL_WIDTH_4_BIT, | ||
829 | host->base + DAVINCI_MMCCTL); | ||
830 | break; | ||
831 | } | ||
832 | |||
833 | calculate_clk_divider(mmc, ios); | ||
834 | |||
835 | host->bus_mode = ios->bus_mode; | ||
836 | if (ios->power_mode == MMC_POWER_UP) { | ||
837 | unsigned long timeout = jiffies + msecs_to_jiffies(50); | ||
838 | bool lose = true; | ||
839 | |||
840 | /* Send clock cycles, poll completion */ | ||
841 | writel(0, host->base + DAVINCI_MMCARGHL); | ||
842 | writel(MMCCMD_INITCK, host->base + DAVINCI_MMCCMD); | ||
843 | while (time_before(jiffies, timeout)) { | ||
844 | u32 tmp = readl(host->base + DAVINCI_MMCST0); | ||
845 | |||
846 | if (tmp & MMCST0_RSPDNE) { | ||
847 | lose = false; | ||
848 | break; | ||
849 | } | ||
850 | cpu_relax(); | ||
851 | } | ||
852 | if (lose) | ||
853 | dev_warn(mmc_dev(host->mmc), "powerup timeout\n"); | ||
854 | } | ||
855 | |||
856 | /* FIXME on power OFF, reset things ... */ | ||
857 | } | ||
858 | |||
859 | static void | ||
860 | mmc_davinci_xfer_done(struct mmc_davinci_host *host, struct mmc_data *data) | ||
861 | { | ||
862 | host->data = NULL; | ||
863 | |||
864 | if (host->do_dma) { | ||
865 | davinci_abort_dma(host); | ||
866 | |||
867 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, | ||
868 | (data->flags & MMC_DATA_WRITE) | ||
869 | ? DMA_TO_DEVICE | ||
870 | : DMA_FROM_DEVICE); | ||
871 | host->do_dma = false; | ||
872 | } | ||
873 | host->data_dir = DAVINCI_MMC_DATADIR_NONE; | ||
874 | |||
875 | if (!data->stop || (host->cmd && host->cmd->error)) { | ||
876 | mmc_request_done(host->mmc, data->mrq); | ||
877 | writel(0, host->base + DAVINCI_MMCIM); | ||
878 | } else | ||
879 | mmc_davinci_start_command(host, data->stop); | ||
880 | } | ||
881 | |||
882 | static void mmc_davinci_cmd_done(struct mmc_davinci_host *host, | ||
883 | struct mmc_command *cmd) | ||
884 | { | ||
885 | host->cmd = NULL; | ||
886 | |||
887 | if (cmd->flags & MMC_RSP_PRESENT) { | ||
888 | if (cmd->flags & MMC_RSP_136) { | ||
889 | /* response type 2 */ | ||
890 | cmd->resp[3] = readl(host->base + DAVINCI_MMCRSP01); | ||
891 | cmd->resp[2] = readl(host->base + DAVINCI_MMCRSP23); | ||
892 | cmd->resp[1] = readl(host->base + DAVINCI_MMCRSP45); | ||
893 | cmd->resp[0] = readl(host->base + DAVINCI_MMCRSP67); | ||
894 | } else { | ||
895 | /* response types 1, 1b, 3, 4, 5, 6 */ | ||
896 | cmd->resp[0] = readl(host->base + DAVINCI_MMCRSP67); | ||
897 | } | ||
898 | } | ||
899 | |||
900 | if (host->data == NULL || cmd->error) { | ||
901 | if (cmd->error == -ETIMEDOUT) | ||
902 | cmd->mrq->cmd->retries = 0; | ||
903 | mmc_request_done(host->mmc, cmd->mrq); | ||
904 | writel(0, host->base + DAVINCI_MMCIM); | ||
905 | } | ||
906 | } | ||
907 | |||
908 | static void | ||
909 | davinci_abort_data(struct mmc_davinci_host *host, struct mmc_data *data) | ||
910 | { | ||
911 | u32 temp; | ||
912 | |||
913 | /* reset command and data state machines */ | ||
914 | temp = readl(host->base + DAVINCI_MMCCTL); | ||
915 | writel(temp | MMCCTL_CMDRST | MMCCTL_DATRST, | ||
916 | host->base + DAVINCI_MMCCTL); | ||
917 | |||
918 | temp &= ~(MMCCTL_CMDRST | MMCCTL_DATRST); | ||
919 | udelay(10); | ||
920 | writel(temp, host->base + DAVINCI_MMCCTL); | ||
921 | } | ||
922 | |||
923 | static irqreturn_t mmc_davinci_irq(int irq, void *dev_id) | ||
924 | { | ||
925 | struct mmc_davinci_host *host = (struct mmc_davinci_host *)dev_id; | ||
926 | unsigned int status, qstatus; | ||
927 | int end_command = 0; | ||
928 | int end_transfer = 0; | ||
929 | struct mmc_data *data = host->data; | ||
930 | |||
931 | if (host->cmd == NULL && host->data == NULL) { | ||
932 | status = readl(host->base + DAVINCI_MMCST0); | ||
933 | dev_dbg(mmc_dev(host->mmc), | ||
934 | "Spurious interrupt 0x%04x\n", status); | ||
935 | /* Disable the interrupt from mmcsd */ | ||
936 | writel(0, host->base + DAVINCI_MMCIM); | ||
937 | return IRQ_NONE; | ||
938 | } | ||
939 | |||
940 | status = readl(host->base + DAVINCI_MMCST0); | ||
941 | qstatus = status; | ||
942 | |||
943 | /* handle FIFO first when using PIO for data. | ||
944 | * bytes_left will decrease to zero as I/O progress and status will | ||
945 | * read zero over iteration because this controller status | ||
946 | * register(MMCST0) reports any status only once and it is cleared | ||
947 | * by read. So, it is not unbouned loop even in the case of | ||
948 | * non-dma. | ||
949 | */ | ||
950 | while (host->bytes_left && (status & (MMCST0_DXRDY | MMCST0_DRRDY))) { | ||
951 | davinci_fifo_data_trans(host, rw_threshold); | ||
952 | status = readl(host->base + DAVINCI_MMCST0); | ||
953 | if (!status) | ||
954 | break; | ||
955 | qstatus |= status; | ||
956 | } | ||
957 | |||
958 | if (qstatus & MMCST0_DATDNE) { | ||
959 | /* All blocks sent/received, and CRC checks passed */ | ||
960 | if (data != NULL) { | ||
961 | if ((host->do_dma == 0) && (host->bytes_left > 0)) { | ||
962 | /* if datasize < rw_threshold | ||
963 | * no RX ints are generated | ||
964 | */ | ||
965 | davinci_fifo_data_trans(host, host->bytes_left); | ||
966 | } | ||
967 | end_transfer = 1; | ||
968 | data->bytes_xfered = data->blocks * data->blksz; | ||
969 | } else { | ||
970 | dev_err(mmc_dev(host->mmc), | ||
971 | "DATDNE with no host->data\n"); | ||
972 | } | ||
973 | } | ||
974 | |||
975 | if (qstatus & MMCST0_TOUTRD) { | ||
976 | /* Read data timeout */ | ||
977 | data->error = -ETIMEDOUT; | ||
978 | end_transfer = 1; | ||
979 | |||
980 | dev_dbg(mmc_dev(host->mmc), | ||
981 | "read data timeout, status %x\n", | ||
982 | qstatus); | ||
983 | |||
984 | davinci_abort_data(host, data); | ||
985 | } | ||
986 | |||
987 | if (qstatus & (MMCST0_CRCWR | MMCST0_CRCRD)) { | ||
988 | /* Data CRC error */ | ||
989 | data->error = -EILSEQ; | ||
990 | end_transfer = 1; | ||
991 | |||
992 | /* NOTE: this controller uses CRCWR to report both CRC | ||
993 | * errors and timeouts (on writes). MMCDRSP values are | ||
994 | * only weakly documented, but 0x9f was clearly a timeout | ||
995 | * case and the two three-bit patterns in various SD specs | ||
996 | * (101, 010) aren't part of it ... | ||
997 | */ | ||
998 | if (qstatus & MMCST0_CRCWR) { | ||
999 | u32 temp = readb(host->base + DAVINCI_MMCDRSP); | ||
1000 | |||
1001 | if (temp == 0x9f) | ||
1002 | data->error = -ETIMEDOUT; | ||
1003 | } | ||
1004 | dev_dbg(mmc_dev(host->mmc), "data %s %s error\n", | ||
1005 | (qstatus & MMCST0_CRCWR) ? "write" : "read", | ||
1006 | (data->error == -ETIMEDOUT) ? "timeout" : "CRC"); | ||
1007 | |||
1008 | davinci_abort_data(host, data); | ||
1009 | } | ||
1010 | |||
1011 | if (qstatus & MMCST0_TOUTRS) { | ||
1012 | /* Command timeout */ | ||
1013 | if (host->cmd) { | ||
1014 | dev_dbg(mmc_dev(host->mmc), | ||
1015 | "CMD%d timeout, status %x\n", | ||
1016 | host->cmd->opcode, qstatus); | ||
1017 | host->cmd->error = -ETIMEDOUT; | ||
1018 | if (data) { | ||
1019 | end_transfer = 1; | ||
1020 | davinci_abort_data(host, data); | ||
1021 | } else | ||
1022 | end_command = 1; | ||
1023 | } | ||
1024 | } | ||
1025 | |||
1026 | if (qstatus & MMCST0_CRCRS) { | ||
1027 | /* Command CRC error */ | ||
1028 | dev_dbg(mmc_dev(host->mmc), "Command CRC error\n"); | ||
1029 | if (host->cmd) { | ||
1030 | host->cmd->error = -EILSEQ; | ||
1031 | end_command = 1; | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | if (qstatus & MMCST0_RSPDNE) { | ||
1036 | /* End of command phase */ | ||
1037 | end_command = (int) host->cmd; | ||
1038 | } | ||
1039 | |||
1040 | if (end_command) | ||
1041 | mmc_davinci_cmd_done(host, host->cmd); | ||
1042 | if (end_transfer) | ||
1043 | mmc_davinci_xfer_done(host, data); | ||
1044 | return IRQ_HANDLED; | ||
1045 | } | ||
1046 | |||
1047 | static int mmc_davinci_get_cd(struct mmc_host *mmc) | ||
1048 | { | ||
1049 | struct platform_device *pdev = to_platform_device(mmc->parent); | ||
1050 | struct davinci_mmc_config *config = pdev->dev.platform_data; | ||
1051 | |||
1052 | if (!config || !config->get_cd) | ||
1053 | return -ENOSYS; | ||
1054 | return config->get_cd(pdev->id); | ||
1055 | } | ||
1056 | |||
1057 | static int mmc_davinci_get_ro(struct mmc_host *mmc) | ||
1058 | { | ||
1059 | struct platform_device *pdev = to_platform_device(mmc->parent); | ||
1060 | struct davinci_mmc_config *config = pdev->dev.platform_data; | ||
1061 | |||
1062 | if (!config || !config->get_ro) | ||
1063 | return -ENOSYS; | ||
1064 | return config->get_ro(pdev->id); | ||
1065 | } | ||
1066 | |||
1067 | static struct mmc_host_ops mmc_davinci_ops = { | ||
1068 | .request = mmc_davinci_request, | ||
1069 | .set_ios = mmc_davinci_set_ios, | ||
1070 | .get_cd = mmc_davinci_get_cd, | ||
1071 | .get_ro = mmc_davinci_get_ro, | ||
1072 | }; | ||
1073 | |||
1074 | /*----------------------------------------------------------------------*/ | ||
1075 | |||
1076 | #ifdef CONFIG_CPU_FREQ | ||
1077 | static int mmc_davinci_cpufreq_transition(struct notifier_block *nb, | ||
1078 | unsigned long val, void *data) | ||
1079 | { | ||
1080 | struct mmc_davinci_host *host; | ||
1081 | unsigned int mmc_pclk; | ||
1082 | struct mmc_host *mmc; | ||
1083 | unsigned long flags; | ||
1084 | |||
1085 | host = container_of(nb, struct mmc_davinci_host, freq_transition); | ||
1086 | mmc = host->mmc; | ||
1087 | mmc_pclk = clk_get_rate(host->clk); | ||
1088 | |||
1089 | if (val == CPUFREQ_POSTCHANGE) { | ||
1090 | spin_lock_irqsave(&mmc->lock, flags); | ||
1091 | host->mmc_input_clk = mmc_pclk; | ||
1092 | calculate_clk_divider(mmc, &mmc->ios); | ||
1093 | spin_unlock_irqrestore(&mmc->lock, flags); | ||
1094 | } | ||
1095 | |||
1096 | return 0; | ||
1097 | } | ||
1098 | |||
1099 | static inline int mmc_davinci_cpufreq_register(struct mmc_davinci_host *host) | ||
1100 | { | ||
1101 | host->freq_transition.notifier_call = mmc_davinci_cpufreq_transition; | ||
1102 | |||
1103 | return cpufreq_register_notifier(&host->freq_transition, | ||
1104 | CPUFREQ_TRANSITION_NOTIFIER); | ||
1105 | } | ||
1106 | |||
1107 | static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host) | ||
1108 | { | ||
1109 | cpufreq_unregister_notifier(&host->freq_transition, | ||
1110 | CPUFREQ_TRANSITION_NOTIFIER); | ||
1111 | } | ||
1112 | #else | ||
1113 | static inline int mmc_davinci_cpufreq_register(struct mmc_davinci_host *host) | ||
1114 | { | ||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host) | ||
1119 | { | ||
1120 | } | ||
1121 | #endif | ||
1122 | static void __init init_mmcsd_host(struct mmc_davinci_host *host) | ||
1123 | { | ||
1124 | /* DAT line portion is diabled and in reset state */ | ||
1125 | writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_DATRST, | ||
1126 | host->base + DAVINCI_MMCCTL); | ||
1127 | |||
1128 | /* CMD line portion is diabled and in reset state */ | ||
1129 | writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_CMDRST, | ||
1130 | host->base + DAVINCI_MMCCTL); | ||
1131 | |||
1132 | udelay(10); | ||
1133 | |||
1134 | writel(0, host->base + DAVINCI_MMCCLK); | ||
1135 | writel(MMCCLK_CLKEN, host->base + DAVINCI_MMCCLK); | ||
1136 | |||
1137 | writel(0x1FFF, host->base + DAVINCI_MMCTOR); | ||
1138 | writel(0xFFFF, host->base + DAVINCI_MMCTOD); | ||
1139 | |||
1140 | writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_DATRST, | ||
1141 | host->base + DAVINCI_MMCCTL); | ||
1142 | writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_CMDRST, | ||
1143 | host->base + DAVINCI_MMCCTL); | ||
1144 | |||
1145 | udelay(10); | ||
1146 | } | ||
1147 | |||
1148 | static int __init davinci_mmcsd_probe(struct platform_device *pdev) | ||
1149 | { | ||
1150 | struct davinci_mmc_config *pdata = pdev->dev.platform_data; | ||
1151 | struct mmc_davinci_host *host = NULL; | ||
1152 | struct mmc_host *mmc = NULL; | ||
1153 | struct resource *r, *mem = NULL; | ||
1154 | int ret = 0, irq = 0; | ||
1155 | size_t mem_size; | ||
1156 | |||
1157 | /* REVISIT: when we're fully converted, fail if pdata is NULL */ | ||
1158 | |||
1159 | ret = -ENODEV; | ||
1160 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1161 | irq = platform_get_irq(pdev, 0); | ||
1162 | if (!r || irq == NO_IRQ) | ||
1163 | goto out; | ||
1164 | |||
1165 | ret = -EBUSY; | ||
1166 | mem_size = resource_size(r); | ||
1167 | mem = request_mem_region(r->start, mem_size, pdev->name); | ||
1168 | if (!mem) | ||
1169 | goto out; | ||
1170 | |||
1171 | ret = -ENOMEM; | ||
1172 | mmc = mmc_alloc_host(sizeof(struct mmc_davinci_host), &pdev->dev); | ||
1173 | if (!mmc) | ||
1174 | goto out; | ||
1175 | |||
1176 | host = mmc_priv(mmc); | ||
1177 | host->mmc = mmc; /* Important */ | ||
1178 | |||
1179 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
1180 | if (!r) | ||
1181 | goto out; | ||
1182 | host->rxdma = r->start; | ||
1183 | |||
1184 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
1185 | if (!r) | ||
1186 | goto out; | ||
1187 | host->txdma = r->start; | ||
1188 | |||
1189 | host->mem_res = mem; | ||
1190 | host->base = ioremap(mem->start, mem_size); | ||
1191 | if (!host->base) | ||
1192 | goto out; | ||
1193 | |||
1194 | ret = -ENXIO; | ||
1195 | host->clk = clk_get(&pdev->dev, "MMCSDCLK"); | ||
1196 | if (IS_ERR(host->clk)) { | ||
1197 | ret = PTR_ERR(host->clk); | ||
1198 | goto out; | ||
1199 | } | ||
1200 | clk_enable(host->clk); | ||
1201 | host->mmc_input_clk = clk_get_rate(host->clk); | ||
1202 | |||
1203 | init_mmcsd_host(host); | ||
1204 | |||
1205 | host->use_dma = use_dma; | ||
1206 | host->irq = irq; | ||
1207 | |||
1208 | if (host->use_dma && davinci_acquire_dma_channels(host) != 0) | ||
1209 | host->use_dma = 0; | ||
1210 | |||
1211 | /* REVISIT: someday, support IRQ-driven card detection. */ | ||
1212 | mmc->caps |= MMC_CAP_NEEDS_POLL; | ||
1213 | mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; | ||
1214 | |||
1215 | if (pdata && (pdata->wires == 4 || pdata->wires == 0)) | ||
1216 | mmc->caps |= MMC_CAP_4_BIT_DATA; | ||
1217 | |||
1218 | if (pdata && (pdata->wires == 8)) | ||
1219 | mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA); | ||
1220 | |||
1221 | host->version = pdata->version; | ||
1222 | |||
1223 | mmc->ops = &mmc_davinci_ops; | ||
1224 | mmc->f_min = 312500; | ||
1225 | mmc->f_max = 25000000; | ||
1226 | if (pdata && pdata->max_freq) | ||
1227 | mmc->f_max = pdata->max_freq; | ||
1228 | if (pdata && pdata->caps) | ||
1229 | mmc->caps |= pdata->caps; | ||
1230 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
1231 | |||
1232 | /* With no iommu coalescing pages, each phys_seg is a hw_seg. | ||
1233 | * Each hw_seg uses one EDMA parameter RAM slot, always one | ||
1234 | * channel and then usually some linked slots. | ||
1235 | */ | ||
1236 | mmc->max_hw_segs = 1 + host->n_link; | ||
1237 | mmc->max_phys_segs = mmc->max_hw_segs; | ||
1238 | |||
1239 | /* EDMA limit per hw segment (one or two MBytes) */ | ||
1240 | mmc->max_seg_size = MAX_CCNT * rw_threshold; | ||
1241 | |||
1242 | /* MMC/SD controller limits for multiblock requests */ | ||
1243 | mmc->max_blk_size = 4095; /* BLEN is 12 bits */ | ||
1244 | mmc->max_blk_count = 65535; /* NBLK is 16 bits */ | ||
1245 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | ||
1246 | |||
1247 | dev_dbg(mmc_dev(host->mmc), "max_phys_segs=%d\n", mmc->max_phys_segs); | ||
1248 | dev_dbg(mmc_dev(host->mmc), "max_hw_segs=%d\n", mmc->max_hw_segs); | ||
1249 | dev_dbg(mmc_dev(host->mmc), "max_blk_size=%d\n", mmc->max_blk_size); | ||
1250 | dev_dbg(mmc_dev(host->mmc), "max_req_size=%d\n", mmc->max_req_size); | ||
1251 | dev_dbg(mmc_dev(host->mmc), "max_seg_size=%d\n", mmc->max_seg_size); | ||
1252 | |||
1253 | platform_set_drvdata(pdev, host); | ||
1254 | |||
1255 | ret = mmc_davinci_cpufreq_register(host); | ||
1256 | if (ret) { | ||
1257 | dev_err(&pdev->dev, "failed to register cpufreq\n"); | ||
1258 | goto cpu_freq_fail; | ||
1259 | } | ||
1260 | |||
1261 | ret = mmc_add_host(mmc); | ||
1262 | if (ret < 0) | ||
1263 | goto out; | ||
1264 | |||
1265 | ret = request_irq(irq, mmc_davinci_irq, 0, mmc_hostname(mmc), host); | ||
1266 | if (ret) | ||
1267 | goto out; | ||
1268 | |||
1269 | rename_region(mem, mmc_hostname(mmc)); | ||
1270 | |||
1271 | dev_info(mmc_dev(host->mmc), "Using %s, %d-bit mode\n", | ||
1272 | host->use_dma ? "DMA" : "PIO", | ||
1273 | (mmc->caps & MMC_CAP_4_BIT_DATA) ? 4 : 1); | ||
1274 | |||
1275 | return 0; | ||
1276 | |||
1277 | out: | ||
1278 | mmc_davinci_cpufreq_deregister(host); | ||
1279 | cpu_freq_fail: | ||
1280 | if (host) { | ||
1281 | davinci_release_dma_channels(host); | ||
1282 | |||
1283 | if (host->clk) { | ||
1284 | clk_disable(host->clk); | ||
1285 | clk_put(host->clk); | ||
1286 | } | ||
1287 | |||
1288 | if (host->base) | ||
1289 | iounmap(host->base); | ||
1290 | } | ||
1291 | |||
1292 | if (mmc) | ||
1293 | mmc_free_host(mmc); | ||
1294 | |||
1295 | if (mem) | ||
1296 | release_resource(mem); | ||
1297 | |||
1298 | dev_dbg(&pdev->dev, "probe err %d\n", ret); | ||
1299 | |||
1300 | return ret; | ||
1301 | } | ||
1302 | |||
1303 | static int __exit davinci_mmcsd_remove(struct platform_device *pdev) | ||
1304 | { | ||
1305 | struct mmc_davinci_host *host = platform_get_drvdata(pdev); | ||
1306 | |||
1307 | platform_set_drvdata(pdev, NULL); | ||
1308 | if (host) { | ||
1309 | mmc_davinci_cpufreq_deregister(host); | ||
1310 | |||
1311 | mmc_remove_host(host->mmc); | ||
1312 | free_irq(host->irq, host); | ||
1313 | |||
1314 | davinci_release_dma_channels(host); | ||
1315 | |||
1316 | clk_disable(host->clk); | ||
1317 | clk_put(host->clk); | ||
1318 | |||
1319 | iounmap(host->base); | ||
1320 | |||
1321 | release_resource(host->mem_res); | ||
1322 | |||
1323 | mmc_free_host(host->mmc); | ||
1324 | } | ||
1325 | |||
1326 | return 0; | ||
1327 | } | ||
1328 | |||
1329 | #ifdef CONFIG_PM | ||
1330 | static int davinci_mmcsd_suspend(struct platform_device *pdev, pm_message_t msg) | ||
1331 | { | ||
1332 | struct mmc_davinci_host *host = platform_get_drvdata(pdev); | ||
1333 | |||
1334 | return mmc_suspend_host(host->mmc, msg); | ||
1335 | } | ||
1336 | |||
1337 | static int davinci_mmcsd_resume(struct platform_device *pdev) | ||
1338 | { | ||
1339 | struct mmc_davinci_host *host = platform_get_drvdata(pdev); | ||
1340 | |||
1341 | return mmc_resume_host(host->mmc); | ||
1342 | } | ||
1343 | #else | ||
1344 | #define davinci_mmcsd_suspend NULL | ||
1345 | #define davinci_mmcsd_resume NULL | ||
1346 | #endif | ||
1347 | |||
1348 | static struct platform_driver davinci_mmcsd_driver = { | ||
1349 | .driver = { | ||
1350 | .name = "davinci_mmc", | ||
1351 | .owner = THIS_MODULE, | ||
1352 | }, | ||
1353 | .remove = __exit_p(davinci_mmcsd_remove), | ||
1354 | .suspend = davinci_mmcsd_suspend, | ||
1355 | .resume = davinci_mmcsd_resume, | ||
1356 | }; | ||
1357 | |||
1358 | static int __init davinci_mmcsd_init(void) | ||
1359 | { | ||
1360 | return platform_driver_probe(&davinci_mmcsd_driver, | ||
1361 | davinci_mmcsd_probe); | ||
1362 | } | ||
1363 | module_init(davinci_mmcsd_init); | ||
1364 | |||
1365 | static void __exit davinci_mmcsd_exit(void) | ||
1366 | { | ||
1367 | platform_driver_unregister(&davinci_mmcsd_driver); | ||
1368 | } | ||
1369 | module_exit(davinci_mmcsd_exit); | ||
1370 | |||
1371 | MODULE_AUTHOR("Texas Instruments India"); | ||
1372 | MODULE_LICENSE("GPL"); | ||
1373 | MODULE_DESCRIPTION("MMC/SD driver for Davinci MMC controller"); | ||
1374 | |||
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index d55fe4fb7935..ad847a24a675 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/slab.h> | ||
29 | #include <linux/bio.h> | 30 | #include <linux/bio.h> |
30 | #include <linux/dma-mapping.h> | 31 | #include <linux/dma-mapping.h> |
31 | #include <linux/crc7.h> | 32 | #include <linux/crc7.h> |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 705a5894a6bb..84c103a7ee13 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver | 2 | * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. | 4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. |
5 | * Copyright (C) 2010 ST-Ericsson AB. | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * 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 | * it under the terms of the GNU General Public License version 2 as |
@@ -34,9 +35,6 @@ | |||
34 | 35 | ||
35 | #define DRIVER_NAME "mmci-pl18x" | 36 | #define DRIVER_NAME "mmci-pl18x" |
36 | 37 | ||
37 | #define DBG(host,fmt,args...) \ | ||
38 | pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args) | ||
39 | |||
40 | static unsigned int fmax = 515633; | 38 | static unsigned int fmax = 515633; |
41 | 39 | ||
42 | /* | 40 | /* |
@@ -56,7 +54,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) | |||
56 | clk = 255; | 54 | clk = 255; |
57 | host->cclk = host->mclk / (2 * (clk + 1)); | 55 | host->cclk = host->mclk / (2 * (clk + 1)); |
58 | } | 56 | } |
59 | if (host->hw_designer == 0x80) | 57 | if (host->hw_designer == AMBA_VENDOR_ST) |
60 | clk |= MCI_FCEN; /* Bug fix in ST IP block */ | 58 | clk |= MCI_FCEN; /* Bug fix in ST IP block */ |
61 | clk |= MCI_CLK_ENABLE; | 59 | clk |= MCI_CLK_ENABLE; |
62 | /* This hasn't proven to be worthwhile */ | 60 | /* This hasn't proven to be worthwhile */ |
@@ -105,8 +103,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
105 | void __iomem *base; | 103 | void __iomem *base; |
106 | int blksz_bits; | 104 | int blksz_bits; |
107 | 105 | ||
108 | DBG(host, "blksz %04x blks %04x flags %08x\n", | 106 | dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", |
109 | data->blksz, data->blocks, data->flags); | 107 | data->blksz, data->blocks, data->flags); |
110 | 108 | ||
111 | host->data = data; | 109 | host->data = data; |
112 | host->size = data->blksz; | 110 | host->size = data->blksz; |
@@ -155,7 +153,7 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) | |||
155 | { | 153 | { |
156 | void __iomem *base = host->base; | 154 | void __iomem *base = host->base; |
157 | 155 | ||
158 | DBG(host, "op %02x arg %08x flags %08x\n", | 156 | dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", |
159 | cmd->opcode, cmd->arg, cmd->flags); | 157 | cmd->opcode, cmd->arg, cmd->flags); |
160 | 158 | ||
161 | if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { | 159 | if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { |
@@ -184,8 +182,20 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, | |||
184 | { | 182 | { |
185 | if (status & MCI_DATABLOCKEND) { | 183 | if (status & MCI_DATABLOCKEND) { |
186 | host->data_xfered += data->blksz; | 184 | host->data_xfered += data->blksz; |
185 | #ifdef CONFIG_ARCH_U300 | ||
186 | /* | ||
187 | * On the U300 some signal or other is | ||
188 | * badly routed so that a data write does | ||
189 | * not properly terminate with a MCI_DATAEND | ||
190 | * status flag. This quirk will make writes | ||
191 | * work again. | ||
192 | */ | ||
193 | if (data->flags & MMC_DATA_WRITE) | ||
194 | status |= MCI_DATAEND; | ||
195 | #endif | ||
187 | } | 196 | } |
188 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { | 197 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { |
198 | dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status); | ||
189 | if (status & MCI_DATACRCFAIL) | 199 | if (status & MCI_DATACRCFAIL) |
190 | data->error = -EILSEQ; | 200 | data->error = -EILSEQ; |
191 | else if (status & MCI_DATATIMEOUT) | 201 | else if (status & MCI_DATATIMEOUT) |
@@ -307,7 +317,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) | |||
307 | 317 | ||
308 | status = readl(base + MMCISTATUS); | 318 | status = readl(base + MMCISTATUS); |
309 | 319 | ||
310 | DBG(host, "irq1 %08x\n", status); | 320 | dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); |
311 | 321 | ||
312 | do { | 322 | do { |
313 | unsigned long flags; | 323 | unsigned long flags; |
@@ -401,7 +411,7 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) | |||
401 | status &= readl(host->base + MMCIMASK0); | 411 | status &= readl(host->base + MMCIMASK0); |
402 | writel(status, host->base + MMCICLEAR); | 412 | writel(status, host->base + MMCICLEAR); |
403 | 413 | ||
404 | DBG(host, "irq0 %08x\n", status); | 414 | dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); |
405 | 415 | ||
406 | data = host->data; | 416 | data = host->data; |
407 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| | 417 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| |
@@ -428,8 +438,8 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
428 | WARN_ON(host->mrq != NULL); | 438 | WARN_ON(host->mrq != NULL); |
429 | 439 | ||
430 | if (mrq->data && !is_power_of_2(mrq->data->blksz)) { | 440 | if (mrq->data && !is_power_of_2(mrq->data->blksz)) { |
431 | printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n", | 441 | dev_err(mmc_dev(mmc), "unsupported block size (%d bytes)\n", |
432 | mmc_hostname(mmc), mrq->data->blksz); | 442 | mrq->data->blksz); |
433 | mrq->cmd->error = -EINVAL; | 443 | mrq->cmd->error = -EINVAL; |
434 | mmc_request_done(mmc, mrq); | 444 | mmc_request_done(mmc, mrq); |
435 | return; | 445 | return; |
@@ -582,8 +592,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
582 | 592 | ||
583 | host->hw_designer = amba_manf(dev); | 593 | host->hw_designer = amba_manf(dev); |
584 | host->hw_revision = amba_rev(dev); | 594 | host->hw_revision = amba_rev(dev); |
585 | DBG(host, "designer ID = 0x%02x\n", host->hw_designer); | 595 | dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); |
586 | DBG(host, "revision = 0x%01x\n", host->hw_revision); | 596 | dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); |
587 | 597 | ||
588 | host->clk = clk_get(&dev->dev, NULL); | 598 | host->clk = clk_get(&dev->dev, NULL); |
589 | if (IS_ERR(host->clk)) { | 599 | if (IS_ERR(host->clk)) { |
@@ -608,7 +618,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
608 | if (ret < 0) | 618 | if (ret < 0) |
609 | goto clk_disable; | 619 | goto clk_disable; |
610 | host->mclk = clk_get_rate(host->clk); | 620 | host->mclk = clk_get_rate(host->clk); |
611 | DBG(host, "eventual mclk rate: %u Hz\n", host->mclk); | 621 | dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", |
622 | host->mclk); | ||
612 | } | 623 | } |
613 | host->base = ioremap(dev->res.start, resource_size(&dev->res)); | 624 | host->base = ioremap(dev->res.start, resource_size(&dev->res)); |
614 | if (!host->base) { | 625 | if (!host->base) { |
@@ -619,6 +630,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
619 | mmc->ops = &mmci_ops; | 630 | mmc->ops = &mmci_ops; |
620 | mmc->f_min = (host->mclk + 511) / 512; | 631 | mmc->f_min = (host->mclk + 511) / 512; |
621 | mmc->f_max = min(host->mclk, fmax); | 632 | mmc->f_max = min(host->mclk, fmax); |
633 | dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); | ||
634 | |||
622 | #ifdef CONFIG_REGULATOR | 635 | #ifdef CONFIG_REGULATOR |
623 | /* If we're using the regulator framework, try to fetch a regulator */ | 636 | /* If we're using the regulator framework, try to fetch a regulator */ |
624 | host->vcc = regulator_get(&dev->dev, "vmmc"); | 637 | host->vcc = regulator_get(&dev->dev, "vmmc"); |
@@ -712,7 +725,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
712 | 725 | ||
713 | mmc_add_host(mmc); | 726 | mmc_add_host(mmc); |
714 | 727 | ||
715 | printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", | 728 | dev_info(&dev->dev, "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", |
716 | mmc_hostname(mmc), amba_rev(dev), amba_config(dev), | 729 | mmc_hostname(mmc), amba_rev(dev), amba_config(dev), |
717 | (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); | 730 | (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); |
718 | 731 | ||
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index dba4600bcdb4..04ae884383f6 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c | |||
@@ -33,15 +33,15 @@ | |||
33 | #include <linux/debugfs.h> | 33 | #include <linux/debugfs.h> |
34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
35 | #include <linux/memory.h> | 35 | #include <linux/memory.h> |
36 | #include <linux/gfp.h> | ||
36 | 37 | ||
37 | #include <asm/cacheflush.h> | 38 | #include <asm/cacheflush.h> |
38 | #include <asm/div64.h> | 39 | #include <asm/div64.h> |
39 | #include <asm/sizes.h> | 40 | #include <asm/sizes.h> |
40 | 41 | ||
41 | #include <asm/mach/mmc.h> | 42 | #include <mach/mmc.h> |
42 | #include <mach/msm_iomap.h> | 43 | #include <mach/msm_iomap.h> |
43 | #include <mach/dma.h> | 44 | #include <mach/dma.h> |
44 | #include <mach/htc_pwrsink.h> | ||
45 | 45 | ||
46 | #include "msm_sdcc.h" | 46 | #include "msm_sdcc.h" |
47 | 47 | ||
@@ -775,13 +775,11 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
775 | 775 | ||
776 | switch (ios->power_mode) { | 776 | switch (ios->power_mode) { |
777 | case MMC_POWER_OFF: | 777 | case MMC_POWER_OFF: |
778 | htc_pwrsink_set(PWRSINK_SDCARD, 0); | ||
779 | break; | 778 | break; |
780 | case MMC_POWER_UP: | 779 | case MMC_POWER_UP: |
781 | pwr |= MCI_PWR_UP; | 780 | pwr |= MCI_PWR_UP; |
782 | break; | 781 | break; |
783 | case MMC_POWER_ON: | 782 | case MMC_POWER_ON: |
784 | htc_pwrsink_set(PWRSINK_SDCARD, 100); | ||
785 | pwr |= MCI_PWR_ON; | 783 | pwr |= MCI_PWR_ON; |
786 | break; | 784 | break; |
787 | } | 785 | } |
@@ -1253,9 +1251,7 @@ msmsdcc_resume(struct platform_device *dev) | |||
1253 | 1251 | ||
1254 | if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) | 1252 | if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) |
1255 | mmc_resume_host(mmc); | 1253 | mmc_resume_host(mmc); |
1256 | if (host->stat_irq) | 1254 | if (host->stat_irq) |
1257 | enable_irq(host->stat_irq); | ||
1258 | else if (host->stat_irq) | ||
1259 | enable_irq(host->stat_irq); | 1255 | enable_irq(host->stat_irq); |
1260 | } | 1256 | } |
1261 | return 0; | 1257 | return 0; |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 88671529c45d..2df90412abb5 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * This is a driver for the SDHC controller found in Freescale MX2/MX3 | 4 | * This is a driver for the SDHC controller found in Freescale MX2/MX3 |
5 | * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). | 5 | * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). |
6 | * Unlike the hardware found on MX1, this hardware just works and does | 6 | * Unlike the hardware found on MX1, this hardware just works and does |
7 | * not need all the quirks found in imxmmc.c, hence the seperate driver. | 7 | * not need all the quirks found in imxmmc.c, hence the separate driver. |
8 | * | 8 | * |
9 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> | 9 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> |
10 | * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> | 10 | * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> |
@@ -679,17 +679,17 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
679 | { | 679 | { |
680 | struct mmc_host *mmc; | 680 | struct mmc_host *mmc; |
681 | struct mxcmci_host *host = NULL; | 681 | struct mxcmci_host *host = NULL; |
682 | struct resource *r; | 682 | struct resource *iores, *r; |
683 | int ret = 0, irq; | 683 | int ret = 0, irq; |
684 | 684 | ||
685 | printk(KERN_INFO "i.MX SDHC driver\n"); | 685 | printk(KERN_INFO "i.MX SDHC driver\n"); |
686 | 686 | ||
687 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 687 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
688 | irq = platform_get_irq(pdev, 0); | 688 | irq = platform_get_irq(pdev, 0); |
689 | if (!r || irq < 0) | 689 | if (!iores || irq < 0) |
690 | return -EINVAL; | 690 | return -EINVAL; |
691 | 691 | ||
692 | r = request_mem_region(r->start, resource_size(r), pdev->name); | 692 | r = request_mem_region(iores->start, resource_size(iores), pdev->name); |
693 | if (!r) | 693 | if (!r) |
694 | return -EBUSY; | 694 | return -EBUSY; |
695 | 695 | ||
@@ -708,7 +708,7 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
708 | mmc->max_blk_size = 2048; | 708 | mmc->max_blk_size = 2048; |
709 | mmc->max_blk_count = 65535; | 709 | mmc->max_blk_count = 65535; |
710 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | 710 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; |
711 | mmc->max_seg_size = mmc->max_seg_size; | 711 | mmc->max_seg_size = mmc->max_req_size; |
712 | 712 | ||
713 | host = mmc_priv(mmc); | 713 | host = mmc_priv(mmc); |
714 | host->base = ioremap(r->start, resource_size(r)); | 714 | host->base = ioremap(r->start, resource_size(r)); |
@@ -809,7 +809,7 @@ out_iounmap: | |||
809 | out_free: | 809 | out_free: |
810 | mmc_free_host(mmc); | 810 | mmc_free_host(mmc); |
811 | out_release_mem: | 811 | out_release_mem: |
812 | release_mem_region(host->res->start, resource_size(host->res)); | 812 | release_mem_region(iores->start, resource_size(iores)); |
813 | return ret; | 813 | return ret; |
814 | } | 814 | } |
815 | 815 | ||
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index 0c44d560bf1a..bb6cc54b558e 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/slab.h> | ||
17 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
18 | #include <linux/of.h> | 19 | #include <linux/of.h> |
19 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
@@ -22,6 +23,8 @@ | |||
22 | #include <linux/mmc/core.h> | 23 | #include <linux/mmc/core.h> |
23 | #include <linux/mmc/host.h> | 24 | #include <linux/mmc/host.h> |
24 | 25 | ||
26 | MODULE_LICENSE("GPL"); | ||
27 | |||
25 | enum { | 28 | enum { |
26 | CD_GPIO = 0, | 29 | CD_GPIO = 0, |
27 | WP_GPIO, | 30 | WP_GPIO, |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index b8fd7af1ceeb..84d280406341 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -26,16 +26,17 @@ | |||
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/scatterlist.h> | 27 | #include <linux/scatterlist.h> |
28 | #include <linux/i2c/tps65010.h> | 28 | #include <linux/i2c/tps65010.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
31 | #include <asm/irq.h> | 32 | #include <asm/irq.h> |
32 | 33 | ||
33 | #include <mach/board.h> | 34 | #include <plat/board.h> |
34 | #include <mach/mmc.h> | 35 | #include <plat/mmc.h> |
35 | #include <mach/gpio.h> | 36 | #include <mach/gpio.h> |
36 | #include <mach/dma.h> | 37 | #include <plat/dma.h> |
37 | #include <mach/mux.h> | 38 | #include <plat/mux.h> |
38 | #include <mach/fpga.h> | 39 | #include <plat/fpga.h> |
39 | 40 | ||
40 | #define OMAP_MMC_REG_CMD 0x00 | 41 | #define OMAP_MMC_REG_CMD 0x00 |
41 | #define OMAP_MMC_REG_ARGL 0x04 | 42 | #define OMAP_MMC_REG_ARGL 0x04 |
@@ -1459,8 +1460,10 @@ static int __init mmc_omap_probe(struct platform_device *pdev) | |||
1459 | goto err_ioremap; | 1460 | goto err_ioremap; |
1460 | 1461 | ||
1461 | host->iclk = clk_get(&pdev->dev, "ick"); | 1462 | host->iclk = clk_get(&pdev->dev, "ick"); |
1462 | if (IS_ERR(host->iclk)) | 1463 | if (IS_ERR(host->iclk)) { |
1464 | ret = PTR_ERR(host->iclk); | ||
1463 | goto err_free_mmc_host; | 1465 | goto err_free_mmc_host; |
1466 | } | ||
1464 | clk_enable(host->iclk); | 1467 | clk_enable(host->iclk); |
1465 | 1468 | ||
1466 | host->fclk = clk_get(&pdev->dev, "fck"); | 1469 | host->fclk = clk_get(&pdev->dev, "fck"); |
@@ -1500,10 +1503,8 @@ err_free_irq: | |||
1500 | err_free_fclk: | 1503 | err_free_fclk: |
1501 | clk_put(host->fclk); | 1504 | clk_put(host->fclk); |
1502 | err_free_iclk: | 1505 | err_free_iclk: |
1503 | if (host->iclk != NULL) { | 1506 | clk_disable(host->iclk); |
1504 | clk_disable(host->iclk); | 1507 | clk_put(host->iclk); |
1505 | clk_put(host->iclk); | ||
1506 | } | ||
1507 | err_free_mmc_host: | 1508 | err_free_mmc_host: |
1508 | iounmap(host->virt_base); | 1509 | iounmap(host->virt_base); |
1509 | err_ioremap: | 1510 | err_ioremap: |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 0aecaaebef3d..e9caf694c59e 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -30,11 +30,13 @@ | |||
30 | #include <linux/mmc/core.h> | 30 | #include <linux/mmc/core.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/semaphore.h> | 32 | #include <linux/semaphore.h> |
33 | #include <mach/dma.h> | 33 | #include <linux/gpio.h> |
34 | #include <linux/regulator/consumer.h> | ||
35 | #include <plat/dma.h> | ||
34 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
35 | #include <mach/board.h> | 37 | #include <plat/board.h> |
36 | #include <mach/mmc.h> | 38 | #include <plat/mmc.h> |
37 | #include <mach/cpu.h> | 39 | #include <plat/cpu.h> |
38 | 40 | ||
39 | /* OMAP HSMMC Host Controller Registers */ | 41 | /* OMAP HSMMC Host Controller Registers */ |
40 | #define OMAP_HSMMC_SYSCONFIG 0x0010 | 42 | #define OMAP_HSMMC_SYSCONFIG 0x0010 |
@@ -146,6 +148,15 @@ struct omap_hsmmc_host { | |||
146 | struct clk *fclk; | 148 | struct clk *fclk; |
147 | struct clk *iclk; | 149 | struct clk *iclk; |
148 | struct clk *dbclk; | 150 | struct clk *dbclk; |
151 | /* | ||
152 | * vcc == configured supply | ||
153 | * vcc_aux == optional | ||
154 | * - MMC1, supply for DAT4..DAT7 | ||
155 | * - MMC2/MMC2, external level shifter voltage supply, for | ||
156 | * chip (SDIO, eMMC, etc) or transceiver (MMC2 only) | ||
157 | */ | ||
158 | struct regulator *vcc; | ||
159 | struct regulator *vcc_aux; | ||
149 | struct semaphore sem; | 160 | struct semaphore sem; |
150 | struct work_struct mmc_carddetect_work; | 161 | struct work_struct mmc_carddetect_work; |
151 | void __iomem *base; | 162 | void __iomem *base; |
@@ -171,10 +182,337 @@ struct omap_hsmmc_host { | |||
171 | int vdd; | 182 | int vdd; |
172 | int protect_card; | 183 | int protect_card; |
173 | int reqs_blocked; | 184 | int reqs_blocked; |
185 | int use_reg; | ||
174 | 186 | ||
175 | struct omap_mmc_platform_data *pdata; | 187 | struct omap_mmc_platform_data *pdata; |
176 | }; | 188 | }; |
177 | 189 | ||
190 | static int omap_hsmmc_card_detect(struct device *dev, int slot) | ||
191 | { | ||
192 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
193 | |||
194 | /* NOTE: assumes card detect signal is active-low */ | ||
195 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | ||
196 | } | ||
197 | |||
198 | static int omap_hsmmc_get_wp(struct device *dev, int slot) | ||
199 | { | ||
200 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
201 | |||
202 | /* NOTE: assumes write protect signal is active-high */ | ||
203 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); | ||
204 | } | ||
205 | |||
206 | static int omap_hsmmc_get_cover_state(struct device *dev, int slot) | ||
207 | { | ||
208 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
209 | |||
210 | /* NOTE: assumes card detect signal is active-low */ | ||
211 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | ||
212 | } | ||
213 | |||
214 | #ifdef CONFIG_PM | ||
215 | |||
216 | static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) | ||
217 | { | ||
218 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
219 | |||
220 | disable_irq(mmc->slots[0].card_detect_irq); | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) | ||
225 | { | ||
226 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
227 | |||
228 | enable_irq(mmc->slots[0].card_detect_irq); | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | #else | ||
233 | |||
234 | #define omap_hsmmc_suspend_cdirq NULL | ||
235 | #define omap_hsmmc_resume_cdirq NULL | ||
236 | |||
237 | #endif | ||
238 | |||
239 | #ifdef CONFIG_REGULATOR | ||
240 | |||
241 | static int omap_hsmmc_1_set_power(struct device *dev, int slot, int power_on, | ||
242 | int vdd) | ||
243 | { | ||
244 | struct omap_hsmmc_host *host = | ||
245 | platform_get_drvdata(to_platform_device(dev)); | ||
246 | int ret; | ||
247 | |||
248 | if (mmc_slot(host).before_set_reg) | ||
249 | mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); | ||
250 | |||
251 | if (power_on) | ||
252 | ret = mmc_regulator_set_ocr(host->vcc, vdd); | ||
253 | else | ||
254 | ret = mmc_regulator_set_ocr(host->vcc, 0); | ||
255 | |||
256 | if (mmc_slot(host).after_set_reg) | ||
257 | mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); | ||
258 | |||
259 | return ret; | ||
260 | } | ||
261 | |||
262 | static int omap_hsmmc_23_set_power(struct device *dev, int slot, int power_on, | ||
263 | int vdd) | ||
264 | { | ||
265 | struct omap_hsmmc_host *host = | ||
266 | platform_get_drvdata(to_platform_device(dev)); | ||
267 | int ret = 0; | ||
268 | |||
269 | /* | ||
270 | * If we don't see a Vcc regulator, assume it's a fixed | ||
271 | * voltage always-on regulator. | ||
272 | */ | ||
273 | if (!host->vcc) | ||
274 | return 0; | ||
275 | |||
276 | if (mmc_slot(host).before_set_reg) | ||
277 | mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); | ||
278 | |||
279 | /* | ||
280 | * Assume Vcc regulator is used only to power the card ... OMAP | ||
281 | * VDDS is used to power the pins, optionally with a transceiver to | ||
282 | * support cards using voltages other than VDDS (1.8V nominal). When a | ||
283 | * transceiver is used, DAT3..7 are muxed as transceiver control pins. | ||
284 | * | ||
285 | * In some cases this regulator won't support enable/disable; | ||
286 | * e.g. it's a fixed rail for a WLAN chip. | ||
287 | * | ||
288 | * In other cases vcc_aux switches interface power. Example, for | ||
289 | * eMMC cards it represents VccQ. Sometimes transceivers or SDIO | ||
290 | * chips/cards need an interface voltage rail too. | ||
291 | */ | ||
292 | if (power_on) { | ||
293 | ret = mmc_regulator_set_ocr(host->vcc, vdd); | ||
294 | /* Enable interface voltage rail, if needed */ | ||
295 | if (ret == 0 && host->vcc_aux) { | ||
296 | ret = regulator_enable(host->vcc_aux); | ||
297 | if (ret < 0) | ||
298 | ret = mmc_regulator_set_ocr(host->vcc, 0); | ||
299 | } | ||
300 | } else { | ||
301 | if (host->vcc_aux) | ||
302 | ret = regulator_disable(host->vcc_aux); | ||
303 | if (ret == 0) | ||
304 | ret = mmc_regulator_set_ocr(host->vcc, 0); | ||
305 | } | ||
306 | |||
307 | if (mmc_slot(host).after_set_reg) | ||
308 | mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); | ||
309 | |||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | static int omap_hsmmc_1_set_sleep(struct device *dev, int slot, int sleep, | ||
314 | int vdd, int cardsleep) | ||
315 | { | ||
316 | struct omap_hsmmc_host *host = | ||
317 | platform_get_drvdata(to_platform_device(dev)); | ||
318 | int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; | ||
319 | |||
320 | return regulator_set_mode(host->vcc, mode); | ||
321 | } | ||
322 | |||
323 | static int omap_hsmmc_23_set_sleep(struct device *dev, int slot, int sleep, | ||
324 | int vdd, int cardsleep) | ||
325 | { | ||
326 | struct omap_hsmmc_host *host = | ||
327 | platform_get_drvdata(to_platform_device(dev)); | ||
328 | int err, mode; | ||
329 | |||
330 | /* | ||
331 | * If we don't see a Vcc regulator, assume it's a fixed | ||
332 | * voltage always-on regulator. | ||
333 | */ | ||
334 | if (!host->vcc) | ||
335 | return 0; | ||
336 | |||
337 | mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; | ||
338 | |||
339 | if (!host->vcc_aux) | ||
340 | return regulator_set_mode(host->vcc, mode); | ||
341 | |||
342 | if (cardsleep) { | ||
343 | /* VCC can be turned off if card is asleep */ | ||
344 | if (sleep) | ||
345 | err = mmc_regulator_set_ocr(host->vcc, 0); | ||
346 | else | ||
347 | err = mmc_regulator_set_ocr(host->vcc, vdd); | ||
348 | } else | ||
349 | err = regulator_set_mode(host->vcc, mode); | ||
350 | if (err) | ||
351 | return err; | ||
352 | |||
353 | if (!mmc_slot(host).vcc_aux_disable_is_sleep) | ||
354 | return regulator_set_mode(host->vcc_aux, mode); | ||
355 | |||
356 | if (sleep) | ||
357 | return regulator_disable(host->vcc_aux); | ||
358 | else | ||
359 | return regulator_enable(host->vcc_aux); | ||
360 | } | ||
361 | |||
362 | static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | ||
363 | { | ||
364 | struct regulator *reg; | ||
365 | int ret = 0; | ||
366 | |||
367 | switch (host->id) { | ||
368 | case OMAP_MMC1_DEVID: | ||
369 | /* On-chip level shifting via PBIAS0/PBIAS1 */ | ||
370 | mmc_slot(host).set_power = omap_hsmmc_1_set_power; | ||
371 | mmc_slot(host).set_sleep = omap_hsmmc_1_set_sleep; | ||
372 | break; | ||
373 | case OMAP_MMC2_DEVID: | ||
374 | case OMAP_MMC3_DEVID: | ||
375 | /* Off-chip level shifting, or none */ | ||
376 | mmc_slot(host).set_power = omap_hsmmc_23_set_power; | ||
377 | mmc_slot(host).set_sleep = omap_hsmmc_23_set_sleep; | ||
378 | break; | ||
379 | default: | ||
380 | pr_err("MMC%d configuration not supported!\n", host->id); | ||
381 | return -EINVAL; | ||
382 | } | ||
383 | |||
384 | reg = regulator_get(host->dev, "vmmc"); | ||
385 | if (IS_ERR(reg)) { | ||
386 | dev_dbg(host->dev, "vmmc regulator missing\n"); | ||
387 | /* | ||
388 | * HACK: until fixed.c regulator is usable, | ||
389 | * we don't require a main regulator | ||
390 | * for MMC2 or MMC3 | ||
391 | */ | ||
392 | if (host->id == OMAP_MMC1_DEVID) { | ||
393 | ret = PTR_ERR(reg); | ||
394 | goto err; | ||
395 | } | ||
396 | } else { | ||
397 | host->vcc = reg; | ||
398 | mmc_slot(host).ocr_mask = mmc_regulator_get_ocrmask(reg); | ||
399 | |||
400 | /* Allow an aux regulator */ | ||
401 | reg = regulator_get(host->dev, "vmmc_aux"); | ||
402 | host->vcc_aux = IS_ERR(reg) ? NULL : reg; | ||
403 | |||
404 | /* | ||
405 | * UGLY HACK: workaround regulator framework bugs. | ||
406 | * When the bootloader leaves a supply active, it's | ||
407 | * initialized with zero usecount ... and we can't | ||
408 | * disable it without first enabling it. Until the | ||
409 | * framework is fixed, we need a workaround like this | ||
410 | * (which is safe for MMC, but not in general). | ||
411 | */ | ||
412 | if (regulator_is_enabled(host->vcc) > 0) { | ||
413 | regulator_enable(host->vcc); | ||
414 | regulator_disable(host->vcc); | ||
415 | } | ||
416 | if (host->vcc_aux) { | ||
417 | if (regulator_is_enabled(reg) > 0) { | ||
418 | regulator_enable(reg); | ||
419 | regulator_disable(reg); | ||
420 | } | ||
421 | } | ||
422 | } | ||
423 | |||
424 | return 0; | ||
425 | |||
426 | err: | ||
427 | mmc_slot(host).set_power = NULL; | ||
428 | mmc_slot(host).set_sleep = NULL; | ||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) | ||
433 | { | ||
434 | regulator_put(host->vcc); | ||
435 | regulator_put(host->vcc_aux); | ||
436 | mmc_slot(host).set_power = NULL; | ||
437 | mmc_slot(host).set_sleep = NULL; | ||
438 | } | ||
439 | |||
440 | static inline int omap_hsmmc_have_reg(void) | ||
441 | { | ||
442 | return 1; | ||
443 | } | ||
444 | |||
445 | #else | ||
446 | |||
447 | static inline int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | ||
448 | { | ||
449 | return -EINVAL; | ||
450 | } | ||
451 | |||
452 | static inline void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) | ||
453 | { | ||
454 | } | ||
455 | |||
456 | static inline int omap_hsmmc_have_reg(void) | ||
457 | { | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | #endif | ||
462 | |||
463 | static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) | ||
464 | { | ||
465 | int ret; | ||
466 | |||
467 | if (gpio_is_valid(pdata->slots[0].switch_pin)) { | ||
468 | pdata->suspend = omap_hsmmc_suspend_cdirq; | ||
469 | pdata->resume = omap_hsmmc_resume_cdirq; | ||
470 | if (pdata->slots[0].cover) | ||
471 | pdata->slots[0].get_cover_state = | ||
472 | omap_hsmmc_get_cover_state; | ||
473 | else | ||
474 | pdata->slots[0].card_detect = omap_hsmmc_card_detect; | ||
475 | pdata->slots[0].card_detect_irq = | ||
476 | gpio_to_irq(pdata->slots[0].switch_pin); | ||
477 | ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd"); | ||
478 | if (ret) | ||
479 | return ret; | ||
480 | ret = gpio_direction_input(pdata->slots[0].switch_pin); | ||
481 | if (ret) | ||
482 | goto err_free_sp; | ||
483 | } else | ||
484 | pdata->slots[0].switch_pin = -EINVAL; | ||
485 | |||
486 | if (gpio_is_valid(pdata->slots[0].gpio_wp)) { | ||
487 | pdata->slots[0].get_ro = omap_hsmmc_get_wp; | ||
488 | ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp"); | ||
489 | if (ret) | ||
490 | goto err_free_cd; | ||
491 | ret = gpio_direction_input(pdata->slots[0].gpio_wp); | ||
492 | if (ret) | ||
493 | goto err_free_wp; | ||
494 | } else | ||
495 | pdata->slots[0].gpio_wp = -EINVAL; | ||
496 | |||
497 | return 0; | ||
498 | |||
499 | err_free_wp: | ||
500 | gpio_free(pdata->slots[0].gpio_wp); | ||
501 | err_free_cd: | ||
502 | if (gpio_is_valid(pdata->slots[0].switch_pin)) | ||
503 | err_free_sp: | ||
504 | gpio_free(pdata->slots[0].switch_pin); | ||
505 | return ret; | ||
506 | } | ||
507 | |||
508 | static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata) | ||
509 | { | ||
510 | if (gpio_is_valid(pdata->slots[0].gpio_wp)) | ||
511 | gpio_free(pdata->slots[0].gpio_wp); | ||
512 | if (gpio_is_valid(pdata->slots[0].switch_pin)) | ||
513 | gpio_free(pdata->slots[0].switch_pin); | ||
514 | } | ||
515 | |||
178 | /* | 516 | /* |
179 | * Stop clock to the card | 517 | * Stop clock to the card |
180 | */ | 518 | */ |
@@ -835,21 +1173,16 @@ static void omap_hsmmc_detect(struct work_struct *work) | |||
835 | sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); | 1173 | sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); |
836 | 1174 | ||
837 | if (slot->card_detect) | 1175 | if (slot->card_detect) |
838 | carddetect = slot->card_detect(slot->card_detect_irq); | 1176 | carddetect = slot->card_detect(host->dev, host->slot_id); |
839 | else { | 1177 | else { |
840 | omap_hsmmc_protect_card(host); | 1178 | omap_hsmmc_protect_card(host); |
841 | carddetect = -ENOSYS; | 1179 | carddetect = -ENOSYS; |
842 | } | 1180 | } |
843 | 1181 | ||
844 | if (carddetect) { | 1182 | if (carddetect) |
845 | mmc_detect_change(host->mmc, (HZ * 200) / 1000); | 1183 | mmc_detect_change(host->mmc, (HZ * 200) / 1000); |
846 | } else { | 1184 | else |
847 | mmc_host_enable(host->mmc); | ||
848 | omap_hsmmc_reset_controller_fsm(host, SRD); | ||
849 | mmc_host_lazy_disable(host->mmc); | ||
850 | |||
851 | mmc_detect_change(host->mmc, (HZ * 50) / 1000); | 1185 | mmc_detect_change(host->mmc, (HZ * 50) / 1000); |
852 | } | ||
853 | } | 1186 | } |
854 | 1187 | ||
855 | /* | 1188 | /* |
@@ -1242,7 +1575,7 @@ static int omap_hsmmc_get_cd(struct mmc_host *mmc) | |||
1242 | 1575 | ||
1243 | if (!mmc_slot(host).card_detect) | 1576 | if (!mmc_slot(host).card_detect) |
1244 | return -ENOSYS; | 1577 | return -ENOSYS; |
1245 | return mmc_slot(host).card_detect(mmc_slot(host).card_detect_irq); | 1578 | return mmc_slot(host).card_detect(host->dev, host->slot_id); |
1246 | } | 1579 | } |
1247 | 1580 | ||
1248 | static int omap_hsmmc_get_ro(struct mmc_host *mmc) | 1581 | static int omap_hsmmc_get_ro(struct mmc_host *mmc) |
@@ -1311,7 +1644,7 @@ static int omap_hsmmc_enabled_to_disabled(struct omap_hsmmc_host *host) | |||
1311 | if (host->power_mode == MMC_POWER_OFF) | 1644 | if (host->power_mode == MMC_POWER_OFF) |
1312 | return 0; | 1645 | return 0; |
1313 | 1646 | ||
1314 | return msecs_to_jiffies(OMAP_MMC_SLEEP_TIMEOUT); | 1647 | return OMAP_MMC_SLEEP_TIMEOUT; |
1315 | } | 1648 | } |
1316 | 1649 | ||
1317 | /* Handler for [DISABLED -> REGSLEEP / CARDSLEEP] transition */ | 1650 | /* Handler for [DISABLED -> REGSLEEP / CARDSLEEP] transition */ |
@@ -1347,11 +1680,14 @@ static int omap_hsmmc_disabled_to_sleep(struct omap_hsmmc_host *host) | |||
1347 | dev_dbg(mmc_dev(host->mmc), "DISABLED -> %s\n", | 1680 | dev_dbg(mmc_dev(host->mmc), "DISABLED -> %s\n", |
1348 | host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP"); | 1681 | host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP"); |
1349 | 1682 | ||
1683 | if (mmc_slot(host).no_off) | ||
1684 | return 0; | ||
1685 | |||
1350 | if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) || | 1686 | if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) || |
1351 | mmc_slot(host).card_detect || | 1687 | mmc_slot(host).card_detect || |
1352 | (mmc_slot(host).get_cover_state && | 1688 | (mmc_slot(host).get_cover_state && |
1353 | mmc_slot(host).get_cover_state(host->dev, host->slot_id))) | 1689 | mmc_slot(host).get_cover_state(host->dev, host->slot_id))) |
1354 | return msecs_to_jiffies(OMAP_MMC_OFF_TIMEOUT); | 1690 | return OMAP_MMC_OFF_TIMEOUT; |
1355 | 1691 | ||
1356 | return 0; | 1692 | return 0; |
1357 | } | 1693 | } |
@@ -1362,6 +1698,9 @@ static int omap_hsmmc_sleep_to_off(struct omap_hsmmc_host *host) | |||
1362 | if (!mmc_try_claim_host(host->mmc)) | 1698 | if (!mmc_try_claim_host(host->mmc)) |
1363 | return 0; | 1699 | return 0; |
1364 | 1700 | ||
1701 | if (mmc_slot(host).no_off) | ||
1702 | return 0; | ||
1703 | |||
1365 | if (!((host->mmc->caps & MMC_CAP_NONREMOVABLE) || | 1704 | if (!((host->mmc->caps & MMC_CAP_NONREMOVABLE) || |
1366 | mmc_slot(host).card_detect || | 1705 | mmc_slot(host).card_detect || |
1367 | (mmc_slot(host).get_cover_state && | 1706 | (mmc_slot(host).get_cover_state && |
@@ -1616,7 +1955,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1616 | struct mmc_host *mmc; | 1955 | struct mmc_host *mmc; |
1617 | struct omap_hsmmc_host *host = NULL; | 1956 | struct omap_hsmmc_host *host = NULL; |
1618 | struct resource *res; | 1957 | struct resource *res; |
1619 | int ret = 0, irq; | 1958 | int ret, irq; |
1620 | 1959 | ||
1621 | if (pdata == NULL) { | 1960 | if (pdata == NULL) { |
1622 | dev_err(&pdev->dev, "Platform Data is missing\n"); | 1961 | dev_err(&pdev->dev, "Platform Data is missing\n"); |
@@ -1638,10 +1977,14 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1638 | if (res == NULL) | 1977 | if (res == NULL) |
1639 | return -EBUSY; | 1978 | return -EBUSY; |
1640 | 1979 | ||
1980 | ret = omap_hsmmc_gpio_init(pdata); | ||
1981 | if (ret) | ||
1982 | goto err; | ||
1983 | |||
1641 | mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev); | 1984 | mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev); |
1642 | if (!mmc) { | 1985 | if (!mmc) { |
1643 | ret = -ENOMEM; | 1986 | ret = -ENOMEM; |
1644 | goto err; | 1987 | goto err_alloc; |
1645 | } | 1988 | } |
1646 | 1989 | ||
1647 | host = mmc_priv(mmc); | 1990 | host = mmc_priv(mmc); |
@@ -1656,7 +1999,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1656 | host->slot_id = 0; | 1999 | host->slot_id = 0; |
1657 | host->mapbase = res->start; | 2000 | host->mapbase = res->start; |
1658 | host->base = ioremap(host->mapbase, SZ_4K); | 2001 | host->base = ioremap(host->mapbase, SZ_4K); |
1659 | host->power_mode = -1; | 2002 | host->power_mode = MMC_POWER_OFF; |
1660 | 2003 | ||
1661 | platform_set_drvdata(pdev, host); | 2004 | platform_set_drvdata(pdev, host); |
1662 | INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); | 2005 | INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); |
@@ -1666,6 +2009,13 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1666 | else | 2009 | else |
1667 | mmc->ops = &omap_hsmmc_ops; | 2010 | mmc->ops = &omap_hsmmc_ops; |
1668 | 2011 | ||
2012 | /* | ||
2013 | * If regulator_disable can only put vcc_aux to sleep then there is | ||
2014 | * no off state. | ||
2015 | */ | ||
2016 | if (mmc_slot(host).vcc_aux_disable_is_sleep) | ||
2017 | mmc_slot(host).no_off = 1; | ||
2018 | |||
1669 | mmc->f_min = 400000; | 2019 | mmc->f_min = 400000; |
1670 | mmc->f_max = 52000000; | 2020 | mmc->f_max = 52000000; |
1671 | 2021 | ||
@@ -1781,7 +2131,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1781 | goto err_irq; | 2131 | goto err_irq; |
1782 | } | 2132 | } |
1783 | 2133 | ||
1784 | /* initialize power supplies, gpios, etc */ | ||
1785 | if (pdata->init != NULL) { | 2134 | if (pdata->init != NULL) { |
1786 | if (pdata->init(&pdev->dev) != 0) { | 2135 | if (pdata->init(&pdev->dev) != 0) { |
1787 | dev_dbg(mmc_dev(host->mmc), | 2136 | dev_dbg(mmc_dev(host->mmc), |
@@ -1789,6 +2138,14 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1789 | goto err_irq_cd_init; | 2138 | goto err_irq_cd_init; |
1790 | } | 2139 | } |
1791 | } | 2140 | } |
2141 | |||
2142 | if (omap_hsmmc_have_reg() && !mmc_slot(host).set_power) { | ||
2143 | ret = omap_hsmmc_reg_get(host); | ||
2144 | if (ret) | ||
2145 | goto err_reg; | ||
2146 | host->use_reg = 1; | ||
2147 | } | ||
2148 | |||
1792 | mmc->ocr_avail = mmc_slot(host).ocr_mask; | 2149 | mmc->ocr_avail = mmc_slot(host).ocr_mask; |
1793 | 2150 | ||
1794 | /* Request IRQ for card detect */ | 2151 | /* Request IRQ for card detect */ |
@@ -1823,19 +2180,22 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1823 | ret = device_create_file(&mmc->class_dev, | 2180 | ret = device_create_file(&mmc->class_dev, |
1824 | &dev_attr_cover_switch); | 2181 | &dev_attr_cover_switch); |
1825 | if (ret < 0) | 2182 | if (ret < 0) |
1826 | goto err_cover_switch; | 2183 | goto err_slot_name; |
1827 | } | 2184 | } |
1828 | 2185 | ||
1829 | omap_hsmmc_debugfs(mmc); | 2186 | omap_hsmmc_debugfs(mmc); |
1830 | 2187 | ||
1831 | return 0; | 2188 | return 0; |
1832 | 2189 | ||
1833 | err_cover_switch: | ||
1834 | device_remove_file(&mmc->class_dev, &dev_attr_cover_switch); | ||
1835 | err_slot_name: | 2190 | err_slot_name: |
1836 | mmc_remove_host(mmc); | 2191 | mmc_remove_host(mmc); |
1837 | err_irq_cd: | ||
1838 | free_irq(mmc_slot(host).card_detect_irq, host); | 2192 | free_irq(mmc_slot(host).card_detect_irq, host); |
2193 | err_irq_cd: | ||
2194 | if (host->use_reg) | ||
2195 | omap_hsmmc_reg_put(host); | ||
2196 | err_reg: | ||
2197 | if (host->pdata->cleanup) | ||
2198 | host->pdata->cleanup(&pdev->dev); | ||
1839 | err_irq_cd_init: | 2199 | err_irq_cd_init: |
1840 | free_irq(host->irq, host); | 2200 | free_irq(host->irq, host); |
1841 | err_irq: | 2201 | err_irq: |
@@ -1847,14 +2207,14 @@ err_irq: | |||
1847 | clk_disable(host->dbclk); | 2207 | clk_disable(host->dbclk); |
1848 | clk_put(host->dbclk); | 2208 | clk_put(host->dbclk); |
1849 | } | 2209 | } |
1850 | |||
1851 | err1: | 2210 | err1: |
1852 | iounmap(host->base); | 2211 | iounmap(host->base); |
2212 | platform_set_drvdata(pdev, NULL); | ||
2213 | mmc_free_host(mmc); | ||
2214 | err_alloc: | ||
2215 | omap_hsmmc_gpio_free(pdata); | ||
1853 | err: | 2216 | err: |
1854 | dev_dbg(mmc_dev(host->mmc), "Probe Failed\n"); | ||
1855 | release_mem_region(res->start, res->end - res->start + 1); | 2217 | release_mem_region(res->start, res->end - res->start + 1); |
1856 | if (host) | ||
1857 | mmc_free_host(mmc); | ||
1858 | return ret; | 2218 | return ret; |
1859 | } | 2219 | } |
1860 | 2220 | ||
@@ -1866,6 +2226,8 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
1866 | if (host) { | 2226 | if (host) { |
1867 | mmc_host_enable(host->mmc); | 2227 | mmc_host_enable(host->mmc); |
1868 | mmc_remove_host(host->mmc); | 2228 | mmc_remove_host(host->mmc); |
2229 | if (host->use_reg) | ||
2230 | omap_hsmmc_reg_put(host); | ||
1869 | if (host->pdata->cleanup) | 2231 | if (host->pdata->cleanup) |
1870 | host->pdata->cleanup(&pdev->dev); | 2232 | host->pdata->cleanup(&pdev->dev); |
1871 | free_irq(host->irq, host); | 2233 | free_irq(host->irq, host); |
@@ -1884,6 +2246,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
1884 | 2246 | ||
1885 | mmc_free_host(host->mmc); | 2247 | mmc_free_host(host->mmc); |
1886 | iounmap(host->base); | 2248 | iounmap(host->base); |
2249 | omap_hsmmc_gpio_free(pdev->dev.platform_data); | ||
1887 | } | 2250 | } |
1888 | 2251 | ||
1889 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2252 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 9fb480bb0e0a..0ed48959b590 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
30 | #include <linux/regulator/consumer.h> | 30 | #include <linux/regulator/consumer.h> |
31 | #include <linux/gpio.h> | 31 | #include <linux/gpio.h> |
32 | #include <linux/gfp.h> | ||
32 | 33 | ||
33 | #include <asm/sizes.h> | 34 | #include <asm/sizes.h> |
34 | 35 | ||
@@ -43,6 +44,9 @@ | |||
43 | #define NR_SG 1 | 44 | #define NR_SG 1 |
44 | #define CLKRT_OFF (~0) | 45 | #define CLKRT_OFF (~0) |
45 | 46 | ||
47 | #define mmc_has_26MHz() (cpu_is_pxa300() || cpu_is_pxa310() \ | ||
48 | || cpu_is_pxa935()) | ||
49 | |||
46 | struct pxamci_host { | 50 | struct pxamci_host { |
47 | struct mmc_host *mmc; | 51 | struct mmc_host *mmc; |
48 | spinlock_t lock; | 52 | spinlock_t lock; |
@@ -457,7 +461,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
457 | clk_enable(host->clk); | 461 | clk_enable(host->clk); |
458 | 462 | ||
459 | if (ios->clock == 26000000) { | 463 | if (ios->clock == 26000000) { |
460 | /* to support 26MHz on pxa300/pxa310 */ | 464 | /* to support 26MHz */ |
461 | host->clkrt = 7; | 465 | host->clkrt = 7; |
462 | } else { | 466 | } else { |
463 | /* to handle (19.5MHz, 26MHz) */ | 467 | /* to handle (19.5MHz, 26MHz) */ |
@@ -608,8 +612,7 @@ static int pxamci_probe(struct platform_device *pdev) | |||
608 | * Calculate minimum clock rate, rounding up. | 612 | * Calculate minimum clock rate, rounding up. |
609 | */ | 613 | */ |
610 | mmc->f_min = (host->clkrate + 63) / 64; | 614 | mmc->f_min = (host->clkrate + 63) / 64; |
611 | mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000 | 615 | mmc->f_max = (mmc_has_26MHz()) ? 26000000 : host->clkrate; |
612 | : host->clkrate; | ||
613 | 616 | ||
614 | pxamci_init_ocr(host); | 617 | pxamci_init_ocr(host); |
615 | 618 | ||
@@ -618,7 +621,7 @@ static int pxamci_probe(struct platform_device *pdev) | |||
618 | if (!cpu_is_pxa25x()) { | 621 | if (!cpu_is_pxa25x()) { |
619 | mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; | 622 | mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; |
620 | host->cmdat |= CMDAT_SDIO_INT_EN; | 623 | host->cmdat |= CMDAT_SDIO_INT_EN; |
621 | if (cpu_is_pxa300() || cpu_is_pxa310()) | 624 | if (mmc_has_26MHz()) |
622 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | | 625 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | |
623 | MMC_CAP_SD_HIGHSPEED; | 626 | MMC_CAP_SD_HIGHSPEED; |
624 | } | 627 | } |
@@ -826,7 +829,7 @@ static int pxamci_resume(struct device *dev) | |||
826 | return ret; | 829 | return ret; |
827 | } | 830 | } |
828 | 831 | ||
829 | static struct dev_pm_ops pxamci_pm_ops = { | 832 | static const struct dev_pm_ops pxamci_pm_ops = { |
830 | .suspend = pxamci_suspend, | 833 | .suspend = pxamci_suspend, |
831 | .resume = pxamci_resume, | 834 | .resume = pxamci_resume, |
832 | }; | 835 | }; |
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c deleted file mode 100644 index f62790513322..000000000000 --- a/drivers/mmc/host/ricoh_mmc.c +++ /dev/null | |||
@@ -1,262 +0,0 @@ | |||
1 | /* | ||
2 | * ricoh_mmc.c - Dummy driver to disable the Rioch MMC controller. | ||
3 | * | ||
4 | * Copyright (C) 2007 Philip Langdale, All Rights Reserved. | ||
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 as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
9 | * your option) any later version. | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This is a conceptually ridiculous driver, but it is required by the way | ||
14 | * the Ricoh multi-function chips (R5CXXX) work. These chips implement | ||
15 | * the four main memory card controllers (SD, MMC, MS, xD) and one or both | ||
16 | * of cardbus or firewire. It happens that they implement SD and MMC | ||
17 | * support as separate controllers (and PCI functions). The linux SDHCI | ||
18 | * driver supports MMC cards but the chip detects MMC cards in hardware | ||
19 | * and directs them to the MMC controller - so the SDHCI driver never sees | ||
20 | * them. To get around this, we must disable the useless MMC controller. | ||
21 | * At that point, the SDHCI controller will start seeing them. As a bonus, | ||
22 | * a detection event occurs immediately, even if the MMC card is already | ||
23 | * in the reader. | ||
24 | * | ||
25 | * It seems to be the case that the relevant PCI registers to deactivate the | ||
26 | * MMC controller live on PCI function 0, which might be the cardbus controller | ||
27 | * or the firewire controller, depending on the particular chip in question. As | ||
28 | * such, it makes what this driver has to do unavoidably ugly. Such is life. | ||
29 | */ | ||
30 | |||
31 | #include <linux/pci.h> | ||
32 | |||
33 | #define DRIVER_NAME "ricoh-mmc" | ||
34 | |||
35 | static const struct pci_device_id pci_ids[] __devinitdata = { | ||
36 | { | ||
37 | .vendor = PCI_VENDOR_ID_RICOH, | ||
38 | .device = PCI_DEVICE_ID_RICOH_R5C843, | ||
39 | .subvendor = PCI_ANY_ID, | ||
40 | .subdevice = PCI_ANY_ID, | ||
41 | }, | ||
42 | { /* end: all zeroes */ }, | ||
43 | }; | ||
44 | |||
45 | MODULE_DEVICE_TABLE(pci, pci_ids); | ||
46 | |||
47 | static int ricoh_mmc_disable(struct pci_dev *fw_dev) | ||
48 | { | ||
49 | u8 write_enable; | ||
50 | u8 write_target; | ||
51 | u8 disable; | ||
52 | |||
53 | if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) { | ||
54 | /* via RL5C476 */ | ||
55 | |||
56 | pci_read_config_byte(fw_dev, 0xB7, &disable); | ||
57 | if (disable & 0x02) { | ||
58 | printk(KERN_INFO DRIVER_NAME | ||
59 | ": Controller already disabled. " \ | ||
60 | "Nothing to do.\n"); | ||
61 | return -ENODEV; | ||
62 | } | ||
63 | |||
64 | pci_read_config_byte(fw_dev, 0x8E, &write_enable); | ||
65 | pci_write_config_byte(fw_dev, 0x8E, 0xAA); | ||
66 | pci_read_config_byte(fw_dev, 0x8D, &write_target); | ||
67 | pci_write_config_byte(fw_dev, 0x8D, 0xB7); | ||
68 | pci_write_config_byte(fw_dev, 0xB7, disable | 0x02); | ||
69 | pci_write_config_byte(fw_dev, 0x8E, write_enable); | ||
70 | pci_write_config_byte(fw_dev, 0x8D, write_target); | ||
71 | } else { | ||
72 | /* via R5C832 */ | ||
73 | |||
74 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
75 | if (disable & 0x02) { | ||
76 | printk(KERN_INFO DRIVER_NAME | ||
77 | ": Controller already disabled. " \ | ||
78 | "Nothing to do.\n"); | ||
79 | return -ENODEV; | ||
80 | } | ||
81 | |||
82 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
83 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
84 | pci_write_config_byte(fw_dev, 0xCB, disable | 0x02); | ||
85 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
86 | } | ||
87 | |||
88 | printk(KERN_INFO DRIVER_NAME | ||
89 | ": Controller is now disabled.\n"); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int ricoh_mmc_enable(struct pci_dev *fw_dev) | ||
95 | { | ||
96 | u8 write_enable; | ||
97 | u8 write_target; | ||
98 | u8 disable; | ||
99 | |||
100 | if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) { | ||
101 | /* via RL5C476 */ | ||
102 | |||
103 | pci_read_config_byte(fw_dev, 0x8E, &write_enable); | ||
104 | pci_write_config_byte(fw_dev, 0x8E, 0xAA); | ||
105 | pci_read_config_byte(fw_dev, 0x8D, &write_target); | ||
106 | pci_write_config_byte(fw_dev, 0x8D, 0xB7); | ||
107 | pci_read_config_byte(fw_dev, 0xB7, &disable); | ||
108 | pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02); | ||
109 | pci_write_config_byte(fw_dev, 0x8E, write_enable); | ||
110 | pci_write_config_byte(fw_dev, 0x8D, write_target); | ||
111 | } else { | ||
112 | /* via R5C832 */ | ||
113 | |||
114 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
115 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
116 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
117 | pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02); | ||
118 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
119 | } | ||
120 | |||
121 | printk(KERN_INFO DRIVER_NAME | ||
122 | ": Controller is now re-enabled.\n"); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | ||
128 | const struct pci_device_id *ent) | ||
129 | { | ||
130 | u8 rev; | ||
131 | u8 ctrlfound = 0; | ||
132 | |||
133 | struct pci_dev *fw_dev = NULL; | ||
134 | |||
135 | BUG_ON(pdev == NULL); | ||
136 | BUG_ON(ent == NULL); | ||
137 | |||
138 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev); | ||
139 | |||
140 | printk(KERN_INFO DRIVER_NAME | ||
141 | ": Ricoh MMC controller found at %s [%04x:%04x] (rev %x)\n", | ||
142 | pci_name(pdev), (int)pdev->vendor, (int)pdev->device, | ||
143 | (int)rev); | ||
144 | |||
145 | while ((fw_dev = | ||
146 | pci_get_device(PCI_VENDOR_ID_RICOH, | ||
147 | PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) { | ||
148 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | ||
149 | PCI_FUNC(fw_dev->devfn) == 0 && | ||
150 | pdev->bus == fw_dev->bus) { | ||
151 | if (ricoh_mmc_disable(fw_dev) != 0) | ||
152 | return -ENODEV; | ||
153 | |||
154 | pci_set_drvdata(pdev, fw_dev); | ||
155 | |||
156 | ++ctrlfound; | ||
157 | break; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | fw_dev = NULL; | ||
162 | |||
163 | while (!ctrlfound && | ||
164 | (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, | ||
165 | PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { | ||
166 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | ||
167 | PCI_FUNC(fw_dev->devfn) == 0 && | ||
168 | pdev->bus == fw_dev->bus) { | ||
169 | if (ricoh_mmc_disable(fw_dev) != 0) | ||
170 | return -ENODEV; | ||
171 | |||
172 | pci_set_drvdata(pdev, fw_dev); | ||
173 | |||
174 | ++ctrlfound; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | if (!ctrlfound) { | ||
179 | printk(KERN_WARNING DRIVER_NAME | ||
180 | ": Main Ricoh function not found. Cannot disable controller.\n"); | ||
181 | return -ENODEV; | ||
182 | } | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static void __devexit ricoh_mmc_remove(struct pci_dev *pdev) | ||
188 | { | ||
189 | struct pci_dev *fw_dev = NULL; | ||
190 | |||
191 | fw_dev = pci_get_drvdata(pdev); | ||
192 | BUG_ON(fw_dev == NULL); | ||
193 | |||
194 | ricoh_mmc_enable(fw_dev); | ||
195 | |||
196 | pci_set_drvdata(pdev, NULL); | ||
197 | } | ||
198 | |||
199 | static int ricoh_mmc_suspend_late(struct pci_dev *pdev, pm_message_t state) | ||
200 | { | ||
201 | struct pci_dev *fw_dev = NULL; | ||
202 | |||
203 | fw_dev = pci_get_drvdata(pdev); | ||
204 | BUG_ON(fw_dev == NULL); | ||
205 | |||
206 | printk(KERN_INFO DRIVER_NAME ": Suspending.\n"); | ||
207 | |||
208 | ricoh_mmc_enable(fw_dev); | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static int ricoh_mmc_resume_early(struct pci_dev *pdev) | ||
214 | { | ||
215 | struct pci_dev *fw_dev = NULL; | ||
216 | |||
217 | fw_dev = pci_get_drvdata(pdev); | ||
218 | BUG_ON(fw_dev == NULL); | ||
219 | |||
220 | printk(KERN_INFO DRIVER_NAME ": Resuming.\n"); | ||
221 | |||
222 | ricoh_mmc_disable(fw_dev); | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static struct pci_driver ricoh_mmc_driver = { | ||
228 | .name = DRIVER_NAME, | ||
229 | .id_table = pci_ids, | ||
230 | .probe = ricoh_mmc_probe, | ||
231 | .remove = __devexit_p(ricoh_mmc_remove), | ||
232 | .suspend_late = ricoh_mmc_suspend_late, | ||
233 | .resume_early = ricoh_mmc_resume_early, | ||
234 | }; | ||
235 | |||
236 | /*****************************************************************************\ | ||
237 | * * | ||
238 | * Driver init/exit * | ||
239 | * * | ||
240 | \*****************************************************************************/ | ||
241 | |||
242 | static int __init ricoh_mmc_drv_init(void) | ||
243 | { | ||
244 | printk(KERN_INFO DRIVER_NAME | ||
245 | ": Ricoh MMC Controller disabling driver\n"); | ||
246 | printk(KERN_INFO DRIVER_NAME ": Copyright(c) Philip Langdale\n"); | ||
247 | |||
248 | return pci_register_driver(&ricoh_mmc_driver); | ||
249 | } | ||
250 | |||
251 | static void __exit ricoh_mmc_drv_exit(void) | ||
252 | { | ||
253 | pci_unregister_driver(&ricoh_mmc_driver); | ||
254 | } | ||
255 | |||
256 | module_init(ricoh_mmc_drv_init); | ||
257 | module_exit(ricoh_mmc_drv_exit); | ||
258 | |||
259 | MODULE_AUTHOR("Philip Langdale <philipl@alumni.utexas.net>"); | ||
260 | MODULE_DESCRIPTION("Ricoh MMC Controller disabling driver"); | ||
261 | MODULE_LICENSE("GPL"); | ||
262 | |||
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 99b74a351020..2fdf7689ae6c 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
@@ -820,7 +820,7 @@ fail_request: | |||
820 | static void finalize_request(struct s3cmci_host *host) | 820 | static void finalize_request(struct s3cmci_host *host) |
821 | { | 821 | { |
822 | struct mmc_request *mrq = host->mrq; | 822 | struct mmc_request *mrq = host->mrq; |
823 | struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; | 823 | struct mmc_command *cmd; |
824 | int debug_as_failure = 0; | 824 | int debug_as_failure = 0; |
825 | 825 | ||
826 | if (host->complete_what != COMPLETION_FINALIZE) | 826 | if (host->complete_what != COMPLETION_FINALIZE) |
@@ -828,6 +828,7 @@ static void finalize_request(struct s3cmci_host *host) | |||
828 | 828 | ||
829 | if (!mrq) | 829 | if (!mrq) |
830 | return; | 830 | return; |
831 | cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; | ||
831 | 832 | ||
832 | if (cmd->data && (cmd->error == 0) && | 833 | if (cmd->data && (cmd->error == 0) && |
833 | (cmd->data->error == 0)) { | 834 | (cmd->data->error == 0)) { |
@@ -1178,7 +1179,7 @@ static int s3cmci_card_present(struct mmc_host *mmc) | |||
1178 | struct s3c24xx_mci_pdata *pdata = host->pdata; | 1179 | struct s3c24xx_mci_pdata *pdata = host->pdata; |
1179 | int ret; | 1180 | int ret; |
1180 | 1181 | ||
1181 | if (pdata->gpio_detect == 0) | 1182 | if (pdata->no_detect) |
1182 | return -ENOSYS; | 1183 | return -ENOSYS; |
1183 | 1184 | ||
1184 | ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1; | 1185 | ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1; |
@@ -1302,10 +1303,8 @@ static int s3cmci_get_ro(struct mmc_host *mmc) | |||
1302 | if (pdata->no_wprotect) | 1303 | if (pdata->no_wprotect) |
1303 | return 0; | 1304 | return 0; |
1304 | 1305 | ||
1305 | ret = s3c2410_gpio_getpin(pdata->gpio_wprotect); | 1306 | ret = gpio_get_value(pdata->gpio_wprotect) ? 1 : 0; |
1306 | 1307 | ret ^= pdata->wprotect_invert; | |
1307 | if (pdata->wprotect_invert) | ||
1308 | ret = !ret; | ||
1309 | 1308 | ||
1310 | return ret; | 1309 | return ret; |
1311 | } | 1310 | } |
@@ -1360,7 +1359,9 @@ static struct mmc_host_ops s3cmci_ops = { | |||
1360 | 1359 | ||
1361 | static struct s3c24xx_mci_pdata s3cmci_def_pdata = { | 1360 | static struct s3c24xx_mci_pdata s3cmci_def_pdata = { |
1362 | /* This is currently here to avoid a number of if (host->pdata) | 1361 | /* This is currently here to avoid a number of if (host->pdata) |
1363 | * checks. Any zero fields to ensure reaonable defaults are picked. */ | 1362 | * checks. Any zero fields to ensure reasonable defaults are picked. */ |
1363 | .no_wprotect = 1, | ||
1364 | .no_detect = 1, | ||
1364 | }; | 1365 | }; |
1365 | 1366 | ||
1366 | #ifdef CONFIG_CPU_FREQ | 1367 | #ifdef CONFIG_CPU_FREQ |
@@ -1654,7 +1655,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev) | |||
1654 | goto probe_free_irq; | 1655 | goto probe_free_irq; |
1655 | } | 1656 | } |
1656 | 1657 | ||
1657 | host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect); | 1658 | host->irq_cd = gpio_to_irq(host->pdata->gpio_detect); |
1658 | 1659 | ||
1659 | if (host->irq_cd >= 0) { | 1660 | if (host->irq_cd >= 0) { |
1660 | if (request_irq(host->irq_cd, s3cmci_irq_cd, | 1661 | if (request_irq(host->irq_cd, s3cmci_irq_cd, |
@@ -1892,7 +1893,7 @@ static int s3cmci_resume(struct device *dev) | |||
1892 | return mmc_resume_host(mmc); | 1893 | return mmc_resume_host(mmc); |
1893 | } | 1894 | } |
1894 | 1895 | ||
1895 | static struct dev_pm_ops s3cmci_pm = { | 1896 | static const struct dev_pm_ops s3cmci_pm = { |
1896 | .suspend = s3cmci_suspend, | 1897 | .suspend = s3cmci_suspend, |
1897 | .resume = s3cmci_resume, | 1898 | .resume = s3cmci_resume, |
1898 | }; | 1899 | }; |
diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of-core.c index 01ab916c2802..55e33135edb4 100644 --- a/drivers/mmc/host/sdhci-of.c +++ b/drivers/mmc/host/sdhci-of-core.c | |||
@@ -22,62 +22,37 @@ | |||
22 | #include <linux/of_platform.h> | 22 | #include <linux/of_platform.h> |
23 | #include <linux/mmc/host.h> | 23 | #include <linux/mmc/host.h> |
24 | #include <asm/machdep.h> | 24 | #include <asm/machdep.h> |
25 | #include "sdhci-of.h" | ||
25 | #include "sdhci.h" | 26 | #include "sdhci.h" |
26 | 27 | ||
27 | struct sdhci_of_data { | 28 | #ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER |
28 | unsigned int quirks; | ||
29 | struct sdhci_ops ops; | ||
30 | }; | ||
31 | |||
32 | struct sdhci_of_host { | ||
33 | unsigned int clock; | ||
34 | u16 xfer_mode_shadow; | ||
35 | }; | ||
36 | 29 | ||
37 | /* | 30 | /* |
38 | * Ops and quirks for the Freescale eSDHC controller. | 31 | * These accessors are designed for big endian hosts doing I/O to |
32 | * little endian controllers incorporating a 32-bit hardware byte swapper. | ||
39 | */ | 33 | */ |
40 | 34 | ||
41 | #define ESDHC_DMA_SYSCTL 0x40c | 35 | u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg) |
42 | #define ESDHC_DMA_SNOOP 0x00000040 | ||
43 | |||
44 | #define ESDHC_SYSTEM_CONTROL 0x2c | ||
45 | #define ESDHC_CLOCK_MASK 0x0000fff0 | ||
46 | #define ESDHC_PREDIV_SHIFT 8 | ||
47 | #define ESDHC_DIVIDER_SHIFT 4 | ||
48 | #define ESDHC_CLOCK_PEREN 0x00000004 | ||
49 | #define ESDHC_CLOCK_HCKEN 0x00000002 | ||
50 | #define ESDHC_CLOCK_IPGEN 0x00000001 | ||
51 | |||
52 | #define ESDHC_HOST_CONTROL_RES 0x05 | ||
53 | |||
54 | static u32 esdhc_readl(struct sdhci_host *host, int reg) | ||
55 | { | 36 | { |
56 | return in_be32(host->ioaddr + reg); | 37 | return in_be32(host->ioaddr + reg); |
57 | } | 38 | } |
58 | 39 | ||
59 | static u16 esdhc_readw(struct sdhci_host *host, int reg) | 40 | u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg) |
60 | { | 41 | { |
61 | u16 ret; | 42 | return in_be16(host->ioaddr + (reg ^ 0x2)); |
62 | |||
63 | if (unlikely(reg == SDHCI_HOST_VERSION)) | ||
64 | ret = in_be16(host->ioaddr + reg); | ||
65 | else | ||
66 | ret = in_be16(host->ioaddr + (reg ^ 0x2)); | ||
67 | return ret; | ||
68 | } | 43 | } |
69 | 44 | ||
70 | static u8 esdhc_readb(struct sdhci_host *host, int reg) | 45 | u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg) |
71 | { | 46 | { |
72 | return in_8(host->ioaddr + (reg ^ 0x3)); | 47 | return in_8(host->ioaddr + (reg ^ 0x3)); |
73 | } | 48 | } |
74 | 49 | ||
75 | static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) | 50 | void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg) |
76 | { | 51 | { |
77 | out_be32(host->ioaddr + reg, val); | 52 | out_be32(host->ioaddr + reg, val); |
78 | } | 53 | } |
79 | 54 | ||
80 | static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) | 55 | void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg) |
81 | { | 56 | { |
82 | struct sdhci_of_host *of_host = sdhci_priv(host); | 57 | struct sdhci_of_host *of_host = sdhci_priv(host); |
83 | int base = reg & ~0x3; | 58 | int base = reg & ~0x3; |
@@ -92,106 +67,21 @@ static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) | |||
92 | of_host->xfer_mode_shadow = val; | 67 | of_host->xfer_mode_shadow = val; |
93 | return; | 68 | return; |
94 | case SDHCI_COMMAND: | 69 | case SDHCI_COMMAND: |
95 | esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow, | 70 | sdhci_be32bs_writel(host, val << 16 | of_host->xfer_mode_shadow, |
96 | SDHCI_TRANSFER_MODE); | 71 | SDHCI_TRANSFER_MODE); |
97 | return; | 72 | return; |
98 | case SDHCI_BLOCK_SIZE: | ||
99 | /* | ||
100 | * Two last DMA bits are reserved, and first one is used for | ||
101 | * non-standard blksz of 4096 bytes that we don't support | ||
102 | * yet. So clear the DMA boundary bits. | ||
103 | */ | ||
104 | val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); | ||
105 | /* fall through */ | ||
106 | } | 73 | } |
107 | clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); | 74 | clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); |
108 | } | 75 | } |
109 | 76 | ||
110 | static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) | 77 | void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg) |
111 | { | 78 | { |
112 | int base = reg & ~0x3; | 79 | int base = reg & ~0x3; |
113 | int shift = (reg & 0x3) * 8; | 80 | int shift = (reg & 0x3) * 8; |
114 | 81 | ||
115 | /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ | ||
116 | if (reg == SDHCI_HOST_CONTROL) | ||
117 | val &= ~ESDHC_HOST_CONTROL_RES; | ||
118 | |||
119 | clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); | 82 | clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); |
120 | } | 83 | } |
121 | 84 | #endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */ | |
122 | static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) | ||
123 | { | ||
124 | int pre_div = 2; | ||
125 | int div = 1; | ||
126 | |||
127 | clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | | ||
128 | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); | ||
129 | |||
130 | if (clock == 0) | ||
131 | goto out; | ||
132 | |||
133 | while (host->max_clk / pre_div / 16 > clock && pre_div < 256) | ||
134 | pre_div *= 2; | ||
135 | |||
136 | while (host->max_clk / pre_div / div > clock && div < 16) | ||
137 | div++; | ||
138 | |||
139 | dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", | ||
140 | clock, host->max_clk / pre_div / div); | ||
141 | |||
142 | pre_div >>= 1; | ||
143 | div--; | ||
144 | |||
145 | setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | | ||
146 | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | | ||
147 | div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT); | ||
148 | mdelay(100); | ||
149 | out: | ||
150 | host->clock = clock; | ||
151 | } | ||
152 | |||
153 | static int esdhc_enable_dma(struct sdhci_host *host) | ||
154 | { | ||
155 | setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static unsigned int esdhc_get_max_clock(struct sdhci_host *host) | ||
160 | { | ||
161 | struct sdhci_of_host *of_host = sdhci_priv(host); | ||
162 | |||
163 | return of_host->clock; | ||
164 | } | ||
165 | |||
166 | static unsigned int esdhc_get_min_clock(struct sdhci_host *host) | ||
167 | { | ||
168 | struct sdhci_of_host *of_host = sdhci_priv(host); | ||
169 | |||
170 | return of_host->clock / 256 / 16; | ||
171 | } | ||
172 | |||
173 | static struct sdhci_of_data sdhci_esdhc = { | ||
174 | .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | | ||
175 | SDHCI_QUIRK_BROKEN_CARD_DETECTION | | ||
176 | SDHCI_QUIRK_NO_BUSY_IRQ | | ||
177 | SDHCI_QUIRK_NONSTANDARD_CLOCK | | ||
178 | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | | ||
179 | SDHCI_QUIRK_PIO_NEEDS_DELAY | | ||
180 | SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | | ||
181 | SDHCI_QUIRK_NO_CARD_NO_RESET, | ||
182 | .ops = { | ||
183 | .readl = esdhc_readl, | ||
184 | .readw = esdhc_readw, | ||
185 | .readb = esdhc_readb, | ||
186 | .writel = esdhc_writel, | ||
187 | .writew = esdhc_writew, | ||
188 | .writeb = esdhc_writeb, | ||
189 | .set_clock = esdhc_set_clock, | ||
190 | .enable_dma = esdhc_enable_dma, | ||
191 | .get_max_clock = esdhc_get_max_clock, | ||
192 | .get_min_clock = esdhc_get_min_clock, | ||
193 | }, | ||
194 | }; | ||
195 | 85 | ||
196 | #ifdef CONFIG_PM | 86 | #ifdef CONFIG_PM |
197 | 87 | ||
@@ -301,9 +191,14 @@ static int __devexit sdhci_of_remove(struct of_device *ofdev) | |||
301 | } | 191 | } |
302 | 192 | ||
303 | static const struct of_device_id sdhci_of_match[] = { | 193 | static const struct of_device_id sdhci_of_match[] = { |
194 | #ifdef CONFIG_MMC_SDHCI_OF_ESDHC | ||
304 | { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, | 195 | { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, |
305 | { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, | 196 | { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, |
306 | { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, | 197 | { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, |
198 | #endif | ||
199 | #ifdef CONFIG_MMC_SDHCI_OF_HLWD | ||
200 | { .compatible = "nintendo,hollywood-sdhci", .data = &sdhci_hlwd, }, | ||
201 | #endif | ||
307 | { .compatible = "generic-sdhci", }, | 202 | { .compatible = "generic-sdhci", }, |
308 | {}, | 203 | {}, |
309 | }; | 204 | }; |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c new file mode 100644 index 000000000000..d5b11a17e648 --- /dev/null +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * Freescale eSDHC controller driver. | ||
3 | * | ||
4 | * Copyright (c) 2007 Freescale Semiconductor, Inc. | ||
5 | * Copyright (c) 2009 MontaVista Software, Inc. | ||
6 | * | ||
7 | * Authors: Xiaobo Xie <X.Xie@freescale.com> | ||
8 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or (at | ||
13 | * your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/io.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/mmc/host.h> | ||
19 | #include "sdhci-of.h" | ||
20 | #include "sdhci.h" | ||
21 | |||
22 | /* | ||
23 | * Ops and quirks for the Freescale eSDHC controller. | ||
24 | */ | ||
25 | |||
26 | #define ESDHC_DMA_SYSCTL 0x40c | ||
27 | #define ESDHC_DMA_SNOOP 0x00000040 | ||
28 | |||
29 | #define ESDHC_SYSTEM_CONTROL 0x2c | ||
30 | #define ESDHC_CLOCK_MASK 0x0000fff0 | ||
31 | #define ESDHC_PREDIV_SHIFT 8 | ||
32 | #define ESDHC_DIVIDER_SHIFT 4 | ||
33 | #define ESDHC_CLOCK_PEREN 0x00000004 | ||
34 | #define ESDHC_CLOCK_HCKEN 0x00000002 | ||
35 | #define ESDHC_CLOCK_IPGEN 0x00000001 | ||
36 | |||
37 | #define ESDHC_HOST_CONTROL_RES 0x05 | ||
38 | |||
39 | static u16 esdhc_readw(struct sdhci_host *host, int reg) | ||
40 | { | ||
41 | u16 ret; | ||
42 | |||
43 | if (unlikely(reg == SDHCI_HOST_VERSION)) | ||
44 | ret = in_be16(host->ioaddr + reg); | ||
45 | else | ||
46 | ret = sdhci_be32bs_readw(host, reg); | ||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) | ||
51 | { | ||
52 | if (reg == SDHCI_BLOCK_SIZE) { | ||
53 | /* | ||
54 | * Two last DMA bits are reserved, and first one is used for | ||
55 | * non-standard blksz of 4096 bytes that we don't support | ||
56 | * yet. So clear the DMA boundary bits. | ||
57 | */ | ||
58 | val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); | ||
59 | } | ||
60 | sdhci_be32bs_writew(host, val, reg); | ||
61 | } | ||
62 | |||
63 | static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) | ||
64 | { | ||
65 | /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ | ||
66 | if (reg == SDHCI_HOST_CONTROL) | ||
67 | val &= ~ESDHC_HOST_CONTROL_RES; | ||
68 | sdhci_be32bs_writeb(host, val, reg); | ||
69 | } | ||
70 | |||
71 | static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) | ||
72 | { | ||
73 | int pre_div = 2; | ||
74 | int div = 1; | ||
75 | |||
76 | clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | | ||
77 | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); | ||
78 | |||
79 | if (clock == 0) | ||
80 | goto out; | ||
81 | |||
82 | while (host->max_clk / pre_div / 16 > clock && pre_div < 256) | ||
83 | pre_div *= 2; | ||
84 | |||
85 | while (host->max_clk / pre_div / div > clock && div < 16) | ||
86 | div++; | ||
87 | |||
88 | dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", | ||
89 | clock, host->max_clk / pre_div / div); | ||
90 | |||
91 | pre_div >>= 1; | ||
92 | div--; | ||
93 | |||
94 | setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | | ||
95 | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | | ||
96 | div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT); | ||
97 | mdelay(100); | ||
98 | out: | ||
99 | host->clock = clock; | ||
100 | } | ||
101 | |||
102 | static int esdhc_enable_dma(struct sdhci_host *host) | ||
103 | { | ||
104 | setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static unsigned int esdhc_get_max_clock(struct sdhci_host *host) | ||
109 | { | ||
110 | struct sdhci_of_host *of_host = sdhci_priv(host); | ||
111 | |||
112 | return of_host->clock; | ||
113 | } | ||
114 | |||
115 | static unsigned int esdhc_get_min_clock(struct sdhci_host *host) | ||
116 | { | ||
117 | struct sdhci_of_host *of_host = sdhci_priv(host); | ||
118 | |||
119 | return of_host->clock / 256 / 16; | ||
120 | } | ||
121 | |||
122 | struct sdhci_of_data sdhci_esdhc = { | ||
123 | .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | | ||
124 | SDHCI_QUIRK_BROKEN_CARD_DETECTION | | ||
125 | SDHCI_QUIRK_NO_BUSY_IRQ | | ||
126 | SDHCI_QUIRK_NONSTANDARD_CLOCK | | ||
127 | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | | ||
128 | SDHCI_QUIRK_PIO_NEEDS_DELAY | | ||
129 | SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | | ||
130 | SDHCI_QUIRK_NO_CARD_NO_RESET, | ||
131 | .ops = { | ||
132 | .readl = sdhci_be32bs_readl, | ||
133 | .readw = esdhc_readw, | ||
134 | .readb = sdhci_be32bs_readb, | ||
135 | .writel = sdhci_be32bs_writel, | ||
136 | .writew = esdhc_writew, | ||
137 | .writeb = esdhc_writeb, | ||
138 | .set_clock = esdhc_set_clock, | ||
139 | .enable_dma = esdhc_enable_dma, | ||
140 | .get_max_clock = esdhc_get_max_clock, | ||
141 | .get_min_clock = esdhc_get_min_clock, | ||
142 | }, | ||
143 | }; | ||
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c new file mode 100644 index 000000000000..35117f3ed757 --- /dev/null +++ b/drivers/mmc/host/sdhci-of-hlwd.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * drivers/mmc/host/sdhci-of-hlwd.c | ||
3 | * | ||
4 | * Nintendo Wii Secure Digital Host Controller Interface. | ||
5 | * Copyright (C) 2009 The GameCube Linux Team | ||
6 | * Copyright (C) 2009 Albert Herranz | ||
7 | * | ||
8 | * Based on sdhci-of-esdhc.c | ||
9 | * | ||
10 | * Copyright (c) 2007 Freescale Semiconductor, Inc. | ||
11 | * Copyright (c) 2009 MontaVista Software, Inc. | ||
12 | * | ||
13 | * Authors: Xiaobo Xie <X.Xie@freescale.com> | ||
14 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or (at | ||
19 | * your option) any later version. | ||
20 | */ | ||
21 | |||
22 | #include <linux/delay.h> | ||
23 | #include <linux/mmc/host.h> | ||
24 | #include "sdhci-of.h" | ||
25 | #include "sdhci.h" | ||
26 | |||
27 | /* | ||
28 | * Ops and quirks for the Nintendo Wii SDHCI controllers. | ||
29 | */ | ||
30 | |||
31 | /* | ||
32 | * We need a small delay after each write, or things go horribly wrong. | ||
33 | */ | ||
34 | #define SDHCI_HLWD_WRITE_DELAY 5 /* usecs */ | ||
35 | |||
36 | static void sdhci_hlwd_writel(struct sdhci_host *host, u32 val, int reg) | ||
37 | { | ||
38 | sdhci_be32bs_writel(host, val, reg); | ||
39 | udelay(SDHCI_HLWD_WRITE_DELAY); | ||
40 | } | ||
41 | |||
42 | static void sdhci_hlwd_writew(struct sdhci_host *host, u16 val, int reg) | ||
43 | { | ||
44 | sdhci_be32bs_writew(host, val, reg); | ||
45 | udelay(SDHCI_HLWD_WRITE_DELAY); | ||
46 | } | ||
47 | |||
48 | static void sdhci_hlwd_writeb(struct sdhci_host *host, u8 val, int reg) | ||
49 | { | ||
50 | sdhci_be32bs_writeb(host, val, reg); | ||
51 | udelay(SDHCI_HLWD_WRITE_DELAY); | ||
52 | } | ||
53 | |||
54 | struct sdhci_of_data sdhci_hlwd = { | ||
55 | .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | | ||
56 | SDHCI_QUIRK_32BIT_DMA_SIZE, | ||
57 | .ops = { | ||
58 | .readl = sdhci_be32bs_readl, | ||
59 | .readw = sdhci_be32bs_readw, | ||
60 | .readb = sdhci_be32bs_readb, | ||
61 | .writel = sdhci_hlwd_writel, | ||
62 | .writew = sdhci_hlwd_writew, | ||
63 | .writeb = sdhci_hlwd_writeb, | ||
64 | }, | ||
65 | }; | ||
diff --git a/drivers/mmc/host/sdhci-of.h b/drivers/mmc/host/sdhci-of.h new file mode 100644 index 000000000000..ad09ad9915d8 --- /dev/null +++ b/drivers/mmc/host/sdhci-of.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * OpenFirmware bindings for Secure Digital Host Controller Interface. | ||
3 | * | ||
4 | * Copyright (c) 2007 Freescale Semiconductor, Inc. | ||
5 | * Copyright (c) 2009 MontaVista Software, Inc. | ||
6 | * | ||
7 | * Authors: Xiaobo Xie <X.Xie@freescale.com> | ||
8 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or (at | ||
13 | * your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #ifndef __SDHCI_OF_H | ||
17 | #define __SDHCI_OF_H | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include "sdhci.h" | ||
21 | |||
22 | struct sdhci_of_data { | ||
23 | unsigned int quirks; | ||
24 | struct sdhci_ops ops; | ||
25 | }; | ||
26 | |||
27 | struct sdhci_of_host { | ||
28 | unsigned int clock; | ||
29 | u16 xfer_mode_shadow; | ||
30 | }; | ||
31 | |||
32 | extern u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg); | ||
33 | extern u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg); | ||
34 | extern u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg); | ||
35 | extern void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg); | ||
36 | extern void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg); | ||
37 | extern void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg); | ||
38 | |||
39 | extern struct sdhci_of_data sdhci_esdhc; | ||
40 | extern struct sdhci_of_data sdhci_hlwd; | ||
41 | |||
42 | #endif /* __SDHCI_OF_H */ | ||
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index e0356644d1aa..6701af629c30 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/highmem.h> | 16 | #include <linux/highmem.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
19 | #include <linux/slab.h> | ||
19 | 20 | ||
20 | #include <linux/mmc/host.h> | 21 | #include <linux/mmc/host.h> |
21 | 22 | ||
@@ -80,9 +81,6 @@ struct sdhci_pci_chip { | |||
80 | 81 | ||
81 | static int ricoh_probe(struct sdhci_pci_chip *chip) | 82 | static int ricoh_probe(struct sdhci_pci_chip *chip) |
82 | { | 83 | { |
83 | if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) | ||
84 | chip->quirks |= SDHCI_QUIRK_CLOCK_BEFORE_RESET; | ||
85 | |||
86 | if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || | 84 | if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || |
87 | chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) | 85 | chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) |
88 | chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; | 86 | chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; |
@@ -92,7 +90,9 @@ static int ricoh_probe(struct sdhci_pci_chip *chip) | |||
92 | 90 | ||
93 | static const struct sdhci_pci_fixes sdhci_ricoh = { | 91 | static const struct sdhci_pci_fixes sdhci_ricoh = { |
94 | .probe = ricoh_probe, | 92 | .probe = ricoh_probe, |
95 | .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR, | 93 | .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | |
94 | SDHCI_QUIRK_FORCE_DMA | | ||
95 | SDHCI_QUIRK_CLOCK_BEFORE_RESET, | ||
96 | }; | 96 | }; |
97 | 97 | ||
98 | static const struct sdhci_pci_fixes sdhci_ene_712 = { | 98 | static const struct sdhci_pci_fixes sdhci_ene_712 = { |
@@ -285,6 +285,73 @@ static const struct sdhci_pci_fixes sdhci_jmicron = { | |||
285 | .resume = jmicron_resume, | 285 | .resume = jmicron_resume, |
286 | }; | 286 | }; |
287 | 287 | ||
288 | /* SysKonnect CardBus2SDIO extra registers */ | ||
289 | #define SYSKT_CTRL 0x200 | ||
290 | #define SYSKT_RDFIFO_STAT 0x204 | ||
291 | #define SYSKT_WRFIFO_STAT 0x208 | ||
292 | #define SYSKT_POWER_DATA 0x20c | ||
293 | #define SYSKT_POWER_330 0xef | ||
294 | #define SYSKT_POWER_300 0xf8 | ||
295 | #define SYSKT_POWER_184 0xcc | ||
296 | #define SYSKT_POWER_CMD 0x20d | ||
297 | #define SYSKT_POWER_START (1 << 7) | ||
298 | #define SYSKT_POWER_STATUS 0x20e | ||
299 | #define SYSKT_POWER_STATUS_OK (1 << 0) | ||
300 | #define SYSKT_BOARD_REV 0x210 | ||
301 | #define SYSKT_CHIP_REV 0x211 | ||
302 | #define SYSKT_CONF_DATA 0x212 | ||
303 | #define SYSKT_CONF_DATA_1V8 (1 << 2) | ||
304 | #define SYSKT_CONF_DATA_2V5 (1 << 1) | ||
305 | #define SYSKT_CONF_DATA_3V3 (1 << 0) | ||
306 | |||
307 | static int syskt_probe(struct sdhci_pci_chip *chip) | ||
308 | { | ||
309 | if ((chip->pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) { | ||
310 | chip->pdev->class &= ~0x0000FF; | ||
311 | chip->pdev->class |= PCI_SDHCI_IFDMA; | ||
312 | } | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int syskt_probe_slot(struct sdhci_pci_slot *slot) | ||
317 | { | ||
318 | int tm, ps; | ||
319 | |||
320 | u8 board_rev = readb(slot->host->ioaddr + SYSKT_BOARD_REV); | ||
321 | u8 chip_rev = readb(slot->host->ioaddr + SYSKT_CHIP_REV); | ||
322 | dev_info(&slot->chip->pdev->dev, "SysKonnect CardBus2SDIO, " | ||
323 | "board rev %d.%d, chip rev %d.%d\n", | ||
324 | board_rev >> 4, board_rev & 0xf, | ||
325 | chip_rev >> 4, chip_rev & 0xf); | ||
326 | if (chip_rev >= 0x20) | ||
327 | slot->host->quirks |= SDHCI_QUIRK_FORCE_DMA; | ||
328 | |||
329 | writeb(SYSKT_POWER_330, slot->host->ioaddr + SYSKT_POWER_DATA); | ||
330 | writeb(SYSKT_POWER_START, slot->host->ioaddr + SYSKT_POWER_CMD); | ||
331 | udelay(50); | ||
332 | tm = 10; /* Wait max 1 ms */ | ||
333 | do { | ||
334 | ps = readw(slot->host->ioaddr + SYSKT_POWER_STATUS); | ||
335 | if (ps & SYSKT_POWER_STATUS_OK) | ||
336 | break; | ||
337 | udelay(100); | ||
338 | } while (--tm); | ||
339 | if (!tm) { | ||
340 | dev_err(&slot->chip->pdev->dev, | ||
341 | "power regulator never stabilized"); | ||
342 | writeb(0, slot->host->ioaddr + SYSKT_POWER_CMD); | ||
343 | return -ENODEV; | ||
344 | } | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static const struct sdhci_pci_fixes sdhci_syskt = { | ||
350 | .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER, | ||
351 | .probe = syskt_probe, | ||
352 | .probe_slot = syskt_probe_slot, | ||
353 | }; | ||
354 | |||
288 | static int via_probe(struct sdhci_pci_chip *chip) | 355 | static int via_probe(struct sdhci_pci_chip *chip) |
289 | { | 356 | { |
290 | if (chip->pdev->revision == 0x10) | 357 | if (chip->pdev->revision == 0x10) |
@@ -363,6 +430,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = { | |||
363 | }, | 430 | }, |
364 | 431 | ||
365 | { | 432 | { |
433 | .vendor = PCI_VENDOR_ID_SYSKONNECT, | ||
434 | .device = 0x8000, | ||
435 | .subvendor = PCI_ANY_ID, | ||
436 | .subdevice = PCI_ANY_ID, | ||
437 | .driver_data = (kernel_ulong_t)&sdhci_syskt, | ||
438 | }, | ||
439 | |||
440 | { | ||
366 | .vendor = PCI_VENDOR_ID_VIA, | 441 | .vendor = PCI_VENDOR_ID_VIA, |
367 | .device = 0x95d0, | 442 | .device = 0x95d0, |
368 | .subvendor = PCI_ANY_ID, | 443 | .subvendor = PCI_ANY_ID, |
@@ -426,6 +501,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
426 | { | 501 | { |
427 | struct sdhci_pci_chip *chip; | 502 | struct sdhci_pci_chip *chip; |
428 | struct sdhci_pci_slot *slot; | 503 | struct sdhci_pci_slot *slot; |
504 | mmc_pm_flag_t pm_flags = 0; | ||
429 | int i, ret; | 505 | int i, ret; |
430 | 506 | ||
431 | chip = pci_get_drvdata(pdev); | 507 | chip = pci_get_drvdata(pdev); |
@@ -444,6 +520,8 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
444 | sdhci_resume_host(chip->slots[i]->host); | 520 | sdhci_resume_host(chip->slots[i]->host); |
445 | return ret; | 521 | return ret; |
446 | } | 522 | } |
523 | |||
524 | pm_flags |= slot->host->mmc->pm_flags; | ||
447 | } | 525 | } |
448 | 526 | ||
449 | if (chip->fixes && chip->fixes->suspend) { | 527 | if (chip->fixes && chip->fixes->suspend) { |
@@ -456,9 +534,15 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
456 | } | 534 | } |
457 | 535 | ||
458 | pci_save_state(pdev); | 536 | pci_save_state(pdev); |
459 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | 537 | if (pm_flags & MMC_PM_KEEP_POWER) { |
460 | pci_disable_device(pdev); | 538 | if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) |
461 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 539 | pci_enable_wake(pdev, PCI_D3hot, 1); |
540 | pci_set_power_state(pdev, PCI_D3hot); | ||
541 | } else { | ||
542 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
543 | pci_disable_device(pdev); | ||
544 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
545 | } | ||
462 | 546 | ||
463 | return 0; | 547 | return 0; |
464 | } | 548 | } |
@@ -578,6 +662,8 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
578 | goto unmap; | 662 | goto unmap; |
579 | } | 663 | } |
580 | 664 | ||
665 | host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; | ||
666 | |||
581 | ret = sdhci_add_host(host); | 667 | ret = sdhci_add_host(host); |
582 | if (ret) | 668 | if (ret) |
583 | goto remove; | 669 | goto remove; |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 50997d2a63e7..2136794c0cfa 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
20 | 21 | ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index c279fbc4c2e5..9d4fdfa685e5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/slab.h> | ||
20 | #include <linux/scatterlist.h> | 21 | #include <linux/scatterlist.h> |
21 | 22 | ||
22 | #include <linux/leds.h> | 23 | #include <linux/leds.h> |
@@ -174,20 +175,31 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) | |||
174 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); | 175 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); |
175 | } | 176 | } |
176 | 177 | ||
177 | static void sdhci_init(struct sdhci_host *host) | 178 | static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); |
179 | |||
180 | static void sdhci_init(struct sdhci_host *host, int soft) | ||
178 | { | 181 | { |
179 | sdhci_reset(host, SDHCI_RESET_ALL); | 182 | if (soft) |
183 | sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); | ||
184 | else | ||
185 | sdhci_reset(host, SDHCI_RESET_ALL); | ||
180 | 186 | ||
181 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, | 187 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, |
182 | SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | | 188 | SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | |
183 | SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | | 189 | SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | |
184 | SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | | 190 | SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | |
185 | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); | 191 | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); |
192 | |||
193 | if (soft) { | ||
194 | /* force clock reconfiguration */ | ||
195 | host->clock = 0; | ||
196 | sdhci_set_ios(host->mmc, &host->mmc->ios); | ||
197 | } | ||
186 | } | 198 | } |
187 | 199 | ||
188 | static void sdhci_reinit(struct sdhci_host *host) | 200 | static void sdhci_reinit(struct sdhci_host *host) |
189 | { | 201 | { |
190 | sdhci_init(host); | 202 | sdhci_init(host, 0); |
191 | sdhci_enable_card_detection(host); | 203 | sdhci_enable_card_detection(host); |
192 | } | 204 | } |
193 | 205 | ||
@@ -376,6 +388,20 @@ static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) | |||
376 | local_irq_restore(*flags); | 388 | local_irq_restore(*flags); |
377 | } | 389 | } |
378 | 390 | ||
391 | static void sdhci_set_adma_desc(u8 *desc, u32 addr, int len, unsigned cmd) | ||
392 | { | ||
393 | __le32 *dataddr = (__le32 __force *)(desc + 4); | ||
394 | __le16 *cmdlen = (__le16 __force *)desc; | ||
395 | |||
396 | /* SDHCI specification says ADMA descriptors should be 4 byte | ||
397 | * aligned, so using 16 or 32bit operations should be safe. */ | ||
398 | |||
399 | cmdlen[0] = cpu_to_le16(cmd); | ||
400 | cmdlen[1] = cpu_to_le16(len); | ||
401 | |||
402 | dataddr[0] = cpu_to_le32(addr); | ||
403 | } | ||
404 | |||
379 | static int sdhci_adma_table_pre(struct sdhci_host *host, | 405 | static int sdhci_adma_table_pre(struct sdhci_host *host, |
380 | struct mmc_data *data) | 406 | struct mmc_data *data) |
381 | { | 407 | { |
@@ -443,19 +469,11 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
443 | sdhci_kunmap_atomic(buffer, &flags); | 469 | sdhci_kunmap_atomic(buffer, &flags); |
444 | } | 470 | } |
445 | 471 | ||
446 | desc[7] = (align_addr >> 24) & 0xff; | 472 | /* tran, valid */ |
447 | desc[6] = (align_addr >> 16) & 0xff; | 473 | sdhci_set_adma_desc(desc, align_addr, offset, 0x21); |
448 | desc[5] = (align_addr >> 8) & 0xff; | ||
449 | desc[4] = (align_addr >> 0) & 0xff; | ||
450 | 474 | ||
451 | BUG_ON(offset > 65536); | 475 | BUG_ON(offset > 65536); |
452 | 476 | ||
453 | desc[3] = (offset >> 8) & 0xff; | ||
454 | desc[2] = (offset >> 0) & 0xff; | ||
455 | |||
456 | desc[1] = 0x00; | ||
457 | desc[0] = 0x21; /* tran, valid */ | ||
458 | |||
459 | align += 4; | 477 | align += 4; |
460 | align_addr += 4; | 478 | align_addr += 4; |
461 | 479 | ||
@@ -465,19 +483,10 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
465 | len -= offset; | 483 | len -= offset; |
466 | } | 484 | } |
467 | 485 | ||
468 | desc[7] = (addr >> 24) & 0xff; | ||
469 | desc[6] = (addr >> 16) & 0xff; | ||
470 | desc[5] = (addr >> 8) & 0xff; | ||
471 | desc[4] = (addr >> 0) & 0xff; | ||
472 | |||
473 | BUG_ON(len > 65536); | 486 | BUG_ON(len > 65536); |
474 | 487 | ||
475 | desc[3] = (len >> 8) & 0xff; | 488 | /* tran, valid */ |
476 | desc[2] = (len >> 0) & 0xff; | 489 | sdhci_set_adma_desc(desc, addr, len, 0x21); |
477 | |||
478 | desc[1] = 0x00; | ||
479 | desc[0] = 0x21; /* tran, valid */ | ||
480 | |||
481 | desc += 8; | 490 | desc += 8; |
482 | 491 | ||
483 | /* | 492 | /* |
@@ -490,16 +499,9 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
490 | /* | 499 | /* |
491 | * Add a terminating entry. | 500 | * Add a terminating entry. |
492 | */ | 501 | */ |
493 | desc[7] = 0; | ||
494 | desc[6] = 0; | ||
495 | desc[5] = 0; | ||
496 | desc[4] = 0; | ||
497 | 502 | ||
498 | desc[3] = 0; | 503 | /* nop, end, valid */ |
499 | desc[2] = 0; | 504 | sdhci_set_adma_desc(desc, 0, 0, 0x3); |
500 | |||
501 | desc[1] = 0x00; | ||
502 | desc[0] = 0x03; /* nop, end, valid */ | ||
503 | 505 | ||
504 | /* | 506 | /* |
505 | * Resync align buffer as we might have changed it. | 507 | * Resync align buffer as we might have changed it. |
@@ -1610,16 +1612,13 @@ int sdhci_resume_host(struct sdhci_host *host) | |||
1610 | if (ret) | 1612 | if (ret) |
1611 | return ret; | 1613 | return ret; |
1612 | 1614 | ||
1613 | sdhci_init(host); | 1615 | sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER)); |
1614 | mmiowb(); | 1616 | mmiowb(); |
1615 | 1617 | ||
1616 | ret = mmc_resume_host(host->mmc); | 1618 | ret = mmc_resume_host(host->mmc); |
1617 | if (ret) | ||
1618 | return ret; | ||
1619 | |||
1620 | sdhci_enable_card_detection(host); | 1619 | sdhci_enable_card_detection(host); |
1621 | 1620 | ||
1622 | return 0; | 1621 | return ret; |
1623 | } | 1622 | } |
1624 | 1623 | ||
1625 | EXPORT_SYMBOL_GPL(sdhci_resume_host); | 1624 | EXPORT_SYMBOL_GPL(sdhci_resume_host); |
@@ -1874,7 +1873,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1874 | if (ret) | 1873 | if (ret) |
1875 | goto untasklet; | 1874 | goto untasklet; |
1876 | 1875 | ||
1877 | sdhci_init(host); | 1876 | sdhci_init(host, 0); |
1878 | 1877 | ||
1879 | #ifdef CONFIG_MMC_DEBUG | 1878 | #ifdef CONFIG_MMC_DEBUG |
1880 | sdhci_dumpregs(host); | 1879 | sdhci_dumpregs(host); |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index ce5f1d73dc04..842f46f94284 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -8,6 +8,8 @@ | |||
8 | * the Free Software Foundation; either version 2 of the License, or (at | 8 | * the Free Software Foundation; either version 2 of the License, or (at |
9 | * your option) any later version. | 9 | * your option) any later version. |
10 | */ | 10 | */ |
11 | #ifndef __SDHCI_H | ||
12 | #define __SDHCI_H | ||
11 | 13 | ||
12 | #include <linux/scatterlist.h> | 14 | #include <linux/scatterlist.h> |
13 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
@@ -408,3 +410,5 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead); | |||
408 | extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); | 410 | extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); |
409 | extern int sdhci_resume_host(struct sdhci_host *host); | 411 | extern int sdhci_resume_host(struct sdhci_host *host); |
410 | #endif | 412 | #endif |
413 | |||
414 | #endif /* __SDHCI_H */ | ||
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 91991b460c45..b2b577f6afd4 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
@@ -46,7 +46,9 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) | |||
46 | clk |= 0x100; | 46 | clk |= 0x100; |
47 | } | 47 | } |
48 | 48 | ||
49 | sd_config_write8(host, CNF_SD_CLK_MODE, clk >> 22); | 49 | if (host->set_clk_div) |
50 | host->set_clk_div(host->pdev, (clk>>22) & 1); | ||
51 | |||
50 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff); | 52 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff); |
51 | } | 53 | } |
52 | 54 | ||
@@ -321,7 +323,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid) | |||
321 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { | 323 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { |
322 | ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | | 324 | ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | |
323 | TMIO_STAT_CARD_REMOVE); | 325 | TMIO_STAT_CARD_REMOVE); |
324 | mmc_detect_change(host->mmc, 0); | 326 | mmc_detect_change(host->mmc, msecs_to_jiffies(100)); |
325 | } | 327 | } |
326 | 328 | ||
327 | /* CRC and other errors */ | 329 | /* CRC and other errors */ |
@@ -427,12 +429,13 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
427 | /* Power sequence - OFF -> ON -> UP */ | 429 | /* Power sequence - OFF -> ON -> UP */ |
428 | switch (ios->power_mode) { | 430 | switch (ios->power_mode) { |
429 | case MMC_POWER_OFF: /* power down SD bus */ | 431 | case MMC_POWER_OFF: /* power down SD bus */ |
430 | sd_config_write8(host, CNF_PWR_CTL_2, 0x00); | 432 | if (host->set_pwr) |
433 | host->set_pwr(host->pdev, 0); | ||
431 | tmio_mmc_clk_stop(host); | 434 | tmio_mmc_clk_stop(host); |
432 | break; | 435 | break; |
433 | case MMC_POWER_ON: /* power up SD bus */ | 436 | case MMC_POWER_ON: /* power up SD bus */ |
434 | 437 | if (host->set_pwr) | |
435 | sd_config_write8(host, CNF_PWR_CTL_2, 0x02); | 438 | host->set_pwr(host->pdev, 1); |
436 | break; | 439 | break; |
437 | case MMC_POWER_UP: /* start bus clock */ | 440 | case MMC_POWER_UP: /* start bus clock */ |
438 | tmio_mmc_clk_start(host); | 441 | tmio_mmc_clk_start(host); |
@@ -485,21 +488,15 @@ static int tmio_mmc_resume(struct platform_device *dev) | |||
485 | { | 488 | { |
486 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | 489 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; |
487 | struct mmc_host *mmc = platform_get_drvdata(dev); | 490 | struct mmc_host *mmc = platform_get_drvdata(dev); |
488 | struct tmio_mmc_host *host = mmc_priv(mmc); | ||
489 | int ret = 0; | 491 | int ret = 0; |
490 | 492 | ||
491 | /* Tell the MFD core we are ready to be enabled */ | 493 | /* Tell the MFD core we are ready to be enabled */ |
492 | if (cell->enable) { | 494 | if (cell->resume) { |
493 | ret = cell->enable(dev); | 495 | ret = cell->resume(dev); |
494 | if (ret) | 496 | if (ret) |
495 | goto out; | 497 | goto out; |
496 | } | 498 | } |
497 | 499 | ||
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 | |||
503 | mmc_resume_host(mmc); | 500 | mmc_resume_host(mmc); |
504 | 501 | ||
505 | out: | 502 | out: |
@@ -514,17 +511,16 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
514 | { | 511 | { |
515 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | 512 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; |
516 | struct tmio_mmc_data *pdata; | 513 | struct tmio_mmc_data *pdata; |
517 | struct resource *res_ctl, *res_cnf; | 514 | struct resource *res_ctl; |
518 | struct tmio_mmc_host *host; | 515 | struct tmio_mmc_host *host; |
519 | struct mmc_host *mmc; | 516 | struct mmc_host *mmc; |
520 | int ret = -EINVAL; | 517 | int ret = -EINVAL; |
521 | 518 | ||
522 | if (dev->num_resources != 3) | 519 | if (dev->num_resources != 2) |
523 | goto out; | 520 | goto out; |
524 | 521 | ||
525 | res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); | 522 | res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); |
526 | res_cnf = platform_get_resource(dev, IORESOURCE_MEM, 1); | 523 | if (!res_ctl) |
527 | if (!res_ctl || !res_cnf) | ||
528 | goto out; | 524 | goto out; |
529 | 525 | ||
530 | pdata = cell->driver_data; | 526 | pdata = cell->driver_data; |
@@ -539,8 +535,12 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
539 | 535 | ||
540 | host = mmc_priv(mmc); | 536 | host = mmc_priv(mmc); |
541 | host->mmc = mmc; | 537 | host->mmc = mmc; |
538 | host->pdev = dev; | ||
542 | platform_set_drvdata(dev, mmc); | 539 | platform_set_drvdata(dev, mmc); |
543 | 540 | ||
541 | host->set_pwr = pdata->set_pwr; | ||
542 | host->set_clk_div = pdata->set_clk_div; | ||
543 | |||
544 | /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ | 544 | /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ |
545 | host->bus_shift = resource_size(res_ctl) >> 10; | 545 | host->bus_shift = resource_size(res_ctl) >> 10; |
546 | 546 | ||
@@ -548,12 +548,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
548 | if (!host->ctl) | 548 | if (!host->ctl) |
549 | goto host_free; | 549 | goto host_free; |
550 | 550 | ||
551 | host->cnf = ioremap(res_cnf->start, resource_size(res_cnf)); | ||
552 | if (!host->cnf) | ||
553 | goto unmap_ctl; | ||
554 | |||
555 | mmc->ops = &tmio_mmc_ops; | 551 | mmc->ops = &tmio_mmc_ops; |
556 | mmc->caps = MMC_CAP_4_BIT_DATA; | 552 | mmc->caps = MMC_CAP_4_BIT_DATA; |
553 | mmc->caps |= pdata->capabilities; | ||
557 | mmc->f_max = pdata->hclk; | 554 | mmc->f_max = pdata->hclk; |
558 | mmc->f_min = mmc->f_max / 512; | 555 | mmc->f_min = mmc->f_max / 512; |
559 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 556 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
@@ -562,23 +559,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
562 | if (cell->enable) { | 559 | if (cell->enable) { |
563 | ret = cell->enable(dev); | 560 | ret = cell->enable(dev); |
564 | if (ret) | 561 | if (ret) |
565 | goto unmap_cnf; | 562 | goto unmap_ctl; |
566 | } | 563 | } |
567 | 564 | ||
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 | |||
573 | /* Disable SD power during suspend */ | ||
574 | sd_config_write8(host, CNF_PWR_CTL_3, 0x01); | ||
575 | |||
576 | /* The below is required but why? FIXME */ | ||
577 | sd_config_write8(host, CNF_STOP_CLK_CTL, 0x1f); | ||
578 | |||
579 | /* Power down SD bus*/ | ||
580 | sd_config_write8(host, CNF_PWR_CTL_2, 0x00); | ||
581 | |||
582 | tmio_mmc_clk_stop(host); | 565 | tmio_mmc_clk_stop(host); |
583 | reset(host); | 566 | reset(host); |
584 | 567 | ||
@@ -586,14 +569,14 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
586 | if (ret >= 0) | 569 | if (ret >= 0) |
587 | host->irq = ret; | 570 | host->irq = ret; |
588 | else | 571 | else |
589 | goto unmap_cnf; | 572 | goto cell_disable; |
590 | 573 | ||
591 | disable_mmc_irqs(host, TMIO_MASK_ALL); | 574 | disable_mmc_irqs(host, TMIO_MASK_ALL); |
592 | 575 | ||
593 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | | 576 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | |
594 | IRQF_TRIGGER_FALLING, "tmio-mmc", host); | 577 | IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host); |
595 | if (ret) | 578 | if (ret) |
596 | goto unmap_cnf; | 579 | goto cell_disable; |
597 | 580 | ||
598 | mmc_add_host(mmc); | 581 | mmc_add_host(mmc); |
599 | 582 | ||
@@ -605,8 +588,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
605 | 588 | ||
606 | return 0; | 589 | return 0; |
607 | 590 | ||
608 | unmap_cnf: | 591 | cell_disable: |
609 | iounmap(host->cnf); | 592 | if (cell->disable) |
593 | cell->disable(dev); | ||
610 | unmap_ctl: | 594 | unmap_ctl: |
611 | iounmap(host->ctl); | 595 | iounmap(host->ctl); |
612 | host_free: | 596 | host_free: |
@@ -617,6 +601,7 @@ out: | |||
617 | 601 | ||
618 | static int __devexit tmio_mmc_remove(struct platform_device *dev) | 602 | static int __devexit tmio_mmc_remove(struct platform_device *dev) |
619 | { | 603 | { |
604 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | ||
620 | struct mmc_host *mmc = platform_get_drvdata(dev); | 605 | struct mmc_host *mmc = platform_get_drvdata(dev); |
621 | 606 | ||
622 | platform_set_drvdata(dev, NULL); | 607 | platform_set_drvdata(dev, NULL); |
@@ -625,8 +610,9 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev) | |||
625 | struct tmio_mmc_host *host = mmc_priv(mmc); | 610 | struct tmio_mmc_host *host = mmc_priv(mmc); |
626 | mmc_remove_host(mmc); | 611 | mmc_remove_host(mmc); |
627 | free_irq(host->irq, host); | 612 | free_irq(host->irq, host); |
613 | if (cell->disable) | ||
614 | cell->disable(dev); | ||
628 | iounmap(host->ctl); | 615 | iounmap(host->ctl); |
629 | iounmap(host->cnf); | ||
630 | mmc_free_host(mmc); | 616 | mmc_free_host(mmc); |
631 | } | 617 | } |
632 | 618 | ||
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 9fa998594974..dafecfbcd91a 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
@@ -11,26 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/highmem.h> | 12 | #include <linux/highmem.h> |
13 | 13 | ||
14 | #define CNF_CMD 0x04 | ||
15 | #define CNF_CTL_BASE 0x10 | ||
16 | #define CNF_INT_PIN 0x3d | ||
17 | #define CNF_STOP_CLK_CTL 0x40 | ||
18 | #define CNF_GCLK_CTL 0x41 | ||
19 | #define CNF_SD_CLK_MODE 0x42 | ||
20 | #define CNF_PIN_STATUS 0x44 | ||
21 | #define CNF_PWR_CTL_1 0x48 | ||
22 | #define CNF_PWR_CTL_2 0x49 | ||
23 | #define CNF_PWR_CTL_3 0x4a | ||
24 | #define CNF_CARD_DETECT_MODE 0x4c | ||
25 | #define CNF_SD_SLOT 0x50 | ||
26 | #define CNF_EXT_GCLK_CTL_1 0xf0 | ||
27 | #define CNF_EXT_GCLK_CTL_2 0xf1 | ||
28 | #define CNF_EXT_GCLK_CTL_3 0xf9 | ||
29 | #define CNF_SD_LED_EN_1 0xfa | ||
30 | #define CNF_SD_LED_EN_2 0xfe | ||
31 | |||
32 | #define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/ | ||
33 | |||
34 | #define CTL_SD_CMD 0x00 | 14 | #define CTL_SD_CMD 0x00 |
35 | #define CTL_ARG_REG 0x04 | 15 | #define CTL_ARG_REG 0x04 |
36 | #define CTL_STOP_INTERNAL_ACTION 0x08 | 16 | #define CTL_STOP_INTERNAL_ACTION 0x08 |
@@ -75,10 +55,8 @@ | |||
75 | /* Define some IRQ masks */ | 55 | /* Define some IRQ masks */ |
76 | /* This is the mask used at reset by the chip */ | 56 | /* This is the mask used at reset by the chip */ |
77 | #define TMIO_MASK_ALL 0x837f031d | 57 | #define TMIO_MASK_ALL 0x837f031d |
78 | #define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \ | 58 | #define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND) |
79 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | 59 | #define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND) |
80 | #define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \ | ||
81 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | ||
82 | #define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \ | 60 | #define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \ |
83 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | 61 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) |
84 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) | 62 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) |
@@ -110,7 +88,6 @@ | |||
110 | 88 | ||
111 | 89 | ||
112 | struct tmio_mmc_host { | 90 | struct tmio_mmc_host { |
113 | void __iomem *cnf; | ||
114 | void __iomem *ctl; | 91 | void __iomem *ctl; |
115 | unsigned long bus_shift; | 92 | unsigned long bus_shift; |
116 | struct mmc_command *cmd; | 93 | struct mmc_command *cmd; |
@@ -119,10 +96,16 @@ struct tmio_mmc_host { | |||
119 | struct mmc_host *mmc; | 96 | struct mmc_host *mmc; |
120 | int irq; | 97 | int irq; |
121 | 98 | ||
99 | /* Callbacks for clock / power control */ | ||
100 | void (*set_pwr)(struct platform_device *host, int state); | ||
101 | void (*set_clk_div)(struct platform_device *host, int state); | ||
102 | |||
122 | /* pio related stuff */ | 103 | /* pio related stuff */ |
123 | struct scatterlist *sg_ptr; | 104 | struct scatterlist *sg_ptr; |
124 | unsigned int sg_len; | 105 | unsigned int sg_len; |
125 | unsigned int sg_off; | 106 | unsigned int sg_off; |
107 | |||
108 | struct platform_device *pdev; | ||
126 | }; | 109 | }; |
127 | 110 | ||
128 | #include <linux/io.h> | 111 | #include <linux/io.h> |
@@ -163,25 +146,6 @@ static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, | |||
163 | writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift)); | 146 | writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift)); |
164 | } | 147 | } |
165 | 148 | ||
166 | static 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 | |||
172 | static 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 | |||
178 | static 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 | |||
185 | #include <linux/scatterlist.h> | 149 | #include <linux/scatterlist.h> |
186 | #include <linux/blkdev.h> | 150 | #include <linux/blkdev.h> |
187 | 151 | ||
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 89bf8cd25cac..69efe01eece8 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
35 | #include <linux/mmc/host.h> | 35 | #include <linux/mmc/host.h> |
36 | #include <linux/scatterlist.h> | 36 | #include <linux/scatterlist.h> |
37 | #include <linux/slab.h> | ||
37 | 38 | ||
38 | #include <asm/io.h> | 39 | #include <asm/io.h> |
39 | #include <asm/dma.h> | 40 | #include <asm/dma.h> |