aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r--drivers/mmc/core/mmc.c289
1 files changed, 192 insertions, 97 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 47449e870131..619581e49163 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -229,55 +229,13 @@ out:
229} 229}
230 230
231/* 231/*
232 * Host is being removed. Free up the current card. 232 * Handle the detection and initialisation of a card.
233 */ 233 *
234static void mmc_remove(struct mmc_host *host) 234 * In the case of a resume, "curcard" will contain the card
235{ 235 * we're trying to reinitialise.
236 BUG_ON(!host);
237 BUG_ON(!host->card);
238
239 mmc_remove_card(host->card);
240 host->card = NULL;
241}
242
243/*
244 * Card detection callback from host.
245 */
246static void mmc_detect(struct mmc_host *host)
247{
248 int err;
249
250 BUG_ON(!host);
251 BUG_ON(!host->card);
252
253 mmc_claim_host(host);
254
255 /*
256 * Just check if our card has been removed.
257 */
258 err = mmc_send_status(host->card, NULL);
259
260 mmc_release_host(host);
261
262 if (err != MMC_ERR_NONE) {
263 mmc_remove_card(host->card);
264 host->card = NULL;
265
266 mmc_claim_host(host);
267 mmc_detach_bus(host);
268 mmc_release_host(host);
269 }
270}
271
272static const struct mmc_bus_ops mmc_ops = {
273 .remove = mmc_remove,
274 .detect = mmc_detect,
275};
276
277/*
278 * Starting point for MMC card init.
279 */ 236 */
280int mmc_attach_mmc(struct mmc_host *host, u32 ocr) 237static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
238 struct mmc_card *oldcard)
281{ 239{
282 struct mmc_card *card; 240 struct mmc_card *card;
283 int err; 241 int err;
@@ -287,27 +245,6 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
287 BUG_ON(!host); 245 BUG_ON(!host);
288 BUG_ON(!host->claimed); 246 BUG_ON(!host->claimed);
289 247
290 mmc_attach_bus(host, &mmc_ops);
291
292 /*
293 * Sanity check the voltages that the card claims to
294 * support.
295 */
296 if (ocr & 0x7F) {
297 printk(KERN_WARNING "%s: card claims to support voltages "
298 "below the defined range. These will be ignored.\n",
299 mmc_hostname(host));
300 ocr &= ~0x7F;
301 }
302
303 host->ocr = mmc_select_voltage(host, ocr);
304
305 /*
306 * Can we support the voltage of the card?
307 */
308 if (!host->ocr)
309 goto err;
310
311 /* 248 /*
312 * Since we're changing the OCR value, we seem to 249 * Since we're changing the OCR value, we seem to
313 * need to tell some cards to go back to the idle 250 * need to tell some cards to go back to the idle
@@ -317,7 +254,9 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
317 mmc_go_idle(host); 254 mmc_go_idle(host);
318 255
319 /* The extra bit indicates that we support high capacity */ 256 /* The extra bit indicates that we support high capacity */
320 mmc_send_op_cond(host, host->ocr | (1 << 30), NULL); 257 err = mmc_send_op_cond(host, ocr | (1 << 30), NULL);
258 if (err != MMC_ERR_NONE)
259 goto err;
321 260
322 /* 261 /*
323 * Fetch CID from card. 262 * Fetch CID from card.
@@ -326,16 +265,23 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
326 if (err != MMC_ERR_NONE) 265 if (err != MMC_ERR_NONE)
327 goto err; 266 goto err;
328 267
329 /* 268 if (oldcard) {
330 * Allocate card structure. 269 if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
331 */ 270 goto err;
332 card = mmc_alloc_card(host); 271
333 if (IS_ERR(card)) 272 card = oldcard;
334 goto err; 273 } else {
274 /*
275 * Allocate card structure.
276 */
277 card = mmc_alloc_card(host);
278 if (IS_ERR(card))
279 goto err;
335 280
336 card->type = MMC_TYPE_MMC; 281 card->type = MMC_TYPE_MMC;
337 card->rca = 1; 282 card->rca = 1;
338 memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); 283 memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
284 }
339 285
340 /* 286 /*
341 * Set card RCA. 287 * Set card RCA.
@@ -346,15 +292,17 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
346 292
347 mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); 293 mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
348 294
349 /* 295 if (!oldcard) {
350 * Fetch CSD from card. 296 /*
351 */ 297 * Fetch CSD from card.
352 err = mmc_send_csd(card, card->raw_csd); 298 */
353 if (err != MMC_ERR_NONE) 299 err = mmc_send_csd(card, card->raw_csd);
354 goto free_card; 300 if (err != MMC_ERR_NONE)
301 goto free_card;
355 302
356 mmc_decode_csd(card); 303 mmc_decode_csd(card);
357 mmc_decode_cid(card); 304 mmc_decode_cid(card);
305 }
358 306
359 /* 307 /*
360 * Select card, as all following commands rely on that. 308 * Select card, as all following commands rely on that.
@@ -363,12 +311,14 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
363 if (err != MMC_ERR_NONE) 311 if (err != MMC_ERR_NONE)
364 goto free_card; 312 goto free_card;
365 313
366 /* 314 if (!oldcard) {
367 * Fetch and process extened CSD. 315 /*
368 */ 316 * Fetch and process extened CSD.
369 err = mmc_read_ext_csd(card); 317 */
370 if (err != MMC_ERR_NONE) 318 err = mmc_read_ext_csd(card);
371 goto free_card; 319 if (err != MMC_ERR_NONE)
320 goto free_card;
321 }
372 322
373 /* 323 /*
374 * Activate high speed (if supported) 324 * Activate high speed (if supported)
@@ -412,11 +362,157 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
412 mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); 362 mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
413 } 363 }
414 364
415 host->card = card; 365 if (!oldcard)
366 host->card = card;
367
368 return MMC_ERR_NONE;
369
370free_card:
371 if (!oldcard)
372 mmc_remove_card(card);
373err:
374
375 return MMC_ERR_FAILED;
376}
377
378/*
379 * Host is being removed. Free up the current card.
380 */
381static void mmc_remove(struct mmc_host *host)
382{
383 BUG_ON(!host);
384 BUG_ON(!host->card);
385
386 mmc_remove_card(host->card);
387 host->card = NULL;
388}
389
390/*
391 * Card detection callback from host.
392 */
393static void mmc_detect(struct mmc_host *host)
394{
395 int err;
396
397 BUG_ON(!host);
398 BUG_ON(!host->card);
399
400 mmc_claim_host(host);
401
402 /*
403 * Just check if our card has been removed.
404 */
405 err = mmc_send_status(host->card, NULL);
406
407 mmc_release_host(host);
408
409 if (err != MMC_ERR_NONE) {
410 mmc_remove_card(host->card);
411 host->card = NULL;
412
413 mmc_claim_host(host);
414 mmc_detach_bus(host);
415 mmc_release_host(host);
416 }
417}
418
419#ifdef CONFIG_MMC_UNSAFE_RESUME
420
421/*
422 * Suspend callback from host.
423 */
424static void mmc_suspend(struct mmc_host *host)
425{
426 BUG_ON(!host);
427 BUG_ON(!host->card);
416 428
429 mmc_claim_host(host);
430 mmc_deselect_cards(host);
431 host->card->state &= ~MMC_STATE_HIGHSPEED;
417 mmc_release_host(host); 432 mmc_release_host(host);
433}
418 434
419 err = mmc_register_card(card); 435/*
436 * Resume callback from host.
437 *
438 * This function tries to determine if the same card is still present
439 * and, if so, restore all state to it.
440 */
441static void mmc_resume(struct mmc_host *host)
442{
443 int err;
444
445 BUG_ON(!host);
446 BUG_ON(!host->card);
447
448 mmc_claim_host(host);
449
450 err = mmc_sd_init_card(host, host->ocr, host->card);
451 if (err != MMC_ERR_NONE) {
452 mmc_remove_card(host->card);
453 host->card = NULL;
454
455 mmc_detach_bus(host);
456 }
457
458 mmc_release_host(host);
459}
460
461#else
462
463#define mmc_suspend NULL
464#define mmc_resume NULL
465
466#endif
467
468static const struct mmc_bus_ops mmc_ops = {
469 .remove = mmc_remove,
470 .detect = mmc_detect,
471 .suspend = mmc_suspend,
472 .resume = mmc_resume,
473};
474
475/*
476 * Starting point for MMC card init.
477 */
478int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
479{
480 int err;
481
482 BUG_ON(!host);
483 BUG_ON(!host->claimed);
484
485 mmc_attach_bus(host, &mmc_ops);
486
487 /*
488 * Sanity check the voltages that the card claims to
489 * support.
490 */
491 if (ocr & 0x7F) {
492 printk(KERN_WARNING "%s: card claims to support voltages "
493 "below the defined range. These will be ignored.\n",
494 mmc_hostname(host));
495 ocr &= ~0x7F;
496 }
497
498 host->ocr = mmc_select_voltage(host, ocr);
499
500 /*
501 * Can we support the voltage of the card?
502 */
503 if (!host->ocr)
504 goto err;
505
506 /*
507 * Detect and init the card.
508 */
509 err = mmc_sd_init_card(host, host->ocr, NULL);
510 if (err != MMC_ERR_NONE)
511 goto err;
512
513 mmc_release_host(host);
514
515 err = mmc_register_card(host->card);
420 if (err) 516 if (err)
421 goto reclaim_host; 517 goto reclaim_host;
422 518
@@ -424,8 +520,7 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
424 520
425reclaim_host: 521reclaim_host:
426 mmc_claim_host(host); 522 mmc_claim_host(host);
427free_card: 523 mmc_remove_card(host->card);
428 mmc_remove_card(card);
429 host->card = NULL; 524 host->card = NULL;
430err: 525err:
431 mmc_detach_bus(host); 526 mmc_detach_bus(host);