diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-12 18:54:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-12 18:54:23 -0400 |
commit | bd6fe9e14589ab39bdabb942773b3ed669fa5738 (patch) | |
tree | 6ba0398cc98dc758ea13d6b208b6b2791c531a12 /drivers | |
parent | 862aad56dcd67fd0313db51d09a5269f7e3f1f0b (diff) | |
parent | 210ce2a7504e429b7ccc191b1efba4c772c4d8b6 (diff) |
Merge master.kernel.org:/home/rmk/linux-2.6-mmc
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/wbsd.c | 441 | ||||
-rw-r--r-- | drivers/mmc/wbsd.h | 23 |
2 files changed, 229 insertions, 235 deletions
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index e11e55dc8924..3cbca7cbea80 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
@@ -93,7 +93,7 @@ static int dma = 2; | |||
93 | static inline void wbsd_unlock_config(struct wbsd_host* host) | 93 | static inline void wbsd_unlock_config(struct wbsd_host* host) |
94 | { | 94 | { |
95 | BUG_ON(host->config == 0); | 95 | BUG_ON(host->config == 0); |
96 | 96 | ||
97 | outb(host->unlock_code, host->config); | 97 | outb(host->unlock_code, host->config); |
98 | outb(host->unlock_code, host->config); | 98 | outb(host->unlock_code, host->config); |
99 | } | 99 | } |
@@ -101,14 +101,14 @@ static inline void wbsd_unlock_config(struct wbsd_host* host) | |||
101 | static inline void wbsd_lock_config(struct wbsd_host* host) | 101 | static inline void wbsd_lock_config(struct wbsd_host* host) |
102 | { | 102 | { |
103 | BUG_ON(host->config == 0); | 103 | BUG_ON(host->config == 0); |
104 | 104 | ||
105 | outb(LOCK_CODE, host->config); | 105 | outb(LOCK_CODE, host->config); |
106 | } | 106 | } |
107 | 107 | ||
108 | static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value) | 108 | static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value) |
109 | { | 109 | { |
110 | BUG_ON(host->config == 0); | 110 | BUG_ON(host->config == 0); |
111 | 111 | ||
112 | outb(reg, host->config); | 112 | outb(reg, host->config); |
113 | outb(value, host->config + 1); | 113 | outb(value, host->config + 1); |
114 | } | 114 | } |
@@ -116,7 +116,7 @@ static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value) | |||
116 | static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg) | 116 | static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg) |
117 | { | 117 | { |
118 | BUG_ON(host->config == 0); | 118 | BUG_ON(host->config == 0); |
119 | 119 | ||
120 | outb(reg, host->config); | 120 | outb(reg, host->config); |
121 | return inb(host->config + 1); | 121 | return inb(host->config + 1); |
122 | } | 122 | } |
@@ -140,21 +140,21 @@ static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index) | |||
140 | static void wbsd_init_device(struct wbsd_host* host) | 140 | static void wbsd_init_device(struct wbsd_host* host) |
141 | { | 141 | { |
142 | u8 setup, ier; | 142 | u8 setup, ier; |
143 | 143 | ||
144 | /* | 144 | /* |
145 | * Reset chip (SD/MMC part) and fifo. | 145 | * Reset chip (SD/MMC part) and fifo. |
146 | */ | 146 | */ |
147 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); | 147 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); |
148 | setup |= WBSD_FIFO_RESET | WBSD_SOFT_RESET; | 148 | setup |= WBSD_FIFO_RESET | WBSD_SOFT_RESET; |
149 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | 149 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); |
150 | 150 | ||
151 | /* | 151 | /* |
152 | * Set DAT3 to input | 152 | * Set DAT3 to input |
153 | */ | 153 | */ |
154 | setup &= ~WBSD_DAT3_H; | 154 | setup &= ~WBSD_DAT3_H; |
155 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | 155 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); |
156 | host->flags &= ~WBSD_FIGNORE_DETECT; | 156 | host->flags &= ~WBSD_FIGNORE_DETECT; |
157 | 157 | ||
158 | /* | 158 | /* |
159 | * Read back default clock. | 159 | * Read back default clock. |
160 | */ | 160 | */ |
@@ -164,12 +164,12 @@ static void wbsd_init_device(struct wbsd_host* host) | |||
164 | * Power down port. | 164 | * Power down port. |
165 | */ | 165 | */ |
166 | outb(WBSD_POWER_N, host->base + WBSD_CSR); | 166 | outb(WBSD_POWER_N, host->base + WBSD_CSR); |
167 | 167 | ||
168 | /* | 168 | /* |
169 | * Set maximum timeout. | 169 | * Set maximum timeout. |
170 | */ | 170 | */ |
171 | wbsd_write_index(host, WBSD_IDX_TAAC, 0x7F); | 171 | wbsd_write_index(host, WBSD_IDX_TAAC, 0x7F); |
172 | 172 | ||
173 | /* | 173 | /* |
174 | * Test for card presence | 174 | * Test for card presence |
175 | */ | 175 | */ |
@@ -177,7 +177,7 @@ static void wbsd_init_device(struct wbsd_host* host) | |||
177 | host->flags |= WBSD_FCARD_PRESENT; | 177 | host->flags |= WBSD_FCARD_PRESENT; |
178 | else | 178 | else |
179 | host->flags &= ~WBSD_FCARD_PRESENT; | 179 | host->flags &= ~WBSD_FCARD_PRESENT; |
180 | 180 | ||
181 | /* | 181 | /* |
182 | * Enable interesting interrupts. | 182 | * Enable interesting interrupts. |
183 | */ | 183 | */ |
@@ -200,9 +200,9 @@ static void wbsd_init_device(struct wbsd_host* host) | |||
200 | static void wbsd_reset(struct wbsd_host* host) | 200 | static void wbsd_reset(struct wbsd_host* host) |
201 | { | 201 | { |
202 | u8 setup; | 202 | u8 setup; |
203 | 203 | ||
204 | printk(KERN_ERR DRIVER_NAME ": Resetting chip\n"); | 204 | printk(KERN_ERR DRIVER_NAME ": Resetting chip\n"); |
205 | 205 | ||
206 | /* | 206 | /* |
207 | * Soft reset of chip (SD/MMC part). | 207 | * Soft reset of chip (SD/MMC part). |
208 | */ | 208 | */ |
@@ -214,9 +214,9 @@ static void wbsd_reset(struct wbsd_host* host) | |||
214 | static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq) | 214 | static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq) |
215 | { | 215 | { |
216 | unsigned long dmaflags; | 216 | unsigned long dmaflags; |
217 | 217 | ||
218 | DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode); | 218 | DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode); |
219 | 219 | ||
220 | if (host->dma >= 0) | 220 | if (host->dma >= 0) |
221 | { | 221 | { |
222 | /* | 222 | /* |
@@ -232,7 +232,7 @@ static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq) | |||
232 | */ | 232 | */ |
233 | wbsd_write_index(host, WBSD_IDX_DMA, 0); | 233 | wbsd_write_index(host, WBSD_IDX_DMA, 0); |
234 | } | 234 | } |
235 | 235 | ||
236 | host->mrq = NULL; | 236 | host->mrq = NULL; |
237 | 237 | ||
238 | /* | 238 | /* |
@@ -275,7 +275,7 @@ static inline int wbsd_next_sg(struct wbsd_host* host) | |||
275 | host->offset = 0; | 275 | host->offset = 0; |
276 | host->remain = host->cur_sg->length; | 276 | host->remain = host->cur_sg->length; |
277 | } | 277 | } |
278 | 278 | ||
279 | return host->num_sg; | 279 | return host->num_sg; |
280 | } | 280 | } |
281 | 281 | ||
@@ -297,12 +297,12 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data) | |||
297 | struct scatterlist* sg; | 297 | struct scatterlist* sg; |
298 | char* dmabuf = host->dma_buffer; | 298 | char* dmabuf = host->dma_buffer; |
299 | char* sgbuf; | 299 | char* sgbuf; |
300 | 300 | ||
301 | size = host->size; | 301 | size = host->size; |
302 | 302 | ||
303 | sg = data->sg; | 303 | sg = data->sg; |
304 | len = data->sg_len; | 304 | len = data->sg_len; |
305 | 305 | ||
306 | /* | 306 | /* |
307 | * Just loop through all entries. Size might not | 307 | * Just loop through all entries. Size might not |
308 | * be the entire list though so make sure that | 308 | * be the entire list though so make sure that |
@@ -317,23 +317,23 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data) | |||
317 | memcpy(dmabuf, sgbuf, sg[i].length); | 317 | memcpy(dmabuf, sgbuf, sg[i].length); |
318 | kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ); | 318 | kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ); |
319 | dmabuf += sg[i].length; | 319 | dmabuf += sg[i].length; |
320 | 320 | ||
321 | if (size < sg[i].length) | 321 | if (size < sg[i].length) |
322 | size = 0; | 322 | size = 0; |
323 | else | 323 | else |
324 | size -= sg[i].length; | 324 | size -= sg[i].length; |
325 | 325 | ||
326 | if (size == 0) | 326 | if (size == 0) |
327 | break; | 327 | break; |
328 | } | 328 | } |
329 | 329 | ||
330 | /* | 330 | /* |
331 | * Check that we didn't get a request to transfer | 331 | * Check that we didn't get a request to transfer |
332 | * more data than can fit into the SG list. | 332 | * more data than can fit into the SG list. |
333 | */ | 333 | */ |
334 | 334 | ||
335 | BUG_ON(size != 0); | 335 | BUG_ON(size != 0); |
336 | 336 | ||
337 | host->size -= size; | 337 | host->size -= size; |
338 | } | 338 | } |
339 | 339 | ||
@@ -343,12 +343,12 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data) | |||
343 | struct scatterlist* sg; | 343 | struct scatterlist* sg; |
344 | char* dmabuf = host->dma_buffer; | 344 | char* dmabuf = host->dma_buffer; |
345 | char* sgbuf; | 345 | char* sgbuf; |
346 | 346 | ||
347 | size = host->size; | 347 | size = host->size; |
348 | 348 | ||
349 | sg = data->sg; | 349 | sg = data->sg; |
350 | len = data->sg_len; | 350 | len = data->sg_len; |
351 | 351 | ||
352 | /* | 352 | /* |
353 | * Just loop through all entries. Size might not | 353 | * Just loop through all entries. Size might not |
354 | * be the entire list though so make sure that | 354 | * be the entire list though so make sure that |
@@ -363,30 +363,30 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data) | |||
363 | memcpy(sgbuf, dmabuf, sg[i].length); | 363 | memcpy(sgbuf, dmabuf, sg[i].length); |
364 | kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ); | 364 | kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ); |
365 | dmabuf += sg[i].length; | 365 | dmabuf += sg[i].length; |
366 | 366 | ||
367 | if (size < sg[i].length) | 367 | if (size < sg[i].length) |
368 | size = 0; | 368 | size = 0; |
369 | else | 369 | else |
370 | size -= sg[i].length; | 370 | size -= sg[i].length; |
371 | 371 | ||
372 | if (size == 0) | 372 | if (size == 0) |
373 | break; | 373 | break; |
374 | } | 374 | } |
375 | 375 | ||
376 | /* | 376 | /* |
377 | * Check that we didn't get a request to transfer | 377 | * Check that we didn't get a request to transfer |
378 | * more data than can fit into the SG list. | 378 | * more data than can fit into the SG list. |
379 | */ | 379 | */ |
380 | 380 | ||
381 | BUG_ON(size != 0); | 381 | BUG_ON(size != 0); |
382 | 382 | ||
383 | host->size -= size; | 383 | host->size -= size; |
384 | } | 384 | } |
385 | 385 | ||
386 | /* | 386 | /* |
387 | * Command handling | 387 | * Command handling |
388 | */ | 388 | */ |
389 | 389 | ||
390 | static inline void wbsd_get_short_reply(struct wbsd_host* host, | 390 | static inline void wbsd_get_short_reply(struct wbsd_host* host, |
391 | struct mmc_command* cmd) | 391 | struct mmc_command* cmd) |
392 | { | 392 | { |
@@ -398,7 +398,7 @@ static inline void wbsd_get_short_reply(struct wbsd_host* host, | |||
398 | cmd->error = MMC_ERR_INVALID; | 398 | cmd->error = MMC_ERR_INVALID; |
399 | return; | 399 | return; |
400 | } | 400 | } |
401 | 401 | ||
402 | cmd->resp[0] = | 402 | cmd->resp[0] = |
403 | wbsd_read_index(host, WBSD_IDX_RESP12) << 24; | 403 | wbsd_read_index(host, WBSD_IDX_RESP12) << 24; |
404 | cmd->resp[0] |= | 404 | cmd->resp[0] |= |
@@ -415,7 +415,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host, | |||
415 | struct mmc_command* cmd) | 415 | struct mmc_command* cmd) |
416 | { | 416 | { |
417 | int i; | 417 | int i; |
418 | 418 | ||
419 | /* | 419 | /* |
420 | * Correct response type? | 420 | * Correct response type? |
421 | */ | 421 | */ |
@@ -424,7 +424,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host, | |||
424 | cmd->error = MMC_ERR_INVALID; | 424 | cmd->error = MMC_ERR_INVALID; |
425 | return; | 425 | return; |
426 | } | 426 | } |
427 | 427 | ||
428 | for (i = 0;i < 4;i++) | 428 | for (i = 0;i < 4;i++) |
429 | { | 429 | { |
430 | cmd->resp[i] = | 430 | cmd->resp[i] = |
@@ -442,7 +442,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) | |||
442 | { | 442 | { |
443 | int i; | 443 | int i; |
444 | u8 status, isr; | 444 | u8 status, isr; |
445 | 445 | ||
446 | DBGF("Sending cmd (%x)\n", cmd->opcode); | 446 | DBGF("Sending cmd (%x)\n", cmd->opcode); |
447 | 447 | ||
448 | /* | 448 | /* |
@@ -451,16 +451,16 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) | |||
451 | * transfer. | 451 | * transfer. |
452 | */ | 452 | */ |
453 | host->isr = 0; | 453 | host->isr = 0; |
454 | 454 | ||
455 | /* | 455 | /* |
456 | * Send the command (CRC calculated by host). | 456 | * Send the command (CRC calculated by host). |
457 | */ | 457 | */ |
458 | outb(cmd->opcode, host->base + WBSD_CMDR); | 458 | outb(cmd->opcode, host->base + WBSD_CMDR); |
459 | for (i = 3;i >= 0;i--) | 459 | for (i = 3;i >= 0;i--) |
460 | outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR); | 460 | outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR); |
461 | 461 | ||
462 | cmd->error = MMC_ERR_NONE; | 462 | cmd->error = MMC_ERR_NONE; |
463 | 463 | ||
464 | /* | 464 | /* |
465 | * Wait for the request to complete. | 465 | * Wait for the request to complete. |
466 | */ | 466 | */ |
@@ -477,7 +477,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) | |||
477 | * Read back status. | 477 | * Read back status. |
478 | */ | 478 | */ |
479 | isr = host->isr; | 479 | isr = host->isr; |
480 | 480 | ||
481 | /* Card removed? */ | 481 | /* Card removed? */ |
482 | if (isr & WBSD_INT_CARD) | 482 | if (isr & WBSD_INT_CARD) |
483 | cmd->error = MMC_ERR_TIMEOUT; | 483 | cmd->error = MMC_ERR_TIMEOUT; |
@@ -509,13 +509,13 @@ static void wbsd_empty_fifo(struct wbsd_host* host) | |||
509 | struct mmc_data* data = host->mrq->cmd->data; | 509 | struct mmc_data* data = host->mrq->cmd->data; |
510 | char* buffer; | 510 | char* buffer; |
511 | int i, fsr, fifo; | 511 | int i, fsr, fifo; |
512 | 512 | ||
513 | /* | 513 | /* |
514 | * Handle excessive data. | 514 | * Handle excessive data. |
515 | */ | 515 | */ |
516 | if (data->bytes_xfered == host->size) | 516 | if (data->bytes_xfered == host->size) |
517 | return; | 517 | return; |
518 | 518 | ||
519 | buffer = wbsd_kmap_sg(host) + host->offset; | 519 | buffer = wbsd_kmap_sg(host) + host->offset; |
520 | 520 | ||
521 | /* | 521 | /* |
@@ -527,14 +527,14 @@ static void wbsd_empty_fifo(struct wbsd_host* host) | |||
527 | /* | 527 | /* |
528 | * The size field in the FSR is broken so we have to | 528 | * The size field in the FSR is broken so we have to |
529 | * do some guessing. | 529 | * do some guessing. |
530 | */ | 530 | */ |
531 | if (fsr & WBSD_FIFO_FULL) | 531 | if (fsr & WBSD_FIFO_FULL) |
532 | fifo = 16; | 532 | fifo = 16; |
533 | else if (fsr & WBSD_FIFO_FUTHRE) | 533 | else if (fsr & WBSD_FIFO_FUTHRE) |
534 | fifo = 8; | 534 | fifo = 8; |
535 | else | 535 | else |
536 | fifo = 1; | 536 | fifo = 1; |
537 | 537 | ||
538 | for (i = 0;i < fifo;i++) | 538 | for (i = 0;i < fifo;i++) |
539 | { | 539 | { |
540 | *buffer = inb(host->base + WBSD_DFR); | 540 | *buffer = inb(host->base + WBSD_DFR); |
@@ -543,23 +543,23 @@ static void wbsd_empty_fifo(struct wbsd_host* host) | |||
543 | host->remain--; | 543 | host->remain--; |
544 | 544 | ||
545 | data->bytes_xfered++; | 545 | data->bytes_xfered++; |
546 | 546 | ||
547 | /* | 547 | /* |
548 | * Transfer done? | 548 | * Transfer done? |
549 | */ | 549 | */ |
550 | if (data->bytes_xfered == host->size) | 550 | if (data->bytes_xfered == host->size) |
551 | { | 551 | { |
552 | wbsd_kunmap_sg(host); | 552 | wbsd_kunmap_sg(host); |
553 | return; | 553 | return; |
554 | } | 554 | } |
555 | 555 | ||
556 | /* | 556 | /* |
557 | * End of scatter list entry? | 557 | * End of scatter list entry? |
558 | */ | 558 | */ |
559 | if (host->remain == 0) | 559 | if (host->remain == 0) |
560 | { | 560 | { |
561 | wbsd_kunmap_sg(host); | 561 | wbsd_kunmap_sg(host); |
562 | 562 | ||
563 | /* | 563 | /* |
564 | * Get next entry. Check if last. | 564 | * Get next entry. Check if last. |
565 | */ | 565 | */ |
@@ -572,17 +572,17 @@ static void wbsd_empty_fifo(struct wbsd_host* host) | |||
572 | * into the scatter list. | 572 | * into the scatter list. |
573 | */ | 573 | */ |
574 | BUG_ON(1); | 574 | BUG_ON(1); |
575 | 575 | ||
576 | host->size = data->bytes_xfered; | 576 | host->size = data->bytes_xfered; |
577 | 577 | ||
578 | return; | 578 | return; |
579 | } | 579 | } |
580 | 580 | ||
581 | buffer = wbsd_kmap_sg(host); | 581 | buffer = wbsd_kmap_sg(host); |
582 | } | 582 | } |
583 | } | 583 | } |
584 | } | 584 | } |
585 | 585 | ||
586 | wbsd_kunmap_sg(host); | 586 | wbsd_kunmap_sg(host); |
587 | 587 | ||
588 | /* | 588 | /* |
@@ -599,7 +599,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
599 | struct mmc_data* data = host->mrq->cmd->data; | 599 | struct mmc_data* data = host->mrq->cmd->data; |
600 | char* buffer; | 600 | char* buffer; |
601 | int i, fsr, fifo; | 601 | int i, fsr, fifo; |
602 | 602 | ||
603 | /* | 603 | /* |
604 | * Check that we aren't being called after the | 604 | * Check that we aren't being called after the |
605 | * entire buffer has been transfered. | 605 | * entire buffer has been transfered. |
@@ -618,7 +618,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
618 | /* | 618 | /* |
619 | * The size field in the FSR is broken so we have to | 619 | * The size field in the FSR is broken so we have to |
620 | * do some guessing. | 620 | * do some guessing. |
621 | */ | 621 | */ |
622 | if (fsr & WBSD_FIFO_EMPTY) | 622 | if (fsr & WBSD_FIFO_EMPTY) |
623 | fifo = 0; | 623 | fifo = 0; |
624 | else if (fsr & WBSD_FIFO_EMTHRE) | 624 | else if (fsr & WBSD_FIFO_EMTHRE) |
@@ -632,9 +632,9 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
632 | buffer++; | 632 | buffer++; |
633 | host->offset++; | 633 | host->offset++; |
634 | host->remain--; | 634 | host->remain--; |
635 | 635 | ||
636 | data->bytes_xfered++; | 636 | data->bytes_xfered++; |
637 | 637 | ||
638 | /* | 638 | /* |
639 | * Transfer done? | 639 | * Transfer done? |
640 | */ | 640 | */ |
@@ -650,7 +650,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
650 | if (host->remain == 0) | 650 | if (host->remain == 0) |
651 | { | 651 | { |
652 | wbsd_kunmap_sg(host); | 652 | wbsd_kunmap_sg(host); |
653 | 653 | ||
654 | /* | 654 | /* |
655 | * Get next entry. Check if last. | 655 | * Get next entry. Check if last. |
656 | */ | 656 | */ |
@@ -663,19 +663,19 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
663 | * into the scatter list. | 663 | * into the scatter list. |
664 | */ | 664 | */ |
665 | BUG_ON(1); | 665 | BUG_ON(1); |
666 | 666 | ||
667 | host->size = data->bytes_xfered; | 667 | host->size = data->bytes_xfered; |
668 | 668 | ||
669 | return; | 669 | return; |
670 | } | 670 | } |
671 | 671 | ||
672 | buffer = wbsd_kmap_sg(host); | 672 | buffer = wbsd_kmap_sg(host); |
673 | } | 673 | } |
674 | } | 674 | } |
675 | } | 675 | } |
676 | 676 | ||
677 | wbsd_kunmap_sg(host); | 677 | wbsd_kunmap_sg(host); |
678 | 678 | ||
679 | /* | 679 | /* |
680 | * The controller stops sending interrupts for | 680 | * The controller stops sending interrupts for |
681 | * 'FIFO empty' under certain conditions. So we | 681 | * 'FIFO empty' under certain conditions. So we |
@@ -694,7 +694,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
694 | 1 << data->blksz_bits, data->blocks, data->flags); | 694 | 1 << data->blksz_bits, data->blocks, data->flags); |
695 | DBGF("tsac %d ms nsac %d clk\n", | 695 | DBGF("tsac %d ms nsac %d clk\n", |
696 | data->timeout_ns / 1000000, data->timeout_clks); | 696 | data->timeout_ns / 1000000, data->timeout_clks); |
697 | 697 | ||
698 | /* | 698 | /* |
699 | * Calculate size. | 699 | * Calculate size. |
700 | */ | 700 | */ |
@@ -708,12 +708,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
708 | wbsd_write_index(host, WBSD_IDX_TAAC, 127); | 708 | wbsd_write_index(host, WBSD_IDX_TAAC, 127); |
709 | else | 709 | else |
710 | wbsd_write_index(host, WBSD_IDX_TAAC, data->timeout_ns/1000000); | 710 | wbsd_write_index(host, WBSD_IDX_TAAC, data->timeout_ns/1000000); |
711 | 711 | ||
712 | if (data->timeout_clks > 255) | 712 | if (data->timeout_clks > 255) |
713 | wbsd_write_index(host, WBSD_IDX_NSAC, 255); | 713 | wbsd_write_index(host, WBSD_IDX_NSAC, 255); |
714 | else | 714 | else |
715 | wbsd_write_index(host, WBSD_IDX_NSAC, data->timeout_clks); | 715 | wbsd_write_index(host, WBSD_IDX_NSAC, data->timeout_clks); |
716 | 716 | ||
717 | /* | 717 | /* |
718 | * Inform the chip of how large blocks will be | 718 | * Inform the chip of how large blocks will be |
719 | * sent. It needs this to determine when to | 719 | * sent. It needs this to determine when to |
@@ -732,7 +732,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
732 | else if (host->bus_width == MMC_BUS_WIDTH_4) | 732 | else if (host->bus_width == MMC_BUS_WIDTH_4) |
733 | { | 733 | { |
734 | blksize = (1 << data->blksz_bits) + 2 * 4; | 734 | blksize = (1 << data->blksz_bits) + 2 * 4; |
735 | 735 | ||
736 | wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0) | 736 | wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0) |
737 | | WBSD_DATA_WIDTH); | 737 | | WBSD_DATA_WIDTH); |
738 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); | 738 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); |
@@ -751,12 +751,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
751 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); | 751 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); |
752 | setup |= WBSD_FIFO_RESET; | 752 | setup |= WBSD_FIFO_RESET; |
753 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | 753 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); |
754 | 754 | ||
755 | /* | 755 | /* |
756 | * DMA transfer? | 756 | * DMA transfer? |
757 | */ | 757 | */ |
758 | if (host->dma >= 0) | 758 | if (host->dma >= 0) |
759 | { | 759 | { |
760 | /* | 760 | /* |
761 | * The buffer for DMA is only 64 kB. | 761 | * The buffer for DMA is only 64 kB. |
762 | */ | 762 | */ |
@@ -766,17 +766,17 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
766 | data->error = MMC_ERR_INVALID; | 766 | data->error = MMC_ERR_INVALID; |
767 | return; | 767 | return; |
768 | } | 768 | } |
769 | 769 | ||
770 | /* | 770 | /* |
771 | * Transfer data from the SG list to | 771 | * Transfer data from the SG list to |
772 | * the DMA buffer. | 772 | * the DMA buffer. |
773 | */ | 773 | */ |
774 | if (data->flags & MMC_DATA_WRITE) | 774 | if (data->flags & MMC_DATA_WRITE) |
775 | wbsd_sg_to_dma(host, data); | 775 | wbsd_sg_to_dma(host, data); |
776 | 776 | ||
777 | /* | 777 | /* |
778 | * Initialise the ISA DMA controller. | 778 | * Initialise the ISA DMA controller. |
779 | */ | 779 | */ |
780 | dmaflags = claim_dma_lock(); | 780 | dmaflags = claim_dma_lock(); |
781 | disable_dma(host->dma); | 781 | disable_dma(host->dma); |
782 | clear_dma_ff(host->dma); | 782 | clear_dma_ff(host->dma); |
@@ -802,17 +802,17 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
802 | * output to a minimum. | 802 | * output to a minimum. |
803 | */ | 803 | */ |
804 | host->firsterr = 1; | 804 | host->firsterr = 1; |
805 | 805 | ||
806 | /* | 806 | /* |
807 | * Initialise the SG list. | 807 | * Initialise the SG list. |
808 | */ | 808 | */ |
809 | wbsd_init_sg(host, data); | 809 | wbsd_init_sg(host, data); |
810 | 810 | ||
811 | /* | 811 | /* |
812 | * Turn off DMA. | 812 | * Turn off DMA. |
813 | */ | 813 | */ |
814 | wbsd_write_index(host, WBSD_IDX_DMA, 0); | 814 | wbsd_write_index(host, WBSD_IDX_DMA, 0); |
815 | 815 | ||
816 | /* | 816 | /* |
817 | * Set up FIFO threshold levels (and fill | 817 | * Set up FIFO threshold levels (and fill |
818 | * buffer if doing a write). | 818 | * buffer if doing a write). |
@@ -828,8 +828,8 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
828 | WBSD_FIFOEN_EMPTY | 8); | 828 | WBSD_FIFOEN_EMPTY | 8); |
829 | wbsd_fill_fifo(host); | 829 | wbsd_fill_fifo(host); |
830 | } | 830 | } |
831 | } | 831 | } |
832 | 832 | ||
833 | data->error = MMC_ERR_NONE; | 833 | data->error = MMC_ERR_NONE; |
834 | } | 834 | } |
835 | 835 | ||
@@ -838,7 +838,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | |||
838 | unsigned long dmaflags; | 838 | unsigned long dmaflags; |
839 | int count; | 839 | int count; |
840 | u8 status; | 840 | u8 status; |
841 | 841 | ||
842 | WARN_ON(host->mrq == NULL); | 842 | WARN_ON(host->mrq == NULL); |
843 | 843 | ||
844 | /* | 844 | /* |
@@ -855,7 +855,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | |||
855 | { | 855 | { |
856 | status = wbsd_read_index(host, WBSD_IDX_STATUS); | 856 | status = wbsd_read_index(host, WBSD_IDX_STATUS); |
857 | } while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE)); | 857 | } while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE)); |
858 | 858 | ||
859 | /* | 859 | /* |
860 | * DMA transfer? | 860 | * DMA transfer? |
861 | */ | 861 | */ |
@@ -865,7 +865,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | |||
865 | * Disable DMA on the host. | 865 | * Disable DMA on the host. |
866 | */ | 866 | */ |
867 | wbsd_write_index(host, WBSD_IDX_DMA, 0); | 867 | wbsd_write_index(host, WBSD_IDX_DMA, 0); |
868 | 868 | ||
869 | /* | 869 | /* |
870 | * Turn of ISA DMA controller. | 870 | * Turn of ISA DMA controller. |
871 | */ | 871 | */ |
@@ -874,7 +874,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | |||
874 | clear_dma_ff(host->dma); | 874 | clear_dma_ff(host->dma); |
875 | count = get_dma_residue(host->dma); | 875 | count = get_dma_residue(host->dma); |
876 | release_dma_lock(dmaflags); | 876 | release_dma_lock(dmaflags); |
877 | 877 | ||
878 | /* | 878 | /* |
879 | * Any leftover data? | 879 | * Any leftover data? |
880 | */ | 880 | */ |
@@ -882,7 +882,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | |||
882 | { | 882 | { |
883 | printk(KERN_ERR DRIVER_NAME ": Incomplete DMA " | 883 | printk(KERN_ERR DRIVER_NAME ": Incomplete DMA " |
884 | "transfer. %d bytes left.\n", count); | 884 | "transfer. %d bytes left.\n", count); |
885 | 885 | ||
886 | data->error = MMC_ERR_FAILED; | 886 | data->error = MMC_ERR_FAILED; |
887 | } | 887 | } |
888 | else | 888 | else |
@@ -893,13 +893,13 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | |||
893 | */ | 893 | */ |
894 | if (data->flags & MMC_DATA_READ) | 894 | if (data->flags & MMC_DATA_READ) |
895 | wbsd_dma_to_sg(host, data); | 895 | wbsd_dma_to_sg(host, data); |
896 | 896 | ||
897 | data->bytes_xfered = host->size; | 897 | data->bytes_xfered = host->size; |
898 | } | 898 | } |
899 | } | 899 | } |
900 | 900 | ||
901 | DBGF("Ending data transfer (%d bytes)\n", data->bytes_xfered); | 901 | DBGF("Ending data transfer (%d bytes)\n", data->bytes_xfered); |
902 | 902 | ||
903 | wbsd_request_end(host, host->mrq); | 903 | wbsd_request_end(host, host->mrq); |
904 | } | 904 | } |
905 | 905 | ||
@@ -924,7 +924,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
924 | cmd = mrq->cmd; | 924 | cmd = mrq->cmd; |
925 | 925 | ||
926 | host->mrq = mrq; | 926 | host->mrq = mrq; |
927 | 927 | ||
928 | /* | 928 | /* |
929 | * If there is no card in the slot then | 929 | * If there is no card in the slot then |
930 | * timeout immediatly. | 930 | * timeout immediatly. |
@@ -941,18 +941,18 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
941 | if (cmd->data) | 941 | if (cmd->data) |
942 | { | 942 | { |
943 | wbsd_prepare_data(host, cmd->data); | 943 | wbsd_prepare_data(host, cmd->data); |
944 | 944 | ||
945 | if (cmd->data->error != MMC_ERR_NONE) | 945 | if (cmd->data->error != MMC_ERR_NONE) |
946 | goto done; | 946 | goto done; |
947 | } | 947 | } |
948 | 948 | ||
949 | wbsd_send_command(host, cmd); | 949 | wbsd_send_command(host, cmd); |
950 | 950 | ||
951 | /* | 951 | /* |
952 | * If this is a data transfer the request | 952 | * If this is a data transfer the request |
953 | * will be finished after the data has | 953 | * will be finished after the data has |
954 | * transfered. | 954 | * transfered. |
955 | */ | 955 | */ |
956 | if (cmd->data && (cmd->error == MMC_ERR_NONE)) | 956 | if (cmd->data && (cmd->error == MMC_ERR_NONE)) |
957 | { | 957 | { |
958 | /* | 958 | /* |
@@ -965,7 +965,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
965 | 965 | ||
966 | return; | 966 | return; |
967 | } | 967 | } |
968 | 968 | ||
969 | done: | 969 | done: |
970 | wbsd_request_end(host, mrq); | 970 | wbsd_request_end(host, mrq); |
971 | 971 | ||
@@ -976,7 +976,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
976 | { | 976 | { |
977 | struct wbsd_host* host = mmc_priv(mmc); | 977 | struct wbsd_host* host = mmc_priv(mmc); |
978 | u8 clk, setup, pwr; | 978 | u8 clk, setup, pwr; |
979 | 979 | ||
980 | DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", | 980 | DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", |
981 | ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, | 981 | ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, |
982 | ios->vdd, ios->bus_width); | 982 | ios->vdd, ios->bus_width); |
@@ -989,7 +989,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
989 | */ | 989 | */ |
990 | if (ios->power_mode == MMC_POWER_OFF) | 990 | if (ios->power_mode == MMC_POWER_OFF) |
991 | wbsd_init_device(host); | 991 | wbsd_init_device(host); |
992 | 992 | ||
993 | if (ios->clock >= 24000000) | 993 | if (ios->clock >= 24000000) |
994 | clk = WBSD_CLK_24M; | 994 | clk = WBSD_CLK_24M; |
995 | else if (ios->clock >= 16000000) | 995 | else if (ios->clock >= 16000000) |
@@ -1042,7 +1042,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
1042 | mod_timer(&host->ignore_timer, jiffies + HZ/100); | 1042 | mod_timer(&host->ignore_timer, jiffies + HZ/100); |
1043 | } | 1043 | } |
1044 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | 1044 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); |
1045 | 1045 | ||
1046 | /* | 1046 | /* |
1047 | * Store bus width for later. Will be used when | 1047 | * Store bus width for later. Will be used when |
1048 | * setting up the data transfer. | 1048 | * setting up the data transfer. |
@@ -1128,7 +1128,7 @@ static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host) | |||
1128 | WARN_ON(!host->mrq->cmd->data); | 1128 | WARN_ON(!host->mrq->cmd->data); |
1129 | if (!host->mrq->cmd->data) | 1129 | if (!host->mrq->cmd->data) |
1130 | return NULL; | 1130 | return NULL; |
1131 | 1131 | ||
1132 | return host->mrq->cmd->data; | 1132 | return host->mrq->cmd->data; |
1133 | } | 1133 | } |
1134 | 1134 | ||
@@ -1136,72 +1136,67 @@ static void wbsd_tasklet_card(unsigned long param) | |||
1136 | { | 1136 | { |
1137 | struct wbsd_host* host = (struct wbsd_host*)param; | 1137 | struct wbsd_host* host = (struct wbsd_host*)param; |
1138 | u8 csr; | 1138 | u8 csr; |
1139 | 1139 | int delay = -1; | |
1140 | |||
1140 | spin_lock(&host->lock); | 1141 | spin_lock(&host->lock); |
1141 | 1142 | ||
1142 | if (host->flags & WBSD_FIGNORE_DETECT) | 1143 | if (host->flags & WBSD_FIGNORE_DETECT) |
1143 | { | 1144 | { |
1144 | spin_unlock(&host->lock); | 1145 | spin_unlock(&host->lock); |
1145 | return; | 1146 | return; |
1146 | } | 1147 | } |
1147 | 1148 | ||
1148 | csr = inb(host->base + WBSD_CSR); | 1149 | csr = inb(host->base + WBSD_CSR); |
1149 | WARN_ON(csr == 0xff); | 1150 | WARN_ON(csr == 0xff); |
1150 | 1151 | ||
1151 | if (csr & WBSD_CARDPRESENT) | 1152 | if (csr & WBSD_CARDPRESENT) |
1152 | { | 1153 | { |
1153 | if (!(host->flags & WBSD_FCARD_PRESENT)) | 1154 | if (!(host->flags & WBSD_FCARD_PRESENT)) |
1154 | { | 1155 | { |
1155 | DBG("Card inserted\n"); | 1156 | DBG("Card inserted\n"); |
1156 | host->flags |= WBSD_FCARD_PRESENT; | 1157 | host->flags |= WBSD_FCARD_PRESENT; |
1157 | |||
1158 | spin_unlock(&host->lock); | ||
1159 | 1158 | ||
1160 | /* | 1159 | delay = 500; |
1161 | * Delay card detection to allow electrical connections | ||
1162 | * to stabilise. | ||
1163 | */ | ||
1164 | mmc_detect_change(host->mmc, msecs_to_jiffies(500)); | ||
1165 | } | 1160 | } |
1166 | else | ||
1167 | spin_unlock(&host->lock); | ||
1168 | } | 1161 | } |
1169 | else if (host->flags & WBSD_FCARD_PRESENT) | 1162 | else if (host->flags & WBSD_FCARD_PRESENT) |
1170 | { | 1163 | { |
1171 | DBG("Card removed\n"); | 1164 | DBG("Card removed\n"); |
1172 | host->flags &= ~WBSD_FCARD_PRESENT; | 1165 | host->flags &= ~WBSD_FCARD_PRESENT; |
1173 | 1166 | ||
1174 | if (host->mrq) | 1167 | if (host->mrq) |
1175 | { | 1168 | { |
1176 | printk(KERN_ERR DRIVER_NAME | 1169 | printk(KERN_ERR DRIVER_NAME |
1177 | ": Card removed during transfer!\n"); | 1170 | ": Card removed during transfer!\n"); |
1178 | wbsd_reset(host); | 1171 | wbsd_reset(host); |
1179 | 1172 | ||
1180 | host->mrq->cmd->error = MMC_ERR_FAILED; | 1173 | host->mrq->cmd->error = MMC_ERR_FAILED; |
1181 | tasklet_schedule(&host->finish_tasklet); | 1174 | tasklet_schedule(&host->finish_tasklet); |
1182 | } | 1175 | } |
1183 | |||
1184 | /* | ||
1185 | * Unlock first since we might get a call back. | ||
1186 | */ | ||
1187 | spin_unlock(&host->lock); | ||
1188 | 1176 | ||
1189 | mmc_detect_change(host->mmc, 0); | 1177 | delay = 0; |
1190 | } | 1178 | } |
1191 | else | 1179 | |
1192 | spin_unlock(&host->lock); | 1180 | /* |
1181 | * Unlock first since we might get a call back. | ||
1182 | */ | ||
1183 | |||
1184 | spin_unlock(&host->lock); | ||
1185 | |||
1186 | if (delay != -1) | ||
1187 | mmc_detect_change(host->mmc, msecs_to_jiffies(delay)); | ||
1193 | } | 1188 | } |
1194 | 1189 | ||
1195 | static void wbsd_tasklet_fifo(unsigned long param) | 1190 | static void wbsd_tasklet_fifo(unsigned long param) |
1196 | { | 1191 | { |
1197 | struct wbsd_host* host = (struct wbsd_host*)param; | 1192 | struct wbsd_host* host = (struct wbsd_host*)param; |
1198 | struct mmc_data* data; | 1193 | struct mmc_data* data; |
1199 | 1194 | ||
1200 | spin_lock(&host->lock); | 1195 | spin_lock(&host->lock); |
1201 | 1196 | ||
1202 | if (!host->mrq) | 1197 | if (!host->mrq) |
1203 | goto end; | 1198 | goto end; |
1204 | 1199 | ||
1205 | data = wbsd_get_data(host); | 1200 | data = wbsd_get_data(host); |
1206 | if (!data) | 1201 | if (!data) |
1207 | goto end; | 1202 | goto end; |
@@ -1220,7 +1215,7 @@ static void wbsd_tasklet_fifo(unsigned long param) | |||
1220 | tasklet_schedule(&host->finish_tasklet); | 1215 | tasklet_schedule(&host->finish_tasklet); |
1221 | } | 1216 | } |
1222 | 1217 | ||
1223 | end: | 1218 | end: |
1224 | spin_unlock(&host->lock); | 1219 | spin_unlock(&host->lock); |
1225 | } | 1220 | } |
1226 | 1221 | ||
@@ -1228,23 +1223,23 @@ static void wbsd_tasklet_crc(unsigned long param) | |||
1228 | { | 1223 | { |
1229 | struct wbsd_host* host = (struct wbsd_host*)param; | 1224 | struct wbsd_host* host = (struct wbsd_host*)param; |
1230 | struct mmc_data* data; | 1225 | struct mmc_data* data; |
1231 | 1226 | ||
1232 | spin_lock(&host->lock); | 1227 | spin_lock(&host->lock); |
1233 | 1228 | ||
1234 | if (!host->mrq) | 1229 | if (!host->mrq) |
1235 | goto end; | 1230 | goto end; |
1236 | 1231 | ||
1237 | data = wbsd_get_data(host); | 1232 | data = wbsd_get_data(host); |
1238 | if (!data) | 1233 | if (!data) |
1239 | goto end; | 1234 | goto end; |
1240 | 1235 | ||
1241 | DBGF("CRC error\n"); | 1236 | DBGF("CRC error\n"); |
1242 | 1237 | ||
1243 | data->error = MMC_ERR_BADCRC; | 1238 | data->error = MMC_ERR_BADCRC; |
1244 | 1239 | ||
1245 | tasklet_schedule(&host->finish_tasklet); | 1240 | tasklet_schedule(&host->finish_tasklet); |
1246 | 1241 | ||
1247 | end: | 1242 | end: |
1248 | spin_unlock(&host->lock); | 1243 | spin_unlock(&host->lock); |
1249 | } | 1244 | } |
1250 | 1245 | ||
@@ -1252,23 +1247,23 @@ static void wbsd_tasklet_timeout(unsigned long param) | |||
1252 | { | 1247 | { |
1253 | struct wbsd_host* host = (struct wbsd_host*)param; | 1248 | struct wbsd_host* host = (struct wbsd_host*)param; |
1254 | struct mmc_data* data; | 1249 | struct mmc_data* data; |
1255 | 1250 | ||
1256 | spin_lock(&host->lock); | 1251 | spin_lock(&host->lock); |
1257 | 1252 | ||
1258 | if (!host->mrq) | 1253 | if (!host->mrq) |
1259 | goto end; | 1254 | goto end; |
1260 | 1255 | ||
1261 | data = wbsd_get_data(host); | 1256 | data = wbsd_get_data(host); |
1262 | if (!data) | 1257 | if (!data) |
1263 | goto end; | 1258 | goto end; |
1264 | 1259 | ||
1265 | DBGF("Timeout\n"); | 1260 | DBGF("Timeout\n"); |
1266 | 1261 | ||
1267 | data->error = MMC_ERR_TIMEOUT; | 1262 | data->error = MMC_ERR_TIMEOUT; |
1268 | 1263 | ||
1269 | tasklet_schedule(&host->finish_tasklet); | 1264 | tasklet_schedule(&host->finish_tasklet); |
1270 | 1265 | ||
1271 | end: | 1266 | end: |
1272 | spin_unlock(&host->lock); | 1267 | spin_unlock(&host->lock); |
1273 | } | 1268 | } |
1274 | 1269 | ||
@@ -1276,20 +1271,20 @@ static void wbsd_tasklet_finish(unsigned long param) | |||
1276 | { | 1271 | { |
1277 | struct wbsd_host* host = (struct wbsd_host*)param; | 1272 | struct wbsd_host* host = (struct wbsd_host*)param; |
1278 | struct mmc_data* data; | 1273 | struct mmc_data* data; |
1279 | 1274 | ||
1280 | spin_lock(&host->lock); | 1275 | spin_lock(&host->lock); |
1281 | 1276 | ||
1282 | WARN_ON(!host->mrq); | 1277 | WARN_ON(!host->mrq); |
1283 | if (!host->mrq) | 1278 | if (!host->mrq) |
1284 | goto end; | 1279 | goto end; |
1285 | 1280 | ||
1286 | data = wbsd_get_data(host); | 1281 | data = wbsd_get_data(host); |
1287 | if (!data) | 1282 | if (!data) |
1288 | goto end; | 1283 | goto end; |
1289 | 1284 | ||
1290 | wbsd_finish_data(host, data); | 1285 | wbsd_finish_data(host, data); |
1291 | 1286 | ||
1292 | end: | 1287 | end: |
1293 | spin_unlock(&host->lock); | 1288 | spin_unlock(&host->lock); |
1294 | } | 1289 | } |
1295 | 1290 | ||
@@ -1297,7 +1292,7 @@ static void wbsd_tasklet_block(unsigned long param) | |||
1297 | { | 1292 | { |
1298 | struct wbsd_host* host = (struct wbsd_host*)param; | 1293 | struct wbsd_host* host = (struct wbsd_host*)param; |
1299 | struct mmc_data* data; | 1294 | struct mmc_data* data; |
1300 | 1295 | ||
1301 | spin_lock(&host->lock); | 1296 | spin_lock(&host->lock); |
1302 | 1297 | ||
1303 | if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) != | 1298 | if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) != |
@@ -1306,15 +1301,15 @@ static void wbsd_tasklet_block(unsigned long param) | |||
1306 | data = wbsd_get_data(host); | 1301 | data = wbsd_get_data(host); |
1307 | if (!data) | 1302 | if (!data) |
1308 | goto end; | 1303 | goto end; |
1309 | 1304 | ||
1310 | DBGF("CRC error\n"); | 1305 | DBGF("CRC error\n"); |
1311 | 1306 | ||
1312 | data->error = MMC_ERR_BADCRC; | 1307 | data->error = MMC_ERR_BADCRC; |
1313 | 1308 | ||
1314 | tasklet_schedule(&host->finish_tasklet); | 1309 | tasklet_schedule(&host->finish_tasklet); |
1315 | } | 1310 | } |
1316 | 1311 | ||
1317 | end: | 1312 | end: |
1318 | spin_unlock(&host->lock); | 1313 | spin_unlock(&host->lock); |
1319 | } | 1314 | } |
1320 | 1315 | ||
@@ -1326,7 +1321,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
1326 | { | 1321 | { |
1327 | struct wbsd_host* host = dev_id; | 1322 | struct wbsd_host* host = dev_id; |
1328 | int isr; | 1323 | int isr; |
1329 | 1324 | ||
1330 | isr = inb(host->base + WBSD_ISR); | 1325 | isr = inb(host->base + WBSD_ISR); |
1331 | 1326 | ||
1332 | /* | 1327 | /* |
@@ -1334,7 +1329,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
1334 | */ | 1329 | */ |
1335 | if (isr == 0xff || isr == 0x00) | 1330 | if (isr == 0xff || isr == 0x00) |
1336 | return IRQ_NONE; | 1331 | return IRQ_NONE; |
1337 | 1332 | ||
1338 | host->isr |= isr; | 1333 | host->isr |= isr; |
1339 | 1334 | ||
1340 | /* | 1335 | /* |
@@ -1352,7 +1347,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
1352 | tasklet_hi_schedule(&host->block_tasklet); | 1347 | tasklet_hi_schedule(&host->block_tasklet); |
1353 | if (isr & WBSD_INT_TC) | 1348 | if (isr & WBSD_INT_TC) |
1354 | tasklet_schedule(&host->finish_tasklet); | 1349 | tasklet_schedule(&host->finish_tasklet); |
1355 | 1350 | ||
1356 | return IRQ_HANDLED; | 1351 | return IRQ_HANDLED; |
1357 | } | 1352 | } |
1358 | 1353 | ||
@@ -1370,14 +1365,14 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) | |||
1370 | { | 1365 | { |
1371 | struct mmc_host* mmc; | 1366 | struct mmc_host* mmc; |
1372 | struct wbsd_host* host; | 1367 | struct wbsd_host* host; |
1373 | 1368 | ||
1374 | /* | 1369 | /* |
1375 | * Allocate MMC structure. | 1370 | * Allocate MMC structure. |
1376 | */ | 1371 | */ |
1377 | mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev); | 1372 | mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev); |
1378 | if (!mmc) | 1373 | if (!mmc) |
1379 | return -ENOMEM; | 1374 | return -ENOMEM; |
1380 | 1375 | ||
1381 | host = mmc_priv(mmc); | 1376 | host = mmc_priv(mmc); |
1382 | host->mmc = mmc; | 1377 | host->mmc = mmc; |
1383 | 1378 | ||
@@ -1391,37 +1386,37 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) | |||
1391 | mmc->f_max = 24000000; | 1386 | mmc->f_max = 24000000; |
1392 | mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; | 1387 | mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; |
1393 | mmc->caps = MMC_CAP_4_BIT_DATA; | 1388 | mmc->caps = MMC_CAP_4_BIT_DATA; |
1394 | 1389 | ||
1395 | spin_lock_init(&host->lock); | 1390 | spin_lock_init(&host->lock); |
1396 | 1391 | ||
1397 | /* | 1392 | /* |
1398 | * Set up timers | 1393 | * Set up timers |
1399 | */ | 1394 | */ |
1400 | init_timer(&host->ignore_timer); | 1395 | init_timer(&host->ignore_timer); |
1401 | host->ignore_timer.data = (unsigned long)host; | 1396 | host->ignore_timer.data = (unsigned long)host; |
1402 | host->ignore_timer.function = wbsd_reset_ignore; | 1397 | host->ignore_timer.function = wbsd_reset_ignore; |
1403 | 1398 | ||
1404 | /* | 1399 | /* |
1405 | * Maximum number of segments. Worst case is one sector per segment | 1400 | * Maximum number of segments. Worst case is one sector per segment |
1406 | * so this will be 64kB/512. | 1401 | * so this will be 64kB/512. |
1407 | */ | 1402 | */ |
1408 | mmc->max_hw_segs = 128; | 1403 | mmc->max_hw_segs = 128; |
1409 | mmc->max_phys_segs = 128; | 1404 | mmc->max_phys_segs = 128; |
1410 | 1405 | ||
1411 | /* | 1406 | /* |
1412 | * Maximum number of sectors in one transfer. Also limited by 64kB | 1407 | * Maximum number of sectors in one transfer. Also limited by 64kB |
1413 | * buffer. | 1408 | * buffer. |
1414 | */ | 1409 | */ |
1415 | mmc->max_sectors = 128; | 1410 | mmc->max_sectors = 128; |
1416 | 1411 | ||
1417 | /* | 1412 | /* |
1418 | * Maximum segment size. Could be one segment with the maximum number | 1413 | * Maximum segment size. Could be one segment with the maximum number |
1419 | * of segments. | 1414 | * of segments. |
1420 | */ | 1415 | */ |
1421 | mmc->max_seg_size = mmc->max_sectors * 512; | 1416 | mmc->max_seg_size = mmc->max_sectors * 512; |
1422 | 1417 | ||
1423 | dev_set_drvdata(dev, mmc); | 1418 | dev_set_drvdata(dev, mmc); |
1424 | 1419 | ||
1425 | return 0; | 1420 | return 0; |
1426 | } | 1421 | } |
1427 | 1422 | ||
@@ -1429,18 +1424,18 @@ static void __devexit wbsd_free_mmc(struct device* dev) | |||
1429 | { | 1424 | { |
1430 | struct mmc_host* mmc; | 1425 | struct mmc_host* mmc; |
1431 | struct wbsd_host* host; | 1426 | struct wbsd_host* host; |
1432 | 1427 | ||
1433 | mmc = dev_get_drvdata(dev); | 1428 | mmc = dev_get_drvdata(dev); |
1434 | if (!mmc) | 1429 | if (!mmc) |
1435 | return; | 1430 | return; |
1436 | 1431 | ||
1437 | host = mmc_priv(mmc); | 1432 | host = mmc_priv(mmc); |
1438 | BUG_ON(host == NULL); | 1433 | BUG_ON(host == NULL); |
1439 | 1434 | ||
1440 | del_timer_sync(&host->ignore_timer); | 1435 | del_timer_sync(&host->ignore_timer); |
1441 | 1436 | ||
1442 | mmc_free_host(mmc); | 1437 | mmc_free_host(mmc); |
1443 | 1438 | ||
1444 | dev_set_drvdata(dev, NULL); | 1439 | dev_set_drvdata(dev, NULL); |
1445 | } | 1440 | } |
1446 | 1441 | ||
@@ -1452,7 +1447,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host) | |||
1452 | { | 1447 | { |
1453 | int i, j, k; | 1448 | int i, j, k; |
1454 | int id; | 1449 | int id; |
1455 | 1450 | ||
1456 | /* | 1451 | /* |
1457 | * Iterate through all ports, all codes to | 1452 | * Iterate through all ports, all codes to |
1458 | * find hardware that is in our known list. | 1453 | * find hardware that is in our known list. |
@@ -1461,32 +1456,32 @@ static int __devinit wbsd_scan(struct wbsd_host* host) | |||
1461 | { | 1456 | { |
1462 | if (!request_region(config_ports[i], 2, DRIVER_NAME)) | 1457 | if (!request_region(config_ports[i], 2, DRIVER_NAME)) |
1463 | continue; | 1458 | continue; |
1464 | 1459 | ||
1465 | for (j = 0;j < sizeof(unlock_codes)/sizeof(int);j++) | 1460 | for (j = 0;j < sizeof(unlock_codes)/sizeof(int);j++) |
1466 | { | 1461 | { |
1467 | id = 0xFFFF; | 1462 | id = 0xFFFF; |
1468 | 1463 | ||
1469 | outb(unlock_codes[j], config_ports[i]); | 1464 | outb(unlock_codes[j], config_ports[i]); |
1470 | outb(unlock_codes[j], config_ports[i]); | 1465 | outb(unlock_codes[j], config_ports[i]); |
1471 | 1466 | ||
1472 | outb(WBSD_CONF_ID_HI, config_ports[i]); | 1467 | outb(WBSD_CONF_ID_HI, config_ports[i]); |
1473 | id = inb(config_ports[i] + 1) << 8; | 1468 | id = inb(config_ports[i] + 1) << 8; |
1474 | 1469 | ||
1475 | outb(WBSD_CONF_ID_LO, config_ports[i]); | 1470 | outb(WBSD_CONF_ID_LO, config_ports[i]); |
1476 | id |= inb(config_ports[i] + 1); | 1471 | id |= inb(config_ports[i] + 1); |
1477 | 1472 | ||
1478 | for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++) | 1473 | for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++) |
1479 | { | 1474 | { |
1480 | if (id == valid_ids[k]) | 1475 | if (id == valid_ids[k]) |
1481 | { | 1476 | { |
1482 | host->chip_id = id; | 1477 | host->chip_id = id; |
1483 | host->config = config_ports[i]; | 1478 | host->config = config_ports[i]; |
1484 | host->unlock_code = unlock_codes[i]; | 1479 | host->unlock_code = unlock_codes[i]; |
1485 | 1480 | ||
1486 | return 0; | 1481 | return 0; |
1487 | } | 1482 | } |
1488 | } | 1483 | } |
1489 | 1484 | ||
1490 | if (id != 0xFFFF) | 1485 | if (id != 0xFFFF) |
1491 | { | 1486 | { |
1492 | DBG("Unknown hardware (id %x) found at %x\n", | 1487 | DBG("Unknown hardware (id %x) found at %x\n", |
@@ -1495,10 +1490,10 @@ static int __devinit wbsd_scan(struct wbsd_host* host) | |||
1495 | 1490 | ||
1496 | outb(LOCK_CODE, config_ports[i]); | 1491 | outb(LOCK_CODE, config_ports[i]); |
1497 | } | 1492 | } |
1498 | 1493 | ||
1499 | release_region(config_ports[i], 2); | 1494 | release_region(config_ports[i], 2); |
1500 | } | 1495 | } |
1501 | 1496 | ||
1502 | return -ENODEV; | 1497 | return -ENODEV; |
1503 | } | 1498 | } |
1504 | 1499 | ||
@@ -1510,12 +1505,12 @@ static int __devinit wbsd_request_region(struct wbsd_host* host, int base) | |||
1510 | { | 1505 | { |
1511 | if (io & 0x7) | 1506 | if (io & 0x7) |
1512 | return -EINVAL; | 1507 | return -EINVAL; |
1513 | 1508 | ||
1514 | if (!request_region(base, 8, DRIVER_NAME)) | 1509 | if (!request_region(base, 8, DRIVER_NAME)) |
1515 | return -EIO; | 1510 | return -EIO; |
1516 | 1511 | ||
1517 | host->base = io; | 1512 | host->base = io; |
1518 | 1513 | ||
1519 | return 0; | 1514 | return 0; |
1520 | } | 1515 | } |
1521 | 1516 | ||
@@ -1523,12 +1518,12 @@ static void __devexit wbsd_release_regions(struct wbsd_host* host) | |||
1523 | { | 1518 | { |
1524 | if (host->base) | 1519 | if (host->base) |
1525 | release_region(host->base, 8); | 1520 | release_region(host->base, 8); |
1526 | 1521 | ||
1527 | host->base = 0; | 1522 | host->base = 0; |
1528 | 1523 | ||
1529 | if (host->config) | 1524 | if (host->config) |
1530 | release_region(host->config, 2); | 1525 | release_region(host->config, 2); |
1531 | 1526 | ||
1532 | host->config = 0; | 1527 | host->config = 0; |
1533 | } | 1528 | } |
1534 | 1529 | ||
@@ -1540,10 +1535,10 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) | |||
1540 | { | 1535 | { |
1541 | if (dma < 0) | 1536 | if (dma < 0) |
1542 | return; | 1537 | return; |
1543 | 1538 | ||
1544 | if (request_dma(dma, DRIVER_NAME)) | 1539 | if (request_dma(dma, DRIVER_NAME)) |
1545 | goto err; | 1540 | goto err; |
1546 | 1541 | ||
1547 | /* | 1542 | /* |
1548 | * We need to allocate a special buffer in | 1543 | * We need to allocate a special buffer in |
1549 | * order for ISA to be able to DMA to it. | 1544 | * order for ISA to be able to DMA to it. |
@@ -1558,7 +1553,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) | |||
1558 | */ | 1553 | */ |
1559 | host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer, | 1554 | host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer, |
1560 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); | 1555 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); |
1561 | 1556 | ||
1562 | /* | 1557 | /* |
1563 | * ISA DMA must be aligned on a 64k basis. | 1558 | * ISA DMA must be aligned on a 64k basis. |
1564 | */ | 1559 | */ |
@@ -1571,19 +1566,19 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) | |||
1571 | goto kfree; | 1566 | goto kfree; |
1572 | 1567 | ||
1573 | host->dma = dma; | 1568 | host->dma = dma; |
1574 | 1569 | ||
1575 | return; | 1570 | return; |
1576 | 1571 | ||
1577 | kfree: | 1572 | kfree: |
1578 | /* | 1573 | /* |
1579 | * If we've gotten here then there is some kind of alignment bug | 1574 | * If we've gotten here then there is some kind of alignment bug |
1580 | */ | 1575 | */ |
1581 | BUG_ON(1); | 1576 | BUG_ON(1); |
1582 | 1577 | ||
1583 | dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, | 1578 | dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, |
1584 | DMA_BIDIRECTIONAL); | 1579 | DMA_BIDIRECTIONAL); |
1585 | host->dma_addr = (dma_addr_t)NULL; | 1580 | host->dma_addr = (dma_addr_t)NULL; |
1586 | 1581 | ||
1587 | kfree(host->dma_buffer); | 1582 | kfree(host->dma_buffer); |
1588 | host->dma_buffer = NULL; | 1583 | host->dma_buffer = NULL; |
1589 | 1584 | ||
@@ -1604,7 +1599,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host) | |||
1604 | kfree(host->dma_buffer); | 1599 | kfree(host->dma_buffer); |
1605 | if (host->dma >= 0) | 1600 | if (host->dma >= 0) |
1606 | free_dma(host->dma); | 1601 | free_dma(host->dma); |
1607 | 1602 | ||
1608 | host->dma = -1; | 1603 | host->dma = -1; |
1609 | host->dma_buffer = NULL; | 1604 | host->dma_buffer = NULL; |
1610 | host->dma_addr = (dma_addr_t)NULL; | 1605 | host->dma_addr = (dma_addr_t)NULL; |
@@ -1617,7 +1612,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host) | |||
1617 | static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq) | 1612 | static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq) |
1618 | { | 1613 | { |
1619 | int ret; | 1614 | int ret; |
1620 | 1615 | ||
1621 | /* | 1616 | /* |
1622 | * Allocate interrupt. | 1617 | * Allocate interrupt. |
1623 | */ | 1618 | */ |
@@ -1625,7 +1620,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq) | |||
1625 | ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host); | 1620 | ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host); |
1626 | if (ret) | 1621 | if (ret) |
1627 | return ret; | 1622 | return ret; |
1628 | 1623 | ||
1629 | host->irq = irq; | 1624 | host->irq = irq; |
1630 | 1625 | ||
1631 | /* | 1626 | /* |
@@ -1637,7 +1632,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq) | |||
1637 | tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host); | 1632 | tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host); |
1638 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); | 1633 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); |
1639 | tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host); | 1634 | tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host); |
1640 | 1635 | ||
1641 | return 0; | 1636 | return 0; |
1642 | } | 1637 | } |
1643 | 1638 | ||
@@ -1647,9 +1642,9 @@ static void __devexit wbsd_release_irq(struct wbsd_host* host) | |||
1647 | return; | 1642 | return; |
1648 | 1643 | ||
1649 | free_irq(host->irq, host); | 1644 | free_irq(host->irq, host); |
1650 | 1645 | ||
1651 | host->irq = 0; | 1646 | host->irq = 0; |
1652 | 1647 | ||
1653 | tasklet_kill(&host->card_tasklet); | 1648 | tasklet_kill(&host->card_tasklet); |
1654 | tasklet_kill(&host->fifo_tasklet); | 1649 | tasklet_kill(&host->fifo_tasklet); |
1655 | tasklet_kill(&host->crc_tasklet); | 1650 | tasklet_kill(&host->crc_tasklet); |
@@ -1666,7 +1661,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host, | |||
1666 | int base, int irq, int dma) | 1661 | int base, int irq, int dma) |
1667 | { | 1662 | { |
1668 | int ret; | 1663 | int ret; |
1669 | 1664 | ||
1670 | /* | 1665 | /* |
1671 | * Allocate I/O ports. | 1666 | * Allocate I/O ports. |
1672 | */ | 1667 | */ |
@@ -1685,7 +1680,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host, | |||
1685 | * Allocate DMA. | 1680 | * Allocate DMA. |
1686 | */ | 1681 | */ |
1687 | wbsd_request_dma(host, dma); | 1682 | wbsd_request_dma(host, dma); |
1688 | 1683 | ||
1689 | return 0; | 1684 | return 0; |
1690 | } | 1685 | } |
1691 | 1686 | ||
@@ -1708,7 +1703,7 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host) | |||
1708 | { | 1703 | { |
1709 | /* | 1704 | /* |
1710 | * Reset the chip. | 1705 | * Reset the chip. |
1711 | */ | 1706 | */ |
1712 | wbsd_write_config(host, WBSD_CONF_SWRST, 1); | 1707 | wbsd_write_config(host, WBSD_CONF_SWRST, 1); |
1713 | wbsd_write_config(host, WBSD_CONF_SWRST, 0); | 1708 | wbsd_write_config(host, WBSD_CONF_SWRST, 0); |
1714 | 1709 | ||
@@ -1716,23 +1711,23 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host) | |||
1716 | * Select SD/MMC function. | 1711 | * Select SD/MMC function. |
1717 | */ | 1712 | */ |
1718 | wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); | 1713 | wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); |
1719 | 1714 | ||
1720 | /* | 1715 | /* |
1721 | * Set up card detection. | 1716 | * Set up card detection. |
1722 | */ | 1717 | */ |
1723 | wbsd_write_config(host, WBSD_CONF_PINS, WBSD_PINS_DETECT_GP11); | 1718 | wbsd_write_config(host, WBSD_CONF_PINS, WBSD_PINS_DETECT_GP11); |
1724 | 1719 | ||
1725 | /* | 1720 | /* |
1726 | * Configure chip | 1721 | * Configure chip |
1727 | */ | 1722 | */ |
1728 | wbsd_write_config(host, WBSD_CONF_PORT_HI, host->base >> 8); | 1723 | wbsd_write_config(host, WBSD_CONF_PORT_HI, host->base >> 8); |
1729 | wbsd_write_config(host, WBSD_CONF_PORT_LO, host->base & 0xff); | 1724 | wbsd_write_config(host, WBSD_CONF_PORT_LO, host->base & 0xff); |
1730 | 1725 | ||
1731 | wbsd_write_config(host, WBSD_CONF_IRQ, host->irq); | 1726 | wbsd_write_config(host, WBSD_CONF_IRQ, host->irq); |
1732 | 1727 | ||
1733 | if (host->dma >= 0) | 1728 | if (host->dma >= 0) |
1734 | wbsd_write_config(host, WBSD_CONF_DRQ, host->dma); | 1729 | wbsd_write_config(host, WBSD_CONF_DRQ, host->dma); |
1735 | 1730 | ||
1736 | /* | 1731 | /* |
1737 | * Enable and power up chip. | 1732 | * Enable and power up chip. |
1738 | */ | 1733 | */ |
@@ -1743,26 +1738,26 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host) | |||
1743 | /* | 1738 | /* |
1744 | * Check that configured resources are correct. | 1739 | * Check that configured resources are correct. |
1745 | */ | 1740 | */ |
1746 | 1741 | ||
1747 | static int __devinit wbsd_chip_validate(struct wbsd_host* host) | 1742 | static int __devinit wbsd_chip_validate(struct wbsd_host* host) |
1748 | { | 1743 | { |
1749 | int base, irq, dma; | 1744 | int base, irq, dma; |
1750 | 1745 | ||
1751 | /* | 1746 | /* |
1752 | * Select SD/MMC function. | 1747 | * Select SD/MMC function. |
1753 | */ | 1748 | */ |
1754 | wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); | 1749 | wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); |
1755 | 1750 | ||
1756 | /* | 1751 | /* |
1757 | * Read configuration. | 1752 | * Read configuration. |
1758 | */ | 1753 | */ |
1759 | base = wbsd_read_config(host, WBSD_CONF_PORT_HI) << 8; | 1754 | base = wbsd_read_config(host, WBSD_CONF_PORT_HI) << 8; |
1760 | base |= wbsd_read_config(host, WBSD_CONF_PORT_LO); | 1755 | base |= wbsd_read_config(host, WBSD_CONF_PORT_LO); |
1761 | 1756 | ||
1762 | irq = wbsd_read_config(host, WBSD_CONF_IRQ); | 1757 | irq = wbsd_read_config(host, WBSD_CONF_IRQ); |
1763 | 1758 | ||
1764 | dma = wbsd_read_config(host, WBSD_CONF_DRQ); | 1759 | dma = wbsd_read_config(host, WBSD_CONF_DRQ); |
1765 | 1760 | ||
1766 | /* | 1761 | /* |
1767 | * Validate against given configuration. | 1762 | * Validate against given configuration. |
1768 | */ | 1763 | */ |
@@ -1772,7 +1767,7 @@ static int __devinit wbsd_chip_validate(struct wbsd_host* host) | |||
1772 | return 0; | 1767 | return 0; |
1773 | if ((dma != host->dma) && (host->dma != -1)) | 1768 | if ((dma != host->dma) && (host->dma != -1)) |
1774 | return 0; | 1769 | return 0; |
1775 | 1770 | ||
1776 | return 1; | 1771 | return 1; |
1777 | } | 1772 | } |
1778 | 1773 | ||
@@ -1788,14 +1783,14 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | |||
1788 | struct wbsd_host* host = NULL; | 1783 | struct wbsd_host* host = NULL; |
1789 | struct mmc_host* mmc = NULL; | 1784 | struct mmc_host* mmc = NULL; |
1790 | int ret; | 1785 | int ret; |
1791 | 1786 | ||
1792 | ret = wbsd_alloc_mmc(dev); | 1787 | ret = wbsd_alloc_mmc(dev); |
1793 | if (ret) | 1788 | if (ret) |
1794 | return ret; | 1789 | return ret; |
1795 | 1790 | ||
1796 | mmc = dev_get_drvdata(dev); | 1791 | mmc = dev_get_drvdata(dev); |
1797 | host = mmc_priv(mmc); | 1792 | host = mmc_priv(mmc); |
1798 | 1793 | ||
1799 | /* | 1794 | /* |
1800 | * Scan for hardware. | 1795 | * Scan for hardware. |
1801 | */ | 1796 | */ |
@@ -1814,7 +1809,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | |||
1814 | return ret; | 1809 | return ret; |
1815 | } | 1810 | } |
1816 | } | 1811 | } |
1817 | 1812 | ||
1818 | /* | 1813 | /* |
1819 | * Request resources. | 1814 | * Request resources. |
1820 | */ | 1815 | */ |
@@ -1825,7 +1820,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | |||
1825 | wbsd_free_mmc(dev); | 1820 | wbsd_free_mmc(dev); |
1826 | return ret; | 1821 | return ret; |
1827 | } | 1822 | } |
1828 | 1823 | ||
1829 | /* | 1824 | /* |
1830 | * See if chip needs to be configured. | 1825 | * See if chip needs to be configured. |
1831 | */ | 1826 | */ |
@@ -1842,7 +1837,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | |||
1842 | } | 1837 | } |
1843 | else | 1838 | else |
1844 | wbsd_chip_config(host); | 1839 | wbsd_chip_config(host); |
1845 | 1840 | ||
1846 | /* | 1841 | /* |
1847 | * Power Management stuff. No idea how this works. | 1842 | * Power Management stuff. No idea how this works. |
1848 | * Not tested. | 1843 | * Not tested. |
@@ -1860,7 +1855,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | |||
1860 | * Reset the chip into a known state. | 1855 | * Reset the chip into a known state. |
1861 | */ | 1856 | */ |
1862 | wbsd_init_device(host); | 1857 | wbsd_init_device(host); |
1863 | 1858 | ||
1864 | mmc_add_host(mmc); | 1859 | mmc_add_host(mmc); |
1865 | 1860 | ||
1866 | printk(KERN_INFO "%s: W83L51xD", mmc_hostname(mmc)); | 1861 | printk(KERN_INFO "%s: W83L51xD", mmc_hostname(mmc)); |
@@ -1882,12 +1877,12 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp) | |||
1882 | { | 1877 | { |
1883 | struct mmc_host* mmc = dev_get_drvdata(dev); | 1878 | struct mmc_host* mmc = dev_get_drvdata(dev); |
1884 | struct wbsd_host* host; | 1879 | struct wbsd_host* host; |
1885 | 1880 | ||
1886 | if (!mmc) | 1881 | if (!mmc) |
1887 | return; | 1882 | return; |
1888 | 1883 | ||
1889 | host = mmc_priv(mmc); | 1884 | host = mmc_priv(mmc); |
1890 | 1885 | ||
1891 | mmc_remove_host(mmc); | 1886 | mmc_remove_host(mmc); |
1892 | 1887 | ||
1893 | if (!pnp) | 1888 | if (!pnp) |
@@ -1900,9 +1895,9 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp) | |||
1900 | wbsd_write_config(host, WBSD_CONF_ENABLE, 0); | 1895 | wbsd_write_config(host, WBSD_CONF_ENABLE, 0); |
1901 | wbsd_lock_config(host); | 1896 | wbsd_lock_config(host); |
1902 | } | 1897 | } |
1903 | 1898 | ||
1904 | wbsd_release_resources(host); | 1899 | wbsd_release_resources(host); |
1905 | 1900 | ||
1906 | wbsd_free_mmc(dev); | 1901 | wbsd_free_mmc(dev); |
1907 | } | 1902 | } |
1908 | 1903 | ||
@@ -1932,7 +1927,7 @@ static int __devinit | |||
1932 | wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id) | 1927 | wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id) |
1933 | { | 1928 | { |
1934 | int io, irq, dma; | 1929 | int io, irq, dma; |
1935 | 1930 | ||
1936 | /* | 1931 | /* |
1937 | * Get resources from PnP layer. | 1932 | * Get resources from PnP layer. |
1938 | */ | 1933 | */ |
@@ -1942,9 +1937,9 @@ wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id) | |||
1942 | dma = pnp_dma(pnpdev, 0); | 1937 | dma = pnp_dma(pnpdev, 0); |
1943 | else | 1938 | else |
1944 | dma = -1; | 1939 | dma = -1; |
1945 | 1940 | ||
1946 | DBGF("PnP resources: port %3x irq %d dma %d\n", io, irq, dma); | 1941 | DBGF("PnP resources: port %3x irq %d dma %d\n", io, irq, dma); |
1947 | 1942 | ||
1948 | return wbsd_init(&pnpdev->dev, io, irq, dma, 1); | 1943 | return wbsd_init(&pnpdev->dev, io, irq, dma, 1); |
1949 | } | 1944 | } |
1950 | 1945 | ||
@@ -1985,7 +1980,7 @@ static struct device_driver wbsd_driver = { | |||
1985 | .bus = &platform_bus_type, | 1980 | .bus = &platform_bus_type, |
1986 | .probe = wbsd_probe, | 1981 | .probe = wbsd_probe, |
1987 | .remove = wbsd_remove, | 1982 | .remove = wbsd_remove, |
1988 | 1983 | ||
1989 | .suspend = wbsd_suspend, | 1984 | .suspend = wbsd_suspend, |
1990 | .resume = wbsd_resume, | 1985 | .resume = wbsd_resume, |
1991 | }; | 1986 | }; |
@@ -2008,7 +2003,7 @@ static struct pnp_driver wbsd_pnp_driver = { | |||
2008 | static int __init wbsd_drv_init(void) | 2003 | static int __init wbsd_drv_init(void) |
2009 | { | 2004 | { |
2010 | int result; | 2005 | int result; |
2011 | 2006 | ||
2012 | printk(KERN_INFO DRIVER_NAME | 2007 | printk(KERN_INFO DRIVER_NAME |
2013 | ": Winbond W83L51xD SD/MMC card interface driver, " | 2008 | ": Winbond W83L51xD SD/MMC card interface driver, " |
2014 | DRIVER_VERSION "\n"); | 2009 | DRIVER_VERSION "\n"); |
@@ -2023,8 +2018,8 @@ static int __init wbsd_drv_init(void) | |||
2023 | return result; | 2018 | return result; |
2024 | } | 2019 | } |
2025 | 2020 | ||
2026 | #endif /* CONFIG_PNP */ | 2021 | #endif /* CONFIG_PNP */ |
2027 | 2022 | ||
2028 | if (nopnp) | 2023 | if (nopnp) |
2029 | { | 2024 | { |
2030 | result = driver_register(&wbsd_driver); | 2025 | result = driver_register(&wbsd_driver); |
@@ -2046,13 +2041,13 @@ static void __exit wbsd_drv_exit(void) | |||
2046 | 2041 | ||
2047 | if (!nopnp) | 2042 | if (!nopnp) |
2048 | pnp_unregister_driver(&wbsd_pnp_driver); | 2043 | pnp_unregister_driver(&wbsd_pnp_driver); |
2049 | 2044 | ||
2050 | #endif /* CONFIG_PNP */ | 2045 | #endif /* CONFIG_PNP */ |
2051 | 2046 | ||
2052 | if (nopnp) | 2047 | if (nopnp) |
2053 | { | 2048 | { |
2054 | platform_device_unregister(wbsd_device); | 2049 | platform_device_unregister(wbsd_device); |
2055 | 2050 | ||
2056 | driver_unregister(&wbsd_driver); | 2051 | driver_unregister(&wbsd_driver); |
2057 | } | 2052 | } |
2058 | 2053 | ||
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h index 9005b5241b3c..249baa701cb0 100644 --- a/drivers/mmc/wbsd.h +++ b/drivers/mmc/wbsd.h | |||
@@ -139,51 +139,50 @@ | |||
139 | struct wbsd_host | 139 | struct wbsd_host |
140 | { | 140 | { |
141 | struct mmc_host* mmc; /* MMC structure */ | 141 | struct mmc_host* mmc; /* MMC structure */ |
142 | 142 | ||
143 | spinlock_t lock; /* Mutex */ | 143 | spinlock_t lock; /* Mutex */ |
144 | 144 | ||
145 | int flags; /* Driver states */ | 145 | int flags; /* Driver states */ |
146 | 146 | ||
147 | #define WBSD_FCARD_PRESENT (1<<0) /* Card is present */ | 147 | #define WBSD_FCARD_PRESENT (1<<0) /* Card is present */ |
148 | #define WBSD_FIGNORE_DETECT (1<<1) /* Ignore card detection */ | 148 | #define WBSD_FIGNORE_DETECT (1<<1) /* Ignore card detection */ |
149 | 149 | ||
150 | struct mmc_request* mrq; /* Current request */ | 150 | struct mmc_request* mrq; /* Current request */ |
151 | 151 | ||
152 | u8 isr; /* Accumulated ISR */ | 152 | u8 isr; /* Accumulated ISR */ |
153 | 153 | ||
154 | struct scatterlist* cur_sg; /* Current SG entry */ | 154 | struct scatterlist* cur_sg; /* Current SG entry */ |
155 | unsigned int num_sg; /* Number of entries left */ | 155 | unsigned int num_sg; /* Number of entries left */ |
156 | void* mapped_sg; /* vaddr of mapped sg */ | 156 | void* mapped_sg; /* vaddr of mapped sg */ |
157 | 157 | ||
158 | unsigned int offset; /* Offset into current entry */ | 158 | unsigned int offset; /* Offset into current entry */ |
159 | unsigned int remain; /* Data left in curren entry */ | 159 | unsigned int remain; /* Data left in curren entry */ |
160 | 160 | ||
161 | int size; /* Total size of transfer */ | 161 | int size; /* Total size of transfer */ |
162 | 162 | ||
163 | char* dma_buffer; /* ISA DMA buffer */ | 163 | char* dma_buffer; /* ISA DMA buffer */ |
164 | dma_addr_t dma_addr; /* Physical address for same */ | 164 | dma_addr_t dma_addr; /* Physical address for same */ |
165 | 165 | ||
166 | int firsterr; /* See fifo functions */ | 166 | int firsterr; /* See fifo functions */ |
167 | 167 | ||
168 | u8 clk; /* Current clock speed */ | 168 | u8 clk; /* Current clock speed */ |
169 | unsigned char bus_width; /* Current bus width */ | 169 | unsigned char bus_width; /* Current bus width */ |
170 | 170 | ||
171 | int config; /* Config port */ | 171 | int config; /* Config port */ |
172 | u8 unlock_code; /* Code to unlock config */ | 172 | u8 unlock_code; /* Code to unlock config */ |
173 | 173 | ||
174 | int chip_id; /* ID of controller */ | 174 | int chip_id; /* ID of controller */ |
175 | 175 | ||
176 | int base; /* I/O port base */ | 176 | int base; /* I/O port base */ |
177 | int irq; /* Interrupt */ | 177 | int irq; /* Interrupt */ |
178 | int dma; /* DMA channel */ | 178 | int dma; /* DMA channel */ |
179 | 179 | ||
180 | struct tasklet_struct card_tasklet; /* Tasklet structures */ | 180 | struct tasklet_struct card_tasklet; /* Tasklet structures */ |
181 | struct tasklet_struct fifo_tasklet; | 181 | struct tasklet_struct fifo_tasklet; |
182 | struct tasklet_struct crc_tasklet; | 182 | struct tasklet_struct crc_tasklet; |
183 | struct tasklet_struct timeout_tasklet; | 183 | struct tasklet_struct timeout_tasklet; |
184 | struct tasklet_struct finish_tasklet; | 184 | struct tasklet_struct finish_tasklet; |
185 | struct tasklet_struct block_tasklet; | 185 | struct tasklet_struct block_tasklet; |
186 | 186 | ||
187 | struct timer_list detect_timer; /* Card detection timer */ | ||
188 | struct timer_list ignore_timer; /* Ignore detection timer */ | 187 | struct timer_list ignore_timer; /* Ignore detection timer */ |
189 | }; | 188 | }; |