summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/Kconfig2
-rw-r--r--drivers/mmc/host/mmci.c156
-rw-r--r--drivers/mmc/host/mmci.h39
-rw-r--r--drivers/mmc/host/mxcmmc.c48
-rw-r--r--drivers/mmc/host/omap.c1
-rw-r--r--drivers/mmc/host/sdhci-s3c.c20
-rw-r--r--drivers/mmc/host/sh_mmcif.c125
7 files changed, 199 insertions, 192 deletions
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index e171e77f6129..f06d06e7fdfa 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -249,7 +249,7 @@ config MMC_IMX
config MMC_MSM7X00A
tristate "Qualcomm MSM 7X00A SDCC Controller Support"
- depends on MMC && ARCH_MSM
+ depends on MMC && ARCH_MSM && !ARCH_MSM7X30
help
This provides support for the SD/MMC cell found in the
MSM 7X00A controllers from Qualcomm.
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 4917af96bae1..840b301b5671 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -26,7 +26,6 @@
#include <linux/amba/mmci.h>
#include <linux/regulator/consumer.h>
-#include <asm/cacheflush.h>
#include <asm/div64.h>
#include <asm/io.h>
#include <asm/sizes.h>
@@ -37,12 +36,39 @@
static unsigned int fmax = 515633;
+/**
+ * struct variant_data - MMCI variant-specific quirks
+ * @clkreg: default value for MCICLOCK register
+ * @clkreg_enable: enable value for MMCICLOCK register
+ * @datalength_bits: number of bits in the MMCIDATALENGTH register
+ */
+struct variant_data {
+ unsigned int clkreg;
+ unsigned int clkreg_enable;
+ unsigned int datalength_bits;
+};
+
+static struct variant_data variant_arm = {
+ .datalength_bits = 16,
+};
+
+static struct variant_data variant_u300 = {
+ .clkreg_enable = 1 << 13, /* HWFCEN */
+ .datalength_bits = 16,
+};
+
+static struct variant_data variant_ux500 = {
+ .clkreg = MCI_CLK_ENABLE,
+ .clkreg_enable = 1 << 14, /* HWFCEN */
+ .datalength_bits = 24,
+};
/*
* This must be called with host->lock held
*/
static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
{
- u32 clk = 0;
+ struct variant_data *variant = host->variant;
+ u32 clk = variant->clkreg;
if (desired) {
if (desired >= host->mclk) {
@@ -54,8 +80,8 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
clk = 255;
host->cclk = host->mclk / (2 * (clk + 1));
}
- if (host->hw_designer == AMBA_VENDOR_ST)
- clk |= MCI_ST_FCEN; /* Bug fix in ST IP block */
+
+ clk |= variant->clkreg_enable;
clk |= MCI_CLK_ENABLE;
/* This hasn't proven to be worthwhile */
/* clk |= MCI_CLK_PWRSAVE; */
@@ -98,6 +124,18 @@ static void mmci_stop_data(struct mmci_host *host)
host->data = NULL;
}
+static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
+{
+ unsigned int flags = SG_MITER_ATOMIC;
+
+ if (data->flags & MMC_DATA_READ)
+ flags |= SG_MITER_TO_SG;
+ else
+ flags |= SG_MITER_FROM_SG;
+
+ sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
+}
+
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
{
unsigned int datactrl, timeout, irqmask;
@@ -109,7 +147,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
data->blksz, data->blocks, data->flags);
host->data = data;
- host->size = data->blksz;
+ host->size = data->blksz * data->blocks;
host->data_xfered = 0;
mmci_init_sg(host, data);
@@ -210,8 +248,17 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
* We hit an error condition. Ensure that any data
* partially written to a page is properly coherent.
*/
- if (host->sg_len && data->flags & MMC_DATA_READ)
- flush_dcache_page(sg_page(host->sg_ptr));
+ if (data->flags & MMC_DATA_READ) {
+ struct sg_mapping_iter *sg_miter = &host->sg_miter;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (sg_miter_next(sg_miter)) {
+ flush_dcache_page(sg_miter->page);
+ sg_miter_stop(sg_miter);
+ }
+ local_irq_restore(flags);
+ }
}
if (status & MCI_DATAEND) {
mmci_stop_data(host);
@@ -314,15 +361,18 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
{
struct mmci_host *host = dev_id;
+ struct sg_mapping_iter *sg_miter = &host->sg_miter;
void __iomem *base = host->base;
+ unsigned long flags;
u32 status;
status = readl(base + MMCISTATUS);
dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status);
+ local_irq_save(flags);
+
do {
- unsigned long flags;
unsigned int remain, len;
char *buffer;
@@ -336,11 +386,11 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL)))
break;
- /*
- * Map the current scatter buffer.
- */
- buffer = mmci_kmap_atomic(host, &flags) + host->sg_off;
- remain = host->sg_ptr->length - host->sg_off;
+ if (!sg_miter_next(sg_miter))
+ break;
+
+ buffer = sg_miter->addr;
+ remain = sg_miter->length;
len = 0;
if (status & MCI_RXACTIVE)
@@ -348,31 +398,24 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
if (status & MCI_TXACTIVE)
len = mmci_pio_write(host, buffer, remain, status);
- /*
- * Unmap the buffer.
- */
- mmci_kunmap_atomic(host, buffer, &flags);
+ sg_miter->consumed = len;
- host->sg_off += len;
host->size -= len;
remain -= len;
if (remain)
break;
- /*
- * If we were reading, and we have completed this
- * page, ensure that the data cache is coherent.
- */
if (status & MCI_RXACTIVE)
- flush_dcache_page(sg_page(host->sg_ptr));
-
- if (!mmci_next_sg(host))
- break;
+ flush_dcache_page(sg_miter->page);
status = readl(base + MMCISTATUS);
} while (1);
+ sg_miter_stop(sg_miter);
+
+ local_irq_restore(flags);
+
/*
* If we're nearing the end of the read, switch to
* "any data available" mode.
@@ -477,16 +520,9 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
/* This implicitly enables the regulator */
mmc_regulator_set_ocr(host->vcc, ios->vdd);
#endif
- /*
- * The translate_vdd function is not used if you have
- * an external regulator, or your design is really weird.
- * Using it would mean sending in power control BOTH using
- * a regulator AND the 4 MMCIPWR bits. If we don't have
- * a regulator, we might have some other platform specific
- * power control behind this translate function.
- */
- if (!host->vcc && host->plat->translate_vdd)
- pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);
+ if (host->plat->vdd_handler)
+ pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd,
+ ios->power_mode);
/* The ST version does not have this, fall through to POWER_ON */
if (host->hw_designer != AMBA_VENDOR_ST) {
pwr |= MCI_PWR_UP;
@@ -539,9 +575,13 @@ static int mmci_get_cd(struct mmc_host *mmc)
if (host->gpio_cd == -ENOSYS)
status = host->plat->status(mmc_dev(host->mmc));
else
- status = gpio_get_value(host->gpio_cd);
+ status = !gpio_get_value(host->gpio_cd);
- return !status;
+ /*
+ * Use positive logic throughout - status is zero for no card,
+ * non-zero for card inserted.
+ */
+ return status;
}
static const struct mmc_host_ops mmci_ops = {
@@ -551,21 +591,10 @@ static const struct mmc_host_ops mmci_ops = {
.get_cd = mmci_get_cd,
};
-static void mmci_check_status(unsigned long data)
-{
- struct mmci_host *host = (struct mmci_host *)data;
- unsigned int status = mmci_get_cd(host->mmc);
-
- if (status ^ host->oldstat)
- mmc_detect_change(host->mmc, 0);
-
- host->oldstat = status;
- mod_timer(&host->timer, jiffies + HZ);
-}
-
static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
{
struct mmci_platform_data *plat = dev->dev.platform_data;
+ struct variant_data *variant = id->data;
struct mmci_host *host;
struct mmc_host *mmc;
int ret;
@@ -609,6 +638,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
goto clk_free;
host->plat = plat;
+ host->variant = variant;
host->mclk = clk_get_rate(host->clk);
/*
* According to the spec, mclk is max 100 MHz,
@@ -669,6 +699,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
if (host->vcc == NULL)
mmc->ocr_avail = plat->ocr_mask;
mmc->caps = plat->capabilities;
+ mmc->caps |= MMC_CAP_NEEDS_POLL;
/*
* We can do SGIO
@@ -677,10 +708,11 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
mmc->max_phys_segs = NR_SG;
/*
- * Since we only have a 16-bit data length register, we must
- * ensure that we don't exceed 2^16-1 bytes in a single request.
+ * Since only a certain number of bits are valid in the data length
+ * register, we must ensure that we don't exceed 2^num-1 bytes in a
+ * single request.
*/
- mmc->max_req_size = 65535;
+ mmc->max_req_size = (1 << variant->datalength_bits) - 1;
/*
* Set the maximum segment size. Since we aren't doing DMA
@@ -734,7 +766,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
writel(MCI_IRQENABLE, host->base + MMCIMASK0);
amba_set_drvdata(dev, mmc);
- host->oldstat = mmci_get_cd(host->mmc);
mmc_add_host(mmc);
@@ -742,12 +773,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
(unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]);
- init_timer(&host->timer);
- host->timer.data = (unsigned long)host;
- host->timer.function = mmci_check_status;
- host->timer.expires = jiffies + HZ;
- add_timer(&host->timer);
-
return 0;
irq0_free:
@@ -781,8 +806,6 @@ static int __devexit mmci_remove(struct amba_device *dev)
if (mmc) {
struct mmci_host *host = mmc_priv(mmc);
- del_timer_sync(&host->timer);
-
mmc_remove_host(mmc);
writel(0, host->base + MMCIMASK0);
@@ -856,19 +879,28 @@ static struct amba_id mmci_ids[] = {
{
.id = 0x00041180,
.mask = 0x000fffff,
+ .data = &variant_arm,
},
{
.id = 0x00041181,
.mask = 0x000fffff,
+ .data = &variant_arm,
},
/* ST Micro variants */
{
.id = 0x00180180,
.mask = 0x00ffffff,
+ .data = &variant_u300,
},
{
.id = 0x00280180,
.mask = 0x00ffffff,
+ .data = &variant_u300,
+ },
+ {
+ .id = 0x00480180,
+ .mask = 0x00ffffff,
+ .data = &variant_ux500,
},
{ 0, 0 },
};
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index d77062e5e3af..68970cfb81e1 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -28,8 +28,6 @@
#define MCI_4BIT_BUS (1 << 11)
/* 8bit wide buses supported in ST Micro versions */
#define MCI_ST_8BIT_BUS (1 << 12)
-/* HW flow control on the ST Micro version */
-#define MCI_ST_FCEN (1 << 13)
#define MMCIARGUMENT 0x008
#define MMCICOMMAND 0x00c
@@ -145,6 +143,7 @@
#define NR_SG 16
struct clk;
+struct variant_data;
struct mmci_host {
void __iomem *base;
@@ -164,6 +163,7 @@ struct mmci_host {
unsigned int cclk;
u32 pwr;
struct mmci_platform_data *plat;
+ struct variant_data *variant;
u8 hw_designer;
u8 hw_revision:4;
@@ -171,42 +171,9 @@ struct mmci_host {
struct timer_list timer;
unsigned int oldstat;
- unsigned int sg_len;
-
/* pio stuff */
- struct scatterlist *sg_ptr;
- unsigned int sg_off;
+ struct sg_mapping_iter sg_miter;
unsigned int size;
struct regulator *vcc;
};
-static inline void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
-{
- /*
- * Ideally, we want the higher levels to pass us a scatter list.
- */
- host->sg_len = data->sg_len;
- host->sg_ptr = data->sg;
- host->sg_off = 0;
-}
-
-static inline int mmci_next_sg(struct mmci_host *host)
-{
- host->sg_ptr++;
- host->sg_off = 0;
- return --host->sg_len;
-}
-
-static inline char *mmci_kmap_atomic(struct mmci_host *host, unsigned long *flags)
-{
- struct scatterlist *sg = host->sg_ptr;
-
- local_irq_save(*flags);
- return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
-}
-
-static inline void mmci_kunmap_atomic(struct mmci_host *host, void *buffer, unsigned long *flags)
-{
- kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
- local_irq_restore(*flags);
-}
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index d9d4a72e0ec7..350f78e86245 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -119,6 +119,7 @@ struct mxcmci_host {
int detect_irq;
int dma;
int do_dma;
+ int default_irq_mask;
int use_sdio;
unsigned int power_mode;
struct imxmmc_platform_data *pdata;
@@ -228,7 +229,7 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
unsigned int cmdat)
{
- u32 int_cntr;
+ u32 int_cntr = host->default_irq_mask;
unsigned long flags;
WARN_ON(host->cmd != NULL);
@@ -275,7 +276,7 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
static void mxcmci_finish_request(struct mxcmci_host *host,
struct mmc_request *req)
{
- u32 int_cntr = 0;
+ u32 int_cntr = host->default_irq_mask;
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
@@ -585,6 +586,9 @@ static irqreturn_t mxcmci_irq(int irq, void *devid)
(stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
mxcmci_data_done(host, stat);
#endif
+ if (host->default_irq_mask &&
+ (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL)))
+ mmc_detect_change(host->mmc, msecs_to_jiffies(200));
return IRQ_HANDLED;
}
@@ -809,6 +813,12 @@ static int mxcmci_probe(struct platform_device *pdev)
else
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+ if (host->pdata && host->pdata->dat3_card_detect)
+ host->default_irq_mask =
+ INT_CARD_INSERTION_EN | INT_CARD_REMOVAL_EN;
+ else
+ host->default_irq_mask = 0;
+
host->res = r;
host->irq = irq;
@@ -835,7 +845,7 @@ static int mxcmci_probe(struct platform_device *pdev)
/* recommended in data sheet */
writew(0x2db4, host->base + MMC_REG_READ_TO);
- writel(0, host->base + MMC_REG_INT_CNTR);
+ writel(host->default_irq_mask, host->base + MMC_REG_INT_CNTR);
#ifdef HAS_DMA
host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW);
@@ -926,43 +936,47 @@ static int mxcmci_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
-static int mxcmci_suspend(struct platform_device *dev, pm_message_t state)
+static int mxcmci_suspend(struct device *dev)
{
- struct mmc_host *mmc = platform_get_drvdata(dev);
+ struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct mxcmci_host *host = mmc_priv(mmc);
int ret = 0;
if (mmc)
ret = mmc_suspend_host(mmc);
+ clk_disable(host->clk);
return ret;
}
-static int mxcmci_resume(struct platform_device *dev)
+static int mxcmci_resume(struct device *dev)
{
- struct mmc_host *mmc = platform_get_drvdata(dev);
- struct mxcmci_host *host;
+ struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct mxcmci_host *host = mmc_priv(mmc);
int ret = 0;
- if (mmc) {
- host = mmc_priv(mmc);
+ clk_enable(host->clk);
+ if (mmc)
ret = mmc_resume_host(mmc);
- }
return ret;
}
-#else
-#define mxcmci_suspend NULL
-#define mxcmci_resume NULL
-#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops mxcmci_pm_ops = {
+ .suspend = mxcmci_suspend,
+ .resume = mxcmci_resume,
+};
+#endif
static struct platform_driver mxcmci_driver = {
.probe = mxcmci_probe,
.remove = mxcmci_remove,
- .suspend = mxcmci_suspend,
- .resume = mxcmci_resume,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &mxcmci_pm_ops,
+#endif
}
};
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 2b281680e320..d98ddcfac5e5 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1157,7 +1157,6 @@ static void mmc_omap_start_request(struct mmc_omap_host *host,
mmc_omap_start_command(host, req->cmd);
if (host->dma_in_use)
omap_start_dma(host->dma_ch);
- BUG_ON(irqs_disabled());
}
static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index af217924a76e..ad30f074ee15 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -365,6 +365,26 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
{
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+ struct sdhci_s3c *sc = sdhci_priv(host);
+ int ptr;
+
+ sdhci_remove_host(host, 1);
+
+ for (ptr = 0; ptr < 3; ptr++) {
+ clk_disable(sc->clk_bus[ptr]);
+ clk_put(sc->clk_bus[ptr]);
+ }
+ clk_disable(sc->clk_io);
+ clk_put(sc->clk_io);
+
+ iounmap(host->ioaddr);
+ release_resource(sc->ioarea);
+ kfree(sc->ioarea);
+
+ sdhci_free_host(host);
+ platform_set_drvdata(pdev, NULL);
+
return 0;
}
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index eb97830c0344..5d3f824bb5a3 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -30,25 +30,6 @@
#define DRIVER_NAME "sh_mmcif"
#define DRIVER_VERSION "2010-04-28"
-#define MMCIF_CE_CMD_SET 0x00000000
-#define MMCIF_CE_ARG 0x00000008
-#define MMCIF_CE_ARG_CMD12 0x0000000C
-#define MMCIF_CE_CMD_CTRL 0x00000010
-#define MMCIF_CE_BLOCK_SET 0x00000014
-#define MMCIF_CE_CLK_CTRL 0x00000018
-#define MMCIF_CE_BUF_ACC 0x0000001C
-#define MMCIF_CE_RESP3 0x00000020
-#define MMCIF_CE_RESP2 0x00000024
-#define MMCIF_CE_RESP1 0x00000028
-#define MMCIF_CE_RESP0 0x0000002C
-#define MMCIF_CE_RESP_CMD12 0x00000030
-#define MMCIF_CE_DATA 0x00000034
-#define MMCIF_CE_INT 0x00000040
-#define MMCIF_CE_INT_MASK 0x00000044
-#define MMCIF_CE_HOST_STS1 0x00000048
-#define MMCIF_CE_HOST_STS2 0x0000004C
-#define MMCIF_CE_VERSION 0x0000007C
-
/* CE_CMD_SET */
#define CMD_MASK 0x3f000000
#define CMD_SET_RTYP_NO ((0 << 23) | (0 << 22))
@@ -207,27 +188,17 @@ struct sh_mmcif_host {
wait_queue_head_t intr_wait;
};
-static inline u32 sh_mmcif_readl(struct sh_mmcif_host *host, unsigned int reg)
-{
- return readl(host->addr + reg);
-}
-
-static inline void sh_mmcif_writel(struct sh_mmcif_host *host,
- unsigned int reg, u32 val)
-{
- writel(val, host->addr + reg);
-}
static inline void sh_mmcif_bitset(struct sh_mmcif_host *host,
unsigned int reg, u32 val)
{
- writel(val | sh_mmcif_readl(host, reg), host->addr + reg);
+ writel(val | readl(host->addr + reg), host->addr + reg);
}
static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host,
unsigned int reg, u32 val)
{
- writel(~val & sh_mmcif_readl(host, reg), host->addr + reg);
+ writel(~val & readl(host->addr + reg), host->addr + reg);
}
@@ -253,10 +224,10 @@ static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
{
u32 tmp;
- tmp = 0x010f0000 & sh_mmcif_readl(host, MMCIF_CE_CLK_CTRL);
+ tmp = 0x010f0000 & sh_mmcif_readl(host->addr, MMCIF_CE_CLK_CTRL);
- sh_mmcif_writel(host, MMCIF_CE_VERSION, SOFT_RST_ON);
- sh_mmcif_writel(host, MMCIF_CE_VERSION, SOFT_RST_OFF);
+ sh_mmcif_writel(host->addr, MMCIF_CE_VERSION, SOFT_RST_ON);
+ sh_mmcif_writel(host->addr, MMCIF_CE_VERSION, SOFT_RST_OFF);
sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, tmp |
SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29);
/* byte swap on */
@@ -271,12 +242,10 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
host->sd_error = 0;
host->wait_int = 0;
- state1 = sh_mmcif_readl(host, MMCIF_CE_HOST_STS1);
- state2 = sh_mmcif_readl(host, MMCIF_CE_HOST_STS2);
- pr_debug("%s: ERR HOST_STS1 = %08x\n", \
- DRIVER_NAME, sh_mmcif_readl(host, MMCIF_CE_HOST_STS1));
- pr_debug("%s: ERR HOST_STS2 = %08x\n", \
- DRIVER_NAME, sh_mmcif_readl(host, MMCIF_CE_HOST_STS2));
+ state1 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1);
+ state2 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS2);
+ pr_debug("%s: ERR HOST_STS1 = %08x\n", DRIVER_NAME, state1);
+ pr_debug("%s: ERR HOST_STS2 = %08x\n", DRIVER_NAME, state2);
if (state1 & STS1_CMDSEQ) {
sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK);
@@ -288,7 +257,7 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
"command sequence timeout err\n");
return -EIO;
}
- if (!(sh_mmcif_readl(host, MMCIF_CE_HOST_STS1)
+ if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1)
& STS1_CMDSEQ))
break;
mdelay(1);
@@ -330,9 +299,9 @@ static int sh_mmcif_single_read(struct sh_mmcif_host *host,
host->wait_int = 0;
blocksize = (BLOCK_SIZE_MASK &
- sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET)) + 3;
+ sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
for (i = 0; i < blocksize / 4; i++)
- *p++ = sh_mmcif_readl(host, MMCIF_CE_DATA);
+ *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
/* buffer read end */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
@@ -353,7 +322,8 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
long time;
u32 blocksize, i, j, sec, *p;
- blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET);
+ blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr,
+ MMCIF_CE_BLOCK_SET);
for (j = 0; j < data->sg_len; j++) {
p = sg_virt(data->sg);
host->wait_int = 0;
@@ -370,7 +340,8 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
host->wait_int = 0;
for (i = 0; i < blocksize / 4; i++)
- *p++ = sh_mmcif_readl(host, MMCIF_CE_DATA);
+ *p++ = sh_mmcif_readl(host->addr,
+ MMCIF_CE_DATA);
}
if (j < data->sg_len - 1)
data->sg++;
@@ -397,9 +368,9 @@ static int sh_mmcif_single_write(struct sh_mmcif_host *host,
host->wait_int = 0;
blocksize = (BLOCK_SIZE_MASK &
- sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET)) + 3;
+ sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
for (i = 0; i < blocksize / 4; i++)
- sh_mmcif_writel(host, MMCIF_CE_DATA, *p++);
+ sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++);
/* buffer write end */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
@@ -421,7 +392,8 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
long time;
u32 i, sec, j, blocksize, *p;
- blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET);
+ blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr,
+ MMCIF_CE_BLOCK_SET);
for (j = 0; j < data->sg_len; j++) {
p = sg_virt(data->sg);
@@ -439,7 +411,8 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
host->wait_int = 0;
for (i = 0; i < blocksize / 4; i++)
- sh_mmcif_writel(host, MMCIF_CE_DATA, *p++);
+ sh_mmcif_writel(host->addr,
+ MMCIF_CE_DATA, *p++);
}
if (j < data->sg_len - 1)
data->sg++;
@@ -451,18 +424,18 @@ static void sh_mmcif_get_response(struct sh_mmcif_host *host,
struct mmc_command *cmd)
{
if (cmd->flags & MMC_RSP_136) {
- cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP3);
- cmd->resp[1] = sh_mmcif_readl(host, MMCIF_CE_RESP2);
- cmd->resp[2] = sh_mmcif_readl(host, MMCIF_CE_RESP1);
- cmd->resp[3] = sh_mmcif_readl(host, MMCIF_CE_RESP0);
+ cmd->resp[0] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP3);
+ cmd->resp[1] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP2);
+ cmd->resp[2] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP1);
+ cmd->resp[3] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP0);
} else
- cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP0);
+ cmd->resp[0] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP0);
}
static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host,
struct mmc_command *cmd)
{
- cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP_CMD12);
+ cmd->resp[0] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP_CMD12);
}
static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
@@ -596,18 +569,19 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO;
if (host->data) {
- sh_mmcif_writel(host, MMCIF_CE_BLOCK_SET, 0);
- sh_mmcif_writel(host, MMCIF_CE_BLOCK_SET, mrq->data->blksz);
+ sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0);
+ sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET,
+ mrq->data->blksz);
}
opc = sh_mmcif_set_cmd(host, mrq, cmd, opc);
- sh_mmcif_writel(host, MMCIF_CE_INT, 0xD80430C0);
- sh_mmcif_writel(host, MMCIF_CE_INT_MASK, mask);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask);
/* set arg */
- sh_mmcif_writel(host, MMCIF_CE_ARG, cmd->arg);
+ sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg);
host->wait_int = 0;
/* set cmd */
- sh_mmcif_writel(host, MMCIF_CE_CMD_SET, opc);
+ sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc);
time = wait_event_interruptible_timeout(host->intr_wait,
host->wait_int == 1 || host->sd_error == 1, host->timeout);
@@ -752,43 +726,44 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
u32 state = 0;
int err = 0;
- state = sh_mmcif_readl(host, MMCIF_CE_INT);
+ state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
if (state & INT_RBSYE) {
- sh_mmcif_writel(host, MMCIF_CE_INT, ~(INT_RBSYE | INT_CRSPE));
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT,
+ ~(INT_RBSYE | INT_CRSPE));
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE);
} else if (state & INT_CRSPE) {
- sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_CRSPE);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_CRSPE);
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCRSPE);
} else if (state & INT_BUFREN) {
- sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFREN);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFREN);
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
} else if (state & INT_BUFWEN) {
- sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFWEN);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFWEN);
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
} else if (state & INT_CMD12DRE) {
- sh_mmcif_writel(host, MMCIF_CE_INT,
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT,
~(INT_CMD12DRE | INT_CMD12RBE |
INT_CMD12CRE | INT_BUFRE));
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE);
} else if (state & INT_BUFRE) {
- sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFRE);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFRE);
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
} else if (state & INT_DTRANE) {
- sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_DTRANE);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_DTRANE);
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
} else if (state & INT_CMD12RBE) {
- sh_mmcif_writel(host, MMCIF_CE_INT,
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT,
~(INT_CMD12RBE | INT_CMD12CRE));
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
} else if (state & INT_ERR_STS) {
/* err interrupts */
- sh_mmcif_writel(host, MMCIF_CE_INT, ~state);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
err = 1;
} else {
pr_debug("%s: Not support int\n", DRIVER_NAME);
- sh_mmcif_writel(host, MMCIF_CE_INT, ~state);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
err = 1;
}
@@ -894,12 +869,12 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
goto clean_up2;
}
- sh_mmcif_writel(host, MMCIF_CE_INT_MASK, MASK_ALL);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
sh_mmcif_detect(host->mmc);
pr_info("%s: driver version %s\n", DRIVER_NAME, DRIVER_VERSION);
pr_debug("%s: chip ver H'%04x\n", DRIVER_NAME,
- sh_mmcif_readl(host, MMCIF_CE_VERSION) & 0x0000ffff);
+ sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
return ret;
clean_up2:
@@ -917,7 +892,7 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
struct sh_mmcif_host *host = platform_get_drvdata(pdev);
int irq[2];
- sh_mmcif_writel(host, MMCIF_CE_INT_MASK, MASK_ALL);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
irq[0] = platform_get_irq(pdev, 0);
irq[1] = platform_get_irq(pdev, 1);