From: Greg Kroah-Hartman Date: Wed, 18 Mar 2026 11:58:32 +0000 (+0100) Subject: 6.18-stable patches X-Git-Tag: v6.18.19~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3ccffe9d05a07038dbcce055fe0678c5ca679e64;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-stable patches added patches: bpf-drop-kthread_exit-from-noreturn_deny.patch drm-bridge-ti-sn65dsi86-add-support-for-displayport-mode-with-hpd.patch --- 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 index 0000000000..ba3397922d --- /dev/null +++ b/queue-6.18/bpf-drop-kthread_exit-from-noreturn_deny.patch @@ -0,0 +1,31 @@ +From 7fe44c4388146bdbb3c5932d81a26d9fa0fd3ec9 Mon Sep 17 00:00:00 2001 +From: Christian Loehle +Date: Fri, 6 Mar 2026 10:49:18 +0000 +Subject: bpf: drop kthread_exit from noreturn_deny + +From: Christian Loehle + +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 +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..9051be92b4 --- /dev/null +++ b/queue-6.18/drm-bridge-ti-sn65dsi86-add-support-for-displayport-mode-with-hpd.patch @@ -0,0 +1,224 @@ +From 9133bc3f0564890218cbba6cc7e81ebc0841a6f1 Mon Sep 17 00:00:00 2001 +From: John Ripple +Date: Mon, 15 Sep 2025 11:45:43 -0600 +Subject: drm/bridge: ti-sn65dsi86: Add support for DisplayPort mode with HPD + +From: John Ripple + +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 +Reviewed-by: Douglas Anderson +Signed-off-by: Douglas Anderson +Link: https://lore.kernel.org/r/20250915174543.2564994-1-john.ripple@keysight.com +Signed-off-by: Greg Kroah-Hartman +--- + 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, ®_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 diff --git a/queue-6.18/series b/queue-6.18/series index 60d5ba70ba..718fc9417f 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -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