ARM: MXC: mxcmmc: misc cleanups
Subsystems (2)
PATCH 1/3 ARM: MXC: mxcmmc: misc cleanups
Be more verbose on error messages and add one debug message.
--- drivers/mmc/host/mxcmmc.c | 17 +++++++++++++---- 1 files changed, 13 insertions(+), 4 deletions(-)
drivers/mmc/host/mxcmmc.c +13 -4
@@ -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,16 +292,25 @@ 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 {
@@ -433,8 +444,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 ;
Signature · 1 line
1.7.0
PATCH 1/3 ARM: MXC: mxcmmc: misc cleanups
Is this series ok to go in?
Sascha, will this go thru your tree?
Thanks,
Daniel
Quoted 65 lines · Daniel Mack
Be more verbose on error messages and add one debug message.
Signed-off-by Daniel Mack <[email protected]>Cc Sascha Hauer <[email protected]>Cc Dan Williams <[email protected]>Cc Volker Ernst <[email protected]>Cc Jiri Kosina <[email protected]>Cc Micha? Miros?aw <[email protected]>--- drivers/mmc/host/mxcmmc.c | 17 +++++++++++++---- 1 files changed, 13 insertions(+), 4 deletions(-)drivers/mmc/host/mxcmmc.c +13
-4@@ -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,16 +292,25 @@ 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 {@@ -433,8 +444,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 ;Signature · 1 line
1.7.0
Sascha Hauer
maintainerPATCH 1/3 ARM: MXC: mxcmmc: misc cleanups
Quoted 2 lines · Daniel Mack
Is this series ok to go in?
Sascha, will this go thru your tree?
Can do. One of your patches touches the generic SDIO layer. Can I have an acked-by from someone involved in it?
Sascha
Signature · 4 lines
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 |
PATCH 1/3 ARM: MXC: mxcmmc: misc cleanups
Quoted 6 lines · Sascha Hauer
Quoted 2 lines · Daniel Mack
Is this series ok to go in?
Sascha, will this go thru your tree?Can do. One of your patches touches the generic SDIO layer. Can I have an acked-by from someone involved in it?
AFAIK, there is currently no active maintainer for that.
Daniel
PATCH 1/3 ARM: MXC: mxcmmc: misc cleanups
In reply to Sascha HauerQuoted 6 lines · Sascha Hauer
Quoted 2 lines · Daniel Mack
Is this series ok to go in?
Sascha, will this go thru your tree?Can do. One of your patches touches the generic SDIO layer. Can I have an acked-by from someone involved in it?
I think you can get a Tested-by: from Volker Ernst and Andy Green and a Reviewed-by: from Micha? Miros?aw who was guiding me thru the locking bits. Can anyone give some thumbs-up, please?
Thanks,
Daniel
Sascha Hauer
maintainerPATCH 1/3 ARM: MXC: mxcmmc: misc cleanups
Quoted 11 lines · Daniel Mack
Quoted 6 lines · Sascha Hauer
Quoted 2 lines · Daniel Mack
Is this series ok to go in?
Sascha, will this go thru your tree?Can do. One of your patches touches the generic SDIO layer. Can I have an acked-by from someone involved in it?
I think you can get a Tested-by: from Volker Ernst and Andy Green and a Reviewed-by: from Micha? Miros?aw who was guiding me thru the locking bits. Can anyone give some thumbs-up, please?
Ok, I think it's been enough time for someone to complain. Applied to mxc-master.
Sascha
Signature · 4 lines
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 |
PATCH 1/3 ARM: MXC: mxcmmc: misc cleanups
Quoted 8 lines · Sascha Hauer
Quoted 6 lines · Daniel Mack
Quoted 5 lines · Sascha Hauer
Quoted 2 lines · Daniel Mack
Is this series ok to go in?
Sascha, will this go thru your tree?Can do. One of your patches touches the generic SDIO layer. Can I
have
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
an acked-by from someone involved in it?
I think you can get a Tested-by: from Volker Ernst and Andy Green and a Reviewed-by: from Micha? Miros?aw who was guiding me thru the locking bits. Can anyone give some thumbs-up, please?
Ok, I think it's been enough time for someone to complain. Applied to mxc-master.
Sorry I was travelling yesterday. The patch is definitely worth having.
We've been running a variation of this patch for several days, however not 100% the same since Volker has ported the iMX31 SDMA engine from the freescale tree for a few weeks now on our tree, and now has the SDIO working through SDMA (and a second channel with SD Card also on SDMA) FWIW.
We're not planning to do the work to get that into mainline but I think Daniel expressed an interest.
-Andy
PATCH 2/3 ARM: MXC: mxcmmc: Teach the driver SDIO operations
In reply to Daniel MackSuccessfully tested on MX31 hardware using libertas SDIO peripherals.
--- drivers/mmc/host/mxcmmc.c | 70 +++++++++++++++++++++++++++++++++++++------- 1 files changed, 59 insertions(+), 11 deletions(-)
drivers/mmc/host/mxcmmc.c +59 -11
@@ -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,9 @@ 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; +unsigned long flags; +WARN_ON (host->cmd !=NULL ); host->cmd = cmd;
@@ -249,12 +254,16 @@ 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 ; + +spin_lock_irqsave (&host->lock, flags); +if (host->use_sdio) + int_cntr |=INT_SDIO_IRQ_EN ; +writel (int_cntr, host->base +MMC_REG_INT_CNTR ); +spin_unlock_irqrestore (&host->lock, flags);writew (cmd->opcode, host->base +MMC_REG_CMD );writel (cmd->arg, host->base +MMC_REG_ARG );
@@ -266,7 +275,14 @@ 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 ; +unsigned long flags; + +spin_lock_irqsave (&host->lock, flags); +if (host->use_sdio) + int_cntr |=INT_SDIO_IRQ_EN ; +writel (int_cntr, host->base +MMC_REG_INT_CNTR ); +spin_unlock_irqrestore (&host->lock, flags); host->req =NULL ; host->cmd =NULL ;
@@ -532,15 +548,27 @@ static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)static irqreturn_t mxcmci_irq (int irq,void *devid) {struct mxcmci_host *host = devid; +unsigned long flags; +bool sdio_irq;u32 stat; stat =readl (host->base +MMC_REG_STATUS ); -writel (stat, host->base +MMC_REG_STATUS ); +writel (stat & ~STATUS_SDIO_INT_ACTIVE , host->base +MMC_REG_STATUS );dev_dbg (mmc_dev (host->mmc),"%s: 0x%08x\n" , __func__, stat); +spin_lock_irqsave (&host->lock, flags); + sdio_irq = (stat &STATUS_SDIO_INT_ACTIVE ) && host->use_sdio; +spin_unlock_irqrestore (&host->lock, flags); + +if (sdio_irq) { +writel (STATUS_SDIO_INT_ACTIVE , host->base +MMC_REG_STATUS ); +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 )))
@@ -677,11 +705,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)
@@ -709,7 +756,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 ;
@@ -728,6 +775,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;
Signature · 1 line
1.7.0
PATCH 3/3 ARM: MXC: mxcmmc: work around a bug in the SDHC busy line handling
In reply to Daniel MackMX3 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().
--- drivers/mmc/core/sdio.c | 6 ++++++ drivers/mmc/host/mxcmmc.c | 16 ++++++++++++++++ include/linux/mmc/host.h | 3 +++ 3 files changed, 25 insertions(+), 0 deletions(-)
drivers/mmc/core/sdio.c +6 -0
@@ -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)) {
drivers/mmc/host/mxcmmc.c +16 -0
@@ -724,11 +724,27 @@ 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 ; +else + 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)
include/linux/mmc/host.h +3 -0
@@ -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 ;
Signature · 1 line
1.7.0