X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fmmc%2Fhost%2Fomap_hsmmc.c;h=c9401efd11371916153e8d1894983e679d12b428;hb=b417577d3b9bbb06a4ddc9aa955af9bd503f7242;hp=2c5e15d9f864890cf1ac596fab7cb30659457dab;hpb=db0fefc5119e2cfaa8f57565331e0abe47f0801e;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 2c5e15d..c9401ef 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -157,12 +157,10 @@ struct omap_hsmmc_host { */ struct regulator *vcc; struct regulator *vcc_aux; - struct semaphore sem; struct work_struct mmc_carddetect_work; void __iomem *base; resource_size_t mapbase; spinlock_t irq_lock; /* Prevent races with irq handler */ - unsigned long flags; unsigned int id; unsigned int dma_len; unsigned int dma_sg_idx; @@ -183,6 +181,7 @@ struct omap_hsmmc_host { int protect_card; int reqs_blocked; int use_reg; + int req_in_progress; struct omap_mmc_platform_data *pdata; }; @@ -236,6 +235,8 @@ static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) #endif +#ifdef CONFIG_REGULATOR + static int omap_hsmmc_1_set_power(struct device *dev, int slot, int power_on, int vdd) { @@ -296,11 +297,8 @@ static int omap_hsmmc_23_set_power(struct device *dev, int slot, int power_on, ret = mmc_regulator_set_ocr(host->vcc, 0); } } else { - if (host->vcc_aux) { - ret = regulator_is_enabled(host->vcc_aux); - if (ret > 0) - ret = regulator_disable(host->vcc_aux); - } + if (host->vcc_aux) + ret = regulator_disable(host->vcc_aux); if (ret == 0) ret = mmc_regulator_set_ocr(host->vcc, 0); } @@ -350,60 +348,14 @@ static int omap_hsmmc_23_set_sleep(struct device *dev, int slot, int sleep, err = regulator_set_mode(host->vcc, mode); if (err) return err; - return regulator_set_mode(host->vcc_aux, mode); -} - -static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) -{ - int ret; - if (gpio_is_valid(pdata->slots[0].switch_pin)) { - pdata->suspend = omap_hsmmc_suspend_cdirq; - pdata->resume = omap_hsmmc_resume_cdirq; - if (pdata->slots[0].cover) - pdata->slots[0].get_cover_state = - omap_hsmmc_get_cover_state; - else - pdata->slots[0].card_detect = omap_hsmmc_card_detect; - pdata->slots[0].card_detect_irq = - gpio_to_irq(pdata->slots[0].switch_pin); - ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd"); - if (ret) - return ret; - ret = gpio_direction_input(pdata->slots[0].switch_pin); - if (ret) - goto err_free_sp; - } else - pdata->slots[0].switch_pin = -EINVAL; + if (!mmc_slot(host).vcc_aux_disable_is_sleep) + return regulator_set_mode(host->vcc_aux, mode); - if (gpio_is_valid(pdata->slots[0].gpio_wp)) { - pdata->slots[0].get_ro = omap_hsmmc_get_wp; - ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp"); - if (ret) - goto err_free_cd; - ret = gpio_direction_input(pdata->slots[0].gpio_wp); - if (ret) - goto err_free_wp; - } else - pdata->slots[0].gpio_wp = -EINVAL; - - return 0; - -err_free_wp: - gpio_free(pdata->slots[0].gpio_wp); -err_free_cd: - if (gpio_is_valid(pdata->slots[0].switch_pin)) -err_free_sp: - gpio_free(pdata->slots[0].switch_pin); - return ret; -} - -static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata) -{ - if (gpio_is_valid(pdata->slots[0].gpio_wp)) - gpio_free(pdata->slots[0].gpio_wp); - if (gpio_is_valid(pdata->slots[0].switch_pin)) - gpio_free(pdata->slots[0].switch_pin); + if (sleep) + return regulator_disable(host->vcc_aux); + else + return regulator_enable(host->vcc_aux); } static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) @@ -484,6 +436,82 @@ static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) mmc_slot(host).set_sleep = NULL; } +static inline int omap_hsmmc_have_reg(void) +{ + return 1; +} + +#else + +static inline int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) +{ + return -EINVAL; +} + +static inline void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) +{ +} + +static inline int omap_hsmmc_have_reg(void) +{ + return 0; +} + +#endif + +static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) +{ + int ret; + + if (gpio_is_valid(pdata->slots[0].switch_pin)) { + pdata->suspend = omap_hsmmc_suspend_cdirq; + pdata->resume = omap_hsmmc_resume_cdirq; + if (pdata->slots[0].cover) + pdata->slots[0].get_cover_state = + omap_hsmmc_get_cover_state; + else + pdata->slots[0].card_detect = omap_hsmmc_card_detect; + pdata->slots[0].card_detect_irq = + gpio_to_irq(pdata->slots[0].switch_pin); + ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd"); + if (ret) + return ret; + ret = gpio_direction_input(pdata->slots[0].switch_pin); + if (ret) + goto err_free_sp; + } else + pdata->slots[0].switch_pin = -EINVAL; + + if (gpio_is_valid(pdata->slots[0].gpio_wp)) { + pdata->slots[0].get_ro = omap_hsmmc_get_wp; + ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp"); + if (ret) + goto err_free_cd; + ret = gpio_direction_input(pdata->slots[0].gpio_wp); + if (ret) + goto err_free_wp; + } else + pdata->slots[0].gpio_wp = -EINVAL; + + return 0; + +err_free_wp: + gpio_free(pdata->slots[0].gpio_wp); +err_free_cd: + if (gpio_is_valid(pdata->slots[0].switch_pin)) +err_free_sp: + gpio_free(pdata->slots[0].switch_pin); + return ret; +} + +static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata) +{ + if (gpio_is_valid(pdata->slots[0].gpio_wp)) + gpio_free(pdata->slots[0].gpio_wp); + if (gpio_is_valid(pdata->slots[0].switch_pin)) + gpio_free(pdata->slots[0].switch_pin); +} + /* * Stop clock to the card */ @@ -495,6 +523,27 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host) dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n"); } +static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host) +{ + unsigned int irq_mask; + + if (host->use_dma) + irq_mask = INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE); + else + irq_mask = INT_EN_MASK; + + OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); + OMAP_HSMMC_WRITE(host->base, ISE, irq_mask); + OMAP_HSMMC_WRITE(host->base, IE, irq_mask); +} + +static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host) +{ + OMAP_HSMMC_WRITE(host->base, ISE, 0); + OMAP_HSMMC_WRITE(host->base, IE, 0); + OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); +} + #ifdef CONFIG_PM /* @@ -563,9 +612,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) && time_before(jiffies, timeout)) ; - OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); + omap_hsmmc_disable_irq(host); /* Do not initialize card-specific things if the power is off */ if (host->power_mode == MMC_POWER_OFF) @@ -668,6 +715,8 @@ static void send_init_stream(struct omap_hsmmc_host *host) return; disable_irq(host->irq); + + OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); OMAP_HSMMC_WRITE(host->base, CON, OMAP_HSMMC_READ(host->base, CON) | INIT_STREAM); OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD); @@ -733,17 +782,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, mmc_hostname(host->mmc), cmd->opcode, cmd->arg); host->cmd = cmd; - /* - * Clear status bits and enable interrupts - */ - OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); - - if (host->use_dma) - OMAP_HSMMC_WRITE(host->base, IE, - INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE)); - else - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); + omap_hsmmc_enable_irq(host); host->response_busy = 0; if (cmd->flags & MMC_RSP_PRESENT) { @@ -777,13 +816,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, if (host->use_dma) cmdreg |= DMA_EN; - /* - * In an interrupt context (i.e. STOP command), the spinlock is unlocked - * by the interrupt handler, otherwise (i.e. for a new request) it is - * unlocked here. - */ - if (!in_interrupt()) - spin_unlock_irqrestore(&host->irq_lock, host->flags); + host->req_in_progress = 1; OMAP_HSMMC_WRITE(host->base, ARG, cmd->arg); OMAP_HSMMC_WRITE(host->base, CMD, cmdreg); @@ -798,6 +831,23 @@ omap_hsmmc_get_dma_dir(struct omap_hsmmc_host *host, struct mmc_data *data) return DMA_FROM_DEVICE; } +static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_request *mrq) +{ + int dma_ch; + + spin_lock(&host->irq_lock); + host->req_in_progress = 0; + dma_ch = host->dma_ch; + spin_unlock(&host->irq_lock); + + omap_hsmmc_disable_irq(host); + /* Do not complete the request if DMA is still in progress */ + if (mrq->data && host->use_dma && dma_ch != -1) + return; + host->mrq = NULL; + mmc_request_done(host->mmc, mrq); +} + /* * Notify the transfer complete to MMC core */ @@ -814,25 +864,19 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) return; } - host->mrq = NULL; - mmc_request_done(host->mmc, mrq); + omap_hsmmc_request_done(host, mrq); return; } host->data = NULL; - if (host->use_dma && host->dma_ch != -1) - dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, - omap_hsmmc_get_dma_dir(host, data)); - if (!data->error) data->bytes_xfered += data->blocks * (data->blksz); else data->bytes_xfered = 0; if (!data->stop) { - host->mrq = NULL; - mmc_request_done(host->mmc, data->mrq); + omap_hsmmc_request_done(host, data->mrq); return; } omap_hsmmc_start_command(host, data->stop, NULL); @@ -858,10 +902,8 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10); } } - if ((host->data == NULL && !host->response_busy) || cmd->error) { - host->mrq = NULL; - mmc_request_done(host->mmc, cmd->mrq); - } + if ((host->data == NULL && !host->response_busy) || cmd->error) + omap_hsmmc_request_done(host, cmd->mrq); } /* @@ -869,14 +911,19 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) */ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) { + int dma_ch; + host->data->error = errno; - if (host->use_dma && host->dma_ch != -1) { + spin_lock(&host->irq_lock); + dma_ch = host->dma_ch; + host->dma_ch = -1; + spin_unlock(&host->irq_lock); + + if (host->use_dma && dma_ch != -1) { dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len, omap_hsmmc_get_dma_dir(host, host->data)); - omap_free_dma(host->dma_ch); - host->dma_ch = -1; - up(&host->sem); + omap_free_dma(dma_ch); } host->data = NULL; } @@ -938,28 +985,21 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, __func__); } -/* - * MMC controller IRQ handler - */ -static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) +static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) { - struct omap_hsmmc_host *host = dev_id; struct mmc_data *data; - int end_cmd = 0, end_trans = 0, status; - - spin_lock(&host->irq_lock); - - if (host->mrq == NULL) { - OMAP_HSMMC_WRITE(host->base, STAT, - OMAP_HSMMC_READ(host->base, STAT)); - /* Flush posted write */ - OMAP_HSMMC_READ(host->base, STAT); - spin_unlock(&host->irq_lock); - return IRQ_HANDLED; + int end_cmd = 0, end_trans = 0; + + if (!host->req_in_progress) { + do { + OMAP_HSMMC_WRITE(host->base, STAT, status); + /* Flush posted write */ + status = OMAP_HSMMC_READ(host->base, STAT); + } while (status & INT_EN_MASK); + return; } data = host->data; - status = OMAP_HSMMC_READ(host->base, STAT); dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); if (status & ERR) { @@ -1012,15 +1052,27 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) } OMAP_HSMMC_WRITE(host->base, STAT, status); - /* Flush posted write */ - OMAP_HSMMC_READ(host->base, STAT); if (end_cmd || ((status & CC) && host->cmd)) omap_hsmmc_cmd_done(host, host->cmd); if ((end_trans || (status & TC)) && host->mrq) omap_hsmmc_xfer_done(host, data); +} - spin_unlock(&host->irq_lock); +/* + * MMC controller IRQ handler + */ +static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) +{ + struct omap_hsmmc_host *host = dev_id; + int status; + + status = OMAP_HSMMC_READ(host->base, STAT); + do { + omap_hsmmc_do_irq(host, status); + /* Flush posted write */ + status = OMAP_HSMMC_READ(host->base, STAT); + } while (status & INT_EN_MASK); return IRQ_HANDLED; } @@ -1150,15 +1202,10 @@ static void omap_hsmmc_detect(struct work_struct *work) carddetect = -ENOSYS; } - if (carddetect) { + if (carddetect) mmc_detect_change(host->mmc, (HZ * 200) / 1000); - } else { - mmc_host_enable(host->mmc); - omap_hsmmc_reset_controller_fsm(host, SRD); - mmc_host_lazy_disable(host->mmc); - + else mmc_detect_change(host->mmc, (HZ * 50) / 1000); - } } /* @@ -1220,31 +1267,47 @@ static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host, /* * DMA call back function */ -static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *data) +static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) { - struct omap_hsmmc_host *host = data; + struct omap_hsmmc_host *host = cb_data; + struct mmc_data *data = host->mrq->data; + int dma_ch, req_in_progress; if (ch_status & OMAP2_DMA_MISALIGNED_ERR_IRQ) dev_dbg(mmc_dev(host->mmc), "MISALIGNED_ADRS_ERR\n"); - if (host->dma_ch < 0) + spin_lock(&host->irq_lock); + if (host->dma_ch < 0) { + spin_unlock(&host->irq_lock); return; + } host->dma_sg_idx++; if (host->dma_sg_idx < host->dma_len) { /* Fire up the next transfer. */ - omap_hsmmc_config_dma_params(host, host->data, - host->data->sg + host->dma_sg_idx); + omap_hsmmc_config_dma_params(host, data, + data->sg + host->dma_sg_idx); + spin_unlock(&host->irq_lock); return; } - omap_free_dma(host->dma_ch); + dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, + omap_hsmmc_get_dma_dir(host, data)); + + req_in_progress = host->req_in_progress; + dma_ch = host->dma_ch; host->dma_ch = -1; - /* - * DMA Callback: run in interrupt context. - * mutex_unlock will throw a kernel warning if used. - */ - up(&host->sem); + spin_unlock(&host->irq_lock); + + omap_free_dma(dma_ch); + + /* If DMA has finished after TC, complete the request */ + if (!req_in_progress) { + struct mmc_request *mrq = host->mrq; + + host->mrq = NULL; + mmc_request_done(host->mmc, mrq); + } } /* @@ -1253,7 +1316,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *data) static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, struct mmc_request *req) { - int dma_ch = 0, ret = 0, err = 1, i; + int dma_ch = 0, ret = 0, i; struct mmc_data *data = req->data; /* Sanity check: all the SG entries must be aligned by block size. */ @@ -1270,23 +1333,7 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, */ return -EINVAL; - /* - * If for some reason the DMA transfer is still active, - * we wait for timeout period and free the dma - */ - if (host->dma_ch != -1) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(100); - if (down_trylock(&host->sem)) { - omap_free_dma(host->dma_ch); - host->dma_ch = -1; - up(&host->sem); - return err; - } - } else { - if (down_trylock(&host->sem)) - return err; - } + BUG_ON(host->dma_ch != -1); ret = omap_request_dma(omap_hsmmc_get_dma_sync_dev(host, data), "MMC/SD", omap_hsmmc_dma_cb, host, &dma_ch); @@ -1386,37 +1433,27 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) struct omap_hsmmc_host *host = mmc_priv(mmc); int err; - /* - * Prevent races with the interrupt handler because of unexpected - * interrupts, but not if we are already in interrupt context i.e. - * retries. - */ - if (!in_interrupt()) { - spin_lock_irqsave(&host->irq_lock, host->flags); - /* - * Protect the card from I/O if there is a possibility - * it can be removed. - */ - if (host->protect_card) { - if (host->reqs_blocked < 3) { - /* - * Ensure the controller is left in a consistent - * state by resetting the command and data state - * machines. - */ - omap_hsmmc_reset_controller_fsm(host, SRD); - omap_hsmmc_reset_controller_fsm(host, SRC); - host->reqs_blocked += 1; - } - req->cmd->error = -EBADF; - if (req->data) - req->data->error = -EBADF; - spin_unlock_irqrestore(&host->irq_lock, host->flags); - mmc_request_done(mmc, req); - return; - } else if (host->reqs_blocked) - host->reqs_blocked = 0; - } + BUG_ON(host->req_in_progress); + BUG_ON(host->dma_ch != -1); + if (host->protect_card) { + if (host->reqs_blocked < 3) { + /* + * Ensure the controller is left in a consistent + * state by resetting the command and data state + * machines. + */ + omap_hsmmc_reset_controller_fsm(host, SRD); + omap_hsmmc_reset_controller_fsm(host, SRC); + host->reqs_blocked += 1; + } + req->cmd->error = -EBADF; + if (req->data) + req->data->error = -EBADF; + req->cmd->retries = 0; + mmc_request_done(mmc, req); + return; + } else if (host->reqs_blocked) + host->reqs_blocked = 0; WARN_ON(host->mrq != NULL); host->mrq = req; err = omap_hsmmc_prepare_data(host, req); @@ -1425,8 +1462,6 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) if (req->data) req->data->error = err; host->mrq = NULL; - if (!in_interrupt()) - spin_unlock_irqrestore(&host->irq_lock, host->flags); mmc_request_done(mmc, req); return; } @@ -1620,7 +1655,7 @@ static int omap_hsmmc_enabled_to_disabled(struct omap_hsmmc_host *host) if (host->power_mode == MMC_POWER_OFF) return 0; - return msecs_to_jiffies(OMAP_MMC_SLEEP_TIMEOUT); + return OMAP_MMC_SLEEP_TIMEOUT; } /* Handler for [DISABLED -> REGSLEEP / CARDSLEEP] transition */ @@ -1656,11 +1691,14 @@ static int omap_hsmmc_disabled_to_sleep(struct omap_hsmmc_host *host) dev_dbg(mmc_dev(host->mmc), "DISABLED -> %s\n", host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP"); + if (mmc_slot(host).no_off) + return 0; + if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) || mmc_slot(host).card_detect || (mmc_slot(host).get_cover_state && mmc_slot(host).get_cover_state(host->dev, host->slot_id))) - return msecs_to_jiffies(OMAP_MMC_OFF_TIMEOUT); + return OMAP_MMC_OFF_TIMEOUT; return 0; } @@ -1671,6 +1709,9 @@ static int omap_hsmmc_sleep_to_off(struct omap_hsmmc_host *host) if (!mmc_try_claim_host(host->mmc)) return 0; + if (mmc_slot(host).no_off) + return 0; + if (!((host->mmc->caps & MMC_CAP_NONREMOVABLE) || mmc_slot(host).card_detect || (mmc_slot(host).get_cover_state && @@ -1969,7 +2010,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) host->slot_id = 0; host->mapbase = res->start; host->base = ioremap(host->mapbase, SZ_4K); - host->power_mode = -1; + host->power_mode = MMC_POWER_OFF; platform_set_drvdata(pdev, host); INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); @@ -1979,10 +2020,16 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) else mmc->ops = &omap_hsmmc_ops; + /* + * If regulator_disable can only put vcc_aux to sleep then there is + * no off state. + */ + if (mmc_slot(host).vcc_aux_disable_is_sleep) + mmc_slot(host).no_off = 1; + mmc->f_min = 400000; mmc->f_max = 52000000; - sema_init(&host->sem, 1); spin_lock_init(&host->irq_lock); host->iclk = clk_get(&pdev->dev, "ick"); @@ -2102,7 +2149,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) } } - if (!mmc_slot(host).set_power) { + if (omap_hsmmc_have_reg() && !mmc_slot(host).set_power) { ret = omap_hsmmc_reg_get(host); if (ret) goto err_reg; @@ -2125,8 +2172,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) } } - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); + omap_hsmmc_disable_irq(host); mmc_host_lazy_disable(host->mmc); @@ -2246,10 +2292,7 @@ static int omap_hsmmc_suspend(struct platform_device *pdev, pm_message_t state) mmc_host_enable(host->mmc); ret = mmc_suspend_host(host->mmc, state); if (ret == 0) { - OMAP_HSMMC_WRITE(host->base, ISE, 0); - OMAP_HSMMC_WRITE(host->base, IE, 0); - - + omap_hsmmc_disable_irq(host); OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); mmc_host_disable(host->mmc);