Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 322509
b: refs/heads/master
c: 9623b5b
h: refs/heads/master
i:
  322507: a95d467
v: v3
  • Loading branch information
Doug Anderson authored and Chris Ball committed Sep 4, 2012
1 parent 19b13ac commit e882b3e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e74f3a9c993a088f0a067e13941075e4acb7300a
refs/heads/master: 9623b5b9192b349bcadb31cce159072a78ac6972
41 changes: 38 additions & 3 deletions trunk/drivers/mmc/host/dw_mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
{
struct dw_mci *host = slot->host;
u32 div;
u32 clk_en_a;

if (slot->clock != host->current_speed) {
div = host->bus_hz / slot->clock;
Expand Down Expand Up @@ -659,9 +660,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
mci_send_cmd(slot,
SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);

/* enable clock */
mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE |
SDMMC_CLKEN_LOW_PWR) << slot->id));
/* enable clock; only low power if no SDIO */
clk_en_a = SDMMC_CLKEN_ENABLE << slot->id;
if (!(mci_readl(host, INTMASK) & SDMMC_INT_SDIO(slot->id)))
clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id;
mci_writel(host, CLKENA, clk_en_a);

/* inform CIU */
mci_send_cmd(slot,
Expand Down Expand Up @@ -862,6 +865,30 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
return present;
}

/*
* Disable lower power mode.
*
* Low power mode will stop the card clock when idle. According to the
* description of the CLKENA register we should disable low power mode
* for SDIO cards if we need SDIO interrupts to work.
*
* This function is fast if low power mode is already disabled.
*/
static void dw_mci_disable_low_power(struct dw_mci_slot *slot)
{
struct dw_mci *host = slot->host;
u32 clk_en_a;
const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;

clk_en_a = mci_readl(host, CLKENA);

if (clk_en_a & clken_low_pwr) {
mci_writel(host, CLKENA, clk_en_a & ~clken_low_pwr);
mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
SDMMC_CMD_PRV_DAT_WAIT, 0);
}
}

static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
{
struct dw_mci_slot *slot = mmc_priv(mmc);
Expand All @@ -871,6 +898,14 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
/* Enable/disable Slot Specific SDIO interrupt */
int_mask = mci_readl(host, INTMASK);
if (enb) {
/*
* Turn off low power mode if it was enabled. This is a bit of
* a heavy operation and we disable / enable IRQs a lot, so
* we'll leave low power mode disabled and it will get
* re-enabled again in dw_mci_setup_bus().
*/
dw_mci_disable_low_power(slot);

mci_writel(host, INTMASK,
(int_mask | SDMMC_INT_SDIO(slot->id)));
} else {
Expand Down

0 comments on commit e882b3e

Please sign in to comment.