* [PATCH v2 1/5] drm/xe/printk: Add xe_warn_once()
2026-06-05 20:40 [PATCH v2 0/5] drm/{i915, xe}: Refactor generic_handle_irq_safe() error messages Jonathan Cavitt
@ 2026-06-05 20:40 ` Jonathan Cavitt
2026-06-05 20:40 ` [PATCH v2 2/5] drm/xe/heci: Use xe print functions in xe_heci_gsc.c Jonathan Cavitt
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cavitt @ 2026-06-05 20:40 UTC (permalink / raw)
To: intel-xe, intel-gfx
Cc: saurabhg.gupta, alex.zuo, jonathan.cavitt, raag.jadav,
Michal.Wajdeczko
Create a wrapper function xe_warn_once() that calls drm_warn_once().
Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
---
drivers/gpu/drm/xe/xe_printk.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_printk.h b/drivers/gpu/drm/xe/xe_printk.h
index c5be2385aa95..afa787fcdeb6 100644
--- a/drivers/gpu/drm/xe/xe_printk.h
+++ b/drivers/gpu/drm/xe/xe_printk.h
@@ -27,6 +27,9 @@
#define xe_warn(_xe, _fmt, ...) \
xe_printk((_xe), warn, _fmt, ##__VA_ARGS__)
+#define xe_warn_once(_xe, _fmt, ...) \
+ xe_printk((_xe), warn_once, _fmt, ##__VA_ARGS__)
+
#define xe_notice(_xe, _fmt, ...) \
xe_printk((_xe), notice, _fmt, ##__VA_ARGS__)
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 2/5] drm/xe/heci: Use xe print functions in xe_heci_gsc.c
2026-06-05 20:40 [PATCH v2 0/5] drm/{i915, xe}: Refactor generic_handle_irq_safe() error messages Jonathan Cavitt
2026-06-05 20:40 ` [PATCH v2 1/5] drm/xe/printk: Add xe_warn_once() Jonathan Cavitt
@ 2026-06-05 20:40 ` Jonathan Cavitt
2026-06-05 20:40 ` [PATCH v2 3/5] drm/xe/i2c: Use xe print functions in xe_i2c.c Jonathan Cavitt
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cavitt @ 2026-06-05 20:40 UTC (permalink / raw)
To: intel-xe, intel-gfx
Cc: saurabhg.gupta, alex.zuo, jonathan.cavitt, raag.jadav,
Michal.Wajdeczko
Update xe_heci_gsc.c to use the xe error reporting helper functions in
xe_printk.h instead of directly calling the associated drm print
functions from drm_print.h. While we're here, we should update the
error messages to print the error codes in a more friendly way.
v2:
- Update the error messages to print the error codes in a more friendly
way (Wajdeczko)
Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Cc: Michal Wajdeczko <Michal.Wajdeczko@intel.com>
---
drivers/gpu/drm/xe/xe_heci_gsc.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_heci_gsc.c b/drivers/gpu/drm/xe/xe_heci_gsc.c
index 5af8903e10af..13123990c4e2 100644
--- a/drivers/gpu/drm/xe/xe_heci_gsc.c
+++ b/drivers/gpu/drm/xe/xe_heci_gsc.c
@@ -8,12 +8,11 @@
#include <linux/pci.h>
#include <linux/sizes.h>
-#include <drm/drm_print.h>
-
#include "xe_device_types.h"
#include "xe_heci_gsc.h"
#include "regs/xe_gsc_regs.h"
#include "xe_platform_types.h"
+#include "xe_printk.h"
#include "xe_survivability_mode.h"
#define GSC_BAR_LENGTH 0x00000FFC
@@ -112,13 +111,13 @@ static int heci_gsc_irq_setup(struct xe_device *xe)
heci_gsc->irq = irq_alloc_desc(0);
if (heci_gsc->irq < 0) {
- drm_err(&xe->drm, "gsc irq error %d\n", heci_gsc->irq);
+ xe_err(xe, "GSC: irq allocation failed (%pe)\n", ERR_PTR(heci_gsc->irq));
return heci_gsc->irq;
}
ret = heci_gsc_irq_init(heci_gsc->irq);
if (ret < 0)
- drm_err(&xe->drm, "gsc irq init failed %d\n", ret);
+ xe_err(xe, "GSC: irq initialization failed (%pe)\n", ERR_PTR(ret));
return ret;
}
@@ -151,7 +150,7 @@ static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def *
ret = auxiliary_device_init(aux_dev);
if (ret < 0) {
- drm_err(&xe->drm, "gsc aux init failed %d\n", ret);
+ xe_err(xe, "gsc aux init failed %d\n", ret);
kfree(adev);
return ret;
}
@@ -159,7 +158,7 @@ static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def *
heci_gsc->adev = adev; /* needed by the notifier */
ret = auxiliary_device_add(aux_dev);
if (ret < 0) {
- drm_err(&xe->drm, "gsc aux add failed %d\n", ret);
+ xe_err(xe, "gsc aux add failed %d\n", ret);
heci_gsc->adev = NULL;
/* adev will be freed with the put_device() and .release sequence */
@@ -190,7 +189,7 @@ int xe_heci_gsc_init(struct xe_device *xe)
}
if (!def || !def->name) {
- drm_warn(&xe->drm, "HECI is not implemented!\n");
+ xe_warn(xe, "HECI is not implemented!\n");
return 0;
}
@@ -215,7 +214,7 @@ void xe_heci_gsc_irq_handler(struct xe_device *xe, u32 iir)
return;
if (!xe->info.has_heci_gscfi) {
- drm_warn_once(&xe->drm, "GSC irq: not supported");
+ xe_warn_once(xe, "GSC: unexpected irq %#x\n", iir);
return;
}
@@ -224,7 +223,7 @@ void xe_heci_gsc_irq_handler(struct xe_device *xe, u32 iir)
ret = generic_handle_irq_safe(xe->heci_gsc.irq);
if (ret)
- drm_err_ratelimited(&xe->drm, "error handling GSC irq: %d\n", ret);
+ xe_err_ratelimited(xe, "GSC: irq handling failed (%pe)\n", ERR_PTR(ret));
}
void xe_heci_csc_irq_handler(struct xe_device *xe, u32 iir)
@@ -235,7 +234,7 @@ void xe_heci_csc_irq_handler(struct xe_device *xe, u32 iir)
return;
if (!xe->info.has_heci_cscfi) {
- drm_warn_once(&xe->drm, "CSC irq: not supported");
+ xe_warn_once(xe, "CSC: unexpected irq %#x\n", iir);
return;
}
@@ -244,5 +243,5 @@ void xe_heci_csc_irq_handler(struct xe_device *xe, u32 iir)
ret = generic_handle_irq_safe(xe->heci_gsc.irq);
if (ret)
- drm_err_ratelimited(&xe->drm, "error handling GSC irq: %d\n", ret);
+ xe_err_ratelimited(xe, "CSC: irq handling failed (%pe)\n", ERR_PTR(ret));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 3/5] drm/xe/i2c: Use xe print functions in xe_i2c.c
2026-06-05 20:40 [PATCH v2 0/5] drm/{i915, xe}: Refactor generic_handle_irq_safe() error messages Jonathan Cavitt
2026-06-05 20:40 ` [PATCH v2 1/5] drm/xe/printk: Add xe_warn_once() Jonathan Cavitt
2026-06-05 20:40 ` [PATCH v2 2/5] drm/xe/heci: Use xe print functions in xe_heci_gsc.c Jonathan Cavitt
@ 2026-06-05 20:40 ` Jonathan Cavitt
2026-06-05 20:40 ` [PATCH v2 4/5] drm/i915: Refactor generic_handle_irq_safe() error messages Jonathan Cavitt
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cavitt @ 2026-06-05 20:40 UTC (permalink / raw)
To: intel-xe, intel-gfx
Cc: saurabhg.gupta, alex.zuo, jonathan.cavitt, raag.jadav,
Michal.Wajdeczko
Update xe_i2c.c to use the xe error reporting helper functions in
xe_printk.h instead of directly calling the associated drm print
functions from drm_print.h
Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
---
drivers/gpu/drm/xe/xe_i2c.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_i2c.c b/drivers/gpu/drm/xe/xe_i2c.c
index 706783863d07..148e82e01ae8 100644
--- a/drivers/gpu/drm/xe/xe_i2c.c
+++ b/drivers/gpu/drm/xe/xe_i2c.c
@@ -5,7 +5,6 @@
* Copyright (C) 2025 Intel Corporation.
*/
-#include <drm/drm_print.h>
#include <linux/array_size.h>
#include <linux/container_of.h>
#include <linux/device.h>
@@ -30,6 +29,7 @@
#include "xe_device.h"
#include "xe_i2c.h"
#include "xe_mmio.h"
+#include "xe_printk.h"
#include "xe_sriov.h"
#include "xe_survivability_mode.h"
@@ -285,7 +285,7 @@ void xe_i2c_pm_suspend(struct xe_device *xe)
return;
xe_mmio_rmw32(mmio, I2C_CONFIG_PMCSR, PCI_PM_CTRL_STATE_MASK, (__force u32)PCI_D3hot);
- drm_dbg(&xe->drm, "pmcsr: 0x%08x\n", xe_mmio_read32(mmio, I2C_CONFIG_PMCSR));
+ xe_dbg(xe, "pmcsr: 0x%08x\n", xe_mmio_read32(mmio, I2C_CONFIG_PMCSR));
}
void xe_i2c_pm_resume(struct xe_device *xe, bool d3cold)
@@ -299,7 +299,7 @@ void xe_i2c_pm_resume(struct xe_device *xe, bool d3cold)
xe_mmio_rmw32(mmio, I2C_CONFIG_CMD, 0, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
xe_mmio_rmw32(mmio, I2C_CONFIG_PMCSR, PCI_PM_CTRL_STATE_MASK, (__force u32)PCI_D0);
- drm_dbg(&xe->drm, "pmcsr: 0x%08x\n", xe_mmio_read32(mmio, I2C_CONFIG_PMCSR));
+ xe_dbg(xe, "pmcsr: 0x%08x\n", xe_mmio_read32(mmio, I2C_CONFIG_PMCSR));
}
static void xe_i2c_remove(void *data)
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 4/5] drm/i915: Refactor generic_handle_irq_safe() error messages
2026-06-05 20:40 [PATCH v2 0/5] drm/{i915, xe}: Refactor generic_handle_irq_safe() error messages Jonathan Cavitt
` (2 preceding siblings ...)
2026-06-05 20:40 ` [PATCH v2 3/5] drm/xe/i2c: Use xe print functions in xe_i2c.c Jonathan Cavitt
@ 2026-06-05 20:40 ` Jonathan Cavitt
2026-06-05 20:40 ` [PATCH v2 5/5] drm/xe/i2c: Report i2c irq handler issue Jonathan Cavitt
2026-06-05 21:01 ` ✗ Fi.CI.BUILD: failure for drm/{i915, xe}: Refactor generic_handle_irq_safe() error messages (rev3) Patchwork
5 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cavitt @ 2026-06-05 20:40 UTC (permalink / raw)
To: intel-xe, intel-gfx
Cc: saurabhg.gupta, alex.zuo, jonathan.cavitt, raag.jadav,
Michal.Wajdeczko
Refactor all error messages resulting from generic_handle_irq_safe()
failures in I915 for clarity.
v2:
- Use drm_err_ratelimited() correctly (jcavitt)
v3:
- Use xe_err_ratelimited() instead (Jadav)
- Split into patch series (jcavitt)
v4:
- Use suggested phrasing (Wajdeczko)
Suggested-by: Raag Jadav <raag.jadav@intel.com>
Suggested-by: Michal Wajdeczko <Michal.Wajdeczko@intel.com>
Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
---
drivers/gpu/drm/i915/display/intel_lpe_audio.c | 2 +-
drivers/gpu/drm/i915/gt/intel_gsc.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_lpe_audio.c b/drivers/gpu/drm/i915/display/intel_lpe_audio.c
index 022ad18044bf..ff2cf479d8e1 100644
--- a/drivers/gpu/drm/i915/display/intel_lpe_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_lpe_audio.c
@@ -265,7 +265,7 @@ void intel_lpe_audio_irq_handler(struct intel_display *display)
ret = generic_handle_irq_safe(display->audio.lpe.irq);
if (ret)
drm_err_ratelimited(display->drm,
- "error handling LPE audio irq: %d\n", ret);
+ "LPE audio: irq handling failed (%pe)\n", ERR_PTR(ret));
}
/**
diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c b/drivers/gpu/drm/i915/gt/intel_gsc.c
index 050d909fb4f8..c3a9b7d81e3d 100644
--- a/drivers/gpu/drm/i915/gt/intel_gsc.c
+++ b/drivers/gpu/drm/i915/gt/intel_gsc.c
@@ -286,7 +286,7 @@ static void gsc_irq_handler(struct intel_gt *gt, unsigned int intf_id)
ret = generic_handle_irq_safe(gt->gsc.intf[intf_id].irq);
if (ret)
- gt_err_ratelimited(gt, "error handling GSC irq: %d\n", ret);
+ gt_err_ratelimited(gt, "GSC: irq handling failed (%pe)\n", PTR_ERR(ret));
}
void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir)
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 5/5] drm/xe/i2c: Report i2c irq handler issue
2026-06-05 20:40 [PATCH v2 0/5] drm/{i915, xe}: Refactor generic_handle_irq_safe() error messages Jonathan Cavitt
` (3 preceding siblings ...)
2026-06-05 20:40 ` [PATCH v2 4/5] drm/i915: Refactor generic_handle_irq_safe() error messages Jonathan Cavitt
@ 2026-06-05 20:40 ` Jonathan Cavitt
2026-06-05 21:01 ` ✗ Fi.CI.BUILD: failure for drm/{i915, xe}: Refactor generic_handle_irq_safe() error messages (rev3) Patchwork
5 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cavitt @ 2026-06-05 20:40 UTC (permalink / raw)
To: intel-xe, intel-gfx
Cc: saurabhg.gupta, alex.zuo, jonathan.cavitt, raag.jadav,
Michal.Wajdeczko
Error logging is expected but not included in xe_i2c_irq_handler() for
generic_handle_irq_safe(), so add error logging there.
This issue was caught by static analysis.
v2:
- Reword error message (Wajdeczko)
Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Cc: Raag Jadav <raag.jadav@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
---
drivers/gpu/drm/xe/xe_i2c.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_i2c.c b/drivers/gpu/drm/xe/xe_i2c.c
index 148e82e01ae8..84171021e6ea 100644
--- a/drivers/gpu/drm/xe/xe_i2c.c
+++ b/drivers/gpu/drm/xe/xe_i2c.c
@@ -177,12 +177,15 @@ static bool xe_i2c_irq_present(struct xe_device *xe)
void xe_i2c_irq_handler(struct xe_device *xe, u32 master_ctl)
{
struct xe_mmio *mmio = xe_root_tile_mmio(xe);
+ int ret;
if (!(master_ctl & I2C_IRQ) || !xe_i2c_irq_present(xe))
return;
/* Forward interrupt to I2C adapter */
- generic_handle_irq_safe(xe->i2c->adapter_irq);
+ ret = generic_handle_irq_safe(xe->i2c->adapter_irq);
+ if (ret)
+ xe_err_ratelimited(xe, "I2C: irq handling failure (%pe)\n", ERR_PTR(ret));
/* Deassert after I2C adapter clears the interrupt */
xe_mmio_rmw32(mmio, I2C_CONFIG_CMD, 0, PCI_COMMAND_INTX_DISABLE);
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* ✗ Fi.CI.BUILD: failure for drm/{i915, xe}: Refactor generic_handle_irq_safe() error messages (rev3)
2026-06-05 20:40 [PATCH v2 0/5] drm/{i915, xe}: Refactor generic_handle_irq_safe() error messages Jonathan Cavitt
` (4 preceding siblings ...)
2026-06-05 20:40 ` [PATCH v2 5/5] drm/xe/i2c: Report i2c irq handler issue Jonathan Cavitt
@ 2026-06-05 21:01 ` Patchwork
5 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2026-06-05 21:01 UTC (permalink / raw)
To: Jonathan Cavitt; +Cc: intel-gfx
== Series Details ==
Series: drm/{i915, xe}: Refactor generic_handle_irq_safe() error messages (rev3)
URL : https://patchwork.freedesktop.org/series/167911/
State : failure
== Summary ==
Error: make failed
DESCEND objtool
INSTALL libsubcmd_headers
CC [M] drivers/gpu/drm/i915/gt/intel_gsc.o
In file included from ./include/linux/device.h:15,
from ./include/linux/auxiliary_bus.h:11,
from ./include/linux/mei_aux.h:8,
from drivers/gpu/drm/i915/gt/intel_gsc.c:7:
drivers/gpu/drm/i915/gt/intel_gsc.c: In function ‘gsc_irq_handler’:
drivers/gpu/drm/i915/gt/intel_gsc.c:289:84: error: passing argument 1 of ‘PTR_ERR’ makes pointer from integer without a cast [-Werror=int-conversion]
289 | gt_err_ratelimited(gt, "GSC: irq handling failed (%pe)\n", PTR_ERR(ret));
| ^~~
| |
| int
./include/linux/dev_printk.h:110:37: note: in definition of macro ‘dev_printk_index_wrap’
110 | _p_func(dev, fmt, ##__VA_ARGS__); \
| ^~~~~~~~~~~
./include/linux/dev_printk.h:215:17: note: in expansion of macro ‘dev_err’
215 | dev_level(dev, fmt, ##__VA_ARGS__); \
| ^~~~~~~~~
./include/linux/dev_printk.h:225:9: note: in expansion of macro ‘dev_level_ratelimited’
225 | dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__)
| ^~~~~~~~~~~~~~~~~~~~~
./include/drm/drm_print.h:615:9: note: in expansion of macro ‘dev_err_ratelimited’
615 | dev_##level##type(__drm_to_dev(drm), "[drm] " fmt, ##__VA_ARGS__)
| ^~~~
./include/drm/drm_print.h:645:9: note: in expansion of macro ‘__drm_printk’
645 | __drm_printk((drm), err, _ratelimited, "*ERROR* " fmt, ##__VA_ARGS__)
| ^~~~~~~~~~~~
./drivers/gpu/drm/i915/gt/intel_gt_print.h:32:9: note: in expansion of macro ‘drm_err_ratelimited’
32 | drm_err_ratelimited(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__)
| ^~~~~~~~~~~~~~~~~~~
drivers/gpu/drm/i915/gt/intel_gsc.c:289:17: note: in expansion of macro ‘gt_err_ratelimited’
289 | gt_err_ratelimited(gt, "GSC: irq handling failed (%pe)\n", PTR_ERR(ret));
| ^~~~~~~~~~~~~~~~~~
In file included from ./include/linux/cleanup.h:6,
from ./include/linux/preempt.h:11,
from ./include/linux/spinlock.h:56,
from ./include/linux/irq.h:14,
from drivers/gpu/drm/i915/gt/intel_gsc.c:6:
./include/linux/err.h:63:61: note: expected ‘const void *’ but argument is of type ‘int’
63 | static inline long __must_check PTR_ERR(__force const void *ptr)
| ~~~~~~~~~~~~^~~
./include/drm/drm_print.h:615:46: error: format ‘%p’ expects argument of type ‘void *’, but argument 4 has type ‘long int’ [-Werror=format=]
615 | dev_##level##type(__drm_to_dev(drm), "[drm] " fmt, ##__VA_ARGS__)
| ^~~~~~~~
./include/linux/dev_printk.h:110:30: note: in definition of macro ‘dev_printk_index_wrap’
110 | _p_func(dev, fmt, ##__VA_ARGS__); \
| ^~~
./include/linux/dev_printk.h:154:56: note: in expansion of macro ‘dev_fmt’
154 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~
./include/linux/dev_printk.h:215:17: note: in expansion of macro ‘dev_err’
215 | dev_level(dev, fmt, ##__VA_ARGS__); \
| ^~~~~~~~~
./include/linux/dev_printk.h:225:9: note: in expansion of macro ‘dev_level_ratelimited’
225 | dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__)
| ^~~~~~~~~~~~~~~~~~~~~
./include/drm/drm_print.h:615:9: note: in expansion of macro ‘dev_err_ratelimited’
615 | dev_##level##type(__drm_to_dev(drm), "[drm] " fmt, ##__VA_ARGS__)
| ^~~~
./include/drm/drm_print.h:645:9: note: in expansion of macro ‘__drm_printk’
645 | __drm_printk((drm), err, _ratelimited, "*ERROR* " fmt, ##__VA_ARGS__)
| ^~~~~~~~~~~~
./drivers/gpu/drm/i915/gt/intel_gt_print.h:32:9: note: in expansion of macro ‘drm_err_ratelimited’
32 | drm_err_ratelimited(&(_gt)->i915->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__)
| ^~~~~~~~~~~~~~~~~~~
drivers/gpu/drm/i915/gt/intel_gsc.c:289:17: note: in expansion of macro ‘gt_err_ratelimited’
289 | gt_err_ratelimited(gt, "GSC: irq handling failed (%pe)\n", PTR_ERR(ret));
| ^~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[6]: *** [scripts/Makefile.build:289: drivers/gpu/drm/i915/gt/intel_gsc.o] Error 1
make[5]: *** [scripts/Makefile.build:548: drivers/gpu/drm/i915] Error 2
make[4]: *** [scripts/Makefile.build:548: drivers/gpu/drm] Error 2
make[3]: *** [scripts/Makefile.build:548: drivers/gpu] Error 2
make[2]: *** [scripts/Makefile.build:548: drivers] Error 2
make[1]: *** [/home/kbuild/kernel/Makefile:2143: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
Build failed, no error log produced
^ permalink raw reply [flat|nested] 7+ messages in thread