From: Greg Kroah-Hartman Date: Wed, 22 Nov 2023 18:56:30 +0000 (+0000) Subject: 4.14-stable patches X-Git-Tag: v4.14.331~126 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=18a43496ae6eb4e268b6b6d6e96c8c11b6d1bb55;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: genirq-generic_chip-make-irq_remove_generic_chip-irqdomain-aware.patch mmc-meson-gx-remove-setting-of-cmd_cfg_error.patch regmap-ensure-range-selector-registers-are-updated-after-cache-sync.patch --- diff --git a/queue-4.14/genirq-generic_chip-make-irq_remove_generic_chip-irqdomain-aware.patch b/queue-4.14/genirq-generic_chip-make-irq_remove_generic_chip-irqdomain-aware.patch new file mode 100644 index 00000000000..0d772077aba --- /dev/null +++ b/queue-4.14/genirq-generic_chip-make-irq_remove_generic_chip-irqdomain-aware.patch @@ -0,0 +1,82 @@ +From 5e7afb2eb7b2a7c81e9f608cbdf74a07606fd1b5 Mon Sep 17 00:00:00 2001 +From: Herve Codina +Date: Tue, 24 Oct 2023 17:03:35 +0200 +Subject: genirq/generic_chip: Make irq_remove_generic_chip() irqdomain aware + +From: Herve Codina + +commit 5e7afb2eb7b2a7c81e9f608cbdf74a07606fd1b5 upstream. + +irq_remove_generic_chip() calculates the Linux interrupt number for removing the +handler and interrupt chip based on gc::irq_base as a linear function of +the bit positions of set bits in the @msk argument. + +When the generic chip is present in an irq domain, i.e. created with a call +to irq_alloc_domain_generic_chips(), gc::irq_base contains not the base +Linux interrupt number. It contains the base hardware interrupt for this +chip. It is set to 0 for the first chip in the domain, 0 + N for the next +chip, where $N is the number of hardware interrupts per chip. + +That means the Linux interrupt number cannot be calculated based on +gc::irq_base for irqdomain based chips without a domain map lookup, which +is currently missing. + +Rework the code to take the irqdomain case into account and calculate the +Linux interrupt number by a irqdomain lookup of the domain specific +hardware interrupt number. + +[ tglx: Massage changelog. Reshuffle the logic and add a proper comment. ] + +Fixes: cfefd21e693d ("genirq: Add chip suspend and resume callbacks") +Signed-off-by: Herve Codina +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20231024150335.322282-1-herve.codina@bootlin.com +Signed-off-by: Greg Kroah-Hartman +--- + kernel/irq/generic-chip.c | 25 +++++++++++++++++++------ + 1 file changed, 19 insertions(+), 6 deletions(-) + +--- a/kernel/irq/generic-chip.c ++++ b/kernel/irq/generic-chip.c +@@ -533,21 +533,34 @@ EXPORT_SYMBOL_GPL(irq_setup_alt_chip); + void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, + unsigned int clr, unsigned int set) + { +- unsigned int i = gc->irq_base; ++ unsigned int i, virq; + + raw_spin_lock(&gc_lock); + list_del(&gc->list); + raw_spin_unlock(&gc_lock); + +- for (; msk; msk >>= 1, i++) { ++ for (i = 0; msk; msk >>= 1, i++) { + if (!(msk & 0x01)) + continue; + ++ /* ++ * Interrupt domain based chips store the base hardware ++ * interrupt number in gc::irq_base. Otherwise gc::irq_base ++ * contains the base Linux interrupt number. ++ */ ++ if (gc->domain) { ++ virq = irq_find_mapping(gc->domain, gc->irq_base + i); ++ if (!virq) ++ continue; ++ } else { ++ virq = gc->irq_base + i; ++ } ++ + /* Remove handler first. That will mask the irq line */ +- irq_set_handler(i, NULL); +- irq_set_chip(i, &no_irq_chip); +- irq_set_chip_data(i, NULL); +- irq_modify_status(i, clr, set); ++ irq_set_handler(virq, NULL); ++ irq_set_chip(virq, &no_irq_chip); ++ irq_set_chip_data(virq, NULL); ++ irq_modify_status(virq, clr, set); + } + } + EXPORT_SYMBOL_GPL(irq_remove_generic_chip); diff --git a/queue-4.14/mmc-meson-gx-remove-setting-of-cmd_cfg_error.patch b/queue-4.14/mmc-meson-gx-remove-setting-of-cmd_cfg_error.patch new file mode 100644 index 00000000000..aed9cfd4493 --- /dev/null +++ b/queue-4.14/mmc-meson-gx-remove-setting-of-cmd_cfg_error.patch @@ -0,0 +1,36 @@ +From 57925e16c9f7d18012bcf45bfa658f92c087981a Mon Sep 17 00:00:00 2001 +From: Rong Chen +Date: Thu, 26 Oct 2023 15:31:56 +0800 +Subject: mmc: meson-gx: Remove setting of CMD_CFG_ERROR + +From: Rong Chen + +commit 57925e16c9f7d18012bcf45bfa658f92c087981a upstream. + +For the t7 and older SoC families, the CMD_CFG_ERROR has no effect. +Starting from SoC family C3, setting this bit without SG LINK data +address will cause the controller to generate an IRQ and stop working. + +To fix it, don't set the bit CMD_CFG_ERROR anymore. + +Fixes: 18f92bc02f17 ("mmc: meson-gx: make sure the descriptor is stopped on errors") +Signed-off-by: Rong Chen +Reviewed-by: Jerome Brunet +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20231026073156.2868310-1-rong.chen@amlogic.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/meson-gx-mmc.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/mmc/host/meson-gx-mmc.c ++++ b/drivers/mmc/host/meson-gx-mmc.c +@@ -908,7 +908,6 @@ static void meson_mmc_start_cmd(struct m + + cmd_cfg |= FIELD_PREP(CMD_CFG_CMD_INDEX_MASK, cmd->opcode); + cmd_cfg |= CMD_CFG_OWNER; /* owned by CPU */ +- cmd_cfg |= CMD_CFG_ERROR; /* stop in case of error */ + + meson_mmc_set_response_bits(cmd, &cmd_cfg); + diff --git a/queue-4.14/regmap-ensure-range-selector-registers-are-updated-after-cache-sync.patch b/queue-4.14/regmap-ensure-range-selector-registers-are-updated-after-cache-sync.patch new file mode 100644 index 00000000000..63119a42765 --- /dev/null +++ b/queue-4.14/regmap-ensure-range-selector-registers-are-updated-after-cache-sync.patch @@ -0,0 +1,90 @@ +From 0ec7731655de196bc1e4af99e495b38778109d22 Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Thu, 26 Oct 2023 16:49:19 +0100 +Subject: regmap: Ensure range selector registers are updated after cache sync + +From: Mark Brown + +commit 0ec7731655de196bc1e4af99e495b38778109d22 upstream. + +When we sync the register cache we do so with the cache bypassed in order +to avoid overhead from writing the synced values back into the cache. If +the regmap has ranges and the selector register for those ranges is in a +register which is cached this has the unfortunate side effect of meaning +that the physical and cached copies of the selector register can be out of +sync after a cache sync. The cache will have whatever the selector was when +the sync started and the hardware will have the selector for the register +that was synced last. + +Fix this by rewriting all cached selector registers after every sync, +ensuring that the hardware and cache have the same content. This will +result in extra writes that wouldn't otherwise be needed but is simple +so hopefully robust. We don't read from the hardware since not all +devices have physical read support. + +Given that nobody noticed this until now it is likely that we are rarely if +ever hitting this case. + +Reported-by: Hector Martin +Cc: stable@vger.kernel.org +Signed-off-by: Mark Brown +Link: https://lore.kernel.org/r/20231026-regmap-fix-selector-sync-v1-1-633ded82770d@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + drivers/base/regmap/regcache.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +--- a/drivers/base/regmap/regcache.c ++++ b/drivers/base/regmap/regcache.c +@@ -329,6 +329,11 @@ static int regcache_default_sync(struct + return 0; + } + ++static int rbtree_all(const void *key, const struct rb_node *node) ++{ ++ return 0; ++} ++ + /** + * regcache_sync - Sync the register cache with the hardware. + * +@@ -346,6 +351,7 @@ int regcache_sync(struct regmap *map) + unsigned int i; + const char *name; + bool bypass; ++ struct rb_node *node; + + if (WARN_ON(map->cache_type == REGCACHE_NONE)) + return -EINVAL; +@@ -390,6 +396,30 @@ out: + map->async = false; + map->cache_bypass = bypass; + map->no_sync_defaults = false; ++ ++ /* ++ * If we did any paging with cache bypassed and a cached ++ * paging register then the register and cache state might ++ * have gone out of sync, force writes of all the paging ++ * registers. ++ */ ++ rb_for_each(node, 0, &map->range_tree, rbtree_all) { ++ struct regmap_range_node *this = ++ rb_entry(node, struct regmap_range_node, node); ++ ++ /* If there's nothing in the cache there's nothing to sync */ ++ ret = regcache_read(map, this->selector_reg, &i); ++ if (ret != 0) ++ continue; ++ ++ ret = _regmap_write(map, this->selector_reg, i); ++ if (ret != 0) { ++ dev_err(map->dev, "Failed to write %x = %x: %d\n", ++ this->selector_reg, i, ret); ++ break; ++ } ++ } ++ + map->unlock(map->lock_arg); + + regmap_async_complete(map); diff --git a/queue-4.14/series b/queue-4.14/series index a846da343fb..d1f458de1bf 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -31,3 +31,6 @@ audit-don-t-take-task_lock-in-audit_exe_compare-code-path.patch audit-don-t-warn_on_once-current-mm-in-audit_exe_compare.patch hvc-xen-fix-error-path-in-xen_hvc_init-to-always-register-frontend-driver.patch pci-sysfs-protect-driver-s-d3cold-preference-from-user-space.patch +regmap-ensure-range-selector-registers-are-updated-after-cache-sync.patch +mmc-meson-gx-remove-setting-of-cmd_cfg_error.patch +genirq-generic_chip-make-irq_remove_generic_chip-irqdomain-aware.patch