static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
{
int sg_len;
+ unsigned long flags;
u32 temp;
host->using_dma = 0;
mci_writel(host, CTRL, temp);
/* Disable RX/TX IRQs, let DMA handle it */
+ spin_lock_irqsave(&host->slock, flags);
temp = mci_readl(host, INTMASK);
temp &= ~(SDMMC_INT_RXDR | SDMMC_INT_TXDR);
mci_writel(host, INTMASK, temp);
+ spin_unlock_irqrestore(&host->slock, flags);
host->dma_ops->start(host, sg_len);
static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
{
u32 temp;
+ unsigned long flag;
data->error = -EINPROGRESS;
host->part_buf_start = 0;
host->part_buf_count = 0;
+ spin_lock_irqsave(&host->slock, flag);
mci_writel(host, RINTSTS, SDMMC_INT_TXDR | SDMMC_INT_RXDR);
temp = mci_readl(host, INTMASK);
temp |= SDMMC_INT_TXDR | SDMMC_INT_RXDR;
mci_writel(host, INTMASK, temp);
+ spin_unlock_irqrestore(&host->slock, flag);
temp = mci_readl(host, CTRL);
temp &= ~SDMMC_CTRL_DMA_ENABLE;
{
struct dw_mci_slot *slot = mmc_priv(mmc);
struct dw_mci *host = slot->host;
- //unsigned long flags;
+ unsigned long flags;
u32 int_mask;
u32 sdio_int;
- //spin_lock_irqsave(&host->lock, flags);
+ spin_lock_irqsave(&host->slock, flags);
/* Enable/disable Slot Specific SDIO interrupt */
int_mask = mci_readl(host, INTMASK);
(int_mask & ~sdio_int));
}
- //spin_unlock_irqrestore(&host->lock, flags);
+ spin_unlock_irqrestore(&host->slock, flags);
}
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
static void dw_mci_dealwith_timeout(struct dw_mci *host)
{
u32 ret, i, regs;
+ u32 sdio_int;
switch(host->state){
case STATE_IDLE:
| SDMMC_INT_RXDR | SDMMC_INT_VSI | DW_MCI_ERROR_FLAGS;
if(!(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO))
regs |= SDMMC_INT_CD;
- mci_writel(host, INTMASK, regs);
+
+ if ((host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)) {
+ if (host->verid < DW_MMC_240A)
+ sdio_int = SDMMC_INT_SDIO(0);
+ else
+ sdio_int = SDMMC_INT_SDIO(8);
+
+ if (mci_readl(host, INTMASK) & sdio_int)
+ regs |= sdio_int;
+ }
+
+ mci_writel(host, INTMASK, regs);
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE);
for (i = 0; i < host->num_slots; i++) {
struct dw_mci_slot *slot = host->slot[i];
disable_irq(host->irq);
+ dev_err(host->dev, "data_over interrupt timeout!\n");
host->data_status = SDMMC_INT_EBE;
mci_writel(host, RINTSTS, 0xFFFFFFFF);
dw_mci_dealwith_timeout(host);
host->svi_flags = 0;
spin_lock_init(&host->lock);
+ spin_lock_init(&host->slock);
+
INIT_LIST_HEAD(&host->queue);
INIT_DELAYED_WORK(&host->resume_rescan, resume_rescan_enable);
/*