]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Mar 2026 11:58:32 +0000 (12:58 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Mar 2026 11:58:32 +0000 (12:58 +0100)
added patches:
bpf-drop-kthread_exit-from-noreturn_deny.patch
drm-bridge-ti-sn65dsi86-add-support-for-displayport-mode-with-hpd.patch

queue-6.18/bpf-drop-kthread_exit-from-noreturn_deny.patch [new file with mode: 0644]
queue-6.18/drm-bridge-ti-sn65dsi86-add-support-for-displayport-mode-with-hpd.patch [new file with mode: 0644]
queue-6.18/series

diff --git a/queue-6.18/bpf-drop-kthread_exit-from-noreturn_deny.patch b/queue-6.18/bpf-drop-kthread_exit-from-noreturn_deny.patch
new file mode 100644 (file)
index 0000000..ba33979
--- /dev/null
@@ -0,0 +1,31 @@
+From 7fe44c4388146bdbb3c5932d81a26d9fa0fd3ec9 Mon Sep 17 00:00:00 2001
+From: Christian Loehle <christian.loehle@arm.com>
+Date: Fri, 6 Mar 2026 10:49:18 +0000
+Subject: bpf: drop kthread_exit from noreturn_deny
+
+From: Christian Loehle <christian.loehle@arm.com>
+
+commit 7fe44c4388146bdbb3c5932d81a26d9fa0fd3ec9 upstream.
+
+kthread_exit became a macro to do_exit in commit 28aaa9c39945
+("kthread: consolidate kthread exit paths to prevent use-after-free"),
+so there is no kthread_exit function BTF ID to resolve. Remove it from
+noreturn_deny to avoid resolve_btfids unresolved symbol warnings.
+
+Signed-off-by: Christian Loehle <christian.loehle@arm.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/bpf/verifier.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -24081,7 +24081,6 @@ BTF_ID(func, __x64_sys_exit_group)
+ BTF_ID(func, do_exit)
+ BTF_ID(func, do_group_exit)
+ BTF_ID(func, kthread_complete_and_exit)
+-BTF_ID(func, kthread_exit)
+ BTF_ID(func, make_task_dead)
+ BTF_SET_END(noreturn_deny)
diff --git a/queue-6.18/drm-bridge-ti-sn65dsi86-add-support-for-displayport-mode-with-hpd.patch b/queue-6.18/drm-bridge-ti-sn65dsi86-add-support-for-displayport-mode-with-hpd.patch
new file mode 100644 (file)
index 0000000..9051be9
--- /dev/null
@@ -0,0 +1,224 @@
+From 9133bc3f0564890218cbba6cc7e81ebc0841a6f1 Mon Sep 17 00:00:00 2001
+From: John Ripple <john.ripple@keysight.com>
+Date: Mon, 15 Sep 2025 11:45:43 -0600
+Subject: drm/bridge: ti-sn65dsi86: Add support for DisplayPort mode with HPD
+
+From: John Ripple <john.ripple@keysight.com>
+
+commit 9133bc3f0564890218cbba6cc7e81ebc0841a6f1 upstream.
+
+Add support for DisplayPort to the bridge, which entails the following:
+- Get and use an interrupt for HPD;
+- Properly clear all status bits in the interrupt handler;
+
+Signed-off-by: John Ripple <john.ripple@keysight.com>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20250915174543.2564994-1-john.ripple@keysight.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/bridge/ti-sn65dsi86.c |  112 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 112 insertions(+)
+
+--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+@@ -106,10 +106,21 @@
+ #define SN_PWM_EN_INV_REG                     0xA5
+ #define  SN_PWM_INV_MASK                      BIT(0)
+ #define  SN_PWM_EN_MASK                               BIT(1)
++
++#define SN_IRQ_EN_REG                         0xE0
++#define  IRQ_EN                                       BIT(0)
++
++#define SN_IRQ_EVENTS_EN_REG                  0xE6
++#define  HPD_INSERTION_EN                     BIT(1)
++#define  HPD_REMOVAL_EN                               BIT(2)
++
+ #define SN_AUX_CMD_STATUS_REG                 0xF4
+ #define  AUX_IRQ_STATUS_AUX_RPLY_TOUT         BIT(3)
+ #define  AUX_IRQ_STATUS_AUX_SHORT             BIT(5)
+ #define  AUX_IRQ_STATUS_NAT_I2C_FAIL          BIT(6)
++#define SN_IRQ_STATUS_REG                     0xF5
++#define  HPD_REMOVAL_STATUS                   BIT(2)
++#define  HPD_INSERTION_STATUS                 BIT(1)
+ #define MIN_DSI_CLK_FREQ_MHZ  40
+@@ -152,7 +163,9 @@
+  * @ln_assign:    Value to program to the LN_ASSIGN register.
+  * @ln_polrs:     Value for the 4-bit LN_POLRS field of SN_ENH_FRAME_REG.
+  * @comms_enabled: If true then communication over the aux channel is enabled.
++ * @hpd_enabled:   If true then HPD events are enabled.
+  * @comms_mutex:   Protects modification of comms_enabled.
++ * @hpd_mutex:     Protects modification of hpd_enabled.
+  *
+  * @gchip:        If we expose our GPIOs, this is used.
+  * @gchip_output: A cache of whether we've set GPIOs to output.  This
+@@ -190,7 +203,9 @@ struct ti_sn65dsi86 {
+       u8                              ln_assign;
+       u8                              ln_polrs;
+       bool                            comms_enabled;
++      bool                            hpd_enabled;
+       struct mutex                    comms_mutex;
++      struct mutex                    hpd_mutex;
+ #if defined(CONFIG_OF_GPIO)
+       struct gpio_chip                gchip;
+@@ -221,6 +236,23 @@ static const struct regmap_config ti_sn6
+       .max_register = 0xFF,
+ };
++static int ti_sn65dsi86_read_u8(struct ti_sn65dsi86 *pdata, unsigned int reg,
++                              u8 *val)
++{
++      int ret;
++      unsigned int reg_val;
++
++      ret = regmap_read(pdata->regmap, reg, &reg_val);
++      if (ret) {
++              dev_err(pdata->dev, "fail to read raw reg %#x: %d\n",
++                      reg, ret);
++              return ret;
++      }
++      *val = (u8)reg_val;
++
++      return 0;
++}
++
+ static int __maybe_unused ti_sn65dsi86_read_u16(struct ti_sn65dsi86 *pdata,
+                                               unsigned int reg, u16 *val)
+ {
+@@ -379,6 +411,7 @@ static void ti_sn65dsi86_disable_comms(s
+ static int __maybe_unused ti_sn65dsi86_resume(struct device *dev)
+ {
+       struct ti_sn65dsi86 *pdata = dev_get_drvdata(dev);
++      const struct i2c_client *client = to_i2c_client(pdata->dev);
+       int ret;
+       ret = regulator_bulk_enable(SN_REGULATOR_SUPPLY_NUM, pdata->supplies);
+@@ -413,6 +446,13 @@ static int __maybe_unused ti_sn65dsi86_r
+       if (pdata->refclk)
+               ti_sn65dsi86_enable_comms(pdata, NULL);
++      if (client->irq) {
++              ret = regmap_update_bits(pdata->regmap, SN_IRQ_EN_REG, IRQ_EN,
++                                       IRQ_EN);
++              if (ret)
++                      dev_err(pdata->dev, "Failed to enable IRQ events: %d\n", ret);
++      }
++
+       return ret;
+ }
+@@ -1211,6 +1251,8 @@ static void ti_sn65dsi86_debugfs_init(st
+ static void ti_sn_bridge_hpd_enable(struct drm_bridge *bridge)
+ {
+       struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
++      const struct i2c_client *client = to_i2c_client(pdata->dev);
++      int ret;
+       /*
+        * Device needs to be powered on before reading the HPD state
+@@ -1219,11 +1261,35 @@ static void ti_sn_bridge_hpd_enable(stru
+        */
+       pm_runtime_get_sync(pdata->dev);
++
++      mutex_lock(&pdata->hpd_mutex);
++      pdata->hpd_enabled = true;
++      mutex_unlock(&pdata->hpd_mutex);
++
++      if (client->irq) {
++              ret = regmap_set_bits(pdata->regmap, SN_IRQ_EVENTS_EN_REG,
++                                    HPD_REMOVAL_EN | HPD_INSERTION_EN);
++              if (ret)
++                      dev_err(pdata->dev, "Failed to enable HPD events: %d\n", ret);
++      }
+ }
+ static void ti_sn_bridge_hpd_disable(struct drm_bridge *bridge)
+ {
+       struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
++      const struct i2c_client *client = to_i2c_client(pdata->dev);
++      int ret;
++
++      if (client->irq) {
++              ret = regmap_clear_bits(pdata->regmap, SN_IRQ_EVENTS_EN_REG,
++                                      HPD_REMOVAL_EN | HPD_INSERTION_EN);
++              if (ret)
++                      dev_err(pdata->dev, "Failed to disable HPD events: %d\n", ret);
++      }
++
++      mutex_lock(&pdata->hpd_mutex);
++      pdata->hpd_enabled = false;
++      mutex_unlock(&pdata->hpd_mutex);
+       pm_runtime_put_autosuspend(pdata->dev);
+ }
+@@ -1309,6 +1375,41 @@ static int ti_sn_bridge_parse_dsi_host(s
+       return 0;
+ }
++static irqreturn_t ti_sn_bridge_interrupt(int irq, void *private)
++{
++      struct ti_sn65dsi86 *pdata = private;
++      struct drm_device *dev = pdata->bridge.dev;
++      u8 status;
++      int ret;
++      bool hpd_event;
++
++      ret = ti_sn65dsi86_read_u8(pdata, SN_IRQ_STATUS_REG, &status);
++      if (ret) {
++              dev_err(pdata->dev, "Failed to read IRQ status: %d\n", ret);
++              return IRQ_NONE;
++      }
++
++      hpd_event = status & (HPD_REMOVAL_STATUS | HPD_INSERTION_STATUS);
++
++      dev_dbg(pdata->dev, "(SN_IRQ_STATUS_REG = %#x)\n", status);
++      if (!status)
++              return IRQ_NONE;
++
++      ret = regmap_write(pdata->regmap, SN_IRQ_STATUS_REG, status);
++      if (ret) {
++              dev_err(pdata->dev, "Failed to clear IRQ status: %d\n", ret);
++              return IRQ_NONE;
++      }
++
++      /* Only send the HPD event if we are bound with a device. */
++      mutex_lock(&pdata->hpd_mutex);
++      if (pdata->hpd_enabled && hpd_event)
++              drm_kms_helper_hotplug_event(dev);
++      mutex_unlock(&pdata->hpd_mutex);
++
++      return IRQ_HANDLED;
++}
++
+ static int ti_sn_bridge_probe(struct auxiliary_device *adev,
+                             const struct auxiliary_device_id *id)
+ {
+@@ -1933,6 +2034,7 @@ static int ti_sn65dsi86_probe(struct i2c
+       dev_set_drvdata(dev, pdata);
+       pdata->dev = dev;
++      mutex_init(&pdata->hpd_mutex);
+       mutex_init(&pdata->comms_mutex);
+       pdata->regmap = devm_regmap_init_i2c(client,
+@@ -1973,6 +2075,16 @@ static int ti_sn65dsi86_probe(struct i2c
+       if (strncmp(id_buf, "68ISD   ", ARRAY_SIZE(id_buf)))
+               return dev_err_probe(dev, -EOPNOTSUPP, "unsupported device id\n");
++      if (client->irq) {
++              ret = devm_request_threaded_irq(pdata->dev, client->irq, NULL,
++                                              ti_sn_bridge_interrupt,
++                                              IRQF_ONESHOT,
++                                              dev_name(pdata->dev), pdata);
++
++              if (ret)
++                      return dev_err_probe(dev, ret, "failed to request interrupt\n");
++      }
++
+       /*
+        * Break ourselves up into a collection of aux devices. The only real
+        * motiviation here is to solve the chicken-and-egg problem of probe
index 60d5ba70ba20debd2495a6f20d4c4149b6053851..718fc9417fa2f5012ee4003e64a32cbf02eb2886 100644 (file)
@@ -331,3 +331,5 @@ net-tcp-md5-fix-mac-comparison-to-be-constant-time.patch
 io_uring-ensure-ctx-rings-is-stable-for-task-work-flags-manipulation.patch
 io_uring-eventfd-use-ctx-rings_rcu-for-flags-checking.patch
 mm-damon-core-disallow-non-power-of-two-min_region_sz.patch
+drm-bridge-ti-sn65dsi86-add-support-for-displayport-mode-with-hpd.patch
+bpf-drop-kthread_exit-from-noreturn_deny.patch