diff options
| -rw-r--r-- | drivers/mmc/at91_mci.c | 346 | ||||
| -rw-r--r-- | drivers/mmc/mmc_queue.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/sdhci.c | 4 |
3 files changed, 190 insertions, 164 deletions
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c index 4633dbc9a90f..08a33c33f6ed 100644 --- a/drivers/mmc/at91_mci.c +++ b/drivers/mmc/at91_mci.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/mmc/at91_mci.c - ATMEL AT91RM9200 MCI Driver | 2 | * linux/drivers/mmc/at91_mci.c - ATMEL AT91 MCI Driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved | 4 | * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved |
| 5 | * | 5 | * |
| @@ -11,7 +11,7 @@ | |||
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | /* | 13 | /* |
| 14 | This is the AT91RM9200 MCI driver that has been tested with both MMC cards | 14 | This is the AT91 MCI driver that has been tested with both MMC cards |
| 15 | and SD-cards. Boards that support write protect are now supported. | 15 | and SD-cards. Boards that support write protect are now supported. |
| 16 | The CCAT91SBC001 board does not support SD cards. | 16 | The CCAT91SBC001 board does not support SD cards. |
| 17 | 17 | ||
| @@ -38,8 +38,8 @@ | |||
| 38 | controller to manage the transfers. | 38 | controller to manage the transfers. |
| 39 | 39 | ||
| 40 | A read is done from the controller directly to the scatterlist passed in from the request. | 40 | A read is done from the controller directly to the scatterlist passed in from the request. |
| 41 | Due to a bug in the controller, when a read is completed, all the words are byte | 41 | Due to a bug in the AT91RM9200 controller, when a read is completed, all the words are byte |
| 42 | swapped in the scatterlist buffers. | 42 | swapped in the scatterlist buffers. AT91SAM926x are not affected by this bug. |
| 43 | 43 | ||
| 44 | The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY | 44 | The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY |
| 45 | 45 | ||
| @@ -72,6 +72,7 @@ | |||
| 72 | #include <asm/irq.h> | 72 | #include <asm/irq.h> |
| 73 | #include <asm/mach/mmc.h> | 73 | #include <asm/mach/mmc.h> |
| 74 | #include <asm/arch/board.h> | 74 | #include <asm/arch/board.h> |
| 75 | #include <asm/arch/cpu.h> | ||
| 75 | #include <asm/arch/gpio.h> | 76 | #include <asm/arch/gpio.h> |
| 76 | #include <asm/arch/at91_mci.h> | 77 | #include <asm/arch/at91_mci.h> |
| 77 | #include <asm/arch/at91_pdc.h> | 78 | #include <asm/arch/at91_pdc.h> |
| @@ -80,34 +81,18 @@ | |||
| 80 | 81 | ||
| 81 | #undef SUPPORT_4WIRE | 82 | #undef SUPPORT_4WIRE |
| 82 | 83 | ||
| 83 | static struct clk *mci_clk; | 84 | #define FL_SENT_COMMAND (1 << 0) |
| 85 | #define FL_SENT_STOP (1 << 1) | ||
| 84 | 86 | ||
| 85 | #define FL_SENT_COMMAND (1 << 0) | 87 | #define AT91_MCI_ERRORS (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE \ |
| 86 | #define FL_SENT_STOP (1 << 1) | 88 | | AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE \ |
| 89 | | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE) | ||
| 87 | 90 | ||
| 91 | #define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) | ||
| 92 | #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) | ||
| 88 | 93 | ||
| 89 | 94 | ||
| 90 | /* | 95 | /* |
| 91 | * Read from a MCI register. | ||
| 92 | */ | ||
| 93 | static inline unsigned long at91_mci_read(unsigned int reg) | ||
| 94 | { | ||
| 95 | void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI; | ||
| 96 | |||
| 97 | return __raw_readl(mci_base + reg); | ||
| 98 | } | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Write to a MCI register. | ||
| 102 | */ | ||
| 103 | static inline void at91_mci_write(unsigned int reg, unsigned long value) | ||
| 104 | { | ||
| 105 | void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI; | ||
| 106 | |||
| 107 | __raw_writel(value, mci_base + reg); | ||
| 108 | } | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Low level type for this driver | 96 | * Low level type for this driver |
| 112 | */ | 97 | */ |
| 113 | struct at91mci_host | 98 | struct at91mci_host |
| @@ -116,9 +101,14 @@ struct at91mci_host | |||
| 116 | struct mmc_command *cmd; | 101 | struct mmc_command *cmd; |
| 117 | struct mmc_request *request; | 102 | struct mmc_request *request; |
| 118 | 103 | ||
| 104 | void __iomem *baseaddr; | ||
| 105 | int irq; | ||
| 106 | |||
| 119 | struct at91_mmc_data *board; | 107 | struct at91_mmc_data *board; |
| 120 | int present; | 108 | int present; |
| 121 | 109 | ||
| 110 | struct clk *mci_clk; | ||
| 111 | |||
| 122 | /* | 112 | /* |
| 123 | * Flag indicating when the command has been sent. This is used to | 113 | * Flag indicating when the command has been sent. This is used to |
| 124 | * work out whether or not to send the stop | 114 | * work out whether or not to send the stop |
| @@ -158,7 +148,6 @@ static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
| 158 | for (i = 0; i < len; i++) { | 148 | for (i = 0; i < len; i++) { |
| 159 | struct scatterlist *sg; | 149 | struct scatterlist *sg; |
| 160 | int amount; | 150 | int amount; |
| 161 | int index; | ||
| 162 | unsigned int *sgbuffer; | 151 | unsigned int *sgbuffer; |
| 163 | 152 | ||
| 164 | sg = &data->sg[i]; | 153 | sg = &data->sg[i]; |
| @@ -166,10 +155,15 @@ static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
| 166 | sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; | 155 | sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; |
| 167 | amount = min(size, sg->length); | 156 | amount = min(size, sg->length); |
| 168 | size -= amount; | 157 | size -= amount; |
| 169 | amount /= 4; | ||
| 170 | 158 | ||
| 171 | for (index = 0; index < amount; index++) | 159 | if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ |
| 172 | *dmabuf++ = swab32(sgbuffer[index]); | 160 | int index; |
| 161 | |||
| 162 | for (index = 0; index < (amount / 4); index++) | ||
| 163 | *dmabuf++ = swab32(sgbuffer[index]); | ||
| 164 | } | ||
| 165 | else | ||
| 166 | memcpy(dmabuf, sgbuffer, amount); | ||
| 173 | 167 | ||
| 174 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | 168 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); |
| 175 | 169 | ||
| @@ -217,13 +211,13 @@ static void at91mci_pre_dma_read(struct at91mci_host *host) | |||
| 217 | 211 | ||
| 218 | /* Check to see if this needs filling */ | 212 | /* Check to see if this needs filling */ |
| 219 | if (i == 0) { | 213 | if (i == 0) { |
| 220 | if (at91_mci_read(AT91_PDC_RCR) != 0) { | 214 | if (at91_mci_read(host, AT91_PDC_RCR) != 0) { |
| 221 | pr_debug("Transfer active in current\n"); | 215 | pr_debug("Transfer active in current\n"); |
| 222 | continue; | 216 | continue; |
| 223 | } | 217 | } |
| 224 | } | 218 | } |
| 225 | else { | 219 | else { |
| 226 | if (at91_mci_read(AT91_PDC_RNCR) != 0) { | 220 | if (at91_mci_read(host, AT91_PDC_RNCR) != 0) { |
| 227 | pr_debug("Transfer active in next\n"); | 221 | pr_debug("Transfer active in next\n"); |
| 228 | continue; | 222 | continue; |
| 229 | } | 223 | } |
| @@ -240,12 +234,12 @@ static void at91mci_pre_dma_read(struct at91mci_host *host) | |||
| 240 | pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length); | 234 | pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length); |
| 241 | 235 | ||
| 242 | if (i == 0) { | 236 | if (i == 0) { |
| 243 | at91_mci_write(AT91_PDC_RPR, sg->dma_address); | 237 | at91_mci_write(host, AT91_PDC_RPR, sg->dma_address); |
| 244 | at91_mci_write(AT91_PDC_RCR, sg->length / 4); | 238 | at91_mci_write(host, AT91_PDC_RCR, sg->length / 4); |
| 245 | } | 239 | } |
| 246 | else { | 240 | else { |
| 247 | at91_mci_write(AT91_PDC_RNPR, sg->dma_address); | 241 | at91_mci_write(host, AT91_PDC_RNPR, sg->dma_address); |
| 248 | at91_mci_write(AT91_PDC_RNCR, sg->length / 4); | 242 | at91_mci_write(host, AT91_PDC_RNCR, sg->length / 4); |
| 249 | } | 243 | } |
| 250 | } | 244 | } |
| 251 | 245 | ||
| @@ -276,8 +270,6 @@ static void at91mci_post_dma_read(struct at91mci_host *host) | |||
| 276 | 270 | ||
| 277 | while (host->in_use_index < host->transfer_index) { | 271 | while (host->in_use_index < host->transfer_index) { |
| 278 | unsigned int *buffer; | 272 | unsigned int *buffer; |
| 279 | int index; | ||
| 280 | int len; | ||
| 281 | 273 | ||
| 282 | struct scatterlist *sg; | 274 | struct scatterlist *sg; |
| 283 | 275 | ||
| @@ -295,11 +287,13 @@ static void at91mci_post_dma_read(struct at91mci_host *host) | |||
| 295 | 287 | ||
| 296 | data->bytes_xfered += sg->length; | 288 | data->bytes_xfered += sg->length; |
| 297 | 289 | ||
| 298 | len = sg->length / 4; | 290 | if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ |
| 291 | int index; | ||
| 299 | 292 | ||
| 300 | for (index = 0; index < len; index++) { | 293 | for (index = 0; index < (sg->length / 4); index++) |
| 301 | buffer[index] = swab32(buffer[index]); | 294 | buffer[index] = swab32(buffer[index]); |
| 302 | } | 295 | } |
| 296 | |||
| 303 | kunmap_atomic(buffer, KM_BIO_SRC_IRQ); | 297 | kunmap_atomic(buffer, KM_BIO_SRC_IRQ); |
| 304 | flush_dcache_page(sg->page); | 298 | flush_dcache_page(sg->page); |
| 305 | } | 299 | } |
| @@ -308,8 +302,8 @@ static void at91mci_post_dma_read(struct at91mci_host *host) | |||
| 308 | if (host->transfer_index < data->sg_len) | 302 | if (host->transfer_index < data->sg_len) |
| 309 | at91mci_pre_dma_read(host); | 303 | at91mci_pre_dma_read(host); |
| 310 | else { | 304 | else { |
| 311 | at91_mci_write(AT91_MCI_IER, AT91_MCI_RXBUFF); | 305 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); |
| 312 | at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); | 306 | at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); |
| 313 | } | 307 | } |
| 314 | 308 | ||
| 315 | pr_debug("post dma read done\n"); | 309 | pr_debug("post dma read done\n"); |
| @@ -326,11 +320,11 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host) | |||
| 326 | pr_debug("Handling the transmit\n"); | 320 | pr_debug("Handling the transmit\n"); |
| 327 | 321 | ||
| 328 | /* Disable the transfer */ | 322 | /* Disable the transfer */ |
| 329 | at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); | 323 | at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); |
| 330 | 324 | ||
| 331 | /* Now wait for cmd ready */ | 325 | /* Now wait for cmd ready */ |
| 332 | at91_mci_write(AT91_MCI_IDR, AT91_MCI_TXBUFE); | 326 | at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE); |
| 333 | at91_mci_write(AT91_MCI_IER, AT91_MCI_NOTBUSY); | 327 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); |
| 334 | 328 | ||
| 335 | cmd = host->cmd; | 329 | cmd = host->cmd; |
| 336 | if (!cmd) return; | 330 | if (!cmd) return; |
| @@ -344,21 +338,23 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host) | |||
| 344 | /* | 338 | /* |
| 345 | * Enable the controller | 339 | * Enable the controller |
| 346 | */ | 340 | */ |
| 347 | static void at91_mci_enable(void) | 341 | static void at91_mci_enable(struct at91mci_host *host) |
| 348 | { | 342 | { |
| 349 | at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN); | 343 | at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN); |
| 350 | at91_mci_write(AT91_MCI_IDR, 0xFFFFFFFF); | 344 | at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); |
| 351 | at91_mci_write(AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); | 345 | at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); |
| 352 | at91_mci_write(AT91_MCI_MR, 0x834A); | 346 | at91_mci_write(host, AT91_MCI_MR, AT91_MCI_PDCMODE | 0x34a); |
| 353 | at91_mci_write(AT91_MCI_SDCR, 0x0); | 347 | |
| 348 | /* use Slot A or B (only one at same time) */ | ||
| 349 | at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b); | ||
| 354 | } | 350 | } |
| 355 | 351 | ||
| 356 | /* | 352 | /* |
| 357 | * Disable the controller | 353 | * Disable the controller |
| 358 | */ | 354 | */ |
| 359 | static void at91_mci_disable(void) | 355 | static void at91_mci_disable(struct at91mci_host *host) |
| 360 | { | 356 | { |
| 361 | at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST); | 357 | at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST); |
| 362 | } | 358 | } |
| 363 | 359 | ||
| 364 | /* | 360 | /* |
| @@ -378,13 +374,13 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ | |||
| 378 | 374 | ||
| 379 | /* Not sure if this is needed */ | 375 | /* Not sure if this is needed */ |
| 380 | #if 0 | 376 | #if 0 |
| 381 | if ((at91_mci_read(AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) { | 377 | if ((at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) { |
| 382 | pr_debug("Clearing timeout\n"); | 378 | pr_debug("Clearing timeout\n"); |
| 383 | at91_mci_write(AT91_MCI_ARGR, 0); | 379 | at91_mci_write(host, AT91_MCI_ARGR, 0); |
| 384 | at91_mci_write(AT91_MCI_CMDR, AT91_MCI_OPDCMD); | 380 | at91_mci_write(host, AT91_MCI_CMDR, AT91_MCI_OPDCMD); |
| 385 | while (!(at91_mci_read(AT91_MCI_SR) & AT91_MCI_CMDRDY)) { | 381 | while (!(at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_CMDRDY)) { |
| 386 | /* spin */ | 382 | /* spin */ |
| 387 | pr_debug("Clearing: SR = %08X\n", at91_mci_read(AT91_MCI_SR)); | 383 | pr_debug("Clearing: SR = %08X\n", at91_mci_read(host, AT91_MCI_SR)); |
| 388 | } | 384 | } |
| 389 | } | 385 | } |
| 390 | #endif | 386 | #endif |
| @@ -431,32 +427,32 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ | |||
| 431 | /* | 427 | /* |
| 432 | * Set the arguments and send the command | 428 | * Set the arguments and send the command |
| 433 | */ | 429 | */ |
| 434 | pr_debug("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08lX)\n", | 430 | pr_debug("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08X)\n", |
| 435 | cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(AT91_MCI_MR)); | 431 | cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(host, AT91_MCI_MR)); |
| 436 | 432 | ||
| 437 | if (!data) { | 433 | if (!data) { |
| 438 | at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTDIS | AT91_PDC_RXTDIS); | 434 | at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_TXTDIS | AT91_PDC_RXTDIS); |
| 439 | at91_mci_write(AT91_PDC_RPR, 0); | 435 | at91_mci_write(host, AT91_PDC_RPR, 0); |
| 440 | at91_mci_write(AT91_PDC_RCR, 0); | 436 | at91_mci_write(host, AT91_PDC_RCR, 0); |
| 441 | at91_mci_write(AT91_PDC_RNPR, 0); | 437 | at91_mci_write(host, AT91_PDC_RNPR, 0); |
| 442 | at91_mci_write(AT91_PDC_RNCR, 0); | 438 | at91_mci_write(host, AT91_PDC_RNCR, 0); |
| 443 | at91_mci_write(AT91_PDC_TPR, 0); | 439 | at91_mci_write(host, AT91_PDC_TPR, 0); |
| 444 | at91_mci_write(AT91_PDC_TCR, 0); | 440 | at91_mci_write(host, AT91_PDC_TCR, 0); |
| 445 | at91_mci_write(AT91_PDC_TNPR, 0); | 441 | at91_mci_write(host, AT91_PDC_TNPR, 0); |
| 446 | at91_mci_write(AT91_PDC_TNCR, 0); | 442 | at91_mci_write(host, AT91_PDC_TNCR, 0); |
| 447 | 443 | ||
| 448 | at91_mci_write(AT91_MCI_ARGR, cmd->arg); | 444 | at91_mci_write(host, AT91_MCI_ARGR, cmd->arg); |
| 449 | at91_mci_write(AT91_MCI_CMDR, cmdr); | 445 | at91_mci_write(host, AT91_MCI_CMDR, cmdr); |
| 450 | return AT91_MCI_CMDRDY; | 446 | return AT91_MCI_CMDRDY; |
| 451 | } | 447 | } |
| 452 | 448 | ||
| 453 | mr = at91_mci_read(AT91_MCI_MR) & 0x7fff; /* zero block length and PDC mode */ | 449 | mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; /* zero block length and PDC mode */ |
| 454 | at91_mci_write(AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE); | 450 | at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE); |
| 455 | 451 | ||
| 456 | /* | 452 | /* |
| 457 | * Disable the PDC controller | 453 | * Disable the PDC controller |
| 458 | */ | 454 | */ |
| 459 | at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); | 455 | at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); |
| 460 | 456 | ||
| 461 | if (cmdr & AT91_MCI_TRCMD_START) { | 457 | if (cmdr & AT91_MCI_TRCMD_START) { |
| 462 | data->bytes_xfered = 0; | 458 | data->bytes_xfered = 0; |
| @@ -485,8 +481,8 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ | |||
| 485 | 481 | ||
| 486 | pr_debug("Transmitting %d bytes\n", host->total_length); | 482 | pr_debug("Transmitting %d bytes\n", host->total_length); |
| 487 | 483 | ||
| 488 | at91_mci_write(AT91_PDC_TPR, host->physical_address); | 484 | at91_mci_write(host, AT91_PDC_TPR, host->physical_address); |
| 489 | at91_mci_write(AT91_PDC_TCR, host->total_length / 4); | 485 | at91_mci_write(host, AT91_PDC_TCR, host->total_length / 4); |
| 490 | ier = AT91_MCI_TXBUFE; | 486 | ier = AT91_MCI_TXBUFE; |
| 491 | } | 487 | } |
| 492 | } | 488 | } |
| @@ -496,14 +492,14 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ | |||
| 496 | * the data sheet says | 492 | * the data sheet says |
| 497 | */ | 493 | */ |
| 498 | 494 | ||
| 499 | at91_mci_write(AT91_MCI_ARGR, cmd->arg); | 495 | at91_mci_write(host, AT91_MCI_ARGR, cmd->arg); |
| 500 | at91_mci_write(AT91_MCI_CMDR, cmdr); | 496 | at91_mci_write(host, AT91_MCI_CMDR, cmdr); |
| 501 | 497 | ||
| 502 | if (cmdr & AT91_MCI_TRCMD_START) { | 498 | if (cmdr & AT91_MCI_TRCMD_START) { |
| 503 | if (cmdr & AT91_MCI_TRDIR) | 499 | if (cmdr & AT91_MCI_TRDIR) |
| 504 | at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTEN); | 500 | at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTEN); |
| 505 | else | 501 | else |
| 506 | at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTEN); | 502 | at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_TXTEN); |
| 507 | } | 503 | } |
| 508 | return ier; | 504 | return ier; |
| 509 | } | 505 | } |
| @@ -520,7 +516,7 @@ static void at91mci_process_command(struct at91mci_host *host, struct mmc_comman | |||
| 520 | pr_debug("setting ier to %08X\n", ier); | 516 | pr_debug("setting ier to %08X\n", ier); |
| 521 | 517 | ||
| 522 | /* Stop on errors or the required value */ | 518 | /* Stop on errors or the required value */ |
| 523 | at91_mci_write(AT91_MCI_IER, 0xffff0000 | ier); | 519 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_ERRORS | ier); |
| 524 | } | 520 | } |
| 525 | 521 | ||
| 526 | /* | 522 | /* |
| @@ -548,19 +544,19 @@ static void at91mci_completed_command(struct at91mci_host *host) | |||
| 548 | struct mmc_command *cmd = host->cmd; | 544 | struct mmc_command *cmd = host->cmd; |
| 549 | unsigned int status; | 545 | unsigned int status; |
| 550 | 546 | ||
| 551 | at91_mci_write(AT91_MCI_IDR, 0xffffffff); | 547 | at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); |
| 552 | 548 | ||
| 553 | cmd->resp[0] = at91_mci_read(AT91_MCI_RSPR(0)); | 549 | cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0)); |
| 554 | cmd->resp[1] = at91_mci_read(AT91_MCI_RSPR(1)); | 550 | cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1)); |
| 555 | cmd->resp[2] = at91_mci_read(AT91_MCI_RSPR(2)); | 551 | cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2)); |
| 556 | cmd->resp[3] = at91_mci_read(AT91_MCI_RSPR(3)); | 552 | cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3)); |
| 557 | 553 | ||
| 558 | if (host->buffer) { | 554 | if (host->buffer) { |
| 559 | dma_free_coherent(NULL, host->total_length, host->buffer, host->physical_address); | 555 | dma_free_coherent(NULL, host->total_length, host->buffer, host->physical_address); |
| 560 | host->buffer = NULL; | 556 | host->buffer = NULL; |
| 561 | } | 557 | } |
| 562 | 558 | ||
| 563 | status = at91_mci_read(AT91_MCI_SR); | 559 | status = at91_mci_read(host, AT91_MCI_SR); |
| 564 | 560 | ||
| 565 | pr_debug("Status = %08X [%08X %08X %08X %08X]\n", | 561 | pr_debug("Status = %08X [%08X %08X %08X %08X]\n", |
| 566 | status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | 562 | status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); |
| @@ -611,18 +607,18 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 611 | { | 607 | { |
| 612 | int clkdiv; | 608 | int clkdiv; |
| 613 | struct at91mci_host *host = mmc_priv(mmc); | 609 | struct at91mci_host *host = mmc_priv(mmc); |
| 614 | unsigned long at91_master_clock = clk_get_rate(mci_clk); | 610 | unsigned long at91_master_clock = clk_get_rate(host->mci_clk); |
| 615 | 611 | ||
| 616 | host->bus_mode = ios->bus_mode; | 612 | host->bus_mode = ios->bus_mode; |
| 617 | 613 | ||
| 618 | if (ios->clock == 0) { | 614 | if (ios->clock == 0) { |
| 619 | /* Disable the MCI controller */ | 615 | /* Disable the MCI controller */ |
| 620 | at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS); | 616 | at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS); |
| 621 | clkdiv = 0; | 617 | clkdiv = 0; |
| 622 | } | 618 | } |
| 623 | else { | 619 | else { |
| 624 | /* Enable the MCI controller */ | 620 | /* Enable the MCI controller */ |
| 625 | at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN); | 621 | at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN); |
| 626 | 622 | ||
| 627 | if ((at91_master_clock % (ios->clock * 2)) == 0) | 623 | if ((at91_master_clock % (ios->clock * 2)) == 0) |
| 628 | clkdiv = ((at91_master_clock / ios->clock) / 2) - 1; | 624 | clkdiv = ((at91_master_clock / ios->clock) / 2) - 1; |
| @@ -634,25 +630,25 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 634 | } | 630 | } |
| 635 | if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) { | 631 | if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) { |
| 636 | pr_debug("MMC: Setting controller bus width to 4\n"); | 632 | pr_debug("MMC: Setting controller bus width to 4\n"); |
| 637 | at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) | AT91_MCI_SDCBUS); | 633 | at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) | AT91_MCI_SDCBUS); |
| 638 | } | 634 | } |
| 639 | else { | 635 | else { |
| 640 | pr_debug("MMC: Setting controller bus width to 1\n"); | 636 | pr_debug("MMC: Setting controller bus width to 1\n"); |
| 641 | at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); | 637 | at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); |
| 642 | } | 638 | } |
| 643 | 639 | ||
| 644 | /* Set the clock divider */ | 640 | /* Set the clock divider */ |
| 645 | at91_mci_write(AT91_MCI_MR, (at91_mci_read(AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv); | 641 | at91_mci_write(host, AT91_MCI_MR, (at91_mci_read(host, AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv); |
| 646 | 642 | ||
| 647 | /* maybe switch power to the card */ | 643 | /* maybe switch power to the card */ |
| 648 | if (host->board->vcc_pin) { | 644 | if (host->board->vcc_pin) { |
| 649 | switch (ios->power_mode) { | 645 | switch (ios->power_mode) { |
| 650 | case MMC_POWER_OFF: | 646 | case MMC_POWER_OFF: |
| 651 | at91_set_gpio_output(host->board->vcc_pin, 0); | 647 | at91_set_gpio_value(host->board->vcc_pin, 0); |
| 652 | break; | 648 | break; |
| 653 | case MMC_POWER_UP: | 649 | case MMC_POWER_UP: |
| 654 | case MMC_POWER_ON: | 650 | case MMC_POWER_ON: |
| 655 | at91_set_gpio_output(host->board->vcc_pin, 1); | 651 | at91_set_gpio_value(host->board->vcc_pin, 1); |
| 656 | break; | 652 | break; |
| 657 | } | 653 | } |
| 658 | } | 654 | } |
| @@ -665,39 +661,40 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) | |||
| 665 | { | 661 | { |
| 666 | struct at91mci_host *host = devid; | 662 | struct at91mci_host *host = devid; |
| 667 | int completed = 0; | 663 | int completed = 0; |
| 664 | unsigned int int_status, int_mask; | ||
| 668 | 665 | ||
| 669 | unsigned int int_status; | 666 | int_status = at91_mci_read(host, AT91_MCI_SR); |
| 667 | int_mask = at91_mci_read(host, AT91_MCI_IMR); | ||
| 668 | |||
| 669 | pr_debug("MCI irq: status = %08X, %08X, %08X\n", int_status, int_mask, | ||
| 670 | int_status & int_mask); | ||
| 671 | |||
| 672 | int_status = int_status & int_mask; | ||
| 670 | 673 | ||
| 671 | int_status = at91_mci_read(AT91_MCI_SR); | 674 | if (int_status & AT91_MCI_ERRORS) { |
| 672 | pr_debug("MCI irq: status = %08X, %08lX, %08lX\n", int_status, at91_mci_read(AT91_MCI_IMR), | ||
| 673 | int_status & at91_mci_read(AT91_MCI_IMR)); | ||
| 674 | |||
| 675 | if ((int_status & at91_mci_read(AT91_MCI_IMR)) & 0xffff0000) | ||
| 676 | completed = 1; | 675 | completed = 1; |
| 676 | |||
| 677 | if (int_status & AT91_MCI_UNRE) | ||
| 678 | pr_debug("MMC: Underrun error\n"); | ||
| 679 | if (int_status & AT91_MCI_OVRE) | ||
| 680 | pr_debug("MMC: Overrun error\n"); | ||
| 681 | if (int_status & AT91_MCI_DTOE) | ||
| 682 | pr_debug("MMC: Data timeout\n"); | ||
| 683 | if (int_status & AT91_MCI_DCRCE) | ||
| 684 | pr_debug("MMC: CRC error in data\n"); | ||
| 685 | if (int_status & AT91_MCI_RTOE) | ||
| 686 | pr_debug("MMC: Response timeout\n"); | ||
| 687 | if (int_status & AT91_MCI_RENDE) | ||
| 688 | pr_debug("MMC: Response end bit error\n"); | ||
| 689 | if (int_status & AT91_MCI_RCRCE) | ||
| 690 | pr_debug("MMC: Response CRC error\n"); | ||
| 691 | if (int_status & AT91_MCI_RDIRE) | ||
| 692 | pr_debug("MMC: Response direction error\n"); | ||
| 693 | if (int_status & AT91_MCI_RINDE) | ||
| 694 | pr_debug("MMC: Response index error\n"); | ||
| 695 | } else { | ||
| 696 | /* Only continue processing if no errors */ | ||
| 677 | 697 | ||
| 678 | int_status &= at91_mci_read(AT91_MCI_IMR); | ||
| 679 | |||
| 680 | if (int_status & AT91_MCI_UNRE) | ||
| 681 | pr_debug("MMC: Underrun error\n"); | ||
| 682 | if (int_status & AT91_MCI_OVRE) | ||
| 683 | pr_debug("MMC: Overrun error\n"); | ||
| 684 | if (int_status & AT91_MCI_DTOE) | ||
| 685 | pr_debug("MMC: Data timeout\n"); | ||
| 686 | if (int_status & AT91_MCI_DCRCE) | ||
| 687 | pr_debug("MMC: CRC error in data\n"); | ||
| 688 | if (int_status & AT91_MCI_RTOE) | ||
| 689 | pr_debug("MMC: Response timeout\n"); | ||
| 690 | if (int_status & AT91_MCI_RENDE) | ||
| 691 | pr_debug("MMC: Response end bit error\n"); | ||
| 692 | if (int_status & AT91_MCI_RCRCE) | ||
| 693 | pr_debug("MMC: Response CRC error\n"); | ||
| 694 | if (int_status & AT91_MCI_RDIRE) | ||
| 695 | pr_debug("MMC: Response direction error\n"); | ||
| 696 | if (int_status & AT91_MCI_RINDE) | ||
| 697 | pr_debug("MMC: Response index error\n"); | ||
| 698 | |||
| 699 | /* Only continue processing if no errors */ | ||
| 700 | if (!completed) { | ||
| 701 | if (int_status & AT91_MCI_TXBUFE) { | 698 | if (int_status & AT91_MCI_TXBUFE) { |
| 702 | pr_debug("TX buffer empty\n"); | 699 | pr_debug("TX buffer empty\n"); |
| 703 | at91_mci_handle_transmitted(host); | 700 | at91_mci_handle_transmitted(host); |
| @@ -705,12 +702,11 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) | |||
| 705 | 702 | ||
| 706 | if (int_status & AT91_MCI_RXBUFF) { | 703 | if (int_status & AT91_MCI_RXBUFF) { |
| 707 | pr_debug("RX buffer full\n"); | 704 | pr_debug("RX buffer full\n"); |
| 708 | at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY); | 705 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY); |
| 709 | } | 706 | } |
| 710 | 707 | ||
| 711 | if (int_status & AT91_MCI_ENDTX) { | 708 | if (int_status & AT91_MCI_ENDTX) |
| 712 | pr_debug("Transmit has ended\n"); | 709 | pr_debug("Transmit has ended\n"); |
| 713 | } | ||
| 714 | 710 | ||
| 715 | if (int_status & AT91_MCI_ENDRX) { | 711 | if (int_status & AT91_MCI_ENDRX) { |
| 716 | pr_debug("Receive has ended\n"); | 712 | pr_debug("Receive has ended\n"); |
| @@ -719,37 +715,33 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) | |||
| 719 | 715 | ||
| 720 | if (int_status & AT91_MCI_NOTBUSY) { | 716 | if (int_status & AT91_MCI_NOTBUSY) { |
| 721 | pr_debug("Card is ready\n"); | 717 | pr_debug("Card is ready\n"); |
| 722 | at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY); | 718 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY); |
| 723 | } | 719 | } |
| 724 | 720 | ||
| 725 | if (int_status & AT91_MCI_DTIP) { | 721 | if (int_status & AT91_MCI_DTIP) |
| 726 | pr_debug("Data transfer in progress\n"); | 722 | pr_debug("Data transfer in progress\n"); |
| 727 | } | ||
| 728 | 723 | ||
| 729 | if (int_status & AT91_MCI_BLKE) { | 724 | if (int_status & AT91_MCI_BLKE) |
| 730 | pr_debug("Block transfer has ended\n"); | 725 | pr_debug("Block transfer has ended\n"); |
| 731 | } | ||
| 732 | 726 | ||
| 733 | if (int_status & AT91_MCI_TXRDY) { | 727 | if (int_status & AT91_MCI_TXRDY) |
| 734 | pr_debug("Ready to transmit\n"); | 728 | pr_debug("Ready to transmit\n"); |
| 735 | } | ||
| 736 | 729 | ||
| 737 | if (int_status & AT91_MCI_RXRDY) { | 730 | if (int_status & AT91_MCI_RXRDY) |
| 738 | pr_debug("Ready to receive\n"); | 731 | pr_debug("Ready to receive\n"); |
| 739 | } | ||
| 740 | 732 | ||
| 741 | if (int_status & AT91_MCI_CMDRDY) { | 733 | if (int_status & AT91_MCI_CMDRDY) { |
| 742 | pr_debug("Command ready\n"); | 734 | pr_debug("Command ready\n"); |
| 743 | completed = 1; | 735 | completed = 1; |
| 744 | } | 736 | } |
| 745 | } | 737 | } |
| 746 | at91_mci_write(AT91_MCI_IDR, int_status); | ||
| 747 | 738 | ||
| 748 | if (completed) { | 739 | if (completed) { |
| 749 | pr_debug("Completed command\n"); | 740 | pr_debug("Completed command\n"); |
| 750 | at91_mci_write(AT91_MCI_IDR, 0xffffffff); | 741 | at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); |
| 751 | at91mci_completed_command(host); | 742 | at91mci_completed_command(host); |
| 752 | } | 743 | } else |
| 744 | at91_mci_write(host, AT91_MCI_IDR, int_status); | ||
| 753 | 745 | ||
| 754 | return IRQ_HANDLED; | 746 | return IRQ_HANDLED; |
| 755 | } | 747 | } |
| @@ -769,7 +761,7 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host) | |||
| 769 | present ? "insert" : "remove"); | 761 | present ? "insert" : "remove"); |
| 770 | if (!present) { | 762 | if (!present) { |
| 771 | pr_debug("****** Resetting SD-card bus width ******\n"); | 763 | pr_debug("****** Resetting SD-card bus width ******\n"); |
| 772 | at91_mci_write(AT91_MCI_SDCR, 0); | 764 | at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); |
| 773 | } | 765 | } |
| 774 | mmc_detect_change(host->mmc, msecs_to_jiffies(100)); | 766 | mmc_detect_change(host->mmc, msecs_to_jiffies(100)); |
| 775 | } | 767 | } |
| @@ -806,15 +798,22 @@ static int at91_mci_probe(struct platform_device *pdev) | |||
| 806 | { | 798 | { |
| 807 | struct mmc_host *mmc; | 799 | struct mmc_host *mmc; |
| 808 | struct at91mci_host *host; | 800 | struct at91mci_host *host; |
| 801 | struct resource *res; | ||
| 809 | int ret; | 802 | int ret; |
| 810 | 803 | ||
| 811 | pr_debug("Probe MCI devices\n"); | 804 | pr_debug("Probe MCI devices\n"); |
| 812 | at91_mci_disable(); | 805 | |
| 813 | at91_mci_enable(); | 806 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 807 | if (!res) | ||
| 808 | return -ENXIO; | ||
| 809 | |||
| 810 | if (!request_mem_region(res->start, res->end - res->start + 1, DRIVER_NAME)) | ||
| 811 | return -EBUSY; | ||
| 814 | 812 | ||
| 815 | mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); | 813 | mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); |
| 816 | if (!mmc) { | 814 | if (!mmc) { |
| 817 | pr_debug("Failed to allocate mmc host\n"); | 815 | pr_debug("Failed to allocate mmc host\n"); |
| 816 | release_mem_region(res->start, res->end - res->start + 1); | ||
| 818 | return -ENOMEM; | 817 | return -ENOMEM; |
| 819 | } | 818 | } |
| 820 | 819 | ||
| @@ -833,30 +832,51 @@ static int at91_mci_probe(struct platform_device *pdev) | |||
| 833 | #ifdef SUPPORT_4WIRE | 832 | #ifdef SUPPORT_4WIRE |
| 834 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 833 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
| 835 | #else | 834 | #else |
| 836 | printk("MMC: 4 wire bus mode not supported by this driver - using 1 wire\n"); | 835 | printk("AT91 MMC: 4 wire bus mode not supported by this driver - using 1 wire\n"); |
| 837 | #endif | 836 | #endif |
| 838 | } | 837 | } |
| 839 | 838 | ||
| 840 | /* | 839 | /* |
| 841 | * Get Clock | 840 | * Get Clock |
| 842 | */ | 841 | */ |
| 843 | mci_clk = clk_get(&pdev->dev, "mci_clk"); | 842 | host->mci_clk = clk_get(&pdev->dev, "mci_clk"); |
| 844 | if (IS_ERR(mci_clk)) { | 843 | if (IS_ERR(host->mci_clk)) { |
| 845 | printk(KERN_ERR "AT91 MMC: no clock defined.\n"); | 844 | printk(KERN_ERR "AT91 MMC: no clock defined.\n"); |
| 846 | mmc_free_host(mmc); | 845 | mmc_free_host(mmc); |
| 846 | release_mem_region(res->start, res->end - res->start + 1); | ||
| 847 | return -ENODEV; | 847 | return -ENODEV; |
| 848 | } | 848 | } |
| 849 | clk_enable(mci_clk); /* Enable the peripheral clock */ | 849 | |
| 850 | /* | ||
| 851 | * Map I/O region | ||
| 852 | */ | ||
| 853 | host->baseaddr = ioremap(res->start, res->end - res->start + 1); | ||
| 854 | if (!host->baseaddr) { | ||
| 855 | clk_put(host->mci_clk); | ||
| 856 | mmc_free_host(mmc); | ||
| 857 | release_mem_region(res->start, res->end - res->start + 1); | ||
| 858 | return -ENOMEM; | ||
| 859 | } | ||
| 860 | |||
| 861 | /* | ||
| 862 | * Reset hardware | ||
| 863 | */ | ||
| 864 | clk_enable(host->mci_clk); /* Enable the peripheral clock */ | ||
| 865 | at91_mci_disable(host); | ||
| 866 | at91_mci_enable(host); | ||
| 850 | 867 | ||
| 851 | /* | 868 | /* |
| 852 | * Allocate the MCI interrupt | 869 | * Allocate the MCI interrupt |
| 853 | */ | 870 | */ |
| 854 | ret = request_irq(AT91RM9200_ID_MCI, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host); | 871 | host->irq = platform_get_irq(pdev, 0); |
| 872 | ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host); | ||
| 855 | if (ret) { | 873 | if (ret) { |
| 856 | printk(KERN_ERR "Failed to request MCI interrupt\n"); | 874 | printk(KERN_ERR "AT91 MMC: Failed to request MCI interrupt\n"); |
| 857 | clk_disable(mci_clk); | 875 | clk_disable(host->mci_clk); |
| 858 | clk_put(mci_clk); | 876 | clk_put(host->mci_clk); |
| 859 | mmc_free_host(mmc); | 877 | mmc_free_host(mmc); |
| 878 | iounmap(host->baseaddr); | ||
| 879 | release_mem_region(res->start, res->end - res->start + 1); | ||
| 860 | return ret; | 880 | return ret; |
| 861 | } | 881 | } |
| 862 | 882 | ||
| @@ -879,10 +899,10 @@ static int at91_mci_probe(struct platform_device *pdev) | |||
| 879 | ret = request_irq(host->board->det_pin, at91_mmc_det_irq, | 899 | ret = request_irq(host->board->det_pin, at91_mmc_det_irq, |
| 880 | 0, DRIVER_NAME, host); | 900 | 0, DRIVER_NAME, host); |
| 881 | if (ret) | 901 | if (ret) |
| 882 | printk(KERN_ERR "couldn't allocate MMC detect irq\n"); | 902 | printk(KERN_ERR "AT91 MMC: Couldn't allocate MMC detect irq\n"); |
| 883 | } | 903 | } |
| 884 | 904 | ||
| 885 | pr_debug(KERN_INFO "Added MCI driver\n"); | 905 | pr_debug("Added MCI driver\n"); |
| 886 | 906 | ||
| 887 | return 0; | 907 | return 0; |
| 888 | } | 908 | } |
| @@ -894,6 +914,7 @@ static int at91_mci_remove(struct platform_device *pdev) | |||
| 894 | { | 914 | { |
| 895 | struct mmc_host *mmc = platform_get_drvdata(pdev); | 915 | struct mmc_host *mmc = platform_get_drvdata(pdev); |
| 896 | struct at91mci_host *host; | 916 | struct at91mci_host *host; |
| 917 | struct resource *res; | ||
| 897 | 918 | ||
| 898 | if (!mmc) | 919 | if (!mmc) |
| 899 | return -1; | 920 | return -1; |
| @@ -905,16 +926,19 @@ static int at91_mci_remove(struct platform_device *pdev) | |||
| 905 | cancel_delayed_work(&host->mmc->detect); | 926 | cancel_delayed_work(&host->mmc->detect); |
| 906 | } | 927 | } |
| 907 | 928 | ||
| 929 | at91_mci_disable(host); | ||
| 908 | mmc_remove_host(mmc); | 930 | mmc_remove_host(mmc); |
| 909 | at91_mci_disable(); | 931 | free_irq(host->irq, host); |
| 910 | free_irq(AT91RM9200_ID_MCI, host); | ||
| 911 | mmc_free_host(mmc); | ||
| 912 | 932 | ||
| 913 | clk_disable(mci_clk); /* Disable the peripheral clock */ | 933 | clk_disable(host->mci_clk); /* Disable the peripheral clock */ |
| 914 | clk_put(mci_clk); | 934 | clk_put(host->mci_clk); |
| 915 | 935 | ||
| 916 | platform_set_drvdata(pdev, NULL); | 936 | iounmap(host->baseaddr); |
| 937 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 938 | release_mem_region(res->start, res->end - res->start + 1); | ||
| 917 | 939 | ||
| 940 | mmc_free_host(mmc); | ||
| 941 | platform_set_drvdata(pdev, NULL); | ||
| 918 | pr_debug("MCI Removed\n"); | 942 | pr_debug("MCI Removed\n"); |
| 919 | 943 | ||
| 920 | return 0; | 944 | return 0; |
diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c index a17423a4ed8f..3e35a43819fb 100644 --- a/drivers/mmc/mmc_queue.c +++ b/drivers/mmc/mmc_queue.c | |||
| @@ -78,8 +78,10 @@ static int mmc_queue_thread(void *d) | |||
| 78 | spin_unlock_irq(q->queue_lock); | 78 | spin_unlock_irq(q->queue_lock); |
| 79 | 79 | ||
| 80 | if (!req) { | 80 | if (!req) { |
| 81 | if (kthread_should_stop()) | 81 | if (kthread_should_stop()) { |
| 82 | set_current_state(TASK_RUNNING); | ||
| 82 | break; | 83 | break; |
| 84 | } | ||
| 83 | up(&mq->thread_sem); | 85 | up(&mq->thread_sem); |
| 84 | schedule(); | 86 | schedule(); |
| 85 | down(&mq->thread_sem); | 87 | down(&mq->thread_sem); |
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index cd98117632d3..c2d13d7e9911 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c | |||
| @@ -1170,8 +1170,8 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
| 1170 | } | 1170 | } |
| 1171 | 1171 | ||
| 1172 | if (pci_resource_len(pdev, first_bar + slot) != 0x100) { | 1172 | if (pci_resource_len(pdev, first_bar + slot) != 0x100) { |
| 1173 | printk(KERN_ERR DRIVER_NAME ": Invalid iomem size. Aborting.\n"); | 1173 | printk(KERN_ERR DRIVER_NAME ": Invalid iomem size. " |
| 1174 | return -ENODEV; | 1174 | "You may experience problems.\n"); |
| 1175 | } | 1175 | } |
| 1176 | 1176 | ||
| 1177 | if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) { | 1177 | if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) { |
