MMC compatibility fix - GO_IDLE
PATCH 1/3 MMC compatibility fix - GO_IDLE
This patch adds a GO_IDLE before sending a new SEND_OP_COND (as required by MMC standard).
drivers/mmc/mmc.c +12 -0
@@ -579,6 +579,8 @@static void mmc_setup (struct mmc_host *host) { +struct mmc_command cmd; +if (host->ios.power_mode !=MMC_POWER_ON ) {int err;u32 ocr;
@@ -613,6 +615,16 @@if (host->ocr ==0 )return ; +/* Put cards in idle before sending new OCR */ + + cmd.opcode =MMC_GO_IDLE_STATE ; + cmd.arg =0 ; + cmd.flags =MMC_RSP_NONE ; + +mmc_wait_for_cmd (host, &cmd,0 ); + +mmc_delay (1 ); +/* * Send the selected OCR multiple times... until the cards * all get the idea that they should be ready for CMD2.
Quoted 2 lines · Pierre Ossman
This patch adds a
GO_IDLEbefore sending a newSEND_OP_COND(as required by MMC standard).
Thanks; I haven't completely vanished off the face of the planet.
We already have a function using MMC_GO_IDLE_STATE, so I suggest we separate this out. If you need a 1ms delay after sending this, maybe the other case also needs this delay as well?
How about this patch?
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coredrivers/mmc/mmc.c +26 -7
@@ -451,11 +451,26 @@ }/* +* Tell attached cards to go to IDLE state +*/ +static void mmc_idle_cards (struct mmc_host *host) +{ +struct mmc_command cmd; + + cmd.opcode =MMC_GO_IDLE_STATE ; + cmd.arg =0 ; + cmd.flags =MMC_RSP_NONE ; + +mmc_wait_for_cmd (host, &cmd,0 ); + +mmc_delay (1 ); +} + +/* * Apply power to the MMC stack. */ static void mmc_power_up (struct mmc_host *host) { -struct mmc_command cmd;int bit =fls (host->ocr_avail) -1 ; host->ios.vdd = bit;
@@ -470,12 +485,6 @@ host->ops->set_ios (host, &host->ios);mmc_delay (2 ); - - cmd.opcode =MMC_GO_IDLE_STATE ; - cmd.arg =0 ; - cmd.flags =MMC_RSP_NONE ; - -mmc_wait_for_cmd (host, &cmd,0 ); }static void mmc_power_off (struct mmc_host *host)
@@ -647,12 +656,22 @@u32 ocr;mmc_power_up (host); +mmc_idle_cards (host); err =mmc_send_op_cond (host,0 , &ocr);if (err !=MMC_ERR_NONE )return ; host->ocr =mmc_select_voltage (host, ocr); + +/* +* Since we're changing the OCR value, we seem to +* need to tell some cards to go back to the idle +* state. We wait 1ms to give cards time to +* respond. +*/ +if (host->ocr) +mmc_idle_cards (host); }else { host->ios.bus_mode =MMC_BUSMODE_OPENDRAIN ; host->ios.clock = host->f_min;
Quoted 10 lines · Russell King
Quoted 3 lines · Pierre Ossman
This patch adds a
GO_IDLEbefore sending a newSEND_OP_COND(as required by MMC standard).Thanks; I haven't completely vanished off the face of the planet.
Good to know. You've seemed a bit busy :)
Quoted 6 lines
We already have a function using
MMC_GO_IDLE_STATE, so I suggest we separate this out. If you need a 1ms delay after sending this, maybe the other case also needs this delay as well?
The delay was added just in case. The cards I have here work fine without it. I just thought adding a small delay might avoid problematic cards later on. Seems to be a few of those.
Quoted 4 lines
How about this patch?
Looks ok. You sure we don't need to put all cards into an idle state before issuing a new SEND_OP_COND? I haven't studied how the MMC layer is called in detail. Can a rescan be done while a card is in a selected state?
Rgds
Pierre
Quoted 5 lines · Pierre Ossman
Quoted 1 line · Russell King
How about this patch?
Looks ok. You sure we don't need to put all cards into an idle state before issuing a new
SEND_OP_COND?
We aren't sending that to the existing cards - they are still in whatever state they were when they were previously detected. In addition, we aren't actually changing or detecting the operational conditions, we're merely informing the new cards about the existing setup.
Quoted 1 line
Can a rescan be done while a card is in a selected state?
Yes - any cards not already in idle state will ignore the command as intended.
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core