From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932245AbcHKCXu (ORCPT ); Wed, 10 Aug 2016 22:23:50 -0400 Received: from lucky1.263xmail.com ([211.157.147.133]:48460 "EHLO lucky1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751550AbcHKCXs (ORCPT ); Wed, 10 Aug 2016 22:23:48 -0400 X-263anti-spam: KSV:0; X-MAIL-GRAY: 1 X-MAIL-DELIVERY: 0 X-KSVirus-check: 0 X-ABS-CHECKED: 4 X-ADDR-CHECKED: 0 X-RL-SENDER: shawn.lin@rock-chips.com X-FST-TO: zhangfei.gao@linaro.org X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: shawn.lin@rock-chips.com X-UNIQUE-TAG: <0b0a7c9a4b872a61e32bc7ebd942ca53> X-ATTACHMENT-NUM: 0 X-DNS-TYPE: 0 Subject: Re: [PATCH v4 2/2] mmc: dw_mmc: add reset support to dwmmc host controller To: Guodong Xu , heiko@sntech.de, shawn.lin@rock-chips.com, jh80.chung@samsung.com, robh+dt@kernel.org, mark.rutland@arm.com, ulf.hansson@linaro.org References: <1470816228-8874-1-git-send-email-guodong.xu@linaro.org> <1470816228-8874-3-git-send-email-guodong.xu@linaro.org> Cc: shawn.lin@rock-chips.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mmc@vger.kernel.org, Xinwei Kong , Zhangfei Gao From: Shawn Lin Message-ID: Date: Thu, 11 Aug 2016 10:23:37 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: <1470816228-8874-3-git-send-email-guodong.xu@linaro.org> Content-Type: text/plain; charset=gbk; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2016/8/10 16:03, Guodong Xu wrote: > Dwmmc host controller may in unknown state when entering kernel boot. One > example is when booting from eMMC, bootloader need initialize MMC host > controller into some state so it can read. In order to make sure MMC host > controller in a clean initial state, this reset support is added. > > With this patch, a 'resets' property can be added into dw_mmc device > tree node. The hardware logic is: dwmmc host controller IP receives a reset > signal from a 'reset provider' (eg. power management unit). The 'resets' > property points to this reset signal. So, during dwmmc driver probe, > it can use this signal to reset itself. > > Refer to [1] for more information. > > [1] Documentation/devicetree/bindings/reset/reset.txt > > Signed-off-by: Guodong Xu > Signed-off-by: Xinwei Kong > Signed-off-by: Zhangfei Gao Looks good to me, Reviewed-by: Shawn Lin > --- > drivers/mmc/host/dw_mmc.c | 23 ++++++++++++++++++++++- > include/linux/mmc/dw_mmc.h | 2 ++ > 2 files changed, 24 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 32380d5..481d441 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -2915,6 +2915,13 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) > if (!pdata) > return ERR_PTR(-ENOMEM); > > + /* find reset controller when exist */ > + pdata->rstc = devm_reset_control_get_optional(dev, NULL); > + if (IS_ERR(pdata->rstc)) { > + if (PTR_ERR(pdata->rstc) == -EPROBE_DEFER) > + return ERR_PTR(-EPROBE_DEFER); > + } > + > /* find out number of slots supported */ > of_property_read_u32(np, "num-slots", &pdata->num_slots); > > @@ -2986,7 +2993,9 @@ int dw_mci_probe(struct dw_mci *host) > > if (!host->pdata) { > host->pdata = dw_mci_parse_dt(host); > - if (IS_ERR(host->pdata)) { > + if (PTR_ERR(host->pdata) == -EPROBE_DEFER) { > + return -EPROBE_DEFER; > + } else if (IS_ERR(host->pdata)) { > dev_err(host->dev, "platform data not available\n"); > return -EINVAL; > } > @@ -3040,6 +3049,12 @@ int dw_mci_probe(struct dw_mci *host) > } > } > > + if (!IS_ERR(host->pdata->rstc)) { > + reset_control_assert(host->pdata->rstc); > + usleep_range(10, 50); > + reset_control_deassert(host->pdata->rstc); > + } > + > setup_timer(&host->cmd11_timer, > dw_mci_cmd11_timer, (unsigned long)host); > > @@ -3189,6 +3204,9 @@ err_dmaunmap: > if (host->use_dma && host->dma_ops->exit) > host->dma_ops->exit(host); > > + if (!IS_ERR(host->pdata->rstc)) > + reset_control_assert(host->pdata->rstc); > + > err_clk_ciu: > if (!IS_ERR(host->ciu_clk)) > clk_disable_unprepare(host->ciu_clk); > @@ -3221,6 +3239,9 @@ void dw_mci_remove(struct dw_mci *host) > if (host->use_dma && host->dma_ops->exit) > host->dma_ops->exit(host); > > + if (!IS_ERR(host->pdata->rstc)) > + reset_control_assert(host->pdata->rstc); > + > if (!IS_ERR(host->ciu_clk)) > clk_disable_unprepare(host->ciu_clk); > > diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h > index 83b0edfc..f5af2bd 100644 > --- a/include/linux/mmc/dw_mmc.h > +++ b/include/linux/mmc/dw_mmc.h > @@ -17,6 +17,7 @@ > #include > #include > #include > +#include > > #define MAX_MCI_SLOTS 2 > > @@ -259,6 +260,7 @@ struct dw_mci_board { > /* delay in mS before detecting cards after interrupt */ > u32 detect_delay_ms; > > + struct reset_control *rstc; > struct dw_mci_dma_ops *dma_ops; > struct dma_pdata *data; > }; > -- Best Regards Shawn Lin From mboxrd@z Thu Jan 1 00:00:00 1970 From: Shawn Lin Subject: Re: [PATCH v4 2/2] mmc: dw_mmc: add reset support to dwmmc host controller Date: Thu, 11 Aug 2016 10:23:37 +0800 Message-ID: References: <1470816228-8874-1-git-send-email-guodong.xu@linaro.org> <1470816228-8874-3-git-send-email-guodong.xu@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset=gbk; format=flowed Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1470816228-8874-3-git-send-email-guodong.xu@linaro.org> Sender: linux-mmc-owner@vger.kernel.org To: Guodong Xu , heiko@sntech.de, jh80.chung@samsung.com, robh+dt@kernel.org, mark.rutland@arm.com, ulf.hansson@linaro.org Cc: shawn.lin@rock-chips.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mmc@vger.kernel.org, Xinwei Kong , Zhangfei Gao List-Id: devicetree@vger.kernel.org On 2016/8/10 16:03, Guodong Xu wrote: > Dwmmc host controller may in unknown state when entering kernel boot. One > example is when booting from eMMC, bootloader need initialize MMC host > controller into some state so it can read. In order to make sure MMC host > controller in a clean initial state, this reset support is added. > > With this patch, a 'resets' property can be added into dw_mmc device > tree node. The hardware logic is: dwmmc host controller IP receives a reset > signal from a 'reset provider' (eg. power management unit). The 'resets' > property points to this reset signal. So, during dwmmc driver probe, > it can use this signal to reset itself. > > Refer to [1] for more information. > > [1] Documentation/devicetree/bindings/reset/reset.txt > > Signed-off-by: Guodong Xu > Signed-off-by: Xinwei Kong > Signed-off-by: Zhangfei Gao Looks good to me, Reviewed-by: Shawn Lin > --- > drivers/mmc/host/dw_mmc.c | 23 ++++++++++++++++++++++- > include/linux/mmc/dw_mmc.h | 2 ++ > 2 files changed, 24 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 32380d5..481d441 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -2915,6 +2915,13 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) > if (!pdata) > return ERR_PTR(-ENOMEM); > > + /* find reset controller when exist */ > + pdata->rstc = devm_reset_control_get_optional(dev, NULL); > + if (IS_ERR(pdata->rstc)) { > + if (PTR_ERR(pdata->rstc) == -EPROBE_DEFER) > + return ERR_PTR(-EPROBE_DEFER); > + } > + > /* find out number of slots supported */ > of_property_read_u32(np, "num-slots", &pdata->num_slots); > > @@ -2986,7 +2993,9 @@ int dw_mci_probe(struct dw_mci *host) > > if (!host->pdata) { > host->pdata = dw_mci_parse_dt(host); > - if (IS_ERR(host->pdata)) { > + if (PTR_ERR(host->pdata) == -EPROBE_DEFER) { > + return -EPROBE_DEFER; > + } else if (IS_ERR(host->pdata)) { > dev_err(host->dev, "platform data not available\n"); > return -EINVAL; > } > @@ -3040,6 +3049,12 @@ int dw_mci_probe(struct dw_mci *host) > } > } > > + if (!IS_ERR(host->pdata->rstc)) { > + reset_control_assert(host->pdata->rstc); > + usleep_range(10, 50); > + reset_control_deassert(host->pdata->rstc); > + } > + > setup_timer(&host->cmd11_timer, > dw_mci_cmd11_timer, (unsigned long)host); > > @@ -3189,6 +3204,9 @@ err_dmaunmap: > if (host->use_dma && host->dma_ops->exit) > host->dma_ops->exit(host); > > + if (!IS_ERR(host->pdata->rstc)) > + reset_control_assert(host->pdata->rstc); > + > err_clk_ciu: > if (!IS_ERR(host->ciu_clk)) > clk_disable_unprepare(host->ciu_clk); > @@ -3221,6 +3239,9 @@ void dw_mci_remove(struct dw_mci *host) > if (host->use_dma && host->dma_ops->exit) > host->dma_ops->exit(host); > > + if (!IS_ERR(host->pdata->rstc)) > + reset_control_assert(host->pdata->rstc); > + > if (!IS_ERR(host->ciu_clk)) > clk_disable_unprepare(host->ciu_clk); > > diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h > index 83b0edfc..f5af2bd 100644 > --- a/include/linux/mmc/dw_mmc.h > +++ b/include/linux/mmc/dw_mmc.h > @@ -17,6 +17,7 @@ > #include > #include > #include > +#include > > #define MAX_MCI_SLOTS 2 > > @@ -259,6 +260,7 @@ struct dw_mci_board { > /* delay in mS before detecting cards after interrupt */ > u32 detect_delay_ms; > > + struct reset_control *rstc; > struct dw_mci_dma_ops *dma_ops; > struct dma_pdata *data; > }; > -- Best Regards Shawn Lin From mboxrd@z Thu Jan 1 00:00:00 1970 From: shawn.lin@rock-chips.com (Shawn Lin) Date: Thu, 11 Aug 2016 10:23:37 +0800 Subject: [PATCH v4 2/2] mmc: dw_mmc: add reset support to dwmmc host controller In-Reply-To: <1470816228-8874-3-git-send-email-guodong.xu@linaro.org> References: <1470816228-8874-1-git-send-email-guodong.xu@linaro.org> <1470816228-8874-3-git-send-email-guodong.xu@linaro.org> Message-ID: To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On 2016/8/10 16:03, Guodong Xu wrote: > Dwmmc host controller may in unknown state when entering kernel boot. One > example is when booting from eMMC, bootloader need initialize MMC host > controller into some state so it can read. In order to make sure MMC host > controller in a clean initial state, this reset support is added. > > With this patch, a 'resets' property can be added into dw_mmc device > tree node. The hardware logic is: dwmmc host controller IP receives a reset > signal from a 'reset provider' (eg. power management unit). The 'resets' > property points to this reset signal. So, during dwmmc driver probe, > it can use this signal to reset itself. > > Refer to [1] for more information. > > [1] Documentation/devicetree/bindings/reset/reset.txt > > Signed-off-by: Guodong Xu > Signed-off-by: Xinwei Kong > Signed-off-by: Zhangfei Gao Looks good to me, Reviewed-by: Shawn Lin > --- > drivers/mmc/host/dw_mmc.c | 23 ++++++++++++++++++++++- > include/linux/mmc/dw_mmc.h | 2 ++ > 2 files changed, 24 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 32380d5..481d441 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -2915,6 +2915,13 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) > if (!pdata) > return ERR_PTR(-ENOMEM); > > + /* find reset controller when exist */ > + pdata->rstc = devm_reset_control_get_optional(dev, NULL); > + if (IS_ERR(pdata->rstc)) { > + if (PTR_ERR(pdata->rstc) == -EPROBE_DEFER) > + return ERR_PTR(-EPROBE_DEFER); > + } > + > /* find out number of slots supported */ > of_property_read_u32(np, "num-slots", &pdata->num_slots); > > @@ -2986,7 +2993,9 @@ int dw_mci_probe(struct dw_mci *host) > > if (!host->pdata) { > host->pdata = dw_mci_parse_dt(host); > - if (IS_ERR(host->pdata)) { > + if (PTR_ERR(host->pdata) == -EPROBE_DEFER) { > + return -EPROBE_DEFER; > + } else if (IS_ERR(host->pdata)) { > dev_err(host->dev, "platform data not available\n"); > return -EINVAL; > } > @@ -3040,6 +3049,12 @@ int dw_mci_probe(struct dw_mci *host) > } > } > > + if (!IS_ERR(host->pdata->rstc)) { > + reset_control_assert(host->pdata->rstc); > + usleep_range(10, 50); > + reset_control_deassert(host->pdata->rstc); > + } > + > setup_timer(&host->cmd11_timer, > dw_mci_cmd11_timer, (unsigned long)host); > > @@ -3189,6 +3204,9 @@ err_dmaunmap: > if (host->use_dma && host->dma_ops->exit) > host->dma_ops->exit(host); > > + if (!IS_ERR(host->pdata->rstc)) > + reset_control_assert(host->pdata->rstc); > + > err_clk_ciu: > if (!IS_ERR(host->ciu_clk)) > clk_disable_unprepare(host->ciu_clk); > @@ -3221,6 +3239,9 @@ void dw_mci_remove(struct dw_mci *host) > if (host->use_dma && host->dma_ops->exit) > host->dma_ops->exit(host); > > + if (!IS_ERR(host->pdata->rstc)) > + reset_control_assert(host->pdata->rstc); > + > if (!IS_ERR(host->ciu_clk)) > clk_disable_unprepare(host->ciu_clk); > > diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h > index 83b0edfc..f5af2bd 100644 > --- a/include/linux/mmc/dw_mmc.h > +++ b/include/linux/mmc/dw_mmc.h > @@ -17,6 +17,7 @@ > #include > #include > #include > +#include > > #define MAX_MCI_SLOTS 2 > > @@ -259,6 +260,7 @@ struct dw_mci_board { > /* delay in mS before detecting cards after interrupt */ > u32 detect_delay_ms; > > + struct reset_control *rstc; > struct dw_mci_dma_ops *dma_ops; > struct dma_pdata *data; > }; > -- Best Regards Shawn Lin