mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
mmc: add atomic operation for register
This commit is contained in:
@@ -872,6 +872,7 @@ disable:
|
||||
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;
|
||||
@@ -910,9 +911,11 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
|
||||
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);
|
||||
|
||||
@@ -922,6 +925,7 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
|
||||
static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
|
||||
{
|
||||
u32 temp;
|
||||
unsigned long flag;
|
||||
|
||||
data->error = -EINPROGRESS;
|
||||
|
||||
@@ -954,10 +958,12 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
|
||||
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;
|
||||
@@ -1704,11 +1710,11 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
|
||||
{
|
||||
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);
|
||||
@@ -1734,7 +1740,7 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
|
||||
(int_mask & ~sdio_int));
|
||||
}
|
||||
|
||||
//spin_unlock_irqrestore(&host->lock, flags);
|
||||
spin_unlock_irqrestore(&host->slock, flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
@@ -3700,6 +3706,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
|
||||
static void dw_mci_dealwith_timeout(struct dw_mci *host)
|
||||
{
|
||||
u32 ret, i, regs;
|
||||
u32 sdio_int;
|
||||
|
||||
switch(host->state){
|
||||
case STATE_IDLE:
|
||||
@@ -3734,7 +3741,18 @@ static void dw_mci_dealwith_timeout(struct dw_mci *host)
|
||||
| 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];
|
||||
@@ -3758,6 +3776,7 @@ static void dw_mci_dto_timeout(unsigned long host_data)
|
||||
|
||||
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);
|
||||
@@ -3862,6 +3881,8 @@ int dw_mci_probe(struct dw_mci *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);
|
||||
/*
|
||||
|
||||
@@ -128,6 +128,7 @@ struct mmc_data;
|
||||
*/
|
||||
struct dw_mci {
|
||||
spinlock_t lock;
|
||||
spinlock_t slock;
|
||||
void __iomem *regs;
|
||||
|
||||
struct scatterlist *sg;
|
||||
|
||||
Reference in New Issue
Block a user