]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.5
authorSasha Levin <sashal@kernel.org>
Wed, 18 Mar 2020 19:27:17 +0000 (15:27 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 18 Mar 2020 19:27:17 +0000 (15:27 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.5/gpiolib-add-support-for-the-irqdomain-which-doesn-t-.patch [new file with mode: 0644]
queue-5.5/mmc-core-allow-host-controllers-to-require-r1b-for-c.patch [new file with mode: 0644]
queue-5.5/mmc-core-default-to-generic_cmd6_time-as-timeout-in-.patch [new file with mode: 0644]
queue-5.5/mmc-core-respect-mmc_cap_need_rsp_busy-for-emmc-slee.patch [new file with mode: 0644]
queue-5.5/mmc-core-respect-mmc_cap_need_rsp_busy-for-erase-tri.patch [new file with mode: 0644]
queue-5.5/mmc-sdhci-omap-fix-busy-detection-by-enabling-mmc_ca.patch [new file with mode: 0644]
queue-5.5/mmc-sdhci-tegra-fix-busy-detection-by-enabling-mmc_c.patch [new file with mode: 0644]
queue-5.5/pinctrl-qcom-ssbi-gpio-fix-fwspec-parsing-bug.patch [new file with mode: 0644]
queue-5.5/series [new file with mode: 0644]

diff --git a/queue-5.5/gpiolib-add-support-for-the-irqdomain-which-doesn-t-.patch b/queue-5.5/gpiolib-add-support-for-the-irqdomain-which-doesn-t-.patch
new file mode 100644 (file)
index 0000000..a0eaf53
--- /dev/null
@@ -0,0 +1,256 @@
+From 55f9c35937b7f1ab1747a346c5ae83e4c751ac5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jan 2020 16:28:19 +0800
+Subject: gpiolib: Add support for the irqdomain which doesn't use irq_fwspec
+ as arg
+
+From: Kevin Hao <haokexin@gmail.com>
+
+[ Upstream commit 242587616710576808dc8d7cdf18cfe0d7bf9831 ]
+
+Some gpio's parent irqdomain may not use the struct irq_fwspec as
+argument, such as msi irqdomain. So rename the callback
+populate_parent_fwspec() to populate_parent_alloc_arg() and make it
+allocate and populate the specific struct which is needed by the
+parent irqdomain.
+
+Signed-off-by: Kevin Hao <haokexin@gmail.com>
+Link: https://lore.kernel.org/r/20200114082821.14015-3-haokexin@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-tegra186.c             | 13 +++++--
+ drivers/gpio/gpiolib.c                   | 45 +++++++++++++++---------
+ drivers/pinctrl/qcom/pinctrl-spmi-gpio.c |  2 +-
+ drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c |  2 +-
+ include/linux/gpio/driver.h              | 21 +++++------
+ 5 files changed, 49 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
+index 55b43b7ce88db..de241263d4be3 100644
+--- a/drivers/gpio/gpio-tegra186.c
++++ b/drivers/gpio/gpio-tegra186.c
+@@ -448,17 +448,24 @@ static int tegra186_gpio_irq_domain_translate(struct irq_domain *domain,
+       return 0;
+ }
+-static void tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip,
+-                                               struct irq_fwspec *fwspec,
++static void *tegra186_gpio_populate_parent_fwspec(struct gpio_chip *chip,
+                                                unsigned int parent_hwirq,
+                                                unsigned int parent_type)
+ {
+       struct tegra_gpio *gpio = gpiochip_get_data(chip);
++      struct irq_fwspec *fwspec;
++      fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
++      if (!fwspec)
++              return NULL;
++
++      fwspec->fwnode = chip->irq.parent_domain->fwnode;
+       fwspec->param_count = 3;
+       fwspec->param[0] = gpio->soc->instance;
+       fwspec->param[1] = parent_hwirq;
+       fwspec->param[2] = parent_type;
++
++      return fwspec;
+ }
+ static int tegra186_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
+@@ -621,7 +628,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
+       irq->chip = &gpio->intc;
+       irq->fwnode = of_node_to_fwnode(pdev->dev.of_node);
+       irq->child_to_parent_hwirq = tegra186_gpio_child_to_parent_hwirq;
+-      irq->populate_parent_fwspec = tegra186_gpio_populate_parent_fwspec;
++      irq->populate_parent_alloc_arg = tegra186_gpio_populate_parent_fwspec;
+       irq->child_offset_to_irq = tegra186_gpio_child_offset_to_irq;
+       irq->child_irq_domain_ops.translate = tegra186_gpio_irq_domain_translate;
+       irq->handler = handle_simple_irq;
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index 175c6363cf611..cdbaa8bf72f74 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -2003,7 +2003,7 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
+       irq_hw_number_t hwirq;
+       unsigned int type = IRQ_TYPE_NONE;
+       struct irq_fwspec *fwspec = data;
+-      struct irq_fwspec parent_fwspec;
++      void *parent_arg;
+       unsigned int parent_hwirq;
+       unsigned int parent_type;
+       struct gpio_irq_chip *girq = &gc->irq;
+@@ -2042,24 +2042,21 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
+                           NULL, NULL);
+       irq_set_probe(irq);
+-      /*
+-       * Create a IRQ fwspec to send up to the parent irqdomain:
+-       * specify the hwirq we address on the parent and tie it
+-       * all together up the chain.
+-       */
+-      parent_fwspec.fwnode = d->parent->fwnode;
+       /* This parent only handles asserted level IRQs */
+-      girq->populate_parent_fwspec(gc, &parent_fwspec, parent_hwirq,
+-                                   parent_type);
++      parent_arg = girq->populate_parent_alloc_arg(gc, parent_hwirq, parent_type);
++      if (!parent_arg)
++              return -ENOMEM;
++
+       chip_info(gc, "alloc_irqs_parent for %d parent hwirq %d\n",
+                 irq, parent_hwirq);
+       irq_set_lockdep_class(irq, gc->irq.lock_key, gc->irq.request_key);
+-      ret = irq_domain_alloc_irqs_parent(d, irq, 1, &parent_fwspec);
++      ret = irq_domain_alloc_irqs_parent(d, irq, 1, parent_arg);
+       if (ret)
+               chip_err(gc,
+                        "failed to allocate parent hwirq %d for hwirq %lu\n",
+                        parent_hwirq, hwirq);
++      kfree(parent_arg);
+       return ret;
+ }
+@@ -2096,8 +2093,8 @@ static int gpiochip_hierarchy_add_domain(struct gpio_chip *gc)
+       if (!gc->irq.child_offset_to_irq)
+               gc->irq.child_offset_to_irq = gpiochip_child_offset_to_irq_noop;
+-      if (!gc->irq.populate_parent_fwspec)
+-              gc->irq.populate_parent_fwspec =
++      if (!gc->irq.populate_parent_alloc_arg)
++              gc->irq.populate_parent_alloc_arg =
+                       gpiochip_populate_parent_fwspec_twocell;
+       gpiochip_hierarchy_setup_domain_ops(&gc->irq.child_irq_domain_ops);
+@@ -2123,27 +2120,43 @@ static bool gpiochip_hierarchy_is_hierarchical(struct gpio_chip *gc)
+       return !!gc->irq.parent_domain;
+ }
+-void gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
+-                                           struct irq_fwspec *fwspec,
++void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
+                                            unsigned int parent_hwirq,
+                                            unsigned int parent_type)
+ {
++      struct irq_fwspec *fwspec;
++
++      fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
++      if (!fwspec)
++              return NULL;
++
++      fwspec->fwnode = chip->irq.parent_domain->fwnode;
+       fwspec->param_count = 2;
+       fwspec->param[0] = parent_hwirq;
+       fwspec->param[1] = parent_type;
++
++      return fwspec;
+ }
+ EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_twocell);
+-void gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
+-                                            struct irq_fwspec *fwspec,
++void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
+                                             unsigned int parent_hwirq,
+                                             unsigned int parent_type)
+ {
++      struct irq_fwspec *fwspec;
++
++      fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
++      if (!fwspec)
++              return NULL;
++
++      fwspec->fwnode = chip->irq.parent_domain->fwnode;
+       fwspec->param_count = 4;
+       fwspec->param[0] = 0;
+       fwspec->param[1] = parent_hwirq;
+       fwspec->param[2] = 0;
+       fwspec->param[3] = parent_type;
++
++      return fwspec;
+ }
+ EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_fourcell);
+diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+index 653d1095bfeaf..fe0be8a6ebb7b 100644
+--- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
++++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+@@ -1060,7 +1060,7 @@ static int pmic_gpio_probe(struct platform_device *pdev)
+       girq->fwnode = of_node_to_fwnode(state->dev->of_node);
+       girq->parent_domain = parent_domain;
+       girq->child_to_parent_hwirq = pmic_gpio_child_to_parent_hwirq;
+-      girq->populate_parent_fwspec = gpiochip_populate_parent_fwspec_fourcell;
++      girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell;
+       girq->child_offset_to_irq = pmic_gpio_child_offset_to_irq;
+       girq->child_irq_domain_ops.translate = pmic_gpio_domain_translate;
+diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
+index dca86886b1f99..73d986a903f1b 100644
+--- a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
++++ b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
+@@ -794,7 +794,7 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
+       girq->fwnode = of_node_to_fwnode(pctrl->dev->of_node);
+       girq->parent_domain = parent_domain;
+       girq->child_to_parent_hwirq = pm8xxx_child_to_parent_hwirq;
+-      girq->populate_parent_fwspec = gpiochip_populate_parent_fwspec_fourcell;
++      girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell;
+       girq->child_offset_to_irq = pm8xxx_child_offset_to_irq;
+       girq->child_irq_domain_ops.translate = pm8xxx_domain_translate;
+diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
+index e2480ef94c559..9bb43467ed11d 100644
+--- a/include/linux/gpio/driver.h
++++ b/include/linux/gpio/driver.h
+@@ -94,16 +94,15 @@ struct gpio_irq_chip {
+                                    unsigned int *parent_type);
+       /**
+-       * @populate_parent_fwspec:
++       * @populate_parent_alloc_arg :
+        *
+-       * This optional callback populates the &struct irq_fwspec for the
+-       * parent's IRQ domain. If this is not specified, then
++       * This optional callback allocates and populates the specific struct
++       * for the parent's IRQ domain. If this is not specified, then
+        * &gpiochip_populate_parent_fwspec_twocell will be used. A four-cell
+        * variant named &gpiochip_populate_parent_fwspec_fourcell is also
+        * available.
+        */
+-      void (*populate_parent_fwspec)(struct gpio_chip *chip,
+-                                     struct irq_fwspec *fwspec,
++      void *(*populate_parent_alloc_arg)(struct gpio_chip *chip,
+                                      unsigned int parent_hwirq,
+                                      unsigned int parent_type);
+@@ -537,26 +536,22 @@ struct bgpio_pdata {
+ #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+-void gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
+-                                           struct irq_fwspec *fwspec,
++void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
+                                            unsigned int parent_hwirq,
+                                            unsigned int parent_type);
+-void gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
+-                                            struct irq_fwspec *fwspec,
++void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
+                                             unsigned int parent_hwirq,
+                                             unsigned int parent_type);
+ #else
+-static inline void gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
+-                                                  struct irq_fwspec *fwspec,
++static inline void *gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
+                                                   unsigned int parent_hwirq,
+                                                   unsigned int parent_type)
+ {
+ }
+-static inline void gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
+-                                                   struct irq_fwspec *fwspec,
++static inline void *gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
+                                                    unsigned int parent_hwirq,
+                                                    unsigned int parent_type)
+ {
+-- 
+2.20.1
+
diff --git a/queue-5.5/mmc-core-allow-host-controllers-to-require-r1b-for-c.patch b/queue-5.5/mmc-core-allow-host-controllers-to-require-r1b-for-c.patch
new file mode 100644 (file)
index 0000000..2f2d493
--- /dev/null
@@ -0,0 +1,63 @@
+From 4bb9794258026c7600bff6bed55b100261a402d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2020 12:49:43 +0100
+Subject: mmc: core: Allow host controllers to require R1B for CMD6
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit 1292e3efb149ee21d8d33d725eeed4e6b1ade963 ]
+
+It has turned out that some host controllers can't use R1B for CMD6 and
+other commands that have R1B associated with them. Therefore invent a new
+host cap, MMC_CAP_NEED_RSP_BUSY to let them specify this.
+
+In __mmc_switch(), let's check the flag and use it to prevent R1B responses
+from being converted into R1. Note that, this also means that the host are
+on its own, when it comes to manage the busy timeout.
+
+Suggested-by: Sowjanya Komatineni <skomatineni@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Tested-by: Anders Roxell <anders.roxell@linaro.org>
+Tested-by: Sowjanya Komatineni <skomatineni@nvidia.com>
+Tested-by: Faiz Abbas <faiz_abbas@ti.com>
+Tested-By: Peter Geis <pgwipeout@gmail.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/mmc_ops.c | 6 ++++--
+ include/linux/mmc/host.h   | 1 +
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
+index cfb2ce979baf1..5a4eddef8067b 100644
+--- a/drivers/mmc/core/mmc_ops.c
++++ b/drivers/mmc/core/mmc_ops.c
+@@ -540,9 +540,11 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
+        * If the max_busy_timeout of the host is specified, make sure it's
+        * enough to fit the used timeout_ms. In case it's not, let's instruct
+        * the host to avoid HW busy detection, by converting to a R1 response
+-       * instead of a R1B.
++       * instead of a R1B. Note, some hosts requires R1B, which also means
++       * they are on their own when it comes to deal with the busy timeout.
+        */
+-      if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout))
++      if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout &&
++          (timeout_ms > host->max_busy_timeout))
+               use_r1b_resp = false;
+       cmd.opcode = MMC_SWITCH;
+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
+index ba703384bea0c..4c5eb3aa8e723 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -333,6 +333,7 @@ struct mmc_host {
+                                MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | \
+                                MMC_CAP_UHS_DDR50)
+ #define MMC_CAP_SYNC_RUNTIME_PM       (1 << 21)       /* Synced runtime PM suspends. */
++#define MMC_CAP_NEED_RSP_BUSY (1 << 22)       /* Commands with R1B can't use R1. */
+ #define MMC_CAP_DRIVER_TYPE_A (1 << 23)       /* Host supports Driver Type A */
+ #define MMC_CAP_DRIVER_TYPE_C (1 << 24)       /* Host supports Driver Type C */
+ #define MMC_CAP_DRIVER_TYPE_D (1 << 25)       /* Host supports Driver Type D */
+-- 
+2.20.1
+
diff --git a/queue-5.5/mmc-core-default-to-generic_cmd6_time-as-timeout-in-.patch b/queue-5.5/mmc-core-default-to-generic_cmd6_time-as-timeout-in-.patch
new file mode 100644 (file)
index 0000000..5545751
--- /dev/null
@@ -0,0 +1,79 @@
+From 69edb5611ac110e617406215c17945524c4b60e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2020 15:27:47 +0100
+Subject: mmc: core: Default to generic_cmd6_time as timeout in __mmc_switch()
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit 533a6cfe08f96a7b5c65e06d20916d552c11b256 ]
+
+All callers of __mmc_switch() should now be specifying a valid timeout for
+the CMD6 command. However, just to be sure, let's print a warning and
+default to use the generic_cmd6_time in case the provided timeout_ms
+argument is zero.
+
+In this context, let's also simplify some of the corresponding code and
+clarify some related comments.
+
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://lore.kernel.org/r/20200122142747.5690-4-ulf.hansson@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/mmc_ops.c | 25 +++++++++++--------------
+ 1 file changed, 11 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
+index 09113b9ad6790..cfb2ce979baf1 100644
+--- a/drivers/mmc/core/mmc_ops.c
++++ b/drivers/mmc/core/mmc_ops.c
+@@ -458,10 +458,6 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
+       bool expired = false;
+       bool busy = false;
+-      /* We have an unspecified cmd timeout, use the fallback value. */
+-      if (!timeout_ms)
+-              timeout_ms = MMC_OPS_TIMEOUT_MS;
+-
+       /*
+        * In cases when not allowed to poll by using CMD13 or because we aren't
+        * capable of polling by using ->card_busy(), then rely on waiting the
+@@ -534,14 +530,19 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
+       mmc_retune_hold(host);
++      if (!timeout_ms) {
++              pr_warn("%s: unspecified timeout for CMD6 - use generic\n",
++                      mmc_hostname(host));
++              timeout_ms = card->ext_csd.generic_cmd6_time;
++      }
++
+       /*
+-       * If the cmd timeout and the max_busy_timeout of the host are both
+-       * specified, let's validate them. A failure means we need to prevent
+-       * the host from doing hw busy detection, which is done by converting
+-       * to a R1 response instead of a R1B.
++       * If the max_busy_timeout of the host is specified, make sure it's
++       * enough to fit the used timeout_ms. In case it's not, let's instruct
++       * the host to avoid HW busy detection, by converting to a R1 response
++       * instead of a R1B.
+        */
+-      if (timeout_ms && host->max_busy_timeout &&
+-              (timeout_ms > host->max_busy_timeout))
++      if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout))
+               use_r1b_resp = false;
+       cmd.opcode = MMC_SWITCH;
+@@ -552,10 +553,6 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
+       cmd.flags = MMC_CMD_AC;
+       if (use_r1b_resp) {
+               cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B;
+-              /*
+-               * A busy_timeout of zero means the host can decide to use
+-               * whatever value it finds suitable.
+-               */
+               cmd.busy_timeout = timeout_ms;
+       } else {
+               cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1;
+-- 
+2.20.1
+
diff --git a/queue-5.5/mmc-core-respect-mmc_cap_need_rsp_busy-for-emmc-slee.patch b/queue-5.5/mmc-core-respect-mmc_cap_need_rsp_busy-for-emmc-slee.patch
new file mode 100644 (file)
index 0000000..05962a2
--- /dev/null
@@ -0,0 +1,50 @@
+From 586bb8ad748ec1c102d2359c4ba90f678a2b6c01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Mar 2020 10:20:36 +0100
+Subject: mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for eMMC sleep command
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit 18d200460cd73636d4f20674085c39e32b4e0097 ]
+
+The busy timeout for the CMD5 to put the eMMC into sleep state, is specific
+to the card. Potentially the timeout may exceed the host->max_busy_timeout.
+If that becomes the case, mmc_sleep() converts from using an R1B response
+to an R1 response, as to prevent the host from doing HW busy detection.
+
+However, it has turned out that some hosts requires an R1B response no
+matter what, so let's respect that via checking MMC_CAP_NEED_RSP_BUSY. Note
+that, if the R1B gets enforced, the host becomes fully responsible of
+managing the needed busy timeout, in one way or the other.
+
+Suggested-by: Sowjanya Komatineni <skomatineni@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200311092036.16084-1-ulf.hansson@linaro.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/mmc.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
+index f6912ded652dc..de14b5845f525 100644
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -1910,9 +1910,12 @@ static int mmc_sleep(struct mmc_host *host)
+        * If the max_busy_timeout of the host is specified, validate it against
+        * the sleep cmd timeout. A failure means we need to prevent the host
+        * from doing hw busy detection, which is done by converting to a R1
+-       * response instead of a R1B.
++       * response instead of a R1B. Note, some hosts requires R1B, which also
++       * means they are on their own when it comes to deal with the busy
++       * timeout.
+        */
+-      if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) {
++      if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout &&
++          (timeout_ms > host->max_busy_timeout)) {
+               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+       } else {
+               cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
+-- 
+2.20.1
+
diff --git a/queue-5.5/mmc-core-respect-mmc_cap_need_rsp_busy-for-erase-tri.patch b/queue-5.5/mmc-core-respect-mmc_cap_need_rsp_busy-for-erase-tri.patch
new file mode 100644 (file)
index 0000000..49cd012
--- /dev/null
@@ -0,0 +1,51 @@
+From 718168b10350f5a0ad7dd1ca8bb6f76aa30fcd25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2020 14:43:00 +0100
+Subject: mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for erase/trim/discard
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit 43cc64e5221cc6741252b64bc4531dd1eefb733d ]
+
+The busy timeout that is computed for each erase/trim/discard operation,
+can become quite long and may thus exceed the host->max_busy_timeout. If
+that becomes the case, mmc_do_erase() converts from using an R1B response
+to an R1 response, as to prevent the host from doing HW busy detection.
+
+However, it has turned out that some hosts requires an R1B response no
+matter what, so let's respect that via checking MMC_CAP_NEED_RSP_BUSY. Note
+that, if the R1B gets enforced, the host becomes fully responsible of
+managing the needed busy timeout, in one way or the other.
+
+Suggested-by: Sowjanya Komatineni <skomatineni@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Tested-by: Anders Roxell <anders.roxell@linaro.org>
+Tested-by: Sowjanya Komatineni <skomatineni@nvidia.com>
+Tested-by: Faiz Abbas <faiz_abbas@ti.com>
+Tested-By: Peter Geis <pgwipeout@gmail.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/core.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index abf8f5eb0a1c8..26644b7ec13e3 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -1732,8 +1732,11 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
+        * the erase operation does not exceed the max_busy_timeout, we should
+        * use R1B response. Or we need to prevent the host from doing hw busy
+        * detection, which is done by converting to a R1 response instead.
++       * Note, some hosts requires R1B, which also means they are on their own
++       * when it comes to deal with the busy timeout.
+        */
+-      if (card->host->max_busy_timeout &&
++      if (!(card->host->caps & MMC_CAP_NEED_RSP_BUSY) &&
++          card->host->max_busy_timeout &&
+           busy_timeout > card->host->max_busy_timeout) {
+               cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
+       } else {
+-- 
+2.20.1
+
diff --git a/queue-5.5/mmc-sdhci-omap-fix-busy-detection-by-enabling-mmc_ca.patch b/queue-5.5/mmc-sdhci-omap-fix-busy-detection-by-enabling-mmc_ca.patch
new file mode 100644 (file)
index 0000000..dfb7764
--- /dev/null
@@ -0,0 +1,46 @@
+From 8729df3cf4f0efd1d2659657d38cdec027dfd5bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2020 15:05:02 +0100
+Subject: mmc: sdhci-omap: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit 055e04830d4544c57f2a5192a26c9e25915c29c0 ]
+
+It has turned out that the sdhci-omap controller requires the R1B response,
+for commands that has this response associated with them. So, converting
+from an R1B to an R1 response for a CMD6 for example, leads to problems
+with the HW busy detection support.
+
+Fix this by informing the mmc core about the requirement, via setting the
+host cap, MMC_CAP_NEED_RSP_BUSY.
+
+Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
+Reported-by: Anders Roxell <anders.roxell@linaro.org>
+Reported-by: Faiz Abbas <faiz_abbas@ti.com>
+Cc: <stable@vger.kernel.org>
+Tested-by: Anders Roxell <anders.roxell@linaro.org>
+Tested-by: Faiz Abbas <faiz_abbas@ti.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-omap.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
+index 083e7e053c954..d3135249b2e40 100644
+--- a/drivers/mmc/host/sdhci-omap.c
++++ b/drivers/mmc/host/sdhci-omap.c
+@@ -1134,6 +1134,9 @@ static int sdhci_omap_probe(struct platform_device *pdev)
+       host->mmc_host_ops.execute_tuning = sdhci_omap_execute_tuning;
+       host->mmc_host_ops.enable_sdio_irq = sdhci_omap_enable_sdio_irq;
++      /* R1B responses is required to properly manage HW busy detection. */
++      mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
++
+       ret = sdhci_setup_host(host);
+       if (ret)
+               goto err_put_sync;
+-- 
+2.20.1
+
diff --git a/queue-5.5/mmc-sdhci-tegra-fix-busy-detection-by-enabling-mmc_c.patch b/queue-5.5/mmc-sdhci-tegra-fix-busy-detection-by-enabling-mmc_c.patch
new file mode 100644 (file)
index 0000000..31a2cd9
--- /dev/null
@@ -0,0 +1,47 @@
+From 4e3bb73ec2bd46302e3fb46fd2f2bfb85c926d58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2020 15:50:11 +0100
+Subject: mmc: sdhci-tegra: Fix busy detection by enabling
+ MMC_CAP_NEED_RSP_BUSY
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit d2f8bfa4bff5028bc40ed56b4497c32e05b0178f ]
+
+It has turned out that the sdhci-tegra controller requires the R1B response,
+for commands that has this response associated with them. So, converting
+from an R1B to an R1 response for a CMD6 for example, leads to problems
+with the HW busy detection support.
+
+Fix this by informing the mmc core about the requirement, via setting the
+host cap, MMC_CAP_NEED_RSP_BUSY.
+
+Reported-by: Bitan Biswas <bbiswas@nvidia.com>
+Reported-by: Peter Geis <pgwipeout@gmail.com>
+Suggested-by: Sowjanya Komatineni <skomatineni@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Tested-by: Sowjanya Komatineni <skomatineni@nvidia.com>
+Tested-By: Peter Geis <pgwipeout@gmail.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-tegra.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
+index 403ac44a73782..a25c3a4d3f6cb 100644
+--- a/drivers/mmc/host/sdhci-tegra.c
++++ b/drivers/mmc/host/sdhci-tegra.c
+@@ -1552,6 +1552,9 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
+       if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50)
+               host->mmc->caps |= MMC_CAP_1_8V_DDR;
++      /* R1B responses is required to properly manage HW busy detection. */
++      host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
++
+       tegra_sdhci_parse_dt(host);
+       tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power",
+-- 
+2.20.1
+
diff --git a/queue-5.5/pinctrl-qcom-ssbi-gpio-fix-fwspec-parsing-bug.patch b/queue-5.5/pinctrl-qcom-ssbi-gpio-fix-fwspec-parsing-bug.patch
new file mode 100644 (file)
index 0000000..7183b34
--- /dev/null
@@ -0,0 +1,42 @@
+From 06fea570e3118b902daa6b00c6187c79c4d16f4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2020 15:34:15 +0100
+Subject: pinctrl: qcom: ssbi-gpio: Fix fwspec parsing bug
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit f98371476f36359da2285d1807b43e5b17fd18de ]
+
+We are parsing SSBI gpios as fourcell fwspecs but they are
+twocell. Probably a simple copy-and-paste bug.
+
+Tested on the APQ8060 DragonBoard and after this ethernet
+and MMC card detection works again.
+
+Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
+Cc: stable@vger.kernel.org
+Reviewed-by: Brian Masney <masneyb@onstation.org>
+Fixes: ae436fe81053 ("pinctrl: ssbi-gpio: convert to hierarchical IRQ helpers in gpio core")
+Link: https://lore.kernel.org/r/20200306143416.1476250-1-linus.walleij@linaro.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
+index 73d986a903f1b..3059b245ad2b2 100644
+--- a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
++++ b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
+@@ -794,7 +794,7 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
+       girq->fwnode = of_node_to_fwnode(pctrl->dev->of_node);
+       girq->parent_domain = parent_domain;
+       girq->child_to_parent_hwirq = pm8xxx_child_to_parent_hwirq;
+-      girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell;
++      girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell;
+       girq->child_offset_to_irq = pm8xxx_child_offset_to_irq;
+       girq->child_irq_domain_ops.translate = pm8xxx_domain_translate;
+-- 
+2.20.1
+
diff --git a/queue-5.5/series b/queue-5.5/series
new file mode 100644 (file)
index 0000000..460c886
--- /dev/null
@@ -0,0 +1,8 @@
+gpiolib-add-support-for-the-irqdomain-which-doesn-t-.patch
+pinctrl-qcom-ssbi-gpio-fix-fwspec-parsing-bug.patch
+mmc-core-default-to-generic_cmd6_time-as-timeout-in-.patch
+mmc-core-allow-host-controllers-to-require-r1b-for-c.patch
+mmc-sdhci-tegra-fix-busy-detection-by-enabling-mmc_c.patch
+mmc-sdhci-omap-fix-busy-detection-by-enabling-mmc_ca.patch
+mmc-core-respect-mmc_cap_need_rsp_busy-for-emmc-slee.patch
+mmc-core-respect-mmc_cap_need_rsp_busy-for-erase-tri.patch