Skip to content

Commit 71578a1

Browse files
osctobetorvalds
authored andcommitted
mmc: split mmc_sd_init_card()
This series adds support for SD combo cards to MMC/SD driver stack. SD combo consists of SD memory and SDIO parts in one package. Since the parts have a separate SD command sets, after initialization, they can be treated as independent cards on one bus. Changes are divided into two patches. First is just moving initialization code around so that SD memory part init can be called from SDIO init. Second patch is a proper change enabling SD memory along SDIO. I tried to move as much no-op changes to the first patch so that it's easier to follow the required changes to initialization flow for SDIO cards. This is based on Simplified SDIO spec v.2.00. The init sequence is slightly modified to follow current SD memory init implementation. Command sequences, assuming SD memory and SDIO indeed ignore unknown commands, are the same as before for both parts. This patch: Prepare for SD-combo (IO+mem) support by splitting SD memory card init and related functions. Signed-off-by: Michal Miroslaw <mirq-linux@rere.qmqm.pl> Cc: Adrian Hunter <adrian.hunter@nokia.com> Cc: Chris Ball <cjb@laptop.org> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 6da24b7 commit 71578a1

File tree

3 files changed

+186
-119
lines changed

3 files changed

+186
-119
lines changed

drivers/mmc/core/sd.c

Lines changed: 145 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static const unsigned int tacc_mant[] = {
5959
/*
6060
* Given the decoded CSD structure, decode the raw CID to our CID structure.
6161
*/
62-
static void mmc_decode_cid(struct mmc_card *card)
62+
void mmc_decode_cid(struct mmc_card *card)
6363
{
6464
u32 *resp = card->raw_cid;
6565

@@ -238,7 +238,7 @@ static int mmc_read_switch(struct mmc_card *card)
238238
/*
239239
* Test if the card supports high-speed mode and, if so, switch to it.
240240
*/
241-
static int mmc_switch_hs(struct mmc_card *card)
241+
int mmc_sd_switch_hs(struct mmc_card *card)
242242
{
243243
int err;
244244
u8 *status;
@@ -272,9 +272,9 @@ static int mmc_switch_hs(struct mmc_card *card)
272272
printk(KERN_WARNING "%s: Problem switching card "
273273
"into high-speed mode!\n",
274274
mmc_hostname(card->host));
275+
err = 0;
275276
} else {
276-
mmc_card_set_highspeed(card);
277-
mmc_set_timing(card->host, MMC_TIMING_SD_HS);
277+
err = 1;
278278
}
279279

280280
out:
@@ -320,26 +320,16 @@ static const struct attribute_group *sd_attr_groups[] = {
320320
NULL,
321321
};
322322

323-
static struct device_type sd_type = {
323+
struct device_type sd_type = {
324324
.groups = sd_attr_groups,
325325
};
326326

327327
/*
328-
* Handle the detection and initialisation of a card.
329-
*
330-
* In the case of a resume, "oldcard" will contain the card
331-
* we're trying to reinitialise.
328+
* Fetch CID from card.
332329
*/
333-
static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
334-
struct mmc_card *oldcard)
330+
int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid)
335331
{
336-
struct mmc_card *card;
337332
int err;
338-
u32 cid[4];
339-
unsigned int max_dtr;
340-
341-
BUG_ON(!host);
342-
WARN_ON(!host->claimed);
343333

344334
/*
345335
* Since we're changing the OCR value, we seem to
@@ -361,34 +351,145 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
361351

362352
err = mmc_send_app_op_cond(host, ocr, NULL);
363353
if (err)
364-
goto err;
354+
return err;
365355

366-
/*
367-
* Fetch CID from card.
368-
*/
369356
if (mmc_host_is_spi(host))
370357
err = mmc_send_cid(host, cid);
371358
else
372359
err = mmc_all_send_cid(host, cid);
360+
361+
return err;
362+
}
363+
364+
int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card)
365+
{
366+
int err;
367+
368+
/*
369+
* Fetch CSD from card.
370+
*/
371+
err = mmc_send_csd(card, card->raw_csd);
373372
if (err)
374-
goto err;
373+
return err;
375374

376-
if (oldcard) {
377-
if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
378-
err = -ENOENT;
379-
goto err;
375+
err = mmc_decode_csd(card);
376+
if (err)
377+
return err;
378+
379+
return 0;
380+
}
381+
382+
int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
383+
bool reinit)
384+
{
385+
int err;
386+
387+
if (!reinit) {
388+
/*
389+
* Fetch SCR from card.
390+
*/
391+
err = mmc_app_send_scr(card, card->raw_scr);
392+
if (err)
393+
return err;
394+
395+
err = mmc_decode_scr(card);
396+
if (err)
397+
return err;
398+
399+
/*
400+
* Fetch switch information from card.
401+
*/
402+
err = mmc_read_switch(card);
403+
if (err)
404+
return err;
405+
}
406+
407+
/*
408+
* For SPI, enable CRC as appropriate.
409+
* This CRC enable is located AFTER the reading of the
410+
* card registers because some SDHC cards are not able
411+
* to provide valid CRCs for non-512-byte blocks.
412+
*/
413+
if (mmc_host_is_spi(host)) {
414+
err = mmc_spi_set_crc(host, use_spi_crc);
415+
if (err)
416+
return err;
417+
}
418+
419+
/*
420+
* Check if read-only switch is active.
421+
*/
422+
if (!reinit) {
423+
int ro = -1;
424+
425+
if (host->ops->get_ro)
426+
ro = host->ops->get_ro(host);
427+
428+
if (ro < 0) {
429+
printk(KERN_WARNING "%s: host does not "
430+
"support reading read-only "
431+
"switch. assuming write-enable.\n",
432+
mmc_hostname(host));
433+
} else if (ro > 0) {
434+
mmc_card_set_readonly(card);
380435
}
436+
}
437+
438+
return 0;
439+
}
440+
441+
unsigned mmc_sd_get_max_clock(struct mmc_card *card)
442+
{
443+
unsigned max_dtr = (unsigned int)-1;
444+
445+
if (mmc_card_highspeed(card)) {
446+
if (max_dtr > card->sw_caps.hs_max_dtr)
447+
max_dtr = card->sw_caps.hs_max_dtr;
448+
} else if (max_dtr > card->csd.max_dtr) {
449+
max_dtr = card->csd.max_dtr;
450+
}
451+
452+
return max_dtr;
453+
}
454+
455+
void mmc_sd_go_highspeed(struct mmc_card *card)
456+
{
457+
mmc_card_set_highspeed(card);
458+
mmc_set_timing(card->host, MMC_TIMING_SD_HS);
459+
}
460+
461+
/*
462+
* Handle the detection and initialisation of a card.
463+
*
464+
* In the case of a resume, "oldcard" will contain the card
465+
* we're trying to reinitialise.
466+
*/
467+
static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
468+
struct mmc_card *oldcard)
469+
{
470+
struct mmc_card *card;
471+
int err;
472+
u32 cid[4];
473+
474+
BUG_ON(!host);
475+
WARN_ON(!host->claimed);
476+
477+
err = mmc_sd_get_cid(host, ocr, cid);
478+
if (err)
479+
return err;
480+
481+
if (oldcard) {
482+
if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
483+
return -ENOENT;
381484

382485
card = oldcard;
383486
} else {
384487
/*
385488
* Allocate card structure.
386489
*/
387490
card = mmc_alloc_card(host, &sd_type);
388-
if (IS_ERR(card)) {
389-
err = PTR_ERR(card);
390-
goto err;
391-
}
491+
if (IS_ERR(card))
492+
return PTR_ERR(card);
392493

393494
card->type = MMC_TYPE_SD;
394495
memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
@@ -400,22 +501,15 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
400501
if (!mmc_host_is_spi(host)) {
401502
err = mmc_send_relative_addr(host, &card->rca);
402503
if (err)
403-
goto free_card;
504+
return err;
404505

405506
mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
406507
}
407508

408509
if (!oldcard) {
409-
/*
410-
* Fetch CSD from card.
411-
*/
412-
err = mmc_send_csd(card, card->raw_csd);
510+
err = mmc_sd_get_csd(host, card);
413511
if (err)
414-
goto free_card;
415-
416-
err = mmc_decode_csd(card);
417-
if (err)
418-
goto free_card;
512+
return err;
419513

420514
mmc_decode_cid(card);
421515
}
@@ -426,61 +520,26 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
426520
if (!mmc_host_is_spi(host)) {
427521
err = mmc_select_card(card);
428522
if (err)
429-
goto free_card;
523+
return err;
430524
}
431525

432-
if (!oldcard) {
433-
/*
434-
* Fetch SCR from card.
435-
*/
436-
err = mmc_app_send_scr(card, card->raw_scr);
437-
if (err)
438-
goto free_card;
439-
440-
err = mmc_decode_scr(card);
441-
if (err < 0)
442-
goto free_card;
443-
444-
/*
445-
* Fetch switch information from card.
446-
*/
447-
err = mmc_read_switch(card);
448-
if (err)
449-
goto free_card;
450-
}
451-
452-
/*
453-
* For SPI, enable CRC as appropriate.
454-
* This CRC enable is located AFTER the reading of the
455-
* card registers because some SDHC cards are not able
456-
* to provide valid CRCs for non-512-byte blocks.
457-
*/
458-
if (mmc_host_is_spi(host)) {
459-
err = mmc_spi_set_crc(host, use_spi_crc);
460-
if (err)
461-
goto free_card;
462-
}
526+
err = mmc_sd_setup_card(host, card, oldcard != NULL);
527+
if (err)
528+
goto free_card;
463529

464530
/*
465531
* Attempt to change to high-speed (if supported)
466532
*/
467-
err = mmc_switch_hs(card);
468-
if (err)
533+
err = mmc_sd_switch_hs(card);
534+
if (err > 0)
535+
mmc_sd_go_highspeed(card);
536+
else if (err)
469537
goto free_card;
470538

471539
/*
472-
* Compute bus speed.
540+
* Set bus speed.
473541
*/
474-
max_dtr = (unsigned int)-1;
475-
476-
if (mmc_card_highspeed(card)) {
477-
if (max_dtr > card->sw_caps.hs_max_dtr)
478-
max_dtr = card->sw_caps.hs_max_dtr;
479-
} else if (max_dtr > card->csd.max_dtr) {
480-
max_dtr = card->csd.max_dtr;
481-
}
482-
483-
mmc_set_clock(host, max_dtr);
542+
mmc_set_clock(host, mmc_sd_get_max_clock(card));
484543

485544
/*
486545
* Switch to wider bus (if supported).
@@ -494,30 +553,12 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
494553
mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
495554
}
496555

497-
/*
498-
* Check if read-only switch is active.
499-
*/
500-
if (!oldcard) {
501-
if (!host->ops->get_ro || host->ops->get_ro(host) < 0) {
502-
printk(KERN_WARNING "%s: host does not "
503-
"support reading read-only "
504-
"switch. assuming write-enable.\n",
505-
mmc_hostname(host));
506-
} else {
507-
if (host->ops->get_ro(host) > 0)
508-
mmc_card_set_readonly(card);
509-
}
510-
}
511-
512-
if (!oldcard)
513-
host->card = card;
514-
556+
host->card = card;
515557
return 0;
516558

517559
free_card:
518560
if (!oldcard)
519561
mmc_remove_card(card);
520-
err:
521562

522563
return err;
523564
}

drivers/mmc/core/sd.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef _MMC_CORE_SD_H
2+
#define _MMC_CORE_SD_H
3+
4+
#include <linux/mmc/card.h>
5+
6+
extern struct device_type sd_type;
7+
8+
int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid);
9+
int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card);
10+
void mmc_decode_cid(struct mmc_card *card);
11+
int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
12+
bool reinit);
13+
unsigned mmc_sd_get_max_clock(struct mmc_card *card);
14+
int mmc_sd_switch_hs(struct mmc_card *card);
15+
void mmc_sd_go_highspeed(struct mmc_card *card);
16+
17+
#endif

0 commit comments

Comments
 (0)