From: kernel test robot <lkp@intel.com>
To: Ben Hoff <hoff.benjamin.k@gmail.com>, linux-media@vger.kernel.org
Cc: oe-kbuild-all@lists.linux.dev, linux-kernel@vger.kernel.org,
mchehab@kernel.org, hverkuil+cisco@kernel.org,
kernel test robot <lkp@intel.com>
Subject: Re: [PATCH v6] media: pci: add AVMatrix HWS capture driver
Date: Thu, 14 May 2026 13:56:18 +0800 [thread overview]
Message-ID: <202605141318.V8xxhJE4-lkp@intel.com> (raw)
In-Reply-To: <20260506192618.35384-1-hoff.benjamin.k@gmail.com>
Hi Ben,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 74fe02ce122a6103f207d29fafc8b3a53de6abaf]
url: https://github.com/intel-lab-lkp/linux/commits/Ben-Hoff/media-pci-add-AVMatrix-HWS-capture-driver/20260514-065339
base: 74fe02ce122a6103f207d29fafc8b3a53de6abaf
patch link: https://lore.kernel.org/r/20260506192618.35384-1-hoff.benjamin.k%40gmail.com
patch subject: [PATCH v6] media: pci: add AVMatrix HWS capture driver
config: openrisc-allmodconfig (https://download.01.org/0day-ci/archive/20260514/202605141318.V8xxhJE4-lkp@intel.com/config)
compiler: or1k-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260514/202605141318.V8xxhJE4-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605141318.V8xxhJE4-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/media/pci/hws/hws_pci.c: In function 'hws_probe':
>> drivers/media/pci/hws/hws_pci.c:357:41: warning: unused variable 'using_msi' [-Wunused-variable]
357 | bool has_msix_cap, has_msi_cap, using_msi;
| ^~~~~~~~~
>> drivers/media/pci/hws/hws_pci.c:357:28: warning: unused variable 'has_msi_cap' [-Wunused-variable]
357 | bool has_msix_cap, has_msi_cap, using_msi;
| ^~~~~~~~~~~
>> drivers/media/pci/hws/hws_pci.c:357:14: warning: unused variable 'has_msix_cap' [-Wunused-variable]
357 | bool has_msix_cap, has_msi_cap, using_msi;
| ^~~~~~~~~~~~
>> drivers/media/pci/hws/hws_pci.c:355:21: warning: unused variable 'nvec' [-Wunused-variable]
355 | int i, ret, nvec, irq;
| ^~~~
drivers/media/pci/hws/hws_pci.c: At top level:
>> drivers/media/pci/hws/hws_pci.c:173:13: warning: 'hws_any_capture_active' defined but not used [-Wunused-function]
173 | static bool hws_any_capture_active(const struct hws_pcie_dev *pdx)
| ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/media/pci/hws/hws_pci.c:168:13: warning: 'hws_free_irq_vectors_action' defined but not used [-Wunused-function]
168 | static void hws_free_irq_vectors_action(void *data)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
--
drivers/media/pci/hws/hws_video.c: In function 'hws_video_init_channel':
>> drivers/media/pci/hws/hws_video.c:336:35: warning: unused variable 'hdl' [-Wunused-variable]
336 | struct v4l2_ctrl_handler *hdl;
| ^~~
--
drivers/media/pci/hws/hws_v4l2_ioctl.c:280:5: warning: no previous prototype for 'hws_vidioc_query_dv_timings' [-Wmissing-prototypes]
280 | int hws_vidioc_query_dv_timings(struct file *file, void *fh,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c: In function 'hws_vidioc_query_dv_timings':
>> drivers/media/pci/hws/hws_v4l2_ioctl.c:286:25: warning: variable 'live_ok' set but not used [-Wunused-but-set-variable]
286 | bool interlace, live_ok;
| ^~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c: At top level:
drivers/media/pci/hws/hws_v4l2_ioctl.c:309:5: warning: no previous prototype for 'hws_vidioc_enum_dv_timings' [-Wmissing-prototypes]
309 | int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:326:5: warning: no previous prototype for 'hws_vidioc_g_dv_timings' [-Wmissing-prototypes]
326 | int hws_vidioc_g_dv_timings(struct file *file, void *fh,
| ^~~~~~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:352:5: warning: no previous prototype for 'hws_vidioc_s_dv_timings' [-Wmissing-prototypes]
352 | int hws_vidioc_s_dv_timings(struct file *file, void *fh,
| ^~~~~~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:412:5: warning: no previous prototype for 'hws_vidioc_dv_timings_cap' [-Wmissing-prototypes]
412 | int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
| ^~~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:504:5: warning: no previous prototype for 'hws_vidioc_querycap' [-Wmissing-prototypes]
504 | int hws_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
| ^~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:520:5: warning: no previous prototype for 'hws_vidioc_enum_fmt_vid_cap' [-Wmissing-prototypes]
520 | int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh, struct v4l2_fmtdesc *f)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:529:5: warning: no previous prototype for 'hws_vidioc_g_fmt_vid_cap' [-Wmissing-prototypes]
529 | int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
| ^~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:556:5: warning: no previous prototype for 'hws_vidioc_try_fmt_vid_cap' [-Wmissing-prototypes]
556 | int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:633:5: warning: no previous prototype for 'hws_vidioc_s_fmt_vid_cap' [-Wmissing-prototypes]
633 | int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
| ^~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:690:5: warning: no previous prototype for 'hws_vidioc_g_parm' [-Wmissing-prototypes]
690 | int hws_vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *param)
| ^~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:711:5: warning: no previous prototype for 'hws_vidioc_enum_input' [-Wmissing-prototypes]
711 | int hws_vidioc_enum_input(struct file *file, void *priv,
| ^~~~~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:724:5: warning: no previous prototype for 'hws_vidioc_g_input' [-Wmissing-prototypes]
724 | int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *index)
| ^~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:730:5: warning: no previous prototype for 'hws_vidioc_s_input' [-Wmissing-prototypes]
730 | int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i)
| ^~~~~~~~~~~~~~~~~~
drivers/media/pci/hws/hws_v4l2_ioctl.c:735:5: warning: no previous prototype for 'hws_vidioc_s_parm' [-Wmissing-prototypes]
735 | int hws_vidioc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *param)
| ^~~~~~~~~~~~~~~~~
vim +/using_msi +357 drivers/media/pci/hws/hws_pci.c
167
> 168 static void hws_free_irq_vectors_action(void *data)
169 {
170 pci_free_irq_vectors((struct pci_dev *)data);
171 }
172
> 173 static bool hws_any_capture_active(const struct hws_pcie_dev *pdx)
174 {
175 unsigned int ch, max;
176
177 if (!pdx)
178 return false;
179
180 max = READ_ONCE(pdx->cur_max_video_ch);
181 if (max > pdx->max_channels)
182 max = pdx->max_channels;
183
184 for (ch = 0; ch < max; ch++) {
185 if (READ_ONCE(pdx->video[ch].cap_active))
186 return true;
187 }
188
189 return false;
190 }
191
192 static int main_ks_thread_handle(void *data)
193 {
194 struct hws_pcie_dev *pdx = data;
195
196 set_freezable();
197
198 while (!kthread_should_stop()) {
199 /* If we're suspending, don't touch hardware; just sleep/freeeze */
200 if (READ_ONCE(pdx->suspended)) {
201 try_to_freeze();
202 schedule_timeout_interruptible(msecs_to_jiffies(1000));
203 continue;
204 }
205
206 /* avoid MMIO when suspended (guarded above) */
207 check_video_format(pdx);
208
209 try_to_freeze(); /* cooperate with freezer each loop */
210
211 /* Sleep 1s or until signaled to wake/stop */
212 schedule_timeout_interruptible(msecs_to_jiffies(1000));
213 }
214
215 dev_dbg(&pdx->pdev->dev, "%s: exiting\n", __func__);
216 return 0;
217 }
218
219 static void hws_stop_kthread_action(void *data)
220 {
221 struct hws_pcie_dev *hws = data;
222 struct task_struct *t;
223
224 if (!hws)
225 return;
226
227 t = READ_ONCE(hws->main_task);
228 if (!IS_ERR_OR_NULL(t)) {
229 WRITE_ONCE(hws->main_task, NULL);
230 kthread_stop(t);
231 }
232 }
233
234 static int hws_alloc_seed_buffers(struct hws_pcie_dev *hws)
235 {
236 int ch;
237 /* 64 KiB is plenty for a safe dummy; align to 64 for your HW */
238 const size_t need = ALIGN(64 * 1024, 64);
239
240 for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
241 #if defined(CONFIG_HAS_DMA) /* normal on PCIe platforms */
242 void *cpu = dma_alloc_coherent(&hws->pdev->dev, need,
243 &hws->scratch_vid[ch].dma,
244 GFP_KERNEL);
245 #else
246 void *cpu = NULL;
247 #endif
248 if (!cpu) {
249 dev_warn(&hws->pdev->dev,
250 "scratch: dma_alloc_coherent failed ch=%d\n", ch);
251 /* not fatal: free earlier ones and continue without seeding */
252 while (--ch >= 0) {
253 if (hws->scratch_vid[ch].cpu)
254 dma_free_coherent(&hws->pdev->dev,
255 hws->scratch_vid[ch].size,
256 hws->scratch_vid[ch].cpu,
257 hws->scratch_vid[ch].dma);
258 hws->scratch_vid[ch].cpu = NULL;
259 hws->scratch_vid[ch].size = 0;
260 }
261 return -ENOMEM;
262 }
263 hws->scratch_vid[ch].cpu = cpu;
264 hws->scratch_vid[ch].size = need;
265 }
266 return 0;
267 }
268
269 static void hws_free_seed_buffers(struct hws_pcie_dev *hws)
270 {
271 int ch;
272
273 for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
274 if (hws->scratch_vid[ch].cpu) {
275 dma_free_coherent(&hws->pdev->dev,
276 hws->scratch_vid[ch].size,
277 hws->scratch_vid[ch].cpu,
278 hws->scratch_vid[ch].dma);
279 hws->scratch_vid[ch].cpu = NULL;
280 hws->scratch_vid[ch].size = 0;
281 }
282 }
283 }
284
285 static void hws_seed_channel(struct hws_pcie_dev *hws, int ch)
286 {
287 dma_addr_t paddr = hws->scratch_vid[ch].dma;
288 u32 lo = lower_32_bits(paddr);
289 u32 hi = upper_32_bits(paddr);
290 u32 pci_addr = lo & PCI_E_BAR_ADD_LOWMASK;
291
292 lo &= PCI_E_BAR_ADD_MASK;
293
294 /* Program 64-bit BAR remap entry for this channel (table @ 0x208 + ch * 8) */
295 writel_relaxed(hi, hws->bar0_base +
296 PCI_ADDR_TABLE_BASE + 0x208 + ch * 8);
297 writel_relaxed(lo, hws->bar0_base +
298 PCI_ADDR_TABLE_BASE + 0x208 + ch * 8 +
299 PCIE_BARADDROFSIZE);
300
301 /* Program capture engine per-channel base/half */
302 writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
303 hws->bar0_base + CVBS_IN_BUF_BASE +
304 ch * PCIE_BARADDROFSIZE);
305
306 /* half size: use either the current format's half or half of scratch */
307 {
308 u32 half = hws->video[ch].pix.half_size ?
309 hws->video[ch].pix.half_size :
310 (u32)(hws->scratch_vid[ch].size / 2);
311
312 writel_relaxed(half / 16,
313 hws->bar0_base + CVBS_IN_BUF_BASE2 +
314 ch * PCIE_BARADDROFSIZE);
315 }
316
317 (void)readl(hws->bar0_base + HWS_REG_INT_STATUS); /* flush posted writes */
318 }
319
320 static void hws_seed_all_channels(struct hws_pcie_dev *hws)
321 {
322 int ch;
323
324 for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
325 if (hws->scratch_vid[ch].cpu)
326 hws_seed_channel(hws, ch);
327 }
328 }
329
330 static void hws_irq_mask_gate(struct hws_pcie_dev *hws)
331 {
332 writel(0x00000000, hws->bar0_base + INT_EN_REG_BASE);
333 (void)readl(hws->bar0_base + INT_EN_REG_BASE);
334 }
335
336 static void hws_irq_unmask_gate(struct hws_pcie_dev *hws)
337 {
338 writel(HWS_INT_EN_MASK, hws->bar0_base + INT_EN_REG_BASE);
339 (void)readl(hws->bar0_base + INT_EN_REG_BASE);
340 }
341
342 static void hws_irq_clear_pending(struct hws_pcie_dev *hws)
343 {
344 u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
345
346 if (st) {
347 writel(st, hws->bar0_base + HWS_REG_INT_STATUS); /* W1C */
348 (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
349 }
350 }
351
352 static int hws_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
353 {
354 struct hws_pcie_dev *hws;
> 355 int i, ret, nvec, irq;
356 unsigned long irqf = 0;
> 357 bool has_msix_cap, has_msi_cap, using_msi;
358 bool v4l2_registered = false;
359
360 /* devres-backed device object */
361 hws = devm_kzalloc(&pdev->dev, sizeof(*hws), GFP_KERNEL);
362 if (!hws)
363 return -ENOMEM;
364
365 hws->pdev = pdev;
366 hws->irq = -1;
367 hws->suspended = false;
368 pci_set_drvdata(pdev, hws);
369
370 /* 1) Enable device + bus mastering (managed) */
371 ret = pcim_enable_device(pdev);
372 if (ret)
373 return dev_err_probe(&pdev->dev, ret, "pcim_enable_device\n");
374 pci_set_master(pdev);
375
376 /* 2) Map BAR0 (managed) */
377 ret = pcim_iomap_regions(pdev, BIT(0), KBUILD_MODNAME);
378 if (ret)
379 return dev_err_probe(&pdev->dev, ret, "pcim_iomap_regions BAR0\n");
380 hws->bar0_base = pcim_iomap_table(pdev)[0];
381
382 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
383 if (ret) {
384 dev_warn(&pdev->dev,
385 "64-bit DMA mask unavailable, falling back to 32-bit (%d)\n",
386 ret);
387 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
388 if (ret)
389 return dev_err_probe(&pdev->dev, ret,
390 "No suitable DMA configuration\n");
391 } else {
392 dev_dbg(&pdev->dev, "Using 64-bit DMA mask\n");
393 }
394
395 /* 3) Optional PCIe tuning (same as before) */
396 enable_pcie_relaxed_ordering(pdev);
397 #ifdef CONFIG_ARCH_TI816X
398 pcie_set_readrq(pdev, 128);
399 #endif
400
401 /* 4) Identify chip & capabilities */
402 read_chip_id(hws);
403 dev_info(&pdev->dev, "Device VID=0x%04x DID=0x%04x\n",
404 pdev->vendor, pdev->device);
405 hws_init_video_sys(hws, false);
406
407 /* 5) Init channels (video state, locks, vb2, ctrls) */
408 for (i = 0; i < hws->max_channels; i++) {
409 ret = hws_video_init_channel(hws, i);
410 if (ret) {
411 dev_err(&pdev->dev, "video channel init failed (ch=%d)\n", i);
412 goto err_unwind_channels;
413 }
414 }
415
416 /* 6) Allocate scratch DMA and seed BAR table + channel base/half (legacy SetDMAAddress) */
417 ret = hws_alloc_seed_buffers(hws);
418 if (!ret)
419 hws_seed_all_channels(hws);
420
421 /* 7) Start-run sequence (like InitVideoSys) */
422 hws_init_video_sys(hws, false);
423
424 /* A) Force legacy INTx; legacy used request_irq(pdev->irq, ..., IRQF_SHARED) */
425 pci_intx(pdev, 1);
426 irqf = IRQF_SHARED;
427 irq = pdev->irq;
428 hws->irq = irq;
429 dev_info(&pdev->dev, "IRQ mode: legacy INTx (shared), irq=%d\n", irq);
430
431 /* B) Mask the device's global/bridge gate (INT_EN_REG_BASE) */
432 hws_irq_mask_gate(hws);
433
434 /* C) Clear any sticky pending interrupt status (W1C) before we arm the line */
435 hws_irq_clear_pending(hws);
436
437 /* D) Request the legacy shared interrupt line (no vectors/MSI/MSI-X) */
438 ret = devm_request_irq(&pdev->dev, irq, hws_irq_handler, irqf,
439 dev_name(&pdev->dev), hws);
440 if (ret) {
441 dev_err(&pdev->dev, "request_irq(%d) failed: %d\n", irq, ret);
442 goto err_unwind_channels;
443 }
444
445 /* E) Set the global interrupt enable bit in main control register */
446 {
447 u32 ctl_reg = readl(hws->bar0_base + HWS_REG_CTL);
448
449 ctl_reg |= HWS_CTL_IRQ_ENABLE_BIT;
450 writel(ctl_reg, hws->bar0_base + HWS_REG_CTL);
451 (void)readl(hws->bar0_base + HWS_REG_CTL); /* flush write */
452 dev_info(&pdev->dev, "Global IRQ enable bit set in control register\n");
453 }
454
455 /* F) Open the global gate just like legacy did */
456 hws_irq_unmask_gate(hws);
457 dev_info(&pdev->dev, "INT_EN_GATE readback=0x%08x\n",
458 readl(hws->bar0_base + INT_EN_REG_BASE));
459
460 /* 11) Register V4L2 */
461 ret = hws_video_register(hws);
462 if (ret) {
463 dev_err(&pdev->dev, "video_register: %d\n", ret);
464 goto err_unwind_channels;
465 }
466 v4l2_registered = true;
467
468 /* 12) Background monitor thread (managed) */
469 hws->main_task = kthread_run(main_ks_thread_handle, hws, "hws-mon");
470 if (IS_ERR(hws->main_task)) {
471 ret = PTR_ERR(hws->main_task);
472 hws->main_task = NULL;
473 dev_err(&pdev->dev, "kthread_run: %d\n", ret);
474 goto err_unregister_va;
475 }
476 ret = devm_add_action_or_reset(&pdev->dev, hws_stop_kthread_action, hws);
477 if (ret) {
478 dev_err(&pdev->dev, "devm_add_action kthread_stop: %d\n", ret);
479 goto err_unregister_va; /* reset already stopped the thread */
480 }
481
482 /* 13) Final: show the line is armed */
483 dev_info(&pdev->dev, "irq handler installed on irq=%d\n", irq);
484 return 0;
485
486 err_unregister_va:
487 hws_stop_device(hws);
488 hws_video_unregister(hws);
489 hws_free_seed_buffers(hws);
490 return ret;
491 err_unwind_channels:
492 hws_free_seed_buffers(hws);
493 if (!v4l2_registered) {
494 while (--i >= 0)
495 hws_video_cleanup_channel(hws, i);
496 }
497 return ret;
498 }
499
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
next prev parent reply other threads:[~2026-05-14 5:56 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-06 19:26 [PATCH v6] media: pci: add AVMatrix HWS capture driver Ben Hoff
2026-05-14 5:56 ` kernel test robot [this message]
2026-05-14 10:15 ` kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202605141318.V8xxhJE4-lkp@intel.com \
--to=lkp@intel.com \
--cc=hoff.benjamin.k@gmail.com \
--cc=hverkuil+cisco@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=oe-kbuild-all@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox