Merge master.kernel.org:/home/rmk/linux-2.6-mmc
This commit is contained in:
commit
da1f136c26
4 changed files with 70 additions and 15 deletions
|
@ -457,6 +457,11 @@ static void mmc_idle_cards(struct mmc_host *host)
|
|||
{
|
||||
struct mmc_command cmd;
|
||||
|
||||
host->ios.chip_select = MMC_CS_HIGH;
|
||||
host->ops->set_ios(host, &host->ios);
|
||||
|
||||
mmc_delay(1);
|
||||
|
||||
cmd.opcode = MMC_GO_IDLE_STATE;
|
||||
cmd.arg = 0;
|
||||
cmd.flags = MMC_RSP_NONE;
|
||||
|
@ -464,6 +469,11 @@ static void mmc_idle_cards(struct mmc_host *host)
|
|||
mmc_wait_for_cmd(host, &cmd, 0);
|
||||
|
||||
mmc_delay(1);
|
||||
|
||||
host->ios.chip_select = MMC_CS_DONTCARE;
|
||||
host->ops->set_ios(host, &host->ios);
|
||||
|
||||
mmc_delay(1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -475,6 +485,7 @@ static void mmc_power_up(struct mmc_host *host)
|
|||
|
||||
host->ios.vdd = bit;
|
||||
host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
|
||||
host->ios.chip_select = MMC_CS_DONTCARE;
|
||||
host->ios.power_mode = MMC_POWER_UP;
|
||||
host->ops->set_ios(host, &host->ios);
|
||||
|
||||
|
@ -492,6 +503,7 @@ static void mmc_power_off(struct mmc_host *host)
|
|||
host->ios.clock = 0;
|
||||
host->ios.vdd = 0;
|
||||
host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
|
||||
host->ios.chip_select = MMC_CS_DONTCARE;
|
||||
host->ios.power_mode = MMC_POWER_OFF;
|
||||
host->ops->set_ios(host, &host->ios);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "wbsd.h"
|
||||
|
||||
#define DRIVER_NAME "wbsd"
|
||||
#define DRIVER_VERSION "1.3"
|
||||
#define DRIVER_VERSION "1.4"
|
||||
|
||||
#ifdef CONFIG_MMC_DEBUG
|
||||
#define DBG(x...) \
|
||||
|
@ -960,8 +960,9 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
|
|||
struct wbsd_host* host = mmc_priv(mmc);
|
||||
u8 clk, setup, pwr;
|
||||
|
||||
DBGF("clock %uHz busmode %u powermode %u Vdd %u\n",
|
||||
ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);
|
||||
DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u\n",
|
||||
ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select,
|
||||
ios->vdd);
|
||||
|
||||
spin_lock_bh(&host->lock);
|
||||
|
||||
|
@ -1003,13 +1004,11 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
|
|||
|
||||
/*
|
||||
* MMC cards need to have pin 1 high during init.
|
||||
* Init time corresponds rather nicely with the bus mode.
|
||||
* It wreaks havoc with the card detection though so
|
||||
* that needs to be disabed.
|
||||
* that needs to be disabled.
|
||||
*/
|
||||
setup = wbsd_read_index(host, WBSD_IDX_SETUP);
|
||||
if ((ios->power_mode == MMC_POWER_ON) &&
|
||||
(ios->bus_mode == MMC_BUSMODE_OPENDRAIN))
|
||||
if (ios->chip_select == MMC_CS_HIGH)
|
||||
{
|
||||
setup |= WBSD_DAT3_H;
|
||||
host->flags |= WBSD_FIGNORE_DETECT;
|
||||
|
@ -1017,7 +1016,12 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
|
|||
else
|
||||
{
|
||||
setup &= ~WBSD_DAT3_H;
|
||||
host->flags &= ~WBSD_FIGNORE_DETECT;
|
||||
|
||||
/*
|
||||
* We cannot resume card detection immediatly
|
||||
* because of capacitance and delays in the chip.
|
||||
*/
|
||||
mod_timer(&host->ignore_timer, jiffies + HZ/100);
|
||||
}
|
||||
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
|
||||
|
||||
|
@ -1035,6 +1039,31 @@ static struct mmc_host_ops wbsd_ops = {
|
|||
* *
|
||||
\*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Helper function to reset detection ignore
|
||||
*/
|
||||
|
||||
static void wbsd_reset_ignore(unsigned long data)
|
||||
{
|
||||
struct wbsd_host *host = (struct wbsd_host*)data;
|
||||
|
||||
BUG_ON(host == NULL);
|
||||
|
||||
DBG("Resetting card detection ignore\n");
|
||||
|
||||
spin_lock_bh(&host->lock);
|
||||
|
||||
host->flags &= ~WBSD_FIGNORE_DETECT;
|
||||
|
||||
/*
|
||||
* Card status might have changed during the
|
||||
* blackout.
|
||||
*/
|
||||
tasklet_schedule(&host->card_tasklet);
|
||||
|
||||
spin_unlock_bh(&host->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function for card detection
|
||||
*/
|
||||
|
@ -1097,7 +1126,7 @@ static void wbsd_tasklet_card(unsigned long param)
|
|||
* Delay card detection to allow electrical connections
|
||||
* to stabilise.
|
||||
*/
|
||||
mod_timer(&host->timer, jiffies + HZ/2);
|
||||
mod_timer(&host->detect_timer, jiffies + HZ/2);
|
||||
}
|
||||
|
||||
spin_unlock(&host->lock);
|
||||
|
@ -1124,6 +1153,8 @@ static void wbsd_tasklet_card(unsigned long param)
|
|||
|
||||
mmc_detect_change(host->mmc);
|
||||
}
|
||||
else
|
||||
spin_unlock(&host->lock);
|
||||
}
|
||||
|
||||
static void wbsd_tasklet_fifo(unsigned long param)
|
||||
|
@ -1328,11 +1359,15 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
|
|||
spin_lock_init(&host->lock);
|
||||
|
||||
/*
|
||||
* Set up detection timer
|
||||
* Set up timers
|
||||
*/
|
||||
init_timer(&host->timer);
|
||||
host->timer.data = (unsigned long)host;
|
||||
host->timer.function = wbsd_detect_card;
|
||||
init_timer(&host->detect_timer);
|
||||
host->detect_timer.data = (unsigned long)host;
|
||||
host->detect_timer.function = wbsd_detect_card;
|
||||
|
||||
init_timer(&host->ignore_timer);
|
||||
host->ignore_timer.data = (unsigned long)host;
|
||||
host->ignore_timer.function = wbsd_reset_ignore;
|
||||
|
||||
/*
|
||||
* Maximum number of segments. Worst case is one sector per segment
|
||||
|
@ -1370,7 +1405,8 @@ static void __devexit wbsd_free_mmc(struct device* dev)
|
|||
host = mmc_priv(mmc);
|
||||
BUG_ON(host == NULL);
|
||||
|
||||
del_timer_sync(&host->timer);
|
||||
del_timer_sync(&host->ignore_timer);
|
||||
del_timer_sync(&host->detect_timer);
|
||||
|
||||
mmc_free_host(mmc);
|
||||
|
||||
|
|
|
@ -181,5 +181,6 @@ struct wbsd_host
|
|||
struct tasklet_struct finish_tasklet;
|
||||
struct tasklet_struct block_tasklet;
|
||||
|
||||
struct timer_list timer; /* Card detection timer */
|
||||
struct timer_list detect_timer; /* Card detection timer */
|
||||
struct timer_list ignore_timer; /* Ignore detection timer */
|
||||
};
|
||||
|
|
|
@ -46,6 +46,12 @@ struct mmc_ios {
|
|||
#define MMC_BUSMODE_OPENDRAIN 1
|
||||
#define MMC_BUSMODE_PUSHPULL 2
|
||||
|
||||
unsigned char chip_select; /* SPI chip select */
|
||||
|
||||
#define MMC_CS_DONTCARE 0
|
||||
#define MMC_CS_HIGH 1
|
||||
#define MMC_CS_LOW 2
|
||||
|
||||
unsigned char power_mode; /* power supply mode */
|
||||
|
||||
#define MMC_POWER_OFF 0
|
||||
|
|
Loading…
Reference in a new issue