* [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups
@ 2010-03-30 18:31 Daniel Mack
2010-03-30 18:32 ` [PATCH 2/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations Daniel Mack
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Daniel Mack @ 2010-03-30 18:31 UTC (permalink / raw)
To: linux-arm-kernel
Cc: linux-mmc, Daniel Mack, Sascha Hauer, Dan Williams, Volker Ernst,
Jiri Kosina
Add some more debug information and fix a couple of coding style things
in mxcmmc.c.
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Volker Ernst <volker.ernst@txtr.com>
Cc: Jiri Kosina <jkosina@suse.cz>
---
drivers/mmc/host/mxcmmc.c | 28 +++++++++++++++++-----------
1 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 2df9041..21037ff 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -151,6 +151,8 @@ static void mxcmci_softreset(struct mxcmci_host *host)
{
int i;
+ dev_dbg(mmc_dev(host->mmc), "mxcmci_softreset\n");
+
/* reset sequence */
writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK);
writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
@@ -290,21 +292,29 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
stat);
if (stat & STATUS_CRC_READ_ERR) {
+ dev_err(mmc_dev(host->mmc), "%s: -EILSEQ\n", __func__);
data->error = -EILSEQ;
} else if (stat & STATUS_CRC_WRITE_ERR) {
u32 err_code = (stat >> 9) & 0x3;
- if (err_code == 2) /* No CRC response */
+ if (err_code == 2) { /* No CRC response */
+ dev_err(mmc_dev(host->mmc),
+ "%s: No CRC -ETIMEDOUT\n", __func__);
data->error = -ETIMEDOUT;
- else
+ } else {
+ dev_err(mmc_dev(host->mmc),
+ "%s: -EILSEQ\n", __func__);
data->error = -EILSEQ;
+ }
} else if (stat & STATUS_TIME_OUT_READ) {
+ dev_err(mmc_dev(host->mmc),
+ "%s: read -ETIMEDOUT\n", __func__);
data->error = -ETIMEDOUT;
} else {
+ dev_err(mmc_dev(host->mmc), "%s: -EIO\n", __func__);
data->error = -EIO;
}
- } else {
+ } else
data->bytes_xfered = host->datasize;
- }
data_error = data->error;
@@ -433,8 +443,6 @@ static int mxcmci_transfer_data(struct mxcmci_host *host)
struct scatterlist *sg;
int stat, i;
- host->datasize = 0;
-
host->data = data;
host->datasize = 0;
@@ -471,9 +479,8 @@ static void mxcmci_datawork(struct work_struct *work)
mxcmci_finish_request(host, host->req);
return;
}
- } else {
+ } else
mxcmci_finish_request(host, host->req);
- }
}
#ifdef HAS_DMA
@@ -495,9 +502,8 @@ static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat)
mxcmci_finish_request(host, host->req);
return;
}
- } else {
+ } else
mxcmci_finish_request(host, host->req);
- }
}
#endif /* HAS_DMA */
@@ -512,7 +518,7 @@ static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
}
/* For the DMA case the DMA engine handles the data transfer
- * automatically. For non DMA we have to do it ourselves.
+ * automatically. For non DMA we have to to it ourselves.
* Don't do it in interrupt context though.
*/
if (!mxcmci_use_dma(host) && host->data)
--
1.7.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations
2010-03-30 18:31 [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Daniel Mack
@ 2010-03-30 18:32 ` Daniel Mack
2010-03-31 13:03 ` Sascha Hauer
2010-03-30 18:32 ` [PATCH 3/3] ARM: MXC: mxcmmc: work around a bug in the SDHC busy line handling Daniel Mack
2010-03-31 12:38 ` [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Sascha Hauer
2 siblings, 1 reply; 8+ messages in thread
From: Daniel Mack @ 2010-03-30 18:32 UTC (permalink / raw)
To: linux-arm-kernel
Cc: linux-mmc, Daniel Mack, Sascha Hauer, Dan Williams, Volker Ernst,
Jiri Kosina
Successfully tested on MX31 hardware using libertas SDIO peripherals.
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Volker Ernst <volker.ernst@txtr.com>
Cc: Jiri Kosina <jkosina@suse.cz>
---
drivers/mmc/host/mxcmmc.c | 55 ++++++++++++++++++++++++++++++++++++--------
1 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 21037ff..83a4545 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 use_sdio;
unsigned int power_mode;
struct imxmmc_platform_data *pdata;
@@ -138,6 +139,7 @@ struct mxcmci_host {
int clock;
struct work_struct datawork;
+ spinlock_t lock;
};
static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
@@ -226,6 +228,8 @@ 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;
+
WARN_ON(host->cmd != NULL);
host->cmd = cmd;
@@ -249,13 +253,15 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
return -EINVAL;
}
+ int_cntr = INT_END_CMD_RES_EN;
+
if (mxcmci_use_dma(host))
- writel(INT_READ_OP_EN | INT_WRITE_OP_DONE_EN |
- INT_END_CMD_RES_EN,
- host->base + MMC_REG_INT_CNTR);
- else
- writel(INT_END_CMD_RES_EN, host->base + MMC_REG_INT_CNTR);
+ int_cntr |= INT_READ_OP_EN | INT_WRITE_OP_DONE_EN;
+
+ if (host->use_sdio)
+ int_cntr |= INT_SDIO_IRQ_EN;
+ writel(int_cntr, host->base + MMC_REG_INT_CNTR);
writew(cmd->opcode, host->base + MMC_REG_CMD);
writel(cmd->arg, host->base + MMC_REG_ARG);
writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT);
@@ -266,7 +272,12 @@ 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)
{
- writel(0, host->base + MMC_REG_INT_CNTR);
+ u32 int_cntr = 0;
+
+ if (host->use_sdio)
+ int_cntr |= INT_SDIO_IRQ_EN;
+
+ writel(int_cntr, host->base + MMC_REG_INT_CNTR);
host->req = NULL;
host->cmd = NULL;
@@ -536,8 +547,12 @@ static irqreturn_t mxcmci_irq(int irq, void *devid)
dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
+ if ((stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio)
+ mmc_signal_sdio_irq(host->mmc);
+
if (stat & STATUS_END_CMD_RESP)
mxcmci_cmd_done(host, stat);
+
#ifdef HAS_DMA
if (mxcmci_use_dma(host) &&
(stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
@@ -674,11 +689,30 @@ static int mxcmci_get_ro(struct mmc_host *mmc)
return -ENOSYS;
}
+static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct mxcmci_host *host = mmc_priv(mmc);
+ unsigned long flags;
+ u32 int_cntr;
+
+ spin_lock_irqsave(&host->lock, flags);
+ host->use_sdio = enable;
+ int_cntr = readl(host->base + MMC_REG_INT_CNTR);
+
+ if (enable)
+ int_cntr |= INT_SDIO_IRQ_EN;
+ else
+ int_cntr &= ~INT_SDIO_IRQ_EN;
+
+ writel(int_cntr, host->base + MMC_REG_INT_CNTR);
+ spin_unlock_irqrestore(&host->lock, flags);
+}
static const struct mmc_host_ops mxcmci_ops = {
- .request = mxcmci_request,
- .set_ios = mxcmci_set_ios,
- .get_ro = mxcmci_get_ro,
+ .request = mxcmci_request,
+ .set_ios = mxcmci_set_ios,
+ .get_ro = mxcmci_get_ro,
+ .enable_sdio_irq = mxcmci_enable_sdio_irq,
};
static int mxcmci_probe(struct platform_device *pdev)
@@ -706,7 +740,7 @@ static int mxcmci_probe(struct platform_device *pdev)
}
mmc->ops = &mxcmci_ops;
- mmc->caps = MMC_CAP_4_BIT_DATA;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
/* MMC core transfer sizes tunable parameters */
mmc->max_hw_segs = 64;
@@ -725,6 +759,7 @@ static int mxcmci_probe(struct platform_device *pdev)
host->mmc = mmc;
host->pdata = pdev->dev.platform_data;
+ spin_lock_init(&host->lock);
if (host->pdata && host->pdata->ocr_avail)
mmc->ocr_avail = host->pdata->ocr_avail;
--
1.7.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] ARM: MXC: mxcmmc: work around a bug in the SDHC busy line handling
2010-03-30 18:31 [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Daniel Mack
2010-03-30 18:32 ` [PATCH 2/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations Daniel Mack
@ 2010-03-30 18:32 ` Daniel Mack
2010-03-31 12:38 ` [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Sascha Hauer
2 siblings, 0 replies; 8+ messages in thread
From: Daniel Mack @ 2010-03-30 18:32 UTC (permalink / raw)
To: linux-arm-kernel
Cc: linux-mmc, Daniel Mack, Sascha Hauer, Dan Williams, Volker Ernst,
Jiri Kosina
MX3 SoCs have a silicon bug which corrupts CRC calculation of
multi-block transfers when connected SDIO peripheral doesn't drive the
BUSY line as required by the specs.
One way to prevent this is to only allow 1-bit transfers.
Another way is playing tricks with the DMA engine, but this isn't
mainline yet. So for now, we live with the performance drawback of 1-bit
transfers until a nicer solution is found.
This patch introduces a new host controller callback 'init_card' which
is for now only called from mmc_sdio_init_card().
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Volker Ernst <volker.ernst@txtr.com>
Cc: Jiri Kosina <jkosina@suse.cz>
---
drivers/mmc/core/sdio.c | 6 ++++++
drivers/mmc/host/mxcmmc.c | 14 ++++++++++++++
include/linux/mmc/host.h | 3 +++
3 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 2dd4cfe..b9dee28 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -296,6 +296,12 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
card->type = MMC_TYPE_SDIO;
/*
+ * Call the optional HC's init_card function to handle quirks.
+ */
+ if (host->ops->init_card)
+ host->ops->init_card(host, card);
+
+ /*
* For native busses: set card RCA and quit open drain mode.
*/
if (!powered_resume && !mmc_host_is_spi(host)) {
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 83a4545..f584c1b 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -708,11 +708,25 @@ static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
spin_unlock_irqrestore(&host->lock, flags);
}
+static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card)
+{
+ /*
+ * MX3 SoCs have a silicon bug which corrupts CRC calculation of
+ * multi-block transfers when connected SDIO peripheral doesn't
+ * drive the BUSY line as required by the specs.
+ * One way to prevent this is to only allow 1-bit transfers.
+ */
+
+ if (cpu_is_mx3() && card->type == MMC_TYPE_SDIO)
+ host->caps &= ~MMC_CAP_4_BIT_DATA;
+}
+
static const struct mmc_host_ops mxcmci_ops = {
.request = mxcmci_request,
.set_ios = mxcmci_set_ios,
.get_ro = mxcmci_get_ro,
.enable_sdio_irq = mxcmci_enable_sdio_irq,
+ .init_card = mxcmci_init_card,
};
static int mxcmci_probe(struct platform_device *pdev)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 43eaf5c..3196c84 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -108,6 +108,9 @@ struct mmc_host_ops {
int (*get_cd)(struct mmc_host *host);
void (*enable_sdio_irq)(struct mmc_host *host, int enable);
+
+ /* optional callback for HC quirks */
+ void (*init_card)(struct mmc_host *host, struct mmc_card *card);
};
struct mmc_card;
--
1.7.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups
2010-03-30 18:31 [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Daniel Mack
2010-03-30 18:32 ` [PATCH 2/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations Daniel Mack
2010-03-30 18:32 ` [PATCH 3/3] ARM: MXC: mxcmmc: work around a bug in the SDHC busy line handling Daniel Mack
@ 2010-03-31 12:38 ` Sascha Hauer
2010-03-31 13:02 ` Daniel Mack
2 siblings, 1 reply; 8+ messages in thread
From: Sascha Hauer @ 2010-03-31 12:38 UTC (permalink / raw)
To: Daniel Mack
Cc: linux-arm-kernel, linux-mmc, Dan Williams, Volker Ernst,
Jiri Kosina
Hi Daniel,
On Tue, Mar 30, 2010 at 08:31:59PM +0200, Daniel Mack wrote:
> Add some more debug information and fix a couple of coding style things
> in mxcmmc.c.
>
> Signed-off-by: Daniel Mack <daniel@caiaq.de>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: Volker Ernst <volker.ernst@txtr.com>
> Cc: Jiri Kosina <jkosina@suse.cz>
> ---
> drivers/mmc/host/mxcmmc.c | 28 +++++++++++++++++-----------
> 1 files changed, 17 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
> index 2df9041..21037ff 100644
> --- a/drivers/mmc/host/mxcmmc.c
> +++ b/drivers/mmc/host/mxcmmc.c
> @@ -151,6 +151,8 @@ static void mxcmci_softreset(struct mxcmci_host *host)
> {
> int i;
>
> + dev_dbg(mmc_dev(host->mmc), "mxcmci_softreset\n");
> +
> /* reset sequence */
> writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK);
> writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
> @@ -290,21 +292,29 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
> dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
> stat);
> if (stat & STATUS_CRC_READ_ERR) {
> + dev_err(mmc_dev(host->mmc), "%s: -EILSEQ\n", __func__);
> data->error = -EILSEQ;
> } else if (stat & STATUS_CRC_WRITE_ERR) {
> u32 err_code = (stat >> 9) & 0x3;
> - if (err_code == 2) /* No CRC response */
> + if (err_code == 2) { /* No CRC response */
> + dev_err(mmc_dev(host->mmc),
> + "%s: No CRC -ETIMEDOUT\n", __func__);
> data->error = -ETIMEDOUT;
> - else
> + } else {
> + dev_err(mmc_dev(host->mmc),
> + "%s: -EILSEQ\n", __func__);
> data->error = -EILSEQ;
> + }
> } else if (stat & STATUS_TIME_OUT_READ) {
> + dev_err(mmc_dev(host->mmc),
> + "%s: read -ETIMEDOUT\n", __func__);
> data->error = -ETIMEDOUT;
> } else {
> + dev_err(mmc_dev(host->mmc), "%s: -EIO\n", __func__);
Do we really want to have these messages with dev_err? In the subject
you are talking about debug output.
> data->error = -EIO;
> }
> - } else {
> + } else
> data->bytes_xfered = host->datasize;
> - }
Documentation/CodingStyle says that if braces are used in one branch of
a conditional then they should be used in both branches.
I personally don't care much about this statement but I think we should
leave it as is. Otherwise some day someone wants to change it back
according to the coding style.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups
2010-03-31 12:38 ` [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Sascha Hauer
@ 2010-03-31 13:02 ` Daniel Mack
0 siblings, 0 replies; 8+ messages in thread
From: Daniel Mack @ 2010-03-31 13:02 UTC (permalink / raw)
To: Sascha Hauer
Cc: linux-arm-kernel, linux-mmc, Dan Williams, Volker Ernst,
Jiri Kosina
On Wed, Mar 31, 2010 at 02:38:56PM +0200, Sascha Hauer wrote:
> On Tue, Mar 30, 2010 at 08:31:59PM +0200, Daniel Mack wrote:
> > + dev_err(mmc_dev(host->mmc),
> > + "%s: read -ETIMEDOUT\n", __func__);
> > data->error = -ETIMEDOUT;
> > } else {
> > + dev_err(mmc_dev(host->mmc), "%s: -EIO\n", __func__);
>
> Do we really want to have these messages with dev_err? In the subject
> you are talking about debug output.
This _is_ definitely an error if get there, so I'll rather change the
commit message ;)
>
> > data->error = -EIO;
> > }
> > - } else {
> > + } else
> > data->bytes_xfered = host->datasize;
> > - }
>
> Documentation/CodingStyle says that if braces are used in one branch of
> a conditional then they should be used in both branches.
> I personally don't care much about this statement but I think we should
> leave it as is. Otherwise some day someone wants to change it back
> according to the coding style.
Ok, true. I'll fix this (and the commit message) and resend.
Thanks,
Daniel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations
2010-03-30 18:32 ` [PATCH 2/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations Daniel Mack
@ 2010-03-31 13:03 ` Sascha Hauer
2010-03-31 13:29 ` Daniel Mack
0 siblings, 1 reply; 8+ messages in thread
From: Sascha Hauer @ 2010-03-31 13:03 UTC (permalink / raw)
To: Daniel Mack
Cc: linux-arm-kernel, linux-mmc, Dan Williams, Volker Ernst,
Jiri Kosina
On Tue, Mar 30, 2010 at 08:32:00PM +0200, Daniel Mack wrote:
> Successfully tested on MX31 hardware using libertas SDIO peripherals.
>
> Signed-off-by: Daniel Mack <daniel@caiaq.de>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: Volker Ernst <volker.ernst@txtr.com>
> Cc: Jiri Kosina <jkosina@suse.cz>
> ---
> drivers/mmc/host/mxcmmc.c | 55 ++++++++++++++++++++++++++++++++++++--------
> 1 files changed, 45 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
> index 21037ff..83a4545 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 use_sdio;
> unsigned int power_mode;
> struct imxmmc_platform_data *pdata;
>
> @@ -138,6 +139,7 @@ struct mxcmci_host {
> int clock;
>
> struct work_struct datawork;
> + spinlock_t lock;
> };
>
> static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
> @@ -226,6 +228,8 @@ 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;
> +
> WARN_ON(host->cmd != NULL);
> host->cmd = cmd;
>
> @@ -249,13 +253,15 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
> return -EINVAL;
> }
>
> + int_cntr = INT_END_CMD_RES_EN;
> +
> if (mxcmci_use_dma(host))
> - writel(INT_READ_OP_EN | INT_WRITE_OP_DONE_EN |
> - INT_END_CMD_RES_EN,
> - host->base + MMC_REG_INT_CNTR);
> - else
> - writel(INT_END_CMD_RES_EN, host->base + MMC_REG_INT_CNTR);
> + int_cntr |= INT_READ_OP_EN | INT_WRITE_OP_DONE_EN;
> +
> + if (host->use_sdio)
> + int_cntr |= INT_SDIO_IRQ_EN;
>
> + writel(int_cntr, host->base + MMC_REG_INT_CNTR);
> writew(cmd->opcode, host->base + MMC_REG_CMD);
> writel(cmd->arg, host->base + MMC_REG_ARG);
> writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT);
> @@ -266,7 +272,12 @@ 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)
> {
> - writel(0, host->base + MMC_REG_INT_CNTR);
> + u32 int_cntr = 0;
> +
> + if (host->use_sdio)
> + int_cntr |= INT_SDIO_IRQ_EN;
> +
> + writel(int_cntr, host->base + MMC_REG_INT_CNTR);
>
> host->req = NULL;
> host->cmd = NULL;
> @@ -536,8 +547,12 @@ static irqreturn_t mxcmci_irq(int irq, void *devid)
>
> dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
>
> + if ((stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio)
> + mmc_signal_sdio_irq(host->mmc);
> +
> if (stat & STATUS_END_CMD_RESP)
> mxcmci_cmd_done(host, stat);
> +
> #ifdef HAS_DMA
> if (mxcmci_use_dma(host) &&
> (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
> @@ -674,11 +689,30 @@ static int mxcmci_get_ro(struct mmc_host *mmc)
> return -ENOSYS;
> }
>
> +static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
> +{
> + struct mxcmci_host *host = mmc_priv(mmc);
> + unsigned long flags;
> + u32 int_cntr;
> +
> + spin_lock_irqsave(&host->lock, flags);
> + host->use_sdio = enable;
> + int_cntr = readl(host->base + MMC_REG_INT_CNTR);
> +
> + if (enable)
> + int_cntr |= INT_SDIO_IRQ_EN;
> + else
> + int_cntr &= ~INT_SDIO_IRQ_EN;
> +
> + writel(int_cntr, host->base + MMC_REG_INT_CNTR);
> + spin_unlock_irqrestore(&host->lock, flags);
The other places where MMC_REG_INT_CNTR is touched should be protected
by this spinlock aswell.
Sascha
> +}
>
> static const struct mmc_host_ops mxcmci_ops = {
> - .request = mxcmci_request,
> - .set_ios = mxcmci_set_ios,
> - .get_ro = mxcmci_get_ro,
> + .request = mxcmci_request,
> + .set_ios = mxcmci_set_ios,
> + .get_ro = mxcmci_get_ro,
> + .enable_sdio_irq = mxcmci_enable_sdio_irq,
> };
>
> static int mxcmci_probe(struct platform_device *pdev)
> @@ -706,7 +740,7 @@ static int mxcmci_probe(struct platform_device *pdev)
> }
>
> mmc->ops = &mxcmci_ops;
> - mmc->caps = MMC_CAP_4_BIT_DATA;
> + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
>
> /* MMC core transfer sizes tunable parameters */
> mmc->max_hw_segs = 64;
> @@ -725,6 +759,7 @@ static int mxcmci_probe(struct platform_device *pdev)
>
> host->mmc = mmc;
> host->pdata = pdev->dev.platform_data;
> + spin_lock_init(&host->lock);
>
> if (host->pdata && host->pdata->ocr_avail)
> mmc->ocr_avail = host->pdata->ocr_avail;
> --
> 1.7.0
>
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations
2010-03-31 13:03 ` Sascha Hauer
@ 2010-03-31 13:29 ` Daniel Mack
2010-03-31 16:41 ` Michał Mirosław
0 siblings, 1 reply; 8+ messages in thread
From: Daniel Mack @ 2010-03-31 13:29 UTC (permalink / raw)
To: Sascha Hauer
Cc: linux-arm-kernel, linux-mmc, Dan Williams, Volker Ernst,
Jiri Kosina
On Wed, Mar 31, 2010 at 03:03:39PM +0200, Sascha Hauer wrote:
> On Tue, Mar 30, 2010 at 08:32:00PM +0200, Daniel Mack wrote:
> > +static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
> > +{
> > + struct mxcmci_host *host = mmc_priv(mmc);
> > + unsigned long flags;
> > + u32 int_cntr;
> > +
> > + spin_lock_irqsave(&host->lock, flags);
> > + host->use_sdio = enable;
> > + int_cntr = readl(host->base + MMC_REG_INT_CNTR);
> > +
> > + if (enable)
> > + int_cntr |= INT_SDIO_IRQ_EN;
> > + else
> > + int_cntr &= ~INT_SDIO_IRQ_EN;
> > +
> > + writel(int_cntr, host->base + MMC_REG_INT_CNTR);
> > + spin_unlock_irqrestore(&host->lock, flags);
>
> The other places where MMC_REG_INT_CNTR is touched should be protected
> by this spinlock aswell.
Hmm, all other place don't do a read/modify/write cycle, so I'd say the
don't need protection?
Daniel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations
2010-03-31 13:29 ` Daniel Mack
@ 2010-03-31 16:41 ` Michał Mirosław
0 siblings, 0 replies; 8+ messages in thread
From: Michał Mirosław @ 2010-03-31 16:41 UTC (permalink / raw)
To: Daniel Mack
Cc: Sascha Hauer, linux-arm-kernel, linux-mmc, Dan Williams,
Volker Ernst, Jiri Kosina
2010/3/31 Daniel Mack <daniel@caiaq.de>:
> On Wed, Mar 31, 2010 at 03:03:39PM +0200, Sascha Hauer wrote:
>> On Tue, Mar 30, 2010 at 08:32:00PM +0200, Daniel Mack wrote:
>> > +static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
>> > +{
>> > + struct mxcmci_host *host = mmc_priv(mmc);
>> > + unsigned long flags;
>> > + u32 int_cntr;
>> > +
>> > + spin_lock_irqsave(&host->lock, flags);
>> > + host->use_sdio = enable;
>> > + int_cntr = readl(host->base + MMC_REG_INT_CNTR);
>> > +
>> > + if (enable)
>> > + int_cntr |= INT_SDIO_IRQ_EN;
>> > + else
>> > + int_cntr &= ~INT_SDIO_IRQ_EN;
>> > +
>> > + writel(int_cntr, host->base + MMC_REG_INT_CNTR);
>> > + spin_unlock_irqrestore(&host->lock, flags);
>>
>> The other places where MMC_REG_INT_CNTR is touched should be protected
>> by this spinlock aswell.
> Hmm, all other place don't do a read/modify/write cycle, so I'd say the
> don't need protection?
If you miss spinlocks around the unconditional writes they might
happen between your readl() and writel().
Best Regards,
Michał Mirosław
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-03-31 16:41 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-30 18:31 [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Daniel Mack
2010-03-30 18:32 ` [PATCH 2/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations Daniel Mack
2010-03-31 13:03 ` Sascha Hauer
2010-03-31 13:29 ` Daniel Mack
2010-03-31 16:41 ` Michał Mirosław
2010-03-30 18:32 ` [PATCH 3/3] ARM: MXC: mxcmmc: work around a bug in the SDHC busy line handling Daniel Mack
2010-03-31 12:38 ` [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Sascha Hauer
2010-03-31 13:02 ` Daniel Mack
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).