diff options
-rw-r--r-- | drivers/mmc/host/Kconfig | 7 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 159 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 95 |
3 files changed, 180 insertions, 81 deletions
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 092baf66733..e8a7b50a01e 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -37,6 +37,13 @@ config MMC_SDHCI If unsure, say N. +config MMC_SDHCI_IO_ACCESSORS + bool + depends on MMC_SDHCI + help + This is silent Kconfig symbol that is selected by the drivers that + need to overwrite SDHCI IO memory accessors. + config MMC_SDHCI_PCI tristate "SDHCI support on PCI bus" depends on MMC_SDHCI && PCI diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index accb592764e..fd36b822f80 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -48,35 +48,35 @@ static void sdhci_dumpregs(struct sdhci_host *host) printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n"); printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", - readl(host->ioaddr + SDHCI_DMA_ADDRESS), - readw(host->ioaddr + SDHCI_HOST_VERSION)); + sdhci_readl(host, SDHCI_DMA_ADDRESS), + sdhci_readw(host, SDHCI_HOST_VERSION)); printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", - readw(host->ioaddr + SDHCI_BLOCK_SIZE), - readw(host->ioaddr + SDHCI_BLOCK_COUNT)); + sdhci_readw(host, SDHCI_BLOCK_SIZE), + sdhci_readw(host, SDHCI_BLOCK_COUNT)); printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", - readl(host->ioaddr + SDHCI_ARGUMENT), - readw(host->ioaddr + SDHCI_TRANSFER_MODE)); + sdhci_readl(host, SDHCI_ARGUMENT), + sdhci_readw(host, SDHCI_TRANSFER_MODE)); printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", - readl(host->ioaddr + SDHCI_PRESENT_STATE), - readb(host->ioaddr + SDHCI_HOST_CONTROL)); + sdhci_readl(host, SDHCI_PRESENT_STATE), + sdhci_readb(host, SDHCI_HOST_CONTROL)); printk(KERN_DEBUG DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n", - readb(host->ioaddr + SDHCI_POWER_CONTROL), - readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL)); + sdhci_readb(host, SDHCI_POWER_CONTROL), + sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL)); printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", - readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL), - readw(host->ioaddr + SDHCI_CLOCK_CONTROL)); + sdhci_readb(host, SDHCI_WAKE_UP_CONTROL), + sdhci_readw(host, SDHCI_CLOCK_CONTROL)); printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", - readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL), - readl(host->ioaddr + SDHCI_INT_STATUS)); + sdhci_readb(host, SDHCI_TIMEOUT_CONTROL), + sdhci_readl(host, SDHCI_INT_STATUS)); printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", - readl(host->ioaddr + SDHCI_INT_ENABLE), - readl(host->ioaddr + SDHCI_SIGNAL_ENABLE)); + sdhci_readl(host, SDHCI_INT_ENABLE), + sdhci_readl(host, SDHCI_SIGNAL_ENABLE)); printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", - readw(host->ioaddr + SDHCI_ACMD12_ERR), - readw(host->ioaddr + SDHCI_SLOT_INT_STATUS)); + sdhci_readw(host, SDHCI_ACMD12_ERR), + sdhci_readw(host, SDHCI_SLOT_INT_STATUS)); printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n", - readl(host->ioaddr + SDHCI_CAPABILITIES), - readl(host->ioaddr + SDHCI_MAX_CURRENT)); + sdhci_readl(host, SDHCI_CAPABILITIES), + sdhci_readl(host, SDHCI_MAX_CURRENT)); printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); } @@ -92,12 +92,12 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) unsigned long timeout; if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { - if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & + if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) return; } - writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET); + sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET); if (mask & SDHCI_RESET_ALL) host->clock = 0; @@ -106,7 +106,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) timeout = 100; /* hw clears the bit when it's done */ - while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) { + while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) { if (timeout == 0) { printk(KERN_ERR "%s: Reset 0x%x never completed.\n", mmc_hostname(host->mmc), (int)mask); @@ -132,26 +132,26 @@ static void sdhci_init(struct sdhci_host *host) SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE | SDHCI_INT_ADMA_ERROR; - writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); - writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); + sdhci_writel(host, intmask, SDHCI_INT_ENABLE); + sdhci_writel(host, intmask, SDHCI_SIGNAL_ENABLE); } static void sdhci_activate_led(struct sdhci_host *host) { u8 ctrl; - ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); ctrl |= SDHCI_CTRL_LED; - writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); } static void sdhci_deactivate_led(struct sdhci_host *host) { u8 ctrl; - ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); ctrl &= ~SDHCI_CTRL_LED; - writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); } #ifdef SDHCI_USE_LEDS_CLASS @@ -205,7 +205,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host) while (len) { if (chunk == 0) { - scratch = readl(host->ioaddr + SDHCI_BUFFER); + scratch = sdhci_readl(host, SDHCI_BUFFER); chunk = 4; } @@ -257,7 +257,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host) len--; if ((chunk == 4) || ((len == 0) && (blksize == 0))) { - writel(scratch, host->ioaddr + SDHCI_BUFFER); + sdhci_writel(host, scratch, SDHCI_BUFFER); chunk = 0; scratch = 0; } @@ -292,7 +292,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host) (host->data->blocks == 1)) mask = ~0; - while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { + while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { if (host->data->flags & MMC_DATA_READ) sdhci_read_block_pio(host); else @@ -581,7 +581,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) host->data_early = 0; count = sdhci_calc_timeout(host, data); - writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL); + sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); if (host->flags & SDHCI_USE_DMA) host->flags |= SDHCI_REQ_USE_DMA; @@ -661,8 +661,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) WARN_ON(1); host->flags &= ~SDHCI_REQ_USE_DMA; } else { - writel(host->adma_addr, - host->ioaddr + SDHCI_ADMA_ADDRESS); + sdhci_writel(host, host->adma_addr, + SDHCI_ADMA_ADDRESS); } } else { int sg_cnt; @@ -681,8 +681,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) host->flags &= ~SDHCI_REQ_USE_DMA; } else { WARN_ON(sg_cnt != 1); - writel(sg_dma_address(data->sg), - host->ioaddr + SDHCI_DMA_ADDRESS); + sdhci_writel(host, sg_dma_address(data->sg), + SDHCI_DMA_ADDRESS); } } } @@ -693,14 +693,14 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) * is ADMA. */ if (host->version >= SDHCI_SPEC_200) { - ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); ctrl &= ~SDHCI_CTRL_DMA_MASK; if ((host->flags & SDHCI_REQ_USE_DMA) && (host->flags & SDHCI_USE_ADMA)) ctrl |= SDHCI_CTRL_ADMA32; else ctrl |= SDHCI_CTRL_SDMA; - writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); } if (!(host->flags & SDHCI_REQ_USE_DMA)) { @@ -710,9 +710,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) } /* We do not handle DMA boundaries, so set it to max (512 KiB) */ - writew(SDHCI_MAKE_BLKSZ(7, data->blksz), - host->ioaddr + SDHCI_BLOCK_SIZE); - writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT); + sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE); + sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT); } static void sdhci_set_transfer_mode(struct sdhci_host *host, @@ -733,7 +732,7 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, if (host->flags & SDHCI_REQ_USE_DMA) mode |= SDHCI_TRNS_DMA; - writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); + sdhci_writew(host, mode, SDHCI_TRANSFER_MODE); } static void sdhci_finish_data(struct sdhci_host *host) @@ -802,7 +801,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) if (host->mrq->data && (cmd == host->mrq->data->stop)) mask &= ~SDHCI_DATA_INHIBIT; - while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { + while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { if (timeout == 0) { printk(KERN_ERR "%s: Controller never released " "inhibit bit(s).\n", mmc_hostname(host->mmc)); @@ -821,7 +820,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) sdhci_prepare_data(host, cmd->data); - writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT); + sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); sdhci_set_transfer_mode(host, cmd->data); @@ -849,8 +848,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) if (cmd->data) flags |= SDHCI_CMD_DATA; - writew(SDHCI_MAKE_CMD(cmd->opcode, flags), - host->ioaddr + SDHCI_COMMAND); + sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); } static void sdhci_finish_command(struct sdhci_host *host) @@ -863,15 +861,15 @@ static void sdhci_finish_command(struct sdhci_host *host) if (host->cmd->flags & MMC_RSP_136) { /* CRC is stripped so we need to do some shifting. */ for (i = 0;i < 4;i++) { - host->cmd->resp[i] = readl(host->ioaddr + + host->cmd->resp[i] = sdhci_readl(host, SDHCI_RESPONSE + (3-i)*4) << 8; if (i != 3) host->cmd->resp[i] |= - readb(host->ioaddr + + sdhci_readb(host, SDHCI_RESPONSE + (3-i)*4-1); } } else { - host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE); + host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE); } } @@ -895,7 +893,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) if (clock == host->clock) return; - writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); if (clock == 0) goto out; @@ -908,11 +906,11 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) clk = div << SDHCI_DIVIDER_SHIFT; clk |= SDHCI_CLOCK_INT_EN; - writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); /* Wait max 10 ms */ timeout = 10; - while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL)) + while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) & SDHCI_CLOCK_INT_STABLE)) { if (timeout == 0) { printk(KERN_ERR "%s: Internal clock never " @@ -925,7 +923,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) } clk |= SDHCI_CLOCK_CARD_EN; - writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); out: host->clock = clock; @@ -939,7 +937,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) return; if (power == (unsigned short)-1) { - writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); goto out; } @@ -948,7 +946,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) * a new value. Some controllers don't seem to like this though. */ if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) - writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); pwr = SDHCI_POWER_ON; @@ -973,10 +971,9 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) * and set turn on power at the same time, so set the voltage first. */ if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)) - writeb(pwr & ~SDHCI_POWER_ON, - host->ioaddr + SDHCI_POWER_CONTROL); + sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL); - writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL); + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); out: host->power = power; @@ -1005,7 +1002,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) host->mrq = mrq; - if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT) + if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT) || (host->flags & SDHCI_DEVICE_DEAD)) { host->mrq->cmd->error = -ENOMEDIUM; tasklet_schedule(&host->finish_tasklet); @@ -1034,7 +1031,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * Should clear out any weird states. */ if (ios->power_mode == MMC_POWER_OFF) { - writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE); + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); sdhci_init(host); } @@ -1045,7 +1042,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) else sdhci_set_power(host, ios->vdd); - ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); if (ios->bus_width == MMC_BUS_WIDTH_4) ctrl |= SDHCI_CTRL_4BITBUS; @@ -1057,7 +1054,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) else ctrl &= ~SDHCI_CTRL_HISPD; - writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); /* * Some (ENE) controllers go apeshit on some ios operation, @@ -1085,7 +1082,7 @@ static int sdhci_get_ro(struct mmc_host *mmc) if (host->flags & SDHCI_DEVICE_DEAD) present = 0; else - present = readl(host->ioaddr + SDHCI_PRESENT_STATE); + present = sdhci_readl(host, SDHCI_PRESENT_STATE); spin_unlock_irqrestore(&host->lock, flags); @@ -1105,14 +1102,14 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) if (host->flags & SDHCI_DEVICE_DEAD) goto out; - ier = readl(host->ioaddr + SDHCI_INT_ENABLE); + ier = sdhci_readl(host, SDHCI_INT_ENABLE); ier &= ~SDHCI_INT_CARD_INT; if (enable) ier |= SDHCI_INT_CARD_INT; - writel(ier, host->ioaddr + SDHCI_INT_ENABLE); - writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE); + sdhci_writel(host, ier, SDHCI_INT_ENABLE); + sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE); out: mmiowb(); @@ -1142,7 +1139,7 @@ static void sdhci_tasklet_card(unsigned long param) spin_lock_irqsave(&host->lock, flags); - if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { + if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { if (host->mrq) { printk(KERN_ERR "%s: Card removed during transfer!\n", mmc_hostname(host->mmc)); @@ -1346,8 +1343,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) * we need to at least restart the transfer. */ if (intmask & SDHCI_INT_DMA_END) - writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), - host->ioaddr + SDHCI_DMA_ADDRESS); + sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS), + SDHCI_DMA_ADDRESS); if (intmask & SDHCI_INT_DATA_END) { if (host->cmd) { @@ -1373,7 +1370,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) spin_lock(&host->lock); - intmask = readl(host->ioaddr + SDHCI_INT_STATUS); + intmask = sdhci_readl(host, SDHCI_INT_STATUS); if (!intmask || intmask == 0xffffffff) { result = IRQ_NONE; @@ -1384,22 +1381,22 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) mmc_hostname(host->mmc), intmask); if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { - writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE), - host->ioaddr + SDHCI_INT_STATUS); + sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT | + SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS); tasklet_schedule(&host->card_tasklet); } intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE); if (intmask & SDHCI_INT_CMD_MASK) { - writel(intmask & SDHCI_INT_CMD_MASK, - host->ioaddr + SDHCI_INT_STATUS); + sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK, + SDHCI_INT_STATUS); sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); } if (intmask & SDHCI_INT_DATA_MASK) { - writel(intmask & SDHCI_INT_DATA_MASK, - host->ioaddr + SDHCI_INT_STATUS); + sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK, + SDHCI_INT_STATUS); sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK); } @@ -1410,7 +1407,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) if (intmask & SDHCI_INT_BUS_POWER) { printk(KERN_ERR "%s: Card is consuming too much power!\n", mmc_hostname(host->mmc)); - writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS); + sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS); } intmask &= ~SDHCI_INT_BUS_POWER; @@ -1425,7 +1422,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) mmc_hostname(host->mmc), intmask); sdhci_dumpregs(host); - writel(intmask, host->ioaddr + SDHCI_INT_STATUS); + sdhci_writel(host, intmask, SDHCI_INT_STATUS); } result = IRQ_HANDLED; @@ -1537,7 +1534,7 @@ int sdhci_add_host(struct sdhci_host *host) sdhci_reset(host, SDHCI_RESET_ALL); - host->version = readw(host->ioaddr + SDHCI_HOST_VERSION); + host->version = sdhci_readw(host, SDHCI_HOST_VERSION); host->version = (host->version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; if (host->version > SDHCI_SPEC_200) { @@ -1546,7 +1543,7 @@ int sdhci_add_host(struct sdhci_host *host) host->version); } - caps = readl(host->ioaddr + SDHCI_CAPABILITIES); + caps = sdhci_readl(host, SDHCI_CAPABILITIES); if (host->quirks & SDHCI_QUIRK_FORCE_DMA) host->flags |= SDHCI_USE_DMA; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 43c37c68d07..d9733f84106 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -10,6 +10,9 @@ */ #include <linux/scatterlist.h> +#include <linux/compiler.h> +#include <linux/types.h> +#include <linux/io.h> /* * Controller registers @@ -267,9 +270,101 @@ struct sdhci_host { struct sdhci_ops { +#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS + u32 (*readl)(struct sdhci_host *host, int reg); + u16 (*readw)(struct sdhci_host *host, int reg); + u8 (*readb)(struct sdhci_host *host, int reg); + void (*writel)(struct sdhci_host *host, u32 val, int reg); + void (*writew)(struct sdhci_host *host, u16 val, int reg); + void (*writeb)(struct sdhci_host *host, u8 val, int reg); +#endif + int (*enable_dma)(struct sdhci_host *host); }; +#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS + +static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg) +{ + if (unlikely(host->ops->writel)) + host->ops->writel(host, val, reg); + else + writel(val, host->ioaddr + reg); +} + +static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg) +{ + if (unlikely(host->ops->writew)) + host->ops->writew(host, val, reg); + else + writew(val, host->ioaddr + reg); +} + +static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg) +{ + if (unlikely(host->ops->writeb)) + host->ops->writeb(host, val, reg); + else + writeb(val, host->ioaddr + reg); +} + +static inline u32 sdhci_readl(struct sdhci_host *host, int reg) +{ + if (unlikely(host->ops->readl)) + return host->ops->readl(host, reg); + else + return readl(host->ioaddr + reg); +} + +static inline u16 sdhci_readw(struct sdhci_host *host, int reg) +{ + if (unlikely(host->ops->readw)) + return host->ops->readw(host, reg); + else + return readw(host->ioaddr + reg); +} + +static inline u8 sdhci_readb(struct sdhci_host *host, int reg) +{ + if (unlikely(host->ops->readb)) + return host->ops->readb(host, reg); + else + return readb(host->ioaddr + reg); +} + +#else + +static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg) +{ + writel(val, host->ioaddr + reg); +} + +static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg) +{ + writew(val, host->ioaddr + reg); +} + +static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg) +{ + writeb(val, host->ioaddr + reg); +} + +static inline u32 sdhci_readl(struct sdhci_host *host, int reg) +{ + return readl(host->ioaddr + reg); +} + +static inline u16 sdhci_readw(struct sdhci_host *host, int reg) +{ + return readw(host->ioaddr + reg); +} + +static inline u8 sdhci_readb(struct sdhci_host *host, int reg) +{ + return readb(host->ioaddr + reg); +} + +#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */ extern struct sdhci_host *sdhci_alloc_host(struct device *dev, size_t priv_size); |