Loading drivers/mmc/mmc.c +12 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); } /* Loading @@ -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); Loading @@ -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); } Loading drivers/mmc/wbsd.c +50 −14 Original line number Diff line number Diff line Loading @@ -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...) \ Loading Loading @@ -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); Loading Loading @@ -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; Loading @@ -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); Loading @@ -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 */ Loading Loading @@ -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); Loading @@ -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) Loading Loading @@ -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 Loading Loading @@ -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); Loading drivers/mmc/wbsd.h +2 −1 Original line number Diff line number Diff line Loading @@ -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 */ }; include/linux/mmc/host.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/mmc/mmc.c +12 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); } /* Loading @@ -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); Loading @@ -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); } Loading
drivers/mmc/wbsd.c +50 −14 Original line number Diff line number Diff line Loading @@ -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...) \ Loading Loading @@ -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); Loading Loading @@ -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; Loading @@ -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); Loading @@ -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 */ Loading Loading @@ -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); Loading @@ -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) Loading Loading @@ -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 Loading Loading @@ -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); Loading
drivers/mmc/wbsd.h +2 −1 Original line number Diff line number Diff line Loading @@ -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 */ };
include/linux/mmc/host.h +6 −0 Original line number Diff line number Diff line Loading @@ -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