From nobody Fri Sep 25 08:46:03 2026 Received: from mail-qk2-f13.google.com (mail-qk2-f13.google.com [74.125.230.205]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 984942236EE for ; Tue, 15 Sep 2026 01:01:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789434079; cv=none; b=HS8N3/q0xpn4dk+GXNsywzAP3jPwRi6LwvphJ0/Ouz2R/USahnTMBTAe2sbSWA8ZYnNosm96Z6hbhNXJuBuzW+mxkBoMZpDKPcxL3FJIFpHcx6ECTVXylcKHPopYH/CbQattPBBorvXviGh477LytM5vRPBBTmeN6y4isAhZJ04= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789434079; c=relaxed/simple; bh=iAb7A5wNgtJCrMo9307qow4ioWDd+SLfoYen1G2IpzU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tSb5G/ft4fvoWfvSVuI+9z31k3UZyQzVO1yz9bK0cMIdCl1N6rOoSoYriYozWKy/2biHfCcm/A0z/zBeCAVu3JUscteVD6xBt8GSPuoOvfCXLLUZlRVUeosrx4Pmf55SCwxcgY2jYEJmqlJtswnRKRlskBZsvVbUT+Fhpt6NNrE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=F92xoZgg; arc=none smtp.client-ip=74.125.230.205 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="F92xoZgg" Received: by mail-qk2-f13.google.com with SMTP id af79cd13be357-93910ca5aa8so316108785a.3 for ; Mon, 14 Sep 2026 18:01:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789434075; x=1790038875; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=DGhLYNsepumqw5u0oBUFEEWpvpdu68HMTUiCLOJMcZE=; b=F92xoZggng1FwhMCkco2EryOwkI+DsEpgg7jsRSPauFpJjtOT00Qbsdj4F6jl6tuyT nn4ZkS3Qhmu83QvMknReLLE/quLouK7DzqLRuDzE2JDeDgMkE4QooVN7bz0dhDbZgzXt xSEUDi9dhM3EUPUuVGI3rHpV+qMFrIPl3G9OjnfYKkvh5edVNJ6i9bNV4BfnewNFufXX I/KpnfhGzxDkV+xPoVumEkGL7op3crTWz1Ky+CLgOPCHvVUjRrL9kUhyFELEekAkpRU5 i6YAwshypsepE0kyexNFtxTJU9tGp2PEvzZdJuy0ts7PTjUldS6a0HPgQT0DD7PCxcAO giFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789434075; x=1790038875; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=DGhLYNsepumqw5u0oBUFEEWpvpdu68HMTUiCLOJMcZE=; b=By1le9SB86JOkw0Y82s/eDZQGxXig1338cuEUlj6F63DLUcOjUBy5fh9YLFP9x/wEo NtG7n+Fjv8i23uFTNeiWzUBBte9ylJJhXeUhU/r/WM3wCFwvnxUKPNzVs4SZTAKdcQ/c aPyUOKSn9c4J0iZCF1dWQ/5JnKkvrctVmEES3tFagwu5b0FaHn0QFqNzaRXED+pxHufx GR3rMz8lxZhkagTtRPBpH+GSObFbjWhKVgEX/Dd+QReQm69DGSmRt/AEkJMHy71bLDUk UOjJyLVYaXOpC61cQRipndPXoFpn8DrYU/+wSSNqKTnY3QaXBBcNXG8XvBRmzcT7qh4I FalA== X-Forwarded-Encrypted: i=1; AKwUvBwiuJ1oEJnt8b/hRijYsr1grtCEkNzR4itO/q1RH5YoR9ziDMgd1Ln5EViQVsSdEdJCJU1SXlhjwbvk8ZU=@vger.kernel.org X-Gm-Message-State: AFuF++njz5t6QESzlTt8xZakyV5U9u9d2z5d1TwwsOPGjWyVwIjvTqH2 RbXmRpDoj+kQvOcQ4xoDt40gXlXohFQWtFN7dQeZlaIoQd8G9pxSHguE X-Gm-Gg: AYBFou2BeFjeB3KzbQIhsoNPk1a/YMYOgUABM7tq8J8GyHFZ06WHcWVTz3eQMwGF6gU oLsJb7ziZQ336xCf7X43n6IpT9aQesmyzdPrGNRHLx+PKKcrD5S4NTDBmhpcuB7zWvCK7qnDsdo uVMRpxST/oL+jCsbpbj3U9IK0E7n8sn6PbA9lCCL1Waa4IZyZv9DjoEwj79mHvGUwM9tJbPslYQ EokSI8fARy8xg9YlxBE8icTL1SzK482HQu1dC/opmohAe8AUpUgkCI3L7sFGc9dibTAJScGTVn6 3IS5C2ihmZs7z0oUuqdBaS5XMyYxFqpMWbeced3T2NYBrjIrCbTYQ69PpRsdKA1zTEVqw8uf/C0 HKscvZC7dRV9l9df2CHEN+A+yldVr6Q3wGZPuAQz7rj+vR67uIQXypc8tHVKbE0GcIV/YMEZoJt ZzEXuPnRKy+DvII3H8SlqPCW9OWYpDpdLmsYhwRCRMKaehsdDK+cKAtp6lsVZea2Zn09c2w90j1 aoHkjRK2w8PPEPNkxjy5ymK+naJlSUPLeaM4JaYLE33GhzS X-Received: by 2002:a05:620a:2702:b0:92e:71bb:d1c0 with SMTP id af79cd13be357-93a297ee80cmr821092685a.15.1789434074608; Mon, 14 Sep 2026 18:01:14 -0700 (PDT) Received: from father (76-224-4-192.lightspeed.clmboh.sbcglobal.net. [76.224.4.192]) by smtp.gmail.com with ESMTPSA id af79cd13be357-939e7f18467sm1147705885a.11.2026.09.14.18.01.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 18:01:14 -0700 (PDT) From: Ben Hoff To: linux-media@vger.kernel.org Cc: mchehab@kernel.org, hverkuil@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/3] media: hws: remove debug controls and lifecycle tracing Date: Mon, 14 Sep 2026 21:01:09 -0400 Message-ID: <20260915010111.101551-2-hoff.benjamin.k@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260915010111.101551-1-hoff.benjamin.k@gmail.com> References: <20260915010111.101551-1-hoff.benjamin.k@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Remove the toggle_debug and dma_window_verify module parameters, register snapshots, and routine capture and lifecycle messages. These diagnostics add register reads to interrupt and format paths, including IRQ debug reads before the suspended-state check. Keep error reporting and the posted-write flush needed before arming DMA. This also removes diagnostic MMIO accesses that would otherwise bypass the suspended-handler guard in the following shared-IRQ fix. Assisted-by: Codex:GPT-6 Signed-off-by: Ben Hoff --- drivers/media/pci/hws/hws_irq.c | 74 ------------- drivers/media/pci/hws/hws_pci.c | 145 +------------------------ drivers/media/pci/hws/hws_v4l2_ioctl.c | 14 --- drivers/media/pci/hws/hws_video.c | 125 +-------------------- 4 files changed, 4 insertions(+), 354 deletions(-) diff --git a/drivers/media/pci/hws/hws_irq.c b/drivers/media/pci/hws/hws_ir= q.c index eebb4b8a5cd5..787c9e498799 100644 --- a/drivers/media/pci/hws/hws_irq.c +++ b/drivers/media/pci/hws/hws_irq.c @@ -16,38 +16,23 @@ =20 #define MAX_INT_LOOPS 100 =20 -static bool hws_toggle_debug; -module_param_named(toggle_debug, hws_toggle_debug, bool, 0644); -MODULE_PARM_DESC(toggle_debug, - "Read toggle registers in IRQ handler for debug logging"); - static int hws_arm_next(struct hws_pcie_dev *hws, u32 ch) { struct hws_video *v =3D &hws->video[ch]; unsigned long flags; struct hwsvideo_buffer *buf; =20 - dev_dbg(&hws->pdev->dev, - "arm_next(ch=3D%u): stop=3D%d cap=3D%d queued=3D%d\n", - ch, READ_ONCE(v->stop_requested), READ_ONCE(v->cap_active), - !list_empty(&v->capture_queue)); - if (READ_ONCE(hws->suspended)) { - dev_dbg(&hws->pdev->dev, "arm_next(ch=3D%u): suspended\n", ch); return -EBUSY; } =20 if (READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active)) { - dev_dbg(&hws->pdev->dev, - "arm_next(ch=3D%u): stop=3D%d cap=3D%d -> cancel\n", ch, - v->stop_requested, v->cap_active); return -ECANCELED; } =20 spin_lock_irqsave(&v->irq_lock, flags); if (list_empty(&v->capture_queue)) { spin_unlock_irqrestore(&v->irq_lock, flags); - dev_dbg(&hws->pdev->dev, "arm_next(ch=3D%u): queue empty\n", ch); return -EAGAIN; } =20 @@ -57,8 +42,6 @@ static int hws_arm_next(struct hws_pcie_dev *hws, u32 ch) v->queued_count--; v->active =3D buf; spin_unlock_irqrestore(&v->irq_lock, flags); - dev_dbg(&hws->pdev->dev, "arm_next(ch=3D%u): picked buffer %p\n", ch, - buf); =20 /* Publish descriptor(s) before doorbell/MMIO kicks. */ wmb(); @@ -67,8 +50,6 @@ static int hws_arm_next(struct hws_pcie_dev *hws, u32 ch) if (READ_ONCE(hws->suspended)) { unsigned long f; =20 - dev_dbg(&hws->pdev->dev, - "arm_next(ch=3D%u): suspended after pick\n", ch); spin_lock_irqsave(&v->irq_lock, f); if (v->active) { list_add(&buf->list, &v->capture_queue); @@ -88,8 +69,6 @@ static int hws_arm_next(struct hws_pcie_dev *hws, u32 ch) hws->bar0_base + HWS_REG_DMA_ADDR(ch)); } =20 - dev_dbg(&hws->pdev->dev, "arm_next(ch=3D%u): programmed buffer %p\n", ch, - buf); spin_lock_irqsave(&v->irq_lock, flags); hws_prime_next_locked(v); spin_unlock_irqrestore(&v->irq_lock, flags); @@ -104,16 +83,8 @@ static void hws_video_handle_vdone(struct hws_video *v) unsigned long flags; bool promoted =3D false; =20 - dev_dbg(&hws->pdev->dev, - "bh_video(ch=3D%u): stop=3D%d cap=3D%d active=3D%p\n", - ch, READ_ONCE(v->stop_requested), READ_ONCE(v->cap_active), - v->active); - int ret; =20 - dev_dbg(&hws->pdev->dev, - "bh_video(ch=3D%u): entry stop=3D%d cap=3D%d\n", ch, - v->stop_requested, v->cap_active); if (READ_ONCE(hws->suspended)) return; =20 @@ -149,10 +120,6 @@ static void hws_video_handle_vdone(struct hws_video *v) =20 vb2v->sequence =3D (u32)atomic_inc_return(&v->sequence_number); vb2v->vb2_buf.timestamp =3D ktime_get_ns(); - dev_dbg(&hws->pdev->dev, - "bh_video(ch=3D%u): DONE buf=3D%p seq=3D%u half_seen=3D%d toggle=3D%u\n= ", - ch, done, vb2v->sequence, v->half_seen, - v->last_buf_half_toggle); =20 if (!promoted) v->active =3D NULL; /* channel no longer owns this buffer */ @@ -163,9 +130,6 @@ static void hws_video_handle_vdone(struct hws_video *v) return; =20 if (promoted) { - dev_dbg(&hws->pdev->dev, - "bh_video(ch=3D%u): promoted pre-armed buffer active=3D%p\n", - ch, v->active); spin_lock_irqsave(&v->irq_lock, flags); hws_prime_next_locked(v); spin_unlock_irqrestore(&v->irq_lock, flags); @@ -176,13 +140,8 @@ static void hws_video_handle_vdone(struct hws_video *v) /* 2) Immediately arm the next queued buffer (if present) */ ret =3D hws_arm_next(hws, ch); if (ret =3D=3D -EAGAIN) { - dev_dbg(&hws->pdev->dev, - "bh_video(ch=3D%u): no queued buffer to arm\n", ch); return; } - dev_dbg(&hws->pdev->dev, - "bh_video(ch=3D%u): armed next buffer, active=3D%p\n", ch, - v->active); /* On success the engine now points at v->active's DMA address */ } =20 @@ -191,14 +150,6 @@ irqreturn_t hws_irq_handler(int irq, void *info) struct hws_pcie_dev *pdx =3D info; u32 int_state; =20 - dev_dbg(&pdx->pdev->dev, "irq: entry\n"); - if (pdx->bar0_base) { - dev_dbg(&pdx->pdev->dev, - "irq: INT_EN=3D0x%08x INT_STATUS=3D0x%08x\n", - readl(pdx->bar0_base + INT_EN_REG_BASE), - readl(pdx->bar0_base + HWS_REG_INT_STATUS)); - } - /* Fast path: if suspended, quietly ack and exit */ if (READ_ONCE(pdx->suspended)) { int_state =3D readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS); @@ -210,12 +161,8 @@ irqreturn_t hws_irq_handler(int irq, void *info) } int_state =3D readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS); if (!int_state || int_state =3D=3D 0xFFFFFFFF) { - dev_dbg(&pdx->pdev->dev, - "irq: spurious or device-gone int_state=3D0x%08x\n", - int_state); return IRQ_NONE; } - dev_dbg(&pdx->pdev->dev, "irq: entry INT_STATUS=3D0x%08x\n", int_state); =20 /* Loop until all pending bits are serviced (max 100 iterations) */ for (u32 cnt =3D 0; int_state && cnt < MAX_INT_LOOPS; ++cnt) { @@ -227,27 +174,9 @@ irqreturn_t hws_irq_handler(int irq, void *info) =20 if (READ_ONCE(pdx->video[ch].cap_active) && !READ_ONCE(pdx->video[ch].stop_requested)) { - if (hws_toggle_debug) { - u32 toggle =3D - readl_relaxed(pdx->bar0_base + - HWS_REG_VBUF_TOGGLE(ch)) & 0x01; - WRITE_ONCE(pdx->video[ch].last_buf_half_toggle, - toggle); - } dma_rmb(); WRITE_ONCE(pdx->video[ch].half_seen, true); - dev_dbg(&pdx->pdev->dev, - "irq: VDONE ch=3D%u toggle=3D%u handling inline (cap=3D%d)\n", - ch, - READ_ONCE(pdx->video[ch].last_buf_half_toggle), - READ_ONCE(pdx->video[ch].cap_active)); hws_video_handle_vdone(&pdx->video[ch]); - } else { - dev_dbg(&pdx->pdev->dev, - "irq: VDONE ch=3D%u ignored (cap=3D%d stop=3D%d)\n", - ch, - READ_ONCE(pdx->video[ch].cap_active), - READ_ONCE(pdx->video[ch].stop_requested)); } =20 writel(vbit, pdx->bar0_base + HWS_REG_INT_STATUS); @@ -256,9 +185,6 @@ irqreturn_t hws_irq_handler(int irq, void *info) =20 /* Re-read in case new interrupt bits popped while processing */ int_state =3D readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS); - dev_dbg(&pdx->pdev->dev, - "irq: loop cnt=3D%u new INT_STATUS=3D0x%08x\n", cnt, - int_state); if (cnt + 1 =3D=3D MAX_INT_LOOPS) dev_warn_ratelimited(&pdx->pdev->dev, "IRQ storm? status=3D0x%08x\n", diff --git a/drivers/media/pci/hws/hws_pci.c b/drivers/media/pci/hws/hws_pc= i.c index f06e60dc2ee6..65b32fac6d1a 100644 --- a/drivers/media/pci/hws/hws_pci.c +++ b/drivers/media/pci/hws/hws_pci.c @@ -27,11 +27,6 @@ #define HWS_BUSY_POLL_DELAY_US 10 #define HWS_BUSY_POLL_TIMEOUT_US 1000000 =20 -static unsigned long long hws_elapsed_us(u64 start_ns) -{ - return div_u64(ktime_get_mono_fast_ns() - start_ns, 1000); -} - /* register layout inside HWS_REG_DEVICE_INFO */ #define DEVINFO_VER GENMASK(15, 8) #define DEVINFO_SUBVER GENMASK(23, 16) @@ -139,38 +134,6 @@ static void hws_configure_hardware_capabilities(struct= hws_pcie_dev *hdev) =20 static void hws_stop_device(struct hws_pcie_dev *hws); =20 -static void hws_log_lifecycle_snapshot(struct hws_pcie_dev *hws, - const char *action, - const char *phase) -{ - struct device *dev; - u32 int_en, int_status, vcap, sys_status, dec_mode; - - if (!hws || !hws->pdev) - return; - - dev =3D &hws->pdev->dev; - if (!hws->bar0_base) { - dev_dbg(dev, - "lifecycle:%s:%s bar0-unmapped suspended=3D%d start_run=3D%d pci_lost= =3D%d irq=3D%d\n", - action, phase, READ_ONCE(hws->suspended), hws->start_run, - hws->pci_lost, hws->irq); - return; - } - - int_en =3D readl(hws->bar0_base + INT_EN_REG_BASE); - int_status =3D readl(hws->bar0_base + HWS_REG_INT_STATUS); - vcap =3D readl(hws->bar0_base + HWS_REG_VCAP_ENABLE); - sys_status =3D readl(hws->bar0_base + HWS_REG_SYS_STATUS); - dec_mode =3D readl(hws->bar0_base + HWS_REG_DEC_MODE); - - dev_dbg(dev, - "lifecycle:%s:%s suspended=3D%d start_run=3D%d pci_lost=3D%d irq=3D%d IN= T_EN=3D0x%08x INT_STATUS=3D0x%08x VCAP=3D0x%08x SYS=3D0x%08x DEC=3D0x%08x\n= ", - action, phase, READ_ONCE(hws->suspended), hws->start_run, - hws->pci_lost, hws->irq, int_en, int_status, vcap, - sys_status, dec_mode); -} - static int read_chip_id(struct hws_pcie_dev *hdev) { u32 reg; @@ -197,11 +160,6 @@ static int read_chip_id(struct hws_pcie_dev *hdev) =20 hws_configure_hardware_capabilities(hdev); =20 - dev_info(&hdev->pdev->dev, - "chip detected: ver=3D%u subver=3D%u port=3D%u yv12=3D%u\n", - hdev->device_ver, hdev->sub_ver, hdev->port_id, - hdev->support_yv12); - return 0; } =20 @@ -228,7 +186,6 @@ static int main_ks_thread_handle(void *data) schedule_timeout_interruptible(msecs_to_jiffies(1000)); } =20 - dev_dbg(&pdx->pdev->dev, "%s: exiting\n", __func__); return 0; } =20 @@ -236,22 +193,14 @@ static void hws_stop_kthread_action(void *data) { struct hws_pcie_dev *hws =3D data; struct task_struct *t; - u64 start_ns; =20 if (!hws) return; =20 t =3D READ_ONCE(hws->main_task); if (!IS_ERR_OR_NULL(t)) { - start_ns =3D ktime_get_mono_fast_ns(); - dev_dbg(&hws->pdev->dev, - "lifecycle:kthread-stop:begin task=3D%s[%d]\n", - t->comm, t->pid); WRITE_ONCE(hws->main_task, NULL); kthread_stop(t); - dev_dbg(&hws->pdev->dev, - "lifecycle:kthread-stop:done (%lluus)\n", - hws_elapsed_us(start_ns)); } } =20 @@ -424,8 +373,6 @@ static int hws_probe(struct pci_dev *pdev, const struct= pci_device_id *pci_id) if (ret) return dev_err_probe(&pdev->dev, ret, "No suitable DMA configuration\n"); - } else { - dev_dbg(&pdev->dev, "Using 64-bit DMA mask\n"); } =20 /* 3) Apply optional PCIe tuning. */ @@ -436,8 +383,6 @@ static int hws_probe(struct pci_dev *pdev, const struct= pci_device_id *pci_id) =20 /* 4) Identify chip & capabilities */ read_chip_id(hws); - dev_info(&pdev->dev, "Device VID=3D0x%04x DID=3D0x%04x\n", - pdev->vendor, pdev->device); hws_init_video_sys(hws, false); =20 /* 5) Init channels (video state, locks, vb2, ctrls) */ @@ -462,7 +407,6 @@ static int hws_probe(struct pci_dev *pdev, const struct= pci_device_id *pci_id) irqf =3D IRQF_SHARED; irq =3D pdev->irq; hws->irq =3D irq; - dev_info(&pdev->dev, "IRQ mode: legacy INTx (shared), irq=3D%d\n", irq); =20 /* B) Mask the device's global/bridge gate (INT_EN_REG_BASE) */ hws_irq_mask_gate(hws); @@ -485,13 +429,10 @@ static int hws_probe(struct pci_dev *pdev, const stru= ct pci_device_id *pci_id) ctl_reg |=3D HWS_CTL_IRQ_ENABLE_BIT; writel(ctl_reg, hws->bar0_base + HWS_REG_CTL); (void)readl(hws->bar0_base + HWS_REG_CTL); /* flush write */ - dev_info(&pdev->dev, "Global IRQ enable bit set in control register\n"); } =20 /* F) Open the global gate just like legacy did */ hws_irq_unmask_gate(hws); - dev_info(&pdev->dev, "INT_EN_GATE readback=3D0x%08x\n", - readl(hws->bar0_base + INT_EN_REG_BASE)); =20 /* 11) Register V4L2 */ ret =3D hws_video_register(hws); @@ -515,8 +456,6 @@ static int hws_probe(struct pci_dev *pdev, const struct= pci_device_id *pci_id) goto err_unregister_va; /* reset already stopped the thread */ } =20 - /* 13) Final: show the line is armed */ - dev_info(&pdev->dev, "irq handler installed on irq=3D%d\n", irq); return 0; =20 err_unregister_va: @@ -558,7 +497,6 @@ static void hws_stop_dsp(struct hws_pcie_dev *hws) =20 /* Read the decoder mode/status register */ status =3D readl(hws->bar0_base + HWS_REG_DEC_MODE); - dev_dbg(&hws->pdev->dev, "%s: status=3D0x%08x\n", __func__, status); =20 /* If the device looks unplugged/stuck, bail out */ if (status =3D=3D 0xFFFFFFFF) @@ -593,7 +531,6 @@ static void hws_drain_after_stop(struct hws_pcie_dev *h= ws) { u32 ackmask =3D 0; unsigned int i; - u64 start_ns =3D ktime_get_mono_fast_ns(); =20 /* Mask device enables: no new DMA starts. */ writel(0x0, hws->bar0_base + HWS_REG_VCAP_ENABLE); @@ -613,23 +550,17 @@ static void hws_drain_after_stop(struct hws_pcie_dev = *hws) /* Ensure no hard IRQ is still running. */ if (hws->irq >=3D 0) synchronize_irq(hws->irq); - - dev_dbg(&hws->pdev->dev, "lifecycle:drain-after-stop:done (%lluus)\n", - hws_elapsed_us(start_ns)); } =20 static void hws_stop_device(struct hws_pcie_dev *hws) { u32 status =3D readl(hws->bar0_base + HWS_REG_SYS_STATUS); - u64 start_ns =3D ktime_get_mono_fast_ns(); bool live =3D status !=3D 0xFFFFFFFF; =20 - dev_dbg(&hws->pdev->dev, "%s: status=3D0x%08x\n", __func__, status); if (!live) { hws->pci_lost =3D true; goto out; } - hws_log_lifecycle_snapshot(hws, "stop-device", "begin"); =20 /* Make ISR/BH a no-op, then drain engines/IRQ. */ hws_publish_stop_flags(hws); @@ -640,13 +571,6 @@ static void hws_stop_device(struct hws_pcie_dev *hws) =20 out: hws->start_run =3D false; - if (live) - hws_log_lifecycle_snapshot(hws, "stop-device", "end"); - else - dev_dbg(&hws->pdev->dev, "lifecycle:stop-device:device-lost\n"); - dev_dbg(&hws->pdev->dev, "lifecycle:stop-device:done (%lluus)\n", - hws_elapsed_us(start_ns)); - dev_dbg(&hws->pdev->dev, "%s: complete\n", __func__); } =20 static int hws_quiesce_for_transition(struct hws_pcie_dev *hws, @@ -654,40 +578,20 @@ static int hws_quiesce_for_transition(struct hws_pcie= _dev *hws, bool stop_thread) { struct device *dev =3D &hws->pdev->dev; - u64 start_ns =3D ktime_get_mono_fast_ns(); - u64 step_ns; int vret; =20 - hws_log_lifecycle_snapshot(hws, action, "begin"); - - step_ns =3D ktime_get_mono_fast_ns(); hws_block_hotpaths(hws); - dev_dbg(dev, "lifecycle:%s:block-hotpaths (%lluus)\n", action, - hws_elapsed_us(step_ns)); - hws_log_lifecycle_snapshot(hws, action, "blocked"); =20 if (stop_thread) { - step_ns =3D ktime_get_mono_fast_ns(); hws_stop_kthread_action(hws); - dev_dbg(dev, "lifecycle:%s:stop-kthread (%lluus)\n", action, - hws_elapsed_us(step_ns)); } =20 - step_ns =3D ktime_get_mono_fast_ns(); vret =3D hws_video_quiesce(hws, action); - dev_dbg(dev, "lifecycle:%s:video-quiesce ret=3D%d (%lluus)\n", action, - vret, hws_elapsed_us(step_ns)); if (vret) dev_warn(dev, "lifecycle:%s video quiesce returned %d\n", action, vret); =20 - step_ns =3D ktime_get_mono_fast_ns(); hws_stop_device(hws); - dev_dbg(dev, "lifecycle:%s:stop-device (%lluus)\n", action, - hws_elapsed_us(step_ns)); - hws_log_lifecycle_snapshot(hws, action, "end"); - dev_dbg(dev, "lifecycle:%s:quiesce-done ret=3D%d (%lluus)\n", action, - vret, hws_elapsed_us(start_ns)); =20 return vret; } @@ -695,15 +599,10 @@ static int hws_quiesce_for_transition(struct hws_pcie= _dev *hws, static void hws_remove(struct pci_dev *pdev) { struct hws_pcie_dev *hws =3D pci_get_drvdata(pdev); - u64 start_ns; =20 if (!hws) return; =20 - start_ns =3D ktime_get_mono_fast_ns(); - dev_info(&pdev->dev, "lifecycle:remove begin\n"); - hws_log_lifecycle_snapshot(hws, "remove", "begin"); - /* Stop the monitor thread before tearing down V4L2/vb2 objects. */ hws_block_hotpaths(hws); hws_stop_kthread_action(hws); @@ -717,9 +616,6 @@ static void hws_remove(struct pci_dev *pdev) /* Release seeded DMA buffers */ hws_free_seed_buffers(hws); /* kthread is stopped by the devm action registered in probe. */ - hws_log_lifecycle_snapshot(hws, "remove", "end"); - dev_info(&pdev->dev, "lifecycle:remove done (%lluus)\n", - hws_elapsed_us(start_ns)); } =20 #ifdef CONFIG_PM_SLEEP @@ -727,22 +623,13 @@ static int hws_pm_suspend(struct device *dev) { struct pci_dev *pdev =3D to_pci_dev(dev); struct hws_pcie_dev *hws =3D pci_get_drvdata(pdev); - int vret; - u64 start_ns =3D ktime_get_mono_fast_ns(); - u64 step_ns; =20 - dev_info(dev, "lifecycle:pm_suspend begin\n"); - vret =3D hws_quiesce_for_transition(hws, "pm_suspend", false); + hws_quiesce_for_transition(hws, "pm_suspend", false); =20 - step_ns =3D ktime_get_mono_fast_ns(); pci_save_state(pdev); pci_clear_master(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); - dev_dbg(dev, "lifecycle:pm_suspend:pci-d3hot (%lluus)\n", - hws_elapsed_us(step_ns)); - dev_info(dev, "lifecycle:pm_suspend done ret=3D%d (%lluus)\n", vret, - hws_elapsed_us(start_ns)); =20 return 0; } @@ -752,13 +639,8 @@ static int hws_pm_resume(struct device *dev) struct pci_dev *pdev =3D to_pci_dev(dev); struct hws_pcie_dev *hws =3D pci_get_drvdata(pdev); int ret; - u64 start_ns =3D ktime_get_mono_fast_ns(); - u64 step_ns; - - dev_info(dev, "lifecycle:pm_resume begin\n"); =20 /* Back to D0 and re-enable the function */ - step_ns =3D ktime_get_mono_fast_ns(); pci_set_power_state(pdev, PCI_D0); =20 ret =3D pci_enable_device(pdev); @@ -768,39 +650,25 @@ static int hws_pm_resume(struct device *dev) } pci_restore_state(pdev); pci_set_master(pdev); - dev_dbg(dev, "lifecycle:pm_resume:pci-enable (%lluus)\n", - hws_elapsed_us(step_ns)); =20 /* Reapply any PCIe tuning lost across D3 */ enable_pcie_relaxed_ordering(pdev); =20 /* Reinitialize chip-side capabilities / registers */ - step_ns =3D ktime_get_mono_fast_ns(); read_chip_id(hws); /* Re-seed BAR remaps/DMA windows and restart the capture core */ hws_seed_all_channels(hws); hws_init_video_sys(hws, true); hws_irq_clear_pending(hws); - dev_dbg(dev, "lifecycle:pm_resume:chip-reinit (%lluus)\n", - hws_elapsed_us(step_ns)); =20 /* IRQs can be re-enabled now that MMIO is sane */ - step_ns =3D ktime_get_mono_fast_ns(); if (hws->irq >=3D 0) enable_irq(hws->irq); =20 WRITE_ONCE(hws->suspended, false); - dev_dbg(dev, "lifecycle:pm_resume:irq-unsuspend (%lluus)\n", - hws_elapsed_us(step_ns)); =20 /* vb2: nothing mandatory; userspace will STREAMON again when ready */ - step_ns =3D ktime_get_mono_fast_ns(); hws_video_pm_resume(hws); - dev_dbg(dev, "lifecycle:pm_resume:video-resume (%lluus)\n", - hws_elapsed_us(step_ns)); - hws_log_lifecycle_snapshot(hws, "pm_resume", "end"); - dev_info(dev, "lifecycle:pm_resume done (%lluus)\n", - hws_elapsed_us(start_ns)); =20 return 0; } @@ -814,22 +682,13 @@ static SIMPLE_DEV_PM_OPS(hws_pm_ops, hws_pm_suspend, = hws_pm_resume); static void hws_shutdown(struct pci_dev *pdev) { struct hws_pcie_dev *hws =3D pci_get_drvdata(pdev); - int vret =3D 0; - u64 start_ns =3D ktime_get_mono_fast_ns(); - u64 step_ns; =20 if (!hws) return; =20 - dev_info(&pdev->dev, "lifecycle:pci_shutdown begin\n"); - vret =3D hws_quiesce_for_transition(hws, "pci_shutdown", true); + hws_quiesce_for_transition(hws, "pci_shutdown", true); =20 - step_ns =3D ktime_get_mono_fast_ns(); pci_clear_master(pdev); - dev_dbg(&pdev->dev, "lifecycle:pci_shutdown:clear-master (%lluus)\n", - hws_elapsed_us(step_ns)); - dev_info(&pdev->dev, "lifecycle:pci_shutdown done ret=3D%d (%lluus)\n", - vret, hws_elapsed_us(start_ns)); } =20 static struct pci_driver hws_pci_driver =3D { diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.c b/drivers/media/pci/hws= /hws_v4l2_ioctl.c index ce396b7225d2..7169fd048e73 100644 --- a/drivers/media/pci/hws/hws_v4l2_ioctl.c +++ b/drivers/media/pci/hws/hws_v4l2_ioctl.c @@ -794,10 +794,6 @@ int hws_vidioc_try_fmt_vid_cap(struct file *file, void= *fh, struct v4l2_format * if (!max_bpl_hw) return -ERANGE; if (bpl > max_bpl_hw) { - if (pdev) - dev_dbg(&pdev->pdev->dev, - "try_fmt: clamp bpl %u -> %zu due to hw buf cap %zu\n", - bpl, max_bpl_hw, max_frame); bpl =3D (u32)max_bpl_hw; } } @@ -811,11 +807,6 @@ int hws_vidioc_try_fmt_vid_cap(struct file *file, void= *fh, struct v4l2_format * pix->sizeimage =3D (u32)size; /* logical size, not page-aligned */ =20 hws_set_colorimetry_fmt(pix); - if (pdev) - dev_dbg(&pdev->pdev->dev, - "try_fmt: w=3D%u h=3D%u bpl=3D%u size=3D%u field=3D%u\n", - pix->width, pix->height, pix->bytesperline, - pix->sizeimage, pix->field); return 0; } =20 @@ -862,11 +853,6 @@ int hws_vidioc_s_fmt_vid_cap(struct file *file, void *= priv, struct v4l2_format * * hws_calc_sizeimage(vid, vid->pix.width, vid->pix.height, false); */ =20 - dev_dbg(&vid->parent->pdev->dev, - "s_fmt: w=3D%u h=3D%u bpl=3D%u size=3D%u\n", - vid->pix.width, vid->pix.height, vid->pix.bytesperline, - vid->pix.sizeimage); - return 0; } =20 diff --git a/drivers/media/pci/hws/hws_video.c b/drivers/media/pci/hws/hws_= video.c index dbe0fc2a66b5..624c48a63b3b 100644 --- a/drivers/media/pci/hws/hws_video.c +++ b/drivers/media/pci/hws/hws_video.c @@ -44,27 +44,15 @@ static void hws_program_dma_window(struct hws_video *vi= d, dma_addr_t dma); static struct hwsvideo_buffer * hws_take_queued_buffer_locked(struct hws_video *vid); =20 -static unsigned long long hws_elapsed_us(u64 start_ns) -{ - return div_u64(ktime_get_mono_fast_ns() - start_ns, 1000); -} - static inline bool list_node_unlinked(const struct list_head *n) { return n->next =3D=3D LIST_POISON1 || n->prev =3D=3D LIST_POISON2; } =20 -static bool dma_window_verify; -module_param_named(dma_window_verify, dma_window_verify, bool, 0644); -MODULE_PARM_DESC(dma_window_verify, - "Read back DMA window registers after programming (debug)"); - void hws_set_dma_doorbell(struct hws_pcie_dev *hws, unsigned int ch, dma_addr_t dma, const char *tag) { iowrite32(lower_32_bits(dma), hws->bar0_base + HWS_REG_DMA_ADDR(ch)); - dev_dbg(&hws->pdev->dev, "dma_doorbell ch%u: dma=3D0x%llx tag=3D%s\n", ch, - (u64)dma, tag ? tag : ""); } =20 static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma) @@ -111,21 +99,7 @@ static void hws_program_dma_window(struct hws_video *vi= d, dma_addr_t dma) =20 vid->window_valid =3D true; =20 - if (dma_window_verify && wrote) { - u32 r_hi =3D - readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off); - u32 r_lo =3D - readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off + - PCIE_BARADDROFSIZE); - u32 r_base =3D readl(hws->bar0_base + HWS_BUF_BASE_OFF(ch)); - u32 r_half =3D readl(hws->bar0_base + HWS_HALF_SZ_OFF(ch)); - - dev_dbg(&hws->pdev->dev, - "ch%u remap verify: hi=3D0x%08x page_lo=3D0x%08x exp_page=3D0x%08x base= =3D0x%08x exp_base=3D0x%08x half16B=3D0x%08x exp_half=3D0x%08x\n", - ch, r_hi, r_lo, page_lo, r_base, - (ch + 1) * PCIEBAR_AXI_BASE + pci_addr, r_half, - vid->pix.half_size / 16); - } else if (wrote) { + if (wrote) { /* Flush posted writes before arming DMA */ readl_relaxed(hws->bar0_base + HWS_HALF_SZ_OFF(ch)); } @@ -172,9 +146,6 @@ void hws_prime_next_locked(struct hws_video *vid) hws_program_dma_for_addr(hws, vid->channel_index, dma); iowrite32(lower_32_bits(dma), hws->bar0_base + HWS_REG_DMA_ADDR(vid->channel_index)); - dev_dbg(&hws->pdev->dev, - "ch%u pre-armed next buffer %p dma=3D0x%llx\n", - vid->channel_index, next, (u64)dma); } =20 static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag) @@ -312,7 +283,6 @@ int hws_video_init_channel(struct hws_pcie_dev *pdev, i= nt ch) atomic_set(&vid->sequence_number, 0); vid->active =3D NULL; =20 - /* DMA watchdog removed; retain counters for diagnostics */ vid->timeout_count =3D 0; vid->error_count =3D 0; =20 @@ -525,9 +495,6 @@ void hws_enable_video_capture(struct hws_pcie_dev *hws,= unsigned int chan, (void)readl(hws->bar0_base + HWS_REG_VCAP_ENABLE); =20 WRITE_ONCE(hws->video[chan].cap_active, on); - - dev_dbg(&hws->pdev->dev, "vcap %s ch%u (reg=3D0x%08x)\n", - on ? "ON" : "OFF", chan, status); } =20 static void hws_seed_dma_windows(struct hws_pcie_dev *hws) @@ -660,9 +627,6 @@ int hws_check_card_status(struct hws_pcie_dev *hws) =20 /* If RUN/READY bit (bit0) is not set, reinitialize the video core. */ if (!(status & BIT(0))) { - dev_dbg(&hws->pdev->dev, - "SYS_STATUS not ready (0x%08x), reinitializing\n", - status); hws_init_video_sys(hws, true); } =20 @@ -743,18 +707,13 @@ static bool hws_read_active_state(struct hws_pcie_dev= *pdx, unsigned int ch, static void handle_hwv2_path(struct hws_pcie_dev *hws, unsigned int ch) { struct hws_video *vid; - u32 reg, in_fps, cur_out_res, want_out_res; + u32 reg, cur_out_res, want_out_res; =20 if (!hws || !hws->bar0_base || ch >=3D hws->max_channels) return; =20 vid =3D &hws->video[ch]; =20 - /* 1) Input frame rate (read-only; log or export via debugfs if wanted) */ - in_fps =3D readl(hws->bar0_base + HWS_REG_FRAME_RATE(ch)); - /* dev_dbg(&hws->pdev->dev, "ch%u input fps=3D%u\n", ch, in_fps); */ - (void)in_fps; - /* 2) Output resolution programming. * For now, mirror the current format to OUT_RES. */ @@ -1104,11 +1063,6 @@ static void hws_buffer_queue(struct vb2_buffer *vb) struct hws_pcie_dev *hws =3D vid->parent; unsigned long flags; =20 - dev_dbg(&hws->pdev->dev, - "buffer_queue(ch=3D%u): vb=3D%p sizeimage=3D%u q_active=3D%d\n", - vid->channel_index, vb, vid->pix.sizeimage, - READ_ONCE(vid->cap_active)); - /* Initialize buffer slot */ buf->slot =3D 0; =20 @@ -1120,9 +1074,6 @@ static void hws_buffer_queue(struct vb2_buffer *vb) if (READ_ONCE(vid->cap_active) && !vid->active) { dma_addr_t dma_addr; =20 - dev_dbg(&hws->pdev->dev, - "buffer_queue(ch=3D%u): priming first vb=3D%p\n", - vid->channel_index, &buf->vb.vb2_buf); list_del_init(&buf->list); vid->queued_count--; vid->active =3D buf; @@ -1151,9 +1102,6 @@ static int hws_start_streaming(struct vb2_queue *q, u= nsigned int count) unsigned long flags; int ret; =20 - dev_dbg(&hws->pdev->dev, "start_streaming: ch=3D%u count=3D%u\n", - v->channel_index, count); - ret =3D hws_check_card_status(hws); if (ret) { struct hwsvideo_buffer *b, *tmp; @@ -1201,9 +1149,6 @@ static int hws_start_streaming(struct vb2_queue *q, u= nsigned int count) v->queued_count--; v->active =3D to_program; prog_vb2 =3D &to_program->vb.vb2_buf; - dev_dbg(&hws->pdev->dev, - "start_streaming: ch=3D%u took buffer %p\n", - v->channel_index, to_program); } spin_unlock_irqrestore(&v->irq_lock, flags); =20 @@ -1219,10 +1164,6 @@ static int hws_start_streaming(struct vb2_queue *q, = unsigned int count) iowrite32(lower_32_bits(dma_addr), hws->bar0_base + HWS_REG_DMA_ADDR(v->channel_index)); - dev_dbg(&hws->pdev->dev, - "start_streaming: ch=3D%u programmed buffer %p dma=3D0x%08x\n", - v->channel_index, to_program, - lower_32_bits(dma_addr)); (void)readl(hws->bar0_base + HWS_REG_INT_STATUS); } =20 @@ -1235,47 +1176,11 @@ static int hws_start_streaming(struct vb2_queue *q,= unsigned int count) hws_prime_next_locked(v); spin_unlock_irqrestore(&v->irq_lock, pf); } - } else { - dev_dbg(&hws->pdev->dev, - "start_streaming: ch=3D%u no buffer yet (will arm on QBUF)\n", - v->channel_index); } =20 return 0; } =20 -static void hws_log_video_state(struct hws_video *v, const char *action, - const char *phase) -{ - struct hws_pcie_dev *hws =3D v->parent; - unsigned long flags; - unsigned int queued =3D 0; - unsigned int tracked =3D 0; - unsigned int seq =3D 0; - struct hwsvideo_buffer *b; - bool streaming =3D vb2_is_streaming(&v->buffer_queue); - bool cap_active; - bool stop_requested; - struct hwsvideo_buffer *active; - struct hwsvideo_buffer *next_prepared; - - spin_lock_irqsave(&v->irq_lock, flags); - list_for_each_entry(b, &v->capture_queue, list) - queued++; - cap_active =3D READ_ONCE(v->cap_active); - stop_requested =3D READ_ONCE(v->stop_requested); - active =3D v->active; - next_prepared =3D v->next_prepared; - tracked =3D v->queued_count; - seq =3D (u32)atomic_read(&v->sequence_number); - spin_unlock_irqrestore(&v->irq_lock, flags); - - dev_dbg(&hws->pdev->dev, - "video:%s:%s ch=3D%u streaming=3D%d cap=3D%d stop=3D%d active=3D%p next= =3D%p queued=3D%u tracked=3D%u seq=3D%u\n", - action, phase, v->channel_index, streaming, cap_active, - stop_requested, active, next_prepared, queued, tracked, seq); -} - static void hws_stop_streaming(struct vb2_queue *q) { struct hws_video *v =3D q->drv_priv; @@ -1283,10 +1188,6 @@ static void hws_stop_streaming(struct vb2_queue *q) unsigned long flags; struct hwsvideo_buffer *b, *tmp; LIST_HEAD(done); - unsigned int done_cnt =3D 0; - u64 start_ns =3D ktime_get_mono_fast_ns(); - - hws_log_video_state(v, "streamoff", "begin"); =20 /* 1) Quiesce SW/HW first */ lockdep_assert_held(&v->state_lock); @@ -1307,12 +1208,7 @@ static void hws_stop_streaming(struct vb2_queue *q) /* Unlink from 'done' before completing */ list_del_init(&b->list); vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR); - done_cnt++; } - dev_dbg(&hws->pdev->dev, - "video:streamoff:done ch=3D%u completed=3D%u (%lluus)\n", - v->channel_index, done_cnt, hws_elapsed_us(start_ns)); - hws_log_video_state(v, "streamoff", "end"); } =20 static const struct vb2_ops hwspcie_video_qops =3D { @@ -1447,42 +1343,25 @@ void hws_video_unregister(struct hws_pcie_dev *dev) int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason) { int i, ret =3D 0; - u64 start_ns =3D ktime_get_mono_fast_ns(); =20 - dev_dbg(&hws->pdev->dev, "video:%s:begin channels=3D%u\n", reason, - hws->cur_max_video_ch); for (i =3D 0; i < hws->cur_max_video_ch; i++) { struct hws_video *vid =3D &hws->video[i]; struct vb2_queue *q =3D &vid->buffer_queue; - u64 ch_start_ns =3D ktime_get_mono_fast_ns(); bool streaming; =20 if (!q || !q->ops) { - dev_dbg(&hws->pdev->dev, - "video:%s:ch=3D%d skipped queue-unavailable\n", - reason, i); continue; } =20 streaming =3D vb2_is_streaming(q); - hws_log_video_state(vid, reason, "channel"); if (streaming) { /* Stop via vb2, which runs .stop_streaming. */ int r =3D vb2_streamoff(q, q->type); =20 - dev_dbg(&hws->pdev->dev, - "video:%s:ch=3D%d streamoff ret=3D%d (%lluus)\n", - reason, i, r, hws_elapsed_us(ch_start_ns)); if (r && !ret) ret =3D r; - } else { - dev_dbg(&hws->pdev->dev, - "video:%s:ch=3D%d idle (%lluus)\n", - reason, i, hws_elapsed_us(ch_start_ns)); } } - dev_dbg(&hws->pdev->dev, "video:%s:done ret=3D%d (%lluus)\n", reason, - ret, hws_elapsed_us(start_ns)); return ret; } From nobody Fri Sep 25 08:46:03 2026 Received: from mail-qk2-f13.google.com (mail-qk2-f13.google.com [74.125.230.205]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 372272FC893 for ; Tue, 15 Sep 2026 01:01:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789434078; cv=none; b=qecCx19D0OK7yPLOkQgytDpPqA//7j7oBDqb6lNJtehzzLxbBlZhzjAxbg8L4QUvUw5Q6JxlHQXsDY1WkHReIO+iwbDZRtP5yhgit6qEnWzmkGmQayBIk8nOftTyYyPIf3hRBG/WDK1zNarp2G/X1weVAaKlkN2MwkPFErmW/Vc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789434078; c=relaxed/simple; bh=6VDkLnXloEgLZAQkEc6JPjUeoK2T5pqG7bVPz15pr1c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YMsEUHbZFTH0w8FFrSjy1hJwDa5bc21n9wk/X8ThjKq1q23MxZm09dvLBfmIVLUKit4iZKa8Get1fyxFDd3tAs1vwgg9UOWHfJ5SqMBoPKwivSqp49K0yBGKm+nsBdMB0CDlycVDQM4MY7TBVNehzrUuAD6mZmmYK3DVEFBZI9I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KWajsXJQ; arc=none smtp.client-ip=74.125.230.205 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KWajsXJQ" Received: by mail-qk2-f13.google.com with SMTP id af79cd13be357-93910cadeb7so346549085a.0 for ; Mon, 14 Sep 2026 18:01:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789434076; x=1790038876; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Nkm39s62KoUeXtjUMR2iUNjO7KM7iB+N7kJ3tlV0Lus=; b=KWajsXJQca+8jP+4W+Awv3bcxbQgBX4xCK/pvK2wkUqizCqB7V7m3epjimcquqeIqK wXIKj+6+FJnCrO5/WQbk7q4ukAe0MsriFQA1YM/ilpyE2xFZul9V+pRg2H/YoThOvCyT bDoa8AsyOdYCbHMr2/j51zmvc4BlZX62PVOnZYEbHZWbDpyUcNfX646Tj2P6XvXDChI/ Flk08hhrZ0TM85BcCcceZGtVAIrt12U/xJ+XNWotVBaKE1OFOlo/jSxRhZRj85t96vQR LlICI0NGS+P5etWwmUCtM1ke896oDbULB3O8YTxYH2n1fh+KqA4jnQWjicFhEshg/cPr f/DA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789434076; x=1790038876; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Nkm39s62KoUeXtjUMR2iUNjO7KM7iB+N7kJ3tlV0Lus=; b=uw6UEEfqGdyRRy+4pP4754ryW12U1hl4h0ZXVOliFCCAijy/vXq8E4auO+mkqh7oys jXWKnkRD42d/3aBB1WzicJ80VxyOrF6f8iZMx+XRYvoQP+mtjzGChz5CZM4t3v/EQt8h sML6ba6SOVApP3f3JW65zs4TshZASWOw5D3+LoEJphW6VMDpikbPtvpusNvw9I27pije F27c5VPwWzItlVPdfrPiSIWLZZT9v3wty/cQOdoVfySLWk11YlI76UxPtigiFPJkpDy2 4POGFo+WcA0Cpr9SSMt/wQHG1kAH0xJg7d3NuPS0uCu9gO612KxIw4sfp6geCNmEZd/a ZeXA== X-Forwarded-Encrypted: i=1; AKwUvBztRnHyx76C/pfArj+aNb9pTf6DDA+6no6d56BcrqHVMYPSihsJDfAb0HU7z5lxKBEJeK9lVI8DtsoykQU=@vger.kernel.org X-Gm-Message-State: AFuF++n2bVWePU7FuQ8gnkg32vPilOmbdZsO6C/LVNY2ye1hi4/J8Wzo 1GIHSpmjOOZX2HKeL1Grph5nrvjZ+LvwxxcaBqQW4cNpsvsOmio3d3Ld X-Gm-Gg: AYBFou0hQKyw0DYvsn+OOYv/+cgiojIbgIU/rLY69k5LqGiik0EfrJ9gN4r/TNii3GX 2LCPMmHHIBJty7qepmsjVXwyF2LIp7drNVNmHzLODguEibsp3Ymk4pLbBOdwgCfz1J2kplb8olI vgZvBT44QGshp7TnOMxTvoSedJDqB6GK87QqcpEwtKLaAAU59TRVpTbxb2idvZjR9KKJ/dfcrKq ZvuR4wXipz5ENCH/F61cExhWCgXP3vAcN18Ouz8YHqDfiB1qYDIgeZzKP5RPop8Y/CqQQ0gLdjh Dgntg46GsG3TcNrzQS1S0Qc+yyqNZAM1exvbaE4UyIj1g0rUaKJ+lYBB8DNavRk5fyMVxE7qGbS bqnKuaa7CfUS4IVnVVoVkM4W2080+dPtjicvfT4amhdlLAX8e7vWKeW0KHC5VeDOUC5/cyj2kRL h8rAJhsrtFY5QW12349t/g8u8rPZgygyBVia2IhCC13074bwud0L6z8m3AD9Nk3ug98yeIaCRfE 2RWM+uL6IXeqnlAByCotwwByJ0qwUNzzi1BOOoAiNbQ2st6Dw== X-Received: by 2002:a05:620a:2904:b0:930:9091:f0ce with SMTP id af79cd13be357-93a2985a593mr819363885a.22.1789434075834; Mon, 14 Sep 2026 18:01:15 -0700 (PDT) Received: from father (76-224-4-192.lightspeed.clmboh.sbcglobal.net. [76.224.4.192]) by smtp.gmail.com with ESMTPSA id af79cd13be357-939e7f18467sm1147705885a.11.2026.09.14.18.01.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 18:01:15 -0700 (PDT) From: Ben Hoff To: linux-media@vger.kernel.org Cc: mchehab@kernel.org, hverkuil@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/3] media: hws: quiesce interrupts without disabling shared IRQ Date: Mon, 14 Sep 2026 21:01:10 -0400 Message-ID: <20260915010111.101551-3-hoff.benjamin.k@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260915010111.101551-1-hoff.benjamin.k@gmail.com> References: <20260915010111.101551-1-hoff.benjamin.k@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" HWS requests its legacy interrupt with IRQF_SHARED, but suspend, shutdown, and removal call disable_irq() on the shared descriptor. This prevents other devices on the line from being serviced, and removal leaves the IRQ disable unbalanced. Mask the HWS interrupt gate, flush the write, and synchronize the handler. Publish suspended state before draining so callbacks caused by a peer on the shared line return without accessing HWS registers after suspend. Keep capture-core initialization from opening the interrupt gate. Resume restores the core and clears pending causes before publishing live state and unmasking the device-local gate. Fixes: ba07fd2f5742 ("media: pci: add AVMatrix HWS capture driver") Assisted-by: Codex:GPT-6 Signed-off-by: Ben Hoff --- drivers/media/pci/hws/hws_irq.c | 12 +++--------- drivers/media/pci/hws/hws_pci.c | 27 +++++++++++++++++---------- drivers/media/pci/hws/hws_video.c | 8 ++------ 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/drivers/media/pci/hws/hws_irq.c b/drivers/media/pci/hws/hws_ir= q.c index 787c9e498799..8d883663617b 100644 --- a/drivers/media/pci/hws/hws_irq.c +++ b/drivers/media/pci/hws/hws_irq.c @@ -150,15 +150,9 @@ irqreturn_t hws_irq_handler(int irq, void *info) struct hws_pcie_dev *pdx =3D info; u32 int_state; =20 - /* Fast path: if suspended, quietly ack and exit */ - if (READ_ONCE(pdx->suspended)) { - int_state =3D readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS); - if (int_state) { - writel(int_state, pdx->bar0_base + HWS_REG_INT_STATUS); - (void)readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS); - } - return int_state ? IRQ_HANDLED : IRQ_NONE; - } + if (!pdx || READ_ONCE(pdx->suspended) || !pdx->bar0_base) + return IRQ_NONE; + int_state =3D readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS); if (!int_state || int_state =3D=3D 0xFFFFFFFF) { return IRQ_NONE; diff --git a/drivers/media/pci/hws/hws_pci.c b/drivers/media/pci/hws/hws_pc= i.c index 65b32fac6d1a..c9397b13392a 100644 --- a/drivers/media/pci/hws/hws_pci.c +++ b/drivers/media/pci/hws/hws_pci.c @@ -325,14 +325,21 @@ static void hws_irq_clear_pending(struct hws_pcie_dev= *hws) static void hws_block_hotpaths(struct hws_pcie_dev *hws) { WRITE_ONCE(hws->suspended, true); - if (hws->irq >=3D 0) - disable_irq(hws->irq); + /* Publish the stop state before a racing handler can enter MMIO. */ + smp_mb(); =20 - if (!hws->bar0_base) - return; + if (hws->bar0_base) + hws_irq_mask_gate(hws); =20 - hws_irq_mask_gate(hws); - hws_irq_clear_pending(hws); + /* + * Do not disable the shared descriptor. Wait for any invocation of this + * handler that raced with the device-local gate instead. + */ + if (hws->irq >=3D 0) + synchronize_irq(hws->irq); + + if (hws->bar0_base) + hws_irq_clear_pending(hws); } =20 static int hws_probe(struct pci_dev *pdev, const struct pci_device_id *pci= _id) @@ -661,11 +668,11 @@ static int hws_pm_resume(struct device *dev) hws_init_video_sys(hws, true); hws_irq_clear_pending(hws); =20 - /* IRQs can be re-enabled now that MMIO is sane */ - if (hws->irq >=3D 0) - enable_irq(hws->irq); - + /* Make our handler live before reopening only this device's IRQ gate. */ WRITE_ONCE(hws->suspended, false); + /* Publish the live state before the device can raise another interrupt. = */ + smp_mb(); + hws_irq_unmask_gate(hws); =20 /* vb2: nothing mandatory; userspace will STREAMON again when ready */ hws_video_pm_resume(hws); diff --git a/drivers/media/pci/hws/hws_video.c b/drivers/media/pci/hws/hws_= video.c index 624c48a63b3b..bdbce09ec3e6 100644 --- a/drivers/media/pci/hws/hws_video.c +++ b/drivers/media/pci/hws/hws_video.c @@ -565,7 +565,7 @@ static void hws_ack_all_irqs(struct hws_pcie_dev *hws) } } =20 -static void hws_open_irq_fabric(struct hws_pcie_dev *hws) +static void hws_configure_irq_fabric(struct hws_pcie_dev *hws) { /* Route all sources to vector 0. */ writel(0x00000000, hws->bar0_base + PCIE_INT_DEC_REG_BASE); @@ -574,10 +574,6 @@ static void hws_open_irq_fabric(struct hws_pcie_dev *h= ws) /* Enable the PCIe bridge. */ writel(0x00000001, hws->bar0_base + PCIEBR_EN_REG_BASE); (void)readl(hws->bar0_base + PCIEBR_EN_REG_BASE); - - /* Open the global/bridge gate (legacy 0x3FFFF) */ - writel(HWS_INT_EN_MASK, hws->bar0_base + INT_EN_REG_BASE); - (void)readl(hws->bar0_base + INT_EN_REG_BASE); } =20 void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable) @@ -604,7 +600,7 @@ void hws_init_video_sys(struct hws_pcie_dev *hws, bool = enable) writel(0x80FFFFFF, hws->bar0_base + HWS_REG_DEC_MODE); writel(0x13, hws->bar0_base + HWS_REG_DEC_MODE); hws_ack_all_irqs(hws); - hws_open_irq_fabric(hws); + hws_configure_irq_fabric(hws); /* 6) record that we're now running */ hws->start_run =3D true; } From nobody Fri Sep 25 08:46:03 2026 Received: from mail-qk1-f172.google.com (mail-qk1-f172.google.com [209.85.222.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A4B83090C6 for ; Tue, 15 Sep 2026 01:01:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789434096; cv=none; b=RQirzO4SD+DPug6Qg0nrtBZq06V5KUQSccjSOzVKIoy3AI4hh4w81ohW3TNc4dQgx9pc7xw8wppHhYAwjQ19kbxnXw4BUKPgCGY2CbFRfvl/bJQ1g6cn4fFSDFpLsQMTmxsr3c9JWhP7tvswUw+hcRrHfwDheBXLissZcPF3vf4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789434096; c=relaxed/simple; bh=a2CvPDWK8OINt/Yx73WFbopm3aGUJjkMAmtmX/0I7hs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=V4/MD6YAQY5/3m5Ig2ypSgMHTxpLmJY5ym2aPzYr5FzJWZ3waivKzOtZZTL/QV3/qOO4NV2MGP9mLxqSIa59+2Mo3ZlEx5QHcYKYDxNLKhW8tKNh5S7H2V6r8iPXG+otsaPWTMVBiGXZ8sWEJBaCce7h+AjYBJTkooOaiq8aIz8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Yb/lczxz; arc=none smtp.client-ip=209.85.222.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Yb/lczxz" Received: by mail-qk1-f172.google.com with SMTP id af79cd13be357-939fa4f2b81so227191885a.0 for ; Mon, 14 Sep 2026 18:01:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789434094; x=1790038894; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=JJid9mVb8+u4dBU/DUaqBCMQDqXmAvzr8S+H2u9/oJc=; b=Yb/lczxzVoVQ05eyjgvfZgg9XtQygMMGTYHxO8JxAOH34EncYaTPq3u7sGew1qo7gy BR/+xKBrKT+Rgrnf5PoKbD0FWWMBWxCTZmOdl9NJXFNnd2YuB5jiTB45QjtBuwptx8sC BFqBZUaxZcTw96NVKWmlWET00tYHmx/QXVPmMswvCfWGMdt7XOsS1iQmmCpNzfqmzNhe aXqUahp9VvNPsVU4Sn/dEhI8ruFUj/H5HA7vi9VxihNNZ+bMwBeTV+20/10roc48BqWr +phPeu6GanX5oAa33nLpxq7/uhYNiK9uUknnbk794MdOayVGfIf5qMjtdhHAxX0sftfN 6ybg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789434094; x=1790038894; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=JJid9mVb8+u4dBU/DUaqBCMQDqXmAvzr8S+H2u9/oJc=; b=nuiYJ4gK4bjVjvnytruwTsW37ee2rgHX2UAojCV6FHJxDgG87JZHqRQmd60CCy1GVD f2H610eJVVu4WhxQKAGgazKFk+IPkUjXDoV6socXYFkth0JFPG1/tit2uTiU5B8BVjPO EIrFsEKYV/Eync+xuM0qoTzrVCUJCROvuanyIXT+VwD7myZfhZavhy6qZ4YyqdAXrXoF MFxt9r12UjHXJcTr23PjPUC58rhxcoUS60je/M06+LqeRDB26Bh+fwM2tRScSo2sfXJJ p6kABemqLKmaeyh/Y+gM+X/uAoJj/9a4K1zKEdd/sWv2dEOiuB90LYVDFYup8zTTwnPn Hpng== X-Forwarded-Encrypted: i=1; AKwUvBzRswUAfpsCz9RkkUexQWryVLeFTFXQXv7qMxXguWc1ujkuDwVYmguGwM7D66qgUAQE8LsLCrBSctqklgo=@vger.kernel.org X-Gm-Message-State: AFuF++msaThu1OdZgiSHtlwr0iBwdLV0ZQDnfxd9ECWt07RqBM78z0s2 CFHf7l1m1g4u6AYyz8xO+kTCn79ESRVQAot7UcnCnN+Tz/UgYxE2M1tA X-Gm-Gg: AYBFou1nXWKdWwlcqzZZmMYAD9V8jLZIBClXI5XZksuAof+NqB0Iz530Z2Eh3/Dg18l 0F678qSROV6ulX93iDj1O3hVQauln2UIhRBn/9def9HBEvvKPP2sy6jrZQZFX9nBA7WdjaHWw+t mag/Qdk+gSqpUCdEhiJUbeBB+/bfWQT0FGWXA8BMwRhpUHePxfawxxfpiCHzoJgtwDQq4gMWMui SEAfgBG5g7WE004pmRF/qbdMhLErWl3JfbWKyguwt0IV2hppDFM6MMDElXHaAB23bVlNpp4oxAp 5ANwGl2khhR2NoH3+3IZndtHXqDt1bzUAbQTzqiYTylsBDdFlyP8nVZgP3DcGD/F+HEMdSgvG9b S0CMfTBfvBbpW/l4xy9lb/wPdnHFAVoKJt0j5aa2OrZghApHoSY9dBSOz0AaGDgnUVCiMVAlcKM ptvj1Tf9gJ6K7EZ4F0FJPG1sF0sjp3N/eTEtoYljHlktclkuIhDEABKCCHYVy2gZ2sVNlYKBfNZ E6W1nLO2tJG8G95YCtSh6Ad6WMYi1xvS3ryfuLr0weq/14D X-Received: by 2002:a05:620a:2955:b0:939:6df9:6547 with SMTP id af79cd13be357-93a29bf983cmr753040985a.51.1789434076622; Mon, 14 Sep 2026 18:01:16 -0700 (PDT) Received: from father (76-224-4-192.lightspeed.clmboh.sbcglobal.net. [76.224.4.192]) by smtp.gmail.com with ESMTPSA id af79cd13be357-939e7f18467sm1147705885a.11.2026.09.14.18.01.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 18:01:16 -0700 (PDT) From: Ben Hoff To: linux-media@vger.kernel.org Cc: mchehab@kernel.org, hverkuil@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/3] media: hws: serialize video quiesce with queue state Date: Mon, 14 Sep 2026 21:01:11 -0400 Message-ID: <20260915010111.101551-4-hoff.benjamin.k@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260915010111.101551-1-hoff.benjamin.k@gmail.com> References: <20260915010111.101551-1-hoff.benjamin.k@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Suspend and shutdown call vb2_streamoff() without taking the state mutex used by the video device and its vb2 queue. This can race userspace queue operations and violates the locking requirement in hws_stop_streaming(). Hold the channel state mutex around the streaming check and streamoff. Serialize monitor passes with lifecycle quiescence, and recheck suspended state after acquiring the monitor mutex so a delayed pass cannot enter hardware access after teardown has drained it. Reject readiness checks once suspension begins. If the core is not ready, return an error instead of resetting shared hardware while another channel may still own capture buffers. Fixes: ba07fd2f5742 ("media: pci: add AVMatrix HWS capture driver") Assisted-by: Codex:GPT-6 Signed-off-by: Ben Hoff --- drivers/media/pci/hws/hws.h | 2 ++ drivers/media/pci/hws/hws_pci.c | 11 +++++++++-- drivers/media/pci/hws/hws_video.c | 11 +++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/media/pci/hws/hws.h b/drivers/media/pci/hws/hws.h index d87d52674b69..01a6b00dcca6 100644 --- a/drivers/media/pci/hws/hws.h +++ b/drivers/media/pci/hws/hws.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -161,6 +162,7 @@ struct hws_pcie_dev { =20 /* Kernel thread */ struct task_struct *main_task; + struct mutex monitor_lock; /* serializes monitor and lifecycle changes */ struct hws_scratch_dma scratch_vid[MAX_VID_CHANNELS]; =20 bool suspended; diff --git a/drivers/media/pci/hws/hws_pci.c b/drivers/media/pci/hws/hws_pc= i.c index c9397b13392a..7fdb1087d247 100644 --- a/drivers/media/pci/hws/hws_pci.c +++ b/drivers/media/pci/hws/hws_pci.c @@ -177,8 +177,10 @@ static int main_ks_thread_handle(void *data) continue; } =20 - /* avoid MMIO when suspended (guarded above) */ - check_video_format(pdx); + mutex_lock(&pdx->monitor_lock); + if (!READ_ONCE(pdx->suspended)) + check_video_format(pdx); + mutex_unlock(&pdx->monitor_lock); =20 try_to_freeze(); /* cooperate with freezer each loop */ =20 @@ -338,6 +340,10 @@ static void hws_block_hotpaths(struct hws_pcie_dev *hw= s) if (hws->irq >=3D 0) synchronize_irq(hws->irq); =20 + /* Wait for a monitor pass that started before suspended was set. */ + mutex_lock(&hws->monitor_lock); + mutex_unlock(&hws->monitor_lock); + if (hws->bar0_base) hws_irq_clear_pending(hws); } @@ -357,6 +363,7 @@ static int hws_probe(struct pci_dev *pdev, const struct= pci_device_id *pci_id) hws->pdev =3D pdev; hws->irq =3D -1; hws->suspended =3D false; + mutex_init(&hws->monitor_lock); pci_set_drvdata(pdev, hws); =20 /* 1) Enable device + bus mastering (managed) */ diff --git a/drivers/media/pci/hws/hws_video.c b/drivers/media/pci/hws/hws_= video.c index bdbce09ec3e6..8e029b71b5b5 100644 --- a/drivers/media/pci/hws/hws_video.c +++ b/drivers/media/pci/hws/hws_video.c @@ -611,6 +611,8 @@ int hws_check_card_status(struct hws_pcie_dev *hws) =20 if (!hws || !hws->bar0_base) return -ENODEV; + if (READ_ONCE(hws->suspended)) + return -EBUSY; =20 status =3D readl(hws->bar0_base + HWS_REG_SYS_STATUS); =20 @@ -621,9 +623,12 @@ int hws_check_card_status(struct hws_pcie_dev *hws) return -ENODEV; } =20 - /* If RUN/READY bit (bit0) is not set, reinitialize the video core. */ + /* Runtime reset would invalidate every active channel's DMA ownership. */ if (!(status & BIT(0))) { - hws_init_video_sys(hws, true); + dev_warn_ratelimited(&hws->pdev->dev, + "SYS_STATUS not ready (0x%08x); runtime core reset refused\n", + status); + return -EIO; } =20 return 0; @@ -1349,6 +1354,7 @@ int hws_video_quiesce(struct hws_pcie_dev *hws, const= char *reason) continue; } =20 + mutex_lock(&vid->state_lock); streaming =3D vb2_is_streaming(q); if (streaming) { /* Stop via vb2, which runs .stop_streaming. */ @@ -1357,6 +1363,7 @@ int hws_video_quiesce(struct hws_pcie_dev *hws, const= char *reason) if (r && !ret) ret =3D r; } + mutex_unlock(&vid->state_lock); } return ret; }