Re: [PATCH v3 5/7] mmc: SDHI: add DT compatibility strings for further SoCs
Hi Guennadi diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index cc4c872..b58c1a9 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -130,6 +130,9 @@ static const struct of_device_id sh_mobile_sdhi_of_match[] = { { .compatible = renesas,shmobile-sdhi }, { .compatible = renesas,sh7372-sdhi }, { .compatible = renesas,r8a7740-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,sh73a0-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a73a4-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a7790-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, {}, According to HW people, latest Renesas chip needs TMIO_MMC_HAS_IDLE_WAIT. Could you plase add r8a7778 / r8a7779 here ? # or we can use common compatible name for it ? Best regards --- Kuninori Morimoto -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: omap_hsmmc: use for OMAP5 as well
On Mon, Jul 08, 2013 at 02:58:28PM -0500, Nishanth Menon wrote: On 10:46-20130708, Felipe Balbi wrote: On Sun, Jul 07, 2013 at 05:13:10PM -0300, Ezequiel Garcia wrote: Hi guys, On Fri, Jun 28, 2013 at 09:27:20PM +0530, Balaji T K wrote: On Friday 28 June 2013 06:04 PM, a-bin...@ti.com wrote: From: Amarinder Bindra a-bin...@ti.com OMAP's hs_mmc driver is also used for OMAP5 MMC controller operation. Considering that the device tree entries are already there for this, allow the driver to be built when only OMAP5 is enabled. This allows MMC root filesystems to be available in OMAP5 only configurations. Signed-off-by: Amarinder Bindra a-bin...@ti.com Acked-by: Felipe Balbi ba...@ti.com Acked-by: Nishanth Menon n...@ti.com Looks good to me, Acked-by: Balaji T K balaj...@ti.com I came across this same issue while trying MMC patches on AM3xx, which is nor OMAP3 neither OMAP4. Now, looking at the driver I don't see any OMAP-specific bits (welcome to the multiplatform world ;-) so I think we can just remove the 'depends' line. Something like this: frankly speaking, this driver should be deleted and all users should be moved to sdhci. OMAP's HSMMC controller is compatible with SDHCI except for a couple quirks which can be easily worked around. Do we take that as a NAK to this specific patch? heh, not really. We can't prevent bug fixes to this driver just because long ago TI decided to write a TI-specific driver when it could just re-use SDHCI :-) -- balbi signature.asc Description: Digital signature
Re: [PATCH] mmc: omap_hsmmc: use for OMAP5 as well
On Mon, Jul 08, 2013 at 05:27:50PM -0300, Ezequiel Garcia wrote: On Mon, Jul 08, 2013 at 02:58:28PM -0500, Nishanth Menon wrote: On 10:46-20130708, Felipe Balbi wrote: On Sun, Jul 07, 2013 at 05:13:10PM -0300, Ezequiel Garcia wrote: Hi guys, On Fri, Jun 28, 2013 at 09:27:20PM +0530, Balaji T K wrote: On Friday 28 June 2013 06:04 PM, a-bin...@ti.com wrote: From: Amarinder Bindra a-bin...@ti.com OMAP's hs_mmc driver is also used for OMAP5 MMC controller operation. Considering that the device tree entries are already there for this, allow the driver to be built when only OMAP5 is enabled. This allows MMC root filesystems to be available in OMAP5 only configurations. Signed-off-by: Amarinder Bindra a-bin...@ti.com Acked-by: Felipe Balbi ba...@ti.com Acked-by: Nishanth Menon n...@ti.com Looks good to me, Acked-by: Balaji T K balaj...@ti.com I came across this same issue while trying MMC patches on AM3xx, which is nor OMAP3 neither OMAP4. Now, looking at the driver I don't see any OMAP-specific bits (welcome to the multiplatform world ;-) so I think we can just remove the 'depends' line. Something like this: frankly speaking, this driver should be deleted and all users should be moved to sdhci. OMAP's HSMMC controller is compatible with SDHCI except for a couple quirks which can be easily worked around. @Felipe: Do you mind giving me some hints about this quirks? I'm not too familiar with these drivers. one of the quirks is that TI decided to registers into one (because they both had 16-bits reserved, so, well, we can make the HW 0.1 dollar cheaper :-p ) The other is related where our SDHCI registers start. Because of TI's added registers (SYSConfig and REVISION, etc), SDHCI registers have an offset which generic SDHCI driver, doesn't cope with right now. Do we take that as a NAK to this specific patch? I am not complaining about the future migration to a solution that is much more generic and scalable, but having fixes for current problems should'nt be ignored IMHO. Of course. How about a depends on CONFIG_ARCH_OMAP2PLUS instead? will that solve our pains with all OMAP2+ usin this? Yes, I think that using ARCH_OMAP2PLUS should do. FWIW, until we have sdhci ready to replace omap_hsmmc, we have no choice but to apply such a patch. if you do change to ARCH_OMAP2PLUS, please also add COMPILE_TEST (ARCH_OMAP2PLUS || COMPILE_TEST) so we can build in other archs. -- balbi signature.asc Description: Digital signature
[PATCH v4 5/7] mmc: SDHI: add DT compatibility strings for further SoCs
Add further OF compatibility strings to the SDHI driver to be able to precisely control driver's behaviour on each of them. Signed-off-by: Guennadi Liakhovetski g.liakhovetski+rene...@gmail.com --- v4: 1. added r8a7778 and r8a7779 per Morimoto-san's request 2. sh* and r8a* entries now sorted alphabetically drivers/mmc/host/sh_mobile_sdhi.c |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index cc4c872..dc4f0e0 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -129,7 +129,12 @@ static const struct sh_mobile_sdhi_ops sdhi_ops = { static const struct of_device_id sh_mobile_sdhi_of_match[] = { { .compatible = renesas,shmobile-sdhi }, { .compatible = renesas,sh7372-sdhi }, + { .compatible = renesas,sh73a0-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a73a4-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, { .compatible = renesas,r8a7740-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a7778-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a7779-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a7790-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, {}, }; MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match); -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 5/7] mmc: SDHI: add DT compatibility strings for further SoCs
On Tue, Jul 9, 2013 at 4:43 PM, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: Add further OF compatibility strings to the SDHI driver to be able to precisely control driver's behaviour on each of them. Signed-off-by: Guennadi Liakhovetski g.liakhovetski+rene...@gmail.com --- v4: 1. added r8a7778 and r8a7779 per Morimoto-san's request 2. sh* and r8a* entries now sorted alphabetically This looks good to me, thanks. Acked-by: Magnus Damm d...@opensource.se -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: TMIO: update Device Tree binding documentation
The SDHI mmc-tmio implementation has been updated to cover additional SoC types. This patch documents the changes. Signed-off-by: Guennadi Liakhovetski g.liakhovetski+rene...@gmail.com --- Now, that the patch mmc: SDHI: add DT compatibility strings for further SoCs has been approved, it shall be accompanied by this documentation update. Documentation/devicetree/bindings/mmc/tmio_mmc.txt | 13 + 1 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt index df204e1..ec6f5bd 100644 --- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt +++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt @@ -13,8 +13,13 @@ Optional properties: - toshiba,mmc-wrprotect-disable: write-protect detection is unavailable When used with Renesas SDHI hardware, the following compatibility strings -configure various model-specific properties: +configure properties, specific to the respective SoC model: -renesas,sh7372-sdhi: (default) compatible with SH7372 -renesas,r8a7740-sdhi:compatible with R8A7740: certain MMC/SD commands have to - wait for the interface to become idle. +renesas,shmobile-sdhi: generic SDHI block +renesas,sh7372-sdhi: SDHI block, used on SH7372 (SH-Mobile AP4) +renesas,sh73a0-sdhi: SDHI block, used on SH73A0 (SH-Mobile AG5) +renesas,r8a73a4-sdhi:SDHI block, used on R8A73A4 (R-Mobile APE6) +renesas,r8a7740-sdhi:SDHI block, used on R8A7740 (R-Mobile A1) +renesas,r8a7778-sdhi:SDHI block, used on R8A7778 (R-Car M1A) +renesas,r8a7779-sdhi:SDHI block, used on R8A7779 (R-Car H1) +renesas,r8a7790-sdhi:SDHI block, used on R8A7790 (R-Car H2) -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] MMC: Detect execution mode errors after r/w command
From: Lars Svensson lars1.svens...@sonymobile.com Some error bits in the status field of R1/R1b response are only set by the device in response to the command following the failing command. The status is only read and checked after a r/w command if an error is detected during the initial command or the following data transfer. In some situations this causes errors passing undetected. The solution is to read the status and check for these errors after each r/w operation. Signed-off-by: Lars Svensson lars1.svens...@sonymobile.com Signed-off-by: Oskar Andero oskar.and...@sonymobile.com Cc: linux-mmc@vger.kernel.org --- drivers/mmc/card/block.c | 105 +-- 1 file changed, 57 insertions(+), 48 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index dd27b07..b2664d7 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -754,10 +754,9 @@ static int mmc_blk_cmd_error(struct request *req, const char *name, int error, * Initial r/w and stop cmd error recovery. * We don't know whether the card received the r/w cmd or not, so try to * restore things back to a sane state. Essentially, we do this as follows: - * - Obtain card status. If the first attempt to obtain card status fails, - * the status word will reflect the failed status cmd, not the failed - * r/w cmd. If we fail to obtain card status, it suggests we can no - * longer communicate with the card. + * - Check card status. If the status_valid argument is false, the first attempt + * to obtain card status failed and the status argument will not reflect the + * failed r/w cmd. * - Check the card state. If the card received the cmd but there was a * transient problem with the response, it might still be in a data transfer * mode. Try to send it a stop command. If this fails, we can't recover. @@ -769,38 +768,15 @@ static int mmc_blk_cmd_error(struct request *req, const char *name, int error, * Otherwise we don't understand what happened, so abort. */ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, - struct mmc_blk_request *brq, int *ecc_err) + struct mmc_blk_request *brq, int *ecc_err, u32 status, + bool status_valid) { - bool prev_cmd_status_valid = true; - u32 status, stop_status = 0; - int err, retry; + u32 stop_status = 0; + int err; if (mmc_card_removed(card)) return ERR_NOMEDIUM; - /* -* Try to get card status which indicates both the card state -* and why there was no response. If the first attempt fails, -* we can't be sure the returned status is for the r/w command. -*/ - for (retry = 2; retry = 0; retry--) { - err = get_card_status(card, status, 0); - if (!err) - break; - - prev_cmd_status_valid = false; - pr_err(%s: error %d sending status command, %sing\n, - req-rq_disk-disk_name, err, retry ? retry : abort); - } - - /* We couldn't get a response from the card. Give up. */ - if (err) { - /* Check if the card is removed */ - if (mmc_detect_card_removed(card-host)) - return ERR_NOMEDIUM; - return ERR_ABORT; - } - /* Flag ECC errors */ if ((status R1_CARD_ECC_FAILED) || (brq-stop.resp[0] R1_CARD_ECC_FAILED) || @@ -831,12 +807,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, /* Check for set block count errors */ if (brq-sbc.error) return mmc_blk_cmd_error(req, SET_BLOCK_COUNT, brq-sbc.error, - prev_cmd_status_valid, status); + status_valid, status); /* Check for r/w command errors */ if (brq-cmd.error) return mmc_blk_cmd_error(req, r/w cmd, brq-cmd.error, - prev_cmd_status_valid, status); + status_valid, status); /* Data errors */ if (!brq-stop.error) @@ -1062,6 +1038,12 @@ static inline void mmc_apply_rel_rw(struct mmc_blk_request *brq, R1_CC_ERROR | /* Card controller error */ \ R1_ERROR) /* General/unknown error */ +#define EXE_ERRORS \ + (R1_OUT_OF_RANGE | /* Command argument out of range */ \ +R1_ADDRESS_ERROR | /* Misaligned address */\ +R1_WP_VIOLATION | /* Tried to write to protected block */ \ +R1_ERROR) /* General/unknown error */ + static int mmc_blk_err_check(struct mmc_card *card, struct mmc_async_req *areq) { @@ -1069,7 +1051,33 @@ static int mmc_blk_err_check(struct mmc_card *card,
[PATCH 3/8] sdhci: Use work structs instead of tasklets
The driver can happily live without an atomic context and tasklets, so turn the tasklets into the work structs. Tasklets handlers still grab irqsave spinlocks, but we'll deal with it in a separate patch. Patch based on: http://thread.gmane.org/gmane.linux.kernel.mmc/2579. Signed-off-by: Anton Vorontsov avoront...@mvista.com Signed-off-by: Jeremie Samuel jeremie.samuel@parrot.com --- drivers/mmc/host/sdhci.c | 55 + include/linux/mmc/sdhci.h |4 ++-- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 06ad0bb..ab635d5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -979,7 +979,7 @@ static void sdhci_finish_data(struct sdhci_host *host) sdhci_send_command(host, data-stop); } else - tasklet_schedule(host-finish_tasklet); + schedule_work(host-finish_work); } static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) @@ -1008,7 +1008,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) inhibit bit(s).\n, mmc_hostname(host-mmc)); sdhci_dumpregs(host); cmd-error = -EIO; - tasklet_schedule(host-finish_tasklet); + schedule_work(host-finish_work); return; } timeout--; @@ -1029,7 +1029,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) pr_err(%s: Unsupported response type!\n, mmc_hostname(host-mmc)); cmd-error = -EINVAL; - tasklet_schedule(host-finish_tasklet); + schedule_work(host-finish_work); return; } @@ -1090,7 +1090,7 @@ static void sdhci_finish_command(struct sdhci_host *host) sdhci_finish_data(host); if (!host-cmd-data) - tasklet_schedule(host-finish_tasklet); + schedule_work(host-finish_work); host-cmd = NULL; } @@ -1374,7 +1374,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) if (!present || host-flags SDHCI_DEVICE_DEAD) { host-mrq-cmd-error = -ENOMEDIUM; - tasklet_schedule(host-finish_tasklet); + schedule_work(host-finish_work); } else { u32 present_state; @@ -2081,7 +2081,7 @@ static void sdhci_card_event(struct mmc_host *mmc) sdhci_reset(host, SDHCI_RESET_DATA); host-mrq-cmd-error = -ENOMEDIUM; - tasklet_schedule(host-finish_tasklet); + schedule_work(host-finish_work); } spin_unlock_irqrestore(host-lock, flags); @@ -2106,29 +2106,30 @@ static const struct mmc_host_ops sdhci_ops = { * * \*/ -static void sdhci_tasklet_card(unsigned long param) +static void sdhci_card_detect_work(struct work_struct *wk) { - struct sdhci_host *host = (struct sdhci_host*)param; + struct sdhci_host *host = container_of(wk, struct sdhci_host, + card_detect_work); sdhci_card_event(host-mmc); mmc_detect_change(host-mmc, msecs_to_jiffies(200)); } -static void sdhci_tasklet_finish(unsigned long param) +static void sdhci_finish_work(struct work_struct *wk) { struct sdhci_host *host; unsigned long flags; struct mmc_request *mrq; - host = (struct sdhci_host*)param; + host = container_of(wk, struct sdhci_host, finish_work); spin_lock_irqsave(host-lock, flags); -/* - * If this tasklet gets rescheduled while running, it will - * be run again afterwards but without any active request. - */ + /* +* If this work gets rescheduled while running, it will +* be run again afterwards but without any active request. +*/ if (!host-mrq) { spin_unlock_irqrestore(host-lock, flags); return; @@ -2197,7 +2198,7 @@ static void sdhci_timeout_work(struct work_struct *wk) else host-mrq-cmd-error = -ETIMEDOUT; - tasklet_schedule(host-finish_tasklet); + schedule_work(host-finish_work); } } @@ -2244,7 +2245,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) host-cmd-error = -EILSEQ; if (host-cmd-error) { - tasklet_schedule(host-finish_tasklet); + schedule_work(host-finish_work);
[PATCH 4/8] sdhci: Use threaded IRQ handler
We only need atomic context to disable SDHCI interrupts, after that we can run in a kernel thread. Note that irq handler still grabs an irqsave spinlock, we'll deal with it in a subsequent patch. Patch based on: http://thread.gmane.org/gmane.linux.kernel.mmc/2579. Signed-off-by: Anton Vorontsov avoront...@mvista.com Signed-off-by: Jeremie Samuel jeremie.samuel@parrot.com --- drivers/mmc/host/sdhci.c | 46 -- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ab635d5..21ef1e0 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2405,9 +2405,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) } } -static irqreturn_t sdhci_irq(int irq, void *dev_id) +static irqreturn_t sdhci_irq_thread(int irq, void *dev_id) { - irqreturn_t result; struct sdhci_host *host = dev_id; u32 intmask, unexpected = 0; int cardint = 0, max_loops = 16; @@ -2423,15 +2422,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) intmask = sdhci_readl(host, SDHCI_INT_STATUS); - if (!intmask || intmask == 0x) { - result = IRQ_NONE; - goto out; - } - again: - DBG(*** %s got interrupt: 0x%08x\n, - mmc_hostname(host-mmc), intmask); - if (intmask (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) SDHCI_CARD_PRESENT; @@ -2491,12 +2482,10 @@ again: sdhci_writel(host, intmask, SDHCI_INT_STATUS); } - result = IRQ_HANDLED; - intmask = sdhci_readl(host, SDHCI_INT_STATUS); if (intmask --max_loops) goto again; -out: + spin_unlock(host-lock); if (unexpected) { @@ -2510,7 +2499,27 @@ out: if (cardint) mmc_signal_sdio_irq(host-mmc); - return result; + intmask = sdhci_readl(host, SDHCI_INT_ENABLE); + sdhci_writel(host, intmask, SDHCI_SIGNAL_ENABLE); + + return IRQ_HANDLED; +} + +static irqreturn_t sdhci_irq(int irq, void *dev_id) +{ + struct sdhci_host *host = dev_id; + u32 intmask = sdhci_readl(host, SDHCI_INT_STATUS); + + if (!intmask || intmask == 0x) + return IRQ_NONE; + + /* Disable interrupts */ + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); + + DBG(*** %s got interrupt: 0x%08x\n, + mmc_hostname(host-mmc), intmask); + + return IRQ_WAKE_THREAD; } /*\ @@ -2597,8 +2606,9 @@ int sdhci_resume_host(struct sdhci_host *host) } if (!device_may_wakeup(mmc_dev(host-mmc))) { - ret = request_irq(host-irq, sdhci_irq, IRQF_SHARED, - mmc_hostname(host-mmc), host); + ret = request_threaded_irq(host-irq, sdhci_irq, + sdhci_irq_thread, IRQF_SHARED, + mmc_hostname(host-mmc), host); if (ret) return ret; } else { @@ -3213,8 +3223,8 @@ int sdhci_add_host(struct sdhci_host *host) sdhci_tuning_timeout_work); } - ret = request_irq(host-irq, sdhci_irq, IRQF_SHARED, - mmc_hostname(mmc), host); + ret = request_threaded_irq(host-irq, sdhci_irq, sdhci_irq_thread, + IRQF_SHARED, mmc_hostname(host-mmc), host); if (ret) { pr_err(%s: Failed to request IRQ %d: %d\n, mmc_hostname(mmc), host-irq, ret); -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/8] sdhci: Move real work out of an atomic context
Hi all, Currently the sdhci driver does everything in the atomic context. And what is worse, PIO transfers are made from the IRQ handler. Some patches were already submitted to solve this issue. But there were rejected because they involved new issues. This set of patches is an evolution of an old patch from Anton Vorontsov. I tried to fix all the problems involved by the patches. I tested it for several time now with SD cards and SDIO. So, this patch set reworks sdhci code to avoid atomic context, almost completely. Thanks, Jeremie Samuel Jeremie Samuel (8): sdhci: Turn timeout timer into delayed work sdhci: Turn tuning timeout timer into delayed work sdhci: Use work structs instead of tasklets sdhci: Use threaded IRQ handler sdhci: Delay led blinking sdhci: Turn host-lock into a mutex sdhci: Get rid of mdelay()s where it is safe and makes sense sdhci: Use jiffies instead of a timeout counter drivers/mmc/host/sdhci.c | 327 ++--- include/linux/mmc/sdhci.h | 13 +- 2 files changed, 168 insertions(+), 172 deletions(-) -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/8] sdhci: Turn tuning timeout timer into delayed work
Same as previous patch Signed-off-by: Jeremie Samuel jeremie.samuel@parrot.com --- drivers/mmc/host/sdhci.c | 46 ++--- include/linux/mmc/sdhci.h |2 +- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 3fede60..06ad0bb 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -53,7 +53,7 @@ static void sdhci_finish_data(struct sdhci_host *); static void sdhci_send_command(struct sdhci_host *, struct mmc_command *); static void sdhci_finish_command(struct sdhci_host *); static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); -static void sdhci_tuning_timer(unsigned long data); +static void sdhci_tuning_timeout_work(struct work_struct *wk); static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); #ifdef CONFIG_PM_RUNTIME @@ -268,7 +268,7 @@ static void sdhci_reinit(struct sdhci_host *host) if (host-flags SDHCI_USING_RETUNING_TIMER) { host-flags = ~SDHCI_USING_RETUNING_TIMER; - del_timer_sync(host-tuning_timer); + flush_delayed_work(host-tuning_timeout_work); host-flags = ~SDHCI_NEEDS_RETUNING; host-mmc-max_blk_count = (host-quirks SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535; @@ -1380,7 +1380,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); /* -* Check if the re-tuning timer has already expired and there +* Check if the re-tuning timeout has already expired and there * is no on-going data transfer. If so, we need to execute * tuning procedure before sending command. */ @@ -1994,32 +1994,33 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) out: /* * If this is the very first time we are here, we start the retuning -* timer. Since only during the first time, SDHCI_NEEDS_RETUNING -* flag won't be set, we check this condition before actually starting -* the timer. +* timeout workqueue. Since only during the first time, +* SDHCI_NEEDS_RETUNING flag won't be set, we check this condition +* before actually starting the timeout worqueue. */ if (!(host-flags SDHCI_NEEDS_RETUNING) host-tuning_count (host-tuning_mode == SDHCI_TUNING_MODE_1)) { host-flags |= SDHCI_USING_RETUNING_TIMER; - mod_timer(host-tuning_timer, jiffies + + schedule_delayed_work(host-tuning_timeout_work, host-tuning_count * HZ); /* Tuning mode 1 limits the maximum data length to 4MB */ mmc-max_blk_count = (4 * 1024 * 1024) / mmc-max_blk_size; } else { host-flags = ~SDHCI_NEEDS_RETUNING; - /* Reload the new initial value for timer */ + /* Reload the new initial value for timeout workqueue */ if (host-tuning_mode == SDHCI_TUNING_MODE_1) - mod_timer(host-tuning_timer, jiffies + + schedule_delayed_work(host-tuning_timeout_work, host-tuning_count * HZ); } /* * In case tuning fails, host controllers which support re-tuning can -* try tuning again at a later time, when the re-tuning timer expires. +* try tuning again at a later time, when the re-tuning timeout +* workqueue expires. * So for these controllers, we return 0. Since there might be other * controllers who do not have this capability, we return error for * them. SDHCI_USING_RETUNING_TIMER means the host is currently using -* a retuning timer to do the retuning for the card. +* a retuning timeout workqueue to do the retuning for the card. */ if (err (host-flags SDHCI_USING_RETUNING_TIMER)) err = 0; @@ -2204,12 +2205,12 @@ static void sdhci_timeout_work(struct work_struct *wk) spin_unlock_irqrestore(host-lock, flags); } -static void sdhci_tuning_timer(unsigned long data) +static void sdhci_tuning_timeout_work(struct work_struct *wk) { struct sdhci_host *host; unsigned long flags; - host = (struct sdhci_host *)data; + host = container_of(wk, struct sdhci_host, tuning_timeout_work.work); spin_lock_irqsave(host-lock, flags); @@ -2556,7 +2557,7 @@ int sdhci_suspend_host(struct sdhci_host *host) /* Disable tuning since we are suspending */ if (host-flags SDHCI_USING_RETUNING_TIMER) { - del_timer_sync(host-tuning_timer); + flush_delayed_work(host-tuning_timeout_work); host-flags = ~SDHCI_NEEDS_RETUNING; } @@ -2564,7
[PATCH 5/8] sdhci: Delay led blinking
The function sdhci_led_control is called in an atomic context by the led_trigger driver. So, it is necessary to delay the activation or deactivation of the led. Signed-off-by: Jeremie Samuel jeremie.samuel@parrot.com --- drivers/mmc/host/sdhci.c | 42 ++ include/linux/mmc/sdhci.h |1 + 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 21ef1e0..9a7471c 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -281,8 +281,14 @@ static void sdhci_activate_led(struct sdhci_host *host) u8 ctrl; ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); - ctrl |= SDHCI_CTRL_LED; - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); +#ifdef SDHCI_USE_LEDS_CLASS + if (host-brightness !(ctrl SDHCI_CTRL_LED)) { +#else + if (!(ctrl SDHCI_CTRL_LED)) { +#endif + ctrl |= SDHCI_CTRL_LED; + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); + } } static void sdhci_deactivate_led(struct sdhci_host *host) @@ -290,8 +296,14 @@ static void sdhci_deactivate_led(struct sdhci_host *host) u8 ctrl; ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); - ctrl = ~SDHCI_CTRL_LED; - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); +#ifdef SDHCI_USE_LEDS_CLASS + if (!host-brightness (ctrl SDHCI_CTRL_LED)) { +#else + if (ctrl SDHCI_CTRL_LED) { +#endif + ctrl = ~SDHCI_CTRL_LED; + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); + } } #ifdef SDHCI_USE_LEDS_CLASS @@ -299,19 +311,11 @@ static void sdhci_led_control(struct led_classdev *led, enum led_brightness brightness) { struct sdhci_host *host = container_of(led, struct sdhci_host, led); - unsigned long flags; - - spin_lock_irqsave(host-lock, flags); if (host-runtime_suspended) - goto out; + return; - if (brightness == LED_OFF) - sdhci_deactivate_led(host); - else - sdhci_activate_led(host); -out: - spin_unlock_irqrestore(host-lock, flags); + host-brightness = brightness; } #endif @@ -1338,9 +1342,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) WARN_ON(host-mrq != NULL); -#ifndef SDHCI_USE_LEDS_CLASS sdhci_activate_led(host); -#endif /* * Ensure we don't send the STOP for non-SET_BLOCK_COUNTED @@ -2164,15 +2166,15 @@ static void sdhci_finish_work(struct work_struct *wk) host-cmd = NULL; host-data = NULL; -#ifndef SDHCI_USE_LEDS_CLASS - sdhci_deactivate_led(host); -#endif - mmiowb(); spin_unlock_irqrestore(host-lock, flags); mmc_request_done(host-mmc, mrq); sdhci_runtime_pm_put(host); + + spin_lock_irqsave(host-lock, flags); + sdhci_deactivate_led(host); + spin_unlock_irqrestore(host-lock, flags); } static void sdhci_timeout_work(struct work_struct *wk) diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 0cc97ce..adb95c3 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -115,6 +115,7 @@ struct sdhci_host { #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) struct led_classdev led;/* LED control */ char led_name[32]; + enum led_brightness brightness; #endif spinlock_t lock;/* Mutex */ -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/8] sdhci: Get rid of mdelay()s where it is safe and makes sense
Since we don't run in the atomic context any longer, we can turn mdelay()s into msleep()s. The only place where the driver is still using mdelay() is sdhci_send_command(). There it is possible to use sleepable delays too, but we don't actually want to force rescheduling in a hot path. Sure, we might end up calling msleep() there too, just not via this safe patch. PAtch based on: http://thread.gmane.org/gmane.linux.kernel.mmc/2579. Signed-off-by: Anton Vorontsov avoront...@mvista.com Signed-off-by: Jeremie Samuel jeremie.samuel@parrot.com --- drivers/mmc/host/sdhci.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9161ae3..cabbe29 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -221,7 +221,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) return; } timeout--; - mdelay(1); + msleep(1); } if (host-ops-platform_reset_exit) @@ -1238,7 +1238,7 @@ clock_set: return; } timeout--; - mdelay(1); + msleep(1); } clk |= SDHCI_CLOCK_CARD_EN; @@ -1317,7 +1317,7 @@ static int sdhci_set_power(struct sdhci_host *host, unsigned short power) * can apply clock after applying power */ if (host-quirks SDHCI_QUIRK_DELAY_AFTER_POWER) - mdelay(10); + msleep(10); return power; } @@ -1971,7 +1971,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); tuning_loop_counter--; timeout--; - mdelay(1); + msleep(1); } while (ctrl SDHCI_CTRL_EXEC_TUNING); /* -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/8] sdhci: Turn host-lock into a mutex
Finally, we can get rid of the host-lock spinlock, and turn it into a mutex. This patch does just this. Patch based on: http://thread.gmane.org/gmane.linux.kernel.mmc/2579. Signed-off-by: Anton Vorontsov avoront...@mvista.com Signed-off-by: Jeremie Samuel jeremie.samuel@parrot.com --- drivers/mmc/host/sdhci.c | 99 - include/linux/mmc/sdhci.h |3 +- 2 files changed, 46 insertions(+), 56 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9a7471c..9161ae3 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -20,6 +20,7 @@ #include linux/module.h #include linux/dma-mapping.h #include linux/slab.h +#include linux/mutex.h #include linux/scatterlist.h #include linux/regulator/consumer.h #include linux/pm_runtime.h @@ -1331,14 +1332,13 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct sdhci_host *host; int present; - unsigned long flags; u32 tuning_opcode; host = mmc_priv(mmc); sdhci_runtime_pm_get(host); - spin_lock_irqsave(host-lock, flags); + mutex_lock(host-lock); WARN_ON(host-mrq != NULL); @@ -1394,9 +1394,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) mmc-card-type == MMC_TYPE_MMC ? MMC_SEND_TUNING_BLOCK_HS200 : MMC_SEND_TUNING_BLOCK; - spin_unlock_irqrestore(host-lock, flags); + mutex_unlock(host-lock); sdhci_execute_tuning(mmc, tuning_opcode); - spin_lock_irqsave(host-lock, flags); + mutex_lock(host-lock); /* Restore original mmc_request structure */ host-mrq = mrq; @@ -1410,19 +1410,18 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) } mmiowb(); - spin_unlock_irqrestore(host-lock, flags); + mutex_unlock(host-lock); } static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) { - unsigned long flags; int vdd_bit = -1; u8 ctrl; - spin_lock_irqsave(host-lock, flags); + mutex_lock(host-lock); if (host-flags SDHCI_DEVICE_DEAD) { - spin_unlock_irqrestore(host-lock, flags); + mutex_unlock(host-lock); if (host-vmmc ios-power_mode == MMC_POWER_OFF) mmc_regulator_set_ocr(host-mmc, host-vmmc, 0); return; @@ -1449,9 +1448,9 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) vdd_bit = sdhci_set_power(host, ios-vdd); if (host-vmmc vdd_bit != -1) { - spin_unlock_irqrestore(host-lock, flags); + mutex_unlock(host-lock); mmc_regulator_set_ocr(host-mmc, host-vmmc, vdd_bit); - spin_lock_irqsave(host-lock, flags); + mutex_lock(host-lock); } if (host-ops-platform_send_init_74_clocks) @@ -1588,7 +1587,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); mmiowb(); - spin_unlock_irqrestore(host-lock, flags); + mutex_unlock(host-lock); } static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) @@ -1633,10 +1632,9 @@ static int sdhci_get_cd(struct mmc_host *mmc) static int sdhci_check_ro(struct sdhci_host *host) { - unsigned long flags; int is_readonly; - spin_lock_irqsave(host-lock, flags); + mutex_lock(host-lock); if (host-flags SDHCI_DEVICE_DEAD) is_readonly = 0; @@ -1646,7 +1644,7 @@ static int sdhci_check_ro(struct sdhci_host *host) is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE) SDHCI_WRITE_PROTECT); - spin_unlock_irqrestore(host-lock, flags); + mutex_unlock(host-lock); /* This quirk needs to be replaced by a callback-function later */ return host-quirks SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? @@ -1717,11 +1715,10 @@ out: static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) { struct sdhci_host *host = mmc_priv(mmc); - unsigned long flags; - spin_lock_irqsave(host-lock, flags); + mutex_lock(host-lock); sdhci_enable_sdio_irq_nolock(host, enable); - spin_unlock_irqrestore(host-lock, flags); + mutex_unlock(host-lock); } static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host, @@ -1852,7 +1849,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) sdhci_runtime_pm_get(host);
[PATCH 8/8] sdhci: Use jiffies instead of a timeout counter
Just a cosmetic change, should not affect functionality. Patch based on: http://thread.gmane.org/gmane.linux.kernel.mmc/2579. Signed-off-by: Anton Vorontsov avoront...@mvista.com Signed-off-by: Jeremie Samuel jeremie.samuel@parrot.com --- drivers/mmc/host/sdhci.c | 22 +- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index cabbe29..b261555 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -210,17 +210,16 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) } /* Wait max 100 ms */ - timeout = 100; + timeout = jiffies + msecs_to_jiffies(100); /* hw clears the bit when it's done */ while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) mask) { - if (timeout == 0) { + if (time_after(jiffies, timeout)) { pr_err(%s: Reset 0x%x never completed.\n, mmc_hostname(host-mmc), (int)mask); sdhci_dumpregs(host); return; } - timeout--; msleep(1); } @@ -996,7 +995,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) WARN_ON(host-cmd); /* Wait max 10 ms */ - timeout = 10; + timeout = jiffies + msecs_to_jiffies(10); mask = SDHCI_CMD_INHIBIT; if ((cmd-data != NULL) || (cmd-flags MMC_RSP_BUSY)) @@ -1008,7 +1007,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) mask = ~SDHCI_DATA_INHIBIT; while (sdhci_readl(host, SDHCI_PRESENT_STATE) mask) { - if (timeout == 0) { + if (time_after(jiffies, timeout)) { pr_err(%s: Controller never released inhibit bit(s).\n, mmc_hostname(host-mmc)); sdhci_dumpregs(host); @@ -1016,7 +1015,6 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) schedule_work(host-finish_work); return; } - timeout--; mdelay(1); } @@ -1228,16 +1226,15 @@ clock_set: sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); /* Wait max 20 ms */ - timeout = 20; + timeout = jiffies + msecs_to_jiffies(20); while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) SDHCI_CLOCK_INT_STABLE)) { - if (timeout == 0) { + if (time_after(jiffies, timeout)) { pr_err(%s: Internal clock never stabilised.\n, mmc_hostname(host-mmc)); sdhci_dumpregs(host); return; } - timeout--; msleep(1); } @@ -1894,12 +1891,12 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number * of loops reaches 40 times or a timeout of 150ms occurs. */ - timeout = 150; + timeout = jiffies + msecs_to_jiffies(150); do { struct mmc_command cmd = {0}; struct mmc_request mrq = {NULL}; - if (!tuning_loop_counter !timeout) + if (!tuning_loop_counter time_after(jiffies, timeout)) break; cmd.opcode = opcode; @@ -1970,7 +1967,6 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); tuning_loop_counter--; - timeout--; msleep(1); } while (ctrl SDHCI_CTRL_EXEC_TUNING); @@ -1978,7 +1974,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) * The Host Driver has exhausted the maximum number of loops allowed, * so use fixed sampling frequency. */ - if (!tuning_loop_counter || !timeout) { + if (!tuning_loop_counter || time_after(jiffies, timeout)) { ctrl = ~SDHCI_CTRL_TUNED_CLK; sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); } else { -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/8] sdhci: Move real work out of an atomic context
On Jul 9, 2013, at 4:44 PM, Jeremie Samuel jeremie.samuel@parrot.com wrote: Hi all, Currently the sdhci driver does everything in the atomic context. And what is worse, PIO transfers are made from the IRQ handler. Some patches were already submitted to solve this issue. But there were rejected because they involved new issues. This set of patches is an evolution of an old patch from Anton Vorontsov. I tried to fix all the problems involved by the patches. I tested it for several time now with SD cards and SDIO. So, this patch set reworks sdhci code to avoid atomic context, almost completely. Thanks, Running DDR50, SDR104 or HS200 what is the performance impact ? Jeremie Samuel Jeremie Samuel (8): sdhci: Turn timeout timer into delayed work sdhci: Turn tuning timeout timer into delayed work sdhci: Use work structs instead of tasklets sdhci: Use threaded IRQ handler sdhci: Delay led blinking sdhci: Turn host-lock into a mutex sdhci: Get rid of mdelay()s where it is safe and makes sense sdhci: Use jiffies instead of a timeout counter drivers/mmc/host/sdhci.c | 327 ++--- include/linux/mmc/sdhci.h | 13 +- 2 files changed, 168 insertions(+), 172 deletions(-) -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/5] mmc: dw_mmc: Invalidate cache of current_speed after suspend/resume
The dw_mmc driver keeps a cache of the current slot-clock in order to avoid doing a whole lot of work every time set_ios() is called. However, after suspend/resume the register values are bogus so we need to ensure that the cached value is invalidated. In many cases we got by without this since the core mmc code fiddles with the clock a lot. If we've got a card present we're probably running it at something like 50MHz and the core will temporarily switch us to 400kHz after resume. One case that didn't work (for me) is the case of having no card in the slot. The slot is initted to 400kHz at boot time. After suspend/resume the slot thinks it's still at 400kHz (due to the cache) so doesn't adjust timing. When it tries to send the command at probe time it just times out and gets left in a bad state. Invalidating the current_speed also means that we don't need to call: dw_mci_setup_bus(slot, true); ...to force an update of the clock in the case when the slot was left powered. Signed-off-by: Doug Anderson diand...@chromium.org --- drivers/mmc/host/dw_mmc.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index bc3a1bc..f20273e 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2488,13 +2488,18 @@ int dw_mci_resume(struct dw_mci *host) DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); + /* +* Invalidate the 'current_speed' value since CLKDIV has some up in +* default state and our cache is incorrect. +*/ + host-current_speed = 0x; + for (i = 0; i host-num_slots; i++) { struct dw_mci_slot *slot = host-slot[i]; if (!slot) continue; if (slot-mmc-pm_flags MMC_PM_KEEP_POWER) { dw_mci_set_ios(slot-mmc, slot-mmc-ios); - dw_mci_setup_bus(slot, true); } ret = mmc_resume_host(host-slot[i]-mmc); -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/5] mmc: dw_mmc: Add suspend/resume callbacks; disable irq during suspend
On some platforms (like exynos5420) the dw_mmc controller may be in a strange state after we wake up from sleep. Add callbacks to allow for dealing with these quirks. Prevent interrupts from firing when we're suspended since this strange state may cause interrupts to fire. In my case I saw the WAKEUP_INT interrupt firing upon resume and needed to add some code to handle this. Signed-off-by: Doug Anderson diand...@chromium.org --- drivers/mmc/host/dw_mmc.c | 12 drivers/mmc/host/dw_mmc.h | 4 2 files changed, 16 insertions(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index f20273e..2aaa93f 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2434,6 +2434,7 @@ EXPORT_SYMBOL(dw_mci_remove); */ int dw_mci_suspend(struct dw_mci *host) { + const struct dw_mci_drv_data *drv_data = host-drv_data; int i, ret = 0; for (i = 0; i host-num_slots; i++) { @@ -2454,14 +2455,25 @@ int dw_mci_suspend(struct dw_mci *host) if (host-vmmc) regulator_disable(host-vmmc); + disable_irq(host-irq); + + if (drv_data drv_data-suspend) + drv_data-suspend(host); + return 0; } EXPORT_SYMBOL(dw_mci_suspend); int dw_mci_resume(struct dw_mci *host) { + const struct dw_mci_drv_data *drv_data = host-drv_data; int i, ret; + if (drv_data drv_data-resume) + drv_data-resume(host); + + enable_irq(host-irq); + if (host-vmmc) { ret = regulator_enable(host-vmmc); if (ret) { diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 0b74189..52a3266 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -190,6 +190,8 @@ extern int dw_mci_resume(struct dw_mci *host); * @prepare_command: handle CMD register extensions. * @set_ios: handle bus specific extensions. * @parse_dt: parse implementation specific device tree properties. + * @suspend: called late in the suspend process + * @resume: called early in the resume process * * Provide controller implementation specific extensions. The usage of this * data structure is fully optional and usage of each member in this structure @@ -202,5 +204,7 @@ struct dw_mci_drv_data { void(*prepare_command)(struct dw_mci *host, u32 *cmdr); void(*set_ios)(struct dw_mci *host, struct mmc_ios *ios); int (*parse_dt)(struct dw_mci *host); + void(*suspend)(struct dw_mci *host); + void(*resume)(struct dw_mci *host); }; #endif /* _DW_MMC_H_ */ -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/5] mmc: dw_mmc: Always setup the bus after suspend/resume
After suspend/resume all of the dw_mmc registers are reset to defaults. We restore most of them, but specifically don't setup the clock registers after resume unless we've got a powered card. Things still work because the core will eventually call set_ios() and we'll set things up. There doesn't seem to be any reason that I can see _not_ to set things up after resume. Restoring this state makes the code easier to reason about and should help prevent bugs. It also allows us to do a register dump before and after suspend/resume to confirm that we've set things up OK. I examined the state of the dw_mmc instance before and after suspend after this patch. I had no card inserted in an SD card slot. Before this patch, differences were: * CLKDIV (0x08) * CLKENA (0x10) * TMOUT (0x14) * CMD (0x2C) - difference is not important * CLKSEL (0x9C - exynos specific) After this patch, only TMOUT was different. I have a separate patch for that. Signed-off-by: Doug Anderson diand...@chromium.org --- drivers/mmc/host/dw_mmc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 2aaa93f..a0a07df 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2510,9 +2510,7 @@ int dw_mci_resume(struct dw_mci *host) struct dw_mci_slot *slot = host-slot[i]; if (!slot) continue; - if (slot-mmc-pm_flags MMC_PM_KEEP_POWER) { - dw_mci_set_ios(slot-mmc, slot-mmc-ios); - } + dw_mci_set_ios(slot-mmc, slot-mmc-ios); ret = mmc_resume_host(host-slot[i]-mmc); if (ret 0) -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/5] mmc: dw_mmc: fixes for suspend/resume on exynos
This series of patches addresses some suspend/resume problems with dw_mmc on exynos platforms. Since suspend/resume is not fully working on ToT Linux (3.10) on exynos5250-snow, this series was tested against the current ToT ChromeOS 3.8 tree. I have confirmed basic booting and eMMC / SD card usage (and compiling, honest!) against ToT Linux. Doug Anderson (5): mmc: dw_mmc: Invalidate cache of current_speed after suspend/resume mmc: dw_mmc: Add suspend/resume callbacks; disable irq during suspend mmc: dw_mmc: Add exynos resume callback to clear WAKEUP_INT mmc: dw_mmc: Always setup the bus after suspend/resume mmc: dw_mmc: Set timeout to max upon resume drivers/mmc/host/dw_mmc-exynos.c | 23 +++ drivers/mmc/host/dw_mmc.c| 26 ++ drivers/mmc/host/dw_mmc.h| 4 3 files changed, 49 insertions(+), 4 deletions(-) -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/5] mmc: dw_mmc: Set timeout to max upon resume
The TMOUT register is initted to 0x at probe time but isn't initted after suspend/resume. Add an init of this value. No problems were observed without this (it will also get initted in __dw_mci_start_request if there is data to send), but it makes the register dump before and after suspend clean. Signed-off-by: Doug Anderson diand...@chromium.org --- drivers/mmc/host/dw_mmc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a0a07df..eedb517 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2494,6 +2494,9 @@ int dw_mci_resume(struct dw_mci *host) /* Restore the old value at FIFOTH register */ mci_writel(host, FIFOTH, host-fifoth_val); + /* Put in max timeout */ + mci_writel(host, TMOUT, 0x); + mci_writel(host, RINTSTS, 0x); mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | SDMMC_INT_TXDR | SDMMC_INT_RXDR | -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/5] mmc: dw_mmc: Add exynos resume callback to clear WAKEUP_INT
If the WAKEUP_INT is asserted at wakeup and not cleared, we'll end up looping around forever. Signed-off-by: Doug Anderson diand...@chromium.org --- drivers/mmc/host/dw_mmc-exynos.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index f013e7e..84d3b78 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -30,6 +30,7 @@ #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ SDMMC_CLKSEL_CCLK_DRIVE(y) |\ SDMMC_CLKSEL_CCLK_DIVIDER(z)) +#define SDMMC_CLKSEL_WAKEUP_INTBIT(11) #define SDMMC_CMD_USE_HOLD_REG BIT(29) @@ -102,6 +103,27 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host) return 0; } +/** + * dw_mci_exynos_resume - Exynos-specific resume code + * + * We have seen cases (at least on the exynos5420) where turning off the INT + * power rail during suspend will leave the WAKEUP_INT bit in the CLKSEL + * register asserted. This bit is 1 to indicate that it fired and we can + * clear it by writing a 1 back. Clear it to prevent interrupts from going off + * constantly. + */ + +static int dw_mci_exynos_resume(struct dw_mci *host) +{ + u32 clksel; + + clksel = mci_readl(host, CLKSEL); + if (clksel SDMMC_CLKSEL_WAKEUP_INT) + mci_writel(host, CLKSEL, clksel); + + return 0; +} + static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) { /* @@ -165,6 +187,7 @@ static const struct dw_mci_drv_data exynos_drv_data = { .caps = exynos_dwmmc_caps, .init = dw_mci_exynos_priv_init, .setup_clock= dw_mci_exynos_setup_clock, + .resume = dw_mci_exynos_resume, .prepare_command= dw_mci_exynos_prepare_command, .set_ios= dw_mci_exynos_set_ios, .parse_dt = dw_mci_exynos_parse_dt, -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/5] mmc: dw_mmc: Add exynos resume callback to clear WAKEUP_INT
Hi, On Tue, Jul 9, 2013 at 10:31 AM, Doug Anderson diand...@chromium.org wrote: If the WAKEUP_INT is asserted at wakeup and not cleared, we'll end up looping around forever. Signed-off-by: Doug Anderson diand...@chromium.org --- drivers/mmc/host/dw_mmc-exynos.c | 23 +++ 1 file changed, 23 insertions(+) Grant just pointed out that the WAKEUP_INT is supposed to only be enabled if bits 8, 9, or 10 are 1. Our driver never sets those so we _should_ never get a WAKEUP_INT. Bits 8-10 are marked as RESERVED on the exynos5420 manual, so the current guess is that they're broken on that silicon but that sometimes the interrupt fires anyway. In any case, it is still a reasonable thing to clear this interrupt at wakeup if it has fired, even if we're on an exynos device without any problems. -Doug -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: 答复: [PATCH] Powerpc/t4240: change the compatible flags for t4240qds board
On 07/09/2013 01:04:01 AM, Zhang Haijun-B42677 wrote: Regards Thanks Haijun. 发件人: Wood Scott-B07421 发送时间: 2013年7月8日 17:14 收件人: Zhang Haijun-B42677 抄送: linux-mmc@vger.kernel.org; linuxppc-...@lists.ozlabs.org; cbouatmai...@gmail.com; c...@laptop.org; Fleming Andy-AFLEMING; Wrobel Heinz-R39252; Zhang Haijun-B42677 主题: Re: [PATCH] Powerpc/t4240: change the compatible flags for t4240qds board On 07/08/2013 02:16:03 AM, Haijun Zhang wrote: In order to make a difference between different T4240 board. Specify T4240QDS board the unique compatible flags for t4240qds eSDHC host. Signed-off-by: Haijun Zhang haijun.zh...@freescale.com --- arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi index bd611a9..08b47d0 100644 --- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi @@ -397,7 +397,7 @@ /include/ qoriq-esdhc-0.dtsi sdhc@114000 { - compatible = fsl,t4240-esdhc, fsl,esdhc; + compatible = fsl,t4240qds-esdhc, fsl,esdhc; sdhci,auto-cmd12; }; NACK. This node is describing the sdhc block of the t4240 SoC. What board you stick it in doesn't change what it is. Plus, what about users with old device trees? Currently no users use this ip block except esdhc driver. I'm not talking about code users. I'm talking about people users. How about change this in arch/powerpc/boot/dts/t4240qds.dts +++ b/arch/powerpc/boot/dts/t4240qds.dts @@ -117,6 +117,10 @@ }; }; sdhc@114000 { compatible = fsl,t4240-esdhc, fsl,esdhc; }; i2c@118000 { +++ b/arch/powerpc/boot/dts/t4240qds.dts @@ -117,6 +117,10 @@ }; }; + sdhc@114000 { + compatible = fsl,t4240qds-esdhc, fsl,esdhc; + }; + i2c@118000 { No. It's still supposed to be describing the sdhc block itself, not the board -- and any workarounds that key off of this will still fail to work with existing device trees. -Scott -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: dw_mmc: Handle DW_MCI_QUIRK_IDMAC_DTO properly
In (1fb5f68 mmc: dw_mmc: Don't loop when handling an interrupt), the code for handling DW_MCI_QUIRK_IDMAC_DTO became dead code. Move it to where it ought to live. Found by code inspection and compile-tested only--I don't know of any boards that need DW_MCI_QUIRK_IDMAC_DTO. Signed-off-by: Doug Anderson diand...@chromium.org --- drivers/mmc/host/dw_mmc.c | 21 ++--- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index bc3a1bc..cdc0940 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1595,18 +1595,17 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) pending = mci_readl(host, MINTSTS); /* read-only mask reg */ - if (pending) { - - /* -* DTO fix - version 2.10a and below, and only if internal DMA -* is configured. -*/ - if (host-quirks DW_MCI_QUIRK_IDMAC_DTO) { - if (!pending - ((mci_readl(host, STATUS) 17) 0x1fff)) - pending |= SDMMC_INT_DATA_OVER; - } + /* +* DTO fix - version 2.10a and below, and only if internal DMA +* is configured. +*/ + if (host-quirks DW_MCI_QUIRK_IDMAC_DTO) { + if (!pending + ((mci_readl(host, STATUS) 17) 0x1fff)) + pending |= SDMMC_INT_DATA_OVER; + } + if (pending) { if (pending DW_MCI_CMD_ERROR_FLAGS) { mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); host-cmd_status = pending; -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5] mmc: dw_mmc: Add suspend/resume callbacks; disable irq during suspend
Hi Doug, On 9 July 2013 18:31, Doug Anderson diand...@chromium.org wrote: On some platforms (like exynos5420) the dw_mmc controller may be in a strange state after we wake up from sleep. Add callbacks to allow for dealing with these quirks. Prevent interrupts from firing when we're suspended since this strange state may cause interrupts to fire. In my case I saw the WAKEUP_INT interrupt firing upon resume and needed to add some code to handle this. Signed-off-by: Doug Anderson diand...@chromium.org Would it make sense to take advantage of the {suspend,resume}_noirq power management callbacks to clear that WAKEUP_INT before interrupts are re-enabled, rather than explicitly disabling and enabling the interrupt at the suspend/resume stage? Cheers James -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5] mmc: dw_mmc: Add suspend/resume callbacks; disable irq during suspend
James, On Tue, Jul 9, 2013 at 2:17 PM, James Hogan james.ho...@imgtec.com wrote: Hi Doug, On 9 July 2013 18:31, Doug Anderson diand...@chromium.org wrote: On some platforms (like exynos5420) the dw_mmc controller may be in a strange state after we wake up from sleep. Add callbacks to allow for dealing with these quirks. Prevent interrupts from firing when we're suspended since this strange state may cause interrupts to fire. In my case I saw the WAKEUP_INT interrupt firing upon resume and needed to add some code to handle this. Signed-off-by: Doug Anderson diand...@chromium.org Would it make sense to take advantage of the {suspend,resume}_noirq power management callbacks to clear that WAKEUP_INT before interrupts are re-enabled, rather than explicitly disabling and enabling the interrupt at the suspend/resume stage? That's a good suggestion. Let me give it a shot and get back to you after I validate that it works. -Doug -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[GIT PULL] MMC updates for 3.11-rc1
Hi Linus, Please pull from: git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git tags/mmc-updates-for-3.11-rc1 to receive the MMC merge for 3.11. There are currently no conflicts, and these patches have been tested in linux-next. Thanks. The following changes since commit 4a29b5591faf2fdf2b717594d50f70c15066: mmc: omap_hsmmc: Skip platform_get_resource_byname() for dt case (2013-05-26 14:23:11 -0400) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git tags/mmc-updates-for-3.11-rc1 for you to fetch changes up to 01ebea1b411aafc8eab440bf1d2037f01bbed99b: mmc: bcm281xx SDHCI driver (2013-07-05 13:00:31 -0400) MMC highlights for 3.11: Core: - Add support for eMMC 5.1 devices. - Add MMC_CAP_AGGRESSIVE_PM capability for aggressive power management of eMMC/SD between requests, using runtime PM. - Add an ioctl to perform the eMMC 4.5 Sanitize command; sample code at: git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc-utils.git Drivers: - dw_mmc: Add support for Rockchip's Cortex-A9 SoCs. - dw_mmc: Add support for Altera SoCFPGAs. - sdhci-esdhc-imx: Add support for 8-bit bus width, non-removable cards. - sdhci-bcm-kona: New driver for Broadcom Kona (281xx) SoCs. - sdhi/tmio: Add DT DMA support. Adrian Hunter (6): mmc: sdhci: add ability to stay runtime-resumed if the card is powered up mmc: sdhci-acpi: support runtime PM for ACPI HID 80860F14 SD cards mmc: sdhci-pci: support runtime PM for BYT SD cards mmc: sdhci-pci: add support for eMMC hardware reset for BYT eMMC. mmc: sdhci-acpi: add support for eMMC hardware reset for HID 80860F14 mmc: sdhci-pci: add another device id Al Cooper (1): mmc: sdhci-pltfm: Allow drivers to set quirks2 from platform data Andy Shevchenko (3): mmc: dw_mmc-pltfm: don't check resource with devm_ioremap_resource mmc: dw_mmc: eliminate useless usage of ret mmc: dw_mmc-pci: convert to use pcim_* and devm_* Arnd Bergmann (1): mmc: sirf: fix sdhci_pltfm_init sequence Barry Song (1): mmc: sdhci-sirf: let device core setup the default pin configuration Christian Daudt (3): mmc: sdhci: Add size for caller in init+register mmc: sdhci: add card_event callback to sdhci mmc: bcm281xx SDHCI driver Daniel Drake (1): sdhci-pxav3: Fix runtime PM initialization Dinh Nguyen (1): mmc: dw_mmc: Add support DW SD/MMC driver on SOCFPGA Doug Anderson (2): mmc: dw_mmc: Handle late vmmc regulators with EPROBE_DEFER mmc: dw_mmc: Add the ability to set the ciu clock frequency Fabio Estevam (1): mmc: mxs-mmc: Let device core handle pinctrl Fredrik Soderstedt (2): mmc: core: Only execute tuning for SDR50 and SDR104 mmc: core: Fix select power class after resume Giuseppe CAVALLARO (2): mmc: sdhci: fix caps2 for HS200 mmc: sdhci: fix ctrl_2 on super-speed selection Guennadi Liakhovetski (7): mmc: sdhi/tmio: make DMA filter implementation specific mmc: sdhi/tmio: switch to using dmaengine_slave_config() mmc: sdhi/tmio: add DT DMA support mmc: tmio: postpone controller reset during resume mmc: sh_mmcif: don't clear masked interrupts mmc: tmio: fix unbalanced power-on calls with clock-gating enabled mmc: tmio: reset the controller after power-up Heiko Stübner (3): mmc: dw_mmc-pltfm: remove static from dw_mci_pltfm_remove mmc: dw_mmc-pltfm: move probe and remove below dt match table mmc: dw_mmc-pltfm: add Rockchip variant Jaehoon Chung (1): mmc: dw_mmc: change the macro name from DTO to DRTO Jingoo Han (3): mmc: atmel-mci: add CONFIG_PM_SLEEP to suspend/resume functions mmc: remove unnecessary platform_set_drvdata() mmc: host: use platform_{get,set}_drvdata() Joonyoung Shim (1): mmc: dw_mmc: clear IDSTS register when initialize IDMAC Lars-Peter Clausen (4): mmc: jz4740: Use clk_prepare_enable/clk_disable_unprepare mmc: jz4740: Use SIMPLE_DEV_PM_OPS mmc: jz4740: Use slot-gpio helpers mmc: jz4740: Use managed resources Lucas Stach (2): mmc: sdhci-esdhc: calculate sdclk divider from controller clock mmc: esdhc-imx: parse max-frequency from devicetree Luciano Coelho (1): mmc: omap: remove unnecessary #if 0's Maya Erez (1): mmc: card: Adding support for sanitize in eMMC 4.5 Nicolas Ferre (1): mmc: atmel-mci: remove include mach/cpu.h Oded Gabbay (2): mmc: esdhc: Add support for 8-bit bus width and non-removable card mmc: esdhc: Fix bug when writing to SDHCI_HOST_CONTROL register Paul Cercueil (2): mmc: jz4740: Remove duplicated code. mmc: jz4740: Fix handling of read errors. Paul Taysom (1): mmc: reordered shutdown sequence in mmc_bld_remove_req Romain Izard (1):
[PATCH v2 1/5] mmc: dw_mmc: Invalidate cache of current_speed after suspend/resume
The dw_mmc driver keeps a cache of the current slot-clock in order to avoid doing a whole lot of work every time set_ios() is called. However, after suspend/resume the register values are bogus so we need to ensure that the cached value is invalidated. In many cases we got by without this since the core mmc code fiddles with the clock a lot. If we've got a card present we're probably running it at something like 50MHz and the core will temporarily switch us to 400kHz after resume. One case that didn't work (for me) is the case of having no card in the slot. The slot is initted to 400kHz at boot time. After suspend/resume the slot thinks it's still at 400kHz (due to the cache) so doesn't adjust timing. When it tries to send the command at probe time it just times out and gets left in a bad state. Invalidating the current_speed also means that we don't need to call: dw_mci_setup_bus(slot, true); ...to force an update of the clock in the case when the slot was left powered. Signed-off-by: Doug Anderson diand...@chromium.org --- Changes in v2: - Fix typo (some - come) - Use ~0 instead of 0x; add comment about value drivers/mmc/host/dw_mmc.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index bc3a1bc..7a5ce6a 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2488,13 +2488,19 @@ int dw_mci_resume(struct dw_mci *host) DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); + /* +* Invalidate the 'current_speed' value since CLKDIV has come up in +* default state and our cache is incorrect; set to something we know +* slot-clock won't be. +*/ + host-current_speed = ~0; + for (i = 0; i host-num_slots; i++) { struct dw_mci_slot *slot = host-slot[i]; if (!slot) continue; if (slot-mmc-pm_flags MMC_PM_KEEP_POWER) { dw_mci_set_ios(slot-mmc, slot-mmc-ios); - dw_mci_setup_bus(slot, true); } ret = mmc_resume_host(host-slot[i]-mmc); -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/5] mmc: dw_mmc: Add exynos resume_noirq callback to clear WAKEUP_INT
If the WAKEUP_INT is asserted at wakeup and not cleared, we'll end up looping around forever. This has been seen to happen on exynos5420 silicon despite the fact that we haven't enabled any wakeup events. Signed-off-by: Doug Anderson diand...@chromium.org --- Changes in v2: - Use suspend_noirq as per James Hogan. drivers/mmc/host/dw_mmc-exynos.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index f013e7e..36b9620 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -30,6 +30,7 @@ #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ SDMMC_CLKSEL_CCLK_DRIVE(y) |\ SDMMC_CLKSEL_CCLK_DIVIDER(z)) +#define SDMMC_CLKSEL_WAKEUP_INTBIT(11) #define SDMMC_CMD_USE_HOLD_REG BIT(29) @@ -102,6 +103,27 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host) return 0; } +/** + * dw_mci_exynos_resume_noirq - Exynos-specific resume code + * + * We have seen cases (at least on the exynos5420) where turning off the INT + * power rail during suspend will leave the WAKEUP_INT bit in the CLKSEL + * register asserted. This bit is 1 to indicate that it fired and we can + * clear it by writing a 1 back. Clear it to prevent interrupts from going off + * constantly. + */ + +static int dw_mci_exynos_resume_noirq(struct dw_mci *host) +{ + u32 clksel; + + clksel = mci_readl(host, CLKSEL); + if (clksel SDMMC_CLKSEL_WAKEUP_INT) + mci_writel(host, CLKSEL, clksel); + + return 0; +} + static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) { /* @@ -165,6 +187,7 @@ static const struct dw_mci_drv_data exynos_drv_data = { .caps = exynos_dwmmc_caps, .init = dw_mci_exynos_priv_init, .setup_clock= dw_mci_exynos_setup_clock, + .resume_noirq = dw_mci_exynos_resume_noirq, .prepare_command= dw_mci_exynos_prepare_command, .set_ios= dw_mci_exynos_set_ios, .parse_dt = dw_mci_exynos_parse_dt, -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/5] mmc: dw_mmc: fixes for suspend/resume on exynos
This series of patches addresses some suspend/resume problems with dw_mmc on exynos platforms. Since suspend/resume is not fully working on ToT Linux (3.10) on exynos5250-snow, this series was tested against the current ToT ChromeOS 3.8 tree. I have confirmed basic booting and eMMC / SD card usage (and compiling, honest!) against ToT Linux. Changes in v2: - Fix typo (some - come) - Use ~0 instead of 0x; add comment about value - Use suspend_noirq as per James Hogan. Doug Anderson (5): mmc: dw_mmc: Invalidate cache of current_speed after suspend/resume mmc: dw_mmc: Add suspend_noirq/resume_noirq callbacks for dw_mmc-pltfm mmc: dw_mmc: Add exynos resume_noirq callback to clear WAKEUP_INT mmc: dw_mmc: Always setup the bus after suspend/resume mmc: dw_mmc: Set timeout to max upon resume drivers/mmc/host/dw_mmc-exynos.c | 23 +++ drivers/mmc/host/dw_mmc-pltfm.c | 37 ++--- drivers/mmc/host/dw_mmc.c| 15 +++ drivers/mmc/host/dw_mmc.h| 4 4 files changed, 72 insertions(+), 7 deletions(-) -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/5] mmc: dw_mmc: Add suspend_noirq/resume_noirq callbacks for dw_mmc-pltfm
On some devices (like exynos5420) the dw_mmc controller may be in a strange state after we wake up from sleep. Add callbacks to allow for dealing with these quirks. We use the _noirq versions of the callbacks since in the case of exynos5420 the strange state caused interrupts to fire so we need to deal with it while interrupts are still off. At the moment this support is only added to dw_mmc-pltfm which calls straight to the callback, since nobody but exynos needs it. We can add some levels of indirection (a call into the generic dw_mmc code) when someone finds a need. Signed-off-by: Doug Anderson diand...@chromium.org --- Changes in v2: - Use suspend_noirq as per James Hogan. drivers/mmc/host/dw_mmc-pltfm.c | 37 ++--- drivers/mmc/host/dw_mmc.h | 4 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index 41c27b7..220568c 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c @@ -105,12 +105,43 @@ static int dw_mci_pltfm_resume(struct device *dev) return 0; } + +static int dw_mci_pltfm_suspend_noirq(struct device *dev) +{ + struct dw_mci *host = dev_get_drvdata(dev); + const struct dw_mci_drv_data *drv_data = host-drv_data; + + if (drv_data drv_data-suspend_noirq) + return drv_data-suspend_noirq(host); + + return 0; +} + +static int dw_mci_pltfm_resume_noirq(struct device *dev) +{ + struct dw_mci *host = dev_get_drvdata(dev); + const struct dw_mci_drv_data *drv_data = host-drv_data; + + if (drv_data drv_data-resume_noirq) + return drv_data-resume_noirq(host); + + return 0; +} + + #else -#define dw_mci_pltfm_suspend NULL -#define dw_mci_pltfm_resumeNULL +#define dw_mci_pltfm_suspend NULL +#define dw_mci_pltfm_resumeNULL +#define dw_mci_pltfm_suspend_noirq NULL +#define dw_mci_pltfm_resume_noirq NULL #endif /* CONFIG_PM_SLEEP */ -SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume); +const struct dev_pm_ops dw_mci_pltfm_pmops = { + SET_SYSTEM_SLEEP_PM_OPS(dw_mci_pltfm_suspend, dw_mci_pltfm_resume) + .suspend_noirq = dw_mci_pltfm_suspend_noirq, + .resume_noirq = dw_mci_pltfm_resume_noirq, +}; + EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops); static const struct of_device_id dw_mci_pltfm_match[] = { diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 0b74189..5d0398f 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -190,6 +190,8 @@ extern int dw_mci_resume(struct dw_mci *host); * @prepare_command: handle CMD register extensions. * @set_ios: handle bus specific extensions. * @parse_dt: parse implementation specific device tree properties. + * @suspend_noirq: called late in the suspend process + * @resume_noirq: called early in the resume process * * Provide controller implementation specific extensions. The usage of this * data structure is fully optional and usage of each member in this structure @@ -202,5 +204,7 @@ struct dw_mci_drv_data { void(*prepare_command)(struct dw_mci *host, u32 *cmdr); void(*set_ios)(struct dw_mci *host, struct mmc_ios *ios); int (*parse_dt)(struct dw_mci *host); + int (*suspend_noirq)(struct dw_mci *host); + int (*resume_noirq)(struct dw_mci *host); }; #endif /* _DW_MMC_H_ */ -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/5] mmc: dw_mmc: Set timeout to max upon resume
The TMOUT register is initted to 0x at probe time but isn't initted after suspend/resume. Add an init of this value. No problems were observed without this (it will also get initted in __dw_mci_start_request if there is data to send), but it makes the register dump before and after suspend clean. Signed-off-by: Doug Anderson diand...@chromium.org --- Changes in v2: None drivers/mmc/host/dw_mmc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index be095b7..d2c5db3 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2482,6 +2482,9 @@ int dw_mci_resume(struct dw_mci *host) /* Restore the old value at FIFOTH register */ mci_writel(host, FIFOTH, host-fifoth_val); + /* Put in max timeout */ + mci_writel(host, TMOUT, 0x); + mci_writel(host, RINTSTS, 0x); mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | SDMMC_INT_TXDR | SDMMC_INT_RXDR | -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 4/5] mmc: dw_mmc: Always setup the bus after suspend/resume
After suspend/resume all of the dw_mmc registers are reset to defaults. We restore most of them, but specifically don't setup the clock registers after resume unless we've got a powered card. Things still work because the core will eventually call set_ios() and we'll set things up. There doesn't seem to be any reason that I can see _not_ to set things up after resume. Restoring this state makes the code easier to reason about and should help prevent bugs. It also allows us to do a register dump before and after suspend/resume to confirm that we've set things up OK. I examined the state of the dw_mmc instance before and after suspend after this patch. I had no card inserted in an SD card slot. Before this patch, differences were: * CLKDIV (0x08) * CLKENA (0x10) * TMOUT (0x14) * CMD (0x2C) - difference is not important * CLKSEL (0x9C - exynos specific) After this patch, only TMOUT was different. I have a separate patch for that. Signed-off-by: Doug Anderson diand...@chromium.org --- Changes in v2: None drivers/mmc/host/dw_mmc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 7a5ce6a..be095b7 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2499,9 +2499,7 @@ int dw_mci_resume(struct dw_mci *host) struct dw_mci_slot *slot = host-slot[i]; if (!slot) continue; - if (slot-mmc-pm_flags MMC_PM_KEEP_POWER) { - dw_mci_set_ios(slot-mmc, slot-mmc-ios); - } + dw_mci_set_ios(slot-mmc, slot-mmc-ios); ret = mmc_resume_host(host-slot[i]-mmc); if (ret 0) -- 1.8.3 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 5/7] mmc: SDHI: add DT compatibility strings for further SoCs
On Mon, Jul 08, 2013 at 11:09:07PM -0700, Kuninori Morimoto wrote: Hi Guennadi diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index cc4c872..b58c1a9 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -130,6 +130,9 @@ static const struct of_device_id sh_mobile_sdhi_of_match[] = { { .compatible = renesas,shmobile-sdhi }, { .compatible = renesas,sh7372-sdhi }, { .compatible = renesas,r8a7740-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,sh73a0-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a73a4-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a7790-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, {}, According to HW people, latest Renesas chip needs TMIO_MMC_HAS_IDLE_WAIT. Could you plase add r8a7778 / r8a7779 here ? # or we can use common compatible name for it ? Hi Guennadi, could you please address Morimoto-san's review? -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 5/7] mmc: SDHI: add DT compatibility strings for further SoCs
Hi Simon diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index cc4c872..b58c1a9 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -130,6 +130,9 @@ static const struct of_device_id sh_mobile_sdhi_of_match[] = { { .compatible = renesas,shmobile-sdhi }, { .compatible = renesas,sh7372-sdhi }, { .compatible = renesas,r8a7740-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,sh73a0-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a73a4-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a7790-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, {}, According to HW people, latest Renesas chip needs TMIO_MMC_HAS_IDLE_WAIT. Could you plase add r8a7778 / r8a7779 here ? # or we can use common compatible name for it ? Hi Guennadi, could you please address Morimoto-san's review? He did it on Subject: [PATCH v4 5/7] mmc: SDHI: add DT compatibility strings for further SoCs Date: Tue, 9 Jul 2013 09:43:40 +0200 (CEST) Best regards --- Kuninori Morimoto -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 5/7] mmc: SDHI: add DT compatibility strings for further SoCs
On Tue, Jul 09, 2013 at 06:06:00PM +0900, Magnus Damm wrote: On Tue, Jul 9, 2013 at 4:43 PM, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: Add further OF compatibility strings to the SDHI driver to be able to precisely control driver's behaviour on each of them. Signed-off-by: Guennadi Liakhovetski g.liakhovetski+rene...@gmail.com --- v4: 1. added r8a7778 and r8a7779 per Morimoto-san's request 2. sh* and r8a* entries now sorted alphabetically This looks good to me, thanks. Acked-by: Magnus Damm d...@opensource.se Thanks, I have queued this up for v3.12 in the soc branch. It should appear in renesas-next-20130710 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 5/7] mmc: SDHI: add DT compatibility strings for further SoCs
On Tue, Jul 09, 2013 at 06:06:00PM +0900, Magnus Damm wrote: On Tue, Jul 9, 2013 at 4:43 PM, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: Add further OF compatibility strings to the SDHI driver to be able to precisely control driver's behaviour on each of them. Signed-off-by: Guennadi Liakhovetski g.liakhovetski+rene...@gmail.com --- v4: 1. added r8a7778 and r8a7779 per Morimoto-san's request 2. sh* and r8a* entries now sorted alphabetically This looks good to me, thanks. Acked-by: Magnus Damm d...@opensource.se Thanks, I have queued this up for v3.12 in the dt branch. It should appear in renesas-next-20130710 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 5/7] mmc: SDHI: add DT compatibility strings for further SoCs
On Tue, Jul 09, 2013 at 06:02:00PM -0700, Kuninori Morimoto wrote: Hi Simon diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index cc4c872..b58c1a9 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -130,6 +130,9 @@ static const struct of_device_id sh_mobile_sdhi_of_match[] = { { .compatible = renesas,shmobile-sdhi }, { .compatible = renesas,sh7372-sdhi }, { .compatible = renesas,r8a7740-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,sh73a0-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a73a4-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, + { .compatible = renesas,r8a7790-sdhi, .data = sh_mobile_sdhi_of_cfg[0], }, {}, According to HW people, latest Renesas chip needs TMIO_MMC_HAS_IDLE_WAIT. Could you plase add r8a7778 / r8a7779 here ? # or we can use common compatible name for it ? Hi Guennadi, could you please address Morimoto-san's review? He did it on Subject: [PATCH v4 5/7] mmc: SDHI: add DT compatibility strings for further SoCs Date: Tue, 9 Jul 2013 09:43:40 +0200 (CEST) Thanks for pointing that out. Somehow I missed it. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] dmaengine: shdma: fix a build failure on platforms with no DMA support
On Mon, Jul 08, 2013 at 12:51:14PM +0530, Vinod Koul wrote: On Mon, Jul 08, 2013 at 12:52:16AM -0700, Olof Johansson wrote: On Thu, Jul 4, 2013 at 9:53 PM, Vinod Koul vinod.k...@intel.com wrote: On Wed, Jun 19, 2013 at 09:32:18PM +0200, Guennadi Liakhovetski wrote: Hi Vinod On Wed, 19 Jun 2013, Kevin Hilman wrote: On Thu, May 30, 2013 at 7:44 PM, Simon Horman ho...@verge.net.au wrote: [...] thanks for this. I will wait for a refresh (as we discussed earlier today). Can I confirm that this is a fix for v3.10? If so, could ou note that when you post your revised patch? Any progress on this patch? The SH-mobile defconfigs are still all failing in linux-next. In https://patchwork.kernel.org/patch/2640061/ And you havent CC maintainers on this patch, so I dont have it! I proposed a simple immediate fix for this problem. Arnd at the same time developed an alternative solution: https://patchwork.kernel.org/patch/2644121/ https://patchwork.kernel.org/patch/2644111/ Reading these patches I agree with Arnd that client drivers should not depend on dma slave drivers. Existing issue need to be fixed Arnd, Have you merged these changes? Looks like we now have breakage in linux-next for this again (new breakage due to the header file move being applied by you on Friday, Vinod? Are you planning on sending the code in for 3.11? If not, you shouldn't apply patches right now). Well they were already in my tree since 18th June. (tree was rebased to fixup for pull on friday) and now these are in Linus's tree. Can we have a fix for breakage for now sent to linus for now and then address the proper way to do this? That is my preferred approach. I will repost the patch at the link https://patchwork.kernel.org/patch/2640061/ above, rebased for the header file rename. Vinod, can you take things from there? -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] dmaengine: shdma: fix a build failure on platforms with no DMA support
From: Guennadi Liakhovetski g.liakhovet...@gmx.de On platforms with no support for the shdma dmaengine driver build is currently failing with drivers/built-in.o: In function `sh_mobile_sdhi_probe': drivers/mmc/host/sh_mobile_sdhi.c:170: undefined reference to`shdma_chan_filter' Fix the breakage by defining shdma_chan_filter to NULL in such configurations. Signed-off-by: Guennadi Liakhovetski g.liakhovetski+rene...@gmail.com [horms+rene...@verge.net.au: Apply change to shdma-base.h instead of sh_dma.h] Signed-off-by: Simon Horman horms+rene...@verge.net.au --- include/linux/shdma-base.h | 4 1 file changed, 4 insertions(+) Hi Vinod, please consider this fix from Guennadi for v3.11 which I have rebased on top of next-20130709. It fixes a build problem on a number of shmobile defconfigs including bockw. diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h index 382cf71..5b1c984 100644 --- a/include/linux/shdma-base.h +++ b/include/linux/shdma-base.h @@ -124,6 +124,10 @@ void shdma_chan_remove(struct shdma_chan *schan); int shdma_init(struct device *dev, struct shdma_dev *sdev, int chan_num); void shdma_cleanup(struct shdma_dev *sdev); +#if IS_ENABLED(CONFIG_SH_DMAE_BASE) bool shdma_chan_filter(struct dma_chan *chan, void *arg); +#else +#define shdma_chan_filter NULL +#endif #endif -- 1.8.2.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: 答复: [PATCH] Powerpc/t4240: change the compatible flags for t4240qds board
Thanks. Regards Haijun. -Original Message- From: Wood Scott-B07421 Sent: Wednesday, July 10, 2013 4:04 AM To: Zhang Haijun-B42677 Cc: Wood Scott-B07421; linux-mmc@vger.kernel.org; linuxppc- d...@lists.ozlabs.org; cbouatmai...@gmail.com; c...@laptop.org; Fleming Andy-AFLEMING; Wrobel Heinz-R39252 Subject: Re: 答复: [PATCH] Powerpc/t4240: change the compatible flags for t4240qds board On 07/09/2013 01:04:01 AM, Zhang Haijun-B42677 wrote: Regards Thanks Haijun. 发件人: Wood Scott-B07421 发送时间: 2013年7月8日 17:14 收件人: Zhang Haijun-B42677 抄送: linux-mmc@vger.kernel.org; linuxppc-...@lists.ozlabs.org; cbouatmai...@gmail.com; c...@laptop.org; Fleming Andy-AFLEMING; Wrobel Heinz-R39252; Zhang Haijun-B42677 主题: Re: [PATCH] Powerpc/t4240: change the compatible flags for t4240qds board On 07/08/2013 02:16:03 AM, Haijun Zhang wrote: In order to make a difference between different T4240 board. Specify T4240QDS board the unique compatible flags for t4240qds eSDHC host. Signed-off-by: Haijun Zhang haijun.zh...@freescale.com --- arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi index bd611a9..08b47d0 100644 --- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi @@ -397,7 +397,7 @@ /include/ qoriq-esdhc-0.dtsi sdhc@114000 { - compatible = fsl,t4240-esdhc, fsl,esdhc; + compatible = fsl,t4240qds-esdhc, fsl,esdhc; sdhci,auto-cmd12; }; NACK. This node is describing the sdhc block of the t4240 SoC. What board you stick it in doesn't change what it is. Plus, what about users with old device trees? Currently no users use this ip block except esdhc driver. I'm not talking about code users. I'm talking about people users. How about change this in arch/powerpc/boot/dts/t4240qds.dts +++ b/arch/powerpc/boot/dts/t4240qds.dts @@ -117,6 +117,10 @@ }; }; sdhc@114000 { compatible = fsl,t4240-esdhc, fsl,esdhc; }; i2c@118000 { +++ b/arch/powerpc/boot/dts/t4240qds.dts @@ -117,6 +117,10 @@ }; }; + sdhc@114000 { + compatible = fsl,t4240qds-esdhc, fsl,esdhc; + }; + i2c@118000 { No. It's still supposed to be describing the sdhc block itself, not the board -- and any workarounds that key off of this will still fail to work with existing device trees. [Haijun Wrote:] So, leave dts unchanged and to check compitable for board in sdhci-pltfm.c e.g.: unsigned long root = of_get_flat_dt_root(); if (of_flat_dt_is_compatible(root, fsl,T4240QDS)) host-quirks |= XXX; Is this ok? -Scott