diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 18:08:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 18:08:33 -0500 |
commit | 8e9c238c3884c226f0cddc31cde87dd5df1a6500 (patch) | |
tree | d6b4bb2f474580fd6f52e70447f8ed79d441a89d /drivers | |
parent | f17578decc40df8fceff82b106582e30bdfb3189 (diff) | |
parent | 7225b3fd0b6e224235fc50a69f70479ff96d5602 (diff) |
Merge master.kernel.org:/home/rmk/linux-2.6-mmc
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/mmc.c | 1 | ||||
-rw-r--r-- | drivers/mmc/mmc_block.c | 8 | ||||
-rw-r--r-- | drivers/mmc/wbsd.c | 533 |
3 files changed, 278 insertions, 264 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6696f71363b9..bfca5c176e88 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
@@ -495,6 +495,7 @@ static void mmc_decode_cid(struct mmc_card *card) | |||
495 | 495 | ||
496 | case 2: /* MMC v2.0 - v2.2 */ | 496 | case 2: /* MMC v2.0 - v2.2 */ |
497 | case 3: /* MMC v3.1 - v3.3 */ | 497 | case 3: /* MMC v3.1 - v3.3 */ |
498 | case 4: /* MMC v4 */ | ||
498 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | 499 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); |
499 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | 500 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); |
500 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | 501 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index d5f28981596b..f2c42b13945d 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
@@ -187,7 +187,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
187 | brq.data.flags |= MMC_DATA_WRITE; | 187 | brq.data.flags |= MMC_DATA_WRITE; |
188 | brq.data.blocks = 1; | 188 | brq.data.blocks = 1; |
189 | } | 189 | } |
190 | brq.mrq.stop = brq.data.blocks > 1 ? &brq.stop : NULL; | 190 | |
191 | if (brq.data.blocks > 1) { | ||
192 | brq.data.flags |= MMC_DATA_MULTI; | ||
193 | brq.mrq.stop = &brq.stop; | ||
194 | } else { | ||
195 | brq.mrq.stop = NULL; | ||
196 | } | ||
191 | 197 | ||
192 | brq.data.sg = mq->sg; | 198 | brq.data.sg = mq->sg; |
193 | brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg); | 199 | brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg); |
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 4f13bd2ccf9a..f25757625361 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
@@ -90,7 +90,7 @@ static int dma = 2; | |||
90 | * Basic functions | 90 | * Basic functions |
91 | */ | 91 | */ |
92 | 92 | ||
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 | ||
@@ -98,14 +98,14 @@ static inline void wbsd_unlock_config(struct wbsd_host* host) | |||
98 | outb(host->unlock_code, host->config); | 98 | outb(host->unlock_code, host->config); |
99 | } | 99 | } |
100 | 100 | ||
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 | ||
@@ -113,7 +113,7 @@ static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value) | |||
113 | outb(value, host->config + 1); | 113 | outb(value, host->config + 1); |
114 | } | 114 | } |
115 | 115 | ||
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 | ||
@@ -121,13 +121,13 @@ static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg) | |||
121 | return inb(host->config + 1); | 121 | return inb(host->config + 1); |
122 | } | 122 | } |
123 | 123 | ||
124 | static inline void wbsd_write_index(struct wbsd_host* host, u8 index, u8 value) | 124 | static inline void wbsd_write_index(struct wbsd_host *host, u8 index, u8 value) |
125 | { | 125 | { |
126 | outb(index, host->base + WBSD_IDXR); | 126 | outb(index, host->base + WBSD_IDXR); |
127 | outb(value, host->base + WBSD_DATAR); | 127 | outb(value, host->base + WBSD_DATAR); |
128 | } | 128 | } |
129 | 129 | ||
130 | static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index) | 130 | static inline u8 wbsd_read_index(struct wbsd_host *host, u8 index) |
131 | { | 131 | { |
132 | outb(index, host->base + WBSD_IDXR); | 132 | outb(index, host->base + WBSD_IDXR); |
133 | return inb(host->base + WBSD_DATAR); | 133 | return inb(host->base + WBSD_DATAR); |
@@ -137,7 +137,7 @@ static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index) | |||
137 | * Common routines | 137 | * Common routines |
138 | */ | 138 | */ |
139 | 139 | ||
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 | ||
@@ -197,7 +197,7 @@ static void wbsd_init_device(struct wbsd_host* host) | |||
197 | inb(host->base + WBSD_ISR); | 197 | inb(host->base + WBSD_ISR); |
198 | } | 198 | } |
199 | 199 | ||
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 | ||
@@ -211,14 +211,13 @@ static void wbsd_reset(struct wbsd_host* host) | |||
211 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | 211 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); |
212 | } | 212 | } |
213 | 213 | ||
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 | { | ||
222 | /* | 221 | /* |
223 | * Release ISA DMA controller. | 222 | * Release ISA DMA controller. |
224 | */ | 223 | */ |
@@ -247,7 +246,7 @@ static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq) | |||
247 | * Scatter/gather functions | 246 | * Scatter/gather functions |
248 | */ | 247 | */ |
249 | 248 | ||
250 | static inline void wbsd_init_sg(struct wbsd_host* host, struct mmc_data* data) | 249 | static inline void wbsd_init_sg(struct wbsd_host *host, struct mmc_data *data) |
251 | { | 250 | { |
252 | /* | 251 | /* |
253 | * Get info. about SG list from data structure. | 252 | * Get info. about SG list from data structure. |
@@ -259,7 +258,7 @@ static inline void wbsd_init_sg(struct wbsd_host* host, struct mmc_data* data) | |||
259 | host->remain = host->cur_sg->length; | 258 | host->remain = host->cur_sg->length; |
260 | } | 259 | } |
261 | 260 | ||
262 | static inline int wbsd_next_sg(struct wbsd_host* host) | 261 | static inline int wbsd_next_sg(struct wbsd_host *host) |
263 | { | 262 | { |
264 | /* | 263 | /* |
265 | * Skip to next SG entry. | 264 | * Skip to next SG entry. |
@@ -270,33 +269,32 @@ static inline int wbsd_next_sg(struct wbsd_host* host) | |||
270 | /* | 269 | /* |
271 | * Any entries left? | 270 | * Any entries left? |
272 | */ | 271 | */ |
273 | if (host->num_sg > 0) | 272 | if (host->num_sg > 0) { |
274 | { | 273 | host->offset = 0; |
275 | host->offset = 0; | 274 | host->remain = host->cur_sg->length; |
276 | host->remain = host->cur_sg->length; | 275 | } |
277 | } | ||
278 | 276 | ||
279 | return host->num_sg; | 277 | return host->num_sg; |
280 | } | 278 | } |
281 | 279 | ||
282 | static inline char* wbsd_kmap_sg(struct wbsd_host* host) | 280 | static inline char *wbsd_kmap_sg(struct wbsd_host *host) |
283 | { | 281 | { |
284 | host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) + | 282 | host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) + |
285 | host->cur_sg->offset; | 283 | host->cur_sg->offset; |
286 | return host->mapped_sg; | 284 | return host->mapped_sg; |
287 | } | 285 | } |
288 | 286 | ||
289 | static inline void wbsd_kunmap_sg(struct wbsd_host* host) | 287 | static inline void wbsd_kunmap_sg(struct wbsd_host *host) |
290 | { | 288 | { |
291 | kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ); | 289 | kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ); |
292 | } | 290 | } |
293 | 291 | ||
294 | static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data) | 292 | static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) |
295 | { | 293 | { |
296 | unsigned int len, i, size; | 294 | unsigned int len, i, size; |
297 | struct scatterlist* sg; | 295 | struct scatterlist *sg; |
298 | char* dmabuf = host->dma_buffer; | 296 | char *dmabuf = host->dma_buffer; |
299 | char* sgbuf; | 297 | char *sgbuf; |
300 | 298 | ||
301 | size = host->size; | 299 | size = host->size; |
302 | 300 | ||
@@ -308,8 +306,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data) | |||
308 | * be the entire list though so make sure that | 306 | * be the entire list though so make sure that |
309 | * we do not transfer too much. | 307 | * we do not transfer too much. |
310 | */ | 308 | */ |
311 | for (i = 0;i < len;i++) | 309 | for (i = 0; i < len; i++) { |
312 | { | ||
313 | sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; | 310 | sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; |
314 | if (size < sg[i].length) | 311 | if (size < sg[i].length) |
315 | memcpy(dmabuf, sgbuf, size); | 312 | memcpy(dmabuf, sgbuf, size); |
@@ -337,12 +334,12 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data) | |||
337 | host->size -= size; | 334 | host->size -= size; |
338 | } | 335 | } |
339 | 336 | ||
340 | static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data) | 337 | static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) |
341 | { | 338 | { |
342 | unsigned int len, i, size; | 339 | unsigned int len, i, size; |
343 | struct scatterlist* sg; | 340 | struct scatterlist *sg; |
344 | char* dmabuf = host->dma_buffer; | 341 | char *dmabuf = host->dma_buffer; |
345 | char* sgbuf; | 342 | char *sgbuf; |
346 | 343 | ||
347 | size = host->size; | 344 | size = host->size; |
348 | 345 | ||
@@ -354,8 +351,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data) | |||
354 | * be the entire list though so make sure that | 351 | * be the entire list though so make sure that |
355 | * we do not transfer too much. | 352 | * we do not transfer too much. |
356 | */ | 353 | */ |
357 | for (i = 0;i < len;i++) | 354 | for (i = 0; i < len; i++) { |
358 | { | ||
359 | sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; | 355 | sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; |
360 | if (size < sg[i].length) | 356 | if (size < sg[i].length) |
361 | memcpy(sgbuf, dmabuf, size); | 357 | memcpy(sgbuf, dmabuf, size); |
@@ -387,46 +383,38 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data) | |||
387 | * Command handling | 383 | * Command handling |
388 | */ | 384 | */ |
389 | 385 | ||
390 | static inline void wbsd_get_short_reply(struct wbsd_host* host, | 386 | static inline void wbsd_get_short_reply(struct wbsd_host *host, |
391 | struct mmc_command* cmd) | 387 | struct mmc_command *cmd) |
392 | { | 388 | { |
393 | /* | 389 | /* |
394 | * Correct response type? | 390 | * Correct response type? |
395 | */ | 391 | */ |
396 | if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) | 392 | if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) { |
397 | { | ||
398 | cmd->error = MMC_ERR_INVALID; | 393 | cmd->error = MMC_ERR_INVALID; |
399 | return; | 394 | return; |
400 | } | 395 | } |
401 | 396 | ||
402 | cmd->resp[0] = | 397 | cmd->resp[0] = wbsd_read_index(host, WBSD_IDX_RESP12) << 24; |
403 | wbsd_read_index(host, WBSD_IDX_RESP12) << 24; | 398 | cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP13) << 16; |
404 | cmd->resp[0] |= | 399 | cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP14) << 8; |
405 | wbsd_read_index(host, WBSD_IDX_RESP13) << 16; | 400 | cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP15) << 0; |
406 | cmd->resp[0] |= | 401 | cmd->resp[1] = wbsd_read_index(host, WBSD_IDX_RESP16) << 24; |
407 | wbsd_read_index(host, WBSD_IDX_RESP14) << 8; | ||
408 | cmd->resp[0] |= | ||
409 | wbsd_read_index(host, WBSD_IDX_RESP15) << 0; | ||
410 | cmd->resp[1] = | ||
411 | wbsd_read_index(host, WBSD_IDX_RESP16) << 24; | ||
412 | } | 402 | } |
413 | 403 | ||
414 | static inline void wbsd_get_long_reply(struct wbsd_host* host, | 404 | static inline void wbsd_get_long_reply(struct wbsd_host *host, |
415 | struct mmc_command* cmd) | 405 | struct mmc_command *cmd) |
416 | { | 406 | { |
417 | int i; | 407 | int i; |
418 | 408 | ||
419 | /* | 409 | /* |
420 | * Correct response type? | 410 | * Correct response type? |
421 | */ | 411 | */ |
422 | if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) | 412 | if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) { |
423 | { | ||
424 | cmd->error = MMC_ERR_INVALID; | 413 | cmd->error = MMC_ERR_INVALID; |
425 | return; | 414 | return; |
426 | } | 415 | } |
427 | 416 | ||
428 | for (i = 0;i < 4;i++) | 417 | for (i = 0; i < 4; i++) { |
429 | { | ||
430 | cmd->resp[i] = | 418 | cmd->resp[i] = |
431 | wbsd_read_index(host, WBSD_IDX_RESP1 + i * 4) << 24; | 419 | wbsd_read_index(host, WBSD_IDX_RESP1 + i * 4) << 24; |
432 | cmd->resp[i] |= | 420 | cmd->resp[i] |= |
@@ -438,7 +426,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host, | |||
438 | } | 426 | } |
439 | } | 427 | } |
440 | 428 | ||
441 | static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) | 429 | static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) |
442 | { | 430 | { |
443 | int i; | 431 | int i; |
444 | u8 status, isr; | 432 | u8 status, isr; |
@@ -456,7 +444,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) | |||
456 | * Send the command (CRC calculated by host). | 444 | * Send the command (CRC calculated by host). |
457 | */ | 445 | */ |
458 | outb(cmd->opcode, host->base + WBSD_CMDR); | 446 | outb(cmd->opcode, host->base + WBSD_CMDR); |
459 | for (i = 3;i >= 0;i--) | 447 | for (i = 3; i >= 0; i--) |
460 | outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR); | 448 | outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR); |
461 | 449 | ||
462 | cmd->error = MMC_ERR_NONE; | 450 | cmd->error = MMC_ERR_NONE; |
@@ -471,8 +459,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) | |||
471 | /* | 459 | /* |
472 | * Do we expect a reply? | 460 | * Do we expect a reply? |
473 | */ | 461 | */ |
474 | if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) | 462 | if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) { |
475 | { | ||
476 | /* | 463 | /* |
477 | * Read back status. | 464 | * Read back status. |
478 | */ | 465 | */ |
@@ -488,8 +475,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) | |||
488 | else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC)) | 475 | else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC)) |
489 | cmd->error = MMC_ERR_BADCRC; | 476 | cmd->error = MMC_ERR_BADCRC; |
490 | /* All ok */ | 477 | /* All ok */ |
491 | else | 478 | else { |
492 | { | ||
493 | if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) | 479 | if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) |
494 | wbsd_get_short_reply(host, cmd); | 480 | wbsd_get_short_reply(host, cmd); |
495 | else | 481 | else |
@@ -504,10 +490,10 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) | |||
504 | * Data functions | 490 | * Data functions |
505 | */ | 491 | */ |
506 | 492 | ||
507 | static void wbsd_empty_fifo(struct wbsd_host* host) | 493 | static void wbsd_empty_fifo(struct wbsd_host *host) |
508 | { | 494 | { |
509 | struct mmc_data* data = host->mrq->cmd->data; | 495 | struct mmc_data *data = host->mrq->cmd->data; |
510 | char* buffer; | 496 | char *buffer; |
511 | int i, fsr, fifo; | 497 | int i, fsr, fifo; |
512 | 498 | ||
513 | /* | 499 | /* |
@@ -522,8 +508,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host) | |||
522 | * Drain the fifo. This has a tendency to loop longer | 508 | * Drain the fifo. This has a tendency to loop longer |
523 | * than the FIFO length (usually one block). | 509 | * than the FIFO length (usually one block). |
524 | */ | 510 | */ |
525 | while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY)) | 511 | while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY)) { |
526 | { | ||
527 | /* | 512 | /* |
528 | * The size field in the FSR is broken so we have to | 513 | * The size field in the FSR is broken so we have to |
529 | * do some guessing. | 514 | * do some guessing. |
@@ -535,8 +520,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host) | |||
535 | else | 520 | else |
536 | fifo = 1; | 521 | fifo = 1; |
537 | 522 | ||
538 | for (i = 0;i < fifo;i++) | 523 | for (i = 0; i < fifo; i++) { |
539 | { | ||
540 | *buffer = inb(host->base + WBSD_DFR); | 524 | *buffer = inb(host->base + WBSD_DFR); |
541 | buffer++; | 525 | buffer++; |
542 | host->offset++; | 526 | host->offset++; |
@@ -547,8 +531,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host) | |||
547 | /* | 531 | /* |
548 | * Transfer done? | 532 | * Transfer done? |
549 | */ | 533 | */ |
550 | if (data->bytes_xfered == host->size) | 534 | if (data->bytes_xfered == host->size) { |
551 | { | ||
552 | wbsd_kunmap_sg(host); | 535 | wbsd_kunmap_sg(host); |
553 | return; | 536 | return; |
554 | } | 537 | } |
@@ -556,15 +539,13 @@ static void wbsd_empty_fifo(struct wbsd_host* host) | |||
556 | /* | 539 | /* |
557 | * End of scatter list entry? | 540 | * End of scatter list entry? |
558 | */ | 541 | */ |
559 | if (host->remain == 0) | 542 | if (host->remain == 0) { |
560 | { | ||
561 | wbsd_kunmap_sg(host); | 543 | wbsd_kunmap_sg(host); |
562 | 544 | ||
563 | /* | 545 | /* |
564 | * Get next entry. Check if last. | 546 | * Get next entry. Check if last. |
565 | */ | 547 | */ |
566 | if (!wbsd_next_sg(host)) | 548 | if (!wbsd_next_sg(host)) { |
567 | { | ||
568 | /* | 549 | /* |
569 | * We should never reach this point. | 550 | * We should never reach this point. |
570 | * It means that we're trying to | 551 | * It means that we're trying to |
@@ -594,10 +575,10 @@ static void wbsd_empty_fifo(struct wbsd_host* host) | |||
594 | tasklet_schedule(&host->fifo_tasklet); | 575 | tasklet_schedule(&host->fifo_tasklet); |
595 | } | 576 | } |
596 | 577 | ||
597 | static void wbsd_fill_fifo(struct wbsd_host* host) | 578 | static void wbsd_fill_fifo(struct wbsd_host *host) |
598 | { | 579 | { |
599 | struct mmc_data* data = host->mrq->cmd->data; | 580 | struct mmc_data *data = host->mrq->cmd->data; |
600 | char* buffer; | 581 | char *buffer; |
601 | int i, fsr, fifo; | 582 | int i, fsr, fifo; |
602 | 583 | ||
603 | /* | 584 | /* |
@@ -613,8 +594,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
613 | * Fill the fifo. This has a tendency to loop longer | 594 | * Fill the fifo. This has a tendency to loop longer |
614 | * than the FIFO length (usually one block). | 595 | * than the FIFO length (usually one block). |
615 | */ | 596 | */ |
616 | while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL)) | 597 | while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL)) { |
617 | { | ||
618 | /* | 598 | /* |
619 | * The size field in the FSR is broken so we have to | 599 | * The size field in the FSR is broken so we have to |
620 | * do some guessing. | 600 | * do some guessing. |
@@ -626,8 +606,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
626 | else | 606 | else |
627 | fifo = 15; | 607 | fifo = 15; |
628 | 608 | ||
629 | for (i = 16;i > fifo;i--) | 609 | for (i = 16; i > fifo; i--) { |
630 | { | ||
631 | outb(*buffer, host->base + WBSD_DFR); | 610 | outb(*buffer, host->base + WBSD_DFR); |
632 | buffer++; | 611 | buffer++; |
633 | host->offset++; | 612 | host->offset++; |
@@ -638,8 +617,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
638 | /* | 617 | /* |
639 | * Transfer done? | 618 | * Transfer done? |
640 | */ | 619 | */ |
641 | if (data->bytes_xfered == host->size) | 620 | if (data->bytes_xfered == host->size) { |
642 | { | ||
643 | wbsd_kunmap_sg(host); | 621 | wbsd_kunmap_sg(host); |
644 | return; | 622 | return; |
645 | } | 623 | } |
@@ -647,15 +625,13 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
647 | /* | 625 | /* |
648 | * End of scatter list entry? | 626 | * End of scatter list entry? |
649 | */ | 627 | */ |
650 | if (host->remain == 0) | 628 | if (host->remain == 0) { |
651 | { | ||
652 | wbsd_kunmap_sg(host); | 629 | wbsd_kunmap_sg(host); |
653 | 630 | ||
654 | /* | 631 | /* |
655 | * Get next entry. Check if last. | 632 | * Get next entry. Check if last. |
656 | */ | 633 | */ |
657 | if (!wbsd_next_sg(host)) | 634 | if (!wbsd_next_sg(host)) { |
658 | { | ||
659 | /* | 635 | /* |
660 | * We should never reach this point. | 636 | * We should never reach this point. |
661 | * It means that we're trying to | 637 | * It means that we're trying to |
@@ -684,7 +660,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
684 | tasklet_schedule(&host->fifo_tasklet); | 660 | tasklet_schedule(&host->fifo_tasklet); |
685 | } | 661 | } |
686 | 662 | ||
687 | static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | 663 | static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) |
688 | { | 664 | { |
689 | u16 blksize; | 665 | u16 blksize; |
690 | u8 setup; | 666 | u8 setup; |
@@ -706,8 +682,10 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
706 | */ | 682 | */ |
707 | if (data->timeout_ns > 127000000) | 683 | if (data->timeout_ns > 127000000) |
708 | wbsd_write_index(host, WBSD_IDX_TAAC, 127); | 684 | wbsd_write_index(host, WBSD_IDX_TAAC, 127); |
709 | else | 685 | else { |
710 | wbsd_write_index(host, WBSD_IDX_TAAC, data->timeout_ns/1000000); | 686 | wbsd_write_index(host, WBSD_IDX_TAAC, |
687 | data->timeout_ns / 1000000); | ||
688 | } | ||
711 | 689 | ||
712 | if (data->timeout_clks > 255) | 690 | if (data->timeout_clks > 255) |
713 | wbsd_write_index(host, WBSD_IDX_NSAC, 255); | 691 | wbsd_write_index(host, WBSD_IDX_NSAC, 255); |
@@ -722,23 +700,18 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
722 | * Space for CRC must be included in the size. | 700 | * Space for CRC must be included in the size. |
723 | * Two bytes are needed for each data line. | 701 | * Two bytes are needed for each data line. |
724 | */ | 702 | */ |
725 | if (host->bus_width == MMC_BUS_WIDTH_1) | 703 | if (host->bus_width == MMC_BUS_WIDTH_1) { |
726 | { | ||
727 | blksize = (1 << data->blksz_bits) + 2; | 704 | blksize = (1 << data->blksz_bits) + 2; |
728 | 705 | ||
729 | wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); | 706 | wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); |
730 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); | 707 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); |
731 | } | 708 | } else if (host->bus_width == MMC_BUS_WIDTH_4) { |
732 | else if (host->bus_width == MMC_BUS_WIDTH_4) | ||
733 | { | ||
734 | blksize = (1 << data->blksz_bits) + 2 * 4; | 709 | blksize = (1 << data->blksz_bits) + 2 * 4; |
735 | 710 | ||
736 | wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0) | 711 | wbsd_write_index(host, WBSD_IDX_PBSMSB, |
737 | | WBSD_DATA_WIDTH); | 712 | ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH); |
738 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); | 713 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); |
739 | } | 714 | } else { |
740 | else | ||
741 | { | ||
742 | data->error = MMC_ERR_INVALID; | 715 | data->error = MMC_ERR_INVALID; |
743 | return; | 716 | return; |
744 | } | 717 | } |
@@ -755,14 +728,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
755 | /* | 728 | /* |
756 | * DMA transfer? | 729 | * DMA transfer? |
757 | */ | 730 | */ |
758 | if (host->dma >= 0) | 731 | if (host->dma >= 0) { |
759 | { | ||
760 | /* | 732 | /* |
761 | * The buffer for DMA is only 64 kB. | 733 | * The buffer for DMA is only 64 kB. |
762 | */ | 734 | */ |
763 | BUG_ON(host->size > 0x10000); | 735 | BUG_ON(host->size > 0x10000); |
764 | if (host->size > 0x10000) | 736 | if (host->size > 0x10000) { |
765 | { | ||
766 | data->error = MMC_ERR_INVALID; | 737 | data->error = MMC_ERR_INVALID; |
767 | return; | 738 | return; |
768 | } | 739 | } |
@@ -794,9 +765,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
794 | * Enable DMA on the host. | 765 | * Enable DMA on the host. |
795 | */ | 766 | */ |
796 | wbsd_write_index(host, WBSD_IDX_DMA, WBSD_DMA_ENABLE); | 767 | wbsd_write_index(host, WBSD_IDX_DMA, WBSD_DMA_ENABLE); |
797 | } | 768 | } else { |
798 | else | ||
799 | { | ||
800 | /* | 769 | /* |
801 | * This flag is used to keep printk | 770 | * This flag is used to keep printk |
802 | * output to a minimum. | 771 | * output to a minimum. |
@@ -817,13 +786,10 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
817 | * Set up FIFO threshold levels (and fill | 786 | * Set up FIFO threshold levels (and fill |
818 | * buffer if doing a write). | 787 | * buffer if doing a write). |
819 | */ | 788 | */ |
820 | if (data->flags & MMC_DATA_READ) | 789 | if (data->flags & MMC_DATA_READ) { |
821 | { | ||
822 | wbsd_write_index(host, WBSD_IDX_FIFOEN, | 790 | wbsd_write_index(host, WBSD_IDX_FIFOEN, |
823 | WBSD_FIFOEN_FULL | 8); | 791 | WBSD_FIFOEN_FULL | 8); |
824 | } | 792 | } else { |
825 | else | ||
826 | { | ||
827 | wbsd_write_index(host, WBSD_IDX_FIFOEN, | 793 | wbsd_write_index(host, WBSD_IDX_FIFOEN, |
828 | WBSD_FIFOEN_EMPTY | 8); | 794 | WBSD_FIFOEN_EMPTY | 8); |
829 | wbsd_fill_fifo(host); | 795 | wbsd_fill_fifo(host); |
@@ -833,7 +799,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
833 | data->error = MMC_ERR_NONE; | 799 | data->error = MMC_ERR_NONE; |
834 | } | 800 | } |
835 | 801 | ||
836 | static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | 802 | static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) |
837 | { | 803 | { |
838 | unsigned long dmaflags; | 804 | unsigned long dmaflags; |
839 | int count; | 805 | int count; |
@@ -851,16 +817,14 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | |||
851 | * Wait for the controller to leave data | 817 | * Wait for the controller to leave data |
852 | * transfer state. | 818 | * transfer state. |
853 | */ | 819 | */ |
854 | do | 820 | do { |
855 | { | ||
856 | status = wbsd_read_index(host, WBSD_IDX_STATUS); | 821 | status = wbsd_read_index(host, WBSD_IDX_STATUS); |
857 | } while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE)); | 822 | } while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE)); |
858 | 823 | ||
859 | /* | 824 | /* |
860 | * DMA transfer? | 825 | * DMA transfer? |
861 | */ | 826 | */ |
862 | if (host->dma >= 0) | 827 | if (host->dma >= 0) { |
863 | { | ||
864 | /* | 828 | /* |
865 | * Disable DMA on the host. | 829 | * Disable DMA on the host. |
866 | */ | 830 | */ |
@@ -878,16 +842,13 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | |||
878 | /* | 842 | /* |
879 | * Any leftover data? | 843 | * Any leftover data? |
880 | */ | 844 | */ |
881 | if (count) | 845 | if (count) { |
882 | { | ||
883 | printk(KERN_ERR "%s: Incomplete DMA transfer. " | 846 | printk(KERN_ERR "%s: Incomplete DMA transfer. " |
884 | "%d bytes left.\n", | 847 | "%d bytes left.\n", |
885 | mmc_hostname(host->mmc), count); | 848 | mmc_hostname(host->mmc), count); |
886 | 849 | ||
887 | data->error = MMC_ERR_FAILED; | 850 | data->error = MMC_ERR_FAILED; |
888 | } | 851 | } else { |
889 | else | ||
890 | { | ||
891 | /* | 852 | /* |
892 | * Transfer data from DMA buffer to | 853 | * Transfer data from DMA buffer to |
893 | * SG list. | 854 | * SG list. |
@@ -910,10 +871,10 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | |||
910 | * * | 871 | * * |
911 | \*****************************************************************************/ | 872 | \*****************************************************************************/ |
912 | 873 | ||
913 | static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) | 874 | static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) |
914 | { | 875 | { |
915 | struct wbsd_host* host = mmc_priv(mmc); | 876 | struct wbsd_host *host = mmc_priv(mmc); |
916 | struct mmc_command* cmd; | 877 | struct mmc_command *cmd; |
917 | 878 | ||
918 | /* | 879 | /* |
919 | * Disable tasklets to avoid a deadlock. | 880 | * Disable tasklets to avoid a deadlock. |
@@ -930,8 +891,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
930 | * If there is no card in the slot then | 891 | * If there is no card in the slot then |
931 | * timeout immediatly. | 892 | * timeout immediatly. |
932 | */ | 893 | */ |
933 | if (!(host->flags & WBSD_FCARD_PRESENT)) | 894 | if (!(host->flags & WBSD_FCARD_PRESENT)) { |
934 | { | ||
935 | cmd->error = MMC_ERR_TIMEOUT; | 895 | cmd->error = MMC_ERR_TIMEOUT; |
936 | goto done; | 896 | goto done; |
937 | } | 897 | } |
@@ -939,8 +899,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
939 | /* | 899 | /* |
940 | * Does the request include data? | 900 | * Does the request include data? |
941 | */ | 901 | */ |
942 | if (cmd->data) | 902 | if (cmd->data) { |
943 | { | ||
944 | wbsd_prepare_data(host, cmd->data); | 903 | wbsd_prepare_data(host, cmd->data); |
945 | 904 | ||
946 | if (cmd->data->error != MMC_ERR_NONE) | 905 | if (cmd->data->error != MMC_ERR_NONE) |
@@ -954,8 +913,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
954 | * will be finished after the data has | 913 | * will be finished after the data has |
955 | * transfered. | 914 | * transfered. |
956 | */ | 915 | */ |
957 | if (cmd->data && (cmd->error == MMC_ERR_NONE)) | 916 | if (cmd->data && (cmd->error == MMC_ERR_NONE)) { |
958 | { | ||
959 | /* | 917 | /* |
960 | * Dirty fix for hardware bug. | 918 | * Dirty fix for hardware bug. |
961 | */ | 919 | */ |
@@ -973,14 +931,14 @@ done: | |||
973 | spin_unlock_bh(&host->lock); | 931 | spin_unlock_bh(&host->lock); |
974 | } | 932 | } |
975 | 933 | ||
976 | static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | 934 | static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
977 | { | 935 | { |
978 | struct wbsd_host* host = mmc_priv(mmc); | 936 | struct wbsd_host *host = mmc_priv(mmc); |
979 | u8 clk, setup, pwr; | 937 | u8 clk, setup, pwr; |
980 | 938 | ||
981 | DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", | 939 | DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", |
982 | ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, | 940 | ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, |
983 | ios->vdd, ios->bus_width); | 941 | ios->vdd, ios->bus_width); |
984 | 942 | ||
985 | spin_lock_bh(&host->lock); | 943 | spin_lock_bh(&host->lock); |
986 | 944 | ||
@@ -1004,8 +962,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
1004 | * Only write to the clock register when | 962 | * Only write to the clock register when |
1005 | * there is an actual change. | 963 | * there is an actual change. |
1006 | */ | 964 | */ |
1007 | if (clk != host->clk) | 965 | if (clk != host->clk) { |
1008 | { | ||
1009 | wbsd_write_index(host, WBSD_IDX_CLK, clk); | 966 | wbsd_write_index(host, WBSD_IDX_CLK, clk); |
1010 | host->clk = clk; | 967 | host->clk = clk; |
1011 | } | 968 | } |
@@ -1013,8 +970,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
1013 | /* | 970 | /* |
1014 | * Power up card. | 971 | * Power up card. |
1015 | */ | 972 | */ |
1016 | if (ios->power_mode != MMC_POWER_OFF) | 973 | if (ios->power_mode != MMC_POWER_OFF) { |
1017 | { | ||
1018 | pwr = inb(host->base + WBSD_CSR); | 974 | pwr = inb(host->base + WBSD_CSR); |
1019 | pwr &= ~WBSD_POWER_N; | 975 | pwr &= ~WBSD_POWER_N; |
1020 | outb(pwr, host->base + WBSD_CSR); | 976 | outb(pwr, host->base + WBSD_CSR); |
@@ -1026,23 +982,19 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
1026 | * that needs to be disabled. | 982 | * that needs to be disabled. |
1027 | */ | 983 | */ |
1028 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); | 984 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); |
1029 | if (ios->chip_select == MMC_CS_HIGH) | 985 | if (ios->chip_select == MMC_CS_HIGH) { |
1030 | { | ||
1031 | BUG_ON(ios->bus_width != MMC_BUS_WIDTH_1); | 986 | BUG_ON(ios->bus_width != MMC_BUS_WIDTH_1); |
1032 | setup |= WBSD_DAT3_H; | 987 | setup |= WBSD_DAT3_H; |
1033 | host->flags |= WBSD_FIGNORE_DETECT; | 988 | host->flags |= WBSD_FIGNORE_DETECT; |
1034 | } | 989 | } else { |
1035 | else | 990 | if (setup & WBSD_DAT3_H) { |
1036 | { | ||
1037 | if (setup & WBSD_DAT3_H) | ||
1038 | { | ||
1039 | setup &= ~WBSD_DAT3_H; | 991 | setup &= ~WBSD_DAT3_H; |
1040 | 992 | ||
1041 | /* | 993 | /* |
1042 | * We cannot resume card detection immediatly | 994 | * We cannot resume card detection immediatly |
1043 | * because of capacitance and delays in the chip. | 995 | * because of capacitance and delays in the chip. |
1044 | */ | 996 | */ |
1045 | mod_timer(&host->ignore_timer, jiffies + HZ/100); | 997 | mod_timer(&host->ignore_timer, jiffies + HZ / 100); |
1046 | } | 998 | } |
1047 | } | 999 | } |
1048 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | 1000 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); |
@@ -1056,9 +1008,9 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
1056 | spin_unlock_bh(&host->lock); | 1008 | spin_unlock_bh(&host->lock); |
1057 | } | 1009 | } |
1058 | 1010 | ||
1059 | static int wbsd_get_ro(struct mmc_host* mmc) | 1011 | static int wbsd_get_ro(struct mmc_host *mmc) |
1060 | { | 1012 | { |
1061 | struct wbsd_host* host = mmc_priv(mmc); | 1013 | struct wbsd_host *host = mmc_priv(mmc); |
1062 | u8 csr; | 1014 | u8 csr; |
1063 | 1015 | ||
1064 | spin_lock_bh(&host->lock); | 1016 | spin_lock_bh(&host->lock); |
@@ -1096,7 +1048,7 @@ static struct mmc_host_ops wbsd_ops = { | |||
1096 | 1048 | ||
1097 | static void wbsd_reset_ignore(unsigned long data) | 1049 | static void wbsd_reset_ignore(unsigned long data) |
1098 | { | 1050 | { |
1099 | struct wbsd_host *host = (struct wbsd_host*)data; | 1051 | struct wbsd_host *host = (struct wbsd_host *)data; |
1100 | 1052 | ||
1101 | BUG_ON(host == NULL); | 1053 | BUG_ON(host == NULL); |
1102 | 1054 | ||
@@ -1119,7 +1071,7 @@ static void wbsd_reset_ignore(unsigned long data) | |||
1119 | * Tasklets | 1071 | * Tasklets |
1120 | */ | 1072 | */ |
1121 | 1073 | ||
1122 | static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host) | 1074 | static inline struct mmc_data *wbsd_get_data(struct wbsd_host *host) |
1123 | { | 1075 | { |
1124 | WARN_ON(!host->mrq); | 1076 | WARN_ON(!host->mrq); |
1125 | if (!host->mrq) | 1077 | if (!host->mrq) |
@@ -1138,14 +1090,13 @@ static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host) | |||
1138 | 1090 | ||
1139 | static void wbsd_tasklet_card(unsigned long param) | 1091 | static void wbsd_tasklet_card(unsigned long param) |
1140 | { | 1092 | { |
1141 | struct wbsd_host* host = (struct wbsd_host*)param; | 1093 | struct wbsd_host *host = (struct wbsd_host *)param; |
1142 | u8 csr; | 1094 | u8 csr; |
1143 | int delay = -1; | 1095 | int delay = -1; |
1144 | 1096 | ||
1145 | spin_lock(&host->lock); | 1097 | spin_lock(&host->lock); |
1146 | 1098 | ||
1147 | if (host->flags & WBSD_FIGNORE_DETECT) | 1099 | if (host->flags & WBSD_FIGNORE_DETECT) { |
1148 | { | ||
1149 | spin_unlock(&host->lock); | 1100 | spin_unlock(&host->lock); |
1150 | return; | 1101 | return; |
1151 | } | 1102 | } |
@@ -1153,23 +1104,18 @@ static void wbsd_tasklet_card(unsigned long param) | |||
1153 | csr = inb(host->base + WBSD_CSR); | 1104 | csr = inb(host->base + WBSD_CSR); |
1154 | WARN_ON(csr == 0xff); | 1105 | WARN_ON(csr == 0xff); |
1155 | 1106 | ||
1156 | if (csr & WBSD_CARDPRESENT) | 1107 | if (csr & WBSD_CARDPRESENT) { |
1157 | { | 1108 | if (!(host->flags & WBSD_FCARD_PRESENT)) { |
1158 | if (!(host->flags & WBSD_FCARD_PRESENT)) | ||
1159 | { | ||
1160 | DBG("Card inserted\n"); | 1109 | DBG("Card inserted\n"); |
1161 | host->flags |= WBSD_FCARD_PRESENT; | 1110 | host->flags |= WBSD_FCARD_PRESENT; |
1162 | 1111 | ||
1163 | delay = 500; | 1112 | delay = 500; |
1164 | } | 1113 | } |
1165 | } | 1114 | } else if (host->flags & WBSD_FCARD_PRESENT) { |
1166 | else if (host->flags & WBSD_FCARD_PRESENT) | ||
1167 | { | ||
1168 | DBG("Card removed\n"); | 1115 | DBG("Card removed\n"); |
1169 | host->flags &= ~WBSD_FCARD_PRESENT; | 1116 | host->flags &= ~WBSD_FCARD_PRESENT; |
1170 | 1117 | ||
1171 | if (host->mrq) | 1118 | if (host->mrq) { |
1172 | { | ||
1173 | printk(KERN_ERR "%s: Card removed during transfer!\n", | 1119 | printk(KERN_ERR "%s: Card removed during transfer!\n", |
1174 | mmc_hostname(host->mmc)); | 1120 | mmc_hostname(host->mmc)); |
1175 | wbsd_reset(host); | 1121 | wbsd_reset(host); |
@@ -1193,8 +1139,8 @@ static void wbsd_tasklet_card(unsigned long param) | |||
1193 | 1139 | ||
1194 | static void wbsd_tasklet_fifo(unsigned long param) | 1140 | static void wbsd_tasklet_fifo(unsigned long param) |
1195 | { | 1141 | { |
1196 | struct wbsd_host* host = (struct wbsd_host*)param; | 1142 | struct wbsd_host *host = (struct wbsd_host *)param; |
1197 | struct mmc_data* data; | 1143 | struct mmc_data *data; |
1198 | 1144 | ||
1199 | spin_lock(&host->lock); | 1145 | spin_lock(&host->lock); |
1200 | 1146 | ||
@@ -1213,8 +1159,7 @@ static void wbsd_tasklet_fifo(unsigned long param) | |||
1213 | /* | 1159 | /* |
1214 | * Done? | 1160 | * Done? |
1215 | */ | 1161 | */ |
1216 | if (host->size == data->bytes_xfered) | 1162 | if (host->size == data->bytes_xfered) { |
1217 | { | ||
1218 | wbsd_write_index(host, WBSD_IDX_FIFOEN, 0); | 1163 | wbsd_write_index(host, WBSD_IDX_FIFOEN, 0); |
1219 | tasklet_schedule(&host->finish_tasklet); | 1164 | tasklet_schedule(&host->finish_tasklet); |
1220 | } | 1165 | } |
@@ -1225,8 +1170,8 @@ end: | |||
1225 | 1170 | ||
1226 | static void wbsd_tasklet_crc(unsigned long param) | 1171 | static void wbsd_tasklet_crc(unsigned long param) |
1227 | { | 1172 | { |
1228 | struct wbsd_host* host = (struct wbsd_host*)param; | 1173 | struct wbsd_host *host = (struct wbsd_host *)param; |
1229 | struct mmc_data* data; | 1174 | struct mmc_data *data; |
1230 | 1175 | ||
1231 | spin_lock(&host->lock); | 1176 | spin_lock(&host->lock); |
1232 | 1177 | ||
@@ -1249,8 +1194,8 @@ end: | |||
1249 | 1194 | ||
1250 | static void wbsd_tasklet_timeout(unsigned long param) | 1195 | static void wbsd_tasklet_timeout(unsigned long param) |
1251 | { | 1196 | { |
1252 | struct wbsd_host* host = (struct wbsd_host*)param; | 1197 | struct wbsd_host *host = (struct wbsd_host *)param; |
1253 | struct mmc_data* data; | 1198 | struct mmc_data *data; |
1254 | 1199 | ||
1255 | spin_lock(&host->lock); | 1200 | spin_lock(&host->lock); |
1256 | 1201 | ||
@@ -1273,8 +1218,8 @@ end: | |||
1273 | 1218 | ||
1274 | static void wbsd_tasklet_finish(unsigned long param) | 1219 | static void wbsd_tasklet_finish(unsigned long param) |
1275 | { | 1220 | { |
1276 | struct wbsd_host* host = (struct wbsd_host*)param; | 1221 | struct wbsd_host *host = (struct wbsd_host *)param; |
1277 | struct mmc_data* data; | 1222 | struct mmc_data *data; |
1278 | 1223 | ||
1279 | spin_lock(&host->lock); | 1224 | spin_lock(&host->lock); |
1280 | 1225 | ||
@@ -1294,14 +1239,13 @@ end: | |||
1294 | 1239 | ||
1295 | static void wbsd_tasklet_block(unsigned long param) | 1240 | static void wbsd_tasklet_block(unsigned long param) |
1296 | { | 1241 | { |
1297 | struct wbsd_host* host = (struct wbsd_host*)param; | 1242 | struct wbsd_host *host = (struct wbsd_host *)param; |
1298 | struct mmc_data* data; | 1243 | struct mmc_data *data; |
1299 | 1244 | ||
1300 | spin_lock(&host->lock); | 1245 | spin_lock(&host->lock); |
1301 | 1246 | ||
1302 | if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) != | 1247 | if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) != |
1303 | WBSD_CRC_OK) | 1248 | WBSD_CRC_OK) { |
1304 | { | ||
1305 | data = wbsd_get_data(host); | 1249 | data = wbsd_get_data(host); |
1306 | if (!data) | 1250 | if (!data) |
1307 | goto end; | 1251 | goto end; |
@@ -1323,7 +1267,7 @@ end: | |||
1323 | 1267 | ||
1324 | static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) | 1268 | static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) |
1325 | { | 1269 | { |
1326 | struct wbsd_host* host = dev_id; | 1270 | struct wbsd_host *host = dev_id; |
1327 | int isr; | 1271 | int isr; |
1328 | 1272 | ||
1329 | isr = inb(host->base + WBSD_ISR); | 1273 | isr = inb(host->base + WBSD_ISR); |
@@ -1365,10 +1309,10 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
1365 | * Allocate/free MMC structure. | 1309 | * Allocate/free MMC structure. |
1366 | */ | 1310 | */ |
1367 | 1311 | ||
1368 | static int __devinit wbsd_alloc_mmc(struct device* dev) | 1312 | static int __devinit wbsd_alloc_mmc(struct device *dev) |
1369 | { | 1313 | { |
1370 | struct mmc_host* mmc; | 1314 | struct mmc_host *mmc; |
1371 | struct wbsd_host* host; | 1315 | struct wbsd_host *host; |
1372 | 1316 | ||
1373 | /* | 1317 | /* |
1374 | * Allocate MMC structure. | 1318 | * Allocate MMC structure. |
@@ -1388,7 +1332,7 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) | |||
1388 | mmc->ops = &wbsd_ops; | 1332 | mmc->ops = &wbsd_ops; |
1389 | mmc->f_min = 375000; | 1333 | mmc->f_min = 375000; |
1390 | mmc->f_max = 24000000; | 1334 | mmc->f_max = 24000000; |
1391 | mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; | 1335 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
1392 | mmc->caps = MMC_CAP_4_BIT_DATA; | 1336 | mmc->caps = MMC_CAP_4_BIT_DATA; |
1393 | 1337 | ||
1394 | spin_lock_init(&host->lock); | 1338 | spin_lock_init(&host->lock); |
@@ -1424,10 +1368,10 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) | |||
1424 | return 0; | 1368 | return 0; |
1425 | } | 1369 | } |
1426 | 1370 | ||
1427 | static void __devexit wbsd_free_mmc(struct device* dev) | 1371 | static void __devexit wbsd_free_mmc(struct device *dev) |
1428 | { | 1372 | { |
1429 | struct mmc_host* mmc; | 1373 | struct mmc_host *mmc; |
1430 | struct wbsd_host* host; | 1374 | struct wbsd_host *host; |
1431 | 1375 | ||
1432 | mmc = dev_get_drvdata(dev); | 1376 | mmc = dev_get_drvdata(dev); |
1433 | if (!mmc) | 1377 | if (!mmc) |
@@ -1447,7 +1391,7 @@ static void __devexit wbsd_free_mmc(struct device* dev) | |||
1447 | * Scan for known chip id:s | 1391 | * Scan for known chip id:s |
1448 | */ | 1392 | */ |
1449 | 1393 | ||
1450 | static int __devinit wbsd_scan(struct wbsd_host* host) | 1394 | static int __devinit wbsd_scan(struct wbsd_host *host) |
1451 | { | 1395 | { |
1452 | int i, j, k; | 1396 | int i, j, k; |
1453 | int id; | 1397 | int id; |
@@ -1477,16 +1421,14 @@ static int __devinit wbsd_scan(struct wbsd_host* host) | |||
1477 | wbsd_lock_config(host); | 1421 | wbsd_lock_config(host); |
1478 | 1422 | ||
1479 | for (k = 0; k < ARRAY_SIZE(valid_ids); k++) { | 1423 | for (k = 0; k < ARRAY_SIZE(valid_ids); k++) { |
1480 | if (id == valid_ids[k]) | 1424 | if (id == valid_ids[k]) { |
1481 | { | ||
1482 | host->chip_id = id; | 1425 | host->chip_id = id; |
1483 | 1426 | ||
1484 | return 0; | 1427 | return 0; |
1485 | } | 1428 | } |
1486 | } | 1429 | } |
1487 | 1430 | ||
1488 | if (id != 0xFFFF) | 1431 | if (id != 0xFFFF) { |
1489 | { | ||
1490 | DBG("Unknown hardware (id %x) found at %x\n", | 1432 | DBG("Unknown hardware (id %x) found at %x\n", |
1491 | id, config_ports[i]); | 1433 | id, config_ports[i]); |
1492 | } | 1434 | } |
@@ -1505,7 +1447,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host) | |||
1505 | * Allocate/free io port ranges | 1447 | * Allocate/free io port ranges |
1506 | */ | 1448 | */ |
1507 | 1449 | ||
1508 | static int __devinit wbsd_request_region(struct wbsd_host* host, int base) | 1450 | static int __devinit wbsd_request_region(struct wbsd_host *host, int base) |
1509 | { | 1451 | { |
1510 | if (io & 0x7) | 1452 | if (io & 0x7) |
1511 | return -EINVAL; | 1453 | return -EINVAL; |
@@ -1518,7 +1460,7 @@ static int __devinit wbsd_request_region(struct wbsd_host* host, int base) | |||
1518 | return 0; | 1460 | return 0; |
1519 | } | 1461 | } |
1520 | 1462 | ||
1521 | static void __devexit wbsd_release_regions(struct wbsd_host* host) | 1463 | static void __devexit wbsd_release_regions(struct wbsd_host *host) |
1522 | { | 1464 | { |
1523 | if (host->base) | 1465 | if (host->base) |
1524 | release_region(host->base, 8); | 1466 | release_region(host->base, 8); |
@@ -1535,7 +1477,7 @@ static void __devexit wbsd_release_regions(struct wbsd_host* host) | |||
1535 | * Allocate/free DMA port and buffer | 1477 | * Allocate/free DMA port and buffer |
1536 | */ | 1478 | */ |
1537 | 1479 | ||
1538 | static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) | 1480 | static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma) |
1539 | { | 1481 | { |
1540 | if (dma < 0) | 1482 | if (dma < 0) |
1541 | return; | 1483 | return; |
@@ -1579,8 +1521,8 @@ kfree: | |||
1579 | */ | 1521 | */ |
1580 | BUG_ON(1); | 1522 | BUG_ON(1); |
1581 | 1523 | ||
1582 | dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, | 1524 | dma_unmap_single(host->mmc->dev, host->dma_addr, |
1583 | DMA_BIDIRECTIONAL); | 1525 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); |
1584 | host->dma_addr = (dma_addr_t)NULL; | 1526 | host->dma_addr = (dma_addr_t)NULL; |
1585 | 1527 | ||
1586 | kfree(host->dma_buffer); | 1528 | kfree(host->dma_buffer); |
@@ -1594,11 +1536,12 @@ err: | |||
1594 | "Falling back on FIFO.\n", dma); | 1536 | "Falling back on FIFO.\n", dma); |
1595 | } | 1537 | } |
1596 | 1538 | ||
1597 | static void __devexit wbsd_release_dma(struct wbsd_host* host) | 1539 | static void __devexit wbsd_release_dma(struct wbsd_host *host) |
1598 | { | 1540 | { |
1599 | if (host->dma_addr) | 1541 | if (host->dma_addr) { |
1600 | dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, | 1542 | dma_unmap_single(host->mmc->dev, host->dma_addr, |
1601 | DMA_BIDIRECTIONAL); | 1543 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); |
1544 | } | ||
1602 | kfree(host->dma_buffer); | 1545 | kfree(host->dma_buffer); |
1603 | if (host->dma >= 0) | 1546 | if (host->dma >= 0) |
1604 | free_dma(host->dma); | 1547 | free_dma(host->dma); |
@@ -1612,7 +1555,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host) | |||
1612 | * Allocate/free IRQ. | 1555 | * Allocate/free IRQ. |
1613 | */ | 1556 | */ |
1614 | 1557 | ||
1615 | static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq) | 1558 | static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) |
1616 | { | 1559 | { |
1617 | int ret; | 1560 | int ret; |
1618 | 1561 | ||
@@ -1629,17 +1572,23 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq) | |||
1629 | /* | 1572 | /* |
1630 | * Set up tasklets. | 1573 | * Set up tasklets. |
1631 | */ | 1574 | */ |
1632 | tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host); | 1575 | tasklet_init(&host->card_tasklet, wbsd_tasklet_card, |
1633 | tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host); | 1576 | (unsigned long)host); |
1634 | tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host); | 1577 | tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, |
1635 | tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host); | 1578 | (unsigned long)host); |
1636 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); | 1579 | tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, |
1637 | tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host); | 1580 | (unsigned long)host); |
1581 | tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, | ||
1582 | (unsigned long)host); | ||
1583 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, | ||
1584 | (unsigned long)host); | ||
1585 | tasklet_init(&host->block_tasklet, wbsd_tasklet_block, | ||
1586 | (unsigned long)host); | ||
1638 | 1587 | ||
1639 | return 0; | 1588 | return 0; |
1640 | } | 1589 | } |
1641 | 1590 | ||
1642 | static void __devexit wbsd_release_irq(struct wbsd_host* host) | 1591 | static void __devexit wbsd_release_irq(struct wbsd_host *host) |
1643 | { | 1592 | { |
1644 | if (!host->irq) | 1593 | if (!host->irq) |
1645 | return; | 1594 | return; |
@@ -1660,7 +1609,7 @@ static void __devexit wbsd_release_irq(struct wbsd_host* host) | |||
1660 | * Allocate all resources for the host. | 1609 | * Allocate all resources for the host. |
1661 | */ | 1610 | */ |
1662 | 1611 | ||
1663 | static int __devinit wbsd_request_resources(struct wbsd_host* host, | 1612 | static int __devinit wbsd_request_resources(struct wbsd_host *host, |
1664 | int base, int irq, int dma) | 1613 | int base, int irq, int dma) |
1665 | { | 1614 | { |
1666 | int ret; | 1615 | int ret; |
@@ -1691,7 +1640,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host, | |||
1691 | * Release all resources for the host. | 1640 | * Release all resources for the host. |
1692 | */ | 1641 | */ |
1693 | 1642 | ||
1694 | static void __devexit wbsd_release_resources(struct wbsd_host* host) | 1643 | static void __devexit wbsd_release_resources(struct wbsd_host *host) |
1695 | { | 1644 | { |
1696 | wbsd_release_dma(host); | 1645 | wbsd_release_dma(host); |
1697 | wbsd_release_irq(host); | 1646 | wbsd_release_irq(host); |
@@ -1702,7 +1651,7 @@ static void __devexit wbsd_release_resources(struct wbsd_host* host) | |||
1702 | * Configure the resources the chip should use. | 1651 | * Configure the resources the chip should use. |
1703 | */ | 1652 | */ |
1704 | 1653 | ||
1705 | static void wbsd_chip_config(struct wbsd_host* host) | 1654 | static void wbsd_chip_config(struct wbsd_host *host) |
1706 | { | 1655 | { |
1707 | wbsd_unlock_config(host); | 1656 | wbsd_unlock_config(host); |
1708 | 1657 | ||
@@ -1746,7 +1695,7 @@ static void wbsd_chip_config(struct wbsd_host* host) | |||
1746 | * Check that configured resources are correct. | 1695 | * Check that configured resources are correct. |
1747 | */ | 1696 | */ |
1748 | 1697 | ||
1749 | static int wbsd_chip_validate(struct wbsd_host* host) | 1698 | static int wbsd_chip_validate(struct wbsd_host *host) |
1750 | { | 1699 | { |
1751 | int base, irq, dma; | 1700 | int base, irq, dma; |
1752 | 1701 | ||
@@ -1786,7 +1735,7 @@ static int wbsd_chip_validate(struct wbsd_host* host) | |||
1786 | * Powers down the SD function | 1735 | * Powers down the SD function |
1787 | */ | 1736 | */ |
1788 | 1737 | ||
1789 | static void wbsd_chip_poweroff(struct wbsd_host* host) | 1738 | static void wbsd_chip_poweroff(struct wbsd_host *host) |
1790 | { | 1739 | { |
1791 | wbsd_unlock_config(host); | 1740 | wbsd_unlock_config(host); |
1792 | 1741 | ||
@@ -1802,11 +1751,11 @@ static void wbsd_chip_poweroff(struct wbsd_host* host) | |||
1802 | * * | 1751 | * * |
1803 | \*****************************************************************************/ | 1752 | \*****************************************************************************/ |
1804 | 1753 | ||
1805 | static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | 1754 | static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma, |
1806 | int pnp) | 1755 | int pnp) |
1807 | { | 1756 | { |
1808 | struct wbsd_host* host = NULL; | 1757 | struct wbsd_host *host = NULL; |
1809 | struct mmc_host* mmc = NULL; | 1758 | struct mmc_host *mmc = NULL; |
1810 | int ret; | 1759 | int ret; |
1811 | 1760 | ||
1812 | ret = wbsd_alloc_mmc(dev); | 1761 | ret = wbsd_alloc_mmc(dev); |
@@ -1820,16 +1769,12 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | |||
1820 | * Scan for hardware. | 1769 | * Scan for hardware. |
1821 | */ | 1770 | */ |
1822 | ret = wbsd_scan(host); | 1771 | ret = wbsd_scan(host); |
1823 | if (ret) | 1772 | if (ret) { |
1824 | { | 1773 | if (pnp && (ret == -ENODEV)) { |
1825 | if (pnp && (ret == -ENODEV)) | ||
1826 | { | ||
1827 | printk(KERN_WARNING DRIVER_NAME | 1774 | printk(KERN_WARNING DRIVER_NAME |
1828 | ": Unable to confirm device presence. You may " | 1775 | ": Unable to confirm device presence. You may " |
1829 | "experience lock-ups.\n"); | 1776 | "experience lock-ups.\n"); |
1830 | } | 1777 | } else { |
1831 | else | ||
1832 | { | ||
1833 | wbsd_free_mmc(dev); | 1778 | wbsd_free_mmc(dev); |
1834 | return ret; | 1779 | return ret; |
1835 | } | 1780 | } |
@@ -1839,8 +1784,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | |||
1839 | * Request resources. | 1784 | * Request resources. |
1840 | */ | 1785 | */ |
1841 | ret = wbsd_request_resources(host, io, irq, dma); | 1786 | ret = wbsd_request_resources(host, io, irq, dma); |
1842 | if (ret) | 1787 | if (ret) { |
1843 | { | ||
1844 | wbsd_release_resources(host); | 1788 | wbsd_release_resources(host); |
1845 | wbsd_free_mmc(dev); | 1789 | wbsd_free_mmc(dev); |
1846 | return ret; | 1790 | return ret; |
@@ -1849,18 +1793,15 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | |||
1849 | /* | 1793 | /* |
1850 | * See if chip needs to be configured. | 1794 | * See if chip needs to be configured. |
1851 | */ | 1795 | */ |
1852 | if (pnp) | 1796 | if (pnp) { |
1853 | { | 1797 | if ((host->config != 0) && !wbsd_chip_validate(host)) { |
1854 | if ((host->config != 0) && !wbsd_chip_validate(host)) | ||
1855 | { | ||
1856 | printk(KERN_WARNING DRIVER_NAME | 1798 | printk(KERN_WARNING DRIVER_NAME |
1857 | ": PnP active but chip not configured! " | 1799 | ": PnP active but chip not configured! " |
1858 | "You probably have a buggy BIOS. " | 1800 | "You probably have a buggy BIOS. " |
1859 | "Configuring chip manually.\n"); | 1801 | "Configuring chip manually.\n"); |
1860 | wbsd_chip_config(host); | 1802 | wbsd_chip_config(host); |
1861 | } | 1803 | } |
1862 | } | 1804 | } else |
1863 | else | ||
1864 | wbsd_chip_config(host); | 1805 | wbsd_chip_config(host); |
1865 | 1806 | ||
1866 | /* | 1807 | /* |
@@ -1868,8 +1809,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | |||
1868 | * Not tested. | 1809 | * Not tested. |
1869 | */ | 1810 | */ |
1870 | #ifdef CONFIG_PM | 1811 | #ifdef CONFIG_PM |
1871 | if (host->config) | 1812 | if (host->config) { |
1872 | { | ||
1873 | wbsd_unlock_config(host); | 1813 | wbsd_unlock_config(host); |
1874 | wbsd_write_config(host, WBSD_CONF_PME, 0xA0); | 1814 | wbsd_write_config(host, WBSD_CONF_PME, 0xA0); |
1875 | wbsd_lock_config(host); | 1815 | wbsd_lock_config(host); |
@@ -1902,10 +1842,10 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | |||
1902 | return 0; | 1842 | return 0; |
1903 | } | 1843 | } |
1904 | 1844 | ||
1905 | static void __devexit wbsd_shutdown(struct device* dev, int pnp) | 1845 | static void __devexit wbsd_shutdown(struct device *dev, int pnp) |
1906 | { | 1846 | { |
1907 | struct mmc_host* mmc = dev_get_drvdata(dev); | 1847 | struct mmc_host *mmc = dev_get_drvdata(dev); |
1908 | struct wbsd_host* host; | 1848 | struct wbsd_host *host; |
1909 | 1849 | ||
1910 | if (!mmc) | 1850 | if (!mmc) |
1911 | return; | 1851 | return; |
@@ -1929,12 +1869,12 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp) | |||
1929 | * Non-PnP | 1869 | * Non-PnP |
1930 | */ | 1870 | */ |
1931 | 1871 | ||
1932 | static int __devinit wbsd_probe(struct platform_device* dev) | 1872 | static int __devinit wbsd_probe(struct platform_device *dev) |
1933 | { | 1873 | { |
1934 | return wbsd_init(&dev->dev, io, irq, dma, 0); | 1874 | return wbsd_init(&dev->dev, io, irq, dma, 0); |
1935 | } | 1875 | } |
1936 | 1876 | ||
1937 | static int __devexit wbsd_remove(struct platform_device* dev) | 1877 | static int __devexit wbsd_remove(struct platform_device *dev) |
1938 | { | 1878 | { |
1939 | wbsd_shutdown(&dev->dev, 0); | 1879 | wbsd_shutdown(&dev->dev, 0); |
1940 | 1880 | ||
@@ -1948,7 +1888,7 @@ static int __devexit wbsd_remove(struct platform_device* dev) | |||
1948 | #ifdef CONFIG_PNP | 1888 | #ifdef CONFIG_PNP |
1949 | 1889 | ||
1950 | static int __devinit | 1890 | static int __devinit |
1951 | wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id) | 1891 | wbsd_pnp_probe(struct pnp_dev *pnpdev, const struct pnp_device_id *dev_id) |
1952 | { | 1892 | { |
1953 | int io, irq, dma; | 1893 | int io, irq, dma; |
1954 | 1894 | ||
@@ -1967,7 +1907,7 @@ wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id) | |||
1967 | return wbsd_init(&pnpdev->dev, io, irq, dma, 1); | 1907 | return wbsd_init(&pnpdev->dev, io, irq, dma, 1); |
1968 | } | 1908 | } |
1969 | 1909 | ||
1970 | static void __devexit wbsd_pnp_remove(struct pnp_dev * dev) | 1910 | static void __devexit wbsd_pnp_remove(struct pnp_dev *dev) |
1971 | { | 1911 | { |
1972 | wbsd_shutdown(&dev->dev, 1); | 1912 | wbsd_shutdown(&dev->dev, 1); |
1973 | } | 1913 | } |
@@ -1980,37 +1920,54 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev * dev) | |||
1980 | 1920 | ||
1981 | #ifdef CONFIG_PM | 1921 | #ifdef CONFIG_PM |
1982 | 1922 | ||
1983 | static int wbsd_suspend(struct platform_device *dev, pm_message_t state) | 1923 | static int wbsd_suspend(struct wbsd_host *host, pm_message_t state) |
1924 | { | ||
1925 | BUG_ON(host == NULL); | ||
1926 | |||
1927 | return mmc_suspend_host(host->mmc, state); | ||
1928 | } | ||
1929 | |||
1930 | static int wbsd_resume(struct wbsd_host *host) | ||
1931 | { | ||
1932 | BUG_ON(host == NULL); | ||
1933 | |||
1934 | wbsd_init_device(host); | ||
1935 | |||
1936 | return mmc_resume_host(host->mmc); | ||
1937 | } | ||
1938 | |||
1939 | static int wbsd_platform_suspend(struct platform_device *dev, | ||
1940 | pm_message_t state) | ||
1984 | { | 1941 | { |
1985 | struct mmc_host *mmc = platform_get_drvdata(dev); | 1942 | struct mmc_host *mmc = platform_get_drvdata(dev); |
1986 | struct wbsd_host *host; | 1943 | struct wbsd_host *host; |
1987 | int ret; | 1944 | int ret; |
1988 | 1945 | ||
1989 | if (!mmc) | 1946 | if (mmc == NULL) |
1990 | return 0; | 1947 | return 0; |
1991 | 1948 | ||
1992 | DBG("Suspending...\n"); | 1949 | DBGF("Suspending...\n"); |
1993 | |||
1994 | ret = mmc_suspend_host(mmc, state); | ||
1995 | if (!ret) | ||
1996 | return ret; | ||
1997 | 1950 | ||
1998 | host = mmc_priv(mmc); | 1951 | host = mmc_priv(mmc); |
1999 | 1952 | ||
1953 | ret = wbsd_suspend(host, state); | ||
1954 | if (ret) | ||
1955 | return ret; | ||
1956 | |||
2000 | wbsd_chip_poweroff(host); | 1957 | wbsd_chip_poweroff(host); |
2001 | 1958 | ||
2002 | return 0; | 1959 | return 0; |
2003 | } | 1960 | } |
2004 | 1961 | ||
2005 | static int wbsd_resume(struct platform_device *dev) | 1962 | static int wbsd_platform_resume(struct platform_device *dev) |
2006 | { | 1963 | { |
2007 | struct mmc_host *mmc = platform_get_drvdata(dev); | 1964 | struct mmc_host *mmc = platform_get_drvdata(dev); |
2008 | struct wbsd_host *host; | 1965 | struct wbsd_host *host; |
2009 | 1966 | ||
2010 | if (!mmc) | 1967 | if (mmc == NULL) |
2011 | return 0; | 1968 | return 0; |
2012 | 1969 | ||
2013 | DBG("Resuming...\n"); | 1970 | DBGF("Resuming...\n"); |
2014 | 1971 | ||
2015 | host = mmc_priv(mmc); | 1972 | host = mmc_priv(mmc); |
2016 | 1973 | ||
@@ -2021,15 +1978,68 @@ static int wbsd_resume(struct platform_device *dev) | |||
2021 | */ | 1978 | */ |
2022 | mdelay(5); | 1979 | mdelay(5); |
2023 | 1980 | ||
2024 | wbsd_init_device(host); | 1981 | return wbsd_resume(host); |
1982 | } | ||
1983 | |||
1984 | #ifdef CONFIG_PNP | ||
1985 | |||
1986 | static int wbsd_pnp_suspend(struct pnp_dev *pnp_dev, pm_message_t state) | ||
1987 | { | ||
1988 | struct mmc_host *mmc = dev_get_drvdata(&pnp_dev->dev); | ||
1989 | struct wbsd_host *host; | ||
1990 | |||
1991 | if (mmc == NULL) | ||
1992 | return 0; | ||
1993 | |||
1994 | DBGF("Suspending...\n"); | ||
1995 | |||
1996 | host = mmc_priv(mmc); | ||
1997 | |||
1998 | return wbsd_suspend(host, state); | ||
1999 | } | ||
2000 | |||
2001 | static int wbsd_pnp_resume(struct pnp_dev *pnp_dev) | ||
2002 | { | ||
2003 | struct mmc_host *mmc = dev_get_drvdata(&pnp_dev->dev); | ||
2004 | struct wbsd_host *host; | ||
2005 | |||
2006 | if (mmc == NULL) | ||
2007 | return 0; | ||
2008 | |||
2009 | DBGF("Resuming...\n"); | ||
2025 | 2010 | ||
2026 | return mmc_resume_host(mmc); | 2011 | host = mmc_priv(mmc); |
2012 | |||
2013 | /* | ||
2014 | * See if chip needs to be configured. | ||
2015 | */ | ||
2016 | if (host->config != 0) { | ||
2017 | if (!wbsd_chip_validate(host)) { | ||
2018 | printk(KERN_WARNING DRIVER_NAME | ||
2019 | ": PnP active but chip not configured! " | ||
2020 | "You probably have a buggy BIOS. " | ||
2021 | "Configuring chip manually.\n"); | ||
2022 | wbsd_chip_config(host); | ||
2023 | } | ||
2024 | } | ||
2025 | |||
2026 | /* | ||
2027 | * Allow device to initialise itself properly. | ||
2028 | */ | ||
2029 | mdelay(5); | ||
2030 | |||
2031 | return wbsd_resume(host); | ||
2027 | } | 2032 | } |
2028 | 2033 | ||
2034 | #endif /* CONFIG_PNP */ | ||
2035 | |||
2029 | #else /* CONFIG_PM */ | 2036 | #else /* CONFIG_PM */ |
2030 | 2037 | ||
2031 | #define wbsd_suspend NULL | 2038 | #define wbsd_platform_suspend NULL |
2032 | #define wbsd_resume NULL | 2039 | #define wbsd_platform_resume NULL |
2040 | |||
2041 | #define wbsd_pnp_suspend NULL | ||
2042 | #define wbsd_pnp_resume NULL | ||
2033 | 2043 | ||
2034 | #endif /* CONFIG_PM */ | 2044 | #endif /* CONFIG_PM */ |
2035 | 2045 | ||
@@ -2039,8 +2049,8 @@ static struct platform_driver wbsd_driver = { | |||
2039 | .probe = wbsd_probe, | 2049 | .probe = wbsd_probe, |
2040 | .remove = __devexit_p(wbsd_remove), | 2050 | .remove = __devexit_p(wbsd_remove), |
2041 | 2051 | ||
2042 | .suspend = wbsd_suspend, | 2052 | .suspend = wbsd_platform_suspend, |
2043 | .resume = wbsd_resume, | 2053 | .resume = wbsd_platform_resume, |
2044 | .driver = { | 2054 | .driver = { |
2045 | .name = DRIVER_NAME, | 2055 | .name = DRIVER_NAME, |
2046 | }, | 2056 | }, |
@@ -2053,6 +2063,9 @@ static struct pnp_driver wbsd_pnp_driver = { | |||
2053 | .id_table = pnp_dev_table, | 2063 | .id_table = pnp_dev_table, |
2054 | .probe = wbsd_pnp_probe, | 2064 | .probe = wbsd_pnp_probe, |
2055 | .remove = __devexit_p(wbsd_pnp_remove), | 2065 | .remove = __devexit_p(wbsd_pnp_remove), |
2066 | |||
2067 | .suspend = wbsd_pnp_suspend, | ||
2068 | .resume = wbsd_pnp_resume, | ||
2056 | }; | 2069 | }; |
2057 | 2070 | ||
2058 | #endif /* CONFIG_PNP */ | 2071 | #endif /* CONFIG_PNP */ |
@@ -2072,31 +2085,26 @@ static int __init wbsd_drv_init(void) | |||
2072 | 2085 | ||
2073 | #ifdef CONFIG_PNP | 2086 | #ifdef CONFIG_PNP |
2074 | 2087 | ||
2075 | if (!nopnp) | 2088 | if (!nopnp) { |
2076 | { | ||
2077 | result = pnp_register_driver(&wbsd_pnp_driver); | 2089 | result = pnp_register_driver(&wbsd_pnp_driver); |
2078 | if (result < 0) | 2090 | if (result < 0) |
2079 | return result; | 2091 | return result; |
2080 | } | 2092 | } |
2081 | |||
2082 | #endif /* CONFIG_PNP */ | 2093 | #endif /* CONFIG_PNP */ |
2083 | 2094 | ||
2084 | if (nopnp) | 2095 | if (nopnp) { |
2085 | { | ||
2086 | result = platform_driver_register(&wbsd_driver); | 2096 | result = platform_driver_register(&wbsd_driver); |
2087 | if (result < 0) | 2097 | if (result < 0) |
2088 | return result; | 2098 | return result; |
2089 | 2099 | ||
2090 | wbsd_device = platform_device_alloc(DRIVER_NAME, -1); | 2100 | wbsd_device = platform_device_alloc(DRIVER_NAME, -1); |
2091 | if (!wbsd_device) | 2101 | if (!wbsd_device) { |
2092 | { | ||
2093 | platform_driver_unregister(&wbsd_driver); | 2102 | platform_driver_unregister(&wbsd_driver); |
2094 | return -ENOMEM; | 2103 | return -ENOMEM; |
2095 | } | 2104 | } |
2096 | 2105 | ||
2097 | result = platform_device_add(wbsd_device); | 2106 | result = platform_device_add(wbsd_device); |
2098 | if (result) | 2107 | if (result) { |
2099 | { | ||
2100 | platform_device_put(wbsd_device); | 2108 | platform_device_put(wbsd_device); |
2101 | platform_driver_unregister(&wbsd_driver); | 2109 | platform_driver_unregister(&wbsd_driver); |
2102 | return result; | 2110 | return result; |
@@ -2115,8 +2123,7 @@ static void __exit wbsd_drv_exit(void) | |||
2115 | 2123 | ||
2116 | #endif /* CONFIG_PNP */ | 2124 | #endif /* CONFIG_PNP */ |
2117 | 2125 | ||
2118 | if (nopnp) | 2126 | if (nopnp) { |
2119 | { | ||
2120 | platform_device_unregister(wbsd_device); | 2127 | platform_device_unregister(wbsd_device); |
2121 | 2128 | ||
2122 | platform_driver_unregister(&wbsd_driver); | 2129 | platform_driver_unregister(&wbsd_driver); |