From: Sasha Levin Date: Wed, 18 Mar 2020 19:27:17 +0000 (-0400) Subject: Fixes for 5.5 X-Git-Tag: v4.4.217~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=36a45ab6f8a3991fec462deb2856038ef07f250c;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.5 Signed-off-by: Sasha Levin --- 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 index 00000000000..a0eaf533a5d --- /dev/null +++ b/queue-5.5/gpiolib-add-support-for-the-irqdomain-which-doesn-t-.patch @@ -0,0 +1,256 @@ +From 55f9c35937b7f1ab1747a346c5ae83e4c751ac5d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20200114082821.14015-3-haokexin@gmail.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2f2d493063a --- /dev/null +++ b/queue-5.5/mmc-core-allow-host-controllers-to-require-r1b-for-c.patch @@ -0,0 +1,63 @@ +From 4bb9794258026c7600bff6bed55b100261a402d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2020 12:49:43 +0100 +Subject: mmc: core: Allow host controllers to require R1B for CMD6 + +From: Ulf Hansson + +[ 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 +Cc: +Tested-by: Anders Roxell +Tested-by: Sowjanya Komatineni +Tested-by: Faiz Abbas +Tested-By: Peter Geis +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..55457512efb --- /dev/null +++ b/queue-5.5/mmc-core-default-to-generic_cmd6_time-as-timeout-in-.patch @@ -0,0 +1,79 @@ +From 69edb5611ac110e617406215c17945524c4b60e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20200122142747.5690-4-ulf.hansson@linaro.org +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..05962a27bb1 --- /dev/null +++ b/queue-5.5/mmc-core-respect-mmc_cap_need_rsp_busy-for-emmc-slee.patch @@ -0,0 +1,50 @@ +From 586bb8ad748ec1c102d2359c4ba90f678a2b6c01 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: +Link: https://lore.kernel.org/r/20200311092036.16084-1-ulf.hansson@linaro.org +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..49cd0125097 --- /dev/null +++ b/queue-5.5/mmc-core-respect-mmc_cap_need_rsp_busy-for-erase-tri.patch @@ -0,0 +1,51 @@ +From 718168b10350f5a0ad7dd1ca8bb6f76aa30fcd25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: +Tested-by: Anders Roxell +Tested-by: Sowjanya Komatineni +Tested-by: Faiz Abbas +Tested-By: Peter Geis +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..dfb7764282b --- /dev/null +++ b/queue-5.5/mmc-sdhci-omap-fix-busy-detection-by-enabling-mmc_ca.patch @@ -0,0 +1,46 @@ +From 8729df3cf4f0efd1d2659657d38cdec027dfd5bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reported-by: Anders Roxell +Reported-by: Faiz Abbas +Cc: +Tested-by: Anders Roxell +Tested-by: Faiz Abbas +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..31a2cd98d3d --- /dev/null +++ b/queue-5.5/mmc-sdhci-tegra-fix-busy-detection-by-enabling-mmc_c.patch @@ -0,0 +1,47 @@ +From 4e3bb73ec2bd46302e3fb46fd2f2bfb85c926d58 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reported-by: Peter Geis +Suggested-by: Sowjanya Komatineni +Cc: +Tested-by: Sowjanya Komatineni +Tested-By: Peter Geis +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..7183b34f693 --- /dev/null +++ b/queue-5.5/pinctrl-qcom-ssbi-gpio-fix-fwspec-parsing-bug.patch @@ -0,0 +1,42 @@ +From 06fea570e3118b902daa6b00c6187c79c4d16f4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2020 15:34:15 +0100 +Subject: pinctrl: qcom: ssbi-gpio: Fix fwspec parsing bug + +From: Linus Walleij + +[ 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 +Cc: stable@vger.kernel.org +Reviewed-by: Brian Masney +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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..460c886460a --- /dev/null +++ b/queue-5.5/series @@ -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