* [PATCH 0/1] mmc: sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO hangs
@ 2016-04-15 11:06 Adrian Hunter
2016-04-15 11:06 ` [PATCH 1/1] " Adrian Hunter
0 siblings, 1 reply; 3+ messages in thread
From: Adrian Hunter @ 2016-04-15 11:06 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc
Hi
Here is a patch to reduce BayTrail eMMC hangs.
I had previously sent patches relating to C-states:
http://marc.info/?l=linux-mmc&m=142720456725463&w=2
but I have found so far that this patch gives better results.
I would encourage anyone using the C-State patches to try this one
instead.
Adrian Hunter (1):
mmc: sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO hangs
drivers/mmc/host/Kconfig | 1 +
drivers/mmc/host/sdhci-acpi.c | 81 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 82 insertions(+)
Regards
Adrian
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/1] mmc: sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO hangs
2016-04-15 11:06 [PATCH 0/1] mmc: sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO hangs Adrian Hunter
@ 2016-04-15 11:06 ` Adrian Hunter
2016-04-18 11:21 ` Ulf Hansson
0 siblings, 1 reply; 3+ messages in thread
From: Adrian Hunter @ 2016-04-15 11:06 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc
Baytrail eMMC/SD/SDIO host controllers have been known to
hang. A change to a hardware setting has been found to
reduce the occurrence of such hangs. This patch ensures
the correct setting.
This patch applies cleanly to v4.4+. It could go to
earlier kernels also, so I will send backports to the
stable list in due course.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org # v4.4+
---
drivers/mmc/host/Kconfig | 1 +
drivers/mmc/host/sdhci-acpi.c | 81 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 82 insertions(+)
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 04feea8354cb..e657af0e95fa 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -97,6 +97,7 @@ config MMC_RICOH_MMC
config MMC_SDHCI_ACPI
tristate "SDHCI support for ACPI enumerated SDHCI controllers"
depends on MMC_SDHCI && ACPI
+ select IOSF_MBI if X86
help
This selects support for ACPI enumerated SDHCI controllers,
identified by ACPI Compatibility ID PNP0D40 or specific
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 6106354c6c17..b2d70ba6caa7 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -41,6 +41,11 @@
#include <linux/mmc/pm.h>
#include <linux/mmc/slot-gpio.h>
+#ifdef CONFIG_X86
+#include <asm/cpu_device_id.h>
+#include <asm/iosf_mbi.h>
+#endif
+
#include "sdhci.h"
enum {
@@ -116,6 +121,75 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = {
.ops = &sdhci_acpi_ops_int,
};
+#ifdef CONFIG_X86
+
+static bool sdhci_acpi_byt(void)
+{
+ static const struct x86_cpu_id byt[] = {
+ { X86_VENDOR_INTEL, 6, 0x37 },
+ {}
+ };
+
+ return x86_match_cpu(byt);
+}
+
+#define BYT_IOSF_SCCEP 0x63
+#define BYT_IOSF_OCP_NETCTRL0 0x1078
+#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8)
+
+static void sdhci_acpi_byt_setting(struct device *dev)
+{
+ u32 val = 0;
+
+ if (!sdhci_acpi_byt())
+ return;
+
+ if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0,
+ &val)) {
+ dev_err(dev, "%s read error\n", __func__);
+ return;
+ }
+
+ if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE))
+ return;
+
+ val &= ~BYT_IOSF_OCP_TIMEOUT_BASE;
+
+ if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0,
+ val)) {
+ dev_err(dev, "%s write error\n", __func__);
+ return;
+ }
+
+ dev_dbg(dev, "%s completed\n", __func__);
+}
+
+static bool sdhci_acpi_byt_defer(struct device *dev)
+{
+ if (!sdhci_acpi_byt())
+ return false;
+
+ if (!iosf_mbi_available())
+ return true;
+
+ sdhci_acpi_byt_setting(dev);
+
+ return false;
+}
+
+#else
+
+static inline void sdhci_acpi_byt_setting(struct device *dev)
+{
+}
+
+static inline bool sdhci_acpi_byt_defer(struct device *dev)
+{
+ return false;
+}
+
+#endif
+
static int bxt_get_cd(struct mmc_host *mmc)
{
int gpio_cd = mmc_gpio_get_cd(mmc);
@@ -319,6 +393,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
if (acpi_bus_get_status(device) || !device->status.present)
return -ENODEV;
+ if (sdhci_acpi_byt_defer(dev))
+ return -EPROBE_DEFER;
+
hid = acpi_device_hid(device);
uid = device->pnp.unique_id;
@@ -444,6 +521,8 @@ static int sdhci_acpi_resume(struct device *dev)
{
struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+ sdhci_acpi_byt_setting(&c->pdev->dev);
+
return sdhci_resume_host(c->host);
}
@@ -467,6 +546,8 @@ static int sdhci_acpi_runtime_resume(struct device *dev)
{
struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+ sdhci_acpi_byt_setting(&c->pdev->dev);
+
return sdhci_runtime_resume_host(c->host);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 1/1] mmc: sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO hangs
2016-04-15 11:06 ` [PATCH 1/1] " Adrian Hunter
@ 2016-04-18 11:21 ` Ulf Hansson
0 siblings, 0 replies; 3+ messages in thread
From: Ulf Hansson @ 2016-04-18 11:21 UTC (permalink / raw)
To: Adrian Hunter; +Cc: linux-mmc
On 15 April 2016 at 13:06, Adrian Hunter <adrian.hunter@intel.com> wrote:
> Baytrail eMMC/SD/SDIO host controllers have been known to
> hang. A change to a hardware setting has been found to
> reduce the occurrence of such hangs. This patch ensures
> the correct setting.
>
> This patch applies cleanly to v4.4+. It could go to
> earlier kernels also, so I will send backports to the
> stable list in due course.
>
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> Cc: stable@vger.kernel.org # v4.4+
Thanks, applied for fixes!
Kind regards
Uffe
> ---
> drivers/mmc/host/Kconfig | 1 +
> drivers/mmc/host/sdhci-acpi.c | 81 +++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 82 insertions(+)
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 04feea8354cb..e657af0e95fa 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -97,6 +97,7 @@ config MMC_RICOH_MMC
> config MMC_SDHCI_ACPI
> tristate "SDHCI support for ACPI enumerated SDHCI controllers"
> depends on MMC_SDHCI && ACPI
> + select IOSF_MBI if X86
> help
> This selects support for ACPI enumerated SDHCI controllers,
> identified by ACPI Compatibility ID PNP0D40 or specific
> diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
> index 6106354c6c17..b2d70ba6caa7 100644
> --- a/drivers/mmc/host/sdhci-acpi.c
> +++ b/drivers/mmc/host/sdhci-acpi.c
> @@ -41,6 +41,11 @@
> #include <linux/mmc/pm.h>
> #include <linux/mmc/slot-gpio.h>
>
> +#ifdef CONFIG_X86
> +#include <asm/cpu_device_id.h>
> +#include <asm/iosf_mbi.h>
> +#endif
> +
> #include "sdhci.h"
>
> enum {
> @@ -116,6 +121,75 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = {
> .ops = &sdhci_acpi_ops_int,
> };
>
> +#ifdef CONFIG_X86
> +
> +static bool sdhci_acpi_byt(void)
> +{
> + static const struct x86_cpu_id byt[] = {
> + { X86_VENDOR_INTEL, 6, 0x37 },
> + {}
> + };
> +
> + return x86_match_cpu(byt);
> +}
> +
> +#define BYT_IOSF_SCCEP 0x63
> +#define BYT_IOSF_OCP_NETCTRL0 0x1078
> +#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8)
> +
> +static void sdhci_acpi_byt_setting(struct device *dev)
> +{
> + u32 val = 0;
> +
> + if (!sdhci_acpi_byt())
> + return;
> +
> + if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0,
> + &val)) {
> + dev_err(dev, "%s read error\n", __func__);
> + return;
> + }
> +
> + if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE))
> + return;
> +
> + val &= ~BYT_IOSF_OCP_TIMEOUT_BASE;
> +
> + if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0,
> + val)) {
> + dev_err(dev, "%s write error\n", __func__);
> + return;
> + }
> +
> + dev_dbg(dev, "%s completed\n", __func__);
> +}
> +
> +static bool sdhci_acpi_byt_defer(struct device *dev)
> +{
> + if (!sdhci_acpi_byt())
> + return false;
> +
> + if (!iosf_mbi_available())
> + return true;
> +
> + sdhci_acpi_byt_setting(dev);
> +
> + return false;
> +}
> +
> +#else
> +
> +static inline void sdhci_acpi_byt_setting(struct device *dev)
> +{
> +}
> +
> +static inline bool sdhci_acpi_byt_defer(struct device *dev)
> +{
> + return false;
> +}
> +
> +#endif
> +
> static int bxt_get_cd(struct mmc_host *mmc)
> {
> int gpio_cd = mmc_gpio_get_cd(mmc);
> @@ -319,6 +393,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
> if (acpi_bus_get_status(device) || !device->status.present)
> return -ENODEV;
>
> + if (sdhci_acpi_byt_defer(dev))
> + return -EPROBE_DEFER;
> +
> hid = acpi_device_hid(device);
> uid = device->pnp.unique_id;
>
> @@ -444,6 +521,8 @@ static int sdhci_acpi_resume(struct device *dev)
> {
> struct sdhci_acpi_host *c = dev_get_drvdata(dev);
>
> + sdhci_acpi_byt_setting(&c->pdev->dev);
> +
> return sdhci_resume_host(c->host);
> }
>
> @@ -467,6 +546,8 @@ static int sdhci_acpi_runtime_resume(struct device *dev)
> {
> struct sdhci_acpi_host *c = dev_get_drvdata(dev);
>
> + sdhci_acpi_byt_setting(&c->pdev->dev);
> +
> return sdhci_runtime_resume_host(c->host);
> }
>
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-04-18 11:21 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-15 11:06 [PATCH 0/1] mmc: sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO hangs Adrian Hunter
2016-04-15 11:06 ` [PATCH 1/1] " Adrian Hunter
2016-04-18 11:21 ` Ulf Hansson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).