* Patches for mxcmmc.c @ 2009-11-05 17:13 Daniel Mack 2009-11-05 17:13 ` [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Daniel Mack 2009-11-11 14:43 ` Patches for mxcmmc.c Daniel Mack 0 siblings, 2 replies; 7+ messages in thread From: Daniel Mack @ 2009-11-05 17:13 UTC (permalink / raw) To: linux-arm-kernel Here are three update patches for the mxc mmc driver to bring it closer to a working SDIO implementation. (There is one more pending which modifies the way the buffers' busy flags are interpreted, but we're not yet sure whether this one does the right thing, so I'm not yet posting it now.) I'm not sure whether the problems we're having here are due to the fact that DMA does not yet work on MX3. Hence, I would appreciate if anyone with access to an MX2 board could try these patches and see if the hardware can talk to SDIO connected peripherals (preferably a Libertas Wifi solution, but trying anything else might also give a hint). Thanks, Daniel [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment [PATCH 3/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups 2009-11-05 17:13 Patches for mxcmmc.c Daniel Mack @ 2009-11-05 17:13 ` Daniel Mack 2009-11-05 17:13 ` [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment Daniel Mack 2009-11-11 14:43 ` Patches for mxcmmc.c Daniel Mack 1 sibling, 1 reply; 7+ messages in thread From: Daniel Mack @ 2009-11-05 17:13 UTC (permalink / raw) To: linux-arm-kernel 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> --- 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 8867152..32ac139 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.6.5.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment 2009-11-05 17:13 ` [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Daniel Mack @ 2009-11-05 17:13 ` Daniel Mack 2009-11-05 17:13 ` [PATCH 3/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations Daniel Mack 2009-11-05 17:32 ` [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment Russell King - ARM Linux 0 siblings, 2 replies; 7+ messages in thread From: Daniel Mack @ 2009-11-05 17:13 UTC (permalink / raw) To: linux-arm-kernel Signed-off-by: Daniel Mack <daniel@caiaq.de> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Dan Williams <dan.j.williams@intel.com> --- drivers/mmc/host/mxcmmc.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 32ac139..8aa6de0 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -714,7 +714,7 @@ static int mxcmci_probe(struct platform_device *pdev) mmc->max_blk_size = 2048; mmc->max_blk_count = 65535; mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; - mmc->max_seg_size = mmc->max_seg_size; + mmc->max_seg_size = mmc->max_req_size; host = mmc_priv(mmc); host->base = ioremap(r->start, resource_size(r)); -- 1.6.5.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations 2009-11-05 17:13 ` [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment Daniel Mack @ 2009-11-05 17:13 ` Daniel Mack 2009-11-05 17:32 ` [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment Russell King - ARM Linux 1 sibling, 0 replies; 7+ messages in thread From: Daniel Mack @ 2009-11-05 17:13 UTC (permalink / raw) To: linux-arm-kernel 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> --- drivers/mmc/host/mxcmmc.c | 48 ++++++++++++++++++++++++++++++++++++-------- 1 files changed, 39 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 8aa6de0..01324c5 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); @@ -536,8 +542,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 +684,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 +735,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 +754,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.6.5.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment 2009-11-05 17:13 ` [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment Daniel Mack 2009-11-05 17:13 ` [PATCH 3/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations Daniel Mack @ 2009-11-05 17:32 ` Russell King - ARM Linux 2009-11-06 0:11 ` Daniel Mack 1 sibling, 1 reply; 7+ messages in thread From: Russell King - ARM Linux @ 2009-11-05 17:32 UTC (permalink / raw) To: linux-arm-kernel Err "fix" ? No, that's not what this is. max_seg_size is the maximum segment size, not the maximum request size. The naming of these comes from the block IO subsystem, so it's a good idea to preserve the naming (and therefore the meaning.) max_req_size suggests that this parameter indicates the maximum size of any single request. A single request can be made up of multiple segments, so clearly this change is misleading. On Thu, Nov 05, 2009 at 06:13:35PM +0100, Daniel Mack wrote: > Signed-off-by: Daniel Mack <daniel@caiaq.de> > Cc: Sascha Hauer <s.hauer@pengutronix.de> > Cc: Dan Williams <dan.j.williams@intel.com> > --- > drivers/mmc/host/mxcmmc.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c > index 32ac139..8aa6de0 100644 > --- a/drivers/mmc/host/mxcmmc.c > +++ b/drivers/mmc/host/mxcmmc.c > @@ -714,7 +714,7 @@ static int mxcmci_probe(struct platform_device *pdev) > mmc->max_blk_size = 2048; > mmc->max_blk_count = 65535; > mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; > - mmc->max_seg_size = mmc->max_seg_size; > + mmc->max_seg_size = mmc->max_req_size; > > host = mmc_priv(mmc); > host->base = ioremap(r->start, resource_size(r)); > -- > 1.6.5.2 > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel at lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment 2009-11-05 17:32 ` [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment Russell King - ARM Linux @ 2009-11-06 0:11 ` Daniel Mack 0 siblings, 0 replies; 7+ messages in thread From: Daniel Mack @ 2009-11-06 0:11 UTC (permalink / raw) To: linux-arm-kernel On Thu, Nov 05, 2009 at 05:32:51PM +0000, Russell King - ARM Linux wrote: > Err "fix" ? No, that's not what this is. > > max_seg_size is the maximum segment size, not the maximum request size. > The naming of these comes from the block IO subsystem, so it's a good > idea to preserve the naming (and therefore the meaning.) > > max_req_size suggests that this parameter indicates the maximum size > of any single request. A single request can be made up of multiple > segments, so clearly this change is misleading. Well - I considered that a typo only, as the left and right side were identical: > > - mmc->max_seg_size = mmc->max_seg_size; Other drivers define seg_size = reg_size, and I thought that was what was intended here. Daniel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Patches for mxcmmc.c 2009-11-05 17:13 Patches for mxcmmc.c Daniel Mack 2009-11-05 17:13 ` [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Daniel Mack @ 2009-11-11 14:43 ` Daniel Mack 1 sibling, 0 replies; 7+ messages in thread From: Daniel Mack @ 2009-11-11 14:43 UTC (permalink / raw) To: linux-arm-kernel On Thu, Nov 05, 2009 at 06:13:33PM +0100, Daniel Mack wrote: > Here are three update patches for the mxc mmc driver to bring it closer > to a working SDIO implementation. > > (There is one more pending which modifies the way the buffers' busy > flags are interpreted, but we're not yet sure whether this one does > the right thing, so I'm not yet posting it now.) > > I'm not sure whether the problems we're having here are due to the > fact that DMA does not yet work on MX3. Hence, I would appreciate if > anyone with access to an MX2 board could try these patches and see > if the hardware can talk to SDIO connected peripherals (preferably > a Libertas Wifi solution, but trying anything else might also give > a hint). Was anyone with a MX2 based board able to help testing this? It would be very important for us to know whether SDIO cards work with DMA. Thanks, Daniel ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-11-11 14:43 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-11-05 17:13 Patches for mxcmmc.c Daniel Mack 2009-11-05 17:13 ` [PATCH 1/3] ARM: MXC: mxcmmc: misc cleanups Daniel Mack 2009-11-05 17:13 ` [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment Daniel Mack 2009-11-05 17:13 ` [PATCH 3/3] ARM: MXC: mxcmmc: Teach the driver SDIO operations Daniel Mack 2009-11-05 17:32 ` [PATCH 2/3] ARM: MXC: mxcmmc: Fix max_seg_size assignment Russell King - ARM Linux 2009-11-06 0:11 ` Daniel Mack 2009-11-11 14:43 ` Patches for mxcmmc.c 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).