]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Sat, 23 Dec 2023 16:04:03 +0000 (11:04 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 23 Dec 2023 16:04:03 +0000 (11:04 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.15/asoc-hdmi-codec-fix-missing-report-for-jack-initial-.patch [new file with mode: 0644]
queue-5.15/gpiolib-cdev-add-gpio_device-locking-wrapper-around-.patch [new file with mode: 0644]
queue-5.15/i2c-aspeed-handle-the-coalesced-stop-conditions-with.patch [new file with mode: 0644]
queue-5.15/pinctrl-at91-pio4-use-dedicated-lock-class-for-irq.patch [new file with mode: 0644]
queue-5.15/series [new file with mode: 0644]

diff --git a/queue-5.15/asoc-hdmi-codec-fix-missing-report-for-jack-initial-.patch b/queue-5.15/asoc-hdmi-codec-fix-missing-report-for-jack-initial-.patch
new file mode 100644 (file)
index 0000000..d62c6ea
--- /dev/null
@@ -0,0 +1,70 @@
+From c08df305049fed8916712aadac54eae93a4abe49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Dec 2023 15:56:52 +0100
+Subject: ASoC: hdmi-codec: fix missing report for jack initial status
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 025222a9d6d25eee2ad9a1bb5a8b29b34b5ba576 ]
+
+This fixes a problem introduced while fixing ELD reporting with no jack
+set.
+
+Most driver using the hdmi-codec will call the 'plugged_cb' callback
+directly when registered to report the initial state of the HDMI connector.
+
+With the commit mentionned, this occurs before jack is ready and the
+initial report is lost for platforms actually providing a jack for HDMI.
+
+Fix this by storing the hdmi connector status regardless of jack being set
+or not and report the last status when jack gets set.
+
+With this, the initial state is reported correctly even if it is
+disconnected. This was not done initially and is also a fix.
+
+Fixes: 15be353d55f9 ("ASoC: hdmi-codec: register hpd callback on component probe")
+Reported-by: Zhengqiao Xia <xiazhengqiao@huaqin.corp-partner.google.com>
+Closes: https://lore.kernel.org/alsa-devel/CADYyEwTNyY+fR9SgfDa-g6iiDwkU3MUdPVCYexs2_3wbcM8_vg@mail.gmail.com/
+Cc: Hsin-Yi Wang <hsinyi@google.com>
+Tested-by: Zhengqiao Xia <xiazhengqiao@huaqin.corp-partner.google.com>
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Link: https://msgid.link/r/20231218145655.134929-1-jbrunet@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/hdmi-codec.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
+index 0a7e2f8ca71af..410fb59807f1b 100644
+--- a/sound/soc/codecs/hdmi-codec.c
++++ b/sound/soc/codecs/hdmi-codec.c
+@@ -843,8 +843,9 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai)
+ static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
+                                  unsigned int jack_status)
+ {
+-      if (hcp->jack && jack_status != hcp->jack_status) {
+-              snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
++      if (jack_status != hcp->jack_status) {
++              if (hcp->jack)
++                      snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
+               hcp->jack_status = jack_status;
+       }
+ }
+@@ -873,6 +874,13 @@ static int hdmi_codec_set_jack(struct snd_soc_component *component,
+       if (hcp->hcd.ops->hook_plugged_cb) {
+               hcp->jack = jack;
++
++              /*
++               * Report the initial jack status which may have been provided
++               * by the parent hdmi driver while the hpd hook was registered.
++               */
++              snd_soc_jack_report(jack, hcp->jack_status, SND_JACK_LINEOUT);
++
+               return 0;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpiolib-cdev-add-gpio_device-locking-wrapper-around-.patch b/queue-5.15/gpiolib-cdev-add-gpio_device-locking-wrapper-around-.patch
new file mode 100644 (file)
index 0000000..6396a40
--- /dev/null
@@ -0,0 +1,64 @@
+From 34df5cd1cf1d402e37e797cd6f3ab4b007cf2bfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Dec 2023 09:20:36 +0800
+Subject: gpiolib: cdev: add gpio_device locking wrapper around gpio_ioctl()
+
+From: Kent Gibson <warthog618@gmail.com>
+
+[ Upstream commit 1d656bd259edb89dc1d9938ec5c5389867088546 ]
+
+While the GPIO cdev gpio_ioctl() call is in progress, the kernel can
+call gpiochip_remove() which will set gdev->chip to NULL, after which
+any subsequent access will cause a crash.
+
+gpio_ioctl() was overlooked by the previous fix to protect syscalls
+(bdbbae241a04), so add protection for that.
+
+Fixes: bdbbae241a04 ("gpiolib: protect the GPIO device against being dropped while in use by user-space")
+Fixes: d7c51b47ac11 ("gpio: userspace ABI for reading/writing GPIO lines")
+Fixes: 3c0d9c635ae2 ("gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and GPIO_V2_LINE_GET_VALUES_IOCTL")
+Fixes: aad955842d1c ("gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and GPIO_V2_GET_LINEINFO_WATCH_IOCTL")
+Signed-off-by: Kent Gibson <warthog618@gmail.com>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib-cdev.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
+index 2a2e0691462bf..1db991cb2efce 100644
+--- a/drivers/gpio/gpiolib-cdev.c
++++ b/drivers/gpio/gpiolib-cdev.c
+@@ -2224,10 +2224,7 @@ static int lineinfo_unwatch(struct gpio_chardev_data *cdev, void __user *ip)
+       return 0;
+ }
+-/*
+- * gpio_ioctl() - ioctl handler for the GPIO chardev
+- */
+-static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++static long gpio_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg)
+ {
+       struct gpio_chardev_data *cdev = file->private_data;
+       struct gpio_device *gdev = cdev->gdev;
+@@ -2264,6 +2261,17 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+       }
+ }
++/*
++ * gpio_ioctl() - ioctl handler for the GPIO chardev
++ */
++static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++      struct gpio_chardev_data *cdev = file->private_data;
++
++      return call_ioctl_locked(file, cmd, arg, cdev->gdev,
++                               gpio_ioctl_unlocked);
++}
++
+ #ifdef CONFIG_COMPAT
+ static long gpio_ioctl_compat(struct file *file, unsigned int cmd,
+                             unsigned long arg)
+-- 
+2.43.0
+
diff --git a/queue-5.15/i2c-aspeed-handle-the-coalesced-stop-conditions-with.patch b/queue-5.15/i2c-aspeed-handle-the-coalesced-stop-conditions-with.patch
new file mode 100644 (file)
index 0000000..c7ebd08
--- /dev/null
@@ -0,0 +1,115 @@
+From f5ffb728ef2640117af6b68afee367b749d58cf8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 17:22:16 +0700
+Subject: i2c: aspeed: Handle the coalesced stop conditions with the start
+ conditions.
+
+From: Quan Nguyen <quan@os.amperecomputing.com>
+
+[ Upstream commit b4cc1cbba5195a4dd497cf2f8f09e7807977d543 ]
+
+Some masters may drive the transfers with low enough latency between
+the nak/stop phase of the current command and the start/address phase
+of the following command that the interrupts are coalesced by the
+time we process them.
+Handle the stop conditions before processing SLAVE_MATCH to fix the
+complaints that sometimes occur below.
+
+"aspeed-i2c-bus 1e78a040.i2c-bus: irq handled != irq. Expected
+0x00000086, but was 0x00000084"
+
+Fixes: f9eb91350bb2 ("i2c: aspeed: added slave support for Aspeed I2C driver")
+Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com>
+Reviewed-by: Andrew Jeffery <andrew@codeconstruct.com.au>
+Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-aspeed.c | 48 ++++++++++++++++++++++-----------
+ 1 file changed, 32 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
+index b7cad1bed3dc1..e61ed702a12ce 100644
+--- a/drivers/i2c/busses/i2c-aspeed.c
++++ b/drivers/i2c/busses/i2c-aspeed.c
+@@ -250,18 +250,46 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
+       if (!slave)
+               return 0;
+-      command = readl(bus->base + ASPEED_I2C_CMD_REG);
++      /*
++       * Handle stop conditions early, prior to SLAVE_MATCH. Some masters may drive
++       * transfers with low enough latency between the nak/stop phase of the current
++       * command and the start/address phase of the following command that the
++       * interrupts are coalesced by the time we process them.
++       */
++      if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) {
++              irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP;
++              bus->slave_state = ASPEED_I2C_SLAVE_STOP;
++      }
++
++      if (irq_status & ASPEED_I2CD_INTR_TX_NAK &&
++          bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) {
++              irq_handled |= ASPEED_I2CD_INTR_TX_NAK;
++              bus->slave_state = ASPEED_I2C_SLAVE_STOP;
++      }
++
++      /* Propagate any stop conditions to the slave implementation. */
++      if (bus->slave_state == ASPEED_I2C_SLAVE_STOP) {
++              i2c_slave_event(slave, I2C_SLAVE_STOP, &value);
++              bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE;
++      }
+-      /* Slave was requested, restart state machine. */
++      /*
++       * Now that we've dealt with any potentially coalesced stop conditions,
++       * address any start conditions.
++       */
+       if (irq_status & ASPEED_I2CD_INTR_SLAVE_MATCH) {
+               irq_handled |= ASPEED_I2CD_INTR_SLAVE_MATCH;
+               bus->slave_state = ASPEED_I2C_SLAVE_START;
+       }
+-      /* Slave is not currently active, irq was for someone else. */
++      /*
++       * If the slave has been stopped and not started then slave interrupt
++       * handling is complete.
++       */
+       if (bus->slave_state == ASPEED_I2C_SLAVE_INACTIVE)
+               return irq_handled;
++      command = readl(bus->base + ASPEED_I2C_CMD_REG);
+       dev_dbg(bus->dev, "slave irq status 0x%08x, cmd 0x%08x\n",
+               irq_status, command);
+@@ -280,17 +308,6 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
+               irq_handled |= ASPEED_I2CD_INTR_RX_DONE;
+       }
+-      /* Slave was asked to stop. */
+-      if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) {
+-              irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP;
+-              bus->slave_state = ASPEED_I2C_SLAVE_STOP;
+-      }
+-      if (irq_status & ASPEED_I2CD_INTR_TX_NAK &&
+-          bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) {
+-              irq_handled |= ASPEED_I2CD_INTR_TX_NAK;
+-              bus->slave_state = ASPEED_I2C_SLAVE_STOP;
+-      }
+-
+       switch (bus->slave_state) {
+       case ASPEED_I2C_SLAVE_READ_REQUESTED:
+               if (unlikely(irq_status & ASPEED_I2CD_INTR_TX_ACK))
+@@ -319,8 +336,7 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
+               i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value);
+               break;
+       case ASPEED_I2C_SLAVE_STOP:
+-              i2c_slave_event(slave, I2C_SLAVE_STOP, &value);
+-              bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE;
++              /* Stop event handling is done early. Unreachable. */
+               break;
+       case ASPEED_I2C_SLAVE_START:
+               /* Slave was just started. Waiting for the next event. */;
+-- 
+2.43.0
+
diff --git a/queue-5.15/pinctrl-at91-pio4-use-dedicated-lock-class-for-irq.patch b/queue-5.15/pinctrl-at91-pio4-use-dedicated-lock-class-for-irq.patch
new file mode 100644 (file)
index 0000000..d6120fc
--- /dev/null
@@ -0,0 +1,121 @@
+From 2b5af37df582f958663c3fc0692c6adeb0d70e87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Dec 2023 22:34:24 +0100
+Subject: pinctrl: at91-pio4: use dedicated lock class for IRQ
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexis LothorĂ© <alexis.lothore@bootlin.com>
+
+[ Upstream commit 14694179e561b5f2f7e56a0f590e2cb49a9cc7ab ]
+
+Trying to suspend to RAM on SAMA5D27 EVK leads to the following lockdep
+warning:
+
+ ============================================
+ WARNING: possible recursive locking detected
+ 6.7.0-rc5-wt+ #532 Not tainted
+ --------------------------------------------
+ sh/92 is trying to acquire lock:
+ c3cf306c (&irq_desc_lock_class){-.-.}-{2:2}, at: __irq_get_desc_lock+0xe8/0x100
+
+ but task is already holding lock:
+ c3d7c46c (&irq_desc_lock_class){-.-.}-{2:2}, at: __irq_get_desc_lock+0xe8/0x100
+
+ other info that might help us debug this:
+  Possible unsafe locking scenario:
+
+        CPU0
+        ----
+   lock(&irq_desc_lock_class);
+   lock(&irq_desc_lock_class);
+
+  *** DEADLOCK ***
+
+  May be due to missing lock nesting notation
+
+ 6 locks held by sh/92:
+  #0: c3aa0258 (sb_writers#6){.+.+}-{0:0}, at: ksys_write+0xd8/0x178
+  #1: c4c2df44 (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x138/0x284
+  #2: c32684a0 (kn->active){.+.+}-{0:0}, at: kernfs_fop_write_iter+0x148/0x284
+  #3: c232b6d4 (system_transition_mutex){+.+.}-{3:3}, at: pm_suspend+0x13c/0x4e8
+  #4: c387b088 (&dev->mutex){....}-{3:3}, at: __device_suspend+0x1e8/0x91c
+  #5: c3d7c46c (&irq_desc_lock_class){-.-.}-{2:2}, at: __irq_get_desc_lock+0xe8/0x100
+
+ stack backtrace:
+ CPU: 0 PID: 92 Comm: sh Not tainted 6.7.0-rc5-wt+ #532
+ Hardware name: Atmel SAMA5
+  unwind_backtrace from show_stack+0x18/0x1c
+  show_stack from dump_stack_lvl+0x34/0x48
+  dump_stack_lvl from __lock_acquire+0x19ec/0x3a0c
+  __lock_acquire from lock_acquire.part.0+0x124/0x2d0
+  lock_acquire.part.0 from _raw_spin_lock_irqsave+0x5c/0x78
+  _raw_spin_lock_irqsave from __irq_get_desc_lock+0xe8/0x100
+  __irq_get_desc_lock from irq_set_irq_wake+0xa8/0x204
+  irq_set_irq_wake from atmel_gpio_irq_set_wake+0x58/0xb4
+  atmel_gpio_irq_set_wake from irq_set_irq_wake+0x100/0x204
+  irq_set_irq_wake from gpio_keys_suspend+0xec/0x2b8
+  gpio_keys_suspend from dpm_run_callback+0xe4/0x248
+  dpm_run_callback from __device_suspend+0x234/0x91c
+  __device_suspend from dpm_suspend+0x224/0x43c
+  dpm_suspend from dpm_suspend_start+0x9c/0xa8
+  dpm_suspend_start from suspend_devices_and_enter+0x1e0/0xa84
+  suspend_devices_and_enter from pm_suspend+0x460/0x4e8
+  pm_suspend from state_store+0x78/0xe4
+  state_store from kernfs_fop_write_iter+0x1a0/0x284
+  kernfs_fop_write_iter from vfs_write+0x38c/0x6f4
+  vfs_write from ksys_write+0xd8/0x178
+  ksys_write from ret_fast_syscall+0x0/0x1c
+ Exception stack(0xc52b3fa8 to 0xc52b3ff0)
+ 3fa0:                   00000004 005a0ae8 00000001 005a0ae8 00000004 00000001
+ 3fc0: 00000004 005a0ae8 00000001 00000004 00000004 b6c616c0 00000020 0059d190
+ 3fe0: 00000004 b6c61678 aec5a041 aebf1a26
+
+This warning is raised because pinctrl-at91-pio4 uses chained IRQ. Whenever
+a wake up source configures an IRQ through irq_set_irq_wake, it will
+lock the corresponding IRQ desc, and then call irq_set_irq_wake on "parent"
+IRQ which will do the same on its own IRQ desc, but since those two locks
+share the same class, lockdep reports this as an issue.
+
+Fix lockdep false positive by setting a different class for parent and
+children IRQ
+
+Fixes: 776180848b57 ("pinctrl: introduce driver for Atmel PIO4 controller")
+Signed-off-by: Alexis LothorĂ© <alexis.lothore@bootlin.com>
+Link: https://lore.kernel.org/r/20231215-lockdep_warning-v1-1-8137b2510ed5@bootlin.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-at91-pio4.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
+index 62b9a94c10baa..d80c3911b5b1c 100644
+--- a/drivers/pinctrl/pinctrl-at91-pio4.c
++++ b/drivers/pinctrl/pinctrl-at91-pio4.c
+@@ -1038,6 +1038,13 @@ static const struct of_device_id atmel_pctrl_of_match[] = {
+       }
+ };
++/*
++ * This lock class allows to tell lockdep that parent IRQ and children IRQ do
++ * not share the same class so it does not raise false positive
++ */
++static struct lock_class_key atmel_lock_key;
++static struct lock_class_key atmel_request_key;
++
+ static int atmel_pinctrl_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -1193,6 +1200,7 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
+               irq_set_chip_and_handler(irq, &atmel_gpio_irq_chip,
+                                        handle_simple_irq);
+               irq_set_chip_data(irq, atmel_pioctrl);
++              irq_set_lockdep_class(irq, &atmel_lock_key, &atmel_request_key);
+               dev_dbg(dev,
+                       "atmel gpio irq domain: hwirq: %d, linux irq: %d\n",
+                       i, irq);
+-- 
+2.43.0
+
diff --git a/queue-5.15/series b/queue-5.15/series
new file mode 100644 (file)
index 0000000..0063ed8
--- /dev/null
@@ -0,0 +1,4 @@
+asoc-hdmi-codec-fix-missing-report-for-jack-initial-.patch
+i2c-aspeed-handle-the-coalesced-stop-conditions-with.patch
+pinctrl-at91-pio4-use-dedicated-lock-class-for-irq.patch
+gpiolib-cdev-add-gpio_device-locking-wrapper-around-.patch