* [PATCH v2 0/2] media: pci: add AVMatrix HWS capture driver
[not found] <20260112022420.390854-1-hoff.benjamin.k@gmail.com>
@ 2026-03-18 0:10 ` Ben Hoff
2026-03-18 0:10 ` [PATCH v2 1/2] " Ben Hoff
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Ben Hoff @ 2026-03-18 0:10 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-kernel, Ben Hoff
Add an AVMatrix HWS PCIe capture driver and its MAINTAINERS entry.
The driver exposes one V4L2 capture node per input channel, supports
YUYV capture through vb2-dma-contig, reports DV timings, emits
SOURCE_CHANGE events, and provides the basic brightness/contrast/
saturation/hue controls used by the hardware.
Changes in v2:
- keep scratch DMA allocation on a single probe-owned path
- fix hws_video_register()/probe unwind ownership to avoid control-handler
double-free on late registration failures
- on live input resolution changes, emit SOURCE_CHANGE, error queued
buffers, and require userspace to renegotiate buffers and restart
streaming
- add enum_frameintervals and report DV_RX_POWER_PRESENT, addressing the
two v1 v4l2-compliance warnings
Testing for v2:
- build-tested with W=1:
make -C /home/hoff/swdev/linux O=/tmp/hws-build \
M=drivers/media/pci/hws W=1 KBUILD_MODPOST_WARN=1 modules
- checkpatch.pl --no-tree --strict --file ... is clean for the new files
Context carried forward from v1:
- audio support remains intentionally omitted from this submission
- the driver is derived from a GPL out-of-tree driver; the baseline tree is
available at https://github.com/benhoff/hws/tree/baseline
- a vendor driver bundle is available at
https://www.acasis.com/pages/acasis-product-drivers
- the vendor is not involved in this upstreaming effort
Ben Hoff (2):
media: pci: add AVMatrix HWS capture driver
MAINTAINERS: add entry for AVMatrix HWS driver
MAINTAINERS | 6 +
drivers/media/pci/Kconfig | 1 +
drivers/media/pci/Makefile | 1 +
drivers/media/pci/hws/Kconfig | 12 +
drivers/media/pci/hws/Makefile | 4 +
drivers/media/pci/hws/hws.h | 176 +++
drivers/media/pci/hws/hws_irq.c | 271 +++++
drivers/media/pci/hws/hws_irq.h | 10 +
drivers/media/pci/hws/hws_pci.c | 864 +++++++++++++
drivers/media/pci/hws/hws_reg.h | 144 +++
drivers/media/pci/hws/hws_v4l2_ioctl.c | 778 ++++++++++++
drivers/media/pci/hws/hws_v4l2_ioctl.h | 43 +
drivers/media/pci/hws/hws_video.c | 1546 ++++++++++++++++++++++++
drivers/media/pci/hws/hws_video.h | 29 +
14 files changed, 3885 insertions(+)
create mode 100644 drivers/media/pci/hws/Kconfig
create mode 100644 drivers/media/pci/hws/Makefile
create mode 100644 drivers/media/pci/hws/hws.h
create mode 100644 drivers/media/pci/hws/hws_irq.c
create mode 100644 drivers/media/pci/hws/hws_irq.h
create mode 100644 drivers/media/pci/hws/hws_pci.c
create mode 100644 drivers/media/pci/hws/hws_reg.h
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.c
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.h
create mode 100644 drivers/media/pci/hws/hws_video.c
create mode 100644 drivers/media/pci/hws/hws_video.h
base-commit: f0caa1d49cc07b30a7e2f104d3853ec6dc1c3cad
--
2.53.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 1/2] media: pci: add AVMatrix HWS capture driver
2026-03-18 0:10 ` [PATCH v2 0/2] media: pci: add AVMatrix HWS capture driver Ben Hoff
@ 2026-03-18 0:10 ` Ben Hoff
2026-03-24 9:17 ` Hans Verkuil
2026-03-18 0:10 ` [PATCH v2 2/2] MAINTAINERS: add entry for AVMatrix HWS driver Ben Hoff
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: Ben Hoff @ 2026-03-18 0:10 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-kernel, Ben Hoff
Add an in-tree AVMatrix HWS PCIe capture driver. The driver supports
up to four HDMI inputs and exposes the video capture path through
V4L2 with vb2-dma-contig streaming, DV timings, and per-input
controls. Audio support is intentionally omitted from this
submission.
This driver is derived from a GPL out-of-tree driver. The baseline
rework used for comparison is available at:
https://github.com/benhoff/hws/tree/baseline
A vendor driver bundle is available at:
https://www.acasis.com/pages/acasis-product-drivers
The vendor is not involved in this upstreaming effort.
This in-tree version folds in the review-driven cleanup needed for a
v2 posting:
- keep scratch DMA allocation on a single probe-owned path
- avoid double-freeing V4L2 control handlers on register unwind
- turn live mode changes into explicit SOURCE_CHANGE renegotiation
- report frame intervals and DV power-present status
Build-tested with:
make -C /home/hoff/swdev/linux O=/tmp/hws-build M=drivers/media/pci/hws W=1 KBUILD_MODPOST_WARN=1 modules
Signed-off-by: Ben Hoff <hoff.benjamin.k@gmail.com>
---
drivers/media/pci/Kconfig | 1 +
drivers/media/pci/Makefile | 1 +
drivers/media/pci/hws/Kconfig | 12 +
drivers/media/pci/hws/Makefile | 4 +
drivers/media/pci/hws/hws.h | 176 +++
drivers/media/pci/hws/hws_irq.c | 271 +++++
drivers/media/pci/hws/hws_irq.h | 10 +
drivers/media/pci/hws/hws_pci.c | 864 +++++++++++++
drivers/media/pci/hws/hws_reg.h | 144 +++
drivers/media/pci/hws/hws_v4l2_ioctl.c | 778 ++++++++++++
drivers/media/pci/hws/hws_v4l2_ioctl.h | 43 +
drivers/media/pci/hws/hws_video.c | 1546 ++++++++++++++++++++++++
drivers/media/pci/hws/hws_video.h | 29 +
13 files changed, 3879 insertions(+)
create mode 100644 drivers/media/pci/hws/Kconfig
create mode 100644 drivers/media/pci/hws/Makefile
create mode 100644 drivers/media/pci/hws/hws.h
create mode 100644 drivers/media/pci/hws/hws_irq.c
create mode 100644 drivers/media/pci/hws/hws_irq.h
create mode 100644 drivers/media/pci/hws/hws_pci.c
create mode 100644 drivers/media/pci/hws/hws_reg.h
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.c
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.h
create mode 100644 drivers/media/pci/hws/hws_video.c
create mode 100644 drivers/media/pci/hws/hws_video.h
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index eebb16c58f3d..bfdb200f85a3 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -13,6 +13,7 @@ if MEDIA_PCI_SUPPORT
if MEDIA_CAMERA_SUPPORT
comment "Media capture support"
+source "drivers/media/pci/hws/Kconfig"
source "drivers/media/pci/mgb4/Kconfig"
source "drivers/media/pci/solo6x10/Kconfig"
source "drivers/media/pci/tw5864/Kconfig"
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index 02763ad88511..c4508b6723a9 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
obj-$(CONFIG_VIDEO_CX25821) += cx25821/
obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_DT3155) += dt3155/
+obj-$(CONFIG_VIDEO_HWS) += hws/
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
obj-$(CONFIG_VIDEO_MGB4) += mgb4/
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
diff --git a/drivers/media/pci/hws/Kconfig b/drivers/media/pci/hws/Kconfig
new file mode 100644
index 000000000000..b606d5ffadef
--- /dev/null
+++ b/drivers/media/pci/hws/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_HWS
+ tristate "AVMatrix HWS capture driver"
+ depends on VIDEO_DEV && PCI
+ select VIDEOBUF2_DMA_CONTIG
+ help
+ This is a Video4Linux2 driver for AVMatrix HWS PCIe capture cards.
+ It provides a PCIe capture interface with V4L2 streaming, DV timings,
+ and per-input controls for the supported HWS boards.
+
+ To compile this driver as a module, choose M here: the module will
+ be called hws.
diff --git a/drivers/media/pci/hws/Makefile b/drivers/media/pci/hws/Makefile
new file mode 100644
index 000000000000..a66aebd348e5
--- /dev/null
+++ b/drivers/media/pci/hws/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+hws-objs := hws_pci.o hws_irq.o hws_video.o hws_v4l2_ioctl.o
+
+obj-$(CONFIG_VIDEO_HWS) += hws.o
diff --git a/drivers/media/pci/hws/hws.h b/drivers/media/pci/hws/hws.h
new file mode 100644
index 000000000000..097f6937b231
--- /dev/null
+++ b/drivers/media/pci/hws/hws.h
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_PCIE_H
+#define HWS_PCIE_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/sizes.h>
+#include <linux/atomic.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "hws_reg.h"
+
+struct hwsmem_param {
+ u32 index;
+ u32 type;
+ u32 status;
+};
+
+struct hws_pix_state {
+ u32 width;
+ u32 height;
+ u32 fourcc; /* V4L2_PIX_FMT_* (YUYV only here) */
+ u32 bytesperline; /* stride */
+ u32 sizeimage; /* full frame */
+ enum v4l2_field field; /* V4L2_FIELD_NONE or INTERLACED */
+ enum v4l2_colorspace colorspace; /* e.g., REC709 */
+ enum v4l2_ycbcr_encoding ycbcr_enc; /* V4L2_YCBCR_ENC_DEFAULT */
+ enum v4l2_quantization quantization; /* V4L2_QUANTIZATION_LIM_RANGE */
+ enum v4l2_xfer_func xfer_func; /* V4L2_XFER_FUNC_DEFAULT */
+ bool interlaced; /* cached hardware state */
+ u32 half_size; /* optional: if your HW needs it */
+};
+
+#define UNSET (-1U)
+
+struct hws_pcie_dev;
+struct hws_adapter;
+struct hws_video;
+
+struct hwsvideo_buffer {
+ struct vb2_v4l2_buffer vb;
+ struct list_head list;
+ int slot; /* for two-buffer approach */
+};
+
+struct hws_video {
+ /* ───── linkage ───── */
+ struct hws_pcie_dev *parent; /* parent device */
+ struct video_device *video_device;
+
+ struct vb2_queue buffer_queue;
+ struct list_head capture_queue;
+ struct hwsvideo_buffer *active;
+ struct hwsvideo_buffer *next_prepared;
+
+ /* ───── locking ───── */
+ struct mutex state_lock; /* primary state */
+ spinlock_t irq_lock; /* ISR-side */
+
+ /* ───── indices ───── */
+ int channel_index;
+
+ /* ───── colour controls ───── */
+ int current_brightness;
+ int current_contrast;
+ int current_saturation;
+ int current_hue;
+
+ /* ───── V4L2 controls ───── */
+ struct v4l2_ctrl_handler control_handler;
+ struct v4l2_ctrl *hotplug_detect_control;
+ struct v4l2_ctrl *ctrl_brightness;
+ struct v4l2_ctrl *ctrl_contrast;
+ struct v4l2_ctrl *ctrl_saturation;
+ struct v4l2_ctrl *ctrl_hue;
+ /* ───── capture queue status ───── */
+ struct hws_pix_state pix;
+ struct v4l2_dv_timings cur_dv_timings; /* last configured DV timings */
+ u32 current_fps; /* Hz, derived from mode or HW rate reg */
+ u32 alloc_sizeimage;
+
+ /* ───── per-channel capture state ───── */
+ bool cap_active;
+ bool stop_requested;
+ u8 last_buf_half_toggle;
+ bool half_seen;
+ atomic_t sequence_number;
+ u32 queued_count;
+
+ /* ───── timeout and error handling ───── */
+ u32 timeout_count;
+ u32 error_count;
+
+ bool window_valid;
+ u32 last_dma_hi;
+ u32 last_dma_page;
+ u32 last_pci_addr;
+ u32 last_half16;
+
+ /* ───── misc counters ───── */
+ int signal_loss_cnt;
+};
+
+static inline void hws_set_current_dv_timings(struct hws_video *vid,
+ u32 width, u32 height,
+ bool interlaced)
+{
+ if (!vid)
+ return;
+
+ vid->cur_dv_timings = (struct v4l2_dv_timings) {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = width,
+ .height = height,
+ .interlaced = interlaced,
+ },
+ };
+}
+
+struct hws_scratch_dma {
+ void *cpu;
+ dma_addr_t dma;
+ size_t size;
+};
+
+struct hws_pcie_dev {
+ /* ───── core objects ───── */
+ struct pci_dev *pdev;
+ struct hws_video video[MAX_VID_CHANNELS];
+
+ /* ───── BAR & workqueues ───── */
+ void __iomem *bar0_base;
+
+ /* ───── device identity / capabilities ───── */
+ u16 vendor_id;
+ u16 device_id;
+ u16 device_ver;
+ u16 hw_ver;
+ u32 sub_ver;
+ u32 port_id;
+ // TriState, used in `set_video_format_size`
+ u32 support_yv12;
+ u32 max_hw_video_buf_sz;
+ u8 max_channels;
+ u8 cur_max_video_ch;
+ bool start_run;
+
+ bool buf_allocated;
+
+ /* ───── V4L2 framework objects ───── */
+ struct v4l2_device v4l2_device;
+
+ /* ───── kernel thread ───── */
+ struct task_struct *main_task;
+ struct hws_scratch_dma scratch_vid[MAX_VID_CHANNELS];
+
+ bool suspended;
+ int irq;
+
+ /* ───── error flags ───── */
+ int pci_lost;
+
+};
+
+#endif
diff --git a/drivers/media/pci/hws/hws_irq.c b/drivers/media/pci/hws/hws_irq.c
new file mode 100644
index 000000000000..11f7dfde0eff
--- /dev/null
+++ b/drivers/media/pci/hws/hws_irq.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/compiler.h>
+#include <linux/moduleparam.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/minmax.h>
+#include <linux/string.h>
+
+#include <media/videobuf2-dma-contig.h>
+
+#include "hws_irq.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws.h"
+
+#define MAX_INT_LOOPS 100
+
+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 = &hws->video[ch];
+ unsigned long flags;
+ struct hwsvideo_buffer *buf;
+
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): stop=%d cap=%d queued=%d\n",
+ ch, READ_ONCE(v->stop_requested), READ_ONCE(v->cap_active),
+ !list_empty(&v->capture_queue));
+
+ if (unlikely(READ_ONCE(hws->suspended))) {
+ dev_dbg(&hws->pdev->dev, "arm_next(ch=%u): suspended\n", ch);
+ return -EBUSY;
+ }
+
+ if (unlikely(READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active))) {
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): stop=%d cap=%d -> cancel\n", ch,
+ v->stop_requested, v->cap_active);
+ return -ECANCELED;
+ }
+
+ 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=%u): queue empty\n", ch);
+ return -EAGAIN;
+ }
+
+ buf = list_first_entry(&v->capture_queue, struct hwsvideo_buffer, list);
+ list_del_init(&buf->list); /* keep buffer safe for later cleanup */
+ if (v->queued_count)
+ v->queued_count--;
+ v->active = buf;
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ dev_dbg(&hws->pdev->dev, "arm_next(ch=%u): picked buffer %p\n", ch,
+ buf);
+
+ /* Publish descriptor(s) before doorbell/MMIO kicks. */
+ wmb();
+
+ /* Avoid MMIO during suspend */
+ if (unlikely(READ_ONCE(hws->suspended))) {
+ unsigned long f;
+
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): suspended after pick\n", ch);
+ spin_lock_irqsave(&v->irq_lock, f);
+ if (v->active) {
+ list_add(&buf->list, &v->capture_queue);
+ v->queued_count++;
+ v->active = NULL;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, f);
+ return -EBUSY;
+ }
+
+ /* Also program the DMA address register directly */
+ {
+ dma_addr_t dma_addr =
+ vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(hws, ch, dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base + HWS_REG_DMA_ADDR(ch));
+ }
+
+ dev_dbg(&hws->pdev->dev, "arm_next(ch=%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);
+ return 0;
+}
+
+static void hws_video_handle_vdone(struct hws_video *v)
+{
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned int ch = v->channel_index;
+ struct hwsvideo_buffer *done;
+ unsigned long flags;
+ bool promoted = false;
+
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): stop=%d cap=%d active=%p\n",
+ ch, READ_ONCE(v->stop_requested), READ_ONCE(v->cap_active),
+ v->active);
+
+ int ret;
+
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): entry stop=%d cap=%d\n", ch,
+ v->stop_requested, v->cap_active);
+ if (unlikely(READ_ONCE(hws->suspended)))
+ return;
+
+ if (unlikely(READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active)))
+ return;
+
+ spin_lock_irqsave(&v->irq_lock, flags);
+ done = v->active;
+ if (done && v->next_prepared) {
+ v->active = v->next_prepared;
+ v->next_prepared = NULL;
+ promoted = true;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* 1) Complete the buffer the HW just finished (if any) */
+ if (done) {
+ struct vb2_v4l2_buffer *vb2v = &done->vb;
+ size_t expected = v->pix.sizeimage;
+ size_t plane_size = vb2_plane_size(&vb2v->vb2_buf, 0);
+
+ if (unlikely(expected > plane_size)) {
+ dev_warn_ratelimited(&hws->pdev->dev,
+ "bh_video(ch=%u): sizeimage %zu > plane %zu, dropping seq=%u\n",
+ ch, expected, plane_size,
+ (u32)atomic_read(&v->sequence_number) + 1);
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_ERROR);
+ goto arm_next;
+ }
+ vb2_set_plane_payload(&vb2v->vb2_buf, 0, expected);
+
+ dma_rmb(); /* device writes visible before userspace sees it */
+
+ vb2v->sequence = (u32)atomic_inc_return(&v->sequence_number);
+ vb2v->vb2_buf.timestamp = ktime_get_ns();
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): DONE buf=%p seq=%u half_seen=%d toggle=%u\n",
+ ch, done, vb2v->sequence, v->half_seen,
+ v->last_buf_half_toggle);
+
+ if (!promoted)
+ v->active = NULL; /* channel no longer owns this buffer */
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+
+ if (unlikely(READ_ONCE(hws->suspended)))
+ return;
+
+ if (promoted) {
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): promoted pre-armed buffer active=%p\n",
+ ch, v->active);
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_prime_next_locked(v);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ return;
+ }
+
+arm_next:
+ /* 2) Immediately arm the next queued buffer (if present) */
+ ret = hws_arm_next(hws, ch);
+ if (ret == -EAGAIN) {
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): no queued buffer to arm\n", ch);
+ return;
+ }
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): armed next buffer, active=%p\n", ch,
+ v->active);
+ /* On success the engine now points at v->active’s DMA address */
+}
+
+irqreturn_t hws_irq_handler(int irq, void *info)
+{
+ struct hws_pcie_dev *pdx = info;
+ u32 int_state;
+
+ dev_dbg(&pdx->pdev->dev, "irq: entry\n");
+ if (likely(pdx->bar0_base)) {
+ dev_dbg(&pdx->pdev->dev,
+ "irq: INT_EN=0x%08x INT_STATUS=0x%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 (unlikely(READ_ONCE(pdx->suspended))) {
+ int_state = 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;
+ }
+ // u32 sys_status = readl(pdx->bar0_base + HWS_REG_SYS_STATUS);
+
+ int_state = readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ if (!int_state || int_state == 0xFFFFFFFF) {
+ dev_dbg(&pdx->pdev->dev,
+ "irq: spurious or device-gone int_state=0x%08x\n",
+ int_state);
+ return IRQ_NONE;
+ }
+ dev_dbg(&pdx->pdev->dev, "irq: entry INT_STATUS=0x%08x\n", int_state);
+
+ /* Loop until all pending bits are serviced (max 100 iterations) */
+ for (u32 cnt = 0; int_state && cnt < MAX_INT_LOOPS; ++cnt) {
+ for (unsigned int ch = 0; ch < pdx->cur_max_video_ch; ++ch) {
+ u32 vbit = HWS_INT_VDONE_BIT(ch);
+
+ if (!(int_state & vbit))
+ continue;
+
+ if (likely(READ_ONCE(pdx->video[ch].cap_active) &&
+ !READ_ONCE(pdx->video[ch].stop_requested))) {
+ if (unlikely(hws_toggle_debug)) {
+ u32 toggle =
+ 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=%u toggle=%u handling inline (cap=%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=%u ignored (cap=%d stop=%d)\n",
+ ch,
+ READ_ONCE(pdx->video[ch].cap_active),
+ READ_ONCE(pdx->video[ch].stop_requested));
+ }
+
+ writel(vbit, pdx->bar0_base + HWS_REG_INT_STATUS);
+ (void)readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ /* Re‐read in case new interrupt bits popped while processing */
+ int_state = readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ dev_dbg(&pdx->pdev->dev,
+ "irq: loop cnt=%u new INT_STATUS=0x%08x\n", cnt,
+ int_state);
+ if (cnt + 1 == MAX_INT_LOOPS)
+ dev_warn_ratelimited(&pdx->pdev->dev,
+ "IRQ storm? status=0x%08x\n",
+ int_state);
+ }
+
+ return IRQ_HANDLED;
+}
diff --git a/drivers/media/pci/hws/hws_irq.h b/drivers/media/pci/hws/hws_irq.h
new file mode 100644
index 000000000000..a42867aa0c46
--- /dev/null
+++ b/drivers/media/pci/hws/hws_irq.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_INTERRUPT_H
+#define HWS_INTERRUPT_H
+
+#include <linux/pci.h>
+#include "hws.h"
+
+irqreturn_t hws_irq_handler(int irq, void *info);
+
+#endif /* HWS_INTERRUPT_H */
diff --git a/drivers/media/pci/hws/hws_pci.c b/drivers/media/pci/hws/hws_pci.c
new file mode 100644
index 000000000000..5f106d268b74
--- /dev/null
+++ b/drivers/media/pci/hws/hws_pci.c
@@ -0,0 +1,864 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/iopoll.h>
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/ktime.h>
+#include <linux/pm.h>
+#include <linux/freezer.h>
+#include <linux/pci_regs.h>
+
+#include <media/v4l2-ctrls.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_irq.h"
+#include "hws_v4l2_ioctl.h"
+
+#define DRV_NAME "hws"
+#define DRV_DESC "AVMatrix HWS capture driver"
+#define HWS_BUSY_POLL_DELAY_US 10
+#define HWS_BUSY_POLL_TIMEOUT_US 1000000
+
+/* register layout inside HWS_REG_DEVICE_INFO */
+#define DEVINFO_VER GENMASK(7, 0)
+#define DEVINFO_SUBVER GENMASK(15, 8)
+#define DEVINFO_YV12 GENMASK(31, 28)
+#define DEVINFO_HWKEY GENMASK(27, 24)
+#define DEVINFO_PORTID GENMASK(25, 24) /* low 2 bits of HW-key */
+
+#define MAKE_ENTRY(__vend, __chip, __subven, __subdev, __configptr) \
+ { .vendor = (__vend), \
+ .device = (__chip), \
+ .subvendor = (__subven), \
+ .subdevice = (__subdev), \
+ .driver_data = (unsigned long)(__configptr) }
+
+/*
+ * PCI IDs for HWS family cards.
+ *
+ * The subsystem IDs are fixed at 0x8888:0x0007 for this family. Some boards
+ * enumerate with vendor ID 0x8888 or 0x1f33. Exact SKU names are not fully
+ * pinned down yet; update these comments when vendor documentation or INF
+ * strings are available.
+ */
+static const struct pci_device_id hws_pci_table[] = {
+ /* HWS family, SKU unknown. */
+ MAKE_ENTRY(0x8888, 0x9534, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x8534, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x8554, 0x8888, 0x0007, NULL),
+
+ /* HWS 2x2 HDMI family. */
+ MAKE_ENTRY(0x8888, 0x8524, 0x8888, 0x0007, NULL),
+ /* HWS 2x2 SDI family. */
+ MAKE_ENTRY(0x1F33, 0x6524, 0x8888, 0x0007, NULL),
+
+ /* HWS X4 HDMI family. */
+ MAKE_ENTRY(0x8888, 0x8504, 0x8888, 0x0007, NULL),
+ /* HWS X4 SDI family. */
+ MAKE_ENTRY(0x8888, 0x6504, 0x8888, 0x0007, NULL),
+
+ /* HWS family, SKU unknown. */
+ MAKE_ENTRY(0x8888, 0x8532, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x8888, 0x8512, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x8888, 0x8501, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x6502, 0x8888, 0x0007, NULL),
+
+ /* HWS X4 HDMI family (alternate vendor ID). */
+ MAKE_ENTRY(0x1F33, 0x8504, 0x8888, 0x0007, NULL),
+ /* HWS 2x2 HDMI family (alternate vendor ID). */
+ MAKE_ENTRY(0x1F33, 0x8524, 0x8888, 0x0007, NULL),
+
+ {}
+};
+
+static void enable_pcie_relaxed_ordering(struct pci_dev *dev)
+{
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
+}
+
+static void hws_configure_hardware_capabilities(struct hws_pcie_dev *hdev)
+{
+ u16 id = hdev->device_id;
+
+ /* select per-chip channel counts */
+ switch (id) {
+ case 0x9534:
+ case 0x6524:
+ case 0x8524:
+ case 0x8504:
+ case 0x6504:
+ hdev->cur_max_video_ch = 4;
+ break;
+ case 0x8532:
+ hdev->cur_max_video_ch = 2;
+ break;
+ case 0x8512:
+ case 0x6502:
+ hdev->cur_max_video_ch = 2;
+ break;
+ case 0x8501:
+ hdev->cur_max_video_ch = 1;
+ break;
+ default:
+ hdev->cur_max_video_ch = 4;
+ break;
+ }
+
+ /* universal buffer capacity */
+ hdev->max_hw_video_buf_sz = MAX_MM_VIDEO_SIZE;
+
+ /* decide hardware-version and program DMA max size if needed */
+ if (hdev->device_ver > 121) {
+ if (id == 0x8501 && hdev->device_ver == 122) {
+ hdev->hw_ver = 0;
+ } else {
+ hdev->hw_ver = 1;
+ u32 dma_max = (u32)(MAX_VIDEO_SCALER_SIZE / 16);
+
+ writel(dma_max, hdev->bar0_base + HWS_REG_DMA_MAX_SIZE);
+ /* readback to flush posted MMIO write */
+ (void)readl(hdev->bar0_base + HWS_REG_DMA_MAX_SIZE);
+ }
+ } else {
+ hdev->hw_ver = 0;
+ }
+}
+
+static void hws_stop_device(struct hws_pcie_dev *hws);
+
+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 = &hws->pdev->dev;
+ if (!hws->bar0_base) {
+ dev_dbg(dev,
+ "lifecycle:%s:%s bar0-unmapped suspended=%d start_run=%d pci_lost=%d irq=%d\n",
+ action, phase, READ_ONCE(hws->suspended), hws->start_run,
+ hws->pci_lost, hws->irq);
+ return;
+ }
+
+ int_en = readl(hws->bar0_base + INT_EN_REG_BASE);
+ int_status = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ vcap = readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ sys_status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+ dec_mode = readl(hws->bar0_base + HWS_REG_DEC_MODE);
+
+ dev_dbg(dev,
+ "lifecycle:%s:%s suspended=%d start_run=%d pci_lost=%d irq=%d INT_EN=0x%08x INT_STATUS=0x%08x VCAP=0x%08x SYS=0x%08x DEC=0x%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;
+ /* mirror PCI IDs for later switches */
+ hdev->device_id = hdev->pdev->device;
+ hdev->vendor_id = hdev->pdev->vendor;
+
+ reg = readl(hdev->bar0_base + HWS_REG_DEVICE_INFO);
+
+ hdev->device_ver = FIELD_GET(DEVINFO_VER, reg);
+ hdev->sub_ver = FIELD_GET(DEVINFO_SUBVER, reg);
+ hdev->support_yv12 = FIELD_GET(DEVINFO_YV12, reg);
+ hdev->port_id = FIELD_GET(DEVINFO_PORTID, reg);
+
+ hdev->max_hw_video_buf_sz = MAX_MM_VIDEO_SIZE;
+ hdev->max_channels = 4;
+ hdev->buf_allocated = false;
+ hdev->main_task = NULL;
+ hdev->start_run = false;
+ hdev->pci_lost = 0;
+
+ writel(0x00, hdev->bar0_base + HWS_REG_DEC_MODE);
+ writel(0x10, hdev->bar0_base + HWS_REG_DEC_MODE);
+
+ hws_configure_hardware_capabilities(hdev);
+
+ dev_info(&hdev->pdev->dev,
+ "chip detected: ver=%u subver=%u port=%u yv12=%u\n",
+ hdev->device_ver, hdev->sub_ver, hdev->port_id,
+ hdev->support_yv12);
+
+ return 0;
+}
+
+static int main_ks_thread_handle(void *data)
+{
+ struct hws_pcie_dev *pdx = data;
+
+ set_freezable();
+
+ while (!kthread_should_stop()) {
+ /* If we’re suspending, don’t touch hardware; just sleep/freeeze */
+ if (READ_ONCE(pdx->suspended)) {
+ try_to_freeze();
+ schedule_timeout_interruptible(msecs_to_jiffies(1000));
+ continue;
+ }
+
+ /* avoid MMIO when suspended (guarded above) */
+ check_video_format(pdx);
+
+ try_to_freeze(); /* cooperate with freezer each loop */
+
+ /* Sleep 1s or until signaled to wake/stop */
+ schedule_timeout_interruptible(msecs_to_jiffies(1000));
+ }
+
+ dev_dbg(&pdx->pdev->dev, "%s: exiting\n", __func__);
+ return 0;
+}
+
+static void hws_stop_kthread_action(void *data)
+{
+ struct hws_pcie_dev *hws = data;
+ struct task_struct *t;
+ u64 start_ns;
+
+ if (!hws)
+ return;
+
+ t = READ_ONCE(hws->main_task);
+ if (!IS_ERR_OR_NULL(t)) {
+ start_ns = ktime_get_mono_fast_ns();
+ dev_dbg(&hws->pdev->dev,
+ "lifecycle:kthread-stop:begin task=%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",
+ (unsigned long long)
+ ((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ }
+}
+
+static int hws_alloc_seed_buffers(struct hws_pcie_dev *hws)
+{
+ int ch;
+ /* 64 KiB is plenty for a safe dummy; align to 64 for your HW */
+ const size_t need = ALIGN(64 * 1024, 64);
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+#if defined(CONFIG_HAS_DMA) /* normal on PCIe platforms */
+ void *cpu = dma_alloc_coherent(&hws->pdev->dev, need,
+ &hws->scratch_vid[ch].dma,
+ GFP_KERNEL);
+#else
+ void *cpu = NULL;
+#endif
+ if (!cpu) {
+ dev_warn(&hws->pdev->dev,
+ "scratch: dma_alloc_coherent failed ch=%d\n", ch);
+ /* not fatal: free earlier ones and continue without seeding */
+ while (--ch >= 0) {
+ if (hws->scratch_vid[ch].cpu)
+ dma_free_coherent(&hws->pdev->dev,
+ hws->scratch_vid[ch].size,
+ hws->scratch_vid[ch].cpu,
+ hws->scratch_vid[ch].dma);
+ hws->scratch_vid[ch].cpu = NULL;
+ hws->scratch_vid[ch].size = 0;
+ }
+ return -ENOMEM;
+ }
+ hws->scratch_vid[ch].cpu = cpu;
+ hws->scratch_vid[ch].size = need;
+ }
+ return 0;
+}
+
+static void hws_free_seed_buffers(struct hws_pcie_dev *hws)
+{
+ int ch;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+ if (hws->scratch_vid[ch].cpu) {
+ dma_free_coherent(&hws->pdev->dev,
+ hws->scratch_vid[ch].size,
+ hws->scratch_vid[ch].cpu,
+ hws->scratch_vid[ch].dma);
+ hws->scratch_vid[ch].cpu = NULL;
+ hws->scratch_vid[ch].size = 0;
+ }
+ }
+}
+
+static void hws_seed_channel(struct hws_pcie_dev *hws, int ch)
+{
+ dma_addr_t paddr = hws->scratch_vid[ch].dma;
+ u32 lo = lower_32_bits(paddr);
+ u32 hi = upper_32_bits(paddr);
+ u32 pci_addr = lo & PCI_E_BAR_ADD_LOWMASK;
+
+ lo &= PCI_E_BAR_ADD_MASK;
+
+ /* Program 64-bit BAR remap entry for this channel (table @ 0x208 + ch * 8) */
+ writel_relaxed(hi, hws->bar0_base +
+ PCI_ADDR_TABLE_BASE + 0x208 + ch * 8);
+ writel_relaxed(lo, hws->bar0_base +
+ PCI_ADDR_TABLE_BASE + 0x208 + ch * 8 +
+ PCIE_BARADDROFSIZE);
+
+ /* Program capture engine per-channel base/half */
+ writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
+ hws->bar0_base + CVBS_IN_BUF_BASE +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* half size: use either the current format’s half or half of scratch */
+ {
+ u32 half = hws->video[ch].pix.half_size ?
+ hws->video[ch].pix.half_size :
+ (u32)(hws->scratch_vid[ch].size / 2);
+
+ writel_relaxed(half / 16,
+ hws->bar0_base + CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+ }
+
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS); /* flush posted writes */
+}
+
+static void hws_seed_all_channels(struct hws_pcie_dev *hws)
+{
+ int ch;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+ if (hws->scratch_vid[ch].cpu)
+ hws_seed_channel(hws, ch);
+ }
+}
+
+static void hws_irq_mask_gate(struct hws_pcie_dev *hws)
+{
+ writel(0x00000000, hws->bar0_base + INT_EN_REG_BASE);
+ (void)readl(hws->bar0_base + INT_EN_REG_BASE);
+}
+
+static void hws_irq_unmask_gate(struct hws_pcie_dev *hws)
+{
+ writel(HWS_INT_EN_MASK, hws->bar0_base + INT_EN_REG_BASE);
+ (void)readl(hws->bar0_base + INT_EN_REG_BASE);
+}
+
+static void hws_irq_clear_pending(struct hws_pcie_dev *hws)
+{
+ u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+
+ if (st) {
+ writel(st, hws->bar0_base + HWS_REG_INT_STATUS); /* W1C */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+}
+
+static void hws_block_hotpaths(struct hws_pcie_dev *hws)
+{
+ WRITE_ONCE(hws->suspended, true);
+ if (hws->irq >= 0)
+ disable_irq(hws->irq);
+
+ if (!hws->bar0_base)
+ return;
+
+ hws_irq_mask_gate(hws);
+ hws_irq_clear_pending(hws);
+}
+
+static int hws_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+ struct hws_pcie_dev *hws;
+ int i, ret, irq;
+ unsigned long irqf = 0;
+ bool v4l2_registered = false;
+
+ /* devres-backed device object */
+ hws = devm_kzalloc(&pdev->dev, sizeof(*hws), GFP_KERNEL);
+ if (!hws)
+ return -ENOMEM;
+
+ hws->pdev = pdev;
+ hws->irq = -1;
+ hws->suspended = false;
+ pci_set_drvdata(pdev, hws);
+
+ /* 1) Enable device + bus mastering (managed) */
+ ret = pcim_enable_device(pdev);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "pcim_enable_device\n");
+ pci_set_master(pdev);
+
+ /* 2) Map BAR0 (managed) */
+ ret = pcim_iomap_regions(pdev, BIT(0), KBUILD_MODNAME);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "pcim_iomap_regions BAR0\n");
+ hws->bar0_base = pcim_iomap_table(pdev)[0];
+
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+ if (ret) {
+ dev_warn(&pdev->dev,
+ "64-bit DMA mask unavailable, falling back to 32-bit (%d)\n",
+ ret);
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ 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");
+ }
+
+ /* 3) Optional PCIe tuning (same as before) */
+ enable_pcie_relaxed_ordering(pdev);
+#ifdef CONFIG_ARCH_TI816X
+ pcie_set_readrq(pdev, 128);
+#endif
+
+ /* 4) Identify chip & capabilities */
+ read_chip_id(hws);
+ dev_info(&pdev->dev, "Device VID=0x%04x DID=0x%04x\n",
+ pdev->vendor, pdev->device);
+ hws_init_video_sys(hws, false);
+
+ /* 5) Init channels (video state, locks, vb2, ctrls) */
+ for (i = 0; i < hws->max_channels; i++) {
+ ret = hws_video_init_channel(hws, i);
+ if (ret) {
+ dev_err(&pdev->dev, "video channel init failed (ch=%d)\n", i);
+ goto err_unwind_channels;
+ }
+ }
+
+ /* 6) Allocate scratch DMA and seed BAR table + channel base/half (legacy SetDMAAddress) */
+ ret = hws_alloc_seed_buffers(hws);
+ if (!ret)
+ hws_seed_all_channels(hws);
+
+ /* 7) Start-run sequence (like InitVideoSys) */
+ hws_init_video_sys(hws, false);
+
+ /* A) Force legacy INTx; legacy used request_irq(pdev->irq, ..., IRQF_SHARED) */
+ pci_intx(pdev, 1);
+ irqf = IRQF_SHARED;
+ irq = pdev->irq;
+ hws->irq = irq;
+ dev_info(&pdev->dev, "IRQ mode: legacy INTx (shared), irq=%d\n", irq);
+
+ /* B) Mask the device's global/bridge gate (INT_EN_REG_BASE) */
+ hws_irq_mask_gate(hws);
+
+ /* C) Clear any sticky pending interrupt status (W1C) before we arm the line */
+ hws_irq_clear_pending(hws);
+
+ /* D) Request the legacy shared interrupt line (no vectors/MSI/MSI-X) */
+ ret = devm_request_irq(&pdev->dev, irq, hws_irq_handler, irqf,
+ dev_name(&pdev->dev), hws);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq(%d) failed: %d\n", irq, ret);
+ goto err_unwind_channels;
+ }
+
+ /* E) Set the global interrupt enable bit in main control register */
+ {
+ u32 ctl_reg = readl(hws->bar0_base + HWS_REG_CTL);
+
+ ctl_reg |= 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");
+ }
+
+ /* F) Open the global gate just like legacy did */
+ hws_irq_unmask_gate(hws);
+ dev_info(&pdev->dev, "INT_EN_GATE readback=0x%08x\n",
+ readl(hws->bar0_base + INT_EN_REG_BASE));
+
+ /* 11) Register V4L2 */
+ ret = hws_video_register(hws);
+ if (ret) {
+ dev_err(&pdev->dev, "video_register: %d\n", ret);
+ goto err_unwind_channels;
+ }
+ v4l2_registered = true;
+
+ /* 12) Background monitor thread (managed) */
+ hws->main_task = kthread_run(main_ks_thread_handle, hws, "hws-mon");
+ if (IS_ERR(hws->main_task)) {
+ ret = PTR_ERR(hws->main_task);
+ hws->main_task = NULL;
+ dev_err(&pdev->dev, "kthread_run: %d\n", ret);
+ goto err_unregister_va;
+ }
+ ret = devm_add_action_or_reset(&pdev->dev, hws_stop_kthread_action, hws);
+ if (ret) {
+ dev_err(&pdev->dev, "devm_add_action kthread_stop: %d\n", ret);
+ goto err_unregister_va; /* reset already stopped the thread */
+ }
+
+ /* 13) Final: show the line is armed */
+ dev_info(&pdev->dev, "irq handler installed on irq=%d\n", irq);
+ return 0;
+
+err_unregister_va:
+ hws_stop_device(hws);
+ hws_video_unregister(hws);
+ hws_free_seed_buffers(hws);
+ return ret;
+err_unwind_channels:
+ hws_free_seed_buffers(hws);
+ if (!v4l2_registered) {
+ while (--i >= 0)
+ hws_video_cleanup_channel(hws, i);
+ }
+ return ret;
+}
+
+static int hws_check_busy(struct hws_pcie_dev *pdx)
+{
+ void __iomem *reg = pdx->bar0_base + HWS_REG_SYS_STATUS;
+ u32 val;
+ int ret;
+
+ /* poll until !(val & BUSY_BIT), sleeping HWS_BUSY_POLL_DELAY_US between reads */
+ ret = readl_poll_timeout(reg, val, !(val & HWS_SYS_DMA_BUSY_BIT),
+ HWS_BUSY_POLL_DELAY_US,
+ HWS_BUSY_POLL_TIMEOUT_US);
+ if (ret) {
+ dev_err(&pdx->pdev->dev,
+ "SYS_STATUS busy bit never cleared (0x%08x)\n", val);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static void hws_stop_dsp(struct hws_pcie_dev *hws)
+{
+ u32 status;
+
+ /* Read the decoder mode/status register */
+ status = readl(hws->bar0_base + HWS_REG_DEC_MODE);
+ dev_dbg(&hws->pdev->dev, "%s: status=0x%08x\n", __func__, status);
+
+ /* If the device looks unplugged/stuck, bail out */
+ if (status == 0xFFFFFFFF)
+ return;
+
+ /* Tell the DSP to stop */
+ writel(0x10, hws->bar0_base + HWS_REG_DEC_MODE);
+
+ if (hws_check_busy(hws))
+ dev_warn(&hws->pdev->dev, "DSP busy timeout on stop\n");
+ /* Disable video capture engine in the DSP */
+ writel(0x0, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+}
+
+/* Publish stop so ISR/BH won’t touch video buffers anymore. */
+static void hws_publish_stop_flags(struct hws_pcie_dev *hws)
+{
+ unsigned int i;
+
+ for (i = 0; i < hws->cur_max_video_ch; ++i) {
+ struct hws_video *v = &hws->video[i];
+
+ WRITE_ONCE(v->cap_active, false);
+ WRITE_ONCE(v->stop_requested, true);
+ }
+
+ smp_wmb(); /* make flags visible before we touch MMIO/queues */
+}
+
+/* Drain engines + ISR/BH after flags are published. */
+static void hws_drain_after_stop(struct hws_pcie_dev *hws)
+{
+ u32 ackmask = 0;
+ unsigned int i;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ /* Mask device enables: no new DMA starts. */
+ writel(0x0, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS); /* flush */
+
+ /* Let any in-flight DMAs finish (best-effort). */
+ (void)hws_check_busy(hws);
+
+ /* Ack any latched VDONE. */
+ for (i = 0; i < hws->cur_max_video_ch; ++i)
+ ackmask |= HWS_INT_VDONE_BIT(i);
+ if (ackmask) {
+ writel(ackmask, hws->bar0_base + HWS_REG_INT_STATUS);
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ /* Ensure no hard IRQ is still running. */
+ if (hws->irq >= 0)
+ synchronize_irq(hws->irq);
+
+ dev_dbg(&hws->pdev->dev, "lifecycle:drain-after-stop:done (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+}
+
+static void hws_stop_device(struct hws_pcie_dev *hws)
+{
+ u32 status = readl(hws->bar0_base + HWS_REG_PIPE_BASE(0));
+ u64 start_ns = ktime_get_mono_fast_ns();
+ bool live = status != 0xFFFFFFFF;
+
+ dev_dbg(&hws->pdev->dev, "%s: status=0x%08x\n", __func__, status);
+ if (!live) {
+ hws->pci_lost = true;
+ goto out;
+ }
+ hws_log_lifecycle_snapshot(hws, "stop-device", "begin");
+
+ /* Make ISR/BH a no-op, then drain engines/IRQ. */
+ hws_publish_stop_flags(hws);
+ hws_drain_after_stop(hws);
+
+ /* 1) Stop the on-board DSP */
+ hws_stop_dsp(hws);
+
+out:
+ hws->start_run = 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",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ dev_dbg(&hws->pdev->dev, "%s: complete\n", __func__);
+}
+
+static int hws_quiesce_for_transition(struct hws_pcie_dev *hws,
+ const char *action,
+ bool stop_thread)
+{
+ struct device *dev = &hws->pdev->dev;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+ int vret;
+
+ hws_log_lifecycle_snapshot(hws, action, "begin");
+
+ step_ns = ktime_get_mono_fast_ns();
+ hws_block_hotpaths(hws);
+ dev_dbg(dev, "lifecycle:%s:block-hotpaths (%lluus)\n", action,
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ hws_log_lifecycle_snapshot(hws, action, "blocked");
+
+ if (stop_thread) {
+ step_ns = ktime_get_mono_fast_ns();
+ hws_stop_kthread_action(hws);
+ dev_dbg(dev, "lifecycle:%s:stop-kthread (%lluus)\n", action,
+ (unsigned long long)
+ ((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ }
+
+ step_ns = ktime_get_mono_fast_ns();
+ vret = hws_video_quiesce(hws, action);
+ dev_dbg(dev, "lifecycle:%s:video-quiesce ret=%d (%lluus)\n", action,
+ vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ if (vret)
+ dev_warn(dev, "lifecycle:%s video quiesce returned %d\n",
+ action, vret);
+
+ step_ns = ktime_get_mono_fast_ns();
+ hws_stop_device(hws);
+ dev_dbg(dev, "lifecycle:%s:stop-device (%lluus)\n", action,
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ hws_log_lifecycle_snapshot(hws, action, "end");
+ dev_dbg(dev, "lifecycle:%s:quiesce-done ret=%d (%lluus)\n", action,
+ vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+
+ return vret;
+}
+
+static void hws_remove(struct pci_dev *pdev)
+{
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ u64 start_ns;
+
+ if (!hws)
+ return;
+
+ start_ns = 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);
+
+ /* Stop hardware / capture cleanly (your helper) */
+ hws_stop_device(hws);
+
+ /* Unregister subsystems you registered */
+ hws_video_unregister(hws);
+
+ /* Release seeded DMA buffers */
+ hws_free_seed_buffers(hws);
+ /* kthread is stopped by the devm action you added in probe */
+ hws_log_lifecycle_snapshot(hws, "remove", "end");
+ dev_info(&pdev->dev, "lifecycle:remove done (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int hws_pm_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int vret;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ dev_info(dev, "lifecycle:pm_suspend begin\n");
+ vret = hws_quiesce_for_transition(hws, "pm_suspend", false);
+
+ step_ns = 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",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ dev_info(dev, "lifecycle:pm_suspend done ret=%d (%lluus)\n", vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+
+ return 0;
+}
+
+static int hws_pm_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int ret;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ dev_info(dev, "lifecycle:pm_resume begin\n");
+
+ /* Back to D0 and re-enable the function */
+ step_ns = ktime_get_mono_fast_ns();
+ pci_set_power_state(pdev, PCI_D0);
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(dev, "pci_enable_device: %d\n", ret);
+ return ret;
+ }
+ pci_restore_state(pdev);
+ pci_set_master(pdev);
+ dev_dbg(dev, "lifecycle:pm_resume:pci-enable (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+
+ /* Reapply any PCIe tuning lost across D3 */
+ enable_pcie_relaxed_ordering(pdev);
+
+ /* Reinitialize chip-side capabilities / registers */
+ step_ns = 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",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+
+ /* IRQs can be re-enabled now that MMIO is sane */
+ step_ns = ktime_get_mono_fast_ns();
+ if (hws->irq >= 0)
+ enable_irq(hws->irq);
+
+ WRITE_ONCE(hws->suspended, false);
+ dev_dbg(dev, "lifecycle:pm_resume:irq-unsuspend (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+
+ /* vb2: nothing mandatory; userspace will STREAMON again when ready */
+ step_ns = ktime_get_mono_fast_ns();
+ hws_video_pm_resume(hws);
+ dev_dbg(dev, "lifecycle:pm_resume:video-resume (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ hws_log_lifecycle_snapshot(hws, "pm_resume", "end");
+ dev_info(dev, "lifecycle:pm_resume done (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(hws_pm_ops, hws_pm_suspend, hws_pm_resume);
+# define HWS_PM_OPS (&hws_pm_ops)
+#else
+# define HWS_PM_OPS NULL
+#endif
+
+static void hws_shutdown(struct pci_dev *pdev)
+{
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int vret = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ if (!hws)
+ return;
+
+ dev_info(&pdev->dev, "lifecycle:pci_shutdown begin\n");
+ vret = hws_quiesce_for_transition(hws, "pci_shutdown", true);
+
+ step_ns = ktime_get_mono_fast_ns();
+ pci_clear_master(pdev);
+ dev_dbg(&pdev->dev, "lifecycle:pci_shutdown:clear-master (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ dev_info(&pdev->dev, "lifecycle:pci_shutdown done ret=%d (%lluus)\n",
+ vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+}
+
+static struct pci_driver hws_pci_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = hws_pci_table,
+ .probe = hws_probe,
+ .remove = hws_remove,
+ .shutdown = hws_shutdown,
+ .driver = {
+ .pm = HWS_PM_OPS,
+ },
+};
+
+MODULE_DEVICE_TABLE(pci, hws_pci_table);
+
+static int __init pcie_hws_init(void)
+{
+ return pci_register_driver(&hws_pci_driver);
+}
+
+static void __exit pcie_hws_exit(void)
+{
+ pci_unregister_driver(&hws_pci_driver);
+}
+
+module_init(pcie_hws_init);
+module_exit(pcie_hws_exit);
+
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_AUTHOR("Ben Hoff <hoff.benjamin.k@gmail.com>");
+MODULE_AUTHOR("Sales <sales@avmatrix.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("DMA_BUF");
diff --git a/drivers/media/pci/hws/hws_reg.h b/drivers/media/pci/hws/hws_reg.h
new file mode 100644
index 000000000000..224573595240
--- /dev/null
+++ b/drivers/media/pci/hws/hws_reg.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _HWS_PCIE_REG_H
+#define _HWS_PCIE_REG_H
+
+#include <linux/bits.h>
+#include <linux/sizes.h>
+
+#define XDMA_CHANNEL_NUM_MAX (1)
+#define MAX_NUM_ENGINES (XDMA_CHANNEL_NUM_MAX * 2)
+
+#define PCIE_BARADDROFSIZE 4u
+
+#define PCI_BUS_ACCESS_BASE 0x00000000U
+#define INT_EN_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0134U)
+#define PCIEBR_EN_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0148U)
+#define PCIE_INT_DEC_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0138U)
+
+#define HWS_INT_EN_MASK 0x0003FFFFU
+
+#define PCIEBAR_AXI_BASE 0x20000000U
+
+#define CTL_REG_ACC_BASE 0x0
+#define PCI_ADDR_TABLE_BASE CTL_REG_ACC_BASE
+
+#define CVBS_IN_BASE 0x00004000U
+#define CVBS_IN_BUF_BASE (CVBS_IN_BASE + (16U * PCIE_BARADDROFSIZE))
+#define CVBS_IN_BUF_BASE2 (CVBS_IN_BASE + (50U * PCIE_BARADDROFSIZE))
+
+/* 2 Mib */
+#define MAX_L_VIDEO_SIZE 0x200000U
+
+#define PCI_E_BAR_PAGE_SIZE 0x20000000
+#define PCI_E_BAR_ADD_MASK 0xE0000000
+#define PCI_E_BAR_ADD_LOWMASK 0x1FFFFFFF
+
+#define MAX_VID_CHANNELS 4
+
+#define MAX_MM_VIDEO_SIZE SZ_4M
+
+#define MAX_VIDEO_HW_W 1920
+#define MAX_VIDEO_HW_H 1080
+#define MAX_VIDEO_SCALER_SIZE (1920U * 1080U * 2U)
+
+#define MIN_VAMP_BRIGHTNESS_UNITS 0
+#define MAX_VAMP_BRIGHTNESS_UNITS 0xff
+
+#define MIN_VAMP_CONTRAST_UNITS 0
+#define MAX_VAMP_CONTRAST_UNITS 0xff
+
+#define MIN_VAMP_SATURATION_UNITS 0
+#define MAX_VAMP_SATURATION_UNITS 0xff
+
+#define MIN_VAMP_HUE_UNITS 0
+#define MAX_VAMP_HUE_UNITS 0xff
+
+#define HWS_BRIGHTNESS_DEFAULT 0x80
+#define HWS_CONTRAST_DEFAULT 0x80
+#define HWS_SATURATION_DEFAULT 0x80
+#define HWS_HUE_DEFAULT 0x00
+
+/* Core/global status. */
+#define HWS_REG_SYS_STATUS (CVBS_IN_BASE + 0 * PCIE_BARADDROFSIZE)
+/* bit3: DMA busy, bit2: int, ... */
+
+#define HWS_SYS_DMA_BUSY_BIT BIT(3) /* 0x08 = DMA busy flag */
+
+#define HWS_REG_DEC_MODE (CVBS_IN_BASE + 0 * PCIE_BARADDROFSIZE)
+/* Main control register */
+#define HWS_REG_CTL (CVBS_IN_BASE + 4 * PCIE_BARADDROFSIZE)
+#define HWS_CTL_IRQ_ENABLE_BIT BIT(0) /* Global interrupt enable bit */
+/* Write 0x00 to fully reset decoder,
+ * set bit 31=1 to "start run",
+ * low byte=0x13 selects YUYV/BT.709/etc,
+ * in ReadChipId() we also write 0x00 and 0x10 here for chip-ID sequencing.
+ */
+
+/* per-pipe base: 0x4000, stride 0x800 ------------------------------------ */
+#define HWS_REG_PIPE_BASE(n) (CVBS_IN_BASE + ((n) * 0x800))
+#define HWS_REG_HPD(n) (HWS_REG_PIPE_BASE(n) + 0x14) /* +5 V & HPD */
+
+/* handy bit masks */
+#define HWS_HPD_BIT BIT(0) /* hot-plug detect */
+#define HWS_5V_BIT BIT(3) /* cable +5-volt */
+
+/* Per-channel done flags. */
+#define HWS_REG_INT_STATUS (CVBS_IN_BASE + 1 * PCIE_BARADDROFSIZE)
+#define HWS_SYS_BUSY_BIT BIT(2) /* matches old 0x04 test */
+
+/* Capture enable switches. */
+/* bit0-3: CH0-CH3 video enable */
+#define HWS_REG_VCAP_ENABLE (CVBS_IN_BASE + 2 * PCIE_BARADDROFSIZE)
+/* bits0-3: signal present, bits8-11: interlace */
+#define HWS_REG_ACTIVE_STATUS (CVBS_IN_BASE + 5 * PCIE_BARADDROFSIZE)
+/* bits0-3: HDCP detected */
+#define HWS_REG_HDCP_STATUS (CVBS_IN_BASE + 8 * PCIE_BARADDROFSIZE)
+#define HWS_REG_DMA_MAX_SIZE (CVBS_IN_BASE + 9 * PCIE_BARADDROFSIZE)
+
+/* Buffer addresses (written once during init/reset). */
+/* Base of host-visible buffer. */
+#define HWS_REG_VBUF1_ADDR (CVBS_IN_BASE + 25 * PCIE_BARADDROFSIZE)
+/* Per-channel DMA address. */
+#define HWS_REG_DMA_ADDR(ch) (CVBS_IN_BASE + (26 + (ch)) * PCIE_BARADDROFSIZE)
+
+/* Per-channel live buffer toggles (read-only). */
+#define HWS_REG_VBUF_TOGGLE(ch) (CVBS_IN_BASE + (32 + (ch)) * PCIE_BARADDROFSIZE)
+/*
+ * Returns 0 or 1 = which half of the video ring the DMA engine is
+ * currently filling for channel *ch* (0-3).
+ */
+
+/* Per-interrupt bits (video 0-3). */
+#define HWS_INT_VDONE_BIT(ch) BIT(ch) /* 0x01,0x02,0x04,0x08 */
+
+#define HWS_REG_INT_ACK (CVBS_IN_BASE + 0x4000 + 1 * PCIE_BARADDROFSIZE)
+
+/* 16-bit W | 16-bit H. */
+#define HWS_REG_IN_RES(ch) (CVBS_IN_BASE + (90 + (ch) * 2) * PCIE_BARADDROFSIZE)
+/* B|C|H|S packed bytes. */
+#define HWS_REG_BCHS(ch) (CVBS_IN_BASE + (91 + (ch) * 2) * PCIE_BARADDROFSIZE)
+
+/* Input fps. */
+#define HWS_REG_FRAME_RATE(ch) (CVBS_IN_BASE + (110 + (ch)) * PCIE_BARADDROFSIZE)
+/* Programmed out W|H. */
+#define HWS_REG_OUT_RES(ch) (CVBS_IN_BASE + (120 + (ch)) * PCIE_BARADDROFSIZE)
+/* Programmed out fps. */
+#define HWS_REG_OUT_FRAME_RATE(ch) (CVBS_IN_BASE + (130 + (ch)) * PCIE_BARADDROFSIZE)
+
+/* Device version/port ID/subversion register. */
+#define HWS_REG_DEVICE_INFO (CVBS_IN_BASE + 88 * PCIE_BARADDROFSIZE)
+/*
+ * Reading this 32-bit word returns:
+ * bits 7:0 = "device version"
+ * bits 15:8 = "device sub-version"
+ * bits 23:24 = "HW key / port ID" etc.
+ * bits 31:28 = "support YV12" flags
+ */
+
+/* Convenience aliases for individual channels. */
+#define HWS_REG_VBUF_TOGGLE_CH0 HWS_REG_VBUF_TOGGLE(0)
+#define HWS_REG_VBUF_TOGGLE_CH1 HWS_REG_VBUF_TOGGLE(1)
+#define HWS_REG_VBUF_TOGGLE_CH2 HWS_REG_VBUF_TOGGLE(2)
+#define HWS_REG_VBUF_TOGGLE_CH3 HWS_REG_VBUF_TOGGLE(3)
+
+#endif /* _HWS_PCIE_REG_H */
diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.c b/drivers/media/pci/hws/hws_v4l2_ioctl.c
new file mode 100644
index 000000000000..a9a7597f76e1
--- /dev/null
+++ b/drivers/media/pci/hws/hws_v4l2_ioctl.c
@@ -0,0 +1,778 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_v4l2_ioctl.h"
+
+struct hws_dv_mode {
+ struct v4l2_dv_timings timings;
+ u32 refresh_hz;
+};
+
+static const struct hws_dv_mode *
+hws_find_dv_by_wh(u32 w, u32 h, bool interlaced);
+
+static const struct hws_dv_mode hws_dv_modes[] = {
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1920,
+ .height = 1080,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 720,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 720,
+ .height = 480,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 720,
+ .height = 576,
+ .interlaced = 0,
+ },
+ },
+ 50,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 800,
+ .height = 600,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 640,
+ .height = 480,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1024,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 800,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 1024,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1360,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1440,
+ .height = 900,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1680,
+ .height = 1050,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ /* Portrait */
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1080,
+ .height = 1920,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+};
+
+static const size_t hws_dv_modes_cnt = ARRAY_SIZE(hws_dv_modes);
+
+/* YUYV: 16 bpp; align to 64 as you did elsewhere */
+static inline u32 hws_calc_bpl_yuyv(u32 w) { return ALIGN(w * 2, 64); }
+static inline u32 hws_calc_size_yuyv(u32 w, u32 h) { return hws_calc_bpl_yuyv(w) * h; }
+static inline u32 hws_calc_half_size(u32 sizeimage)
+{
+ return sizeimage / 2;
+}
+
+static inline void hws_hw_write_bchs(struct hws_pcie_dev *hws, unsigned int ch,
+ u8 br, u8 co, u8 hu, u8 sa)
+{
+ u32 packed = (sa << 24) | (hu << 16) | (co << 8) | br;
+
+ if (!hws || !hws->bar0_base || ch >= hws->max_channels)
+ return;
+ writel_relaxed(packed, hws->bar0_base + HWS_REG_BCHS(ch));
+ (void)readl(hws->bar0_base + HWS_REG_BCHS(ch)); /* post write */
+}
+
+/* Helper: find a supported DV mode by W/H + interlace flag */
+static const struct hws_dv_mode *
+hws_match_supported_dv(const struct v4l2_dv_timings *req)
+{
+ const struct v4l2_bt_timings *bt;
+
+ if (!req || req->type != V4L2_DV_BT_656_1120)
+ return NULL;
+
+ bt = &req->bt;
+ return hws_find_dv_by_wh(bt->width, bt->height, !!bt->interlaced);
+}
+
+/* Helper: find a supported DV mode by W/H + interlace flag */
+static const struct hws_dv_mode *
+hws_find_dv_by_wh(u32 w, u32 h, bool interlaced)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct hws_dv_mode *t = &hws_dv_modes[i];
+ const struct v4l2_bt_timings *bt = &t->timings.bt;
+
+ if (t->timings.type != V4L2_DV_BT_656_1120)
+ continue;
+
+ if (bt->width == w && bt->height == h &&
+ !!bt->interlaced == interlaced)
+ return t;
+ }
+ return NULL;
+}
+
+static bool hws_get_live_dv_geometry(struct hws_video *vid,
+ u32 *w, u32 *h, bool *interlaced)
+{
+ struct hws_pcie_dev *pdx;
+ u32 reg;
+
+ if (!vid)
+ return false;
+
+ pdx = vid->parent;
+ if (!pdx || !pdx->bar0_base)
+ return false;
+
+ reg = readl(pdx->bar0_base + HWS_REG_IN_RES(vid->channel_index));
+ if (!reg || reg == 0xFFFFFFFF)
+ return false;
+
+ if (w)
+ *w = reg & 0xFFFF;
+ if (h)
+ *h = (reg >> 16) & 0xFFFF;
+ if (interlaced) {
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ *interlaced = !!(reg & BIT(8 + vid->channel_index));
+ }
+ return true;
+}
+
+static u32 hws_pick_fps_from_mode(u32 w, u32 h, bool interlaced)
+{
+ const struct hws_dv_mode *m = hws_find_dv_by_wh(w, h, interlaced);
+
+ if (m && m->refresh_hz)
+ return m->refresh_hz;
+ /* Fallback to a sane default */
+ return 60;
+}
+
+/* Query the *current detected* DV timings on the input.
+ * If you have a real hardware detector, call it here; otherwise we
+ * derive from the cached pix state and map to the closest supported DV mode.
+ */
+int hws_vidioc_query_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ const struct hws_dv_mode *m;
+ u32 w, h;
+ bool interlace;
+
+ if (!timings)
+ return -EINVAL;
+
+ w = vid->pix.width;
+ h = vid->pix.height;
+ interlace = vid->pix.interlaced;
+ (void)hws_get_live_dv_geometry(vid, &w, &h, &interlace);
+ /* Map current (live if available, otherwise cached) WxH/interlace
+ * to one of our supported modes.
+ */
+ m = hws_find_dv_by_wh(w, h, !!interlace);
+ if (!m)
+ return -ENOLINK;
+
+ *timings = m->timings;
+ vid->cur_dv_timings = m->timings;
+ vid->current_fps = m->refresh_hz;
+ return 0;
+}
+
+/* Enumerate the Nth supported DV timings from our static table. */
+int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
+ struct v4l2_enum_dv_timings *edv)
+{
+ if (!edv)
+ return -EINVAL;
+
+ if (edv->pad)
+ return -EINVAL;
+
+ if (edv->index >= hws_dv_modes_cnt)
+ return -EINVAL;
+
+ edv->timings = hws_dv_modes[edv->index].timings;
+ return 0;
+}
+
+/* Get the *currently configured* DV timings. */
+int hws_vidioc_g_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+
+ if (!timings)
+ return -EINVAL;
+
+ *timings = vid->cur_dv_timings;
+ return 0;
+}
+
+static inline void hws_set_colorimetry_state(struct hws_pix_state *p)
+{
+ bool sd = p->height <= 576;
+
+ p->colorspace = sd ? V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
+ p->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ p->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ p->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+}
+
+/* Set DV timings: must match one of our supported modes.
+ * If buffers are queued and this implies a size change, we reject with -EBUSY.
+ * Otherwise we update pix state and (optionally) reprogram the HW.
+ */
+int hws_vidioc_s_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ const struct hws_dv_mode *m;
+ const struct v4l2_bt_timings *bt;
+ u32 new_w, new_h;
+ bool interlaced;
+ int ret = 0;
+ unsigned long was_busy;
+
+ if (!timings)
+ return -EINVAL;
+
+ m = hws_match_supported_dv(timings);
+ if (!m)
+ return -EINVAL;
+
+ bt = &m->timings.bt;
+ if (bt->interlaced)
+ return -EINVAL; /* only progressive modes are advertised */
+ new_w = bt->width;
+ new_h = bt->height;
+ interlaced = false;
+
+ lockdep_assert_held(&vid->state_lock);
+
+ /* If vb2 has active buffers and size would change, reject. */
+ was_busy = vb2_is_busy(&vid->buffer_queue);
+ if (was_busy &&
+ (new_w != vid->pix.width || new_h != vid->pix.height ||
+ interlaced != vid->pix.interlaced)) {
+ ret = -EBUSY;
+ return ret;
+ }
+
+ /* Update software pixel state (and recalc sizes) */
+ vid->pix.width = new_w;
+ vid->pix.height = new_h;
+ vid->pix.field = interlaced ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_NONE;
+ vid->pix.interlaced = interlaced;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+
+ hws_set_colorimetry_state(&vid->pix);
+
+ /* Recompute stride/sizeimage/half_size using your helper */
+ vid->pix.bytesperline = hws_calc_bpl_yuyv(new_w);
+ vid->pix.sizeimage = hws_calc_size_yuyv(new_w, new_h);
+ vid->pix.half_size = hws_calc_half_size(vid->pix.sizeimage);
+ vid->cur_dv_timings = m->timings;
+ vid->current_fps = m->refresh_hz;
+ if (!was_busy)
+ vid->alloc_sizeimage = vid->pix.sizeimage;
+ return ret;
+}
+
+/* Report DV timings capability: advertise BT.656/1120 with
+ * the min/max WxH derived from our table and basic progressive support.
+ */
+int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
+ struct v4l2_dv_timings_cap *cap)
+{
+ u32 min_w = ~0U, min_h = ~0U;
+ u32 max_w = 0, max_h = 0;
+ size_t i, n = 0;
+
+ if (!cap)
+ return -EINVAL;
+
+ memset(cap, 0, sizeof(*cap));
+ cap->type = V4L2_DV_BT_656_1120;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct v4l2_bt_timings *bt = &hws_dv_modes[i].timings.bt;
+
+ if (hws_dv_modes[i].timings.type != V4L2_DV_BT_656_1120)
+ continue;
+ n++;
+
+ if (bt->width < min_w)
+ min_w = bt->width;
+ if (bt->height < min_h)
+ min_h = bt->height;
+ if (bt->width > max_w)
+ max_w = bt->width;
+ if (bt->height > max_h)
+ max_h = bt->height;
+ }
+
+ /* If the table was empty, fail gracefully. */
+ if (!n || min_w == U32_MAX)
+ return -ENODATA;
+
+ cap->bt.min_width = min_w;
+ cap->bt.max_width = max_w;
+ cap->bt.min_height = min_h;
+ cap->bt.max_height = max_h;
+
+ /* We support both CEA-861- and VESA-style modes in the list. */
+ cap->bt.standards =
+ V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT;
+
+ /* Progressive only, unless your table includes interlaced entries. */
+ cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE;
+
+ /* Leave pixelclock/porch limits unconstrained (0) for now. */
+ return 0;
+}
+
+static int hws_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct hws_video *vid =
+ container_of(ctrl->handler, struct hws_video, control_handler);
+ struct hws_pcie_dev *pdx = vid->parent;
+ bool program = false;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ vid->current_brightness = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_CONTRAST:
+ vid->current_contrast = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_SATURATION:
+ vid->current_saturation = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_HUE:
+ vid->current_hue = ctrl->val;
+ program = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (program) {
+ hws_hw_write_bchs(pdx, vid->channel_index,
+ (u8)vid->current_brightness,
+ (u8)vid->current_contrast,
+ (u8)vid->current_hue,
+ (u8)vid->current_saturation);
+ }
+ return 0;
+}
+
+const struct v4l2_ctrl_ops hws_ctrl_ops = {
+ .s_ctrl = hws_s_ctrl,
+};
+
+int hws_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
+{
+ struct hws_video *vid = video_drvdata(file);
+ struct hws_pcie_dev *pdev = vid->parent;
+ int vi_index = vid->channel_index + 1; /* keep it simple */
+
+ strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+ snprintf(cap->card, sizeof(cap->card),
+ "AVMatrix HWS Capture %d", vi_index);
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", dev_name(&pdev->pdev->dev));
+
+ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+ return 0;
+}
+
+int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh, struct v4l2_fmtdesc *f)
+{
+ if (f->index != 0)
+ return -EINVAL; /* only one format */
+
+ f->pixelformat = V4L2_PIX_FMT_YUYV;
+ return 0;
+}
+
+int hws_vidioc_enum_frameintervals(struct file *file, void *fh,
+ struct v4l2_frmivalenum *fival)
+{
+ const struct hws_dv_mode *mode;
+
+ if (fival->index)
+ return -EINVAL;
+
+ if (fival->pixel_format != V4L2_PIX_FMT_YUYV)
+ return -EINVAL;
+
+ mode = hws_find_dv_by_wh(fival->width, fival->height, false);
+ if (!mode)
+ return -EINVAL;
+
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator = 1;
+ fival->discrete.denominator = mode->refresh_hz ?: 60;
+
+ return 0;
+}
+
+int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct hws_video *vid = video_drvdata(file);
+
+ fmt->fmt.pix.width = vid->pix.width;
+ fmt->fmt.pix.height = vid->pix.height;
+ fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ fmt->fmt.pix.field = vid->pix.field;
+ fmt->fmt.pix.bytesperline = vid->pix.bytesperline;
+ fmt->fmt.pix.sizeimage = vid->pix.sizeimage;
+ fmt->fmt.pix.colorspace = vid->pix.colorspace;
+ fmt->fmt.pix.ycbcr_enc = vid->pix.ycbcr_enc;
+ fmt->fmt.pix.quantization = vid->pix.quantization;
+ fmt->fmt.pix.xfer_func = vid->pix.xfer_func;
+ return 0;
+}
+
+static inline void hws_set_colorimetry_fmt(struct v4l2_pix_format *p)
+{
+ bool sd = p->height <= 576;
+
+ p->colorspace = sd ? V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
+ p->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ p->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ p->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+}
+
+int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct hws_video *vid = file ? video_drvdata(file) : NULL;
+ struct hws_pcie_dev *pdev = vid ? vid->parent : NULL;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ u32 req_w = pix->width, req_h = pix->height;
+ u32 w, h, min_bpl, bpl;
+ size_t size; /* wider than u32 for overflow check */
+ size_t max_frame = pdev ? pdev->max_hw_video_buf_sz : MAX_MM_VIDEO_SIZE;
+
+ /* Only YUYV */
+ pix->pixelformat = V4L2_PIX_FMT_YUYV;
+
+ /* Defaults then clamp */
+ w = (req_w ? req_w : 640);
+ h = (req_h ? req_h : 480);
+ if (w > MAX_VIDEO_HW_W)
+ w = MAX_VIDEO_HW_W;
+ if (h > MAX_VIDEO_HW_H)
+ h = MAX_VIDEO_HW_H;
+ if (!w)
+ w = 640; /* hard fallback in case macros are odd */
+ if (!h)
+ h = 480;
+
+ /* Field policy */
+ pix->field = V4L2_FIELD_NONE;
+
+ /* Stride policy for packed 16bpp, 64B align */
+ min_bpl = ALIGN(w * 2, 64);
+
+ /* Bound requested bpl to something sane, then align */
+ bpl = pix->bytesperline;
+ if (bpl < min_bpl) {
+ bpl = min_bpl;
+ } else {
+ /* Cap at 16x width to avoid silly values that overflow sizeimage */
+ u32 max_bpl = ALIGN(w * 2 * 16, 64);
+
+ if (bpl > max_bpl)
+ bpl = max_bpl;
+ bpl = ALIGN(bpl, 64);
+ }
+ if (h && max_frame) {
+ size_t max_bpl_hw = max_frame / h;
+
+ if (max_bpl_hw < min_bpl)
+ return -ERANGE;
+ max_bpl_hw = rounddown(max_bpl_hw, 64);
+ 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 = (u32)max_bpl_hw;
+ }
+ }
+ size = (size_t)bpl * (size_t)h;
+ if (size > max_frame)
+ return -ERANGE;
+
+ pix->width = w;
+ pix->height = h;
+ pix->bytesperline = bpl;
+ pix->sizeimage = (u32)size; /* logical size, not page-aligned */
+
+ hws_set_colorimetry_fmt(pix);
+ if (pdev)
+ dev_dbg(&pdev->pdev->dev,
+ "try_fmt: w=%u h=%u bpl=%u size=%u field=%u\n",
+ pix->width, pix->height, pix->bytesperline,
+ pix->sizeimage, pix->field);
+ return 0;
+}
+
+int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
+{
+ struct hws_video *vid = video_drvdata(file);
+ int ret;
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ /* Normalize the request */
+ ret = hws_vidioc_try_fmt_vid_cap(file, priv, f);
+ if (ret)
+ return ret;
+
+ /* Don’t allow size changes while buffers are queued */
+ if (vb2_is_busy(&vid->buffer_queue)) {
+ if (f->fmt.pix.width != vid->pix.width ||
+ f->fmt.pix.height != vid->pix.height ||
+ f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV) {
+ return -EBUSY;
+ }
+ }
+
+ /* Apply to driver state */
+ vid->pix.width = f->fmt.pix.width;
+ vid->pix.height = f->fmt.pix.height;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+ vid->pix.field = f->fmt.pix.field;
+ vid->pix.colorspace = f->fmt.pix.colorspace;
+ vid->pix.ycbcr_enc = f->fmt.pix.ycbcr_enc;
+ vid->pix.quantization = f->fmt.pix.quantization;
+ vid->pix.xfer_func = f->fmt.pix.xfer_func;
+
+ /* Update sizes (use helper if you prefer strict alignment math) */
+ vid->pix.bytesperline = f->fmt.pix.bytesperline; /* aligned */
+ vid->pix.sizeimage = f->fmt.pix.sizeimage; /* logical */
+ vid->pix.half_size = hws_calc_half_size(vid->pix.sizeimage);
+ vid->pix.interlaced = false;
+ hws_set_current_dv_timings(vid, vid->pix.width, vid->pix.height,
+ vid->pix.interlaced);
+ vid->current_fps = hws_pick_fps_from_mode(vid->pix.width,
+ vid->pix.height,
+ vid->pix.interlaced);
+ /* Or:
+ * hws_calc_sizeimage(vid, vid->pix.width, vid->pix.height, false);
+ */
+
+ /* Refresh vb2 watermark when idle */
+ if (!vb2_is_busy(&vid->buffer_queue))
+ vid->alloc_sizeimage = PAGE_ALIGN(vid->pix.sizeimage);
+ dev_dbg(&vid->parent->pdev->dev,
+ "s_fmt: w=%u h=%u bpl=%u size=%u alloc=%u\n",
+ vid->pix.width, vid->pix.height, vid->pix.bytesperline,
+ vid->pix.sizeimage, vid->alloc_sizeimage);
+
+ return 0;
+}
+
+int hws_vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *param)
+{
+ struct hws_video *vid = video_drvdata(file);
+ u32 fps;
+
+ if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ fps = vid->current_fps ? vid->current_fps : 60;
+
+ /* Report cached frame rate; expose timeperframe capability */
+ param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+ param->parm.capture.capturemode = 0;
+ param->parm.capture.timeperframe.numerator = 1;
+ param->parm.capture.timeperframe.denominator = fps;
+ param->parm.capture.extendedmode = 0;
+ param->parm.capture.readbuffers = 0;
+
+ return 0;
+}
+
+int hws_vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *input)
+{
+ if (input->index)
+ return -EINVAL;
+ input->type = V4L2_INPUT_TYPE_CAMERA;
+ strscpy(input->name, KBUILD_MODNAME, sizeof(input->name));
+ input->capabilities = V4L2_IN_CAP_DV_TIMINGS;
+ input->status = 0;
+
+ return 0;
+}
+
+int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *index)
+{
+ *index = 0;
+ return 0;
+}
+
+int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
+
+int hws_vidioc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *param)
+{
+ struct hws_video *vid = video_drvdata(file);
+ struct v4l2_captureparm *cap;
+ u32 fps;
+
+ if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ cap = ¶m->parm.capture;
+
+ fps = vid->current_fps ? vid->current_fps : 60;
+ cap->timeperframe.denominator = fps;
+ cap->timeperframe.numerator = 1;
+ cap->capability = V4L2_CAP_TIMEPERFRAME;
+ cap->capturemode = 0;
+ cap->extendedmode = 0;
+ /* readbuffers left unchanged or zero; vb2 handles queue depth */
+
+ return 0;
+}
diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.h b/drivers/media/pci/hws/hws_v4l2_ioctl.h
new file mode 100644
index 000000000000..f20e6aadff67
--- /dev/null
+++ b/drivers/media/pci/hws/hws_v4l2_ioctl.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_V4L2_IOCTL_H
+#define HWS_V4L2_IOCTL_H
+
+#include <linux/fs.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-ioctl.h>
+
+extern const struct v4l2_ctrl_ops hws_ctrl_ops;
+
+int hws_vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap);
+int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh,
+ struct v4l2_fmtdesc *f);
+int hws_vidioc_enum_frameintervals(struct file *file, void *fh,
+ struct v4l2_frmivalenum *fival);
+int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh,
+ struct v4l2_format *fmt);
+int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh,
+ struct v4l2_format *f);
+int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f);
+int hws_vidioc_g_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *setfps);
+int hws_vidioc_s_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a);
+int hws_vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *i);
+int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *i);
+int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i);
+int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
+ struct v4l2_dv_timings_cap *cap);
+int hws_vidioc_s_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+int hws_vidioc_g_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
+ struct v4l2_enum_dv_timings *edv);
+int hws_vidioc_query_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+
+#endif
diff --git a/drivers/media/pci/hws/hws_video.c b/drivers/media/pci/hws/hws_video.c
new file mode 100644
index 000000000000..9fcf40a12ec3
--- /dev/null
+++ b/drivers/media/pci/hws/hws_video.c
@@ -0,0 +1,1546 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/overflow.h>
+#include <linux/delay.h>
+#include <linux/bits.h>
+#include <linux/jiffies.h>
+#include <linux/ktime.h>
+#include <linux/interrupt.h>
+#include <linux/moduleparam.h>
+#include <linux/sysfs.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_irq.h"
+#include "hws_v4l2_ioctl.h"
+
+#define HWS_REMAP_SLOT_OFF(ch) (0x208 + (ch) * 8) /* one 64-bit slot per ch */
+#define HWS_BUF_BASE_OFF(ch) (CVBS_IN_BUF_BASE + (ch) * PCIE_BARADDROFSIZE)
+#define HWS_HALF_SZ_OFF(ch) (CVBS_IN_BUF_BASE2 + (ch) * PCIE_BARADDROFSIZE)
+
+static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch);
+static bool hws_update_active_interlace(struct hws_pcie_dev *pdx,
+ unsigned int ch);
+static void handle_hwv2_path(struct hws_pcie_dev *hws, unsigned int ch);
+static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch);
+static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
+ bool interlaced);
+
+/* DMA helper functions */
+static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma);
+static struct hwsvideo_buffer *
+hws_take_queued_buffer_locked(struct hws_video *vid);
+
+#if IS_ENABLED(CONFIG_SYSFS)
+static ssize_t resolution_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct video_device *vdev = to_video_device(dev);
+ struct hws_video *vid = video_get_drvdata(vdev);
+ struct hws_pcie_dev *hws;
+ u32 res_reg;
+ u16 w, h;
+ bool interlaced;
+
+ if (!vid)
+ return -ENODEV;
+
+ hws = vid->parent;
+ if (!hws || !hws->bar0_base)
+ return sysfs_emit(buf, "unknown\n");
+
+ res_reg = readl(hws->bar0_base + HWS_REG_IN_RES(vid->channel_index));
+ if (!res_reg || res_reg == 0xFFFFFFFF)
+ return sysfs_emit(buf, "unknown\n");
+
+ w = res_reg & 0xFFFF;
+ h = (res_reg >> 16) & 0xFFFF;
+
+ interlaced =
+ !!(readl(hws->bar0_base + HWS_REG_ACTIVE_STATUS) &
+ BIT(8 + vid->channel_index));
+
+ return sysfs_emit(buf, "%ux%u%s\n", w, h, interlaced ? "i" : "p");
+}
+static DEVICE_ATTR_RO(resolution);
+
+static inline int hws_resolution_create(struct video_device *vdev)
+{
+ return device_create_file(&vdev->dev, &dev_attr_resolution);
+}
+
+static inline void hws_resolution_remove(struct video_device *vdev)
+{
+ device_remove_file(&vdev->dev, &dev_attr_resolution);
+}
+#else
+static inline int hws_resolution_create(struct video_device *vdev)
+{
+ return 0;
+}
+
+static inline void hws_resolution_remove(struct video_device *vdev)
+{
+}
+#endif
+
+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=0x%llx tag=%s\n", ch,
+ (u64)dma, tag ? tag : "");
+}
+
+static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma)
+{
+ const u32 addr_mask = PCI_E_BAR_ADD_MASK; // 0xE0000000
+ const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK; // 0x1FFFFFFF
+ struct hws_pcie_dev *hws = vid->parent;
+ unsigned int ch = vid->channel_index;
+ u32 table_off = HWS_REMAP_SLOT_OFF(ch);
+ u32 lo = lower_32_bits(dma);
+ u32 hi = upper_32_bits(dma);
+ u32 pci_addr = lo & addr_low_mask; // low 29 bits inside 512MB window
+ u32 page_lo = lo & addr_mask; // bits 31..29 only (page bits)
+
+ bool wrote = false;
+
+ /* Remap entry only when DMA crosses into a new 512 MB page */
+ if (!vid->window_valid || vid->last_dma_hi != hi ||
+ vid->last_dma_page != page_lo) {
+ writel(hi, hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
+ writel(page_lo,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
+ PCIE_BARADDROFSIZE);
+ vid->last_dma_hi = hi;
+ vid->last_dma_page = page_lo;
+ wrote = true;
+ }
+
+ /* Base pointer only needs low 29 bits */
+ if (!vid->window_valid || vid->last_pci_addr != pci_addr) {
+ writel((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
+ hws->bar0_base + HWS_BUF_BASE_OFF(ch));
+ vid->last_pci_addr = pci_addr;
+ wrote = true;
+ }
+
+ /* Half-size only changes when resolution changes */
+ if (!vid->window_valid || vid->last_half16 != vid->pix.half_size / 16) {
+ writel(vid->pix.half_size / 16,
+ hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+ vid->last_half16 = vid->pix.half_size / 16;
+ wrote = true;
+ }
+
+ vid->window_valid = true;
+
+ if (unlikely(dma_window_verify) && wrote) {
+ u32 r_hi =
+ readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
+ u32 r_lo =
+ readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
+ PCIE_BARADDROFSIZE);
+ u32 r_base = readl(hws->bar0_base + HWS_BUF_BASE_OFF(ch));
+ u32 r_half = readl(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+
+ dev_dbg(&hws->pdev->dev,
+ "ch%u remap verify: hi=0x%08x page_lo=0x%08x exp_page=0x%08x base=0x%08x exp_base=0x%08x half16B=0x%08x exp_half=0x%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) {
+ /* Flush posted writes before arming DMA */
+ readl_relaxed(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+ }
+}
+
+static struct hwsvideo_buffer *
+hws_take_queued_buffer_locked(struct hws_video *vid)
+{
+ struct hwsvideo_buffer *buf;
+
+ if (!vid || list_empty(&vid->capture_queue))
+ return NULL;
+
+ buf = list_first_entry(&vid->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&buf->list);
+ if (vid->queued_count)
+ vid->queued_count--;
+ return buf;
+}
+
+void hws_prime_next_locked(struct hws_video *vid)
+{
+ struct hws_pcie_dev *hws;
+ struct hwsvideo_buffer *next;
+ dma_addr_t dma;
+
+ if (!vid)
+ return;
+
+ hws = vid->parent;
+ if (!hws || !hws->bar0_base)
+ return;
+
+ if (!READ_ONCE(vid->cap_active) || !vid->active || vid->next_prepared)
+ return;
+
+ next = hws_take_queued_buffer_locked(vid);
+ if (!next)
+ return;
+
+ vid->next_prepared = next;
+ dma = vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
+ 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=0x%llx\n",
+ vid->channel_index, next, (u64)dma);
+}
+
+static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag)
+{
+ struct hws_pcie_dev *hws;
+ unsigned long flags;
+ struct hwsvideo_buffer *buf = NULL, *next = NULL;
+ bool have_next = false;
+ bool doorbell = false;
+
+ if (!v)
+ return false;
+ hws = v->parent;
+ if (!hws || READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active))
+ return false;
+ spin_lock_irqsave(&v->irq_lock, flags);
+ if (v->active) {
+ buf = v->active;
+ v->active = NULL;
+ buf->slot = 0;
+ } else if (!list_empty(&v->capture_queue)) {
+ buf = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&buf->list);
+ if (v->queued_count)
+ v->queued_count--;
+ buf->slot = 0;
+ }
+ if (v->next_prepared) {
+ next = v->next_prepared;
+ v->next_prepared = NULL;
+ next->slot = 0;
+ v->active = next;
+ have_next = true;
+ } else if (!list_empty(&v->capture_queue)) {
+ next = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&next->list);
+ if (v->queued_count)
+ v->queued_count--;
+ next->slot = 0;
+ v->active = next;
+ have_next = true;
+ } else {
+ v->active = NULL;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ if (!buf)
+ return false;
+ /* Complete buffer with a neutral frame so dequeuers keep running. */
+ {
+ struct vb2_v4l2_buffer *vb2v = &buf->vb;
+ void *dst = vb2_plane_vaddr(&vb2v->vb2_buf, 0);
+
+ if (dst)
+ memset(dst, 0x10, v->pix.sizeimage);
+ vb2_set_plane_payload(&vb2v->vb2_buf, 0, v->pix.sizeimage);
+ vb2v->sequence = (u32)atomic_inc_return(&v->sequence_number);
+ vb2v->vb2_buf.timestamp = ktime_get_ns();
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+ if (have_next && next) {
+ dma_addr_t dma =
+ vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(hws, v->channel_index, dma);
+ hws_set_dma_doorbell(hws, v->channel_index, dma,
+ tag ? tag : "nosignal_zero");
+ doorbell = true;
+ }
+ if (doorbell) {
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, v->channel_index, true);
+ }
+ return true;
+}
+
+static int hws_ctrls_init(struct hws_video *vid)
+{
+ struct v4l2_ctrl_handler *hdl = &vid->control_handler;
+
+ /* Create BCHS controls plus signal-detect status. */
+ v4l2_ctrl_handler_init(hdl, 5);
+
+ vid->ctrl_brightness = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
+ V4L2_CID_BRIGHTNESS,
+ MIN_VAMP_BRIGHTNESS_UNITS,
+ MAX_VAMP_BRIGHTNESS_UNITS, 1,
+ HWS_BRIGHTNESS_DEFAULT);
+
+ vid->ctrl_contrast =
+ v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_CONTRAST,
+ MIN_VAMP_CONTRAST_UNITS, MAX_VAMP_CONTRAST_UNITS,
+ 1, HWS_CONTRAST_DEFAULT);
+
+ vid->ctrl_saturation = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
+ V4L2_CID_SATURATION,
+ MIN_VAMP_SATURATION_UNITS,
+ MAX_VAMP_SATURATION_UNITS, 1,
+ HWS_SATURATION_DEFAULT);
+
+ vid->ctrl_hue = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_HUE,
+ MIN_VAMP_HUE_UNITS,
+ MAX_VAMP_HUE_UNITS, 1,
+ HWS_HUE_DEFAULT);
+ vid->hotplug_detect_control = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_DV_RX_POWER_PRESENT,
+ 0, 1, 1, 0);
+ if (vid->hotplug_detect_control)
+ vid->hotplug_detect_control->flags |=
+ V4L2_CTRL_FLAG_READ_ONLY;
+
+ if (hdl->error) {
+ int err = hdl->error;
+
+ v4l2_ctrl_handler_free(hdl);
+ return err;
+ }
+ return 0;
+}
+
+static void hws_video_move_buf_to_done_locked(struct hwsvideo_buffer **buf,
+ struct list_head *done)
+{
+ if (!*buf)
+ return;
+
+ if (list_empty(&(*buf)->list))
+ list_add_tail(&(*buf)->list, done);
+ else
+ list_move_tail(&(*buf)->list, done);
+
+ *buf = NULL;
+}
+
+static void hws_video_collect_done_locked(struct hws_video *vid,
+ struct list_head *done)
+{
+ struct hwsvideo_buffer *buf;
+
+ hws_video_move_buf_to_done_locked(&vid->active, done);
+ hws_video_move_buf_to_done_locked(&vid->next_prepared, done);
+
+ while (!list_empty(&vid->capture_queue)) {
+ buf = list_first_entry(&vid->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_move_tail(&buf->list, done);
+ }
+
+ vid->queued_count = 0;
+}
+
+int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch)
+{
+ struct hws_video *vid;
+
+ /* basic sanity */
+ if (!pdev || ch < 0 || ch >= pdev->max_channels)
+ return -EINVAL;
+
+ vid = &pdev->video[ch];
+
+ /* hard reset the per-channel struct (safe here since we init everything next) */
+ memset(vid, 0, sizeof(*vid));
+
+ /* identity */
+ vid->parent = pdev;
+ vid->channel_index = ch;
+
+ /* locks & lists */
+ mutex_init(&vid->state_lock);
+ spin_lock_init(&vid->irq_lock);
+ INIT_LIST_HEAD(&vid->capture_queue);
+ atomic_set(&vid->sequence_number, 0);
+ vid->active = NULL;
+
+ /* DMA watchdog removed; retain counters for diagnostics */
+ vid->timeout_count = 0;
+ vid->error_count = 0;
+
+ vid->queued_count = 0;
+ vid->window_valid = false;
+
+ /* default format (adjust to your HW) */
+ vid->pix.width = 1920;
+ vid->pix.height = 1080;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+ vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
+ vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
+ vid->pix.field = V4L2_FIELD_NONE;
+ vid->pix.colorspace = V4L2_COLORSPACE_REC709;
+ vid->pix.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ vid->pix.quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ vid->pix.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+ vid->pix.interlaced = false;
+ vid->pix.half_size = vid->pix.sizeimage / 2;
+ vid->alloc_sizeimage = vid->pix.sizeimage;
+ hws_set_current_dv_timings(vid, vid->pix.width,
+ vid->pix.height, vid->pix.interlaced);
+ vid->current_fps = 60;
+
+ /* color controls default (mid-scale) */
+ vid->current_brightness = 0x80;
+ vid->current_contrast = 0x80;
+ vid->current_saturation = 0x80;
+ vid->current_hue = 0x80;
+
+ /* capture state */
+ vid->cap_active = false;
+ vid->stop_requested = false;
+ vid->last_buf_half_toggle = 0;
+ vid->half_seen = false;
+ vid->signal_loss_cnt = 0;
+
+ /* Create BCHS + DV power-present as modern controls */
+ {
+ int err = hws_ctrls_init(vid);
+
+ if (err) {
+ dev_err(&pdev->pdev->dev,
+ "v4l2 ctrl init failed on ch%d: %d\n", ch, err);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch)
+{
+ struct hws_video *vid;
+ unsigned long flags;
+ struct hwsvideo_buffer *buf, *tmp;
+ LIST_HEAD(done);
+
+ if (!pdev || ch < 0 || ch >= pdev->max_channels)
+ return;
+
+ vid = &pdev->video[ch];
+
+ /* 1) Stop HW best-effort for this channel */
+ hws_enable_video_capture(vid->parent, vid->channel_index, false);
+
+ /* 2) Flip software state so IRQ/BH will be no-ops if they run */
+ WRITE_ONCE(vid->stop_requested, true);
+ WRITE_ONCE(vid->cap_active, false);
+
+ /* 3) Ensure the IRQ handler finished any in-flight completions */
+ if (vid->parent && vid->parent->irq >= 0)
+ synchronize_irq(vid->parent->irq);
+
+ /* 4) Drain SW capture queue & in-flight under lock */
+ spin_lock_irqsave(&vid->irq_lock, flags);
+ hws_video_collect_done_locked(vid, &done);
+ spin_unlock_irqrestore(&vid->irq_lock, flags);
+
+ list_for_each_entry_safe(buf, tmp, &done, list) {
+ list_del_init(&buf->list);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+
+ /* 5) Release VB2 queue if initialized */
+ if (vid->buffer_queue.ops)
+ vb2_queue_release(&vid->buffer_queue);
+
+ /* 6) Free V4L2 controls */
+ v4l2_ctrl_handler_free(&vid->control_handler);
+
+ /* 7) Unregister the video_device if we own it */
+ if (vid->video_device && video_is_registered(vid->video_device))
+ video_unregister_device(vid->video_device);
+ /* If you allocated it with video_device_alloc(), release it here:
+ * video_device_release(vid->video_device);
+ */
+ vid->video_device = NULL;
+
+ /* 8) Reset simple state (don’t memset the whole struct here) */
+ mutex_destroy(&vid->state_lock);
+ INIT_LIST_HEAD(&vid->capture_queue);
+ vid->active = NULL;
+ vid->stop_requested = false;
+ vid->last_buf_half_toggle = 0;
+ vid->half_seen = false;
+ vid->signal_loss_cnt = 0;
+}
+
+/* Convenience cast */
+static inline struct hwsvideo_buffer *to_hwsbuf(struct vb2_buffer *vb)
+{
+ return container_of(to_vb2_v4l2_buffer(vb), struct hwsvideo_buffer, vb);
+}
+
+static int hws_buf_init(struct vb2_buffer *vb)
+{
+ struct hwsvideo_buffer *b = to_hwsbuf(vb);
+
+ INIT_LIST_HEAD(&b->list);
+ return 0;
+}
+
+static void hws_buf_finish(struct vb2_buffer *vb)
+{
+ /* vb2 core handles cache maintenance for dma-contig buffers */
+ (void)vb;
+}
+
+static void hws_buf_cleanup(struct vb2_buffer *vb)
+{
+ struct hwsvideo_buffer *b = to_hwsbuf(vb);
+
+ if (!list_empty(&b->list))
+ list_del_init(&b->list);
+}
+
+void hws_program_dma_for_addr(struct hws_pcie_dev *hws, unsigned int ch,
+ dma_addr_t dma)
+{
+ struct hws_video *vid = &hws->video[ch];
+
+ hws_program_dma_window(vid, dma);
+}
+
+void hws_enable_video_capture(struct hws_pcie_dev *hws, unsigned int chan,
+ bool on)
+{
+ u32 status;
+
+ if (!hws || hws->pci_lost || chan >= hws->max_channels)
+ return;
+
+ status = readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ status = on ? (status | BIT(chan)) : (status & ~BIT(chan));
+ writel(status, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ (void)readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+
+ WRITE_ONCE(hws->video[chan].cap_active, on);
+
+ dev_dbg(&hws->pdev->dev, "vcap %s ch%u (reg=0x%08x)\n",
+ on ? "ON" : "OFF", chan, status);
+}
+
+static void hws_seed_dma_windows(struct hws_pcie_dev *hws)
+{
+ const u32 addr_mask = PCI_E_BAR_ADD_MASK;
+ const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK;
+ u32 table = 0x208; /* one 64-bit entry per channel */
+ unsigned int ch;
+
+ if (!hws || !hws->bar0_base)
+ return;
+
+ /* If cur_max_video_ch isn’t set yet, default to max_channels */
+ if (!hws->cur_max_video_ch || hws->cur_max_video_ch > hws->max_channels)
+ hws->cur_max_video_ch = hws->max_channels;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++, table += 8) {
+ /* Scratch buffers are allocated once during probe. */
+ if (!hws->scratch_vid[ch].cpu)
+ continue;
+
+ /* 2) Program 64-bit BAR remap entry for this channel */
+ {
+ dma_addr_t p = hws->scratch_vid[ch].dma;
+ u32 lo = lower_32_bits(p) & addr_mask;
+ u32 hi = upper_32_bits(p);
+ u32 pci_addr_low = lower_32_bits(p) & addr_low_mask;
+
+ writel_relaxed(hi,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE +
+ table);
+ writel_relaxed(lo,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE +
+ table + PCIE_BARADDROFSIZE);
+
+ /* 3) Per-channel AXI base + PCI low */
+ writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE +
+ pci_addr_low,
+ hws->bar0_base + CVBS_IN_BUF_BASE +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* 4) Half-frame length in /16 units.
+ * Prefer the current channel’s computed half_size if available.
+ * Fall back to half of the preallocated scratch buffer.
+ */
+ {
+ u32 half_bytes = hws->video[ch].pix.half_size ?
+ hws->video[ch].pix.half_size :
+ (hws->scratch_vid[ch].size / 2);
+ writel_relaxed(half_bytes / 16,
+ hws->bar0_base +
+ CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+ }
+ }
+ }
+
+ /* Post writes so device sees them before we move on */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+}
+
+static void hws_ack_all_irqs(struct hws_pcie_dev *hws)
+{
+ u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+
+ if (st) {
+ writel(st, hws->bar0_base + HWS_REG_INT_STATUS); /* W1C */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+}
+
+static void hws_open_irq_fabric(struct hws_pcie_dev *hws)
+{
+ /* Route all sources to vector 0 (same value you’re already using) */
+ writel(0x00000000, hws->bar0_base + PCIE_INT_DEC_REG_BASE);
+ (void)readl(hws->bar0_base + PCIE_INT_DEC_REG_BASE);
+
+ /* Turn on the bridge if your IP needs it */
+ 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);
+}
+
+void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable)
+{
+ int i;
+
+ if (hws->start_run && !enable)
+ return;
+
+ /* 1) reset the decoder mode register to 0 */
+ writel(0x00000000, hws->bar0_base + HWS_REG_DEC_MODE);
+ hws_seed_dma_windows(hws);
+
+ /* 3) on a full reset, clear all per-channel status and indices */
+ if (!enable) {
+ for (i = 0; i < hws->max_channels; i++) {
+ /* helpers to arm/disable capture engines */
+ hws_enable_video_capture(hws, i, false);
+ }
+ }
+
+ /* 4) “Start run”: set bit31, wait a bit, then program low 24 bits */
+ writel(0x80000000, hws->bar0_base + HWS_REG_DEC_MODE);
+ // udelay(500);
+ 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);
+ /* 6) record that we're now running */
+ hws->start_run = true;
+}
+
+int hws_check_card_status(struct hws_pcie_dev *hws)
+{
+ u32 status;
+
+ if (!hws || !hws->bar0_base)
+ return -ENODEV;
+
+ status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+
+ /* Common “device missing” pattern */
+ if (unlikely(status == 0xFFFFFFFF)) {
+ hws->pci_lost = true;
+ dev_err(&hws->pdev->dev, "PCIe device not responding\n");
+ return -ENODEV;
+ }
+
+ /* If RUN/READY bit (bit0) isn’t set, (re)initialize 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);
+ /* Optional: verify the core cleared its busy bit, if you have one */
+ /* int ret = hws_check_busy(hws); */
+ /* if (ret) return ret; */
+ }
+
+ return 0;
+}
+
+void check_video_format(struct hws_pcie_dev *pdx)
+{
+ int i;
+
+ for (i = 0; i < pdx->cur_max_video_ch; i++) {
+ if (!hws_update_active_interlace(pdx, i)) {
+ /* No active video; optionally feed neutral frames to keep streaming. */
+ if (pdx->video[i].signal_loss_cnt == 0)
+ pdx->video[i].signal_loss_cnt = 1;
+ if (READ_ONCE(pdx->video[i].cap_active))
+ hws_force_no_signal_frame(&pdx->video[i],
+ "monitor_nosignal");
+ } else {
+ if (pdx->hw_ver > 0)
+ handle_hwv2_path(pdx, i);
+ else
+ /* Legacy path stub; see handle_legacy_path() comment. */
+ handle_legacy_path(pdx, i);
+
+ update_live_resolution(pdx, i);
+ pdx->video[i].signal_loss_cnt = 0;
+ }
+ }
+}
+
+static inline void hws_write_if_diff(struct hws_pcie_dev *hws, u32 reg_off,
+ u32 new_val)
+{
+ void __iomem *addr;
+ u32 old;
+
+ if (!hws || !hws->bar0_base)
+ return;
+
+ addr = hws->bar0_base + reg_off;
+
+ old = readl(addr);
+ /* Treat all-ones as device gone; avoid writing garbage. */
+ if (unlikely(old == 0xFFFFFFFF)) {
+ hws->pci_lost = true;
+ return;
+ }
+
+ if (old != new_val) {
+ writel(new_val, addr);
+ /* Post the write on some bridges / enforce ordering. */
+ (void)readl(addr);
+ }
+}
+
+static bool hws_update_active_interlace(struct hws_pcie_dev *pdx,
+ unsigned int ch)
+{
+ u32 reg;
+ bool active, interlace;
+
+ if (ch >= pdx->cur_max_video_ch)
+ return false;
+
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ active = !!(reg & BIT(ch));
+ interlace = !!(reg & BIT(8 + ch));
+
+ if (pdx->video[ch].hotplug_detect_control) {
+ v4l2_ctrl_lock(pdx->video[ch].hotplug_detect_control);
+ __v4l2_ctrl_s_ctrl(pdx->video[ch].hotplug_detect_control,
+ active);
+ v4l2_ctrl_unlock(pdx->video[ch].hotplug_detect_control);
+ }
+
+ WRITE_ONCE(pdx->video[ch].pix.interlaced, interlace);
+ return active;
+}
+
+/* Modern hardware path: keep HW registers in sync with current per-channel
+ * software state. Adjust the OUT_* bits below to match your HW contract.
+ */
+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;
+
+ if (!hws || !hws->bar0_base || ch >= hws->max_channels)
+ return;
+
+ vid = &hws->video[ch];
+
+ /* 1) Input frame rate (read-only; log or export via debugfs if wanted) */
+ in_fps = readl(hws->bar0_base + HWS_REG_FRAME_RATE(ch));
+ if (in_fps)
+ vid->current_fps = in_fps;
+ /* dev_dbg(&hws->pdev->dev, "ch%u input fps=%u\n", ch, in_fps); */
+
+ /* 2) Output resolution programming
+ * If your HW expects a separate “scaled” size, add fields to track it.
+ * For now, mirror the current format (fmt_curr) to OUT_RES.
+ */
+ want_out_res = (vid->pix.height << 16) | vid->pix.width;
+ cur_out_res = readl(hws->bar0_base + HWS_REG_OUT_RES(ch));
+ if (cur_out_res != want_out_res)
+ hws_write_if_diff(hws, HWS_REG_OUT_RES(ch), want_out_res);
+
+ /* 3) Output FPS: only program if you actually track a target.
+ * Example heuristic (disabled by default):
+ *
+ * u32 out_fps = (vid->fmt_curr.height >= 1080) ? 60 : 30;
+ * hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), out_fps);
+ */
+
+ /* 4) BCHS controls: pack from per-channel current_* fields */
+ reg = readl(hws->bar0_base + HWS_REG_BCHS(ch));
+ {
+ u8 br = reg & 0xFF;
+ u8 co = (reg >> 8) & 0xFF;
+ u8 hu = (reg >> 16) & 0xFF;
+ u8 sa = (reg >> 24) & 0xFF;
+
+ if (br != vid->current_brightness ||
+ co != vid->current_contrast || hu != vid->current_hue ||
+ sa != vid->current_saturation) {
+ u32 packed = (vid->current_saturation << 24) |
+ (vid->current_hue << 16) |
+ (vid->current_contrast << 8) |
+ vid->current_brightness;
+ hws_write_if_diff(hws, HWS_REG_BCHS(ch), packed);
+ }
+ }
+
+ /* 5) HDCP detect: read only (no cache field in your structs today) */
+ reg = readl(hws->bar0_base + HWS_REG_HDCP_STATUS);
+ /* bool hdcp = !!(reg & BIT(ch)); // use if you later add a field/control */
+}
+
+static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch)
+{
+ /*
+ * Legacy (hw_ver == 0) expected behavior:
+ * - A per-channel SW FPS accumulator incremented on each VDONE.
+ * - A once-per-second poll mapped the count to discrete FPS:
+ * >55*2 => 60, >45*2 => 50, >25*2 => 30, >20*2 => 25, else 60,
+ * then reset the accumulator to 0.
+ * - The *2 factor assumed VDONE fired per-field; if legacy VDONE is
+ * per-frame, drop the factor.
+ *
+ * Current code keeps this path as a no-op; vid->current_fps stays at the
+ * default or mode-derived value. If accurate legacy FPS reporting is
+ * needed (V4L2 g_parm/timeperframe), reintroduce the accumulator in the
+ * IRQ path and perform the mapping/reset here.
+ *
+ * No-op by default. If you introduce a SW FPS accumulator, map it here.
+ *
+ * Example skeleton:
+ *
+ * u32 sw_rate = READ_ONCE(hws->sw_fps[ch]); // incremented elsewhere
+ * if (sw_rate > THRESHOLD) {
+ * u32 fps = pick_fps_from_rate(sw_rate);
+ * hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), fps);
+ * WRITE_ONCE(hws->sw_fps[ch], 0);
+ * }
+ */
+ (void)hws;
+ (void)ch;
+}
+
+static void hws_video_apply_mode_change(struct hws_pcie_dev *pdx,
+ unsigned int ch, u16 w, u16 h,
+ bool interlaced)
+{
+ struct hws_video *v = &pdx->video[ch];
+ unsigned long flags;
+ u32 new_size;
+ bool queue_busy;
+ struct list_head done;
+ struct hwsvideo_buffer *b, *tmp;
+
+ if (!pdx || !pdx->bar0_base)
+ return;
+ if (ch >= pdx->max_channels)
+ return;
+ if (!w || !h || w > MAX_VIDEO_HW_W ||
+ (!interlaced && h > MAX_VIDEO_HW_H) ||
+ (interlaced && (h * 2) > MAX_VIDEO_HW_H))
+ return;
+
+ if (!mutex_trylock(&v->state_lock))
+ return;
+
+ INIT_LIST_HEAD(&done);
+
+ WRITE_ONCE(v->stop_requested, true);
+ WRITE_ONCE(v->cap_active, false);
+ /* Publish software stop first so the IRQ completion path sees the stop
+ * before we touch MMIO or the lists. Pairs with READ_ONCE() checks in the
+ * VDONE handler and hws_arm_next() to prevent completions while modes
+ * change.
+ */
+ smp_wmb();
+
+ hws_enable_video_capture(pdx, ch, false);
+ readl(pdx->bar0_base + HWS_REG_INT_STATUS);
+
+ if (v->parent && v->parent->irq >= 0)
+ synchronize_irq(v->parent->irq);
+
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_video_collect_done_locked(v, &done);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* Update software pixel state */
+ v->pix.width = w;
+ v->pix.height = h;
+ v->pix.interlaced = interlaced;
+ hws_set_current_dv_timings(v, w, h, interlaced);
+ /* Try to reflect the live frame rate if HW reports it; otherwise default
+ * to common rates (50 Hz for 576p, else 60 Hz).
+ */
+ {
+ u32 fps = readl(pdx->bar0_base + HWS_REG_FRAME_RATE(ch));
+
+ if (fps)
+ v->current_fps = fps;
+ else
+ v->current_fps = (h == 576) ? 50 : 60;
+ }
+
+ new_size = hws_calc_sizeimage(v, w, h, interlaced);
+ v->window_valid = false;
+ queue_busy = vb2_is_busy(&v->buffer_queue);
+
+ /* Mode changes require userspace to renegotiate buffers and restart
+ * streaming. Complete every queued buffer with an error, surface a
+ * SOURCE_CHANGE event, and leave the queue in an error state until the
+ * next streamoff/reqbufs cycle.
+ */
+ if (queue_busy) {
+ struct v4l2_event ev = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+ };
+
+ ev.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
+ v4l2_event_queue(v->video_device, &ev);
+ vb2_queue_error(&v->buffer_queue);
+ } else {
+ v->alloc_sizeimage = PAGE_ALIGN(new_size);
+ }
+
+ /* Program HW with new resolution */
+ hws_write_if_diff(pdx, HWS_REG_OUT_RES(ch), (h << 16) | w);
+
+ /* Legacy half-buffer programming */
+ writel(v->pix.half_size / 16,
+ pdx->bar0_base + CVBS_IN_BUF_BASE2 + ch * PCIE_BARADDROFSIZE);
+ (void)readl(pdx->bar0_base + CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* Reset per-channel toggles/counters */
+ WRITE_ONCE(v->last_buf_half_toggle, 0);
+ atomic_set(&v->sequence_number, 0);
+
+ mutex_unlock(&v->state_lock);
+
+ list_for_each_entry_safe(b, tmp, &done, list) {
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+}
+
+static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch)
+{
+ u32 reg = readl(pdx->bar0_base + HWS_REG_IN_RES(ch));
+ u16 res_w = reg & 0xFFFF;
+ u16 res_h = (reg >> 16) & 0xFFFF;
+ bool interlace = READ_ONCE(pdx->video[ch].pix.interlaced);
+
+ bool within_hw = (res_w <= MAX_VIDEO_HW_W) &&
+ ((!interlace && res_h <= MAX_VIDEO_HW_H) ||
+ (interlace && (res_h * 2) <= MAX_VIDEO_HW_H));
+
+ if (!within_hw)
+ return;
+
+ if (res_w != pdx->video[ch].pix.width ||
+ res_h != pdx->video[ch].pix.height) {
+ hws_video_apply_mode_change(pdx, ch, res_w, res_h, interlace);
+ }
+}
+
+static int hws_open(struct file *file)
+{
+ return v4l2_fh_open(file);
+}
+
+static const struct v4l2_file_operations hws_fops = {
+ .owner = THIS_MODULE,
+ .open = hws_open,
+ .release = vb2_fop_release,
+ .poll = vb2_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = vb2_fop_mmap,
+};
+
+static int hws_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_src_change_event_subscribe(fh, sub);
+ case V4L2_EVENT_CTRL:
+ return v4l2_ctrl_subscribe_event(fh, sub);
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_ioctl_ops hws_ioctl_fops = {
+ /* Core caps/info */
+ .vidioc_querycap = hws_vidioc_querycap,
+
+ /* Pixel format: still needed to report YUYV etc. */
+ .vidioc_enum_fmt_vid_cap = hws_vidioc_enum_fmt_vid_cap,
+ .vidioc_enum_frameintervals = hws_vidioc_enum_frameintervals,
+ .vidioc_g_fmt_vid_cap = hws_vidioc_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = hws_vidioc_s_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = hws_vidioc_try_fmt_vid_cap,
+
+ /* Buffer queueing / streaming */
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+
+ /* Inputs */
+ .vidioc_enum_input = hws_vidioc_enum_input,
+ .vidioc_g_input = hws_vidioc_g_input,
+ .vidioc_s_input = hws_vidioc_s_input,
+
+ /* DV timings (HDMI/DVI/VESA modes) */
+ .vidioc_query_dv_timings = hws_vidioc_query_dv_timings,
+ .vidioc_enum_dv_timings = hws_vidioc_enum_dv_timings,
+ .vidioc_g_dv_timings = hws_vidioc_g_dv_timings,
+ .vidioc_s_dv_timings = hws_vidioc_s_dv_timings,
+ .vidioc_dv_timings_cap = hws_vidioc_dv_timings_cap,
+
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = hws_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_g_parm = hws_vidioc_g_parm,
+ .vidioc_s_parm = hws_vidioc_s_parm,
+};
+
+static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
+ bool interlaced)
+{
+ /* example for packed 16bpp (YUYV); replace with your real math/align */
+ u32 lines = h; /* full frame lines for sizeimage */
+ u32 bytesperline = ALIGN(w * 2, 64);
+ u32 sizeimage, half0;
+
+ /* publish into pix, since we now carry these in-state */
+ v->pix.bytesperline = bytesperline;
+ sizeimage = bytesperline * lines;
+
+ half0 = sizeimage / 2;
+
+ v->pix.sizeimage = sizeimage;
+ v->pix.half_size = half0; /* first half; second = sizeimage - half0 */
+ v->pix.field = interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
+
+ return v->pix.sizeimage;
+}
+
+static int hws_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
+ unsigned int *nplanes, unsigned int sizes[],
+ struct device *alloc_devs[])
+{
+ struct hws_video *vid = q->drv_priv;
+
+ (void)num_buffers;
+ (void)alloc_devs;
+
+ if (!vid->pix.sizeimage) {
+ vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
+ vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
+ }
+ if (*nplanes) {
+ if (sizes[0] < vid->pix.sizeimage)
+ return -EINVAL;
+ } else {
+ *nplanes = 1;
+ sizes[0] = PAGE_ALIGN(vid->pix.sizeimage);
+ }
+
+ vid->alloc_sizeimage = PAGE_ALIGN(vid->pix.sizeimage);
+ return 0;
+}
+
+static int hws_buffer_prepare(struct vb2_buffer *vb)
+{
+ struct hws_video *vid = vb->vb2_queue->drv_priv;
+ struct hws_pcie_dev *hws = vid->parent;
+ size_t need = vid->pix.sizeimage;
+ dma_addr_t dma_addr;
+
+ if (vb2_plane_size(vb, 0) < need)
+ return -EINVAL;
+
+ /* Validate DMA address alignment */
+ dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ if (dma_addr & 0x3F) { /* 64-byte alignment required */
+ dev_err(&hws->pdev->dev,
+ "Buffer DMA address 0x%llx not 64-byte aligned\n",
+ (unsigned long long)dma_addr);
+ return -EINVAL;
+ }
+
+ vb2_set_plane_payload(vb, 0, need);
+ return 0;
+}
+
+static void hws_buffer_queue(struct vb2_buffer *vb)
+{
+ struct hws_video *vid = vb->vb2_queue->drv_priv;
+ struct hwsvideo_buffer *buf = to_hwsbuf(vb);
+ struct hws_pcie_dev *hws = vid->parent;
+ unsigned long flags;
+
+ dev_dbg(&hws->pdev->dev,
+ "buffer_queue(ch=%u): vb=%p sizeimage=%u q_active=%d\n",
+ vid->channel_index, vb, vid->pix.sizeimage,
+ READ_ONCE(vid->cap_active));
+
+ /* Initialize buffer slot */
+ buf->slot = 0;
+
+ spin_lock_irqsave(&vid->irq_lock, flags);
+ list_add_tail(&buf->list, &vid->capture_queue);
+ vid->queued_count++;
+
+ /* If streaming and no in-flight buffer, prime HW immediately */
+ if (READ_ONCE(vid->cap_active) && !vid->active) {
+ dma_addr_t dma_addr;
+
+ dev_dbg(&hws->pdev->dev,
+ "buffer_queue(ch=%u): priming first vb=%p\n",
+ vid->channel_index, &buf->vb.vb2_buf);
+ list_del_init(&buf->list);
+ vid->queued_count--;
+ vid->active = buf;
+
+ dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(vid->parent, vid->channel_index,
+ dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base + HWS_REG_DMA_ADDR(vid->channel_index));
+
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, vid->channel_index, true);
+ hws_prime_next_locked(vid);
+ } else if (READ_ONCE(vid->cap_active) && vid->active) {
+ hws_prime_next_locked(vid);
+ }
+ spin_unlock_irqrestore(&vid->irq_lock, flags);
+}
+
+static int hws_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct hws_video *v = q->drv_priv;
+ struct hws_pcie_dev *hws = v->parent;
+ struct hwsvideo_buffer *to_program = NULL; /* local copy */
+ struct vb2_buffer *prog_vb2 = NULL;
+ unsigned long flags;
+ int ret;
+
+ dev_dbg(&hws->pdev->dev, "start_streaming: ch=%u count=%u\n",
+ v->channel_index, count);
+
+ ret = hws_check_card_status(hws);
+ if (ret) {
+ struct hwsvideo_buffer *b, *tmp;
+ unsigned long f;
+ LIST_HEAD(queued);
+
+ spin_lock_irqsave(&v->irq_lock, f);
+ if (v->active) {
+ list_add_tail(&v->active->list, &queued);
+ v->active = NULL;
+ }
+ if (v->next_prepared) {
+ list_add_tail(&v->next_prepared->list, &queued);
+ v->next_prepared = NULL;
+ }
+ while (!list_empty(&v->capture_queue)) {
+ b = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_move_tail(&b->list, &queued);
+ }
+ spin_unlock_irqrestore(&v->irq_lock, f);
+
+ list_for_each_entry_safe(b, tmp, &queued, list) {
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+ }
+ return ret;
+ }
+ (void)hws_update_active_interlace(hws, v->channel_index);
+
+ lockdep_assert_held(&v->state_lock);
+ /* init per-stream state */
+ WRITE_ONCE(v->stop_requested, false);
+ WRITE_ONCE(v->cap_active, true);
+ WRITE_ONCE(v->half_seen, false);
+ WRITE_ONCE(v->last_buf_half_toggle, 0);
+
+ /* Try to prime a buffer, but it's OK if none are queued yet */
+ spin_lock_irqsave(&v->irq_lock, flags);
+ if (!v->active && !list_empty(&v->capture_queue)) {
+ to_program = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&to_program->list);
+ v->queued_count--;
+ v->active = to_program;
+ prog_vb2 = &to_program->vb.vb2_buf;
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u took buffer %p\n",
+ v->channel_index, to_program);
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* Only program/enable HW if we actually have a buffer */
+ if (to_program) {
+ if (!prog_vb2)
+ prog_vb2 = &to_program->vb.vb2_buf;
+ {
+ dma_addr_t dma_addr;
+
+ dma_addr = vb2_dma_contig_plane_dma_addr(prog_vb2, 0);
+ hws_program_dma_for_addr(hws, v->channel_index, dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base +
+ HWS_REG_DMA_ADDR(v->channel_index));
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u programmed buffer %p dma=0x%08x\n",
+ v->channel_index, to_program,
+ lower_32_bits(dma_addr));
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, v->channel_index, true);
+ {
+ unsigned long pf;
+
+ spin_lock_irqsave(&v->irq_lock, pf);
+ hws_prime_next_locked(v);
+ spin_unlock_irqrestore(&v->irq_lock, pf);
+ }
+ } else {
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u no buffer yet (will arm on QBUF)\n",
+ v->channel_index);
+ }
+
+ return 0;
+}
+
+static void hws_log_video_state(struct hws_video *v, const char *action,
+ const char *phase)
+{
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned long flags;
+ unsigned int queued = 0;
+ unsigned int tracked = 0;
+ unsigned int seq = 0;
+ struct hwsvideo_buffer *b;
+ bool streaming = 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 = READ_ONCE(v->cap_active);
+ stop_requested = READ_ONCE(v->stop_requested);
+ active = v->active;
+ next_prepared = v->next_prepared;
+ tracked = v->queued_count;
+ seq = (u32)atomic_read(&v->sequence_number);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:%s ch=%u streaming=%d cap=%d stop=%d active=%p next=%p queued=%u tracked=%u seq=%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 = q->drv_priv;
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned long flags;
+ struct hwsvideo_buffer *b, *tmp;
+ LIST_HEAD(done);
+ unsigned int done_cnt = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ hws_log_video_state(v, "streamoff", "begin");
+
+ /* 1) Quiesce SW/HW first */
+ lockdep_assert_held(&v->state_lock);
+ WRITE_ONCE(v->cap_active, false);
+ WRITE_ONCE(v->stop_requested, true);
+
+ hws_enable_video_capture(v->parent, v->channel_index, false);
+
+ /* 2) Collect in-flight + queued under the IRQ lock */
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_video_collect_done_locked(v, &done);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* 3) Complete outside the lock */
+ list_for_each_entry_safe(b, tmp, &done, list) {
+ /* 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=%u completed=%u (%lluus)\n",
+ v->channel_index, done_cnt,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ hws_log_video_state(v, "streamoff", "end");
+}
+
+static const struct vb2_ops hwspcie_video_qops = {
+ .queue_setup = hws_queue_setup,
+ .buf_prepare = hws_buffer_prepare,
+ .buf_init = hws_buf_init,
+ .buf_finish = hws_buf_finish,
+ .buf_cleanup = hws_buf_cleanup,
+ // .buf_finish = hws_buffer_finish,
+ .buf_queue = hws_buffer_queue,
+ .start_streaming = hws_start_streaming,
+ .stop_streaming = hws_stop_streaming,
+};
+
+int hws_video_register(struct hws_pcie_dev *dev)
+{
+ int i, ret;
+
+ ret = v4l2_device_register(&dev->pdev->dev, &dev->v4l2_device);
+ if (ret) {
+ dev_err(&dev->pdev->dev, "v4l2_device_register failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ for (i = 0; i < dev->cur_max_video_ch; i++) {
+ struct hws_video *ch = &dev->video[i];
+ struct video_device *vdev;
+ struct vb2_queue *q;
+
+ /* hws_video_init_channel() should have set:
+ * - ch->parent, ch->channel_index
+ * - locks (state_lock, irq_lock)
+ * - capture_queue (INIT_LIST_HEAD)
+ * - control_handler + controls
+ * - fmt_curr (width/height)
+ * Don’t reinitialize any of those here.
+ */
+
+ vdev = video_device_alloc();
+ if (!vdev) {
+ dev_err(&dev->pdev->dev,
+ "video_device_alloc ch%u failed\n", i);
+ ret = -ENOMEM;
+ goto err_unwind;
+ }
+ ch->video_device = vdev;
+
+ /* Basic V4L2 node setup */
+ snprintf(vdev->name, sizeof(vdev->name), "%s-hdmi%u",
+ KBUILD_MODNAME, i);
+ vdev->v4l2_dev = &dev->v4l2_device;
+ vdev->fops = &hws_fops; /* your file_ops */
+ vdev->ioctl_ops = &hws_ioctl_fops; /* your ioctl_ops */
+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ vdev->lock = &ch->state_lock; /* serialize file ops */
+ vdev->ctrl_handler = &ch->control_handler;
+ vdev->vfl_dir = VFL_DIR_RX;
+ vdev->release = video_device_release;
+ if (ch->control_handler.error) {
+ ret = ch->control_handler.error;
+ goto err_unwind;
+ }
+ video_set_drvdata(vdev, ch);
+
+ /* vb2 queue init (dma-contig) */
+ q = &ch->buffer_queue;
+ memset(q, 0, sizeof(*q));
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_DMABUF;
+ q->drv_priv = ch;
+ q->buf_struct_size = sizeof(struct hwsvideo_buffer);
+ q->ops = &hwspcie_video_qops; /* your vb2_ops */
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &ch->state_lock;
+ q->min_queued_buffers = 1;
+ q->dev = &dev->pdev->dev;
+
+ ret = vb2_queue_init(q);
+ vdev->queue = q;
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "vb2_queue_init ch%u failed: %d\n", i, ret);
+ goto err_unwind;
+ }
+
+ /* Make controls live (no-op if none or already set up) */
+ if (ch->control_handler.error) {
+ ret = ch->control_handler.error;
+ dev_err(&dev->pdev->dev,
+ "ctrl handler ch%u error: %d\n", i, ret);
+ goto err_unwind;
+ }
+ v4l2_ctrl_handler_setup(&ch->control_handler);
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "video_register_device ch%u failed: %d\n", i,
+ ret);
+ goto err_unwind;
+ }
+
+ ret = hws_resolution_create(vdev);
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "device_create_file(resolution) ch%u failed: %d\n",
+ i, ret);
+ goto err_unwind;
+ }
+ }
+
+ return 0;
+
+err_unwind:
+ for (; i >= 0; i--) {
+ struct hws_video *ch = &dev->video[i];
+
+ if (video_is_registered(ch->video_device))
+ hws_resolution_remove(ch->video_device);
+ if (video_is_registered(ch->video_device))
+ vb2_video_unregister_device(ch->video_device);
+ if (ch->video_device) {
+ /* If not registered, we must free the alloc’d vdev ourselves */
+ if (!video_is_registered(ch->video_device))
+ video_device_release(ch->video_device);
+ ch->video_device = NULL;
+ }
+ }
+ v4l2_device_unregister(&dev->v4l2_device);
+ return ret;
+}
+
+void hws_video_unregister(struct hws_pcie_dev *dev)
+{
+ int i;
+
+ if (!dev)
+ return;
+
+ for (i = 0; i < dev->cur_max_video_ch; i++) {
+ struct hws_video *ch = &dev->video[i];
+
+ if (ch->video_device)
+ hws_resolution_remove(ch->video_device);
+ if (ch->video_device) {
+ vb2_video_unregister_device(ch->video_device);
+ ch->video_device = NULL;
+ }
+ v4l2_ctrl_handler_free(&ch->control_handler);
+ }
+ v4l2_device_unregister(&dev->v4l2_device);
+}
+
+int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason)
+{
+ int i, ret = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ dev_dbg(&hws->pdev->dev, "video:%s:begin channels=%u\n", reason,
+ hws->cur_max_video_ch);
+ for (i = 0; i < hws->cur_max_video_ch; i++) {
+ struct hws_video *vid = &hws->video[i];
+ struct vb2_queue *q = &vid->buffer_queue;
+ u64 ch_start_ns = ktime_get_mono_fast_ns();
+ bool streaming;
+
+ if (!q || !q->ops) {
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d skipped queue-unavailable\n",
+ reason, i);
+ continue;
+ }
+
+ streaming = vb2_is_streaming(q);
+ hws_log_video_state(vid, reason, "channel");
+ if (streaming) {
+ /* Stop via vb2 (runs your .stop_streaming) */
+ int r = vb2_streamoff(q, q->type);
+
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d streamoff ret=%d (%lluus)\n",
+ reason, i, r, (unsigned long long)
+ ((ktime_get_mono_fast_ns() - ch_start_ns) / 1000));
+ if (r && !ret)
+ ret = r;
+ } else {
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d idle (%lluus)\n",
+ reason, i, (unsigned long long)
+ ((ktime_get_mono_fast_ns() - ch_start_ns) / 1000));
+ }
+ }
+ dev_dbg(&hws->pdev->dev, "video:%s:done ret=%d (%lluus)\n", reason,
+ ret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ return ret;
+}
+
+void hws_video_pm_resume(struct hws_pcie_dev *hws)
+{
+ /* Nothing mandatory to do here for vb2 — userspace will STREAMON again.
+ * If you track per-channel 'auto-restart' policy, re-arm it here.
+ */
+}
diff --git a/drivers/media/pci/hws/hws_video.h b/drivers/media/pci/hws/hws_video.h
new file mode 100644
index 000000000000..d02cfb2cdeb3
--- /dev/null
+++ b/drivers/media/pci/hws/hws_video.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_VIDEO_H
+#define HWS_VIDEO_H
+
+struct hws_video;
+
+int hws_video_register(struct hws_pcie_dev *dev);
+void hws_video_unregister(struct hws_pcie_dev *dev);
+void hws_enable_video_capture(struct hws_pcie_dev *hws,
+ unsigned int chan,
+ bool on);
+void hws_prime_next_locked(struct hws_video *vid);
+
+int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch);
+void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch);
+void check_video_format(struct hws_pcie_dev *pdx);
+int hws_check_card_status(struct hws_pcie_dev *hws);
+void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable);
+
+void hws_program_dma_for_addr(struct hws_pcie_dev *hws,
+ unsigned int ch,
+ dma_addr_t dma);
+void hws_set_dma_doorbell(struct hws_pcie_dev *hws, unsigned int ch,
+ dma_addr_t dma, const char *tag);
+
+int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason);
+void hws_video_pm_resume(struct hws_pcie_dev *hws);
+
+#endif // HWS_VIDEO_H
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 2/2] MAINTAINERS: add entry for AVMatrix HWS driver
2026-03-18 0:10 ` [PATCH v2 0/2] media: pci: add AVMatrix HWS capture driver Ben Hoff
2026-03-18 0:10 ` [PATCH v2 1/2] " Ben Hoff
@ 2026-03-18 0:10 ` Ben Hoff
2026-03-24 9:19 ` [PATCH v2 0/2] media: pci: add AVMatrix HWS capture driver Hans Verkuil
2026-03-30 19:56 ` [PATCH v3 " hoff.benjamin.k
3 siblings, 0 replies; 11+ messages in thread
From: Ben Hoff @ 2026-03-18 0:10 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-kernel, Ben Hoff
Add the maintainer and file pattern for the new AVMatrix HWS capture
driver series.
Signed-off-by: Ben Hoff <hoff.benjamin.k@gmail.com>
---
MAINTAINERS | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index d7241695df96..71c5d3a575af 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4278,6 +4278,12 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
F: drivers/iio/adc/hx711.c
+AVMATRIX HWS CAPTURE DRIVER
+M: Ben Hoff <hoff.benjamin.k@gmail.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/pci/hws/
+
AWINIC AW99706 WLED BACKLIGHT DRIVER
M: Junjie Cao <caojunjie650@gmail.com>
S: Maintained
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] media: pci: add AVMatrix HWS capture driver
2026-03-18 0:10 ` [PATCH v2 1/2] " Ben Hoff
@ 2026-03-24 9:17 ` Hans Verkuil
0 siblings, 0 replies; 11+ messages in thread
From: Hans Verkuil @ 2026-03-24 9:17 UTC (permalink / raw)
To: Ben Hoff, linux-media; +Cc: Mauro Carvalho Chehab, linux-kernel
Hi Ben,
Some more view comments below:
On 18/03/2026 01:10, Ben Hoff wrote:
> Add an in-tree AVMatrix HWS PCIe capture driver. The driver supports
> up to four HDMI inputs and exposes the video capture path through
> V4L2 with vb2-dma-contig streaming, DV timings, and per-input
> controls. Audio support is intentionally omitted from this
> submission.
>
> This driver is derived from a GPL out-of-tree driver. The baseline
> rework used for comparison is available at:
> https://github.com/benhoff/hws/tree/baseline
>
> A vendor driver bundle is available at:
> https://www.acasis.com/pages/acasis-product-drivers
>
> The vendor is not involved in this upstreaming effort.
>
> This in-tree version folds in the review-driven cleanup needed for a
> v2 posting:
> - keep scratch DMA allocation on a single probe-owned path
> - avoid double-freeing V4L2 control handlers on register unwind
> - turn live mode changes into explicit SOURCE_CHANGE renegotiation
> - report frame intervals and DV power-present status
>
> Build-tested with:
> make -C /home/hoff/swdev/linux O=/tmp/hws-build M=drivers/media/pci/hws W=1 KBUILD_MODPOST_WARN=1 modules
>
> Signed-off-by: Ben Hoff <hoff.benjamin.k@gmail.com>
> ---
> drivers/media/pci/Kconfig | 1 +
> drivers/media/pci/Makefile | 1 +
> drivers/media/pci/hws/Kconfig | 12 +
> drivers/media/pci/hws/Makefile | 4 +
> drivers/media/pci/hws/hws.h | 176 +++
> drivers/media/pci/hws/hws_irq.c | 271 +++++
> drivers/media/pci/hws/hws_irq.h | 10 +
> drivers/media/pci/hws/hws_pci.c | 864 +++++++++++++
> drivers/media/pci/hws/hws_reg.h | 144 +++
> drivers/media/pci/hws/hws_v4l2_ioctl.c | 778 ++++++++++++
> drivers/media/pci/hws/hws_v4l2_ioctl.h | 43 +
> drivers/media/pci/hws/hws_video.c | 1546 ++++++++++++++++++++++++
> drivers/media/pci/hws/hws_video.h | 29 +
> 13 files changed, 3879 insertions(+)
> create mode 100644 drivers/media/pci/hws/Kconfig
> create mode 100644 drivers/media/pci/hws/Makefile
> create mode 100644 drivers/media/pci/hws/hws.h
> create mode 100644 drivers/media/pci/hws/hws_irq.c
> create mode 100644 drivers/media/pci/hws/hws_irq.h
> create mode 100644 drivers/media/pci/hws/hws_pci.c
> create mode 100644 drivers/media/pci/hws/hws_reg.h
> create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.c
> create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.h
> create mode 100644 drivers/media/pci/hws/hws_video.c
> create mode 100644 drivers/media/pci/hws/hws_video.h
>
> diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
> index eebb16c58f3d..bfdb200f85a3 100644
> --- a/drivers/media/pci/Kconfig
> +++ b/drivers/media/pci/Kconfig
> @@ -13,6 +13,7 @@ if MEDIA_PCI_SUPPORT
> if MEDIA_CAMERA_SUPPORT
> comment "Media capture support"
>
> +source "drivers/media/pci/hws/Kconfig"
> source "drivers/media/pci/mgb4/Kconfig"
> source "drivers/media/pci/solo6x10/Kconfig"
> source "drivers/media/pci/tw5864/Kconfig"
> diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
> index 02763ad88511..c4508b6723a9 100644
> --- a/drivers/media/pci/Makefile
> +++ b/drivers/media/pci/Makefile
> @@ -29,6 +29,7 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
> obj-$(CONFIG_VIDEO_CX25821) += cx25821/
> obj-$(CONFIG_VIDEO_CX88) += cx88/
> obj-$(CONFIG_VIDEO_DT3155) += dt3155/
> +obj-$(CONFIG_VIDEO_HWS) += hws/
> obj-$(CONFIG_VIDEO_IVTV) += ivtv/
> obj-$(CONFIG_VIDEO_MGB4) += mgb4/
> obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
> diff --git a/drivers/media/pci/hws/Kconfig b/drivers/media/pci/hws/Kconfig
> new file mode 100644
> index 000000000000..b606d5ffadef
> --- /dev/null
> +++ b/drivers/media/pci/hws/Kconfig
> @@ -0,0 +1,12 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +config VIDEO_HWS
> + tristate "AVMatrix HWS capture driver"
> + depends on VIDEO_DEV && PCI
> + select VIDEOBUF2_DMA_CONTIG
> + help
> + This is a Video4Linux2 driver for AVMatrix HWS PCIe capture cards.
> + It provides a PCIe capture interface with V4L2 streaming, DV timings,
> + and per-input controls for the supported HWS boards.
> +
> + To compile this driver as a module, choose M here: the module will
> + be called hws.
> diff --git a/drivers/media/pci/hws/Makefile b/drivers/media/pci/hws/Makefile
> new file mode 100644
> index 000000000000..a66aebd348e5
> --- /dev/null
> +++ b/drivers/media/pci/hws/Makefile
> @@ -0,0 +1,4 @@
> +# SPDX-License-Identifier: GPL-2.0
> +hws-objs := hws_pci.o hws_irq.o hws_video.o hws_v4l2_ioctl.o
> +
> +obj-$(CONFIG_VIDEO_HWS) += hws.o
> diff --git a/drivers/media/pci/hws/hws.h b/drivers/media/pci/hws/hws.h
> new file mode 100644
> index 000000000000..097f6937b231
> --- /dev/null
> +++ b/drivers/media/pci/hws/hws.h
> @@ -0,0 +1,176 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef HWS_PCIE_H
> +#define HWS_PCIE_H
> +
> +#include <linux/types.h>
> +#include <linux/compiler.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/kthread.h>
> +#include <linux/pci.h>
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/spinlock.h>
> +#include <linux/sizes.h>
> +#include <linux/atomic.h>
> +
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-dv-timings.h>
> +#include <media/videobuf2-dma-contig.h>
> +
> +#include "hws_reg.h"
> +
> +struct hwsmem_param {
> + u32 index;
> + u32 type;
> + u32 status;
> +};
> +
> +struct hws_pix_state {
> + u32 width;
> + u32 height;
> + u32 fourcc; /* V4L2_PIX_FMT_* (YUYV only here) */
> + u32 bytesperline; /* stride */
> + u32 sizeimage; /* full frame */
> + enum v4l2_field field; /* V4L2_FIELD_NONE or INTERLACED */
> + enum v4l2_colorspace colorspace; /* e.g., REC709 */
> + enum v4l2_ycbcr_encoding ycbcr_enc; /* V4L2_YCBCR_ENC_DEFAULT */
> + enum v4l2_quantization quantization; /* V4L2_QUANTIZATION_LIM_RANGE */
> + enum v4l2_xfer_func xfer_func; /* V4L2_XFER_FUNC_DEFAULT */
> + bool interlaced; /* cached hardware state */
> + u32 half_size; /* optional: if your HW needs it */
> +};
> +
> +#define UNSET (-1U)
> +
> +struct hws_pcie_dev;
> +struct hws_adapter;
> +struct hws_video;
> +
> +struct hwsvideo_buffer {
> + struct vb2_v4l2_buffer vb;
> + struct list_head list;
> + int slot; /* for two-buffer approach */
> +};
> +
> +struct hws_video {
> + /* ───── linkage ───── */
> + struct hws_pcie_dev *parent; /* parent device */
> + struct video_device *video_device;
> +
> + struct vb2_queue buffer_queue;
> + struct list_head capture_queue;
> + struct hwsvideo_buffer *active;
> + struct hwsvideo_buffer *next_prepared;
> +
> + /* ───── locking ───── */
> + struct mutex state_lock; /* primary state */
> + spinlock_t irq_lock; /* ISR-side */
> +
> + /* ───── indices ───── */
> + int channel_index;
> +
> + /* ───── colour controls ───── */
> + int current_brightness;
> + int current_contrast;
> + int current_saturation;
> + int current_hue;
> +
> + /* ───── V4L2 controls ───── */
> + struct v4l2_ctrl_handler control_handler;
> + struct v4l2_ctrl *hotplug_detect_control;
> + struct v4l2_ctrl *ctrl_brightness;
> + struct v4l2_ctrl *ctrl_contrast;
> + struct v4l2_ctrl *ctrl_saturation;
> + struct v4l2_ctrl *ctrl_hue;
> + /* ───── capture queue status ───── */
> + struct hws_pix_state pix;
> + struct v4l2_dv_timings cur_dv_timings; /* last configured DV timings */
> + u32 current_fps; /* Hz, derived from mode or HW rate reg */
> + u32 alloc_sizeimage;
> +
> + /* ───── per-channel capture state ───── */
> + bool cap_active;
> + bool stop_requested;
> + u8 last_buf_half_toggle;
> + bool half_seen;
> + atomic_t sequence_number;
> + u32 queued_count;
> +
> + /* ───── timeout and error handling ───── */
> + u32 timeout_count;
> + u32 error_count;
> +
> + bool window_valid;
> + u32 last_dma_hi;
> + u32 last_dma_page;
> + u32 last_pci_addr;
> + u32 last_half16;
> +
> + /* ───── misc counters ───── */
> + int signal_loss_cnt;
> +};
> +
> +static inline void hws_set_current_dv_timings(struct hws_video *vid,
> + u32 width, u32 height,
> + bool interlaced)
> +{
> + if (!vid)
> + return;
> +
> + vid->cur_dv_timings = (struct v4l2_dv_timings) {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = width,
> + .height = height,
> + .interlaced = interlaced,
> + },
> + };
> +}
> +
> +struct hws_scratch_dma {
> + void *cpu;
> + dma_addr_t dma;
> + size_t size;
> +};
> +
> +struct hws_pcie_dev {
> + /* ───── core objects ───── */
> + struct pci_dev *pdev;
> + struct hws_video video[MAX_VID_CHANNELS];
> +
> + /* ───── BAR & workqueues ───── */
> + void __iomem *bar0_base;
> +
> + /* ───── device identity / capabilities ───── */
> + u16 vendor_id;
> + u16 device_id;
> + u16 device_ver;
> + u16 hw_ver;
> + u32 sub_ver;
> + u32 port_id;
> + // TriState, used in `set_video_format_size`
> + u32 support_yv12;
> + u32 max_hw_video_buf_sz;
> + u8 max_channels;
> + u8 cur_max_video_ch;
> + bool start_run;
> +
> + bool buf_allocated;
> +
> + /* ───── V4L2 framework objects ───── */
> + struct v4l2_device v4l2_device;
> +
> + /* ───── kernel thread ───── */
> + struct task_struct *main_task;
> + struct hws_scratch_dma scratch_vid[MAX_VID_CHANNELS];
> +
> + bool suspended;
> + int irq;
> +
> + /* ───── error flags ───── */
> + int pci_lost;
> +
> +};
> +
> +#endif
> diff --git a/drivers/media/pci/hws/hws_irq.c b/drivers/media/pci/hws/hws_irq.c
> new file mode 100644
> index 000000000000..11f7dfde0eff
> --- /dev/null
> +++ b/drivers/media/pci/hws/hws_irq.c
> @@ -0,0 +1,271 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#include <linux/compiler.h>
> +#include <linux/moduleparam.h>
> +#include <linux/io.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/interrupt.h>
> +#include <linux/minmax.h>
> +#include <linux/string.h>
> +
> +#include <media/videobuf2-dma-contig.h>
> +
> +#include "hws_irq.h"
> +#include "hws_reg.h"
> +#include "hws_video.h"
> +#include "hws.h"
> +
> +#define MAX_INT_LOOPS 100
> +
> +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 = &hws->video[ch];
> + unsigned long flags;
> + struct hwsvideo_buffer *buf;
> +
> + dev_dbg(&hws->pdev->dev,
> + "arm_next(ch=%u): stop=%d cap=%d queued=%d\n",
> + ch, READ_ONCE(v->stop_requested), READ_ONCE(v->cap_active),
> + !list_empty(&v->capture_queue));
> +
> + if (unlikely(READ_ONCE(hws->suspended))) {
I noticed a lot of 'likely' and 'unlikely' calls in this driver. These generally
just make the code harder to read. They only make sense inside tight loops where
every CPU cycle counts.
Just drop them, unless they really make sense.
> + dev_dbg(&hws->pdev->dev, "arm_next(ch=%u): suspended\n", ch);
> + return -EBUSY;
> + }
> +
<snip>
> diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.c b/drivers/media/pci/hws/hws_v4l2_ioctl.c
> new file mode 100644
> index 000000000000..a9a7597f76e1
> --- /dev/null
> +++ b/drivers/media/pci/hws/hws_v4l2_ioctl.c
> @@ -0,0 +1,778 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#include <linux/kernel.h>
> +#include <linux/string.h>
> +#include <linux/pci.h>
> +#include <linux/errno.h>
> +#include <linux/io.h>
> +
> +#include <media/v4l2-ioctl.h>
> +#include <media/v4l2-dev.h>
> +#include <media/v4l2-dv-timings.h>
> +#include <media/videobuf2-core.h>
> +#include <media/videobuf2-v4l2.h>
> +
> +#include "hws.h"
> +#include "hws_reg.h"
> +#include "hws_video.h"
> +#include "hws_v4l2_ioctl.h"
> +
> +struct hws_dv_mode {
> + struct v4l2_dv_timings timings;
> + u32 refresh_hz;
> +};
> +
> +static const struct hws_dv_mode *
> +hws_find_dv_by_wh(u32 w, u32 h, bool interlaced);
> +
> +static const struct hws_dv_mode hws_dv_modes[] = {
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 1920,
> + .height = 1080,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 1280,
> + .height = 720,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 720,
> + .height = 480,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 720,
> + .height = 576,
> + .interlaced = 0,
> + },
> + },
> + 50,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 800,
> + .height = 600,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 640,
> + .height = 480,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 1024,
> + .height = 768,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 1280,
> + .height = 768,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 1280,
> + .height = 800,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 1280,
> + .height = 1024,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 1360,
> + .height = 768,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 1440,
> + .height = 900,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 1680,
> + .height = 1050,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> + /* Portrait */
> + {
> + {
> + .type = V4L2_DV_BT_656_1120,
> + .bt = {
> + .width = 1080,
> + .height = 1920,
> + .interlaced = 0,
> + },
> + },
> + 60,
> + },
> +};
> +
> +static const size_t hws_dv_modes_cnt = ARRAY_SIZE(hws_dv_modes);
> +
> +/* YUYV: 16 bpp; align to 64 as you did elsewhere */
> +static inline u32 hws_calc_bpl_yuyv(u32 w) { return ALIGN(w * 2, 64); }
> +static inline u32 hws_calc_size_yuyv(u32 w, u32 h) { return hws_calc_bpl_yuyv(w) * h; }
> +static inline u32 hws_calc_half_size(u32 sizeimage)
> +{
> + return sizeimage / 2;
> +}
> +
> +static inline void hws_hw_write_bchs(struct hws_pcie_dev *hws, unsigned int ch,
> + u8 br, u8 co, u8 hu, u8 sa)
> +{
> + u32 packed = (sa << 24) | (hu << 16) | (co << 8) | br;
> +
> + if (!hws || !hws->bar0_base || ch >= hws->max_channels)
> + return;
> + writel_relaxed(packed, hws->bar0_base + HWS_REG_BCHS(ch));
> + (void)readl(hws->bar0_base + HWS_REG_BCHS(ch)); /* post write */
> +}
> +
> +/* Helper: find a supported DV mode by W/H + interlace flag */
> +static const struct hws_dv_mode *
> +hws_match_supported_dv(const struct v4l2_dv_timings *req)
> +{
> + const struct v4l2_bt_timings *bt;
> +
> + if (!req || req->type != V4L2_DV_BT_656_1120)
> + return NULL;
> +
> + bt = &req->bt;
> + return hws_find_dv_by_wh(bt->width, bt->height, !!bt->interlaced);
> +}
> +
> +/* Helper: find a supported DV mode by W/H + interlace flag */
> +static const struct hws_dv_mode *
> +hws_find_dv_by_wh(u32 w, u32 h, bool interlaced)
> +{
> + size_t i;
> +
> + for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
> + const struct hws_dv_mode *t = &hws_dv_modes[i];
> + const struct v4l2_bt_timings *bt = &t->timings.bt;
> +
> + if (t->timings.type != V4L2_DV_BT_656_1120)
> + continue;
> +
> + if (bt->width == w && bt->height == h &&
> + !!bt->interlaced == interlaced)
> + return t;
> + }
> + return NULL;
> +}
> +
> +static bool hws_get_live_dv_geometry(struct hws_video *vid,
> + u32 *w, u32 *h, bool *interlaced)
> +{
> + struct hws_pcie_dev *pdx;
> + u32 reg;
> +
> + if (!vid)
> + return false;
> +
> + pdx = vid->parent;
> + if (!pdx || !pdx->bar0_base)
> + return false;
> +
> + reg = readl(pdx->bar0_base + HWS_REG_IN_RES(vid->channel_index));
> + if (!reg || reg == 0xFFFFFFFF)
> + return false;
> +
> + if (w)
> + *w = reg & 0xFFFF;
> + if (h)
> + *h = (reg >> 16) & 0xFFFF;
> + if (interlaced) {
> + reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
> + *interlaced = !!(reg & BIT(8 + vid->channel_index));
> + }
> + return true;
> +}
> +
> +static u32 hws_pick_fps_from_mode(u32 w, u32 h, bool interlaced)
> +{
> + const struct hws_dv_mode *m = hws_find_dv_by_wh(w, h, interlaced);
> +
> + if (m && m->refresh_hz)
> + return m->refresh_hz;
> + /* Fallback to a sane default */
> + return 60;
> +}
> +
> +/* Query the *current detected* DV timings on the input.
> + * If you have a real hardware detector, call it here; otherwise we
> + * derive from the cached pix state and map to the closest supported DV mode.
> + */
> +int hws_vidioc_query_dv_timings(struct file *file, void *fh,
> + struct v4l2_dv_timings *timings)
> +{
> + struct hws_video *vid = video_drvdata(file);
> + const struct hws_dv_mode *m;
> + u32 w, h;
> + bool interlace;
> +
> + if (!timings)
> + return -EINVAL;
> +
> + w = vid->pix.width;
> + h = vid->pix.height;
> + interlace = vid->pix.interlaced;
> + (void)hws_get_live_dv_geometry(vid, &w, &h, &interlace);
> + /* Map current (live if available, otherwise cached) WxH/interlace
> + * to one of our supported modes.
> + */
> + m = hws_find_dv_by_wh(w, h, !!interlace);
> + if (!m)
> + return -ENOLINK;
> +
> + *timings = m->timings;
> + vid->cur_dv_timings = m->timings;
> + vid->current_fps = m->refresh_hz;
> + return 0;
> +}
> +
> +/* Enumerate the Nth supported DV timings from our static table. */
> +int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
> + struct v4l2_enum_dv_timings *edv)
> +{
> + if (!edv)
> + return -EINVAL;
> +
> + if (edv->pad)
> + return -EINVAL;
> +
> + if (edv->index >= hws_dv_modes_cnt)
> + return -EINVAL;
> +
> + edv->timings = hws_dv_modes[edv->index].timings;
> + return 0;
> +}
> +
> +/* Get the *currently configured* DV timings. */
> +int hws_vidioc_g_dv_timings(struct file *file, void *fh,
> + struct v4l2_dv_timings *timings)
> +{
> + struct hws_video *vid = video_drvdata(file);
> +
> + if (!timings)
> + return -EINVAL;
> +
> + *timings = vid->cur_dv_timings;
> + return 0;
> +}
> +
> +static inline void hws_set_colorimetry_state(struct hws_pix_state *p)
> +{
> + bool sd = p->height <= 576;
> +
> + p->colorspace = sd ? V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
> + p->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> + p->quantization = V4L2_QUANTIZATION_FULL_RANGE;
> + p->xfer_func = V4L2_XFER_FUNC_DEFAULT;
> +}
> +
> +/* Set DV timings: must match one of our supported modes.
> + * If buffers are queued and this implies a size change, we reject with -EBUSY.
> + * Otherwise we update pix state and (optionally) reprogram the HW.
> + */
> +int hws_vidioc_s_dv_timings(struct file *file, void *fh,
> + struct v4l2_dv_timings *timings)
> +{
> + struct hws_video *vid = video_drvdata(file);
> + const struct hws_dv_mode *m;
> + const struct v4l2_bt_timings *bt;
> + u32 new_w, new_h;
> + bool interlaced;
> + int ret = 0;
> + unsigned long was_busy;
> +
> + if (!timings)
> + return -EINVAL;
> +
> + m = hws_match_supported_dv(timings);
> + if (!m)
> + return -EINVAL;
> +
> + bt = &m->timings.bt;
> + if (bt->interlaced)
> + return -EINVAL; /* only progressive modes are advertised */
> + new_w = bt->width;
> + new_h = bt->height;
> + interlaced = false;
> +
> + lockdep_assert_held(&vid->state_lock);
> +
> + /* If vb2 has active buffers and size would change, reject. */
> + was_busy = vb2_is_busy(&vid->buffer_queue);
> + if (was_busy &&
> + (new_w != vid->pix.width || new_h != vid->pix.height ||
> + interlaced != vid->pix.interlaced)) {
Just checking: you can change the timings on the fly as long as the width,
height and interlaced mode are the same? So going from e.g. 1080p60 to 1080p30
would work?
Often this is not actually possible without stopping streaming and restarting
it afterwards.
> + ret = -EBUSY;
> + return ret;
> + }
> +
> + /* Update software pixel state (and recalc sizes) */
> + vid->pix.width = new_w;
> + vid->pix.height = new_h;
> + vid->pix.field = interlaced ? V4L2_FIELD_INTERLACED
> + : V4L2_FIELD_NONE;
> + vid->pix.interlaced = interlaced;
> + vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
> +
> + hws_set_colorimetry_state(&vid->pix);
> +
> + /* Recompute stride/sizeimage/half_size using your helper */
> + vid->pix.bytesperline = hws_calc_bpl_yuyv(new_w);
> + vid->pix.sizeimage = hws_calc_size_yuyv(new_w, new_h);
> + vid->pix.half_size = hws_calc_half_size(vid->pix.sizeimage);
> + vid->cur_dv_timings = m->timings;
> + vid->current_fps = m->refresh_hz;
> + if (!was_busy)
> + vid->alloc_sizeimage = vid->pix.sizeimage;
> + return ret;
> +}
> +
> +/* Report DV timings capability: advertise BT.656/1120 with
> + * the min/max WxH derived from our table and basic progressive support.
> + */
> +int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
> + struct v4l2_dv_timings_cap *cap)
> +{
> + u32 min_w = ~0U, min_h = ~0U;
> + u32 max_w = 0, max_h = 0;
> + size_t i, n = 0;
> +
> + if (!cap)
> + return -EINVAL;
> +
> + memset(cap, 0, sizeof(*cap));
> + cap->type = V4L2_DV_BT_656_1120;
> +
> + for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
> + const struct v4l2_bt_timings *bt = &hws_dv_modes[i].timings.bt;
> +
> + if (hws_dv_modes[i].timings.type != V4L2_DV_BT_656_1120)
> + continue;
> + n++;
> +
> + if (bt->width < min_w)
> + min_w = bt->width;
> + if (bt->height < min_h)
> + min_h = bt->height;
> + if (bt->width > max_w)
> + max_w = bt->width;
> + if (bt->height > max_h)
> + max_h = bt->height;
> + }
> +
> + /* If the table was empty, fail gracefully. */
> + if (!n || min_w == U32_MAX)
> + return -ENODATA;
> +
> + cap->bt.min_width = min_w;
> + cap->bt.max_width = max_w;
> + cap->bt.min_height = min_h;
> + cap->bt.max_height = max_h;
> +
> + /* We support both CEA-861- and VESA-style modes in the list. */
> + cap->bt.standards =
> + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT;
> +
> + /* Progressive only, unless your table includes interlaced entries. */
> + cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE;
> +
> + /* Leave pixelclock/porch limits unconstrained (0) for now. */
> + return 0;
> +}
> +
> +static int hws_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct hws_video *vid =
> + container_of(ctrl->handler, struct hws_video, control_handler);
> + struct hws_pcie_dev *pdx = vid->parent;
> + bool program = false;
> +
> + switch (ctrl->id) {
> + case V4L2_CID_BRIGHTNESS:
> + vid->current_brightness = ctrl->val;
> + program = true;
> + break;
> + case V4L2_CID_CONTRAST:
> + vid->current_contrast = ctrl->val;
> + program = true;
> + break;
> + case V4L2_CID_SATURATION:
> + vid->current_saturation = ctrl->val;
> + program = true;
> + break;
> + case V4L2_CID_HUE:
> + vid->current_hue = ctrl->val;
> + program = true;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + if (program) {
> + hws_hw_write_bchs(pdx, vid->channel_index,
> + (u8)vid->current_brightness,
> + (u8)vid->current_contrast,
> + (u8)vid->current_hue,
> + (u8)vid->current_saturation);
> + }
> + return 0;
> +}
> +
> +const struct v4l2_ctrl_ops hws_ctrl_ops = {
> + .s_ctrl = hws_s_ctrl,
> +};
> +
> +int hws_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
> +{
> + struct hws_video *vid = video_drvdata(file);
> + struct hws_pcie_dev *pdev = vid->parent;
> + int vi_index = vid->channel_index + 1; /* keep it simple */
> +
> + strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
> + snprintf(cap->card, sizeof(cap->card),
> + "AVMatrix HWS Capture %d", vi_index);
> + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", dev_name(&pdev->pdev->dev));
No need to set bus_info, it's done for you.
> +
> + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
> + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
No need to set these two field, the v4l2 core does that for you.
> + return 0;
> +}
> +
> +int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh, struct v4l2_fmtdesc *f)
> +{
> + if (f->index != 0)
> + return -EINVAL; /* only one format */
> +
> + f->pixelformat = V4L2_PIX_FMT_YUYV;
> + return 0;
> +}
> +
> +int hws_vidioc_enum_frameintervals(struct file *file, void *fh,
> + struct v4l2_frmivalenum *fival)
This generally makes no sense for HDMI receivers. I'd drop it.
> +{
> + const struct hws_dv_mode *mode;
> +
> + if (fival->index)
> + return -EINVAL;
> +
> + if (fival->pixel_format != V4L2_PIX_FMT_YUYV)
> + return -EINVAL;
> +
> + mode = hws_find_dv_by_wh(fival->width, fival->height, false);
> + if (!mode)
> + return -EINVAL;
> +
> + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
> + fival->discrete.numerator = 1;
> + fival->discrete.denominator = mode->refresh_hz ?: 60;
> +
> + return 0;
> +}
> +
> +int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
> +{
> + struct hws_video *vid = video_drvdata(file);
> +
> + fmt->fmt.pix.width = vid->pix.width;
> + fmt->fmt.pix.height = vid->pix.height;
> + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
> + fmt->fmt.pix.field = vid->pix.field;
> + fmt->fmt.pix.bytesperline = vid->pix.bytesperline;
> + fmt->fmt.pix.sizeimage = vid->pix.sizeimage;
> + fmt->fmt.pix.colorspace = vid->pix.colorspace;
> + fmt->fmt.pix.ycbcr_enc = vid->pix.ycbcr_enc;
> + fmt->fmt.pix.quantization = vid->pix.quantization;
> + fmt->fmt.pix.xfer_func = vid->pix.xfer_func;
> + return 0;
> +}
> +
> +static inline void hws_set_colorimetry_fmt(struct v4l2_pix_format *p)
> +{
> + bool sd = p->height <= 576;
> +
> + p->colorspace = sd ? V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
> + p->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> + p->quantization = V4L2_QUANTIZATION_FULL_RANGE;
> + p->xfer_func = V4L2_XFER_FUNC_DEFAULT;
> +}
> +
> +int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
> +{
> + struct hws_video *vid = file ? video_drvdata(file) : NULL;
> + struct hws_pcie_dev *pdev = vid ? vid->parent : NULL;
> + struct v4l2_pix_format *pix = &f->fmt.pix;
> + u32 req_w = pix->width, req_h = pix->height;
> + u32 w, h, min_bpl, bpl;
> + size_t size; /* wider than u32 for overflow check */
> + size_t max_frame = pdev ? pdev->max_hw_video_buf_sz : MAX_MM_VIDEO_SIZE;
> +
> + /* Only YUYV */
> + pix->pixelformat = V4L2_PIX_FMT_YUYV;
> +
> + /* Defaults then clamp */
> + w = (req_w ? req_w : 640);
> + h = (req_h ? req_h : 480);
> + if (w > MAX_VIDEO_HW_W)
> + w = MAX_VIDEO_HW_W;
> + if (h > MAX_VIDEO_HW_H)
> + h = MAX_VIDEO_HW_H;
> + if (!w)
> + w = 640; /* hard fallback in case macros are odd */
> + if (!h)
> + h = 480;
> +
> + /* Field policy */
> + pix->field = V4L2_FIELD_NONE;
> +
> + /* Stride policy for packed 16bpp, 64B align */
> + min_bpl = ALIGN(w * 2, 64);
> +
> + /* Bound requested bpl to something sane, then align */
> + bpl = pix->bytesperline;
> + if (bpl < min_bpl) {
> + bpl = min_bpl;
> + } else {
> + /* Cap at 16x width to avoid silly values that overflow sizeimage */
> + u32 max_bpl = ALIGN(w * 2 * 16, 64);
> +
> + if (bpl > max_bpl)
> + bpl = max_bpl;
> + bpl = ALIGN(bpl, 64);
> + }
> + if (h && max_frame) {
> + size_t max_bpl_hw = max_frame / h;
> +
> + if (max_bpl_hw < min_bpl)
> + return -ERANGE;
> + max_bpl_hw = rounddown(max_bpl_hw, 64);
> + 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 = (u32)max_bpl_hw;
> + }
> + }
> + size = (size_t)bpl * (size_t)h;
> + if (size > max_frame)
> + return -ERANGE;
> +
> + pix->width = w;
> + pix->height = h;
> + pix->bytesperline = bpl;
> + pix->sizeimage = (u32)size; /* logical size, not page-aligned */
> +
> + hws_set_colorimetry_fmt(pix);
> + if (pdev)
> + dev_dbg(&pdev->pdev->dev,
> + "try_fmt: w=%u h=%u bpl=%u size=%u field=%u\n",
> + pix->width, pix->height, pix->bytesperline,
> + pix->sizeimage, pix->field);
> + return 0;
> +}
> +
> +int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
> +{
> + struct hws_video *vid = video_drvdata(file);
> + int ret;
> +
> + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> + return -EINVAL;
> +
> + /* Normalize the request */
> + ret = hws_vidioc_try_fmt_vid_cap(file, priv, f);
> + if (ret)
> + return ret;
> +
> + /* Don’t allow size changes while buffers are queued */
> + if (vb2_is_busy(&vid->buffer_queue)) {
> + if (f->fmt.pix.width != vid->pix.width ||
> + f->fmt.pix.height != vid->pix.height ||
> + f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV) {
Drop the pixelformat check: hws_vidioc_try_fmt_vid_cap already hardcodes it
to V4L2_PIX_FMT_YUYV.
But you are missing a check for bytesperline: changing that will change the buffer size,
which is a no-go for S_FMT when vb2_is_busy.
> + return -EBUSY;
> + }
> + }
> +
> + /* Apply to driver state */
> + vid->pix.width = f->fmt.pix.width;
> + vid->pix.height = f->fmt.pix.height;
> + vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
> + vid->pix.field = f->fmt.pix.field;
> + vid->pix.colorspace = f->fmt.pix.colorspace;
> + vid->pix.ycbcr_enc = f->fmt.pix.ycbcr_enc;
> + vid->pix.quantization = f->fmt.pix.quantization;
> + vid->pix.xfer_func = f->fmt.pix.xfer_func;
> +
> + /* Update sizes (use helper if you prefer strict alignment math) */
> + vid->pix.bytesperline = f->fmt.pix.bytesperline; /* aligned */
> + vid->pix.sizeimage = f->fmt.pix.sizeimage; /* logical */
> + vid->pix.half_size = hws_calc_half_size(vid->pix.sizeimage);
> + vid->pix.interlaced = false;
> + hws_set_current_dv_timings(vid, vid->pix.width, vid->pix.height,
> + vid->pix.interlaced);
> + vid->current_fps = hws_pick_fps_from_mode(vid->pix.width,
> + vid->pix.height,
> + vid->pix.interlaced);
> + /* Or:
> + * hws_calc_sizeimage(vid, vid->pix.width, vid->pix.height, false);
> + */
> +
> + /* Refresh vb2 watermark when idle */
> + if (!vb2_is_busy(&vid->buffer_queue))
> + vid->alloc_sizeimage = PAGE_ALIGN(vid->pix.sizeimage);
> + dev_dbg(&vid->parent->pdev->dev,
> + "s_fmt: w=%u h=%u bpl=%u size=%u alloc=%u\n",
> + vid->pix.width, vid->pix.height, vid->pix.bytesperline,
> + vid->pix.sizeimage, vid->alloc_sizeimage);
> +
> + return 0;
> +}
> +
> +int hws_vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *param)
> +{
> + struct hws_video *vid = video_drvdata(file);
> + u32 fps;
> +
> + if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> + return -EINVAL;
> +
> + fps = vid->current_fps ? vid->current_fps : 60;
> +
> + /* Report cached frame rate; expose timeperframe capability */
> + param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
> + param->parm.capture.capturemode = 0;
> + param->parm.capture.timeperframe.numerator = 1;
> + param->parm.capture.timeperframe.denominator = fps;
> + param->parm.capture.extendedmode = 0;
> + param->parm.capture.readbuffers = 0;
> +
> + return 0;
> +}
> +
> +int hws_vidioc_enum_input(struct file *file, void *priv,
> + struct v4l2_input *input)
> +{
> + if (input->index)
> + return -EINVAL;
> + input->type = V4L2_INPUT_TYPE_CAMERA;
> + strscpy(input->name, KBUILD_MODNAME, sizeof(input->name));
> + input->capabilities = V4L2_IN_CAP_DV_TIMINGS;
> + input->status = 0;
> +
> + return 0;
> +}
> +
> +int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *index)
> +{
> + *index = 0;
> + return 0;
> +}
> +
> +int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i)
> +{
> + return i ? -EINVAL : 0;
> +}
> +
> +int hws_vidioc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *param)
> +{
> + struct hws_video *vid = video_drvdata(file);
> + struct v4l2_captureparm *cap;
> + u32 fps;
> +
> + if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> + return -EINVAL;
> +
> + cap = ¶m->parm.capture;
> +
> + fps = vid->current_fps ? vid->current_fps : 60;
> + cap->timeperframe.denominator = fps;
> + cap->timeperframe.numerator = 1;
> + cap->capability = V4L2_CAP_TIMEPERFRAME;
> + cap->capturemode = 0;
> + cap->extendedmode = 0;
> + /* readbuffers left unchanged or zero; vb2 handles queue depth */
> +
> + return 0;
> +}
> diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.h b/drivers/media/pci/hws/hws_v4l2_ioctl.h
> new file mode 100644
> index 000000000000..f20e6aadff67
> --- /dev/null
> +++ b/drivers/media/pci/hws/hws_v4l2_ioctl.h
> @@ -0,0 +1,43 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef HWS_V4L2_IOCTL_H
> +#define HWS_V4L2_IOCTL_H
> +
> +#include <linux/fs.h>
> +
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-ioctl.h>
> +
> +extern const struct v4l2_ctrl_ops hws_ctrl_ops;
> +
> +int hws_vidioc_querycap(struct file *file, void *priv,
> + struct v4l2_capability *cap);
> +int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh,
> + struct v4l2_fmtdesc *f);
> +int hws_vidioc_enum_frameintervals(struct file *file, void *fh,
> + struct v4l2_frmivalenum *fival);
> +int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh,
> + struct v4l2_format *fmt);
> +int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh,
> + struct v4l2_format *f);
> +int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
> + struct v4l2_format *f);
> +int hws_vidioc_g_parm(struct file *file, void *fh,
> + struct v4l2_streamparm *setfps);
> +int hws_vidioc_s_parm(struct file *file, void *fh,
> + struct v4l2_streamparm *a);
> +int hws_vidioc_enum_input(struct file *file, void *priv,
> + struct v4l2_input *i);
> +int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *i);
> +int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i);
> +int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
> + struct v4l2_dv_timings_cap *cap);
> +int hws_vidioc_s_dv_timings(struct file *file, void *fh,
> + struct v4l2_dv_timings *timings);
> +int hws_vidioc_g_dv_timings(struct file *file, void *fh,
> + struct v4l2_dv_timings *timings);
> +int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
> + struct v4l2_enum_dv_timings *edv);
> +int hws_vidioc_query_dv_timings(struct file *file, void *fh,
> + struct v4l2_dv_timings *timings);
> +
> +#endif
> diff --git a/drivers/media/pci/hws/hws_video.c b/drivers/media/pci/hws/hws_video.c
> new file mode 100644
> index 000000000000..9fcf40a12ec3
> --- /dev/null
> +++ b/drivers/media/pci/hws/hws_video.c
> @@ -0,0 +1,1546 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#include <linux/pci.h>
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <linux/compiler.h>
> +#include <linux/overflow.h>
> +#include <linux/delay.h>
> +#include <linux/bits.h>
> +#include <linux/jiffies.h>
> +#include <linux/ktime.h>
> +#include <linux/interrupt.h>
> +#include <linux/moduleparam.h>
> +#include <linux/sysfs.h>
> +
> +#include <media/v4l2-ioctl.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-dev.h>
> +#include <media/v4l2-event.h>
> +#include <media/videobuf2-v4l2.h>
> +#include <media/v4l2-device.h>
> +#include <media/videobuf2-dma-contig.h>
> +
> +#include "hws.h"
> +#include "hws_reg.h"
> +#include "hws_video.h"
> +#include "hws_irq.h"
> +#include "hws_v4l2_ioctl.h"
> +
> +#define HWS_REMAP_SLOT_OFF(ch) (0x208 + (ch) * 8) /* one 64-bit slot per ch */
> +#define HWS_BUF_BASE_OFF(ch) (CVBS_IN_BUF_BASE + (ch) * PCIE_BARADDROFSIZE)
> +#define HWS_HALF_SZ_OFF(ch) (CVBS_IN_BUF_BASE2 + (ch) * PCIE_BARADDROFSIZE)
> +
> +static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch);
> +static bool hws_update_active_interlace(struct hws_pcie_dev *pdx,
> + unsigned int ch);
> +static void handle_hwv2_path(struct hws_pcie_dev *hws, unsigned int ch);
> +static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch);
> +static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
> + bool interlaced);
> +
> +/* DMA helper functions */
> +static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma);
> +static struct hwsvideo_buffer *
> +hws_take_queued_buffer_locked(struct hws_video *vid);
> +
> +#if IS_ENABLED(CONFIG_SYSFS)
> +static ssize_t resolution_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct video_device *vdev = to_video_device(dev);
> + struct hws_video *vid = video_get_drvdata(vdev);
> + struct hws_pcie_dev *hws;
> + u32 res_reg;
> + u16 w, h;
> + bool interlaced;
> +
> + if (!vid)
> + return -ENODEV;
> +
> + hws = vid->parent;
> + if (!hws || !hws->bar0_base)
> + return sysfs_emit(buf, "unknown\n");
> +
> + res_reg = readl(hws->bar0_base + HWS_REG_IN_RES(vid->channel_index));
> + if (!res_reg || res_reg == 0xFFFFFFFF)
> + return sysfs_emit(buf, "unknown\n");
> +
> + w = res_reg & 0xFFFF;
> + h = (res_reg >> 16) & 0xFFFF;
> +
> + interlaced =
> + !!(readl(hws->bar0_base + HWS_REG_ACTIVE_STATUS) &
> + BIT(8 + vid->channel_index));
> +
> + return sysfs_emit(buf, "%ux%u%s\n", w, h, interlaced ? "i" : "p");
> +}
> +static DEVICE_ATTR_RO(resolution);
> +
> +static inline int hws_resolution_create(struct video_device *vdev)
> +{
> + return device_create_file(&vdev->dev, &dev_attr_resolution);
> +}
> +
> +static inline void hws_resolution_remove(struct video_device *vdev)
> +{
> + device_remove_file(&vdev->dev, &dev_attr_resolution);
> +}
> +#else
> +static inline int hws_resolution_create(struct video_device *vdev)
> +{
> + return 0;
> +}
> +
> +static inline void hws_resolution_remove(struct video_device *vdev)
> +{
> +}
> +#endif
> +
> +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=0x%llx tag=%s\n", ch,
> + (u64)dma, tag ? tag : "");
> +}
> +
> +static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma)
> +{
> + const u32 addr_mask = PCI_E_BAR_ADD_MASK; // 0xE0000000
> + const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK; // 0x1FFFFFFF
> + struct hws_pcie_dev *hws = vid->parent;
> + unsigned int ch = vid->channel_index;
> + u32 table_off = HWS_REMAP_SLOT_OFF(ch);
> + u32 lo = lower_32_bits(dma);
> + u32 hi = upper_32_bits(dma);
> + u32 pci_addr = lo & addr_low_mask; // low 29 bits inside 512MB window
> + u32 page_lo = lo & addr_mask; // bits 31..29 only (page bits)
> +
> + bool wrote = false;
> +
> + /* Remap entry only when DMA crosses into a new 512 MB page */
> + if (!vid->window_valid || vid->last_dma_hi != hi ||
> + vid->last_dma_page != page_lo) {
> + writel(hi, hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
> + writel(page_lo,
> + hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
> + PCIE_BARADDROFSIZE);
> + vid->last_dma_hi = hi;
> + vid->last_dma_page = page_lo;
> + wrote = true;
> + }
> +
> + /* Base pointer only needs low 29 bits */
> + if (!vid->window_valid || vid->last_pci_addr != pci_addr) {
> + writel((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
> + hws->bar0_base + HWS_BUF_BASE_OFF(ch));
> + vid->last_pci_addr = pci_addr;
> + wrote = true;
> + }
> +
> + /* Half-size only changes when resolution changes */
> + if (!vid->window_valid || vid->last_half16 != vid->pix.half_size / 16) {
> + writel(vid->pix.half_size / 16,
> + hws->bar0_base + HWS_HALF_SZ_OFF(ch));
> + vid->last_half16 = vid->pix.half_size / 16;
> + wrote = true;
> + }
> +
> + vid->window_valid = true;
> +
> + if (unlikely(dma_window_verify) && wrote) {
> + u32 r_hi =
> + readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
> + u32 r_lo =
> + readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
> + PCIE_BARADDROFSIZE);
> + u32 r_base = readl(hws->bar0_base + HWS_BUF_BASE_OFF(ch));
> + u32 r_half = readl(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
> +
> + dev_dbg(&hws->pdev->dev,
> + "ch%u remap verify: hi=0x%08x page_lo=0x%08x exp_page=0x%08x base=0x%08x exp_base=0x%08x half16B=0x%08x exp_half=0x%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) {
> + /* Flush posted writes before arming DMA */
> + readl_relaxed(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
> + }
> +}
> +
> +static struct hwsvideo_buffer *
> +hws_take_queued_buffer_locked(struct hws_video *vid)
> +{
> + struct hwsvideo_buffer *buf;
> +
> + if (!vid || list_empty(&vid->capture_queue))
> + return NULL;
> +
> + buf = list_first_entry(&vid->capture_queue,
> + struct hwsvideo_buffer, list);
> + list_del_init(&buf->list);
> + if (vid->queued_count)
> + vid->queued_count--;
> + return buf;
> +}
> +
> +void hws_prime_next_locked(struct hws_video *vid)
> +{
> + struct hws_pcie_dev *hws;
> + struct hwsvideo_buffer *next;
> + dma_addr_t dma;
> +
> + if (!vid)
> + return;
> +
> + hws = vid->parent;
> + if (!hws || !hws->bar0_base)
> + return;
> +
> + if (!READ_ONCE(vid->cap_active) || !vid->active || vid->next_prepared)
> + return;
> +
> + next = hws_take_queued_buffer_locked(vid);
> + if (!next)
> + return;
> +
> + vid->next_prepared = next;
> + dma = vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
> + 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=0x%llx\n",
> + vid->channel_index, next, (u64)dma);
> +}
> +
> +static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag)
> +{
> + struct hws_pcie_dev *hws;
> + unsigned long flags;
> + struct hwsvideo_buffer *buf = NULL, *next = NULL;
> + bool have_next = false;
> + bool doorbell = false;
> +
> + if (!v)
> + return false;
> + hws = v->parent;
> + if (!hws || READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active))
> + return false;
> + spin_lock_irqsave(&v->irq_lock, flags);
> + if (v->active) {
> + buf = v->active;
> + v->active = NULL;
> + buf->slot = 0;
> + } else if (!list_empty(&v->capture_queue)) {
> + buf = list_first_entry(&v->capture_queue,
> + struct hwsvideo_buffer, list);
> + list_del_init(&buf->list);
> + if (v->queued_count)
> + v->queued_count--;
> + buf->slot = 0;
> + }
> + if (v->next_prepared) {
> + next = v->next_prepared;
> + v->next_prepared = NULL;
> + next->slot = 0;
> + v->active = next;
> + have_next = true;
> + } else if (!list_empty(&v->capture_queue)) {
> + next = list_first_entry(&v->capture_queue,
> + struct hwsvideo_buffer, list);
> + list_del_init(&next->list);
> + if (v->queued_count)
> + v->queued_count--;
> + next->slot = 0;
> + v->active = next;
> + have_next = true;
> + } else {
> + v->active = NULL;
> + }
> + spin_unlock_irqrestore(&v->irq_lock, flags);
> + if (!buf)
> + return false;
> + /* Complete buffer with a neutral frame so dequeuers keep running. */
> + {
> + struct vb2_v4l2_buffer *vb2v = &buf->vb;
> + void *dst = vb2_plane_vaddr(&vb2v->vb2_buf, 0);
> +
> + if (dst)
> + memset(dst, 0x10, v->pix.sizeimage);
> + vb2_set_plane_payload(&vb2v->vb2_buf, 0, v->pix.sizeimage);
> + vb2v->sequence = (u32)atomic_inc_return(&v->sequence_number);
> + vb2v->vb2_buf.timestamp = ktime_get_ns();
> + vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
> + }
> + if (have_next && next) {
> + dma_addr_t dma =
> + vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
> + hws_program_dma_for_addr(hws, v->channel_index, dma);
> + hws_set_dma_doorbell(hws, v->channel_index, dma,
> + tag ? tag : "nosignal_zero");
> + doorbell = true;
> + }
> + if (doorbell) {
> + wmb(); /* ensure descriptors visible before enabling capture */
> + hws_enable_video_capture(hws, v->channel_index, true);
> + }
> + return true;
> +}
> +
> +static int hws_ctrls_init(struct hws_video *vid)
> +{
> + struct v4l2_ctrl_handler *hdl = &vid->control_handler;
> +
> + /* Create BCHS controls plus signal-detect status. */
> + v4l2_ctrl_handler_init(hdl, 5);
> +
> + vid->ctrl_brightness = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
> + V4L2_CID_BRIGHTNESS,
> + MIN_VAMP_BRIGHTNESS_UNITS,
> + MAX_VAMP_BRIGHTNESS_UNITS, 1,
> + HWS_BRIGHTNESS_DEFAULT);
> +
> + vid->ctrl_contrast =
> + v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_CONTRAST,
> + MIN_VAMP_CONTRAST_UNITS, MAX_VAMP_CONTRAST_UNITS,
> + 1, HWS_CONTRAST_DEFAULT);
> +
> + vid->ctrl_saturation = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
> + V4L2_CID_SATURATION,
> + MIN_VAMP_SATURATION_UNITS,
> + MAX_VAMP_SATURATION_UNITS, 1,
> + HWS_SATURATION_DEFAULT);
> +
> + vid->ctrl_hue = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_HUE,
> + MIN_VAMP_HUE_UNITS,
> + MAX_VAMP_HUE_UNITS, 1,
> + HWS_HUE_DEFAULT);
> + vid->hotplug_detect_control = v4l2_ctrl_new_std(hdl, NULL,
> + V4L2_CID_DV_RX_POWER_PRESENT,
> + 0, 1, 1, 0);
> + if (vid->hotplug_detect_control)
> + vid->hotplug_detect_control->flags |=
> + V4L2_CTRL_FLAG_READ_ONLY;
> +
> + if (hdl->error) {
> + int err = hdl->error;
> +
> + v4l2_ctrl_handler_free(hdl);
> + return err;
> + }
> + return 0;
> +}
> +
> +static void hws_video_move_buf_to_done_locked(struct hwsvideo_buffer **buf,
> + struct list_head *done)
> +{
> + if (!*buf)
> + return;
> +
> + if (list_empty(&(*buf)->list))
> + list_add_tail(&(*buf)->list, done);
> + else
> + list_move_tail(&(*buf)->list, done);
> +
> + *buf = NULL;
> +}
> +
> +static void hws_video_collect_done_locked(struct hws_video *vid,
> + struct list_head *done)
> +{
> + struct hwsvideo_buffer *buf;
> +
> + hws_video_move_buf_to_done_locked(&vid->active, done);
> + hws_video_move_buf_to_done_locked(&vid->next_prepared, done);
> +
> + while (!list_empty(&vid->capture_queue)) {
> + buf = list_first_entry(&vid->capture_queue,
> + struct hwsvideo_buffer, list);
> + list_move_tail(&buf->list, done);
> + }
> +
> + vid->queued_count = 0;
> +}
> +
> +int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch)
> +{
> + struct hws_video *vid;
> +
> + /* basic sanity */
> + if (!pdev || ch < 0 || ch >= pdev->max_channels)
> + return -EINVAL;
> +
> + vid = &pdev->video[ch];
> +
> + /* hard reset the per-channel struct (safe here since we init everything next) */
> + memset(vid, 0, sizeof(*vid));
> +
> + /* identity */
> + vid->parent = pdev;
> + vid->channel_index = ch;
> +
> + /* locks & lists */
> + mutex_init(&vid->state_lock);
> + spin_lock_init(&vid->irq_lock);
> + INIT_LIST_HEAD(&vid->capture_queue);
> + atomic_set(&vid->sequence_number, 0);
> + vid->active = NULL;
> +
> + /* DMA watchdog removed; retain counters for diagnostics */
> + vid->timeout_count = 0;
> + vid->error_count = 0;
> +
> + vid->queued_count = 0;
> + vid->window_valid = false;
> +
> + /* default format (adjust to your HW) */
> + vid->pix.width = 1920;
> + vid->pix.height = 1080;
> + vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
> + vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
> + vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
> + vid->pix.field = V4L2_FIELD_NONE;
> + vid->pix.colorspace = V4L2_COLORSPACE_REC709;
> + vid->pix.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> + vid->pix.quantization = V4L2_QUANTIZATION_FULL_RANGE;
> + vid->pix.xfer_func = V4L2_XFER_FUNC_DEFAULT;
> + vid->pix.interlaced = false;
> + vid->pix.half_size = vid->pix.sizeimage / 2;
> + vid->alloc_sizeimage = vid->pix.sizeimage;
> + hws_set_current_dv_timings(vid, vid->pix.width,
> + vid->pix.height, vid->pix.interlaced);
> + vid->current_fps = 60;
> +
> + /* color controls default (mid-scale) */
> + vid->current_brightness = 0x80;
> + vid->current_contrast = 0x80;
> + vid->current_saturation = 0x80;
> + vid->current_hue = 0x80;
> +
> + /* capture state */
> + vid->cap_active = false;
> + vid->stop_requested = false;
> + vid->last_buf_half_toggle = 0;
> + vid->half_seen = false;
> + vid->signal_loss_cnt = 0;
> +
> + /* Create BCHS + DV power-present as modern controls */
> + {
> + int err = hws_ctrls_init(vid);
> +
> + if (err) {
> + dev_err(&pdev->pdev->dev,
> + "v4l2 ctrl init failed on ch%d: %d\n", ch, err);
> + return err;
> + }
> + }
> +
> + return 0;
> +}
> +
> +void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch)
> +{
> + struct hws_video *vid;
> + unsigned long flags;
> + struct hwsvideo_buffer *buf, *tmp;
> + LIST_HEAD(done);
> +
> + if (!pdev || ch < 0 || ch >= pdev->max_channels)
> + return;
> +
> + vid = &pdev->video[ch];
> +
> + /* 1) Stop HW best-effort for this channel */
> + hws_enable_video_capture(vid->parent, vid->channel_index, false);
> +
> + /* 2) Flip software state so IRQ/BH will be no-ops if they run */
> + WRITE_ONCE(vid->stop_requested, true);
> + WRITE_ONCE(vid->cap_active, false);
> +
> + /* 3) Ensure the IRQ handler finished any in-flight completions */
> + if (vid->parent && vid->parent->irq >= 0)
> + synchronize_irq(vid->parent->irq);
> +
> + /* 4) Drain SW capture queue & in-flight under lock */
> + spin_lock_irqsave(&vid->irq_lock, flags);
> + hws_video_collect_done_locked(vid, &done);
> + spin_unlock_irqrestore(&vid->irq_lock, flags);
> +
> + list_for_each_entry_safe(buf, tmp, &done, list) {
> + list_del_init(&buf->list);
> + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
> + }
> +
> + /* 5) Release VB2 queue if initialized */
> + if (vid->buffer_queue.ops)
> + vb2_queue_release(&vid->buffer_queue);
> +
> + /* 6) Free V4L2 controls */
> + v4l2_ctrl_handler_free(&vid->control_handler);
> +
> + /* 7) Unregister the video_device if we own it */
> + if (vid->video_device && video_is_registered(vid->video_device))
> + video_unregister_device(vid->video_device);
> + /* If you allocated it with video_device_alloc(), release it here:
> + * video_device_release(vid->video_device);
> + */
> + vid->video_device = NULL;
> +
> + /* 8) Reset simple state (don’t memset the whole struct here) */
> + mutex_destroy(&vid->state_lock);
> + INIT_LIST_HEAD(&vid->capture_queue);
> + vid->active = NULL;
> + vid->stop_requested = false;
> + vid->last_buf_half_toggle = 0;
> + vid->half_seen = false;
> + vid->signal_loss_cnt = 0;
> +}
> +
> +/* Convenience cast */
> +static inline struct hwsvideo_buffer *to_hwsbuf(struct vb2_buffer *vb)
> +{
> + return container_of(to_vb2_v4l2_buffer(vb), struct hwsvideo_buffer, vb);
> +}
> +
> +static int hws_buf_init(struct vb2_buffer *vb)
> +{
> + struct hwsvideo_buffer *b = to_hwsbuf(vb);
> +
> + INIT_LIST_HEAD(&b->list);
> + return 0;
> +}
> +
> +static void hws_buf_finish(struct vb2_buffer *vb)
> +{
> + /* vb2 core handles cache maintenance for dma-contig buffers */
> + (void)vb;
> +}
> +
> +static void hws_buf_cleanup(struct vb2_buffer *vb)
> +{
> + struct hwsvideo_buffer *b = to_hwsbuf(vb);
> +
> + if (!list_empty(&b->list))
> + list_del_init(&b->list);
> +}
> +
> +void hws_program_dma_for_addr(struct hws_pcie_dev *hws, unsigned int ch,
> + dma_addr_t dma)
> +{
> + struct hws_video *vid = &hws->video[ch];
> +
> + hws_program_dma_window(vid, dma);
> +}
> +
> +void hws_enable_video_capture(struct hws_pcie_dev *hws, unsigned int chan,
> + bool on)
> +{
> + u32 status;
> +
> + if (!hws || hws->pci_lost || chan >= hws->max_channels)
> + return;
> +
> + status = readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
> + status = on ? (status | BIT(chan)) : (status & ~BIT(chan));
> + writel(status, hws->bar0_base + HWS_REG_VCAP_ENABLE);
> + (void)readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
> +
> + WRITE_ONCE(hws->video[chan].cap_active, on);
> +
> + dev_dbg(&hws->pdev->dev, "vcap %s ch%u (reg=0x%08x)\n",
> + on ? "ON" : "OFF", chan, status);
> +}
> +
> +static void hws_seed_dma_windows(struct hws_pcie_dev *hws)
> +{
> + const u32 addr_mask = PCI_E_BAR_ADD_MASK;
> + const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK;
> + u32 table = 0x208; /* one 64-bit entry per channel */
> + unsigned int ch;
> +
> + if (!hws || !hws->bar0_base)
> + return;
> +
> + /* If cur_max_video_ch isn’t set yet, default to max_channels */
> + if (!hws->cur_max_video_ch || hws->cur_max_video_ch > hws->max_channels)
> + hws->cur_max_video_ch = hws->max_channels;
> +
> + for (ch = 0; ch < hws->cur_max_video_ch; ch++, table += 8) {
> + /* Scratch buffers are allocated once during probe. */
> + if (!hws->scratch_vid[ch].cpu)
> + continue;
> +
> + /* 2) Program 64-bit BAR remap entry for this channel */
> + {
> + dma_addr_t p = hws->scratch_vid[ch].dma;
> + u32 lo = lower_32_bits(p) & addr_mask;
> + u32 hi = upper_32_bits(p);
> + u32 pci_addr_low = lower_32_bits(p) & addr_low_mask;
> +
> + writel_relaxed(hi,
> + hws->bar0_base + PCI_ADDR_TABLE_BASE +
> + table);
> + writel_relaxed(lo,
> + hws->bar0_base + PCI_ADDR_TABLE_BASE +
> + table + PCIE_BARADDROFSIZE);
> +
> + /* 3) Per-channel AXI base + PCI low */
> + writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE +
> + pci_addr_low,
> + hws->bar0_base + CVBS_IN_BUF_BASE +
> + ch * PCIE_BARADDROFSIZE);
> +
> + /* 4) Half-frame length in /16 units.
> + * Prefer the current channel’s computed half_size if available.
> + * Fall back to half of the preallocated scratch buffer.
> + */
> + {
> + u32 half_bytes = hws->video[ch].pix.half_size ?
> + hws->video[ch].pix.half_size :
> + (hws->scratch_vid[ch].size / 2);
> + writel_relaxed(half_bytes / 16,
> + hws->bar0_base +
> + CVBS_IN_BUF_BASE2 +
> + ch * PCIE_BARADDROFSIZE);
> + }
> + }
> + }
> +
> + /* Post writes so device sees them before we move on */
> + (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
> +}
> +
> +static void hws_ack_all_irqs(struct hws_pcie_dev *hws)
> +{
> + u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
> +
> + if (st) {
> + writel(st, hws->bar0_base + HWS_REG_INT_STATUS); /* W1C */
> + (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
> + }
> +}
> +
> +static void hws_open_irq_fabric(struct hws_pcie_dev *hws)
> +{
> + /* Route all sources to vector 0 (same value you’re already using) */
> + writel(0x00000000, hws->bar0_base + PCIE_INT_DEC_REG_BASE);
> + (void)readl(hws->bar0_base + PCIE_INT_DEC_REG_BASE);
> +
> + /* Turn on the bridge if your IP needs it */
> + 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);
> +}
> +
> +void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable)
> +{
> + int i;
> +
> + if (hws->start_run && !enable)
> + return;
> +
> + /* 1) reset the decoder mode register to 0 */
> + writel(0x00000000, hws->bar0_base + HWS_REG_DEC_MODE);
> + hws_seed_dma_windows(hws);
> +
> + /* 3) on a full reset, clear all per-channel status and indices */
> + if (!enable) {
> + for (i = 0; i < hws->max_channels; i++) {
> + /* helpers to arm/disable capture engines */
> + hws_enable_video_capture(hws, i, false);
> + }
> + }
> +
> + /* 4) “Start run”: set bit31, wait a bit, then program low 24 bits */
> + writel(0x80000000, hws->bar0_base + HWS_REG_DEC_MODE);
> + // udelay(500);
> + 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);
> + /* 6) record that we're now running */
> + hws->start_run = true;
> +}
> +
> +int hws_check_card_status(struct hws_pcie_dev *hws)
> +{
> + u32 status;
> +
> + if (!hws || !hws->bar0_base)
> + return -ENODEV;
> +
> + status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
> +
> + /* Common “device missing” pattern */
> + if (unlikely(status == 0xFFFFFFFF)) {
> + hws->pci_lost = true;
> + dev_err(&hws->pdev->dev, "PCIe device not responding\n");
> + return -ENODEV;
> + }
> +
> + /* If RUN/READY bit (bit0) isn’t set, (re)initialize 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);
> + /* Optional: verify the core cleared its busy bit, if you have one */
> + /* int ret = hws_check_busy(hws); */
> + /* if (ret) return ret; */
> + }
> +
> + return 0;
> +}
> +
> +void check_video_format(struct hws_pcie_dev *pdx)
> +{
> + int i;
> +
> + for (i = 0; i < pdx->cur_max_video_ch; i++) {
> + if (!hws_update_active_interlace(pdx, i)) {
> + /* No active video; optionally feed neutral frames to keep streaming. */
> + if (pdx->video[i].signal_loss_cnt == 0)
> + pdx->video[i].signal_loss_cnt = 1;
> + if (READ_ONCE(pdx->video[i].cap_active))
> + hws_force_no_signal_frame(&pdx->video[i],
> + "monitor_nosignal");
> + } else {
> + if (pdx->hw_ver > 0)
> + handle_hwv2_path(pdx, i);
> + else
> + /* Legacy path stub; see handle_legacy_path() comment. */
> + handle_legacy_path(pdx, i);
> +
> + update_live_resolution(pdx, i);
> + pdx->video[i].signal_loss_cnt = 0;
> + }
> + }
> +}
> +
> +static inline void hws_write_if_diff(struct hws_pcie_dev *hws, u32 reg_off,
> + u32 new_val)
> +{
> + void __iomem *addr;
> + u32 old;
> +
> + if (!hws || !hws->bar0_base)
> + return;
> +
> + addr = hws->bar0_base + reg_off;
> +
> + old = readl(addr);
> + /* Treat all-ones as device gone; avoid writing garbage. */
> + if (unlikely(old == 0xFFFFFFFF)) {
> + hws->pci_lost = true;
> + return;
> + }
> +
> + if (old != new_val) {
> + writel(new_val, addr);
> + /* Post the write on some bridges / enforce ordering. */
> + (void)readl(addr);
> + }
> +}
> +
> +static bool hws_update_active_interlace(struct hws_pcie_dev *pdx,
> + unsigned int ch)
> +{
> + u32 reg;
> + bool active, interlace;
> +
> + if (ch >= pdx->cur_max_video_ch)
> + return false;
> +
> + reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
> + active = !!(reg & BIT(ch));
> + interlace = !!(reg & BIT(8 + ch));
> +
> + if (pdx->video[ch].hotplug_detect_control) {
> + v4l2_ctrl_lock(pdx->video[ch].hotplug_detect_control);
> + __v4l2_ctrl_s_ctrl(pdx->video[ch].hotplug_detect_control,
> + active);
> + v4l2_ctrl_unlock(pdx->video[ch].hotplug_detect_control);
> + }
> +
> + WRITE_ONCE(pdx->video[ch].pix.interlaced, interlace);
> + return active;
> +}
> +
> +/* Modern hardware path: keep HW registers in sync with current per-channel
> + * software state. Adjust the OUT_* bits below to match your HW contract.
> + */
> +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;
> +
> + if (!hws || !hws->bar0_base || ch >= hws->max_channels)
> + return;
> +
> + vid = &hws->video[ch];
> +
> + /* 1) Input frame rate (read-only; log or export via debugfs if wanted) */
> + in_fps = readl(hws->bar0_base + HWS_REG_FRAME_RATE(ch));
> + if (in_fps)
> + vid->current_fps = in_fps;
> + /* dev_dbg(&hws->pdev->dev, "ch%u input fps=%u\n", ch, in_fps); */
> +
> + /* 2) Output resolution programming
> + * If your HW expects a separate “scaled” size, add fields to track it.
> + * For now, mirror the current format (fmt_curr) to OUT_RES.
> + */
> + want_out_res = (vid->pix.height << 16) | vid->pix.width;
> + cur_out_res = readl(hws->bar0_base + HWS_REG_OUT_RES(ch));
> + if (cur_out_res != want_out_res)
> + hws_write_if_diff(hws, HWS_REG_OUT_RES(ch), want_out_res);
> +
> + /* 3) Output FPS: only program if you actually track a target.
> + * Example heuristic (disabled by default):
> + *
> + * u32 out_fps = (vid->fmt_curr.height >= 1080) ? 60 : 30;
> + * hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), out_fps);
> + */
> +
> + /* 4) BCHS controls: pack from per-channel current_* fields */
> + reg = readl(hws->bar0_base + HWS_REG_BCHS(ch));
> + {
> + u8 br = reg & 0xFF;
> + u8 co = (reg >> 8) & 0xFF;
> + u8 hu = (reg >> 16) & 0xFF;
> + u8 sa = (reg >> 24) & 0xFF;
> +
> + if (br != vid->current_brightness ||
> + co != vid->current_contrast || hu != vid->current_hue ||
> + sa != vid->current_saturation) {
> + u32 packed = (vid->current_saturation << 24) |
> + (vid->current_hue << 16) |
> + (vid->current_contrast << 8) |
> + vid->current_brightness;
> + hws_write_if_diff(hws, HWS_REG_BCHS(ch), packed);
> + }
> + }
> +
> + /* 5) HDCP detect: read only (no cache field in your structs today) */
> + reg = readl(hws->bar0_base + HWS_REG_HDCP_STATUS);
> + /* bool hdcp = !!(reg & BIT(ch)); // use if you later add a field/control */
> +}
> +
> +static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch)
> +{
> + /*
> + * Legacy (hw_ver == 0) expected behavior:
> + * - A per-channel SW FPS accumulator incremented on each VDONE.
> + * - A once-per-second poll mapped the count to discrete FPS:
> + * >55*2 => 60, >45*2 => 50, >25*2 => 30, >20*2 => 25, else 60,
> + * then reset the accumulator to 0.
> + * - The *2 factor assumed VDONE fired per-field; if legacy VDONE is
> + * per-frame, drop the factor.
> + *
> + * Current code keeps this path as a no-op; vid->current_fps stays at the
> + * default or mode-derived value. If accurate legacy FPS reporting is
> + * needed (V4L2 g_parm/timeperframe), reintroduce the accumulator in the
> + * IRQ path and perform the mapping/reset here.
> + *
> + * No-op by default. If you introduce a SW FPS accumulator, map it here.
> + *
> + * Example skeleton:
> + *
> + * u32 sw_rate = READ_ONCE(hws->sw_fps[ch]); // incremented elsewhere
> + * if (sw_rate > THRESHOLD) {
> + * u32 fps = pick_fps_from_rate(sw_rate);
> + * hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), fps);
> + * WRITE_ONCE(hws->sw_fps[ch], 0);
> + * }
> + */
> + (void)hws;
> + (void)ch;
> +}
> +
> +static void hws_video_apply_mode_change(struct hws_pcie_dev *pdx,
> + unsigned int ch, u16 w, u16 h,
> + bool interlaced)
> +{
> + struct hws_video *v = &pdx->video[ch];
> + unsigned long flags;
> + u32 new_size;
> + bool queue_busy;
> + struct list_head done;
> + struct hwsvideo_buffer *b, *tmp;
> +
> + if (!pdx || !pdx->bar0_base)
> + return;
> + if (ch >= pdx->max_channels)
> + return;
> + if (!w || !h || w > MAX_VIDEO_HW_W ||
> + (!interlaced && h > MAX_VIDEO_HW_H) ||
> + (interlaced && (h * 2) > MAX_VIDEO_HW_H))
> + return;
> +
> + if (!mutex_trylock(&v->state_lock))
> + return;
> +
> + INIT_LIST_HEAD(&done);
> +
> + WRITE_ONCE(v->stop_requested, true);
> + WRITE_ONCE(v->cap_active, false);
> + /* Publish software stop first so the IRQ completion path sees the stop
> + * before we touch MMIO or the lists. Pairs with READ_ONCE() checks in the
> + * VDONE handler and hws_arm_next() to prevent completions while modes
> + * change.
> + */
> + smp_wmb();
> +
> + hws_enable_video_capture(pdx, ch, false);
> + readl(pdx->bar0_base + HWS_REG_INT_STATUS);
> +
> + if (v->parent && v->parent->irq >= 0)
> + synchronize_irq(v->parent->irq);
> +
> + spin_lock_irqsave(&v->irq_lock, flags);
> + hws_video_collect_done_locked(v, &done);
> + spin_unlock_irqrestore(&v->irq_lock, flags);
> +
> + /* Update software pixel state */
> + v->pix.width = w;
> + v->pix.height = h;
> + v->pix.interlaced = interlaced;
> + hws_set_current_dv_timings(v, w, h, interlaced);
> + /* Try to reflect the live frame rate if HW reports it; otherwise default
> + * to common rates (50 Hz for 576p, else 60 Hz).
> + */
> + {
> + u32 fps = readl(pdx->bar0_base + HWS_REG_FRAME_RATE(ch));
> +
> + if (fps)
> + v->current_fps = fps;
> + else
> + v->current_fps = (h == 576) ? 50 : 60;
> + }
> +
> + new_size = hws_calc_sizeimage(v, w, h, interlaced);
> + v->window_valid = false;
> + queue_busy = vb2_is_busy(&v->buffer_queue);
> +
> + /* Mode changes require userspace to renegotiate buffers and restart
> + * streaming. Complete every queued buffer with an error, surface a
> + * SOURCE_CHANGE event, and leave the queue in an error state until the
> + * next streamoff/reqbufs cycle.
> + */
> + if (queue_busy) {
> + struct v4l2_event ev = {
> + .type = V4L2_EVENT_SOURCE_CHANGE,
> + };
> +
> + ev.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
> + v4l2_event_queue(v->video_device, &ev);
> + vb2_queue_error(&v->buffer_queue);
> + } else {
> + v->alloc_sizeimage = PAGE_ALIGN(new_size);
> + }
> +
> + /* Program HW with new resolution */
> + hws_write_if_diff(pdx, HWS_REG_OUT_RES(ch), (h << 16) | w);
> +
> + /* Legacy half-buffer programming */
> + writel(v->pix.half_size / 16,
> + pdx->bar0_base + CVBS_IN_BUF_BASE2 + ch * PCIE_BARADDROFSIZE);
> + (void)readl(pdx->bar0_base + CVBS_IN_BUF_BASE2 +
> + ch * PCIE_BARADDROFSIZE);
> +
> + /* Reset per-channel toggles/counters */
> + WRITE_ONCE(v->last_buf_half_toggle, 0);
> + atomic_set(&v->sequence_number, 0);
> +
> + mutex_unlock(&v->state_lock);
> +
> + list_for_each_entry_safe(b, tmp, &done, list) {
> + list_del_init(&b->list);
> + vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
> + }
> +}
> +
> +static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch)
> +{
> + u32 reg = readl(pdx->bar0_base + HWS_REG_IN_RES(ch));
> + u16 res_w = reg & 0xFFFF;
> + u16 res_h = (reg >> 16) & 0xFFFF;
> + bool interlace = READ_ONCE(pdx->video[ch].pix.interlaced);
> +
> + bool within_hw = (res_w <= MAX_VIDEO_HW_W) &&
> + ((!interlace && res_h <= MAX_VIDEO_HW_H) ||
> + (interlace && (res_h * 2) <= MAX_VIDEO_HW_H));
> +
> + if (!within_hw)
> + return;
> +
> + if (res_w != pdx->video[ch].pix.width ||
> + res_h != pdx->video[ch].pix.height) {
> + hws_video_apply_mode_change(pdx, ch, res_w, res_h, interlace);
> + }
> +}
> +
> +static int hws_open(struct file *file)
> +{
> + return v4l2_fh_open(file);
> +}
> +
> +static const struct v4l2_file_operations hws_fops = {
> + .owner = THIS_MODULE,
> + .open = hws_open,
> + .release = vb2_fop_release,
> + .poll = vb2_fop_poll,
> + .unlocked_ioctl = video_ioctl2,
> + .mmap = vb2_fop_mmap,
> +};
> +
> +static int hws_subscribe_event(struct v4l2_fh *fh,
> + const struct v4l2_event_subscription *sub)
> +{
> + switch (sub->type) {
> + case V4L2_EVENT_SOURCE_CHANGE:
> + return v4l2_src_change_event_subscribe(fh, sub);
> + case V4L2_EVENT_CTRL:
> + return v4l2_ctrl_subscribe_event(fh, sub);
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static const struct v4l2_ioctl_ops hws_ioctl_fops = {
> + /* Core caps/info */
> + .vidioc_querycap = hws_vidioc_querycap,
> +
> + /* Pixel format: still needed to report YUYV etc. */
> + .vidioc_enum_fmt_vid_cap = hws_vidioc_enum_fmt_vid_cap,
> + .vidioc_enum_frameintervals = hws_vidioc_enum_frameintervals,
> + .vidioc_g_fmt_vid_cap = hws_vidioc_g_fmt_vid_cap,
> + .vidioc_s_fmt_vid_cap = hws_vidioc_s_fmt_vid_cap,
> + .vidioc_try_fmt_vid_cap = hws_vidioc_try_fmt_vid_cap,
> +
> + /* Buffer queueing / streaming */
> + .vidioc_reqbufs = vb2_ioctl_reqbufs,
> + .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
> + .vidioc_create_bufs = vb2_ioctl_create_bufs,
> + .vidioc_querybuf = vb2_ioctl_querybuf,
> + .vidioc_qbuf = vb2_ioctl_qbuf,
> + .vidioc_dqbuf = vb2_ioctl_dqbuf,
> + .vidioc_expbuf = vb2_ioctl_expbuf,
> + .vidioc_streamon = vb2_ioctl_streamon,
> + .vidioc_streamoff = vb2_ioctl_streamoff,
> +
> + /* Inputs */
> + .vidioc_enum_input = hws_vidioc_enum_input,
> + .vidioc_g_input = hws_vidioc_g_input,
> + .vidioc_s_input = hws_vidioc_s_input,
> +
> + /* DV timings (HDMI/DVI/VESA modes) */
> + .vidioc_query_dv_timings = hws_vidioc_query_dv_timings,
> + .vidioc_enum_dv_timings = hws_vidioc_enum_dv_timings,
> + .vidioc_g_dv_timings = hws_vidioc_g_dv_timings,
> + .vidioc_s_dv_timings = hws_vidioc_s_dv_timings,
> + .vidioc_dv_timings_cap = hws_vidioc_dv_timings_cap,
> +
> + .vidioc_log_status = v4l2_ctrl_log_status,
> + .vidioc_subscribe_event = hws_subscribe_event,
> + .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
> + .vidioc_g_parm = hws_vidioc_g_parm,
> + .vidioc_s_parm = hws_vidioc_s_parm,
> +};
> +
> +static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
> + bool interlaced)
> +{
> + /* example for packed 16bpp (YUYV); replace with your real math/align */
> + u32 lines = h; /* full frame lines for sizeimage */
> + u32 bytesperline = ALIGN(w * 2, 64);
> + u32 sizeimage, half0;
> +
> + /* publish into pix, since we now carry these in-state */
> + v->pix.bytesperline = bytesperline;
> + sizeimage = bytesperline * lines;
> +
> + half0 = sizeimage / 2;
> +
> + v->pix.sizeimage = sizeimage;
> + v->pix.half_size = half0; /* first half; second = sizeimage - half0 */
> + v->pix.field = interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
> +
> + return v->pix.sizeimage;
> +}
> +
> +static int hws_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
> + unsigned int *nplanes, unsigned int sizes[],
> + struct device *alloc_devs[])
> +{
> + struct hws_video *vid = q->drv_priv;
> +
> + (void)num_buffers;
> + (void)alloc_devs;
> +
> + if (!vid->pix.sizeimage) {
> + vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
> + vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
> + }
> + if (*nplanes) {
> + if (sizes[0] < vid->pix.sizeimage)
> + return -EINVAL;
> + } else {
> + *nplanes = 1;
> + sizes[0] = PAGE_ALIGN(vid->pix.sizeimage);
> + }
> +
> + vid->alloc_sizeimage = PAGE_ALIGN(vid->pix.sizeimage);
> + return 0;
> +}
> +
> +static int hws_buffer_prepare(struct vb2_buffer *vb)
> +{
> + struct hws_video *vid = vb->vb2_queue->drv_priv;
> + struct hws_pcie_dev *hws = vid->parent;
> + size_t need = vid->pix.sizeimage;
> + dma_addr_t dma_addr;
> +
> + if (vb2_plane_size(vb, 0) < need)
> + return -EINVAL;
> +
> + /* Validate DMA address alignment */
> + dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
> + if (dma_addr & 0x3F) { /* 64-byte alignment required */
> + dev_err(&hws->pdev->dev,
> + "Buffer DMA address 0x%llx not 64-byte aligned\n",
> + (unsigned long long)dma_addr);
> + return -EINVAL;
> + }
> +
> + vb2_set_plane_payload(vb, 0, need);
> + return 0;
> +}
> +
> +static void hws_buffer_queue(struct vb2_buffer *vb)
> +{
> + struct hws_video *vid = vb->vb2_queue->drv_priv;
> + struct hwsvideo_buffer *buf = to_hwsbuf(vb);
> + struct hws_pcie_dev *hws = vid->parent;
> + unsigned long flags;
> +
> + dev_dbg(&hws->pdev->dev,
> + "buffer_queue(ch=%u): vb=%p sizeimage=%u q_active=%d\n",
> + vid->channel_index, vb, vid->pix.sizeimage,
> + READ_ONCE(vid->cap_active));
> +
> + /* Initialize buffer slot */
> + buf->slot = 0;
> +
> + spin_lock_irqsave(&vid->irq_lock, flags);
> + list_add_tail(&buf->list, &vid->capture_queue);
> + vid->queued_count++;
> +
> + /* If streaming and no in-flight buffer, prime HW immediately */
> + if (READ_ONCE(vid->cap_active) && !vid->active) {
> + dma_addr_t dma_addr;
> +
> + dev_dbg(&hws->pdev->dev,
> + "buffer_queue(ch=%u): priming first vb=%p\n",
> + vid->channel_index, &buf->vb.vb2_buf);
> + list_del_init(&buf->list);
> + vid->queued_count--;
> + vid->active = buf;
> +
> + dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
> + hws_program_dma_for_addr(vid->parent, vid->channel_index,
> + dma_addr);
> + iowrite32(lower_32_bits(dma_addr),
> + hws->bar0_base + HWS_REG_DMA_ADDR(vid->channel_index));
> +
> + wmb(); /* ensure descriptors visible before enabling capture */
> + hws_enable_video_capture(hws, vid->channel_index, true);
> + hws_prime_next_locked(vid);
> + } else if (READ_ONCE(vid->cap_active) && vid->active) {
> + hws_prime_next_locked(vid);
> + }
> + spin_unlock_irqrestore(&vid->irq_lock, flags);
> +}
> +
> +static int hws_start_streaming(struct vb2_queue *q, unsigned int count)
> +{
> + struct hws_video *v = q->drv_priv;
> + struct hws_pcie_dev *hws = v->parent;
> + struct hwsvideo_buffer *to_program = NULL; /* local copy */
> + struct vb2_buffer *prog_vb2 = NULL;
> + unsigned long flags;
> + int ret;
> +
> + dev_dbg(&hws->pdev->dev, "start_streaming: ch=%u count=%u\n",
> + v->channel_index, count);
> +
> + ret = hws_check_card_status(hws);
> + if (ret) {
> + struct hwsvideo_buffer *b, *tmp;
> + unsigned long f;
> + LIST_HEAD(queued);
> +
> + spin_lock_irqsave(&v->irq_lock, f);
> + if (v->active) {
> + list_add_tail(&v->active->list, &queued);
> + v->active = NULL;
> + }
> + if (v->next_prepared) {
> + list_add_tail(&v->next_prepared->list, &queued);
> + v->next_prepared = NULL;
> + }
> + while (!list_empty(&v->capture_queue)) {
> + b = list_first_entry(&v->capture_queue,
> + struct hwsvideo_buffer, list);
> + list_move_tail(&b->list, &queued);
> + }
> + spin_unlock_irqrestore(&v->irq_lock, f);
> +
> + list_for_each_entry_safe(b, tmp, &queued, list) {
> + list_del_init(&b->list);
> + vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
> + }
> + return ret;
> + }
> + (void)hws_update_active_interlace(hws, v->channel_index);
> +
> + lockdep_assert_held(&v->state_lock);
> + /* init per-stream state */
> + WRITE_ONCE(v->stop_requested, false);
> + WRITE_ONCE(v->cap_active, true);
> + WRITE_ONCE(v->half_seen, false);
> + WRITE_ONCE(v->last_buf_half_toggle, 0);
> +
> + /* Try to prime a buffer, but it's OK if none are queued yet */
> + spin_lock_irqsave(&v->irq_lock, flags);
> + if (!v->active && !list_empty(&v->capture_queue)) {
> + to_program = list_first_entry(&v->capture_queue,
> + struct hwsvideo_buffer, list);
> + list_del_init(&to_program->list);
> + v->queued_count--;
> + v->active = to_program;
> + prog_vb2 = &to_program->vb.vb2_buf;
> + dev_dbg(&hws->pdev->dev,
> + "start_streaming: ch=%u took buffer %p\n",
> + v->channel_index, to_program);
> + }
> + spin_unlock_irqrestore(&v->irq_lock, flags);
> +
> + /* Only program/enable HW if we actually have a buffer */
> + if (to_program) {
> + if (!prog_vb2)
> + prog_vb2 = &to_program->vb.vb2_buf;
> + {
> + dma_addr_t dma_addr;
> +
> + dma_addr = vb2_dma_contig_plane_dma_addr(prog_vb2, 0);
> + hws_program_dma_for_addr(hws, v->channel_index, dma_addr);
> + iowrite32(lower_32_bits(dma_addr),
> + hws->bar0_base +
> + HWS_REG_DMA_ADDR(v->channel_index));
> + dev_dbg(&hws->pdev->dev,
> + "start_streaming: ch=%u programmed buffer %p dma=0x%08x\n",
> + v->channel_index, to_program,
> + lower_32_bits(dma_addr));
> + (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
> + }
> +
> + wmb(); /* ensure descriptors visible before enabling capture */
> + hws_enable_video_capture(hws, v->channel_index, true);
> + {
> + unsigned long pf;
> +
> + spin_lock_irqsave(&v->irq_lock, pf);
> + hws_prime_next_locked(v);
> + spin_unlock_irqrestore(&v->irq_lock, pf);
> + }
> + } else {
> + dev_dbg(&hws->pdev->dev,
> + "start_streaming: ch=%u no buffer yet (will arm on QBUF)\n",
> + v->channel_index);
> + }
> +
> + return 0;
> +}
> +
> +static void hws_log_video_state(struct hws_video *v, const char *action,
> + const char *phase)
> +{
> + struct hws_pcie_dev *hws = v->parent;
> + unsigned long flags;
> + unsigned int queued = 0;
> + unsigned int tracked = 0;
> + unsigned int seq = 0;
> + struct hwsvideo_buffer *b;
> + bool streaming = 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 = READ_ONCE(v->cap_active);
> + stop_requested = READ_ONCE(v->stop_requested);
> + active = v->active;
> + next_prepared = v->next_prepared;
> + tracked = v->queued_count;
> + seq = (u32)atomic_read(&v->sequence_number);
> + spin_unlock_irqrestore(&v->irq_lock, flags);
> +
> + dev_dbg(&hws->pdev->dev,
> + "video:%s:%s ch=%u streaming=%d cap=%d stop=%d active=%p next=%p queued=%u tracked=%u seq=%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 = q->drv_priv;
> + struct hws_pcie_dev *hws = v->parent;
> + unsigned long flags;
> + struct hwsvideo_buffer *b, *tmp;
> + LIST_HEAD(done);
> + unsigned int done_cnt = 0;
> + u64 start_ns = ktime_get_mono_fast_ns();
> +
> + hws_log_video_state(v, "streamoff", "begin");
> +
> + /* 1) Quiesce SW/HW first */
> + lockdep_assert_held(&v->state_lock);
> + WRITE_ONCE(v->cap_active, false);
> + WRITE_ONCE(v->stop_requested, true);
> +
> + hws_enable_video_capture(v->parent, v->channel_index, false);
> +
> + /* 2) Collect in-flight + queued under the IRQ lock */
> + spin_lock_irqsave(&v->irq_lock, flags);
> + hws_video_collect_done_locked(v, &done);
> + spin_unlock_irqrestore(&v->irq_lock, flags);
> +
> + /* 3) Complete outside the lock */
> + list_for_each_entry_safe(b, tmp, &done, list) {
> + /* 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=%u completed=%u (%lluus)\n",
> + v->channel_index, done_cnt,
> + (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
> + hws_log_video_state(v, "streamoff", "end");
> +}
> +
> +static const struct vb2_ops hwspcie_video_qops = {
> + .queue_setup = hws_queue_setup,
> + .buf_prepare = hws_buffer_prepare,
> + .buf_init = hws_buf_init,
> + .buf_finish = hws_buf_finish,
> + .buf_cleanup = hws_buf_cleanup,
> + // .buf_finish = hws_buffer_finish,
Can be dropped, seems to be a left-over.
> + .buf_queue = hws_buffer_queue,
> + .start_streaming = hws_start_streaming,
> + .stop_streaming = hws_stop_streaming,
> +};
> +
> +int hws_video_register(struct hws_pcie_dev *dev)
> +{
> + int i, ret;
> +
> + ret = v4l2_device_register(&dev->pdev->dev, &dev->v4l2_device);
> + if (ret) {
> + dev_err(&dev->pdev->dev, "v4l2_device_register failed: %d\n",
> + ret);
> + return ret;
> + }
> +
> + for (i = 0; i < dev->cur_max_video_ch; i++) {
> + struct hws_video *ch = &dev->video[i];
> + struct video_device *vdev;
> + struct vb2_queue *q;
> +
> + /* hws_video_init_channel() should have set:
> + * - ch->parent, ch->channel_index
> + * - locks (state_lock, irq_lock)
> + * - capture_queue (INIT_LIST_HEAD)
> + * - control_handler + controls
> + * - fmt_curr (width/height)
> + * Don’t reinitialize any of those here.
> + */
> +
> + vdev = video_device_alloc();
> + if (!vdev) {
> + dev_err(&dev->pdev->dev,
> + "video_device_alloc ch%u failed\n", i);
> + ret = -ENOMEM;
> + goto err_unwind;
> + }
> + ch->video_device = vdev;
> +
> + /* Basic V4L2 node setup */
> + snprintf(vdev->name, sizeof(vdev->name), "%s-hdmi%u",
> + KBUILD_MODNAME, i);
> + vdev->v4l2_dev = &dev->v4l2_device;
> + vdev->fops = &hws_fops; /* your file_ops */
> + vdev->ioctl_ops = &hws_ioctl_fops; /* your ioctl_ops */
> + vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
> + vdev->lock = &ch->state_lock; /* serialize file ops */
> + vdev->ctrl_handler = &ch->control_handler;
> + vdev->vfl_dir = VFL_DIR_RX;
> + vdev->release = video_device_release;
> + if (ch->control_handler.error) {
> + ret = ch->control_handler.error;
> + goto err_unwind;
> + }
> + video_set_drvdata(vdev, ch);
> +
> + /* vb2 queue init (dma-contig) */
> + q = &ch->buffer_queue;
> + memset(q, 0, sizeof(*q));
> + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> + q->io_modes = VB2_MMAP | VB2_DMABUF;
> + q->drv_priv = ch;
> + q->buf_struct_size = sizeof(struct hwsvideo_buffer);
> + q->ops = &hwspcie_video_qops; /* your vb2_ops */
> + q->mem_ops = &vb2_dma_contig_memops;
> + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> + q->lock = &ch->state_lock;
> + q->min_queued_buffers = 1;
> + q->dev = &dev->pdev->dev;
> +
> + ret = vb2_queue_init(q);
> + vdev->queue = q;
> + if (ret) {
> + dev_err(&dev->pdev->dev,
> + "vb2_queue_init ch%u failed: %d\n", i, ret);
> + goto err_unwind;
> + }
> +
> + /* Make controls live (no-op if none or already set up) */
> + if (ch->control_handler.error) {
> + ret = ch->control_handler.error;
> + dev_err(&dev->pdev->dev,
> + "ctrl handler ch%u error: %d\n", i, ret);
> + goto err_unwind;
> + }
> + v4l2_ctrl_handler_setup(&ch->control_handler);
> + ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
> + if (ret) {
> + dev_err(&dev->pdev->dev,
> + "video_register_device ch%u failed: %d\n", i,
> + ret);
> + goto err_unwind;
> + }
> +
> + ret = hws_resolution_create(vdev);
> + if (ret) {
> + dev_err(&dev->pdev->dev,
> + "device_create_file(resolution) ch%u failed: %d\n",
> + i, ret);
> + goto err_unwind;
> + }
> + }
> +
> + return 0;
> +
> +err_unwind:
> + for (; i >= 0; i--) {
> + struct hws_video *ch = &dev->video[i];
> +
> + if (video_is_registered(ch->video_device))
> + hws_resolution_remove(ch->video_device);
> + if (video_is_registered(ch->video_device))
> + vb2_video_unregister_device(ch->video_device);
> + if (ch->video_device) {
> + /* If not registered, we must free the alloc’d vdev ourselves */
> + if (!video_is_registered(ch->video_device))
> + video_device_release(ch->video_device);
> + ch->video_device = NULL;
> + }
> + }
> + v4l2_device_unregister(&dev->v4l2_device);
> + return ret;
> +}
> +
> +void hws_video_unregister(struct hws_pcie_dev *dev)
> +{
> + int i;
> +
> + if (!dev)
> + return;
> +
> + for (i = 0; i < dev->cur_max_video_ch; i++) {
> + struct hws_video *ch = &dev->video[i];
> +
> + if (ch->video_device)
> + hws_resolution_remove(ch->video_device);
> + if (ch->video_device) {
> + vb2_video_unregister_device(ch->video_device);
> + ch->video_device = NULL;
> + }
> + v4l2_ctrl_handler_free(&ch->control_handler);
> + }
> + v4l2_device_unregister(&dev->v4l2_device);
> +}
> +
> +int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason)
> +{
> + int i, ret = 0;
> + u64 start_ns = ktime_get_mono_fast_ns();
> +
> + dev_dbg(&hws->pdev->dev, "video:%s:begin channels=%u\n", reason,
> + hws->cur_max_video_ch);
> + for (i = 0; i < hws->cur_max_video_ch; i++) {
> + struct hws_video *vid = &hws->video[i];
> + struct vb2_queue *q = &vid->buffer_queue;
> + u64 ch_start_ns = ktime_get_mono_fast_ns();
> + bool streaming;
> +
> + if (!q || !q->ops) {
> + dev_dbg(&hws->pdev->dev,
> + "video:%s:ch=%d skipped queue-unavailable\n",
> + reason, i);
> + continue;
> + }
> +
> + streaming = vb2_is_streaming(q);
> + hws_log_video_state(vid, reason, "channel");
> + if (streaming) {
> + /* Stop via vb2 (runs your .stop_streaming) */
> + int r = vb2_streamoff(q, q->type);
> +
> + dev_dbg(&hws->pdev->dev,
> + "video:%s:ch=%d streamoff ret=%d (%lluus)\n",
> + reason, i, r, (unsigned long long)
> + ((ktime_get_mono_fast_ns() - ch_start_ns) / 1000));
> + if (r && !ret)
> + ret = r;
> + } else {
> + dev_dbg(&hws->pdev->dev,
> + "video:%s:ch=%d idle (%lluus)\n",
> + reason, i, (unsigned long long)
> + ((ktime_get_mono_fast_ns() - ch_start_ns) / 1000));
> + }
> + }
> + dev_dbg(&hws->pdev->dev, "video:%s:done ret=%d (%lluus)\n", reason,
> + ret,
> + (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
> + return ret;
> +}
> +
> +void hws_video_pm_resume(struct hws_pcie_dev *hws)
> +{
> + /* Nothing mandatory to do here for vb2 — userspace will STREAMON again.
> + * If you track per-channel 'auto-restart' policy, re-arm it here.
> + */
> +}
> diff --git a/drivers/media/pci/hws/hws_video.h b/drivers/media/pci/hws/hws_video.h
> new file mode 100644
> index 000000000000..d02cfb2cdeb3
> --- /dev/null
> +++ b/drivers/media/pci/hws/hws_video.h
> @@ -0,0 +1,29 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef HWS_VIDEO_H
> +#define HWS_VIDEO_H
> +
> +struct hws_video;
> +
> +int hws_video_register(struct hws_pcie_dev *dev);
> +void hws_video_unregister(struct hws_pcie_dev *dev);
> +void hws_enable_video_capture(struct hws_pcie_dev *hws,
> + unsigned int chan,
> + bool on);
> +void hws_prime_next_locked(struct hws_video *vid);
> +
> +int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch);
> +void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch);
> +void check_video_format(struct hws_pcie_dev *pdx);
> +int hws_check_card_status(struct hws_pcie_dev *hws);
> +void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable);
> +
> +void hws_program_dma_for_addr(struct hws_pcie_dev *hws,
> + unsigned int ch,
> + dma_addr_t dma);
> +void hws_set_dma_doorbell(struct hws_pcie_dev *hws, unsigned int ch,
> + dma_addr_t dma, const char *tag);
> +
> +int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason);
> +void hws_video_pm_resume(struct hws_pcie_dev *hws);
> +
> +#endif // HWS_VIDEO_H
Regards,
Hans
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 0/2] media: pci: add AVMatrix HWS capture driver
2026-03-18 0:10 ` [PATCH v2 0/2] media: pci: add AVMatrix HWS capture driver Ben Hoff
2026-03-18 0:10 ` [PATCH v2 1/2] " Ben Hoff
2026-03-18 0:10 ` [PATCH v2 2/2] MAINTAINERS: add entry for AVMatrix HWS driver Ben Hoff
@ 2026-03-24 9:19 ` Hans Verkuil
2026-03-30 19:56 ` [PATCH v3 " hoff.benjamin.k
3 siblings, 0 replies; 11+ messages in thread
From: Hans Verkuil @ 2026-03-24 9:19 UTC (permalink / raw)
To: Ben Hoff, linux-media; +Cc: Mauro Carvalho Chehab, linux-kernel
Hi Ben,
On 18/03/2026 01:10, Ben Hoff wrote:
> Add an AVMatrix HWS PCIe capture driver and its MAINTAINERS entry.
>
> The driver exposes one V4L2 capture node per input channel, supports
> YUYV capture through vb2-dma-contig, reports DV timings, emits
> SOURCE_CHANGE events, and provides the basic brightness/contrast/
> saturation/hue controls used by the hardware.
I found some issues that need to be addressed, so a v3 is needed.
Please provide the v4l2-compliance output as well when posting v3.
Regards,
Hans
>
> Changes in v2:
> - keep scratch DMA allocation on a single probe-owned path
> - fix hws_video_register()/probe unwind ownership to avoid control-handler
> double-free on late registration failures
> - on live input resolution changes, emit SOURCE_CHANGE, error queued
> buffers, and require userspace to renegotiate buffers and restart
> streaming
> - add enum_frameintervals and report DV_RX_POWER_PRESENT, addressing the
> two v1 v4l2-compliance warnings
>
> Testing for v2:
> - build-tested with W=1:
> make -C /home/hoff/swdev/linux O=/tmp/hws-build \
> M=drivers/media/pci/hws W=1 KBUILD_MODPOST_WARN=1 modules
> - checkpatch.pl --no-tree --strict --file ... is clean for the new files
>
> Context carried forward from v1:
> - audio support remains intentionally omitted from this submission
> - the driver is derived from a GPL out-of-tree driver; the baseline tree is
> available at https://github.com/benhoff/hws/tree/baseline
> - a vendor driver bundle is available at
> https://www.acasis.com/pages/acasis-product-drivers
> - the vendor is not involved in this upstreaming effort
>
> Ben Hoff (2):
> media: pci: add AVMatrix HWS capture driver
> MAINTAINERS: add entry for AVMatrix HWS driver
>
> MAINTAINERS | 6 +
> drivers/media/pci/Kconfig | 1 +
> drivers/media/pci/Makefile | 1 +
> drivers/media/pci/hws/Kconfig | 12 +
> drivers/media/pci/hws/Makefile | 4 +
> drivers/media/pci/hws/hws.h | 176 +++
> drivers/media/pci/hws/hws_irq.c | 271 +++++
> drivers/media/pci/hws/hws_irq.h | 10 +
> drivers/media/pci/hws/hws_pci.c | 864 +++++++++++++
> drivers/media/pci/hws/hws_reg.h | 144 +++
> drivers/media/pci/hws/hws_v4l2_ioctl.c | 778 ++++++++++++
> drivers/media/pci/hws/hws_v4l2_ioctl.h | 43 +
> drivers/media/pci/hws/hws_video.c | 1546 ++++++++++++++++++++++++
> drivers/media/pci/hws/hws_video.h | 29 +
> 14 files changed, 3885 insertions(+)
> create mode 100644 drivers/media/pci/hws/Kconfig
> create mode 100644 drivers/media/pci/hws/Makefile
> create mode 100644 drivers/media/pci/hws/hws.h
> create mode 100644 drivers/media/pci/hws/hws_irq.c
> create mode 100644 drivers/media/pci/hws/hws_irq.h
> create mode 100644 drivers/media/pci/hws/hws_pci.c
> create mode 100644 drivers/media/pci/hws/hws_reg.h
> create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.c
> create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.h
> create mode 100644 drivers/media/pci/hws/hws_video.c
> create mode 100644 drivers/media/pci/hws/hws_video.h
>
>
> base-commit: f0caa1d49cc07b30a7e2f104d3853ec6dc1c3cad
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 0/2] media: pci: add AVMatrix HWS capture driver
2026-03-18 0:10 ` [PATCH v2 0/2] media: pci: add AVMatrix HWS capture driver Ben Hoff
` (2 preceding siblings ...)
2026-03-24 9:19 ` [PATCH v2 0/2] media: pci: add AVMatrix HWS capture driver Hans Verkuil
@ 2026-03-30 19:56 ` hoff.benjamin.k
2026-03-30 19:56 ` [PATCH v3 1/2] " hoff.benjamin.k
2026-03-30 19:56 ` [PATCH v3 2/2] MAINTAINERS: add entry for AVMatrix HWS driver hoff.benjamin.k
3 siblings, 2 replies; 11+ messages in thread
From: hoff.benjamin.k @ 2026-03-30 19:56 UTC (permalink / raw)
To: linux-media; +Cc: linux-kernel, mchehab, hverkuil+cisco, Ben Hoff
From: Ben Hoff <hoff.benjamin.k@gmail.com>
Hi,
This series adds an in-tree AVMatrix HWS PCIe capture driver and a
matching MAINTAINERS entry.
Compared to v2, this revision makes mode-change handling explicit and
removes the previously unvalidated power-present reporting path.
Changes since v2:
- keep scratch DMA allocation on a single probe-owned path
- avoid double-freeing V4L2 control handlers on register unwind
- drop the extra per-node resolution sysfs ABI
- turn live geometry changes into explicit SOURCE_CHANGE renegotiation
- report live DV timings and reject attempts to retime a live source
- stop advertising RESOLUTION source changes for fps-only updates
- keep live fps state across harmless S_FMT restarts
- stop exposing an unvalidated DV RX power-present signal
- clean the imported sources for checkpatch and W=1 builds
Validation:
- make -C /lib/modules/$(uname -r)/build M=drivers/media/pci/hws W=1 CONFIG_VIDEO_HWS=m modules
- scripts/checkpatch.pl --strict --file drivers/media/pci/hws/*
- v4l2-compliance 1.32.0: 51 tests succeeded, 0 failed, 1 warning
The remaining v4l2-compliance warning is:
- V4L2_CID_DV_RX_POWER_PRESENT not found for input 0
DV_RX_POWER_PRESENT is intentionally left unsupported in this revision
because current hardware evidence does not expose a validated
receiver-side power-detect signal distinct from active video presence.
Ben Hoff (2):
media: pci: add AVMatrix HWS capture driver
MAINTAINERS: add entry for AVMatrix HWS driver
MAINTAINERS | 6 +
drivers/media/pci/Kconfig | 1 +
drivers/media/pci/Makefile | 1 +
drivers/media/pci/hws/Kconfig | 12 +
drivers/media/pci/hws/Makefile | 4 +
drivers/media/pci/hws/hws.h | 174 +++
drivers/media/pci/hws/hws_irq.c | 271 +++++
drivers/media/pci/hws/hws_irq.h | 10 +
drivers/media/pci/hws/hws_pci.c | 864 ++++++++++++++
drivers/media/pci/hws/hws_reg.h | 136 +++
drivers/media/pci/hws/hws_v4l2_ioctl.c | 924 +++++++++++++++
drivers/media/pci/hws/hws_v4l2_ioctl.h | 36 +
drivers/media/pci/hws/hws_video.c | 1504 ++++++++++++++++++++++++
drivers/media/pci/hws/hws_video.h | 29 +
14 files changed, 3972 insertions(+)
create mode 100644 drivers/media/pci/hws/Kconfig
create mode 100644 drivers/media/pci/hws/Makefile
create mode 100644 drivers/media/pci/hws/hws.h
create mode 100644 drivers/media/pci/hws/hws_irq.c
create mode 100644 drivers/media/pci/hws/hws_irq.h
create mode 100644 drivers/media/pci/hws/hws_pci.c
create mode 100644 drivers/media/pci/hws/hws_reg.h
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.c
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.h
create mode 100644 drivers/media/pci/hws/hws_video.c
create mode 100644 drivers/media/pci/hws/hws_video.h
--
2.53.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 1/2] media: pci: add AVMatrix HWS capture driver
2026-03-30 19:56 ` [PATCH v3 " hoff.benjamin.k
@ 2026-03-30 19:56 ` hoff.benjamin.k
2026-03-30 19:56 ` [PATCH v3 2/2] MAINTAINERS: add entry for AVMatrix HWS driver hoff.benjamin.k
1 sibling, 0 replies; 11+ messages in thread
From: hoff.benjamin.k @ 2026-03-30 19:56 UTC (permalink / raw)
To: linux-media; +Cc: linux-kernel, mchehab, hverkuil+cisco, Ben Hoff
From: Ben Hoff <hoff.benjamin.k@gmail.com>
Add an in-tree AVMatrix HWS PCIe capture driver. The driver supports
up to four HDMI inputs and exposes the video capture path through
V4L2 with vb2-dma-contig streaming, DV timings, and per-input
controls. Audio support is intentionally omitted from this
submission.
This driver is derived from a GPL out-of-tree driver.
Changes since v2:
- keep scratch DMA allocation on a single probe-owned path
- avoid double-freeing V4L2 control handlers on register unwind
- drop the extra per-node resolution sysfs ABI
- turn live geometry changes into explicit SOURCE_CHANGE renegotiation
- report live DV timings and reject attempts to retime a live source
- stop advertising RESOLUTION source changes for fps-only updates
- keep live fps state across harmless S_FMT restarts
- stop exposing an unvalidated DV RX power-present signal
- clean the imported sources for checkpatch and W=1 builds
Validation:
- make -C /lib/modules/$(uname -r)/build M=drivers/media/pci/hws W=1 CONFIG_VIDEO_HWS=m modules
- scripts/checkpatch.pl --strict --file drivers/media/pci/hws/*
- v4l2-compliance 1.32.0: 51 tests succeeded, 0 failed, 1 warning
Signed-off-by: Ben Hoff <hoff.benjamin.k@gmail.com>
---
drivers/media/pci/Kconfig | 1 +
drivers/media/pci/Makefile | 1 +
drivers/media/pci/hws/Kconfig | 12 +
drivers/media/pci/hws/Makefile | 4 +
drivers/media/pci/hws/hws.h | 174 +++
drivers/media/pci/hws/hws_irq.c | 271 +++++
drivers/media/pci/hws/hws_irq.h | 10 +
drivers/media/pci/hws/hws_pci.c | 864 ++++++++++++++
drivers/media/pci/hws/hws_reg.h | 136 +++
drivers/media/pci/hws/hws_v4l2_ioctl.c | 924 +++++++++++++++
drivers/media/pci/hws/hws_v4l2_ioctl.h | 36 +
drivers/media/pci/hws/hws_video.c | 1504 ++++++++++++++++++++++++
drivers/media/pci/hws/hws_video.h | 29 +
13 files changed, 3966 insertions(+)
create mode 100644 drivers/media/pci/hws/Kconfig
create mode 100644 drivers/media/pci/hws/Makefile
create mode 100644 drivers/media/pci/hws/hws.h
create mode 100644 drivers/media/pci/hws/hws_irq.c
create mode 100644 drivers/media/pci/hws/hws_irq.h
create mode 100644 drivers/media/pci/hws/hws_pci.c
create mode 100644 drivers/media/pci/hws/hws_reg.h
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.c
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.h
create mode 100644 drivers/media/pci/hws/hws_video.c
create mode 100644 drivers/media/pci/hws/hws_video.h
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index eebb16c58f3d..bfdb200f85a3 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -13,6 +13,7 @@ if MEDIA_PCI_SUPPORT
if MEDIA_CAMERA_SUPPORT
comment "Media capture support"
+source "drivers/media/pci/hws/Kconfig"
source "drivers/media/pci/mgb4/Kconfig"
source "drivers/media/pci/solo6x10/Kconfig"
source "drivers/media/pci/tw5864/Kconfig"
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index 02763ad88511..c4508b6723a9 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
obj-$(CONFIG_VIDEO_CX25821) += cx25821/
obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_DT3155) += dt3155/
+obj-$(CONFIG_VIDEO_HWS) += hws/
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
obj-$(CONFIG_VIDEO_MGB4) += mgb4/
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
diff --git a/drivers/media/pci/hws/Kconfig b/drivers/media/pci/hws/Kconfig
new file mode 100644
index 000000000000..b606d5ffadef
--- /dev/null
+++ b/drivers/media/pci/hws/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_HWS
+ tristate "AVMatrix HWS capture driver"
+ depends on VIDEO_DEV && PCI
+ select VIDEOBUF2_DMA_CONTIG
+ help
+ This is a Video4Linux2 driver for AVMatrix HWS PCIe capture cards.
+ It provides a PCIe capture interface with V4L2 streaming, DV timings,
+ and per-input controls for the supported HWS boards.
+
+ To compile this driver as a module, choose M here: the module will
+ be called hws.
diff --git a/drivers/media/pci/hws/Makefile b/drivers/media/pci/hws/Makefile
new file mode 100644
index 000000000000..a66aebd348e5
--- /dev/null
+++ b/drivers/media/pci/hws/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+hws-objs := hws_pci.o hws_irq.o hws_video.o hws_v4l2_ioctl.o
+
+obj-$(CONFIG_VIDEO_HWS) += hws.o
diff --git a/drivers/media/pci/hws/hws.h b/drivers/media/pci/hws/hws.h
new file mode 100644
index 000000000000..ebc8cc0daf36
--- /dev/null
+++ b/drivers/media/pci/hws/hws.h
@@ -0,0 +1,174 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_PCIE_H
+#define HWS_PCIE_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/sizes.h>
+#include <linux/atomic.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/videobuf2-dma-sg.h>
+
+#include "hws_reg.h"
+
+struct hwsmem_param {
+ u32 index;
+ u32 type;
+ u32 status;
+};
+
+struct hws_pix_state {
+ u32 width;
+ u32 height;
+ u32 fourcc; /* V4L2_PIX_FMT_* (YUYV only here) */
+ u32 bytesperline; /* stride */
+ u32 sizeimage; /* full frame */
+ enum v4l2_field field; /* V4L2_FIELD_NONE or INTERLACED */
+ enum v4l2_colorspace colorspace; /* e.g., REC709 */
+ enum v4l2_ycbcr_encoding ycbcr_enc; /* V4L2_YCBCR_ENC_DEFAULT */
+ enum v4l2_quantization quantization; /* V4L2_QUANTIZATION_LIM_RANGE */
+ enum v4l2_xfer_func xfer_func; /* V4L2_XFER_FUNC_DEFAULT */
+ bool interlaced; /* cached hardware state */
+ u32 half_size; /* optional: if your HW needs it */
+};
+
+#define UNSET (-1U)
+
+struct hws_pcie_dev;
+struct hws_adapter;
+struct hws_video;
+
+struct hwsvideo_buffer {
+ struct vb2_v4l2_buffer vb;
+ struct list_head list;
+ int slot; /* for two-buffer approach */
+};
+
+struct hws_video {
+ /* ───── linkage ───── */
+ struct hws_pcie_dev *parent; /* parent device */
+ struct video_device *video_device;
+
+ struct vb2_queue buffer_queue;
+ struct list_head capture_queue;
+ struct hwsvideo_buffer *active;
+ struct hwsvideo_buffer *next_prepared;
+
+ /* ───── locking ───── */
+ struct mutex state_lock; /* primary state */
+ spinlock_t irq_lock; /* ISR-side */
+
+ /* ───── indices ───── */
+ int channel_index;
+
+ /* ───── colour controls ───── */
+ int current_brightness;
+ int current_contrast;
+ int current_saturation;
+ int current_hue;
+
+ /* ───── V4L2 controls ───── */
+ struct v4l2_ctrl_handler control_handler;
+ struct v4l2_ctrl *ctrl_brightness;
+ struct v4l2_ctrl *ctrl_contrast;
+ struct v4l2_ctrl *ctrl_saturation;
+ struct v4l2_ctrl *ctrl_hue;
+ /* ───── capture queue status ───── */
+ struct hws_pix_state pix;
+ struct v4l2_dv_timings cur_dv_timings; /* last configured/notified DV timings */
+ u32 current_fps; /* Hz, updated by mode changes, not by read-only queries */
+ u32 alloc_sizeimage;
+
+ /* ───── per-channel capture state ───── */
+ bool cap_active;
+ bool stop_requested;
+ u8 last_buf_half_toggle;
+ bool half_seen;
+ atomic_t sequence_number;
+ u32 queued_count;
+
+ /* ───── timeout and error handling ───── */
+ u32 timeout_count;
+ u32 error_count;
+
+ bool window_valid;
+ u32 last_dma_hi;
+ u32 last_dma_page;
+ u32 last_pci_addr;
+ u32 last_half16;
+
+ /* ───── misc counters ───── */
+ int signal_loss_cnt;
+};
+
+static inline void hws_set_current_dv_timings(struct hws_video *vid,
+ u32 width, u32 height,
+ bool interlaced)
+{
+ if (!vid)
+ return;
+
+ vid->cur_dv_timings = (struct v4l2_dv_timings) {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = width,
+ .height = height,
+ .interlaced = interlaced,
+ },
+ };
+}
+
+struct hws_scratch_dma {
+ void *cpu;
+ dma_addr_t dma;
+ size_t size;
+};
+
+struct hws_pcie_dev {
+ /* ───── core objects ───── */
+ struct pci_dev *pdev;
+ struct hws_video video[MAX_VID_CHANNELS];
+
+ /* ───── BAR & workqueues ───── */
+ void __iomem *bar0_base;
+
+ /* ───── device identity / capabilities ───── */
+ u16 vendor_id;
+ u16 device_id;
+ u16 device_ver;
+ u16 hw_ver;
+ u32 sub_ver;
+ u32 port_id;
+ // TriState, used in `set_video_format_size`
+ u32 support_yv12;
+ u32 max_hw_video_buf_sz;
+ u8 max_channels;
+ u8 cur_max_video_ch;
+ bool start_run;
+
+ bool buf_allocated;
+
+ /* ───── V4L2 framework objects ───── */
+ struct v4l2_device v4l2_device;
+
+ /* ───── kernel thread ───── */
+ struct task_struct *main_task;
+ struct hws_scratch_dma scratch_vid[MAX_VID_CHANNELS];
+
+ bool suspended;
+ int irq;
+
+ /* ───── error flags ───── */
+ int pci_lost;
+
+};
+
+#endif
diff --git a/drivers/media/pci/hws/hws_irq.c b/drivers/media/pci/hws/hws_irq.c
new file mode 100644
index 000000000000..0747dfb7ab97
--- /dev/null
+++ b/drivers/media/pci/hws/hws_irq.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/compiler.h>
+#include <linux/moduleparam.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/minmax.h>
+#include <linux/string.h>
+
+#include <media/videobuf2-dma-contig.h>
+
+#include "hws_irq.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws.h"
+
+#define MAX_INT_LOOPS 100
+
+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 = &hws->video[ch];
+ unsigned long flags;
+ struct hwsvideo_buffer *buf;
+
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): stop=%d cap=%d queued=%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=%u): suspended\n", ch);
+ return -EBUSY;
+ }
+
+ if (READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active)) {
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): stop=%d cap=%d -> cancel\n", ch,
+ v->stop_requested, v->cap_active);
+ return -ECANCELED;
+ }
+
+ 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=%u): queue empty\n", ch);
+ return -EAGAIN;
+ }
+
+ buf = list_first_entry(&v->capture_queue, struct hwsvideo_buffer, list);
+ list_del_init(&buf->list); /* keep buffer safe for later cleanup */
+ if (v->queued_count)
+ v->queued_count--;
+ v->active = buf;
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ dev_dbg(&hws->pdev->dev, "arm_next(ch=%u): picked buffer %p\n", ch,
+ buf);
+
+ /* Publish descriptor(s) before doorbell/MMIO kicks. */
+ wmb();
+
+ /* Avoid MMIO during suspend */
+ if (READ_ONCE(hws->suspended)) {
+ unsigned long f;
+
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): suspended after pick\n", ch);
+ spin_lock_irqsave(&v->irq_lock, f);
+ if (v->active) {
+ list_add(&buf->list, &v->capture_queue);
+ v->queued_count++;
+ v->active = NULL;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, f);
+ return -EBUSY;
+ }
+
+ /* Also program the DMA address register directly */
+ {
+ dma_addr_t dma_addr =
+ vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(hws, ch, dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base + HWS_REG_DMA_ADDR(ch));
+ }
+
+ dev_dbg(&hws->pdev->dev, "arm_next(ch=%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);
+ return 0;
+}
+
+static void hws_video_handle_vdone(struct hws_video *v)
+{
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned int ch = v->channel_index;
+ struct hwsvideo_buffer *done;
+ unsigned long flags;
+ bool promoted = false;
+
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): stop=%d cap=%d active=%p\n",
+ ch, READ_ONCE(v->stop_requested), READ_ONCE(v->cap_active),
+ v->active);
+
+ int ret;
+
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): entry stop=%d cap=%d\n", ch,
+ v->stop_requested, v->cap_active);
+ if (READ_ONCE(hws->suspended))
+ return;
+
+ if (READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active))
+ return;
+
+ spin_lock_irqsave(&v->irq_lock, flags);
+ done = v->active;
+ if (done && v->next_prepared) {
+ v->active = v->next_prepared;
+ v->next_prepared = NULL;
+ promoted = true;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* 1) Complete the buffer the HW just finished (if any) */
+ if (done) {
+ struct vb2_v4l2_buffer *vb2v = &done->vb;
+ size_t expected = v->pix.sizeimage;
+ size_t plane_size = vb2_plane_size(&vb2v->vb2_buf, 0);
+
+ if (expected > plane_size) {
+ dev_warn_ratelimited(&hws->pdev->dev,
+ "bh_video(ch=%u): sizeimage %zu > plane %zu, dropping seq=%u\n",
+ ch, expected, plane_size,
+ (u32)atomic_read(&v->sequence_number) + 1);
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_ERROR);
+ goto arm_next;
+ }
+ vb2_set_plane_payload(&vb2v->vb2_buf, 0, expected);
+
+ dma_rmb(); /* device writes visible before userspace sees it */
+
+ vb2v->sequence = (u32)atomic_inc_return(&v->sequence_number);
+ vb2v->vb2_buf.timestamp = ktime_get_ns();
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): DONE buf=%p seq=%u half_seen=%d toggle=%u\n",
+ ch, done, vb2v->sequence, v->half_seen,
+ v->last_buf_half_toggle);
+
+ if (!promoted)
+ v->active = NULL; /* channel no longer owns this buffer */
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+
+ if (READ_ONCE(hws->suspended))
+ return;
+
+ if (promoted) {
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): promoted pre-armed buffer active=%p\n",
+ ch, v->active);
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_prime_next_locked(v);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ return;
+ }
+
+arm_next:
+ /* 2) Immediately arm the next queued buffer (if present) */
+ ret = hws_arm_next(hws, ch);
+ if (ret == -EAGAIN) {
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): no queued buffer to arm\n", ch);
+ return;
+ }
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): armed next buffer, active=%p\n", ch,
+ v->active);
+ /* On success the engine now points at v->active’s DMA address */
+}
+
+irqreturn_t hws_irq_handler(int irq, void *info)
+{
+ struct hws_pcie_dev *pdx = info;
+ u32 int_state;
+
+ dev_dbg(&pdx->pdev->dev, "irq: entry\n");
+ if (pdx->bar0_base) {
+ dev_dbg(&pdx->pdev->dev,
+ "irq: INT_EN=0x%08x INT_STATUS=0x%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 = 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;
+ }
+ // u32 sys_status = readl(pdx->bar0_base + HWS_REG_SYS_STATUS);
+
+ int_state = readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ if (!int_state || int_state == 0xFFFFFFFF) {
+ dev_dbg(&pdx->pdev->dev,
+ "irq: spurious or device-gone int_state=0x%08x\n",
+ int_state);
+ return IRQ_NONE;
+ }
+ dev_dbg(&pdx->pdev->dev, "irq: entry INT_STATUS=0x%08x\n", int_state);
+
+ /* Loop until all pending bits are serviced (max 100 iterations) */
+ for (u32 cnt = 0; int_state && cnt < MAX_INT_LOOPS; ++cnt) {
+ for (unsigned int ch = 0; ch < pdx->cur_max_video_ch; ++ch) {
+ u32 vbit = HWS_INT_VDONE_BIT(ch);
+
+ if (!(int_state & vbit))
+ continue;
+
+ if (READ_ONCE(pdx->video[ch].cap_active) &&
+ !READ_ONCE(pdx->video[ch].stop_requested)) {
+ if (hws_toggle_debug) {
+ u32 toggle =
+ 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=%u toggle=%u handling inline (cap=%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=%u ignored (cap=%d stop=%d)\n",
+ ch,
+ READ_ONCE(pdx->video[ch].cap_active),
+ READ_ONCE(pdx->video[ch].stop_requested));
+ }
+
+ writel(vbit, pdx->bar0_base + HWS_REG_INT_STATUS);
+ (void)readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ /* Re‐read in case new interrupt bits popped while processing */
+ int_state = readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ dev_dbg(&pdx->pdev->dev,
+ "irq: loop cnt=%u new INT_STATUS=0x%08x\n", cnt,
+ int_state);
+ if (cnt + 1 == MAX_INT_LOOPS)
+ dev_warn_ratelimited(&pdx->pdev->dev,
+ "IRQ storm? status=0x%08x\n",
+ int_state);
+ }
+
+ return IRQ_HANDLED;
+}
diff --git a/drivers/media/pci/hws/hws_irq.h b/drivers/media/pci/hws/hws_irq.h
new file mode 100644
index 000000000000..a42867aa0c46
--- /dev/null
+++ b/drivers/media/pci/hws/hws_irq.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_INTERRUPT_H
+#define HWS_INTERRUPT_H
+
+#include <linux/pci.h>
+#include "hws.h"
+
+irqreturn_t hws_irq_handler(int irq, void *info);
+
+#endif /* HWS_INTERRUPT_H */
diff --git a/drivers/media/pci/hws/hws_pci.c b/drivers/media/pci/hws/hws_pci.c
new file mode 100644
index 000000000000..d926a88b35da
--- /dev/null
+++ b/drivers/media/pci/hws/hws_pci.c
@@ -0,0 +1,864 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/iopoll.h>
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/ktime.h>
+#include <linux/pm.h>
+#include <linux/freezer.h>
+#include <linux/pci_regs.h>
+
+#include <media/v4l2-ctrls.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_irq.h"
+#include "hws_v4l2_ioctl.h"
+
+#define DRV_NAME "hws"
+#define HWS_BUSY_POLL_DELAY_US 10
+#define HWS_BUSY_POLL_TIMEOUT_US 1000000
+
+/* register layout inside HWS_REG_DEVICE_INFO */
+#define DEVINFO_VER GENMASK(7, 0)
+#define DEVINFO_SUBVER GENMASK(15, 8)
+#define DEVINFO_YV12 GENMASK(31, 28)
+#define DEVINFO_HWKEY GENMASK(27, 24)
+#define DEVINFO_PORTID GENMASK(25, 24) /* low 2 bits of HW-key */
+
+#define MAKE_ENTRY(__vend, __chip, __subven, __subdev, __configptr) \
+ { .vendor = (__vend), \
+ .device = (__chip), \
+ .subvendor = (__subven), \
+ .subdevice = (__subdev), \
+ .driver_data = (unsigned long)(__configptr) }
+
+/*
+ * PCI IDs for HWS family cards.
+ *
+ * The subsystem IDs are fixed at 0x8888:0x0007 for this family. Some boards
+ * enumerate with vendor ID 0x8888 or 0x1f33. Exact SKU names are not fully
+ * pinned down yet; update these comments when vendor documentation or INF
+ * strings are available.
+ */
+static const struct pci_device_id hws_pci_table[] = {
+ /* HWS family, SKU unknown. */
+ MAKE_ENTRY(0x8888, 0x9534, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x8534, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x8554, 0x8888, 0x0007, NULL),
+
+ /* HWS 2x2 HDMI family. */
+ MAKE_ENTRY(0x8888, 0x8524, 0x8888, 0x0007, NULL),
+ /* HWS 2x2 SDI family. */
+ MAKE_ENTRY(0x1F33, 0x6524, 0x8888, 0x0007, NULL),
+
+ /* HWS X4 HDMI family. */
+ MAKE_ENTRY(0x8888, 0x8504, 0x8888, 0x0007, NULL),
+ /* HWS X4 SDI family. */
+ MAKE_ENTRY(0x8888, 0x6504, 0x8888, 0x0007, NULL),
+
+ /* HWS family, SKU unknown. */
+ MAKE_ENTRY(0x8888, 0x8532, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x8888, 0x8512, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x8888, 0x8501, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x6502, 0x8888, 0x0007, NULL),
+
+ /* HWS X4 HDMI family (alternate vendor ID). */
+ MAKE_ENTRY(0x1F33, 0x8504, 0x8888, 0x0007, NULL),
+ /* HWS 2x2 HDMI family (alternate vendor ID). */
+ MAKE_ENTRY(0x1F33, 0x8524, 0x8888, 0x0007, NULL),
+
+ {}
+};
+
+static void enable_pcie_relaxed_ordering(struct pci_dev *dev)
+{
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
+}
+
+static void hws_configure_hardware_capabilities(struct hws_pcie_dev *hdev)
+{
+ u16 id = hdev->device_id;
+
+ /* select per-chip channel counts */
+ switch (id) {
+ case 0x9534:
+ case 0x6524:
+ case 0x8524:
+ case 0x8504:
+ case 0x6504:
+ hdev->cur_max_video_ch = 4;
+ break;
+ case 0x8532:
+ hdev->cur_max_video_ch = 2;
+ break;
+ case 0x8512:
+ case 0x6502:
+ hdev->cur_max_video_ch = 2;
+ break;
+ case 0x8501:
+ hdev->cur_max_video_ch = 1;
+ break;
+ default:
+ hdev->cur_max_video_ch = 4;
+ break;
+ }
+
+ /* universal buffer capacity */
+ hdev->max_hw_video_buf_sz = MAX_MM_VIDEO_SIZE;
+
+ /* decide hardware-version and program DMA max size if needed */
+ if (hdev->device_ver > 121) {
+ if (id == 0x8501 && hdev->device_ver == 122) {
+ hdev->hw_ver = 0;
+ } else {
+ hdev->hw_ver = 1;
+ u32 dma_max = (u32)(MAX_VIDEO_SCALER_SIZE / 16);
+
+ writel(dma_max, hdev->bar0_base + HWS_REG_DMA_MAX_SIZE);
+ /* readback to flush posted MMIO write */
+ (void)readl(hdev->bar0_base + HWS_REG_DMA_MAX_SIZE);
+ }
+ } else {
+ hdev->hw_ver = 0;
+ }
+}
+
+static void hws_stop_device(struct hws_pcie_dev *hws);
+
+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 = &hws->pdev->dev;
+ if (!hws->bar0_base) {
+ dev_dbg(dev,
+ "lifecycle:%s:%s bar0-unmapped suspended=%d start_run=%d pci_lost=%d irq=%d\n",
+ action, phase, READ_ONCE(hws->suspended), hws->start_run,
+ hws->pci_lost, hws->irq);
+ return;
+ }
+
+ int_en = readl(hws->bar0_base + INT_EN_REG_BASE);
+ int_status = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ vcap = readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ sys_status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+ dec_mode = readl(hws->bar0_base + HWS_REG_DEC_MODE);
+
+ dev_dbg(dev,
+ "lifecycle:%s:%s suspended=%d start_run=%d pci_lost=%d irq=%d INT_EN=0x%08x INT_STATUS=0x%08x VCAP=0x%08x SYS=0x%08x DEC=0x%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;
+ /* mirror PCI IDs for later switches */
+ hdev->device_id = hdev->pdev->device;
+ hdev->vendor_id = hdev->pdev->vendor;
+
+ reg = readl(hdev->bar0_base + HWS_REG_DEVICE_INFO);
+
+ hdev->device_ver = FIELD_GET(DEVINFO_VER, reg);
+ hdev->sub_ver = FIELD_GET(DEVINFO_SUBVER, reg);
+ hdev->support_yv12 = FIELD_GET(DEVINFO_YV12, reg);
+ hdev->port_id = FIELD_GET(DEVINFO_PORTID, reg);
+
+ hdev->max_hw_video_buf_sz = MAX_MM_VIDEO_SIZE;
+ hdev->max_channels = 4;
+ hdev->buf_allocated = false;
+ hdev->main_task = NULL;
+ hdev->start_run = false;
+ hdev->pci_lost = 0;
+
+ writel(0x00, hdev->bar0_base + HWS_REG_DEC_MODE);
+ writel(0x10, hdev->bar0_base + HWS_REG_DEC_MODE);
+
+ hws_configure_hardware_capabilities(hdev);
+
+ dev_info(&hdev->pdev->dev,
+ "chip detected: ver=%u subver=%u port=%u yv12=%u\n",
+ hdev->device_ver, hdev->sub_ver, hdev->port_id,
+ hdev->support_yv12);
+
+ return 0;
+}
+
+static int main_ks_thread_handle(void *data)
+{
+ struct hws_pcie_dev *pdx = data;
+
+ set_freezable();
+
+ while (!kthread_should_stop()) {
+ /* If we’re suspending, don’t touch hardware; just sleep/freeeze */
+ if (READ_ONCE(pdx->suspended)) {
+ try_to_freeze();
+ schedule_timeout_interruptible(msecs_to_jiffies(1000));
+ continue;
+ }
+
+ /* avoid MMIO when suspended (guarded above) */
+ check_video_format(pdx);
+
+ try_to_freeze(); /* cooperate with freezer each loop */
+
+ /* Sleep 1s or until signaled to wake/stop */
+ schedule_timeout_interruptible(msecs_to_jiffies(1000));
+ }
+
+ dev_dbg(&pdx->pdev->dev, "%s: exiting\n", __func__);
+ return 0;
+}
+
+static void hws_stop_kthread_action(void *data)
+{
+ struct hws_pcie_dev *hws = data;
+ struct task_struct *t;
+ u64 start_ns;
+
+ if (!hws)
+ return;
+
+ t = READ_ONCE(hws->main_task);
+ if (!IS_ERR_OR_NULL(t)) {
+ start_ns = ktime_get_mono_fast_ns();
+ dev_dbg(&hws->pdev->dev,
+ "lifecycle:kthread-stop:begin task=%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",
+ (unsigned long long)
+ ((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ }
+}
+
+static int hws_alloc_seed_buffers(struct hws_pcie_dev *hws)
+{
+ int ch;
+ /* 64 KiB is plenty for a safe dummy; align to 64 for your HW */
+ const size_t need = ALIGN(64 * 1024, 64);
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+#if defined(CONFIG_HAS_DMA) /* normal on PCIe platforms */
+ void *cpu = dma_alloc_coherent(&hws->pdev->dev, need,
+ &hws->scratch_vid[ch].dma,
+ GFP_KERNEL);
+#else
+ void *cpu = NULL;
+#endif
+ if (!cpu) {
+ dev_warn(&hws->pdev->dev,
+ "scratch: dma_alloc_coherent failed ch=%d\n", ch);
+ /* not fatal: free earlier ones and continue without seeding */
+ while (--ch >= 0) {
+ if (hws->scratch_vid[ch].cpu)
+ dma_free_coherent(&hws->pdev->dev,
+ hws->scratch_vid[ch].size,
+ hws->scratch_vid[ch].cpu,
+ hws->scratch_vid[ch].dma);
+ hws->scratch_vid[ch].cpu = NULL;
+ hws->scratch_vid[ch].size = 0;
+ }
+ return -ENOMEM;
+ }
+ hws->scratch_vid[ch].cpu = cpu;
+ hws->scratch_vid[ch].size = need;
+ }
+ return 0;
+}
+
+static void hws_free_seed_buffers(struct hws_pcie_dev *hws)
+{
+ int ch;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+ if (hws->scratch_vid[ch].cpu) {
+ dma_free_coherent(&hws->pdev->dev,
+ hws->scratch_vid[ch].size,
+ hws->scratch_vid[ch].cpu,
+ hws->scratch_vid[ch].dma);
+ hws->scratch_vid[ch].cpu = NULL;
+ hws->scratch_vid[ch].size = 0;
+ }
+ }
+}
+
+static void hws_seed_channel(struct hws_pcie_dev *hws, int ch)
+{
+ dma_addr_t paddr = hws->scratch_vid[ch].dma;
+ u32 lo = lower_32_bits(paddr);
+ u32 hi = upper_32_bits(paddr);
+ u32 pci_addr = lo & PCI_E_BAR_ADD_LOWMASK;
+
+ lo &= PCI_E_BAR_ADD_MASK;
+
+ /* Program 64-bit BAR remap entry for this channel (table @ 0x208 + ch * 8) */
+ writel_relaxed(hi, hws->bar0_base +
+ PCI_ADDR_TABLE_BASE + 0x208 + ch * 8);
+ writel_relaxed(lo, hws->bar0_base +
+ PCI_ADDR_TABLE_BASE + 0x208 + ch * 8 +
+ PCIE_BARADDROFSIZE);
+
+ /* Program capture engine per-channel base/half */
+ writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
+ hws->bar0_base + CVBS_IN_BUF_BASE +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* half size: use either the current format’s half or half of scratch */
+ {
+ u32 half = hws->video[ch].pix.half_size ?
+ hws->video[ch].pix.half_size :
+ (u32)(hws->scratch_vid[ch].size / 2);
+
+ writel_relaxed(half / 16,
+ hws->bar0_base + CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+ }
+
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS); /* flush posted writes */
+}
+
+static void hws_seed_all_channels(struct hws_pcie_dev *hws)
+{
+ int ch;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+ if (hws->scratch_vid[ch].cpu)
+ hws_seed_channel(hws, ch);
+ }
+}
+
+static void hws_irq_mask_gate(struct hws_pcie_dev *hws)
+{
+ writel(0x00000000, hws->bar0_base + INT_EN_REG_BASE);
+ (void)readl(hws->bar0_base + INT_EN_REG_BASE);
+}
+
+static void hws_irq_unmask_gate(struct hws_pcie_dev *hws)
+{
+ writel(HWS_INT_EN_MASK, hws->bar0_base + INT_EN_REG_BASE);
+ (void)readl(hws->bar0_base + INT_EN_REG_BASE);
+}
+
+static void hws_irq_clear_pending(struct hws_pcie_dev *hws)
+{
+ u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+
+ if (st) {
+ writel(st, hws->bar0_base + HWS_REG_INT_STATUS); /* W1C */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+}
+
+static void hws_block_hotpaths(struct hws_pcie_dev *hws)
+{
+ WRITE_ONCE(hws->suspended, true);
+ if (hws->irq >= 0)
+ disable_irq(hws->irq);
+
+ if (!hws->bar0_base)
+ return;
+
+ hws_irq_mask_gate(hws);
+ hws_irq_clear_pending(hws);
+}
+
+static int hws_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+ struct hws_pcie_dev *hws;
+ int i, ret, irq;
+ unsigned long irqf = 0;
+ bool v4l2_registered = false;
+
+ /* devres-backed device object */
+ hws = devm_kzalloc(&pdev->dev, sizeof(*hws), GFP_KERNEL);
+ if (!hws)
+ return -ENOMEM;
+
+ hws->pdev = pdev;
+ hws->irq = -1;
+ hws->suspended = false;
+ pci_set_drvdata(pdev, hws);
+
+ /* 1) Enable device + bus mastering (managed) */
+ ret = pcim_enable_device(pdev);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "pcim_enable_device\n");
+ pci_set_master(pdev);
+
+ /* 2) Map BAR0 (managed) */
+ ret = pcim_iomap_regions(pdev, BIT(0), KBUILD_MODNAME);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "pcim_iomap_regions BAR0\n");
+ hws->bar0_base = pcim_iomap_table(pdev)[0];
+
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+ if (ret) {
+ dev_warn(&pdev->dev,
+ "64-bit DMA mask unavailable, falling back to 32-bit (%d)\n",
+ ret);
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ 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");
+ }
+
+ /* 3) Optional PCIe tuning (same as before) */
+ enable_pcie_relaxed_ordering(pdev);
+#ifdef CONFIG_ARCH_TI816X
+ pcie_set_readrq(pdev, 128);
+#endif
+
+ /* 4) Identify chip & capabilities */
+ read_chip_id(hws);
+ dev_info(&pdev->dev, "Device VID=0x%04x DID=0x%04x\n",
+ pdev->vendor, pdev->device);
+ hws_init_video_sys(hws, false);
+
+ /* 5) Init channels (video state, locks, vb2, ctrls) */
+ for (i = 0; i < hws->max_channels; i++) {
+ ret = hws_video_init_channel(hws, i);
+ if (ret) {
+ dev_err(&pdev->dev, "video channel init failed (ch=%d)\n", i);
+ goto err_unwind_channels;
+ }
+ }
+
+ /* 6) Allocate scratch DMA and seed BAR table + channel base/half (legacy SetDMAAddress) */
+ ret = hws_alloc_seed_buffers(hws);
+ if (!ret)
+ hws_seed_all_channels(hws);
+
+ /* 7) Start-run sequence (like InitVideoSys) */
+ hws_init_video_sys(hws, false);
+
+ /* A) Force legacy INTx; legacy used request_irq(pdev->irq, ..., IRQF_SHARED) */
+ pci_intx(pdev, 1);
+ irqf = IRQF_SHARED;
+ irq = pdev->irq;
+ hws->irq = irq;
+ dev_info(&pdev->dev, "IRQ mode: legacy INTx (shared), irq=%d\n", irq);
+
+ /* B) Mask the device's global/bridge gate (INT_EN_REG_BASE) */
+ hws_irq_mask_gate(hws);
+
+ /* C) Clear any sticky pending interrupt status (W1C) before we arm the line */
+ hws_irq_clear_pending(hws);
+
+ /* D) Request the legacy shared interrupt line (no vectors/MSI/MSI-X) */
+ ret = devm_request_irq(&pdev->dev, irq, hws_irq_handler, irqf,
+ dev_name(&pdev->dev), hws);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq(%d) failed: %d\n", irq, ret);
+ goto err_unwind_channels;
+ }
+
+ /* E) Set the global interrupt enable bit in main control register */
+ {
+ u32 ctl_reg = readl(hws->bar0_base + HWS_REG_CTL);
+
+ ctl_reg |= 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");
+ }
+
+ /* F) Open the global gate just like legacy did */
+ hws_irq_unmask_gate(hws);
+ dev_info(&pdev->dev, "INT_EN_GATE readback=0x%08x\n",
+ readl(hws->bar0_base + INT_EN_REG_BASE));
+
+ /* 11) Register V4L2 */
+ ret = hws_video_register(hws);
+ if (ret) {
+ dev_err(&pdev->dev, "video_register: %d\n", ret);
+ goto err_unwind_channels;
+ }
+ v4l2_registered = true;
+
+ /* 12) Background monitor thread (managed) */
+ hws->main_task = kthread_run(main_ks_thread_handle, hws, "hws-mon");
+ if (IS_ERR(hws->main_task)) {
+ ret = PTR_ERR(hws->main_task);
+ hws->main_task = NULL;
+ dev_err(&pdev->dev, "kthread_run: %d\n", ret);
+ goto err_unregister_va;
+ }
+ ret = devm_add_action_or_reset(&pdev->dev, hws_stop_kthread_action, hws);
+ if (ret) {
+ dev_err(&pdev->dev, "devm_add_action kthread_stop: %d\n", ret);
+ goto err_unregister_va; /* reset already stopped the thread */
+ }
+
+ /* 13) Final: show the line is armed */
+ dev_info(&pdev->dev, "irq handler installed on irq=%d\n", irq);
+ return 0;
+
+err_unregister_va:
+ hws_stop_device(hws);
+ hws_video_unregister(hws);
+ hws_free_seed_buffers(hws);
+ return ret;
+err_unwind_channels:
+ hws_free_seed_buffers(hws);
+ if (!v4l2_registered) {
+ while (--i >= 0)
+ hws_video_cleanup_channel(hws, i);
+ }
+ return ret;
+}
+
+static int hws_check_busy(struct hws_pcie_dev *pdx)
+{
+ void __iomem *reg = pdx->bar0_base + HWS_REG_SYS_STATUS;
+ u32 val;
+ int ret;
+
+ /* poll until !(val & BUSY_BIT), sleeping HWS_BUSY_POLL_DELAY_US between reads */
+ ret = readl_poll_timeout(reg, val, !(val & HWS_SYS_DMA_BUSY_BIT),
+ HWS_BUSY_POLL_DELAY_US,
+ HWS_BUSY_POLL_TIMEOUT_US);
+ if (ret) {
+ dev_err(&pdx->pdev->dev,
+ "SYS_STATUS busy bit never cleared (0x%08x)\n", val);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static void hws_stop_dsp(struct hws_pcie_dev *hws)
+{
+ u32 status;
+
+ /* Read the decoder mode/status register */
+ status = readl(hws->bar0_base + HWS_REG_DEC_MODE);
+ dev_dbg(&hws->pdev->dev, "%s: status=0x%08x\n", __func__, status);
+
+ /* If the device looks unplugged/stuck, bail out */
+ if (status == 0xFFFFFFFF)
+ return;
+
+ /* Tell the DSP to stop */
+ writel(0x10, hws->bar0_base + HWS_REG_DEC_MODE);
+
+ if (hws_check_busy(hws))
+ dev_warn(&hws->pdev->dev, "DSP busy timeout on stop\n");
+ /* Disable video capture engine in the DSP */
+ writel(0x0, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+}
+
+/* Publish stop so ISR/BH won’t touch video buffers anymore. */
+static void hws_publish_stop_flags(struct hws_pcie_dev *hws)
+{
+ unsigned int i;
+
+ for (i = 0; i < hws->cur_max_video_ch; ++i) {
+ struct hws_video *v = &hws->video[i];
+
+ WRITE_ONCE(v->cap_active, false);
+ WRITE_ONCE(v->stop_requested, true);
+ }
+
+ smp_wmb(); /* make flags visible before we touch MMIO/queues */
+}
+
+/* Drain engines + ISR/BH after flags are published. */
+static void hws_drain_after_stop(struct hws_pcie_dev *hws)
+{
+ u32 ackmask = 0;
+ unsigned int i;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ /* Mask device enables: no new DMA starts. */
+ writel(0x0, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS); /* flush */
+
+ /* Let any in-flight DMAs finish (best-effort). */
+ (void)hws_check_busy(hws);
+
+ /* Ack any latched VDONE. */
+ for (i = 0; i < hws->cur_max_video_ch; ++i)
+ ackmask |= HWS_INT_VDONE_BIT(i);
+ if (ackmask) {
+ writel(ackmask, hws->bar0_base + HWS_REG_INT_STATUS);
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ /* Ensure no hard IRQ is still running. */
+ if (hws->irq >= 0)
+ synchronize_irq(hws->irq);
+
+ dev_dbg(&hws->pdev->dev, "lifecycle:drain-after-stop:done (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+}
+
+static void hws_stop_device(struct hws_pcie_dev *hws)
+{
+ u32 status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+ u64 start_ns = ktime_get_mono_fast_ns();
+ bool live = status != 0xFFFFFFFF;
+
+ dev_dbg(&hws->pdev->dev, "%s: status=0x%08x\n", __func__, status);
+ if (!live) {
+ hws->pci_lost = true;
+ goto out;
+ }
+ hws_log_lifecycle_snapshot(hws, "stop-device", "begin");
+
+ /* Make ISR/BH a no-op, then drain engines/IRQ. */
+ hws_publish_stop_flags(hws);
+ hws_drain_after_stop(hws);
+
+ /* 1) Stop the on-board DSP */
+ hws_stop_dsp(hws);
+
+out:
+ hws->start_run = 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",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ dev_dbg(&hws->pdev->dev, "%s: complete\n", __func__);
+}
+
+static int hws_quiesce_for_transition(struct hws_pcie_dev *hws,
+ const char *action,
+ bool stop_thread)
+{
+ struct device *dev = &hws->pdev->dev;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+ int vret;
+
+ hws_log_lifecycle_snapshot(hws, action, "begin");
+
+ step_ns = ktime_get_mono_fast_ns();
+ hws_block_hotpaths(hws);
+ dev_dbg(dev, "lifecycle:%s:block-hotpaths (%lluus)\n", action,
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ hws_log_lifecycle_snapshot(hws, action, "blocked");
+
+ if (stop_thread) {
+ step_ns = ktime_get_mono_fast_ns();
+ hws_stop_kthread_action(hws);
+ dev_dbg(dev, "lifecycle:%s:stop-kthread (%lluus)\n", action,
+ (unsigned long long)
+ ((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ }
+
+ step_ns = ktime_get_mono_fast_ns();
+ vret = hws_video_quiesce(hws, action);
+ dev_dbg(dev, "lifecycle:%s:video-quiesce ret=%d (%lluus)\n", action,
+ vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ if (vret)
+ dev_warn(dev, "lifecycle:%s video quiesce returned %d\n",
+ action, vret);
+
+ step_ns = ktime_get_mono_fast_ns();
+ hws_stop_device(hws);
+ dev_dbg(dev, "lifecycle:%s:stop-device (%lluus)\n", action,
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ hws_log_lifecycle_snapshot(hws, action, "end");
+ dev_dbg(dev, "lifecycle:%s:quiesce-done ret=%d (%lluus)\n", action,
+ vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+
+ return vret;
+}
+
+static void hws_remove(struct pci_dev *pdev)
+{
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ u64 start_ns;
+
+ if (!hws)
+ return;
+
+ start_ns = 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);
+
+ /* Stop hardware / capture cleanly (your helper) */
+ hws_stop_device(hws);
+
+ /* Unregister subsystems you registered */
+ hws_video_unregister(hws);
+
+ /* Release seeded DMA buffers */
+ hws_free_seed_buffers(hws);
+ /* kthread is stopped by the devm action you added in probe */
+ hws_log_lifecycle_snapshot(hws, "remove", "end");
+ dev_info(&pdev->dev, "lifecycle:remove done (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int hws_pm_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int vret;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ dev_info(dev, "lifecycle:pm_suspend begin\n");
+ vret = hws_quiesce_for_transition(hws, "pm_suspend", false);
+
+ step_ns = 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",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ dev_info(dev, "lifecycle:pm_suspend done ret=%d (%lluus)\n", vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+
+ return 0;
+}
+
+static int hws_pm_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int ret;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ dev_info(dev, "lifecycle:pm_resume begin\n");
+
+ /* Back to D0 and re-enable the function */
+ step_ns = ktime_get_mono_fast_ns();
+ pci_set_power_state(pdev, PCI_D0);
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(dev, "pci_enable_device: %d\n", ret);
+ return ret;
+ }
+ pci_restore_state(pdev);
+ pci_set_master(pdev);
+ dev_dbg(dev, "lifecycle:pm_resume:pci-enable (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+
+ /* Reapply any PCIe tuning lost across D3 */
+ enable_pcie_relaxed_ordering(pdev);
+
+ /* Reinitialize chip-side capabilities / registers */
+ step_ns = 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",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+
+ /* IRQs can be re-enabled now that MMIO is sane */
+ step_ns = ktime_get_mono_fast_ns();
+ if (hws->irq >= 0)
+ enable_irq(hws->irq);
+
+ WRITE_ONCE(hws->suspended, false);
+ dev_dbg(dev, "lifecycle:pm_resume:irq-unsuspend (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+
+ /* vb2: nothing mandatory; userspace will STREAMON again when ready */
+ step_ns = ktime_get_mono_fast_ns();
+ hws_video_pm_resume(hws);
+ dev_dbg(dev, "lifecycle:pm_resume:video-resume (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ hws_log_lifecycle_snapshot(hws, "pm_resume", "end");
+ dev_info(dev, "lifecycle:pm_resume done (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(hws_pm_ops, hws_pm_suspend, hws_pm_resume);
+# define HWS_PM_OPS (&hws_pm_ops)
+#else
+# define HWS_PM_OPS NULL
+#endif
+
+static void hws_shutdown(struct pci_dev *pdev)
+{
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int vret = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ if (!hws)
+ return;
+
+ dev_info(&pdev->dev, "lifecycle:pci_shutdown begin\n");
+ vret = hws_quiesce_for_transition(hws, "pci_shutdown", true);
+
+ step_ns = ktime_get_mono_fast_ns();
+ pci_clear_master(pdev);
+ dev_dbg(&pdev->dev, "lifecycle:pci_shutdown:clear-master (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ dev_info(&pdev->dev, "lifecycle:pci_shutdown done ret=%d (%lluus)\n",
+ vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+}
+
+static struct pci_driver hws_pci_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = hws_pci_table,
+ .probe = hws_probe,
+ .remove = hws_remove,
+ .shutdown = hws_shutdown,
+ .driver = {
+ .pm = HWS_PM_OPS,
+ },
+};
+
+MODULE_DEVICE_TABLE(pci, hws_pci_table);
+
+static int __init pcie_hws_init(void)
+{
+ return pci_register_driver(&hws_pci_driver);
+}
+
+static void __exit pcie_hws_exit(void)
+{
+ pci_unregister_driver(&hws_pci_driver);
+}
+
+module_init(pcie_hws_init);
+module_exit(pcie_hws_exit);
+
+MODULE_DESCRIPTION(DRV_NAME);
+MODULE_AUTHOR("Ben Hoff <hoff.benjamin.k@gmail.com>");
+MODULE_AUTHOR("Sales <sales@avmatrix.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("DMA_BUF");
diff --git a/drivers/media/pci/hws/hws_reg.h b/drivers/media/pci/hws/hws_reg.h
new file mode 100644
index 000000000000..e4fb4af44434
--- /dev/null
+++ b/drivers/media/pci/hws/hws_reg.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _HWS_PCIE_REG_H
+#define _HWS_PCIE_REG_H
+
+#include <linux/bits.h>
+#include <linux/sizes.h>
+
+#define XDMA_CHANNEL_NUM_MAX (1)
+#define MAX_NUM_ENGINES (XDMA_CHANNEL_NUM_MAX * 2)
+
+#define PCIE_BARADDROFSIZE 4u
+
+#define PCI_BUS_ACCESS_BASE 0x00000000U
+#define INT_EN_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0134U)
+#define PCIEBR_EN_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0148U)
+#define PCIE_INT_DEC_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0138U)
+
+#define HWS_INT_EN_MASK 0x0003FFFFU
+
+#define PCIEBAR_AXI_BASE 0x20000000U
+
+#define CTL_REG_ACC_BASE 0x0
+#define PCI_ADDR_TABLE_BASE CTL_REG_ACC_BASE
+
+#define CVBS_IN_BASE 0x00004000U
+#define CVBS_IN_BUF_BASE (CVBS_IN_BASE + (16U * PCIE_BARADDROFSIZE))
+#define CVBS_IN_BUF_BASE2 (CVBS_IN_BASE + (50U * PCIE_BARADDROFSIZE))
+
+/* 2 Mib */
+#define MAX_L_VIDEO_SIZE 0x200000U
+
+#define PCI_E_BAR_PAGE_SIZE 0x20000000
+#define PCI_E_BAR_ADD_MASK 0xE0000000
+#define PCI_E_BAR_ADD_LOWMASK 0x1FFFFFFF
+
+#define MAX_VID_CHANNELS 4
+
+#define MAX_MM_VIDEO_SIZE SZ_4M
+
+#define MAX_VIDEO_HW_W 1920
+#define MAX_VIDEO_HW_H 1080
+#define MAX_VIDEO_SCALER_SIZE (1920U * 1080U * 2U)
+
+#define MIN_VAMP_BRIGHTNESS_UNITS 0
+#define MAX_VAMP_BRIGHTNESS_UNITS 0xff
+
+#define MIN_VAMP_CONTRAST_UNITS 0
+#define MAX_VAMP_CONTRAST_UNITS 0xff
+
+#define MIN_VAMP_SATURATION_UNITS 0
+#define MAX_VAMP_SATURATION_UNITS 0xff
+
+#define MIN_VAMP_HUE_UNITS 0
+#define MAX_VAMP_HUE_UNITS 0xff
+
+#define HWS_BRIGHTNESS_DEFAULT 0x80
+#define HWS_CONTRAST_DEFAULT 0x80
+#define HWS_SATURATION_DEFAULT 0x80
+#define HWS_HUE_DEFAULT 0x00
+
+/* Core/global status. */
+#define HWS_REG_SYS_STATUS (CVBS_IN_BASE + 0 * PCIE_BARADDROFSIZE)
+/* bit3: DMA busy, bit2: int, ... */
+
+#define HWS_SYS_DMA_BUSY_BIT BIT(3) /* 0x08 = DMA busy flag */
+
+#define HWS_REG_DEC_MODE (CVBS_IN_BASE + 0 * PCIE_BARADDROFSIZE)
+/* Main control register */
+#define HWS_REG_CTL (CVBS_IN_BASE + 4 * PCIE_BARADDROFSIZE)
+#define HWS_CTL_IRQ_ENABLE_BIT BIT(0) /* Global interrupt enable bit */
+/* Write 0x00 to fully reset decoder,
+ * set bit 31=1 to "start run",
+ * low byte=0x13 selects YUYV/BT.709/etc,
+ * in ReadChipId() we also write 0x00 and 0x10 here for chip-ID sequencing.
+ */
+
+/* Per-channel done flags. */
+#define HWS_REG_INT_STATUS (CVBS_IN_BASE + 1 * PCIE_BARADDROFSIZE)
+#define HWS_SYS_BUSY_BIT BIT(2) /* matches old 0x04 test */
+
+/* Capture enable switches. */
+/* bit0-3: CH0-CH3 video enable */
+#define HWS_REG_VCAP_ENABLE (CVBS_IN_BASE + 2 * PCIE_BARADDROFSIZE)
+/* bits0-3: signal present, bits8-11: interlace */
+#define HWS_REG_ACTIVE_STATUS (CVBS_IN_BASE + 5 * PCIE_BARADDROFSIZE)
+/* bits0-3: HDCP detected */
+#define HWS_REG_HDCP_STATUS (CVBS_IN_BASE + 8 * PCIE_BARADDROFSIZE)
+#define HWS_REG_DMA_MAX_SIZE (CVBS_IN_BASE + 9 * PCIE_BARADDROFSIZE)
+
+/* Buffer addresses (written once during init/reset). */
+/* Base of host-visible buffer. */
+#define HWS_REG_VBUF1_ADDR (CVBS_IN_BASE + 25 * PCIE_BARADDROFSIZE)
+/* Per-channel DMA address. */
+#define HWS_REG_DMA_ADDR(ch) (CVBS_IN_BASE + (26 + (ch)) * PCIE_BARADDROFSIZE)
+
+/* Per-channel live buffer toggles (read-only). */
+#define HWS_REG_VBUF_TOGGLE(ch) (CVBS_IN_BASE + (32 + (ch)) * PCIE_BARADDROFSIZE)
+/*
+ * Returns 0 or 1 = which half of the video ring the DMA engine is
+ * currently filling for channel *ch* (0-3).
+ */
+
+/* Per-interrupt bits (video 0-3). */
+#define HWS_INT_VDONE_BIT(ch) BIT(ch) /* 0x01,0x02,0x04,0x08 */
+
+#define HWS_REG_INT_ACK (CVBS_IN_BASE + 0x4000 + 1 * PCIE_BARADDROFSIZE)
+
+/* 16-bit W | 16-bit H. */
+#define HWS_REG_IN_RES(ch) (CVBS_IN_BASE + (90 + (ch) * 2) * PCIE_BARADDROFSIZE)
+/* B|C|H|S packed bytes. */
+#define HWS_REG_BCHS(ch) (CVBS_IN_BASE + (91 + (ch) * 2) * PCIE_BARADDROFSIZE)
+
+/* Input fps. */
+#define HWS_REG_FRAME_RATE(ch) (CVBS_IN_BASE + (110 + (ch)) * PCIE_BARADDROFSIZE)
+/* Programmed out W|H. */
+#define HWS_REG_OUT_RES(ch) (CVBS_IN_BASE + (120 + (ch)) * PCIE_BARADDROFSIZE)
+/* Programmed out fps. */
+#define HWS_REG_OUT_FRAME_RATE(ch) (CVBS_IN_BASE + (130 + (ch)) * PCIE_BARADDROFSIZE)
+
+/* Device version/port ID/subversion register. */
+#define HWS_REG_DEVICE_INFO (CVBS_IN_BASE + 88 * PCIE_BARADDROFSIZE)
+/*
+ * Reading this 32-bit word returns:
+ * bits 7:0 = "device version"
+ * bits 15:8 = "device sub-version"
+ * bits 23:24 = "HW key / port ID" etc.
+ * bits 31:28 = "support YV12" flags
+ */
+
+/* Convenience aliases for individual channels. */
+#define HWS_REG_VBUF_TOGGLE_CH0 HWS_REG_VBUF_TOGGLE(0)
+#define HWS_REG_VBUF_TOGGLE_CH1 HWS_REG_VBUF_TOGGLE(1)
+#define HWS_REG_VBUF_TOGGLE_CH2 HWS_REG_VBUF_TOGGLE(2)
+#define HWS_REG_VBUF_TOGGLE_CH3 HWS_REG_VBUF_TOGGLE(3)
+
+#endif /* _HWS_PCIE_REG_H */
diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.c b/drivers/media/pci/hws/hws_v4l2_ioctl.c
new file mode 100644
index 000000000000..9c0826c0f9f9
--- /dev/null
+++ b/drivers/media/pci/hws/hws_v4l2_ioctl.c
@@ -0,0 +1,924 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/math64.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_v4l2_ioctl.h"
+
+struct hws_dv_mode {
+ struct v4l2_dv_timings timings;
+ u32 refresh_hz;
+};
+
+static const struct hws_dv_mode *
+hws_find_dv_by_wh(u32 w, u32 h, bool interlaced);
+static const struct hws_dv_mode *
+hws_find_dv_by_wh_fps(u32 w, u32 h, bool interlaced, u32 fps);
+static u32 hws_get_live_fps(struct hws_video *vid);
+static u32 hws_input_status(struct hws_video *vid);
+static int hws_fill_dv_timings(u32 w, u32 h, bool interlace, u32 fps,
+ struct v4l2_dv_timings *timings);
+
+static const struct hws_dv_mode hws_dv_modes[] = {
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1920,
+ .height = 1080,
+ .hfrontporch = 88,
+ .hsync = 44,
+ .hbackporch = 148,
+ .vfrontporch = 4,
+ .vsync = 5,
+ .vbackporch = 36,
+ .pixelclock = 148500000,
+ .polarities = V4L2_DV_VSYNC_POS_POL |
+ V4L2_DV_HSYNC_POS_POL,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1920,
+ .height = 1080,
+ .hfrontporch = 88,
+ .hsync = 44,
+ .hbackporch = 148,
+ .vfrontporch = 4,
+ .vsync = 5,
+ .vbackporch = 36,
+ .pixelclock = 74250000,
+ .polarities = V4L2_DV_VSYNC_POS_POL |
+ V4L2_DV_HSYNC_POS_POL,
+ .interlaced = 0,
+ },
+ },
+ 30,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 720,
+ .hfrontporch = 110,
+ .hsync = 40,
+ .hbackporch = 220,
+ .vfrontporch = 5,
+ .vsync = 5,
+ .vbackporch = 20,
+ .pixelclock = 74250000,
+ .polarities = V4L2_DV_VSYNC_POS_POL |
+ V4L2_DV_HSYNC_POS_POL,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 720,
+ .height = 480,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 720,
+ .height = 576,
+ .interlaced = 0,
+ },
+ },
+ 50,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 800,
+ .height = 600,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 640,
+ .height = 480,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1024,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 800,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 1024,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1360,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1440,
+ .height = 900,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1680,
+ .height = 1050,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ /* Portrait */
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1080,
+ .height = 1920,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+};
+
+static const size_t hws_dv_modes_cnt = ARRAY_SIZE(hws_dv_modes);
+
+/* YUYV: 16 bpp; align to 64 as you did elsewhere */
+static inline u32 hws_calc_bpl_yuyv(u32 w) { return ALIGN(w * 2, 64); }
+static inline u32 hws_calc_size_yuyv(u32 w, u32 h) { return hws_calc_bpl_yuyv(w) * h; }
+static inline u32 hws_calc_half_size(u32 sizeimage)
+{
+ return sizeimage / 2;
+}
+
+static inline void hws_hw_write_bchs(struct hws_pcie_dev *hws, unsigned int ch,
+ u8 br, u8 co, u8 hu, u8 sa)
+{
+ u32 packed = (sa << 24) | (hu << 16) | (co << 8) | br;
+
+ if (!hws || !hws->bar0_base || ch >= hws->max_channels)
+ return;
+ writel_relaxed(packed, hws->bar0_base + HWS_REG_BCHS(ch));
+ (void)readl(hws->bar0_base + HWS_REG_BCHS(ch)); /* post write */
+}
+
+/* Helper: find a supported DV mode by W/H + interlace flag */
+static const struct hws_dv_mode *
+hws_match_supported_dv(const struct v4l2_dv_timings *req)
+{
+ const struct v4l2_bt_timings *bt;
+ u32 fps;
+
+ if (!req || req->type != V4L2_DV_BT_656_1120)
+ return NULL;
+
+ bt = &req->bt;
+ fps = 0;
+ if (bt->pixelclock) {
+ u32 total_w = bt->width + bt->hfrontporch + bt->hsync +
+ bt->hbackporch;
+ u32 total_h = bt->height + bt->vfrontporch + bt->vsync +
+ bt->vbackporch;
+
+ if (total_w && total_h)
+ fps = DIV_ROUND_CLOSEST_ULL((u64)bt->pixelclock,
+ (u64)total_w * total_h);
+ }
+ if (fps) {
+ const struct hws_dv_mode *exact =
+ hws_find_dv_by_wh_fps(bt->width, bt->height,
+ !!bt->interlaced, fps);
+ if (exact)
+ return exact;
+ }
+ return hws_find_dv_by_wh(bt->width, bt->height, !!bt->interlaced);
+}
+
+/* Helper: find a supported DV mode by W/H + interlace flag */
+static const struct hws_dv_mode *
+hws_find_dv_by_wh(u32 w, u32 h, bool interlaced)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct hws_dv_mode *t = &hws_dv_modes[i];
+ const struct v4l2_bt_timings *bt = &t->timings.bt;
+
+ if (t->timings.type != V4L2_DV_BT_656_1120)
+ continue;
+
+ if (bt->width == w && bt->height == h &&
+ !!bt->interlaced == interlaced)
+ return t;
+ }
+ return NULL;
+}
+
+static const struct hws_dv_mode *
+hws_find_dv_by_wh_fps(u32 w, u32 h, bool interlaced, u32 fps)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct hws_dv_mode *t = &hws_dv_modes[i];
+ const struct v4l2_bt_timings *bt = &t->timings.bt;
+
+ if (t->timings.type != V4L2_DV_BT_656_1120)
+ continue;
+
+ if (bt->width == w && bt->height == h &&
+ !!bt->interlaced == interlaced &&
+ t->refresh_hz == fps)
+ return t;
+ }
+ return NULL;
+}
+
+static bool hws_get_live_dv_geometry(struct hws_video *vid,
+ u32 *w, u32 *h, bool *interlaced)
+{
+ struct hws_pcie_dev *pdx;
+ u32 reg;
+
+ if (!vid)
+ return false;
+
+ pdx = vid->parent;
+ if (!pdx || !pdx->bar0_base)
+ return false;
+
+ reg = readl(pdx->bar0_base + HWS_REG_IN_RES(vid->channel_index));
+ if (!reg || reg == 0xFFFFFFFF)
+ return false;
+
+ if (w)
+ *w = reg & 0xFFFF;
+ if (h)
+ *h = (reg >> 16) & 0xFFFF;
+ if (interlaced) {
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ *interlaced = !!(reg & BIT(8 + vid->channel_index));
+ }
+ return true;
+}
+
+static u32 hws_get_live_fps(struct hws_video *vid)
+{
+ struct hws_pcie_dev *pdx;
+ u32 fps;
+
+ if (!vid)
+ return 0;
+
+ pdx = vid->parent;
+ if (!pdx || !pdx->bar0_base)
+ return 0;
+
+ fps = readl(pdx->bar0_base + HWS_REG_FRAME_RATE(vid->channel_index));
+ if (!fps || fps == 0xFFFFFFFF || fps > 240)
+ return 0;
+
+ return fps;
+}
+
+static u32 hws_pick_fps_from_mode(u32 w, u32 h, bool interlaced)
+{
+ const struct hws_dv_mode *m = hws_find_dv_by_wh(w, h, interlaced);
+
+ if (m && m->refresh_hz)
+ return m->refresh_hz;
+ /* Fallback to a sane default */
+ return 60;
+}
+
+static int hws_fill_dv_timings(u32 w, u32 h, bool interlace, u32 fps,
+ struct v4l2_dv_timings *timings)
+{
+ const struct hws_dv_mode *m;
+
+ m = fps ? hws_find_dv_by_wh_fps(w, h, interlace, fps) : NULL;
+ if (!m)
+ m = hws_find_dv_by_wh(w, h, interlace);
+ if (!m)
+ return -ENOLINK;
+
+ *timings = m->timings;
+ return 0;
+}
+
+static u32 hws_input_status(struct hws_video *vid)
+{
+ struct hws_pcie_dev *pdx;
+ u32 reg;
+
+ if (!vid)
+ return V4L2_IN_ST_NO_SIGNAL;
+
+ pdx = vid->parent;
+ if (!pdx || !pdx->bar0_base)
+ return V4L2_IN_ST_NO_SIGNAL;
+
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ if (reg == 0xffffffff)
+ return V4L2_IN_ST_NO_SIGNAL;
+
+ return (reg & BIT(vid->channel_index)) ? 0 : V4L2_IN_ST_NO_SIGNAL;
+}
+
+/* Query the *current detected* DV timings on the input.
+ * If you have a real hardware detector, call it here; otherwise we
+ * derive from the cached pix state and map to the closest supported DV mode.
+ */
+int hws_vidioc_query_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ u32 w, h;
+ u32 fps;
+ bool interlace;
+
+ if (!timings)
+ return -EINVAL;
+
+ w = vid->pix.width;
+ h = vid->pix.height;
+ interlace = vid->pix.interlaced;
+ (void)hws_get_live_dv_geometry(vid, &w, &h, &interlace);
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(w, h, interlace);
+
+ return hws_fill_dv_timings(w, h, interlace, fps, timings);
+}
+
+/* Enumerate the Nth supported DV timings from our static table. */
+int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
+ struct v4l2_enum_dv_timings *edv)
+{
+ struct hws_video *vid = video_drvdata(file);
+ const struct hws_dv_mode *m;
+ u32 w, h;
+ u32 fps;
+ bool interlace;
+
+ if (!edv)
+ return -EINVAL;
+
+ if (edv->pad)
+ return -EINVAL;
+
+ w = 0;
+ h = 0;
+ interlace = false;
+ if (hws_get_live_dv_geometry(vid, &w, &h, &interlace)) {
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(w, h, interlace);
+ m = fps ? hws_find_dv_by_wh_fps(w, h, interlace, fps) : NULL;
+ if (!m)
+ m = hws_find_dv_by_wh(w, h, interlace);
+ if (m) {
+ if (edv->index)
+ return -EINVAL;
+ edv->timings = m->timings;
+ return 0;
+ }
+ }
+
+ if (edv->index >= hws_dv_modes_cnt)
+ return -EINVAL;
+
+ edv->timings = hws_dv_modes[edv->index].timings;
+ return 0;
+}
+
+/* Get the *currently configured* DV timings. */
+int hws_vidioc_g_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ u32 w, h;
+ u32 fps;
+ bool interlace;
+
+ if (!timings)
+ return -EINVAL;
+
+ w = vid->pix.width;
+ h = vid->pix.height;
+ interlace = vid->pix.interlaced;
+ if (hws_get_live_dv_geometry(vid, &w, &h, &interlace)) {
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(w, h, interlace);
+ return hws_fill_dv_timings(w, h, interlace, fps, timings);
+ }
+
+ *timings = vid->cur_dv_timings;
+ return 0;
+}
+
+static inline void hws_set_colorimetry_state(struct hws_pix_state *p)
+{
+ bool sd = p->height <= 576;
+
+ p->colorspace = sd ? V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
+ p->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ p->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ p->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+}
+
+/* Set DV timings: must match one of our supported modes.
+ * If buffers are queued and this implies a size change, we reject with -EBUSY.
+ * Otherwise we update pix state and (optionally) reprogram the HW.
+ */
+int hws_vidioc_s_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ const struct hws_dv_mode *m;
+ const struct v4l2_bt_timings *bt;
+ u32 new_w, new_h;
+ bool interlaced;
+ int ret = 0;
+ unsigned long was_busy;
+ u32 live_w, live_h;
+ u32 live_fps;
+ bool live_interlaced;
+ bool live_present;
+
+ if (!timings)
+ return -EINVAL;
+
+ m = hws_match_supported_dv(timings);
+ if (!m)
+ return -EINVAL;
+
+ bt = &m->timings.bt;
+ if (bt->interlaced)
+ return -EINVAL; /* only progressive modes are advertised */
+ new_w = bt->width;
+ new_h = bt->height;
+ interlaced = false;
+
+ lockdep_assert_held(&vid->state_lock);
+ live_present = hws_get_live_dv_geometry(vid, &live_w, &live_h,
+ &live_interlaced);
+
+ /* If vb2 has active buffers and size would change, reject. */
+ was_busy = vb2_is_busy(&vid->buffer_queue);
+ if (was_busy &&
+ (new_w != vid->pix.width || new_h != vid->pix.height ||
+ interlaced != vid->pix.interlaced)) {
+ ret = -EBUSY;
+ return ret;
+ }
+
+ /* When a live input signal is present, the receiver owns the timing.
+ * Allow setting the already-active timings so v4l2-compliance can
+ * round-trip them, but reject attempts to retime the live source.
+ */
+ if (live_present) {
+ live_fps = hws_get_live_fps(vid);
+ if (!live_fps)
+ live_fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(live_w, live_h,
+ live_interlaced);
+ if (live_w == new_w && live_h == new_h &&
+ live_interlaced == interlaced &&
+ m->refresh_hz == live_fps)
+ return 0;
+ return -EBUSY;
+ }
+
+ /* Update software pixel state (and recalc sizes) */
+ vid->pix.width = new_w;
+ vid->pix.height = new_h;
+ vid->pix.field = interlaced ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_NONE;
+ vid->pix.interlaced = interlaced;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+
+ hws_set_colorimetry_state(&vid->pix);
+
+ /* Recompute stride/sizeimage/half_size using your helper */
+ vid->pix.bytesperline = hws_calc_bpl_yuyv(new_w);
+ vid->pix.sizeimage = hws_calc_size_yuyv(new_w, new_h);
+ vid->pix.half_size = hws_calc_half_size(vid->pix.sizeimage);
+ vid->cur_dv_timings = m->timings;
+ vid->current_fps = m->refresh_hz;
+ if (!was_busy)
+ vid->alloc_sizeimage = vid->pix.sizeimage;
+ return ret;
+}
+
+/* Report DV timings capability: advertise BT.656/1120 with
+ * the min/max WxH derived from our table and basic progressive support.
+ */
+int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
+ struct v4l2_dv_timings_cap *cap)
+{
+ u32 min_w = ~0U, min_h = ~0U;
+ u32 max_w = 0, max_h = 0;
+ size_t i, n = 0;
+
+ if (!cap)
+ return -EINVAL;
+
+ memset(cap, 0, sizeof(*cap));
+ cap->type = V4L2_DV_BT_656_1120;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct v4l2_bt_timings *bt = &hws_dv_modes[i].timings.bt;
+
+ if (hws_dv_modes[i].timings.type != V4L2_DV_BT_656_1120)
+ continue;
+ n++;
+
+ if (bt->width < min_w)
+ min_w = bt->width;
+ if (bt->height < min_h)
+ min_h = bt->height;
+ if (bt->width > max_w)
+ max_w = bt->width;
+ if (bt->height > max_h)
+ max_h = bt->height;
+ }
+
+ /* If the table was empty, fail gracefully. */
+ if (!n || min_w == U32_MAX)
+ return -ENODATA;
+
+ cap->bt.min_width = min_w;
+ cap->bt.max_width = max_w;
+ cap->bt.min_height = min_h;
+ cap->bt.max_height = max_h;
+
+ /* We support both CEA-861- and VESA-style modes in the list. */
+ cap->bt.standards =
+ V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT;
+
+ /* Progressive only, unless your table includes interlaced entries. */
+ cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE;
+
+ /* Leave pixelclock/porch limits unconstrained (0) for now. */
+ return 0;
+}
+
+static int hws_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct hws_video *vid =
+ container_of(ctrl->handler, struct hws_video, control_handler);
+ struct hws_pcie_dev *pdx = vid->parent;
+ bool program = false;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ vid->current_brightness = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_CONTRAST:
+ vid->current_contrast = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_SATURATION:
+ vid->current_saturation = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_HUE:
+ vid->current_hue = ctrl->val;
+ program = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (program) {
+ hws_hw_write_bchs(pdx, vid->channel_index,
+ (u8)vid->current_brightness,
+ (u8)vid->current_contrast,
+ (u8)vid->current_hue,
+ (u8)vid->current_saturation);
+ }
+ return 0;
+}
+
+const struct v4l2_ctrl_ops hws_ctrl_ops = {
+ .s_ctrl = hws_s_ctrl,
+};
+
+int hws_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
+{
+ struct hws_video *vid = video_drvdata(file);
+ int vi_index = vid->channel_index + 1; /* keep it simple */
+
+ strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+ snprintf(cap->card, sizeof(cap->card),
+ "AVMatrix HWS Capture %d", vi_index);
+ return 0;
+}
+
+int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh, struct v4l2_fmtdesc *f)
+{
+ if (f->index != 0)
+ return -EINVAL; /* only one format */
+
+ f->pixelformat = V4L2_PIX_FMT_YUYV;
+ return 0;
+}
+
+int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct hws_video *vid = video_drvdata(file);
+
+ fmt->fmt.pix.width = vid->pix.width;
+ fmt->fmt.pix.height = vid->pix.height;
+ fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ fmt->fmt.pix.field = vid->pix.field;
+ fmt->fmt.pix.bytesperline = vid->pix.bytesperline;
+ fmt->fmt.pix.sizeimage = vid->pix.sizeimage;
+ fmt->fmt.pix.colorspace = vid->pix.colorspace;
+ fmt->fmt.pix.ycbcr_enc = vid->pix.ycbcr_enc;
+ fmt->fmt.pix.quantization = vid->pix.quantization;
+ fmt->fmt.pix.xfer_func = vid->pix.xfer_func;
+ return 0;
+}
+
+static inline void hws_set_colorimetry_fmt(struct v4l2_pix_format *p)
+{
+ bool sd = p->height <= 576;
+
+ p->colorspace = sd ? V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
+ p->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ p->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ p->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+}
+
+int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct hws_video *vid = file ? video_drvdata(file) : NULL;
+ struct hws_pcie_dev *pdev = vid ? vid->parent : NULL;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ u32 req_w = pix->width, req_h = pix->height;
+ u32 w, h, min_bpl, bpl;
+ size_t size; /* wider than u32 for overflow check */
+ size_t max_frame = pdev ? pdev->max_hw_video_buf_sz : MAX_MM_VIDEO_SIZE;
+
+ /* Only YUYV */
+ pix->pixelformat = V4L2_PIX_FMT_YUYV;
+
+ /* Defaults then clamp */
+ w = (req_w ? req_w : 640);
+ h = (req_h ? req_h : 480);
+ if (w > MAX_VIDEO_HW_W)
+ w = MAX_VIDEO_HW_W;
+ if (h > MAX_VIDEO_HW_H)
+ h = MAX_VIDEO_HW_H;
+ if (!w)
+ w = 640; /* hard fallback in case macros are odd */
+ if (!h)
+ h = 480;
+
+ /* Field policy */
+ pix->field = V4L2_FIELD_NONE;
+
+ /* Stride policy for packed 16bpp, 64B align */
+ min_bpl = ALIGN(w * 2, 64);
+
+ /* Bound requested bpl to something sane, then align */
+ bpl = pix->bytesperline;
+ if (bpl < min_bpl) {
+ bpl = min_bpl;
+ } else {
+ /* Cap at 16x width to avoid silly values that overflow sizeimage */
+ u32 max_bpl = ALIGN(w * 2 * 16, 64);
+
+ if (bpl > max_bpl)
+ bpl = max_bpl;
+ bpl = ALIGN(bpl, 64);
+ }
+ if (h && max_frame) {
+ size_t max_bpl_hw = max_frame / h;
+
+ if (max_bpl_hw < min_bpl)
+ return -ERANGE;
+ max_bpl_hw = rounddown(max_bpl_hw, 64);
+ 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 = (u32)max_bpl_hw;
+ }
+ }
+ size = (size_t)bpl * (size_t)h;
+ if (size > max_frame)
+ return -ERANGE;
+
+ pix->width = w;
+ pix->height = h;
+ pix->bytesperline = bpl;
+ pix->sizeimage = (u32)size; /* logical size, not page-aligned */
+
+ hws_set_colorimetry_fmt(pix);
+ if (pdev)
+ dev_dbg(&pdev->pdev->dev,
+ "try_fmt: w=%u h=%u bpl=%u size=%u field=%u\n",
+ pix->width, pix->height, pix->bytesperline,
+ pix->sizeimage, pix->field);
+ return 0;
+}
+
+int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
+{
+ struct hws_video *vid = video_drvdata(file);
+ int ret;
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ /* Normalize the request */
+ ret = hws_vidioc_try_fmt_vid_cap(file, priv, f);
+ if (ret)
+ return ret;
+
+ /* Don't allow buffer layout changes while buffers are queued. */
+ if (vb2_is_busy(&vid->buffer_queue)) {
+ if (f->fmt.pix.width != vid->pix.width ||
+ f->fmt.pix.height != vid->pix.height ||
+ f->fmt.pix.bytesperline != vid->pix.bytesperline)
+ return -EBUSY;
+ }
+
+ /* Apply to driver state */
+ vid->pix.width = f->fmt.pix.width;
+ vid->pix.height = f->fmt.pix.height;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+ vid->pix.field = f->fmt.pix.field;
+ vid->pix.colorspace = f->fmt.pix.colorspace;
+ vid->pix.ycbcr_enc = f->fmt.pix.ycbcr_enc;
+ vid->pix.quantization = f->fmt.pix.quantization;
+ vid->pix.xfer_func = f->fmt.pix.xfer_func;
+
+ /* Update sizes (use helper if you prefer strict alignment math) */
+ vid->pix.bytesperline = f->fmt.pix.bytesperline; /* aligned */
+ vid->pix.sizeimage = f->fmt.pix.sizeimage; /* logical */
+ vid->pix.half_size = hws_calc_half_size(vid->pix.sizeimage);
+ vid->pix.interlaced = false;
+ /* S_FMT negotiates buffer layout only. Keep detector-owned DV timing
+ * state unchanged so a harmless restart cannot clobber the live FPS.
+ */
+ /* Or:
+ * hws_calc_sizeimage(vid, vid->pix.width, vid->pix.height, false);
+ */
+
+ /* Refresh vb2 watermark when idle */
+ if (!vb2_is_busy(&vid->buffer_queue))
+ vid->alloc_sizeimage = PAGE_ALIGN(vid->pix.sizeimage);
+ dev_dbg(&vid->parent->pdev->dev,
+ "s_fmt: w=%u h=%u bpl=%u size=%u alloc=%u\n",
+ vid->pix.width, vid->pix.height, vid->pix.bytesperline,
+ vid->pix.sizeimage, vid->alloc_sizeimage);
+
+ return 0;
+}
+
+int hws_vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *param)
+{
+ struct hws_video *vid = video_drvdata(file);
+ u32 fps;
+
+ if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps : 60;
+
+ /* HDMI receivers report the detected frame period, they don't set it. */
+ param->parm.capture.capability = 0;
+ param->parm.capture.capturemode = 0;
+ param->parm.capture.timeperframe.numerator = 1;
+ param->parm.capture.timeperframe.denominator = fps;
+ param->parm.capture.extendedmode = 0;
+ param->parm.capture.readbuffers = 0;
+
+ return 0;
+}
+
+int hws_vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *input)
+{
+ struct hws_video *vid = video_drvdata(file);
+
+ if (input->index)
+ return -EINVAL;
+ input->type = V4L2_INPUT_TYPE_CAMERA;
+ strscpy(input->name, KBUILD_MODNAME, sizeof(input->name));
+ input->capabilities = V4L2_IN_CAP_DV_TIMINGS;
+ input->status = hws_input_status(vid);
+
+ return 0;
+}
+
+int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *index)
+{
+ *index = 0;
+ return 0;
+}
+
+int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.h b/drivers/media/pci/hws/hws_v4l2_ioctl.h
new file mode 100644
index 000000000000..53044f78d6fa
--- /dev/null
+++ b/drivers/media/pci/hws/hws_v4l2_ioctl.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_V4L2_IOCTL_H
+#define HWS_V4L2_IOCTL_H
+
+#include <media/v4l2-ctrls.h>
+#include <linux/fs.h>
+
+extern const struct v4l2_ctrl_ops hws_ctrl_ops;
+
+int hws_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap);
+int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh, struct v4l2_fmtdesc *f);
+int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt);
+int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f);
+int hws_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms);
+int hws_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms);
+int hws_vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *setfps);
+int hws_vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i);
+int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *i);
+int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i);
+int hws_vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *a);
+int hws_vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a);
+int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
+ struct v4l2_dv_timings_cap *cap);
+int hws_vidioc_s_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+
+int hws_vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a);
+int hws_vidioc_g_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
+ struct v4l2_enum_dv_timings *edv);
+int hws_vidioc_query_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
+
+#endif
diff --git a/drivers/media/pci/hws/hws_video.c b/drivers/media/pci/hws/hws_video.c
new file mode 100644
index 000000000000..6e1d75701b15
--- /dev/null
+++ b/drivers/media/pci/hws/hws_video.c
@@ -0,0 +1,1504 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/overflow.h>
+#include <linux/delay.h>
+#include <linux/bits.h>
+#include <linux/jiffies.h>
+#include <linux/ktime.h>
+#include <linux/interrupt.h>
+#include <linux/moduleparam.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_irq.h"
+#include "hws_v4l2_ioctl.h"
+
+#define HWS_REMAP_SLOT_OFF(ch) (0x208 + (ch) * 8) /* one 64-bit slot per ch */
+#define HWS_BUF_BASE_OFF(ch) (CVBS_IN_BUF_BASE + (ch) * PCIE_BARADDROFSIZE)
+#define HWS_HALF_SZ_OFF(ch) (CVBS_IN_BUF_BASE2 + (ch) * PCIE_BARADDROFSIZE)
+
+static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool interlace);
+static bool hws_read_active_state(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool *interlace);
+static void handle_hwv2_path(struct hws_pcie_dev *hws, unsigned int ch);
+static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch);
+static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
+ bool interlaced);
+
+/* DMA helper functions */
+static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma);
+static struct hwsvideo_buffer *
+hws_take_queued_buffer_locked(struct hws_video *vid);
+
+static inline bool list_node_unlinked(const struct list_head *n)
+{
+ return n->next == LIST_POISON1 || n->prev == LIST_POISON2;
+}
+
+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=0x%llx tag=%s\n", ch,
+ (u64)dma, tag ? tag : "");
+}
+
+static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma)
+{
+ const u32 addr_mask = PCI_E_BAR_ADD_MASK; // 0xE0000000
+ const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK; // 0x1FFFFFFF
+ struct hws_pcie_dev *hws = vid->parent;
+ unsigned int ch = vid->channel_index;
+ u32 table_off = HWS_REMAP_SLOT_OFF(ch);
+ u32 lo = lower_32_bits(dma);
+ u32 hi = upper_32_bits(dma);
+ u32 pci_addr = lo & addr_low_mask; // low 29 bits inside 512MB window
+ u32 page_lo = lo & addr_mask; // bits 31..29 only (page bits)
+
+ bool wrote = false;
+
+ /* Remap entry only when DMA crosses into a new 512 MB page */
+ if (!vid->window_valid || vid->last_dma_hi != hi ||
+ vid->last_dma_page != page_lo) {
+ writel(hi, hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
+ writel(page_lo,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
+ PCIE_BARADDROFSIZE);
+ vid->last_dma_hi = hi;
+ vid->last_dma_page = page_lo;
+ wrote = true;
+ }
+
+ /* Base pointer only needs low 29 bits */
+ if (!vid->window_valid || vid->last_pci_addr != pci_addr) {
+ writel((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
+ hws->bar0_base + HWS_BUF_BASE_OFF(ch));
+ vid->last_pci_addr = pci_addr;
+ wrote = true;
+ }
+
+ /* Half-size only changes when resolution changes */
+ if (!vid->window_valid || vid->last_half16 != vid->pix.half_size / 16) {
+ writel(vid->pix.half_size / 16,
+ hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+ vid->last_half16 = vid->pix.half_size / 16;
+ wrote = true;
+ }
+
+ vid->window_valid = true;
+
+ if (dma_window_verify && wrote) {
+ u32 r_hi =
+ readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
+ u32 r_lo =
+ readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
+ PCIE_BARADDROFSIZE);
+ u32 r_base = readl(hws->bar0_base + HWS_BUF_BASE_OFF(ch));
+ u32 r_half = readl(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+
+ dev_dbg(&hws->pdev->dev,
+ "ch%u remap verify: hi=0x%08x page_lo=0x%08x exp_page=0x%08x base=0x%08x exp_base=0x%08x half16B=0x%08x exp_half=0x%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) {
+ /* Flush posted writes before arming DMA */
+ readl_relaxed(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+ }
+}
+
+static struct hwsvideo_buffer *
+hws_take_queued_buffer_locked(struct hws_video *vid)
+{
+ struct hwsvideo_buffer *buf;
+
+ if (!vid || list_empty(&vid->capture_queue))
+ return NULL;
+
+ buf = list_first_entry(&vid->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&buf->list);
+ if (vid->queued_count)
+ vid->queued_count--;
+ return buf;
+}
+
+void hws_prime_next_locked(struct hws_video *vid)
+{
+ struct hws_pcie_dev *hws;
+ struct hwsvideo_buffer *next;
+ dma_addr_t dma;
+
+ if (!vid)
+ return;
+
+ hws = vid->parent;
+ if (!hws || !hws->bar0_base)
+ return;
+
+ if (!READ_ONCE(vid->cap_active) || !vid->active || vid->next_prepared)
+ return;
+
+ next = hws_take_queued_buffer_locked(vid);
+ if (!next)
+ return;
+
+ vid->next_prepared = next;
+ dma = vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
+ 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=0x%llx\n",
+ vid->channel_index, next, (u64)dma);
+}
+
+static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag)
+{
+ struct hws_pcie_dev *hws;
+ unsigned long flags;
+ struct hwsvideo_buffer *buf = NULL, *next = NULL;
+ bool have_next = false;
+ bool doorbell = false;
+
+ if (!v)
+ return false;
+ hws = v->parent;
+ if (!hws || READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active))
+ return false;
+ spin_lock_irqsave(&v->irq_lock, flags);
+ if (v->active) {
+ buf = v->active;
+ v->active = NULL;
+ buf->slot = 0;
+ } else if (!list_empty(&v->capture_queue)) {
+ buf = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&buf->list);
+ if (v->queued_count)
+ v->queued_count--;
+ buf->slot = 0;
+ }
+ if (v->next_prepared) {
+ next = v->next_prepared;
+ v->next_prepared = NULL;
+ next->slot = 0;
+ v->active = next;
+ have_next = true;
+ } else if (!list_empty(&v->capture_queue)) {
+ next = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&next->list);
+ if (v->queued_count)
+ v->queued_count--;
+ next->slot = 0;
+ v->active = next;
+ have_next = true;
+ } else {
+ v->active = NULL;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ if (!buf)
+ return false;
+ /* Complete buffer with a neutral frame so dequeuers keep running. */
+ {
+ struct vb2_v4l2_buffer *vb2v = &buf->vb;
+ void *dst = vb2_plane_vaddr(&vb2v->vb2_buf, 0);
+
+ if (dst)
+ memset(dst, 0x10, v->pix.sizeimage);
+ vb2_set_plane_payload(&vb2v->vb2_buf, 0, v->pix.sizeimage);
+ vb2v->sequence = (u32)atomic_inc_return(&v->sequence_number);
+ vb2v->vb2_buf.timestamp = ktime_get_ns();
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+ if (have_next && next) {
+ dma_addr_t dma =
+ vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(hws, v->channel_index, dma);
+ hws_set_dma_doorbell(hws, v->channel_index, dma,
+ tag ? tag : "nosignal_zero");
+ doorbell = true;
+ }
+ if (doorbell) {
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, v->channel_index, true);
+ }
+ return true;
+}
+
+static int hws_ctrls_init(struct hws_video *vid)
+{
+ struct v4l2_ctrl_handler *hdl = &vid->control_handler;
+
+ /* Create BCHS controls. */
+ v4l2_ctrl_handler_init(hdl, 4);
+
+ vid->ctrl_brightness = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
+ V4L2_CID_BRIGHTNESS,
+ MIN_VAMP_BRIGHTNESS_UNITS,
+ MAX_VAMP_BRIGHTNESS_UNITS, 1,
+ HWS_BRIGHTNESS_DEFAULT);
+
+ vid->ctrl_contrast =
+ v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_CONTRAST,
+ MIN_VAMP_CONTRAST_UNITS, MAX_VAMP_CONTRAST_UNITS,
+ 1, HWS_CONTRAST_DEFAULT);
+
+ vid->ctrl_saturation = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
+ V4L2_CID_SATURATION,
+ MIN_VAMP_SATURATION_UNITS,
+ MAX_VAMP_SATURATION_UNITS, 1,
+ HWS_SATURATION_DEFAULT);
+
+ vid->ctrl_hue = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_HUE,
+ MIN_VAMP_HUE_UNITS,
+ MAX_VAMP_HUE_UNITS, 1,
+ HWS_HUE_DEFAULT);
+ if (hdl->error) {
+ int err = hdl->error;
+
+ v4l2_ctrl_handler_free(hdl);
+ return err;
+ }
+ return 0;
+}
+
+int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch)
+{
+ struct hws_video *vid;
+
+ /* basic sanity */
+ if (!pdev || ch < 0 || ch >= pdev->max_channels)
+ return -EINVAL;
+
+ vid = &pdev->video[ch];
+
+ /* hard reset the per-channel struct (safe here since we init everything next) */
+ memset(vid, 0, sizeof(*vid));
+
+ /* identity */
+ vid->parent = pdev;
+ vid->channel_index = ch;
+
+ /* locks & lists */
+ mutex_init(&vid->state_lock);
+ spin_lock_init(&vid->irq_lock);
+ INIT_LIST_HEAD(&vid->capture_queue);
+ atomic_set(&vid->sequence_number, 0);
+ vid->active = NULL;
+
+ /* DMA watchdog removed; retain counters for diagnostics */
+ vid->timeout_count = 0;
+ vid->error_count = 0;
+
+ vid->queued_count = 0;
+ vid->window_valid = false;
+
+ /* default format (adjust to your HW) */
+ vid->pix.width = 1920;
+ vid->pix.height = 1080;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+ vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
+ vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
+ vid->pix.field = V4L2_FIELD_NONE;
+ vid->pix.colorspace = V4L2_COLORSPACE_REC709;
+ vid->pix.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ vid->pix.quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ vid->pix.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+ vid->pix.interlaced = false;
+ vid->pix.half_size = vid->pix.sizeimage / 2;
+ vid->alloc_sizeimage = vid->pix.sizeimage;
+ hws_set_current_dv_timings(vid, vid->pix.width,
+ vid->pix.height, vid->pix.interlaced);
+ vid->current_fps = 60;
+
+ /* color controls default (mid-scale) */
+ vid->current_brightness = 0x80;
+ vid->current_contrast = 0x80;
+ vid->current_saturation = 0x80;
+ vid->current_hue = 0x80;
+
+ /* capture state */
+ vid->cap_active = false;
+ vid->stop_requested = false;
+ vid->last_buf_half_toggle = 0;
+ vid->half_seen = false;
+ vid->signal_loss_cnt = 0;
+
+ /* Create BCHS + DV power-present as modern controls */
+ {
+ int err = hws_ctrls_init(vid);
+
+ if (err) {
+ dev_err(&pdev->pdev->dev,
+ "v4l2 ctrl init failed on ch%d: %d\n", ch, err);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static void hws_video_drain_queue_locked(struct hws_video *vid)
+{
+ /* Return in-flight first */
+ if (vid->active) {
+ vb2_buffer_done(&vid->active->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ vid->active = NULL;
+ }
+
+ /* Then everything queued */
+ while (!list_empty(&vid->capture_queue)) {
+ struct hwsvideo_buffer *b =
+ list_first_entry(&vid->capture_queue,
+ struct hwsvideo_buffer,
+ list);
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+}
+
+static void hws_video_release_registration(struct hws_video *vid)
+{
+ if (vid->buffer_queue.ops) {
+ vb2_queue_release(&vid->buffer_queue);
+ vid->buffer_queue.ops = NULL;
+ }
+
+ if (!vid->video_device)
+ return;
+
+ if (video_is_registered(vid->video_device))
+ vb2_video_unregister_device(vid->video_device);
+ else
+ video_device_release(vid->video_device);
+ vid->video_device = NULL;
+}
+
+static void hws_video_collect_done_locked(struct hws_video *vid,
+ struct list_head *done)
+{
+ struct hwsvideo_buffer *b;
+
+ if (vid->active) {
+ if (!list_node_unlinked(&vid->active->list)) {
+ list_move_tail(&vid->active->list, done);
+ } else {
+ INIT_LIST_HEAD(&vid->active->list);
+ list_add_tail(&vid->active->list, done);
+ }
+ vid->active = NULL;
+ }
+
+ if (vid->next_prepared) {
+ if (!list_node_unlinked(&vid->next_prepared->list)) {
+ list_move_tail(&vid->next_prepared->list, done);
+ } else {
+ INIT_LIST_HEAD(&vid->next_prepared->list);
+ list_add_tail(&vid->next_prepared->list, done);
+ }
+ vid->next_prepared = NULL;
+ }
+
+ while (!list_empty(&vid->capture_queue)) {
+ b = list_first_entry(&vid->capture_queue, struct hwsvideo_buffer,
+ list);
+ list_move_tail(&b->list, done);
+ }
+
+ vid->queued_count = 0;
+}
+
+void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch)
+{
+ struct hws_video *vid;
+ unsigned long flags;
+
+ if (!pdev || ch < 0 || ch >= pdev->max_channels)
+ return;
+
+ vid = &pdev->video[ch];
+
+ /* 1) Stop HW best-effort for this channel */
+ hws_enable_video_capture(vid->parent, vid->channel_index, false);
+
+ /* 2) Flip software state so IRQ/BH will be no-ops if they run */
+ WRITE_ONCE(vid->stop_requested, true);
+ WRITE_ONCE(vid->cap_active, false);
+
+ /* 3) Ensure the IRQ handler finished any in-flight completions */
+ if (vid->parent && vid->parent->irq >= 0)
+ synchronize_irq(vid->parent->irq);
+
+ /* 4) Drain SW capture queue & in-flight under lock */
+ spin_lock_irqsave(&vid->irq_lock, flags);
+ hws_video_drain_queue_locked(vid);
+ spin_unlock_irqrestore(&vid->irq_lock, flags);
+
+ /* 5) Release VB2 queue if initialized */
+ hws_video_release_registration(vid);
+
+ /* 6) Free V4L2 controls */
+ v4l2_ctrl_handler_free(&vid->control_handler);
+
+ /* 8) Reset simple state (don’t memset the whole struct here) */
+ mutex_destroy(&vid->state_lock);
+ INIT_LIST_HEAD(&vid->capture_queue);
+ vid->active = NULL;
+ vid->stop_requested = false;
+ vid->last_buf_half_toggle = 0;
+ vid->half_seen = false;
+ vid->signal_loss_cnt = 0;
+}
+
+/* Convenience cast */
+static inline struct hwsvideo_buffer *to_hwsbuf(struct vb2_buffer *vb)
+{
+ return container_of(to_vb2_v4l2_buffer(vb), struct hwsvideo_buffer, vb);
+}
+
+static int hws_buf_init(struct vb2_buffer *vb)
+{
+ struct hwsvideo_buffer *b = to_hwsbuf(vb);
+
+ INIT_LIST_HEAD(&b->list);
+ return 0;
+}
+
+static void hws_buf_finish(struct vb2_buffer *vb)
+{
+ /* vb2 core handles cache maintenance for dma-contig buffers */
+ (void)vb;
+}
+
+static void hws_buf_cleanup(struct vb2_buffer *vb)
+{
+ struct hwsvideo_buffer *b = to_hwsbuf(vb);
+
+ if (!list_empty(&b->list))
+ list_del_init(&b->list);
+}
+
+void hws_program_dma_for_addr(struct hws_pcie_dev *hws, unsigned int ch,
+ dma_addr_t dma)
+{
+ struct hws_video *vid = &hws->video[ch];
+
+ hws_program_dma_window(vid, dma);
+}
+
+void hws_enable_video_capture(struct hws_pcie_dev *hws, unsigned int chan,
+ bool on)
+{
+ u32 status;
+
+ if (!hws || hws->pci_lost || chan >= hws->max_channels)
+ return;
+
+ status = readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ status = on ? (status | BIT(chan)) : (status & ~BIT(chan));
+ writel(status, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ (void)readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+
+ WRITE_ONCE(hws->video[chan].cap_active, on);
+
+ dev_dbg(&hws->pdev->dev, "vcap %s ch%u (reg=0x%08x)\n",
+ on ? "ON" : "OFF", chan, status);
+}
+
+static void hws_seed_dma_windows(struct hws_pcie_dev *hws)
+{
+ const u32 addr_mask = PCI_E_BAR_ADD_MASK;
+ const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK;
+ u32 table = 0x208; /* one 64-bit entry per channel */
+ unsigned int ch;
+
+ if (!hws || !hws->bar0_base)
+ return;
+
+ /* If cur_max_video_ch isn’t set yet, default to max_channels */
+ if (!hws->cur_max_video_ch || hws->cur_max_video_ch > hws->max_channels)
+ hws->cur_max_video_ch = hws->max_channels;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++, table += 8) {
+ if (!hws->scratch_vid[ch].cpu)
+ continue;
+
+ /* Program 64-bit BAR remap entry for this channel */
+ {
+ dma_addr_t p = hws->scratch_vid[ch].dma;
+ u32 lo = lower_32_bits(p) & addr_mask;
+ u32 hi = upper_32_bits(p);
+ u32 pci_addr_low = lower_32_bits(p) & addr_low_mask;
+
+ writel_relaxed(hi,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE +
+ table);
+ writel_relaxed(lo,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE +
+ table + PCIE_BARADDROFSIZE);
+
+ /* Per-channel AXI base + PCI low */
+ writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE +
+ pci_addr_low,
+ hws->bar0_base + CVBS_IN_BUF_BASE +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* Half-frame length in /16 units.
+ * Prefer the current channel’s computed half_size if available.
+ * Fall back to half of the probe-owned scratch buffer.
+ */
+ {
+ u32 half_bytes = hws->video[ch].pix.half_size ?
+ hws->video[ch].pix.half_size :
+ (u32)(hws->scratch_vid[ch].size / 2);
+ writel_relaxed(half_bytes / 16,
+ hws->bar0_base +
+ CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+ }
+ }
+ }
+
+ /* Post writes so device sees them before we move on */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+}
+
+static void hws_ack_all_irqs(struct hws_pcie_dev *hws)
+{
+ u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+
+ if (st) {
+ writel(st, hws->bar0_base + HWS_REG_INT_STATUS); /* W1C */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+}
+
+static void hws_open_irq_fabric(struct hws_pcie_dev *hws)
+{
+ /* Route all sources to vector 0 (same value you’re already using) */
+ writel(0x00000000, hws->bar0_base + PCIE_INT_DEC_REG_BASE);
+ (void)readl(hws->bar0_base + PCIE_INT_DEC_REG_BASE);
+
+ /* Turn on the bridge if your IP needs it */
+ 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);
+}
+
+void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable)
+{
+ int i;
+
+ if (hws->start_run && !enable)
+ return;
+
+ /* 1) reset the decoder mode register to 0 */
+ writel(0x00000000, hws->bar0_base + HWS_REG_DEC_MODE);
+ hws_seed_dma_windows(hws);
+
+ /* 3) on a full reset, clear all per-channel status and indices */
+ if (!enable) {
+ for (i = 0; i < hws->max_channels; i++) {
+ /* helpers to arm/disable capture engines */
+ hws_enable_video_capture(hws, i, false);
+ }
+ }
+
+ /* 4) “Start run”: set bit31, wait a bit, then program low 24 bits */
+ writel(0x80000000, hws->bar0_base + HWS_REG_DEC_MODE);
+ // udelay(500);
+ 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);
+ /* 6) record that we're now running */
+ hws->start_run = true;
+}
+
+int hws_check_card_status(struct hws_pcie_dev *hws)
+{
+ u32 status;
+
+ if (!hws || !hws->bar0_base)
+ return -ENODEV;
+
+ status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+
+ /* Common “device missing” pattern */
+ if (status == 0xFFFFFFFF) {
+ hws->pci_lost = true;
+ dev_err(&hws->pdev->dev, "PCIe device not responding\n");
+ return -ENODEV;
+ }
+
+ /* If RUN/READY bit (bit0) isn’t set, (re)initialize 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);
+ /* Optional: verify the core cleared its busy bit, if you have one */
+ /* int ret = hws_check_busy(hws); */
+ /* if (ret) return ret; */
+ }
+
+ return 0;
+}
+
+void check_video_format(struct hws_pcie_dev *pdx)
+{
+ int i;
+
+ for (i = 0; i < pdx->cur_max_video_ch; i++) {
+ bool interlace = false;
+
+ if (!hws_read_active_state(pdx, i, &interlace)) {
+ /* No active video; optionally feed neutral frames to keep streaming. */
+ if (pdx->video[i].signal_loss_cnt == 0)
+ pdx->video[i].signal_loss_cnt = 1;
+ if (READ_ONCE(pdx->video[i].cap_active))
+ hws_force_no_signal_frame(&pdx->video[i],
+ "monitor_nosignal");
+ } else {
+ if (pdx->hw_ver > 0)
+ handle_hwv2_path(pdx, i);
+ else
+ /* Legacy path stub; see handle_legacy_path() comment. */
+ handle_legacy_path(pdx, i);
+
+ update_live_resolution(pdx, i, interlace);
+ pdx->video[i].signal_loss_cnt = 0;
+ }
+ }
+}
+
+static inline void hws_write_if_diff(struct hws_pcie_dev *hws, u32 reg_off,
+ u32 new_val)
+{
+ void __iomem *addr;
+ u32 old;
+
+ if (!hws || !hws->bar0_base)
+ return;
+
+ addr = hws->bar0_base + reg_off;
+
+ old = readl(addr);
+ /* Treat all-ones as device gone; avoid writing garbage. */
+ if (old == 0xFFFFFFFF) {
+ hws->pci_lost = true;
+ return;
+ }
+
+ if (old != new_val) {
+ writel(new_val, addr);
+ /* Post the write on some bridges / enforce ordering. */
+ (void)readl(addr);
+ }
+}
+
+static bool hws_read_active_state(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool *interlace)
+{
+ u32 reg;
+ bool active;
+
+ if (ch >= pdx->cur_max_video_ch)
+ return false;
+
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ active = !!(reg & BIT(ch));
+ if (interlace)
+ *interlace = !!(reg & BIT(8 + ch));
+ return active;
+}
+
+/* Modern hardware path: keep HW registers in sync with current per-channel
+ * software state. Adjust the OUT_* bits below to match your HW contract.
+ */
+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;
+
+ if (!hws || !hws->bar0_base || ch >= hws->max_channels)
+ return;
+
+ vid = &hws->video[ch];
+
+ /* 1) Input frame rate (read-only; log or export via debugfs if wanted) */
+ in_fps = readl(hws->bar0_base + HWS_REG_FRAME_RATE(ch));
+ /* dev_dbg(&hws->pdev->dev, "ch%u input fps=%u\n", ch, in_fps); */
+ (void)in_fps;
+
+ /* 2) Output resolution programming
+ * If your HW expects a separate “scaled” size, add fields to track it.
+ * For now, mirror the current format (fmt_curr) to OUT_RES.
+ */
+ want_out_res = (vid->pix.height << 16) | vid->pix.width;
+ cur_out_res = readl(hws->bar0_base + HWS_REG_OUT_RES(ch));
+ if (cur_out_res != want_out_res)
+ hws_write_if_diff(hws, HWS_REG_OUT_RES(ch), want_out_res);
+
+ /* 3) Output FPS: only program if you actually track a target.
+ * Example heuristic (disabled by default):
+ *
+ * u32 out_fps = (vid->fmt_curr.height >= 1080) ? 60 : 30;
+ * hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), out_fps);
+ */
+
+ /* 4) BCHS controls: pack from per-channel current_* fields */
+ reg = readl(hws->bar0_base + HWS_REG_BCHS(ch));
+ {
+ u8 br = reg & 0xFF;
+ u8 co = (reg >> 8) & 0xFF;
+ u8 hu = (reg >> 16) & 0xFF;
+ u8 sa = (reg >> 24) & 0xFF;
+
+ if (br != vid->current_brightness ||
+ co != vid->current_contrast || hu != vid->current_hue ||
+ sa != vid->current_saturation) {
+ u32 packed = (vid->current_saturation << 24) |
+ (vid->current_hue << 16) |
+ (vid->current_contrast << 8) |
+ vid->current_brightness;
+ hws_write_if_diff(hws, HWS_REG_BCHS(ch), packed);
+ }
+ }
+
+ /* 5) HDCP detect: read only (no cache field in your structs today) */
+ reg = readl(hws->bar0_base + HWS_REG_HDCP_STATUS);
+ /* bool hdcp = !!(reg & BIT(ch)); // use if you later add a field/control */
+}
+
+static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch)
+{
+ /*
+ * Legacy (hw_ver == 0) expected behavior:
+ * - A per-channel SW FPS accumulator incremented on each VDONE.
+ * - A once-per-second poll mapped the count to discrete FPS:
+ * >55*2 => 60, >45*2 => 50, >25*2 => 30, >20*2 => 25, else 60,
+ * then reset the accumulator to 0.
+ * - The *2 factor assumed VDONE fired per-field; if legacy VDONE is
+ * per-frame, drop the factor.
+ *
+ * Current code keeps this path as a no-op; vid->current_fps stays at the
+ * default or mode-derived value. If accurate legacy FPS reporting is
+ * needed (V4L2 g_parm/timeperframe), reintroduce the accumulator in the
+ * IRQ path and perform the mapping/reset here.
+ *
+ * No-op by default. If you introduce a SW FPS accumulator, map it here.
+ *
+ * Example skeleton:
+ *
+ * u32 sw_rate = READ_ONCE(hws->sw_fps[ch]); // incremented elsewhere
+ * if (sw_rate > THRESHOLD) {
+ * u32 fps = pick_fps_from_rate(sw_rate);
+ * hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), fps);
+ * WRITE_ONCE(hws->sw_fps[ch], 0);
+ * }
+ */
+ (void)hws;
+ (void)ch;
+}
+
+static void hws_video_apply_mode_change(struct hws_pcie_dev *pdx,
+ unsigned int ch, u16 w, u16 h,
+ bool interlaced, u32 fps)
+{
+ struct hws_video *v = &pdx->video[ch];
+ unsigned long flags;
+ u32 new_size;
+ bool queue_busy;
+ bool geometry_changed;
+ struct list_head done;
+ struct hwsvideo_buffer *b, *tmp;
+
+ if (!pdx || !pdx->bar0_base)
+ return;
+ if (ch >= pdx->max_channels)
+ return;
+ if (!w || !h || w > MAX_VIDEO_HW_W ||
+ (!interlaced && h > MAX_VIDEO_HW_H) ||
+ (interlaced && (h * 2) > MAX_VIDEO_HW_H))
+ return;
+ if (!fps || fps == 0xFFFFFFFF || fps > 240)
+ fps = (h == 576) ? 50 : 60;
+
+ geometry_changed = w != v->pix.width || h != v->pix.height ||
+ interlaced != v->pix.interlaced;
+ if (!geometry_changed && fps == v->current_fps)
+ return;
+
+ if (!geometry_changed) {
+ /* Refresh cached live timing state, but don't emit a resolution
+ * change event when only the frame rate changes.
+ */
+ mutex_lock(&v->state_lock);
+ v->pix.interlaced = interlaced;
+ v->pix.field = interlaced ? V4L2_FIELD_INTERLACED :
+ V4L2_FIELD_NONE;
+ hws_set_current_dv_timings(v, w, h, interlaced);
+ v->current_fps = fps;
+ mutex_unlock(&v->state_lock);
+ return;
+ }
+
+ if (!mutex_trylock(&v->state_lock))
+ return;
+
+ INIT_LIST_HEAD(&done);
+ queue_busy = vb2_is_busy(&v->buffer_queue);
+
+ WRITE_ONCE(v->stop_requested, true);
+ WRITE_ONCE(v->cap_active, false);
+ /* Publish software stop first so the IRQ completion path sees the stop
+ * before we touch MMIO or the lists. Pairs with READ_ONCE() checks in the
+ * VDONE handler and hws_arm_next() to prevent completions while modes
+ * change.
+ */
+ smp_wmb();
+
+ hws_enable_video_capture(pdx, ch, false);
+ readl(pdx->bar0_base + HWS_REG_INT_STATUS);
+
+ if (v->parent && v->parent->irq >= 0)
+ synchronize_irq(v->parent->irq);
+
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_video_collect_done_locked(v, &done);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* Update software pixel state */
+ v->pix.width = w;
+ v->pix.height = h;
+ v->pix.interlaced = interlaced;
+ hws_set_current_dv_timings(v, w, h, interlaced);
+ v->current_fps = fps;
+
+ new_size = hws_calc_sizeimage(v, w, h, interlaced);
+ v->window_valid = false;
+
+ /* Geometry changes require userspace renegotiation once buffers exist.
+ * Emit SOURCE_CHANGE, mark the queue in error, and let userspace
+ * STREAMOFF/REQBUFS/STREAMON rather than trying to restart capture
+ * with partially drained in-flight state.
+ */
+ if (queue_busy) {
+ struct v4l2_event ev = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+ };
+
+ ev.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
+ v4l2_event_queue(v->video_device, &ev);
+ vb2_queue_error(&v->buffer_queue);
+ } else {
+ v->alloc_sizeimage = PAGE_ALIGN(new_size);
+ WRITE_ONCE(v->stop_requested, false);
+ }
+
+ /* Program HW with new resolution */
+ hws_write_if_diff(pdx, HWS_REG_OUT_RES(ch), (h << 16) | w);
+
+ /* Legacy half-buffer programming */
+ writel(v->pix.half_size / 16,
+ pdx->bar0_base + CVBS_IN_BUF_BASE2 + ch * PCIE_BARADDROFSIZE);
+ (void)readl(pdx->bar0_base + CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* Reset per-channel toggles/counters */
+ WRITE_ONCE(v->last_buf_half_toggle, 0);
+ atomic_set(&v->sequence_number, 0);
+
+ mutex_unlock(&v->state_lock);
+
+ list_for_each_entry_safe(b, tmp, &done, list) {
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+}
+
+static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool interlace)
+{
+ u32 reg = readl(pdx->bar0_base + HWS_REG_IN_RES(ch));
+ u32 fps = readl(pdx->bar0_base + HWS_REG_FRAME_RATE(ch));
+ u16 res_w = reg & 0xFFFF;
+ u16 res_h = (reg >> 16) & 0xFFFF;
+ struct hws_video *vid = &pdx->video[ch];
+ bool geometry_changed;
+ bool fps_changed;
+
+ bool within_hw = (res_w <= MAX_VIDEO_HW_W) &&
+ ((!interlace && res_h <= MAX_VIDEO_HW_H) ||
+ (interlace && (res_h * 2) <= MAX_VIDEO_HW_H));
+
+ if (!within_hw)
+ return;
+
+ geometry_changed = res_w != vid->pix.width ||
+ res_h != vid->pix.height ||
+ interlace != vid->pix.interlaced;
+ fps_changed = fps && fps != 0xFFFFFFFF && fps <= 240 &&
+ fps != vid->current_fps;
+
+ if (geometry_changed || fps_changed)
+ hws_video_apply_mode_change(pdx, ch, res_w, res_h, interlace,
+ fps);
+}
+
+static int hws_open(struct file *file)
+{
+ return v4l2_fh_open(file);
+}
+
+static const struct v4l2_file_operations hws_fops = {
+ .owner = THIS_MODULE,
+ .open = hws_open,
+ .release = vb2_fop_release,
+ .poll = vb2_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = vb2_fop_mmap,
+};
+
+static int hws_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_src_change_event_subscribe(fh, sub);
+ case V4L2_EVENT_CTRL:
+ return v4l2_ctrl_subscribe_event(fh, sub);
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_ioctl_ops hws_ioctl_fops = {
+ /* Core caps/info */
+ .vidioc_querycap = hws_vidioc_querycap,
+
+ /* Pixel format: still needed to report YUYV etc. */
+ .vidioc_enum_fmt_vid_cap = hws_vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = hws_vidioc_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = hws_vidioc_s_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = hws_vidioc_try_fmt_vid_cap,
+
+ /* Buffer queueing / streaming */
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+
+ /* Inputs */
+ .vidioc_enum_input = hws_vidioc_enum_input,
+ .vidioc_g_input = hws_vidioc_g_input,
+ .vidioc_s_input = hws_vidioc_s_input,
+
+ /* DV timings (HDMI/DVI/VESA modes) */
+ .vidioc_query_dv_timings = hws_vidioc_query_dv_timings,
+ .vidioc_enum_dv_timings = hws_vidioc_enum_dv_timings,
+ .vidioc_g_dv_timings = hws_vidioc_g_dv_timings,
+ .vidioc_s_dv_timings = hws_vidioc_s_dv_timings,
+ .vidioc_dv_timings_cap = hws_vidioc_dv_timings_cap,
+
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = hws_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_g_parm = hws_vidioc_g_parm,
+};
+
+static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
+ bool interlaced)
+{
+ /* example for packed 16bpp (YUYV); replace with your real math/align */
+ u32 lines = h; /* full frame lines for sizeimage */
+ u32 bytesperline = ALIGN(w * 2, 64);
+ u32 sizeimage, half0;
+
+ /* publish into pix, since we now carry these in-state */
+ v->pix.bytesperline = bytesperline;
+ sizeimage = bytesperline * lines;
+
+ half0 = sizeimage / 2;
+
+ v->pix.sizeimage = sizeimage;
+ v->pix.half_size = half0; /* first half; second = sizeimage - half0 */
+ v->pix.field = interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
+
+ return v->pix.sizeimage;
+}
+
+static int hws_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
+ unsigned int *nplanes, unsigned int sizes[],
+ struct device *alloc_devs[])
+{
+ struct hws_video *vid = q->drv_priv;
+
+ (void)num_buffers;
+ (void)alloc_devs;
+
+ if (!vid->pix.sizeimage) {
+ vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
+ vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
+ }
+ if (*nplanes) {
+ if (sizes[0] < vid->pix.sizeimage)
+ return -EINVAL;
+ } else {
+ *nplanes = 1;
+ sizes[0] = PAGE_ALIGN(vid->pix.sizeimage);
+ }
+
+ vid->alloc_sizeimage = PAGE_ALIGN(vid->pix.sizeimage);
+ return 0;
+}
+
+static int hws_buffer_prepare(struct vb2_buffer *vb)
+{
+ struct hws_video *vid = vb->vb2_queue->drv_priv;
+ struct hws_pcie_dev *hws = vid->parent;
+ size_t need = vid->pix.sizeimage;
+ dma_addr_t dma_addr;
+
+ if (vb2_plane_size(vb, 0) < need)
+ return -EINVAL;
+
+ /* Validate DMA address alignment */
+ dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ if (dma_addr & 0x3F) { /* 64-byte alignment required */
+ dev_err(&hws->pdev->dev,
+ "Buffer DMA address 0x%llx not 64-byte aligned\n",
+ (unsigned long long)dma_addr);
+ return -EINVAL;
+ }
+
+ vb2_set_plane_payload(vb, 0, need);
+ return 0;
+}
+
+static void hws_buffer_queue(struct vb2_buffer *vb)
+{
+ struct hws_video *vid = vb->vb2_queue->drv_priv;
+ struct hwsvideo_buffer *buf = to_hwsbuf(vb);
+ struct hws_pcie_dev *hws = vid->parent;
+ unsigned long flags;
+
+ dev_dbg(&hws->pdev->dev,
+ "buffer_queue(ch=%u): vb=%p sizeimage=%u q_active=%d\n",
+ vid->channel_index, vb, vid->pix.sizeimage,
+ READ_ONCE(vid->cap_active));
+
+ /* Initialize buffer slot */
+ buf->slot = 0;
+
+ spin_lock_irqsave(&vid->irq_lock, flags);
+ list_add_tail(&buf->list, &vid->capture_queue);
+ vid->queued_count++;
+
+ /* If streaming and no in-flight buffer, prime HW immediately */
+ if (READ_ONCE(vid->cap_active) && !vid->active) {
+ dma_addr_t dma_addr;
+
+ dev_dbg(&hws->pdev->dev,
+ "buffer_queue(ch=%u): priming first vb=%p\n",
+ vid->channel_index, &buf->vb.vb2_buf);
+ list_del_init(&buf->list);
+ vid->queued_count--;
+ vid->active = buf;
+
+ dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(vid->parent, vid->channel_index,
+ dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base + HWS_REG_DMA_ADDR(vid->channel_index));
+
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, vid->channel_index, true);
+ hws_prime_next_locked(vid);
+ } else if (READ_ONCE(vid->cap_active) && vid->active) {
+ hws_prime_next_locked(vid);
+ }
+ spin_unlock_irqrestore(&vid->irq_lock, flags);
+}
+
+static int hws_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct hws_video *v = q->drv_priv;
+ struct hws_pcie_dev *hws = v->parent;
+ struct hwsvideo_buffer *to_program = NULL; /* local copy */
+ struct vb2_buffer *prog_vb2 = NULL;
+ unsigned long flags;
+ int ret;
+
+ dev_dbg(&hws->pdev->dev, "start_streaming: ch=%u count=%u\n",
+ v->channel_index, count);
+
+ ret = hws_check_card_status(hws);
+ if (ret) {
+ struct hwsvideo_buffer *b, *tmp;
+ unsigned long f;
+ LIST_HEAD(queued);
+
+ spin_lock_irqsave(&v->irq_lock, f);
+ if (v->active) {
+ list_add_tail(&v->active->list, &queued);
+ v->active = NULL;
+ }
+ if (v->next_prepared) {
+ list_add_tail(&v->next_prepared->list, &queued);
+ v->next_prepared = NULL;
+ }
+ while (!list_empty(&v->capture_queue)) {
+ b = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_move_tail(&b->list, &queued);
+ }
+ spin_unlock_irqrestore(&v->irq_lock, f);
+
+ list_for_each_entry_safe(b, tmp, &queued, list) {
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+ }
+ return ret;
+ }
+ (void)hws_read_active_state(hws, v->channel_index,
+ &v->pix.interlaced);
+
+ lockdep_assert_held(&v->state_lock);
+ /* init per-stream state */
+ WRITE_ONCE(v->stop_requested, false);
+ WRITE_ONCE(v->cap_active, true);
+ WRITE_ONCE(v->half_seen, false);
+ WRITE_ONCE(v->last_buf_half_toggle, 0);
+
+ /* Try to prime a buffer, but it's OK if none are queued yet */
+ spin_lock_irqsave(&v->irq_lock, flags);
+ if (!v->active && !list_empty(&v->capture_queue)) {
+ to_program = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&to_program->list);
+ v->queued_count--;
+ v->active = to_program;
+ prog_vb2 = &to_program->vb.vb2_buf;
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u took buffer %p\n",
+ v->channel_index, to_program);
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* Only program/enable HW if we actually have a buffer */
+ if (to_program) {
+ if (!prog_vb2)
+ prog_vb2 = &to_program->vb.vb2_buf;
+ {
+ dma_addr_t dma_addr;
+
+ dma_addr = vb2_dma_contig_plane_dma_addr(prog_vb2, 0);
+ hws_program_dma_for_addr(hws, v->channel_index, dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base +
+ HWS_REG_DMA_ADDR(v->channel_index));
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u programmed buffer %p dma=0x%08x\n",
+ v->channel_index, to_program,
+ lower_32_bits(dma_addr));
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, v->channel_index, true);
+ {
+ unsigned long pf;
+
+ spin_lock_irqsave(&v->irq_lock, pf);
+ hws_prime_next_locked(v);
+ spin_unlock_irqrestore(&v->irq_lock, pf);
+ }
+ } else {
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u no buffer yet (will arm on QBUF)\n",
+ v->channel_index);
+ }
+
+ return 0;
+}
+
+static void hws_log_video_state(struct hws_video *v, const char *action,
+ const char *phase)
+{
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned long flags;
+ unsigned int queued = 0;
+ unsigned int tracked = 0;
+ unsigned int seq = 0;
+ struct hwsvideo_buffer *b;
+ bool streaming = 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 = READ_ONCE(v->cap_active);
+ stop_requested = READ_ONCE(v->stop_requested);
+ active = v->active;
+ next_prepared = v->next_prepared;
+ tracked = v->queued_count;
+ seq = (u32)atomic_read(&v->sequence_number);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:%s ch=%u streaming=%d cap=%d stop=%d active=%p next=%p queued=%u tracked=%u seq=%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 = q->drv_priv;
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned long flags;
+ struct hwsvideo_buffer *b, *tmp;
+ LIST_HEAD(done);
+ unsigned int done_cnt = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ hws_log_video_state(v, "streamoff", "begin");
+
+ /* 1) Quiesce SW/HW first */
+ lockdep_assert_held(&v->state_lock);
+ WRITE_ONCE(v->cap_active, false);
+ WRITE_ONCE(v->stop_requested, true);
+
+ hws_enable_video_capture(v->parent, v->channel_index, false);
+
+ /* 2) Collect in-flight + queued under the IRQ lock */
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_video_collect_done_locked(v, &done);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* 3) Complete outside the lock */
+ list_for_each_entry_safe(b, tmp, &done, list) {
+ /* 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=%u completed=%u (%lluus)\n",
+ v->channel_index, done_cnt,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ hws_log_video_state(v, "streamoff", "end");
+}
+
+static const struct vb2_ops hwspcie_video_qops = {
+ .queue_setup = hws_queue_setup,
+ .buf_prepare = hws_buffer_prepare,
+ .buf_init = hws_buf_init,
+ .buf_finish = hws_buf_finish,
+ .buf_cleanup = hws_buf_cleanup,
+ .buf_queue = hws_buffer_queue,
+ .start_streaming = hws_start_streaming,
+ .stop_streaming = hws_stop_streaming,
+};
+
+int hws_video_register(struct hws_pcie_dev *dev)
+{
+ int i, ret;
+
+ ret = v4l2_device_register(&dev->pdev->dev, &dev->v4l2_device);
+ if (ret) {
+ dev_err(&dev->pdev->dev, "v4l2_device_register failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ for (i = 0; i < dev->cur_max_video_ch; i++) {
+ struct hws_video *ch = &dev->video[i];
+ struct video_device *vdev;
+ struct vb2_queue *q;
+
+ /* hws_video_init_channel() should have set:
+ * - ch->parent, ch->channel_index
+ * - locks (state_lock, irq_lock)
+ * - capture_queue (INIT_LIST_HEAD)
+ * - control_handler + controls
+ * - fmt_curr (width/height)
+ * Don’t reinitialize any of those here.
+ */
+
+ vdev = video_device_alloc();
+ if (!vdev) {
+ dev_err(&dev->pdev->dev,
+ "video_device_alloc ch%u failed\n", i);
+ ret = -ENOMEM;
+ goto err_unwind;
+ }
+ ch->video_device = vdev;
+
+ /* Basic V4L2 node setup */
+ snprintf(vdev->name, sizeof(vdev->name), "%s-hdmi%u",
+ KBUILD_MODNAME, i);
+ vdev->v4l2_dev = &dev->v4l2_device;
+ vdev->fops = &hws_fops; /* your file_ops */
+ vdev->ioctl_ops = &hws_ioctl_fops; /* your ioctl_ops */
+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ vdev->lock = &ch->state_lock; /* serialize file ops */
+ vdev->ctrl_handler = &ch->control_handler;
+ vdev->vfl_dir = VFL_DIR_RX;
+ vdev->release = video_device_release;
+ if (ch->control_handler.error) {
+ ret = ch->control_handler.error;
+ goto err_unwind;
+ }
+ video_set_drvdata(vdev, ch);
+
+ /* vb2 queue init (dma-contig) */
+ q = &ch->buffer_queue;
+ memset(q, 0, sizeof(*q));
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_DMABUF;
+ q->drv_priv = ch;
+ q->buf_struct_size = sizeof(struct hwsvideo_buffer);
+ q->ops = &hwspcie_video_qops; /* your vb2_ops */
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &ch->state_lock;
+ q->min_queued_buffers = 1;
+ q->dev = &dev->pdev->dev;
+
+ ret = vb2_queue_init(q);
+ vdev->queue = q;
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "vb2_queue_init ch%u failed: %d\n", i, ret);
+ goto err_unwind;
+ }
+
+ /* Make controls live (no-op if none or already set up) */
+ if (ch->control_handler.error) {
+ ret = ch->control_handler.error;
+ dev_err(&dev->pdev->dev,
+ "ctrl handler ch%u error: %d\n", i, ret);
+ goto err_unwind;
+ }
+ v4l2_ctrl_handler_setup(&ch->control_handler);
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "video_register_device ch%u failed: %d\n", i,
+ ret);
+ goto err_unwind;
+ }
+ }
+
+ return 0;
+
+err_unwind:
+ for (; i >= 0; i--) {
+ struct hws_video *ch = &dev->video[i];
+
+ hws_video_release_registration(ch);
+ }
+ v4l2_device_unregister(&dev->v4l2_device);
+ return ret;
+}
+
+void hws_video_unregister(struct hws_pcie_dev *dev)
+{
+ int i;
+
+ if (!dev)
+ return;
+
+ for (i = 0; i < dev->cur_max_video_ch; i++) {
+ struct hws_video *ch = &dev->video[i];
+
+ hws_video_release_registration(ch);
+ v4l2_ctrl_handler_free(&ch->control_handler);
+ }
+ v4l2_device_unregister(&dev->v4l2_device);
+}
+
+int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason)
+{
+ int i, ret = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ dev_dbg(&hws->pdev->dev, "video:%s:begin channels=%u\n", reason,
+ hws->cur_max_video_ch);
+ for (i = 0; i < hws->cur_max_video_ch; i++) {
+ struct hws_video *vid = &hws->video[i];
+ struct vb2_queue *q = &vid->buffer_queue;
+ u64 ch_start_ns = ktime_get_mono_fast_ns();
+ bool streaming;
+
+ if (!q || !q->ops) {
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d skipped queue-unavailable\n",
+ reason, i);
+ continue;
+ }
+
+ streaming = vb2_is_streaming(q);
+ hws_log_video_state(vid, reason, "channel");
+ if (streaming) {
+ /* Stop via vb2 (runs your .stop_streaming) */
+ int r = vb2_streamoff(q, q->type);
+
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d streamoff ret=%d (%lluus)\n",
+ reason, i, r, (unsigned long long)
+ ((ktime_get_mono_fast_ns() - ch_start_ns) / 1000));
+ if (r && !ret)
+ ret = r;
+ } else {
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d idle (%lluus)\n",
+ reason, i, (unsigned long long)
+ ((ktime_get_mono_fast_ns() - ch_start_ns) / 1000));
+ }
+ }
+ dev_dbg(&hws->pdev->dev, "video:%s:done ret=%d (%lluus)\n", reason,
+ ret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ return ret;
+}
+
+void hws_video_pm_resume(struct hws_pcie_dev *hws)
+{
+ /* Nothing mandatory to do here for vb2 — userspace will STREAMON again.
+ * If you track per-channel 'auto-restart' policy, re-arm it here.
+ */
+}
diff --git a/drivers/media/pci/hws/hws_video.h b/drivers/media/pci/hws/hws_video.h
new file mode 100644
index 000000000000..d02cfb2cdeb3
--- /dev/null
+++ b/drivers/media/pci/hws/hws_video.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_VIDEO_H
+#define HWS_VIDEO_H
+
+struct hws_video;
+
+int hws_video_register(struct hws_pcie_dev *dev);
+void hws_video_unregister(struct hws_pcie_dev *dev);
+void hws_enable_video_capture(struct hws_pcie_dev *hws,
+ unsigned int chan,
+ bool on);
+void hws_prime_next_locked(struct hws_video *vid);
+
+int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch);
+void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch);
+void check_video_format(struct hws_pcie_dev *pdx);
+int hws_check_card_status(struct hws_pcie_dev *hws);
+void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable);
+
+void hws_program_dma_for_addr(struct hws_pcie_dev *hws,
+ unsigned int ch,
+ dma_addr_t dma);
+void hws_set_dma_doorbell(struct hws_pcie_dev *hws, unsigned int ch,
+ dma_addr_t dma, const char *tag);
+
+int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason);
+void hws_video_pm_resume(struct hws_pcie_dev *hws);
+
+#endif // HWS_VIDEO_H
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 2/2] MAINTAINERS: add entry for AVMatrix HWS driver
2026-03-30 19:56 ` [PATCH v3 " hoff.benjamin.k
2026-03-30 19:56 ` [PATCH v3 1/2] " hoff.benjamin.k
@ 2026-03-30 19:56 ` hoff.benjamin.k
2026-03-30 23:36 ` [PATCH v4] media: pci: add AVMatrix HWS capture driver hoff.benjamin.k
1 sibling, 1 reply; 11+ messages in thread
From: hoff.benjamin.k @ 2026-03-30 19:56 UTC (permalink / raw)
To: linux-media; +Cc: linux-kernel, mchehab, hverkuil+cisco, Ben Hoff
From: Ben Hoff <hoff.benjamin.k@gmail.com>
Signed-off-by: Ben Hoff <hoff.benjamin.k@gmail.com>
---
MAINTAINERS | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index c3fe46d7c4bc..2c5511d740f2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7471,6 +7471,12 @@ S: Maintained
F: Documentation/admin-guide/media/mgb4.rst
F: drivers/media/pci/mgb4/
+AVMATRIX HWS DRIVER
+M: Ben Hoff <hoff.benjamin.k@gmail.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/pci/hws/
+
DIOLAN U2C-12 I2C DRIVER
M: Guenter Roeck <linux@roeck-us.net>
L: linux-i2c@vger.kernel.org
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4] media: pci: add AVMatrix HWS capture driver
2026-03-30 19:56 ` [PATCH v3 2/2] MAINTAINERS: add entry for AVMatrix HWS driver hoff.benjamin.k
@ 2026-03-30 23:36 ` hoff.benjamin.k
2026-04-02 6:25 ` kernel test robot
2026-04-03 13:57 ` [PATCH v5] " hoff.benjamin.k
0 siblings, 2 replies; 11+ messages in thread
From: hoff.benjamin.k @ 2026-03-30 23:36 UTC (permalink / raw)
To: linux-media; +Cc: linux-kernel, mchehab, hverkuil+cisco
From: Ben Hoff <hoff.benjamin.k@gmail.com>
Add an in-tree AVMatrix HWS PCIe capture driver. The driver supports
up to four HDMI inputs and exposes the video capture path through
V4L2 with vb2-dma-contig streaming, DV timings, and per-input
controls. Audio support is intentionally omitted from this
submission.
This patch also adds the MAINTAINERS entry for the new driver.
This driver is derived from a GPL out-of-tree driver.
Changes since v3:
- fold the MAINTAINERS update into this patch so per-patch CI sees the
new file pattern
- wrap the validation text for checkpatch
Changes since v2:
- keep scratch DMA allocation on a single probe-owned path
- avoid double-freeing V4L2 control handlers on register unwind
- drop the extra per-node resolution sysfs ABI
- turn live geometry changes into explicit SOURCE_CHANGE renegotiation
- report live DV timings and reject attempts to retime a live source
- stop advertising RESOLUTION source changes for fps-only updates
- keep live fps state across harmless S_FMT restarts
- stop exposing an unvalidated DV RX power-present signal
- clean the imported sources for checkpatch and W=1 builds
Validation:
- build-tested with W=1 against a local kernel build tree
- v4l2-compliance 1.32.0 on /dev/video1: 51 tests succeeded,
0 failed, 1 warning
DV_RX_POWER_PRESENT is intentionally left unsupported in this revision
because current hardware evidence does not expose a validated
receiver-side power-detect signal distinct from active video presence.
Signed-off-by: Ben Hoff <hoff.benjamin.k@gmail.com>
---
MAINTAINERS | 6 +
drivers/media/pci/Kconfig | 1 +
drivers/media/pci/Makefile | 1 +
drivers/media/pci/hws/Kconfig | 12 +
drivers/media/pci/hws/Makefile | 4 +
drivers/media/pci/hws/hws.h | 174 +++
drivers/media/pci/hws/hws_irq.c | 271 +++++
drivers/media/pci/hws/hws_irq.h | 10 +
drivers/media/pci/hws/hws_pci.c | 864 ++++++++++++++
drivers/media/pci/hws/hws_reg.h | 136 +++
drivers/media/pci/hws/hws_v4l2_ioctl.c | 924 +++++++++++++++
drivers/media/pci/hws/hws_v4l2_ioctl.h | 36 +
drivers/media/pci/hws/hws_video.c | 1504 ++++++++++++++++++++++++
drivers/media/pci/hws/hws_video.h | 29 +
14 files changed, 3972 insertions(+)
create mode 100644 drivers/media/pci/hws/Kconfig
create mode 100644 drivers/media/pci/hws/Makefile
create mode 100644 drivers/media/pci/hws/hws.h
create mode 100644 drivers/media/pci/hws/hws_irq.c
create mode 100644 drivers/media/pci/hws/hws_irq.h
create mode 100644 drivers/media/pci/hws/hws_pci.c
create mode 100644 drivers/media/pci/hws/hws_reg.h
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.c
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.h
create mode 100644 drivers/media/pci/hws/hws_video.c
create mode 100644 drivers/media/pci/hws/hws_video.h
diff --git a/MAINTAINERS b/MAINTAINERS
index c3fe46d7c4bc..2c5511d740f2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7471,6 +7471,12 @@ S: Maintained
F: Documentation/admin-guide/media/mgb4.rst
F: drivers/media/pci/mgb4/
+AVMATRIX HWS DRIVER
+M: Ben Hoff <hoff.benjamin.k@gmail.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/pci/hws/
+
DIOLAN U2C-12 I2C DRIVER
M: Guenter Roeck <linux@roeck-us.net>
L: linux-i2c@vger.kernel.org
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index eebb16c58f3d..bfdb200f85a3 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -13,6 +13,7 @@ if MEDIA_PCI_SUPPORT
if MEDIA_CAMERA_SUPPORT
comment "Media capture support"
+source "drivers/media/pci/hws/Kconfig"
source "drivers/media/pci/mgb4/Kconfig"
source "drivers/media/pci/solo6x10/Kconfig"
source "drivers/media/pci/tw5864/Kconfig"
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index 02763ad88511..c4508b6723a9 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
obj-$(CONFIG_VIDEO_CX25821) += cx25821/
obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_DT3155) += dt3155/
+obj-$(CONFIG_VIDEO_HWS) += hws/
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
obj-$(CONFIG_VIDEO_MGB4) += mgb4/
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
diff --git a/drivers/media/pci/hws/Kconfig b/drivers/media/pci/hws/Kconfig
new file mode 100644
index 000000000000..b606d5ffadef
--- /dev/null
+++ b/drivers/media/pci/hws/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_HWS
+ tristate "AVMatrix HWS capture driver"
+ depends on VIDEO_DEV && PCI
+ select VIDEOBUF2_DMA_CONTIG
+ help
+ This is a Video4Linux2 driver for AVMatrix HWS PCIe capture cards.
+ It provides a PCIe capture interface with V4L2 streaming, DV timings,
+ and per-input controls for the supported HWS boards.
+
+ To compile this driver as a module, choose M here: the module will
+ be called hws.
diff --git a/drivers/media/pci/hws/Makefile b/drivers/media/pci/hws/Makefile
new file mode 100644
index 000000000000..a66aebd348e5
--- /dev/null
+++ b/drivers/media/pci/hws/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+hws-objs := hws_pci.o hws_irq.o hws_video.o hws_v4l2_ioctl.o
+
+obj-$(CONFIG_VIDEO_HWS) += hws.o
diff --git a/drivers/media/pci/hws/hws.h b/drivers/media/pci/hws/hws.h
new file mode 100644
index 000000000000..ebc8cc0daf36
--- /dev/null
+++ b/drivers/media/pci/hws/hws.h
@@ -0,0 +1,174 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_PCIE_H
+#define HWS_PCIE_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/sizes.h>
+#include <linux/atomic.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/videobuf2-dma-sg.h>
+
+#include "hws_reg.h"
+
+struct hwsmem_param {
+ u32 index;
+ u32 type;
+ u32 status;
+};
+
+struct hws_pix_state {
+ u32 width;
+ u32 height;
+ u32 fourcc; /* V4L2_PIX_FMT_* (YUYV only here) */
+ u32 bytesperline; /* stride */
+ u32 sizeimage; /* full frame */
+ enum v4l2_field field; /* V4L2_FIELD_NONE or INTERLACED */
+ enum v4l2_colorspace colorspace; /* e.g., REC709 */
+ enum v4l2_ycbcr_encoding ycbcr_enc; /* V4L2_YCBCR_ENC_DEFAULT */
+ enum v4l2_quantization quantization; /* V4L2_QUANTIZATION_LIM_RANGE */
+ enum v4l2_xfer_func xfer_func; /* V4L2_XFER_FUNC_DEFAULT */
+ bool interlaced; /* cached hardware state */
+ u32 half_size; /* optional: if your HW needs it */
+};
+
+#define UNSET (-1U)
+
+struct hws_pcie_dev;
+struct hws_adapter;
+struct hws_video;
+
+struct hwsvideo_buffer {
+ struct vb2_v4l2_buffer vb;
+ struct list_head list;
+ int slot; /* for two-buffer approach */
+};
+
+struct hws_video {
+ /* ───── linkage ───── */
+ struct hws_pcie_dev *parent; /* parent device */
+ struct video_device *video_device;
+
+ struct vb2_queue buffer_queue;
+ struct list_head capture_queue;
+ struct hwsvideo_buffer *active;
+ struct hwsvideo_buffer *next_prepared;
+
+ /* ───── locking ───── */
+ struct mutex state_lock; /* primary state */
+ spinlock_t irq_lock; /* ISR-side */
+
+ /* ───── indices ───── */
+ int channel_index;
+
+ /* ───── colour controls ───── */
+ int current_brightness;
+ int current_contrast;
+ int current_saturation;
+ int current_hue;
+
+ /* ───── V4L2 controls ───── */
+ struct v4l2_ctrl_handler control_handler;
+ struct v4l2_ctrl *ctrl_brightness;
+ struct v4l2_ctrl *ctrl_contrast;
+ struct v4l2_ctrl *ctrl_saturation;
+ struct v4l2_ctrl *ctrl_hue;
+ /* ───── capture queue status ───── */
+ struct hws_pix_state pix;
+ struct v4l2_dv_timings cur_dv_timings; /* last configured/notified DV timings */
+ u32 current_fps; /* Hz, updated by mode changes, not by read-only queries */
+ u32 alloc_sizeimage;
+
+ /* ───── per-channel capture state ───── */
+ bool cap_active;
+ bool stop_requested;
+ u8 last_buf_half_toggle;
+ bool half_seen;
+ atomic_t sequence_number;
+ u32 queued_count;
+
+ /* ───── timeout and error handling ───── */
+ u32 timeout_count;
+ u32 error_count;
+
+ bool window_valid;
+ u32 last_dma_hi;
+ u32 last_dma_page;
+ u32 last_pci_addr;
+ u32 last_half16;
+
+ /* ───── misc counters ───── */
+ int signal_loss_cnt;
+};
+
+static inline void hws_set_current_dv_timings(struct hws_video *vid,
+ u32 width, u32 height,
+ bool interlaced)
+{
+ if (!vid)
+ return;
+
+ vid->cur_dv_timings = (struct v4l2_dv_timings) {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = width,
+ .height = height,
+ .interlaced = interlaced,
+ },
+ };
+}
+
+struct hws_scratch_dma {
+ void *cpu;
+ dma_addr_t dma;
+ size_t size;
+};
+
+struct hws_pcie_dev {
+ /* ───── core objects ───── */
+ struct pci_dev *pdev;
+ struct hws_video video[MAX_VID_CHANNELS];
+
+ /* ───── BAR & workqueues ───── */
+ void __iomem *bar0_base;
+
+ /* ───── device identity / capabilities ───── */
+ u16 vendor_id;
+ u16 device_id;
+ u16 device_ver;
+ u16 hw_ver;
+ u32 sub_ver;
+ u32 port_id;
+ // TriState, used in `set_video_format_size`
+ u32 support_yv12;
+ u32 max_hw_video_buf_sz;
+ u8 max_channels;
+ u8 cur_max_video_ch;
+ bool start_run;
+
+ bool buf_allocated;
+
+ /* ───── V4L2 framework objects ───── */
+ struct v4l2_device v4l2_device;
+
+ /* ───── kernel thread ───── */
+ struct task_struct *main_task;
+ struct hws_scratch_dma scratch_vid[MAX_VID_CHANNELS];
+
+ bool suspended;
+ int irq;
+
+ /* ───── error flags ───── */
+ int pci_lost;
+
+};
+
+#endif
diff --git a/drivers/media/pci/hws/hws_irq.c b/drivers/media/pci/hws/hws_irq.c
new file mode 100644
index 000000000000..0747dfb7ab97
--- /dev/null
+++ b/drivers/media/pci/hws/hws_irq.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/compiler.h>
+#include <linux/moduleparam.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/minmax.h>
+#include <linux/string.h>
+
+#include <media/videobuf2-dma-contig.h>
+
+#include "hws_irq.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws.h"
+
+#define MAX_INT_LOOPS 100
+
+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 = &hws->video[ch];
+ unsigned long flags;
+ struct hwsvideo_buffer *buf;
+
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): stop=%d cap=%d queued=%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=%u): suspended\n", ch);
+ return -EBUSY;
+ }
+
+ if (READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active)) {
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): stop=%d cap=%d -> cancel\n", ch,
+ v->stop_requested, v->cap_active);
+ return -ECANCELED;
+ }
+
+ 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=%u): queue empty\n", ch);
+ return -EAGAIN;
+ }
+
+ buf = list_first_entry(&v->capture_queue, struct hwsvideo_buffer, list);
+ list_del_init(&buf->list); /* keep buffer safe for later cleanup */
+ if (v->queued_count)
+ v->queued_count--;
+ v->active = buf;
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ dev_dbg(&hws->pdev->dev, "arm_next(ch=%u): picked buffer %p\n", ch,
+ buf);
+
+ /* Publish descriptor(s) before doorbell/MMIO kicks. */
+ wmb();
+
+ /* Avoid MMIO during suspend */
+ if (READ_ONCE(hws->suspended)) {
+ unsigned long f;
+
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): suspended after pick\n", ch);
+ spin_lock_irqsave(&v->irq_lock, f);
+ if (v->active) {
+ list_add(&buf->list, &v->capture_queue);
+ v->queued_count++;
+ v->active = NULL;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, f);
+ return -EBUSY;
+ }
+
+ /* Also program the DMA address register directly */
+ {
+ dma_addr_t dma_addr =
+ vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(hws, ch, dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base + HWS_REG_DMA_ADDR(ch));
+ }
+
+ dev_dbg(&hws->pdev->dev, "arm_next(ch=%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);
+ return 0;
+}
+
+static void hws_video_handle_vdone(struct hws_video *v)
+{
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned int ch = v->channel_index;
+ struct hwsvideo_buffer *done;
+ unsigned long flags;
+ bool promoted = false;
+
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): stop=%d cap=%d active=%p\n",
+ ch, READ_ONCE(v->stop_requested), READ_ONCE(v->cap_active),
+ v->active);
+
+ int ret;
+
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): entry stop=%d cap=%d\n", ch,
+ v->stop_requested, v->cap_active);
+ if (READ_ONCE(hws->suspended))
+ return;
+
+ if (READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active))
+ return;
+
+ spin_lock_irqsave(&v->irq_lock, flags);
+ done = v->active;
+ if (done && v->next_prepared) {
+ v->active = v->next_prepared;
+ v->next_prepared = NULL;
+ promoted = true;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* 1) Complete the buffer the HW just finished (if any) */
+ if (done) {
+ struct vb2_v4l2_buffer *vb2v = &done->vb;
+ size_t expected = v->pix.sizeimage;
+ size_t plane_size = vb2_plane_size(&vb2v->vb2_buf, 0);
+
+ if (expected > plane_size) {
+ dev_warn_ratelimited(&hws->pdev->dev,
+ "bh_video(ch=%u): sizeimage %zu > plane %zu, dropping seq=%u\n",
+ ch, expected, plane_size,
+ (u32)atomic_read(&v->sequence_number) + 1);
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_ERROR);
+ goto arm_next;
+ }
+ vb2_set_plane_payload(&vb2v->vb2_buf, 0, expected);
+
+ dma_rmb(); /* device writes visible before userspace sees it */
+
+ vb2v->sequence = (u32)atomic_inc_return(&v->sequence_number);
+ vb2v->vb2_buf.timestamp = ktime_get_ns();
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): DONE buf=%p seq=%u half_seen=%d toggle=%u\n",
+ ch, done, vb2v->sequence, v->half_seen,
+ v->last_buf_half_toggle);
+
+ if (!promoted)
+ v->active = NULL; /* channel no longer owns this buffer */
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+
+ if (READ_ONCE(hws->suspended))
+ return;
+
+ if (promoted) {
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): promoted pre-armed buffer active=%p\n",
+ ch, v->active);
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_prime_next_locked(v);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ return;
+ }
+
+arm_next:
+ /* 2) Immediately arm the next queued buffer (if present) */
+ ret = hws_arm_next(hws, ch);
+ if (ret == -EAGAIN) {
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): no queued buffer to arm\n", ch);
+ return;
+ }
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): armed next buffer, active=%p\n", ch,
+ v->active);
+ /* On success the engine now points at v->active’s DMA address */
+}
+
+irqreturn_t hws_irq_handler(int irq, void *info)
+{
+ struct hws_pcie_dev *pdx = info;
+ u32 int_state;
+
+ dev_dbg(&pdx->pdev->dev, "irq: entry\n");
+ if (pdx->bar0_base) {
+ dev_dbg(&pdx->pdev->dev,
+ "irq: INT_EN=0x%08x INT_STATUS=0x%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 = 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;
+ }
+ // u32 sys_status = readl(pdx->bar0_base + HWS_REG_SYS_STATUS);
+
+ int_state = readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ if (!int_state || int_state == 0xFFFFFFFF) {
+ dev_dbg(&pdx->pdev->dev,
+ "irq: spurious or device-gone int_state=0x%08x\n",
+ int_state);
+ return IRQ_NONE;
+ }
+ dev_dbg(&pdx->pdev->dev, "irq: entry INT_STATUS=0x%08x\n", int_state);
+
+ /* Loop until all pending bits are serviced (max 100 iterations) */
+ for (u32 cnt = 0; int_state && cnt < MAX_INT_LOOPS; ++cnt) {
+ for (unsigned int ch = 0; ch < pdx->cur_max_video_ch; ++ch) {
+ u32 vbit = HWS_INT_VDONE_BIT(ch);
+
+ if (!(int_state & vbit))
+ continue;
+
+ if (READ_ONCE(pdx->video[ch].cap_active) &&
+ !READ_ONCE(pdx->video[ch].stop_requested)) {
+ if (hws_toggle_debug) {
+ u32 toggle =
+ 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=%u toggle=%u handling inline (cap=%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=%u ignored (cap=%d stop=%d)\n",
+ ch,
+ READ_ONCE(pdx->video[ch].cap_active),
+ READ_ONCE(pdx->video[ch].stop_requested));
+ }
+
+ writel(vbit, pdx->bar0_base + HWS_REG_INT_STATUS);
+ (void)readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ /* Re‐read in case new interrupt bits popped while processing */
+ int_state = readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ dev_dbg(&pdx->pdev->dev,
+ "irq: loop cnt=%u new INT_STATUS=0x%08x\n", cnt,
+ int_state);
+ if (cnt + 1 == MAX_INT_LOOPS)
+ dev_warn_ratelimited(&pdx->pdev->dev,
+ "IRQ storm? status=0x%08x\n",
+ int_state);
+ }
+
+ return IRQ_HANDLED;
+}
diff --git a/drivers/media/pci/hws/hws_irq.h b/drivers/media/pci/hws/hws_irq.h
new file mode 100644
index 000000000000..a42867aa0c46
--- /dev/null
+++ b/drivers/media/pci/hws/hws_irq.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_INTERRUPT_H
+#define HWS_INTERRUPT_H
+
+#include <linux/pci.h>
+#include "hws.h"
+
+irqreturn_t hws_irq_handler(int irq, void *info);
+
+#endif /* HWS_INTERRUPT_H */
diff --git a/drivers/media/pci/hws/hws_pci.c b/drivers/media/pci/hws/hws_pci.c
new file mode 100644
index 000000000000..d926a88b35da
--- /dev/null
+++ b/drivers/media/pci/hws/hws_pci.c
@@ -0,0 +1,864 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/iopoll.h>
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/ktime.h>
+#include <linux/pm.h>
+#include <linux/freezer.h>
+#include <linux/pci_regs.h>
+
+#include <media/v4l2-ctrls.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_irq.h"
+#include "hws_v4l2_ioctl.h"
+
+#define DRV_NAME "hws"
+#define HWS_BUSY_POLL_DELAY_US 10
+#define HWS_BUSY_POLL_TIMEOUT_US 1000000
+
+/* register layout inside HWS_REG_DEVICE_INFO */
+#define DEVINFO_VER GENMASK(7, 0)
+#define DEVINFO_SUBVER GENMASK(15, 8)
+#define DEVINFO_YV12 GENMASK(31, 28)
+#define DEVINFO_HWKEY GENMASK(27, 24)
+#define DEVINFO_PORTID GENMASK(25, 24) /* low 2 bits of HW-key */
+
+#define MAKE_ENTRY(__vend, __chip, __subven, __subdev, __configptr) \
+ { .vendor = (__vend), \
+ .device = (__chip), \
+ .subvendor = (__subven), \
+ .subdevice = (__subdev), \
+ .driver_data = (unsigned long)(__configptr) }
+
+/*
+ * PCI IDs for HWS family cards.
+ *
+ * The subsystem IDs are fixed at 0x8888:0x0007 for this family. Some boards
+ * enumerate with vendor ID 0x8888 or 0x1f33. Exact SKU names are not fully
+ * pinned down yet; update these comments when vendor documentation or INF
+ * strings are available.
+ */
+static const struct pci_device_id hws_pci_table[] = {
+ /* HWS family, SKU unknown. */
+ MAKE_ENTRY(0x8888, 0x9534, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x8534, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x8554, 0x8888, 0x0007, NULL),
+
+ /* HWS 2x2 HDMI family. */
+ MAKE_ENTRY(0x8888, 0x8524, 0x8888, 0x0007, NULL),
+ /* HWS 2x2 SDI family. */
+ MAKE_ENTRY(0x1F33, 0x6524, 0x8888, 0x0007, NULL),
+
+ /* HWS X4 HDMI family. */
+ MAKE_ENTRY(0x8888, 0x8504, 0x8888, 0x0007, NULL),
+ /* HWS X4 SDI family. */
+ MAKE_ENTRY(0x8888, 0x6504, 0x8888, 0x0007, NULL),
+
+ /* HWS family, SKU unknown. */
+ MAKE_ENTRY(0x8888, 0x8532, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x8888, 0x8512, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x8888, 0x8501, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x6502, 0x8888, 0x0007, NULL),
+
+ /* HWS X4 HDMI family (alternate vendor ID). */
+ MAKE_ENTRY(0x1F33, 0x8504, 0x8888, 0x0007, NULL),
+ /* HWS 2x2 HDMI family (alternate vendor ID). */
+ MAKE_ENTRY(0x1F33, 0x8524, 0x8888, 0x0007, NULL),
+
+ {}
+};
+
+static void enable_pcie_relaxed_ordering(struct pci_dev *dev)
+{
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
+}
+
+static void hws_configure_hardware_capabilities(struct hws_pcie_dev *hdev)
+{
+ u16 id = hdev->device_id;
+
+ /* select per-chip channel counts */
+ switch (id) {
+ case 0x9534:
+ case 0x6524:
+ case 0x8524:
+ case 0x8504:
+ case 0x6504:
+ hdev->cur_max_video_ch = 4;
+ break;
+ case 0x8532:
+ hdev->cur_max_video_ch = 2;
+ break;
+ case 0x8512:
+ case 0x6502:
+ hdev->cur_max_video_ch = 2;
+ break;
+ case 0x8501:
+ hdev->cur_max_video_ch = 1;
+ break;
+ default:
+ hdev->cur_max_video_ch = 4;
+ break;
+ }
+
+ /* universal buffer capacity */
+ hdev->max_hw_video_buf_sz = MAX_MM_VIDEO_SIZE;
+
+ /* decide hardware-version and program DMA max size if needed */
+ if (hdev->device_ver > 121) {
+ if (id == 0x8501 && hdev->device_ver == 122) {
+ hdev->hw_ver = 0;
+ } else {
+ hdev->hw_ver = 1;
+ u32 dma_max = (u32)(MAX_VIDEO_SCALER_SIZE / 16);
+
+ writel(dma_max, hdev->bar0_base + HWS_REG_DMA_MAX_SIZE);
+ /* readback to flush posted MMIO write */
+ (void)readl(hdev->bar0_base + HWS_REG_DMA_MAX_SIZE);
+ }
+ } else {
+ hdev->hw_ver = 0;
+ }
+}
+
+static void hws_stop_device(struct hws_pcie_dev *hws);
+
+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 = &hws->pdev->dev;
+ if (!hws->bar0_base) {
+ dev_dbg(dev,
+ "lifecycle:%s:%s bar0-unmapped suspended=%d start_run=%d pci_lost=%d irq=%d\n",
+ action, phase, READ_ONCE(hws->suspended), hws->start_run,
+ hws->pci_lost, hws->irq);
+ return;
+ }
+
+ int_en = readl(hws->bar0_base + INT_EN_REG_BASE);
+ int_status = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ vcap = readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ sys_status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+ dec_mode = readl(hws->bar0_base + HWS_REG_DEC_MODE);
+
+ dev_dbg(dev,
+ "lifecycle:%s:%s suspended=%d start_run=%d pci_lost=%d irq=%d INT_EN=0x%08x INT_STATUS=0x%08x VCAP=0x%08x SYS=0x%08x DEC=0x%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;
+ /* mirror PCI IDs for later switches */
+ hdev->device_id = hdev->pdev->device;
+ hdev->vendor_id = hdev->pdev->vendor;
+
+ reg = readl(hdev->bar0_base + HWS_REG_DEVICE_INFO);
+
+ hdev->device_ver = FIELD_GET(DEVINFO_VER, reg);
+ hdev->sub_ver = FIELD_GET(DEVINFO_SUBVER, reg);
+ hdev->support_yv12 = FIELD_GET(DEVINFO_YV12, reg);
+ hdev->port_id = FIELD_GET(DEVINFO_PORTID, reg);
+
+ hdev->max_hw_video_buf_sz = MAX_MM_VIDEO_SIZE;
+ hdev->max_channels = 4;
+ hdev->buf_allocated = false;
+ hdev->main_task = NULL;
+ hdev->start_run = false;
+ hdev->pci_lost = 0;
+
+ writel(0x00, hdev->bar0_base + HWS_REG_DEC_MODE);
+ writel(0x10, hdev->bar0_base + HWS_REG_DEC_MODE);
+
+ hws_configure_hardware_capabilities(hdev);
+
+ dev_info(&hdev->pdev->dev,
+ "chip detected: ver=%u subver=%u port=%u yv12=%u\n",
+ hdev->device_ver, hdev->sub_ver, hdev->port_id,
+ hdev->support_yv12);
+
+ return 0;
+}
+
+static int main_ks_thread_handle(void *data)
+{
+ struct hws_pcie_dev *pdx = data;
+
+ set_freezable();
+
+ while (!kthread_should_stop()) {
+ /* If we’re suspending, don’t touch hardware; just sleep/freeeze */
+ if (READ_ONCE(pdx->suspended)) {
+ try_to_freeze();
+ schedule_timeout_interruptible(msecs_to_jiffies(1000));
+ continue;
+ }
+
+ /* avoid MMIO when suspended (guarded above) */
+ check_video_format(pdx);
+
+ try_to_freeze(); /* cooperate with freezer each loop */
+
+ /* Sleep 1s or until signaled to wake/stop */
+ schedule_timeout_interruptible(msecs_to_jiffies(1000));
+ }
+
+ dev_dbg(&pdx->pdev->dev, "%s: exiting\n", __func__);
+ return 0;
+}
+
+static void hws_stop_kthread_action(void *data)
+{
+ struct hws_pcie_dev *hws = data;
+ struct task_struct *t;
+ u64 start_ns;
+
+ if (!hws)
+ return;
+
+ t = READ_ONCE(hws->main_task);
+ if (!IS_ERR_OR_NULL(t)) {
+ start_ns = ktime_get_mono_fast_ns();
+ dev_dbg(&hws->pdev->dev,
+ "lifecycle:kthread-stop:begin task=%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",
+ (unsigned long long)
+ ((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ }
+}
+
+static int hws_alloc_seed_buffers(struct hws_pcie_dev *hws)
+{
+ int ch;
+ /* 64 KiB is plenty for a safe dummy; align to 64 for your HW */
+ const size_t need = ALIGN(64 * 1024, 64);
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+#if defined(CONFIG_HAS_DMA) /* normal on PCIe platforms */
+ void *cpu = dma_alloc_coherent(&hws->pdev->dev, need,
+ &hws->scratch_vid[ch].dma,
+ GFP_KERNEL);
+#else
+ void *cpu = NULL;
+#endif
+ if (!cpu) {
+ dev_warn(&hws->pdev->dev,
+ "scratch: dma_alloc_coherent failed ch=%d\n", ch);
+ /* not fatal: free earlier ones and continue without seeding */
+ while (--ch >= 0) {
+ if (hws->scratch_vid[ch].cpu)
+ dma_free_coherent(&hws->pdev->dev,
+ hws->scratch_vid[ch].size,
+ hws->scratch_vid[ch].cpu,
+ hws->scratch_vid[ch].dma);
+ hws->scratch_vid[ch].cpu = NULL;
+ hws->scratch_vid[ch].size = 0;
+ }
+ return -ENOMEM;
+ }
+ hws->scratch_vid[ch].cpu = cpu;
+ hws->scratch_vid[ch].size = need;
+ }
+ return 0;
+}
+
+static void hws_free_seed_buffers(struct hws_pcie_dev *hws)
+{
+ int ch;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+ if (hws->scratch_vid[ch].cpu) {
+ dma_free_coherent(&hws->pdev->dev,
+ hws->scratch_vid[ch].size,
+ hws->scratch_vid[ch].cpu,
+ hws->scratch_vid[ch].dma);
+ hws->scratch_vid[ch].cpu = NULL;
+ hws->scratch_vid[ch].size = 0;
+ }
+ }
+}
+
+static void hws_seed_channel(struct hws_pcie_dev *hws, int ch)
+{
+ dma_addr_t paddr = hws->scratch_vid[ch].dma;
+ u32 lo = lower_32_bits(paddr);
+ u32 hi = upper_32_bits(paddr);
+ u32 pci_addr = lo & PCI_E_BAR_ADD_LOWMASK;
+
+ lo &= PCI_E_BAR_ADD_MASK;
+
+ /* Program 64-bit BAR remap entry for this channel (table @ 0x208 + ch * 8) */
+ writel_relaxed(hi, hws->bar0_base +
+ PCI_ADDR_TABLE_BASE + 0x208 + ch * 8);
+ writel_relaxed(lo, hws->bar0_base +
+ PCI_ADDR_TABLE_BASE + 0x208 + ch * 8 +
+ PCIE_BARADDROFSIZE);
+
+ /* Program capture engine per-channel base/half */
+ writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
+ hws->bar0_base + CVBS_IN_BUF_BASE +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* half size: use either the current format’s half or half of scratch */
+ {
+ u32 half = hws->video[ch].pix.half_size ?
+ hws->video[ch].pix.half_size :
+ (u32)(hws->scratch_vid[ch].size / 2);
+
+ writel_relaxed(half / 16,
+ hws->bar0_base + CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+ }
+
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS); /* flush posted writes */
+}
+
+static void hws_seed_all_channels(struct hws_pcie_dev *hws)
+{
+ int ch;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+ if (hws->scratch_vid[ch].cpu)
+ hws_seed_channel(hws, ch);
+ }
+}
+
+static void hws_irq_mask_gate(struct hws_pcie_dev *hws)
+{
+ writel(0x00000000, hws->bar0_base + INT_EN_REG_BASE);
+ (void)readl(hws->bar0_base + INT_EN_REG_BASE);
+}
+
+static void hws_irq_unmask_gate(struct hws_pcie_dev *hws)
+{
+ writel(HWS_INT_EN_MASK, hws->bar0_base + INT_EN_REG_BASE);
+ (void)readl(hws->bar0_base + INT_EN_REG_BASE);
+}
+
+static void hws_irq_clear_pending(struct hws_pcie_dev *hws)
+{
+ u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+
+ if (st) {
+ writel(st, hws->bar0_base + HWS_REG_INT_STATUS); /* W1C */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+}
+
+static void hws_block_hotpaths(struct hws_pcie_dev *hws)
+{
+ WRITE_ONCE(hws->suspended, true);
+ if (hws->irq >= 0)
+ disable_irq(hws->irq);
+
+ if (!hws->bar0_base)
+ return;
+
+ hws_irq_mask_gate(hws);
+ hws_irq_clear_pending(hws);
+}
+
+static int hws_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+ struct hws_pcie_dev *hws;
+ int i, ret, irq;
+ unsigned long irqf = 0;
+ bool v4l2_registered = false;
+
+ /* devres-backed device object */
+ hws = devm_kzalloc(&pdev->dev, sizeof(*hws), GFP_KERNEL);
+ if (!hws)
+ return -ENOMEM;
+
+ hws->pdev = pdev;
+ hws->irq = -1;
+ hws->suspended = false;
+ pci_set_drvdata(pdev, hws);
+
+ /* 1) Enable device + bus mastering (managed) */
+ ret = pcim_enable_device(pdev);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "pcim_enable_device\n");
+ pci_set_master(pdev);
+
+ /* 2) Map BAR0 (managed) */
+ ret = pcim_iomap_regions(pdev, BIT(0), KBUILD_MODNAME);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "pcim_iomap_regions BAR0\n");
+ hws->bar0_base = pcim_iomap_table(pdev)[0];
+
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+ if (ret) {
+ dev_warn(&pdev->dev,
+ "64-bit DMA mask unavailable, falling back to 32-bit (%d)\n",
+ ret);
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ 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");
+ }
+
+ /* 3) Optional PCIe tuning (same as before) */
+ enable_pcie_relaxed_ordering(pdev);
+#ifdef CONFIG_ARCH_TI816X
+ pcie_set_readrq(pdev, 128);
+#endif
+
+ /* 4) Identify chip & capabilities */
+ read_chip_id(hws);
+ dev_info(&pdev->dev, "Device VID=0x%04x DID=0x%04x\n",
+ pdev->vendor, pdev->device);
+ hws_init_video_sys(hws, false);
+
+ /* 5) Init channels (video state, locks, vb2, ctrls) */
+ for (i = 0; i < hws->max_channels; i++) {
+ ret = hws_video_init_channel(hws, i);
+ if (ret) {
+ dev_err(&pdev->dev, "video channel init failed (ch=%d)\n", i);
+ goto err_unwind_channels;
+ }
+ }
+
+ /* 6) Allocate scratch DMA and seed BAR table + channel base/half (legacy SetDMAAddress) */
+ ret = hws_alloc_seed_buffers(hws);
+ if (!ret)
+ hws_seed_all_channels(hws);
+
+ /* 7) Start-run sequence (like InitVideoSys) */
+ hws_init_video_sys(hws, false);
+
+ /* A) Force legacy INTx; legacy used request_irq(pdev->irq, ..., IRQF_SHARED) */
+ pci_intx(pdev, 1);
+ irqf = IRQF_SHARED;
+ irq = pdev->irq;
+ hws->irq = irq;
+ dev_info(&pdev->dev, "IRQ mode: legacy INTx (shared), irq=%d\n", irq);
+
+ /* B) Mask the device's global/bridge gate (INT_EN_REG_BASE) */
+ hws_irq_mask_gate(hws);
+
+ /* C) Clear any sticky pending interrupt status (W1C) before we arm the line */
+ hws_irq_clear_pending(hws);
+
+ /* D) Request the legacy shared interrupt line (no vectors/MSI/MSI-X) */
+ ret = devm_request_irq(&pdev->dev, irq, hws_irq_handler, irqf,
+ dev_name(&pdev->dev), hws);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq(%d) failed: %d\n", irq, ret);
+ goto err_unwind_channels;
+ }
+
+ /* E) Set the global interrupt enable bit in main control register */
+ {
+ u32 ctl_reg = readl(hws->bar0_base + HWS_REG_CTL);
+
+ ctl_reg |= 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");
+ }
+
+ /* F) Open the global gate just like legacy did */
+ hws_irq_unmask_gate(hws);
+ dev_info(&pdev->dev, "INT_EN_GATE readback=0x%08x\n",
+ readl(hws->bar0_base + INT_EN_REG_BASE));
+
+ /* 11) Register V4L2 */
+ ret = hws_video_register(hws);
+ if (ret) {
+ dev_err(&pdev->dev, "video_register: %d\n", ret);
+ goto err_unwind_channels;
+ }
+ v4l2_registered = true;
+
+ /* 12) Background monitor thread (managed) */
+ hws->main_task = kthread_run(main_ks_thread_handle, hws, "hws-mon");
+ if (IS_ERR(hws->main_task)) {
+ ret = PTR_ERR(hws->main_task);
+ hws->main_task = NULL;
+ dev_err(&pdev->dev, "kthread_run: %d\n", ret);
+ goto err_unregister_va;
+ }
+ ret = devm_add_action_or_reset(&pdev->dev, hws_stop_kthread_action, hws);
+ if (ret) {
+ dev_err(&pdev->dev, "devm_add_action kthread_stop: %d\n", ret);
+ goto err_unregister_va; /* reset already stopped the thread */
+ }
+
+ /* 13) Final: show the line is armed */
+ dev_info(&pdev->dev, "irq handler installed on irq=%d\n", irq);
+ return 0;
+
+err_unregister_va:
+ hws_stop_device(hws);
+ hws_video_unregister(hws);
+ hws_free_seed_buffers(hws);
+ return ret;
+err_unwind_channels:
+ hws_free_seed_buffers(hws);
+ if (!v4l2_registered) {
+ while (--i >= 0)
+ hws_video_cleanup_channel(hws, i);
+ }
+ return ret;
+}
+
+static int hws_check_busy(struct hws_pcie_dev *pdx)
+{
+ void __iomem *reg = pdx->bar0_base + HWS_REG_SYS_STATUS;
+ u32 val;
+ int ret;
+
+ /* poll until !(val & BUSY_BIT), sleeping HWS_BUSY_POLL_DELAY_US between reads */
+ ret = readl_poll_timeout(reg, val, !(val & HWS_SYS_DMA_BUSY_BIT),
+ HWS_BUSY_POLL_DELAY_US,
+ HWS_BUSY_POLL_TIMEOUT_US);
+ if (ret) {
+ dev_err(&pdx->pdev->dev,
+ "SYS_STATUS busy bit never cleared (0x%08x)\n", val);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static void hws_stop_dsp(struct hws_pcie_dev *hws)
+{
+ u32 status;
+
+ /* Read the decoder mode/status register */
+ status = readl(hws->bar0_base + HWS_REG_DEC_MODE);
+ dev_dbg(&hws->pdev->dev, "%s: status=0x%08x\n", __func__, status);
+
+ /* If the device looks unplugged/stuck, bail out */
+ if (status == 0xFFFFFFFF)
+ return;
+
+ /* Tell the DSP to stop */
+ writel(0x10, hws->bar0_base + HWS_REG_DEC_MODE);
+
+ if (hws_check_busy(hws))
+ dev_warn(&hws->pdev->dev, "DSP busy timeout on stop\n");
+ /* Disable video capture engine in the DSP */
+ writel(0x0, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+}
+
+/* Publish stop so ISR/BH won’t touch video buffers anymore. */
+static void hws_publish_stop_flags(struct hws_pcie_dev *hws)
+{
+ unsigned int i;
+
+ for (i = 0; i < hws->cur_max_video_ch; ++i) {
+ struct hws_video *v = &hws->video[i];
+
+ WRITE_ONCE(v->cap_active, false);
+ WRITE_ONCE(v->stop_requested, true);
+ }
+
+ smp_wmb(); /* make flags visible before we touch MMIO/queues */
+}
+
+/* Drain engines + ISR/BH after flags are published. */
+static void hws_drain_after_stop(struct hws_pcie_dev *hws)
+{
+ u32 ackmask = 0;
+ unsigned int i;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ /* Mask device enables: no new DMA starts. */
+ writel(0x0, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS); /* flush */
+
+ /* Let any in-flight DMAs finish (best-effort). */
+ (void)hws_check_busy(hws);
+
+ /* Ack any latched VDONE. */
+ for (i = 0; i < hws->cur_max_video_ch; ++i)
+ ackmask |= HWS_INT_VDONE_BIT(i);
+ if (ackmask) {
+ writel(ackmask, hws->bar0_base + HWS_REG_INT_STATUS);
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ /* Ensure no hard IRQ is still running. */
+ if (hws->irq >= 0)
+ synchronize_irq(hws->irq);
+
+ dev_dbg(&hws->pdev->dev, "lifecycle:drain-after-stop:done (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+}
+
+static void hws_stop_device(struct hws_pcie_dev *hws)
+{
+ u32 status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+ u64 start_ns = ktime_get_mono_fast_ns();
+ bool live = status != 0xFFFFFFFF;
+
+ dev_dbg(&hws->pdev->dev, "%s: status=0x%08x\n", __func__, status);
+ if (!live) {
+ hws->pci_lost = true;
+ goto out;
+ }
+ hws_log_lifecycle_snapshot(hws, "stop-device", "begin");
+
+ /* Make ISR/BH a no-op, then drain engines/IRQ. */
+ hws_publish_stop_flags(hws);
+ hws_drain_after_stop(hws);
+
+ /* 1) Stop the on-board DSP */
+ hws_stop_dsp(hws);
+
+out:
+ hws->start_run = 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",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ dev_dbg(&hws->pdev->dev, "%s: complete\n", __func__);
+}
+
+static int hws_quiesce_for_transition(struct hws_pcie_dev *hws,
+ const char *action,
+ bool stop_thread)
+{
+ struct device *dev = &hws->pdev->dev;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+ int vret;
+
+ hws_log_lifecycle_snapshot(hws, action, "begin");
+
+ step_ns = ktime_get_mono_fast_ns();
+ hws_block_hotpaths(hws);
+ dev_dbg(dev, "lifecycle:%s:block-hotpaths (%lluus)\n", action,
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ hws_log_lifecycle_snapshot(hws, action, "blocked");
+
+ if (stop_thread) {
+ step_ns = ktime_get_mono_fast_ns();
+ hws_stop_kthread_action(hws);
+ dev_dbg(dev, "lifecycle:%s:stop-kthread (%lluus)\n", action,
+ (unsigned long long)
+ ((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ }
+
+ step_ns = ktime_get_mono_fast_ns();
+ vret = hws_video_quiesce(hws, action);
+ dev_dbg(dev, "lifecycle:%s:video-quiesce ret=%d (%lluus)\n", action,
+ vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ if (vret)
+ dev_warn(dev, "lifecycle:%s video quiesce returned %d\n",
+ action, vret);
+
+ step_ns = ktime_get_mono_fast_ns();
+ hws_stop_device(hws);
+ dev_dbg(dev, "lifecycle:%s:stop-device (%lluus)\n", action,
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ hws_log_lifecycle_snapshot(hws, action, "end");
+ dev_dbg(dev, "lifecycle:%s:quiesce-done ret=%d (%lluus)\n", action,
+ vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+
+ return vret;
+}
+
+static void hws_remove(struct pci_dev *pdev)
+{
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ u64 start_ns;
+
+ if (!hws)
+ return;
+
+ start_ns = 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);
+
+ /* Stop hardware / capture cleanly (your helper) */
+ hws_stop_device(hws);
+
+ /* Unregister subsystems you registered */
+ hws_video_unregister(hws);
+
+ /* Release seeded DMA buffers */
+ hws_free_seed_buffers(hws);
+ /* kthread is stopped by the devm action you added in probe */
+ hws_log_lifecycle_snapshot(hws, "remove", "end");
+ dev_info(&pdev->dev, "lifecycle:remove done (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int hws_pm_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int vret;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ dev_info(dev, "lifecycle:pm_suspend begin\n");
+ vret = hws_quiesce_for_transition(hws, "pm_suspend", false);
+
+ step_ns = 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",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ dev_info(dev, "lifecycle:pm_suspend done ret=%d (%lluus)\n", vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+
+ return 0;
+}
+
+static int hws_pm_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int ret;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ dev_info(dev, "lifecycle:pm_resume begin\n");
+
+ /* Back to D0 and re-enable the function */
+ step_ns = ktime_get_mono_fast_ns();
+ pci_set_power_state(pdev, PCI_D0);
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(dev, "pci_enable_device: %d\n", ret);
+ return ret;
+ }
+ pci_restore_state(pdev);
+ pci_set_master(pdev);
+ dev_dbg(dev, "lifecycle:pm_resume:pci-enable (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+
+ /* Reapply any PCIe tuning lost across D3 */
+ enable_pcie_relaxed_ordering(pdev);
+
+ /* Reinitialize chip-side capabilities / registers */
+ step_ns = 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",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+
+ /* IRQs can be re-enabled now that MMIO is sane */
+ step_ns = ktime_get_mono_fast_ns();
+ if (hws->irq >= 0)
+ enable_irq(hws->irq);
+
+ WRITE_ONCE(hws->suspended, false);
+ dev_dbg(dev, "lifecycle:pm_resume:irq-unsuspend (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+
+ /* vb2: nothing mandatory; userspace will STREAMON again when ready */
+ step_ns = ktime_get_mono_fast_ns();
+ hws_video_pm_resume(hws);
+ dev_dbg(dev, "lifecycle:pm_resume:video-resume (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ hws_log_lifecycle_snapshot(hws, "pm_resume", "end");
+ dev_info(dev, "lifecycle:pm_resume done (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(hws_pm_ops, hws_pm_suspend, hws_pm_resume);
+# define HWS_PM_OPS (&hws_pm_ops)
+#else
+# define HWS_PM_OPS NULL
+#endif
+
+static void hws_shutdown(struct pci_dev *pdev)
+{
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int vret = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ if (!hws)
+ return;
+
+ dev_info(&pdev->dev, "lifecycle:pci_shutdown begin\n");
+ vret = hws_quiesce_for_transition(hws, "pci_shutdown", true);
+
+ step_ns = ktime_get_mono_fast_ns();
+ pci_clear_master(pdev);
+ dev_dbg(&pdev->dev, "lifecycle:pci_shutdown:clear-master (%lluus)\n",
+ (unsigned long long)((ktime_get_mono_fast_ns() - step_ns) / 1000));
+ dev_info(&pdev->dev, "lifecycle:pci_shutdown done ret=%d (%lluus)\n",
+ vret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+}
+
+static struct pci_driver hws_pci_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = hws_pci_table,
+ .probe = hws_probe,
+ .remove = hws_remove,
+ .shutdown = hws_shutdown,
+ .driver = {
+ .pm = HWS_PM_OPS,
+ },
+};
+
+MODULE_DEVICE_TABLE(pci, hws_pci_table);
+
+static int __init pcie_hws_init(void)
+{
+ return pci_register_driver(&hws_pci_driver);
+}
+
+static void __exit pcie_hws_exit(void)
+{
+ pci_unregister_driver(&hws_pci_driver);
+}
+
+module_init(pcie_hws_init);
+module_exit(pcie_hws_exit);
+
+MODULE_DESCRIPTION(DRV_NAME);
+MODULE_AUTHOR("Ben Hoff <hoff.benjamin.k@gmail.com>");
+MODULE_AUTHOR("Sales <sales@avmatrix.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("DMA_BUF");
diff --git a/drivers/media/pci/hws/hws_reg.h b/drivers/media/pci/hws/hws_reg.h
new file mode 100644
index 000000000000..e4fb4af44434
--- /dev/null
+++ b/drivers/media/pci/hws/hws_reg.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _HWS_PCIE_REG_H
+#define _HWS_PCIE_REG_H
+
+#include <linux/bits.h>
+#include <linux/sizes.h>
+
+#define XDMA_CHANNEL_NUM_MAX (1)
+#define MAX_NUM_ENGINES (XDMA_CHANNEL_NUM_MAX * 2)
+
+#define PCIE_BARADDROFSIZE 4u
+
+#define PCI_BUS_ACCESS_BASE 0x00000000U
+#define INT_EN_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0134U)
+#define PCIEBR_EN_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0148U)
+#define PCIE_INT_DEC_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0138U)
+
+#define HWS_INT_EN_MASK 0x0003FFFFU
+
+#define PCIEBAR_AXI_BASE 0x20000000U
+
+#define CTL_REG_ACC_BASE 0x0
+#define PCI_ADDR_TABLE_BASE CTL_REG_ACC_BASE
+
+#define CVBS_IN_BASE 0x00004000U
+#define CVBS_IN_BUF_BASE (CVBS_IN_BASE + (16U * PCIE_BARADDROFSIZE))
+#define CVBS_IN_BUF_BASE2 (CVBS_IN_BASE + (50U * PCIE_BARADDROFSIZE))
+
+/* 2 Mib */
+#define MAX_L_VIDEO_SIZE 0x200000U
+
+#define PCI_E_BAR_PAGE_SIZE 0x20000000
+#define PCI_E_BAR_ADD_MASK 0xE0000000
+#define PCI_E_BAR_ADD_LOWMASK 0x1FFFFFFF
+
+#define MAX_VID_CHANNELS 4
+
+#define MAX_MM_VIDEO_SIZE SZ_4M
+
+#define MAX_VIDEO_HW_W 1920
+#define MAX_VIDEO_HW_H 1080
+#define MAX_VIDEO_SCALER_SIZE (1920U * 1080U * 2U)
+
+#define MIN_VAMP_BRIGHTNESS_UNITS 0
+#define MAX_VAMP_BRIGHTNESS_UNITS 0xff
+
+#define MIN_VAMP_CONTRAST_UNITS 0
+#define MAX_VAMP_CONTRAST_UNITS 0xff
+
+#define MIN_VAMP_SATURATION_UNITS 0
+#define MAX_VAMP_SATURATION_UNITS 0xff
+
+#define MIN_VAMP_HUE_UNITS 0
+#define MAX_VAMP_HUE_UNITS 0xff
+
+#define HWS_BRIGHTNESS_DEFAULT 0x80
+#define HWS_CONTRAST_DEFAULT 0x80
+#define HWS_SATURATION_DEFAULT 0x80
+#define HWS_HUE_DEFAULT 0x00
+
+/* Core/global status. */
+#define HWS_REG_SYS_STATUS (CVBS_IN_BASE + 0 * PCIE_BARADDROFSIZE)
+/* bit3: DMA busy, bit2: int, ... */
+
+#define HWS_SYS_DMA_BUSY_BIT BIT(3) /* 0x08 = DMA busy flag */
+
+#define HWS_REG_DEC_MODE (CVBS_IN_BASE + 0 * PCIE_BARADDROFSIZE)
+/* Main control register */
+#define HWS_REG_CTL (CVBS_IN_BASE + 4 * PCIE_BARADDROFSIZE)
+#define HWS_CTL_IRQ_ENABLE_BIT BIT(0) /* Global interrupt enable bit */
+/* Write 0x00 to fully reset decoder,
+ * set bit 31=1 to "start run",
+ * low byte=0x13 selects YUYV/BT.709/etc,
+ * in ReadChipId() we also write 0x00 and 0x10 here for chip-ID sequencing.
+ */
+
+/* Per-channel done flags. */
+#define HWS_REG_INT_STATUS (CVBS_IN_BASE + 1 * PCIE_BARADDROFSIZE)
+#define HWS_SYS_BUSY_BIT BIT(2) /* matches old 0x04 test */
+
+/* Capture enable switches. */
+/* bit0-3: CH0-CH3 video enable */
+#define HWS_REG_VCAP_ENABLE (CVBS_IN_BASE + 2 * PCIE_BARADDROFSIZE)
+/* bits0-3: signal present, bits8-11: interlace */
+#define HWS_REG_ACTIVE_STATUS (CVBS_IN_BASE + 5 * PCIE_BARADDROFSIZE)
+/* bits0-3: HDCP detected */
+#define HWS_REG_HDCP_STATUS (CVBS_IN_BASE + 8 * PCIE_BARADDROFSIZE)
+#define HWS_REG_DMA_MAX_SIZE (CVBS_IN_BASE + 9 * PCIE_BARADDROFSIZE)
+
+/* Buffer addresses (written once during init/reset). */
+/* Base of host-visible buffer. */
+#define HWS_REG_VBUF1_ADDR (CVBS_IN_BASE + 25 * PCIE_BARADDROFSIZE)
+/* Per-channel DMA address. */
+#define HWS_REG_DMA_ADDR(ch) (CVBS_IN_BASE + (26 + (ch)) * PCIE_BARADDROFSIZE)
+
+/* Per-channel live buffer toggles (read-only). */
+#define HWS_REG_VBUF_TOGGLE(ch) (CVBS_IN_BASE + (32 + (ch)) * PCIE_BARADDROFSIZE)
+/*
+ * Returns 0 or 1 = which half of the video ring the DMA engine is
+ * currently filling for channel *ch* (0-3).
+ */
+
+/* Per-interrupt bits (video 0-3). */
+#define HWS_INT_VDONE_BIT(ch) BIT(ch) /* 0x01,0x02,0x04,0x08 */
+
+#define HWS_REG_INT_ACK (CVBS_IN_BASE + 0x4000 + 1 * PCIE_BARADDROFSIZE)
+
+/* 16-bit W | 16-bit H. */
+#define HWS_REG_IN_RES(ch) (CVBS_IN_BASE + (90 + (ch) * 2) * PCIE_BARADDROFSIZE)
+/* B|C|H|S packed bytes. */
+#define HWS_REG_BCHS(ch) (CVBS_IN_BASE + (91 + (ch) * 2) * PCIE_BARADDROFSIZE)
+
+/* Input fps. */
+#define HWS_REG_FRAME_RATE(ch) (CVBS_IN_BASE + (110 + (ch)) * PCIE_BARADDROFSIZE)
+/* Programmed out W|H. */
+#define HWS_REG_OUT_RES(ch) (CVBS_IN_BASE + (120 + (ch)) * PCIE_BARADDROFSIZE)
+/* Programmed out fps. */
+#define HWS_REG_OUT_FRAME_RATE(ch) (CVBS_IN_BASE + (130 + (ch)) * PCIE_BARADDROFSIZE)
+
+/* Device version/port ID/subversion register. */
+#define HWS_REG_DEVICE_INFO (CVBS_IN_BASE + 88 * PCIE_BARADDROFSIZE)
+/*
+ * Reading this 32-bit word returns:
+ * bits 7:0 = "device version"
+ * bits 15:8 = "device sub-version"
+ * bits 23:24 = "HW key / port ID" etc.
+ * bits 31:28 = "support YV12" flags
+ */
+
+/* Convenience aliases for individual channels. */
+#define HWS_REG_VBUF_TOGGLE_CH0 HWS_REG_VBUF_TOGGLE(0)
+#define HWS_REG_VBUF_TOGGLE_CH1 HWS_REG_VBUF_TOGGLE(1)
+#define HWS_REG_VBUF_TOGGLE_CH2 HWS_REG_VBUF_TOGGLE(2)
+#define HWS_REG_VBUF_TOGGLE_CH3 HWS_REG_VBUF_TOGGLE(3)
+
+#endif /* _HWS_PCIE_REG_H */
diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.c b/drivers/media/pci/hws/hws_v4l2_ioctl.c
new file mode 100644
index 000000000000..9c0826c0f9f9
--- /dev/null
+++ b/drivers/media/pci/hws/hws_v4l2_ioctl.c
@@ -0,0 +1,924 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/math64.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_v4l2_ioctl.h"
+
+struct hws_dv_mode {
+ struct v4l2_dv_timings timings;
+ u32 refresh_hz;
+};
+
+static const struct hws_dv_mode *
+hws_find_dv_by_wh(u32 w, u32 h, bool interlaced);
+static const struct hws_dv_mode *
+hws_find_dv_by_wh_fps(u32 w, u32 h, bool interlaced, u32 fps);
+static u32 hws_get_live_fps(struct hws_video *vid);
+static u32 hws_input_status(struct hws_video *vid);
+static int hws_fill_dv_timings(u32 w, u32 h, bool interlace, u32 fps,
+ struct v4l2_dv_timings *timings);
+
+static const struct hws_dv_mode hws_dv_modes[] = {
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1920,
+ .height = 1080,
+ .hfrontporch = 88,
+ .hsync = 44,
+ .hbackporch = 148,
+ .vfrontporch = 4,
+ .vsync = 5,
+ .vbackporch = 36,
+ .pixelclock = 148500000,
+ .polarities = V4L2_DV_VSYNC_POS_POL |
+ V4L2_DV_HSYNC_POS_POL,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1920,
+ .height = 1080,
+ .hfrontporch = 88,
+ .hsync = 44,
+ .hbackporch = 148,
+ .vfrontporch = 4,
+ .vsync = 5,
+ .vbackporch = 36,
+ .pixelclock = 74250000,
+ .polarities = V4L2_DV_VSYNC_POS_POL |
+ V4L2_DV_HSYNC_POS_POL,
+ .interlaced = 0,
+ },
+ },
+ 30,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 720,
+ .hfrontporch = 110,
+ .hsync = 40,
+ .hbackporch = 220,
+ .vfrontporch = 5,
+ .vsync = 5,
+ .vbackporch = 20,
+ .pixelclock = 74250000,
+ .polarities = V4L2_DV_VSYNC_POS_POL |
+ V4L2_DV_HSYNC_POS_POL,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 720,
+ .height = 480,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 720,
+ .height = 576,
+ .interlaced = 0,
+ },
+ },
+ 50,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 800,
+ .height = 600,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 640,
+ .height = 480,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1024,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 800,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 1024,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1360,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1440,
+ .height = 900,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1680,
+ .height = 1050,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ /* Portrait */
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1080,
+ .height = 1920,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+};
+
+static const size_t hws_dv_modes_cnt = ARRAY_SIZE(hws_dv_modes);
+
+/* YUYV: 16 bpp; align to 64 as you did elsewhere */
+static inline u32 hws_calc_bpl_yuyv(u32 w) { return ALIGN(w * 2, 64); }
+static inline u32 hws_calc_size_yuyv(u32 w, u32 h) { return hws_calc_bpl_yuyv(w) * h; }
+static inline u32 hws_calc_half_size(u32 sizeimage)
+{
+ return sizeimage / 2;
+}
+
+static inline void hws_hw_write_bchs(struct hws_pcie_dev *hws, unsigned int ch,
+ u8 br, u8 co, u8 hu, u8 sa)
+{
+ u32 packed = (sa << 24) | (hu << 16) | (co << 8) | br;
+
+ if (!hws || !hws->bar0_base || ch >= hws->max_channels)
+ return;
+ writel_relaxed(packed, hws->bar0_base + HWS_REG_BCHS(ch));
+ (void)readl(hws->bar0_base + HWS_REG_BCHS(ch)); /* post write */
+}
+
+/* Helper: find a supported DV mode by W/H + interlace flag */
+static const struct hws_dv_mode *
+hws_match_supported_dv(const struct v4l2_dv_timings *req)
+{
+ const struct v4l2_bt_timings *bt;
+ u32 fps;
+
+ if (!req || req->type != V4L2_DV_BT_656_1120)
+ return NULL;
+
+ bt = &req->bt;
+ fps = 0;
+ if (bt->pixelclock) {
+ u32 total_w = bt->width + bt->hfrontporch + bt->hsync +
+ bt->hbackporch;
+ u32 total_h = bt->height + bt->vfrontporch + bt->vsync +
+ bt->vbackporch;
+
+ if (total_w && total_h)
+ fps = DIV_ROUND_CLOSEST_ULL((u64)bt->pixelclock,
+ (u64)total_w * total_h);
+ }
+ if (fps) {
+ const struct hws_dv_mode *exact =
+ hws_find_dv_by_wh_fps(bt->width, bt->height,
+ !!bt->interlaced, fps);
+ if (exact)
+ return exact;
+ }
+ return hws_find_dv_by_wh(bt->width, bt->height, !!bt->interlaced);
+}
+
+/* Helper: find a supported DV mode by W/H + interlace flag */
+static const struct hws_dv_mode *
+hws_find_dv_by_wh(u32 w, u32 h, bool interlaced)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct hws_dv_mode *t = &hws_dv_modes[i];
+ const struct v4l2_bt_timings *bt = &t->timings.bt;
+
+ if (t->timings.type != V4L2_DV_BT_656_1120)
+ continue;
+
+ if (bt->width == w && bt->height == h &&
+ !!bt->interlaced == interlaced)
+ return t;
+ }
+ return NULL;
+}
+
+static const struct hws_dv_mode *
+hws_find_dv_by_wh_fps(u32 w, u32 h, bool interlaced, u32 fps)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct hws_dv_mode *t = &hws_dv_modes[i];
+ const struct v4l2_bt_timings *bt = &t->timings.bt;
+
+ if (t->timings.type != V4L2_DV_BT_656_1120)
+ continue;
+
+ if (bt->width == w && bt->height == h &&
+ !!bt->interlaced == interlaced &&
+ t->refresh_hz == fps)
+ return t;
+ }
+ return NULL;
+}
+
+static bool hws_get_live_dv_geometry(struct hws_video *vid,
+ u32 *w, u32 *h, bool *interlaced)
+{
+ struct hws_pcie_dev *pdx;
+ u32 reg;
+
+ if (!vid)
+ return false;
+
+ pdx = vid->parent;
+ if (!pdx || !pdx->bar0_base)
+ return false;
+
+ reg = readl(pdx->bar0_base + HWS_REG_IN_RES(vid->channel_index));
+ if (!reg || reg == 0xFFFFFFFF)
+ return false;
+
+ if (w)
+ *w = reg & 0xFFFF;
+ if (h)
+ *h = (reg >> 16) & 0xFFFF;
+ if (interlaced) {
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ *interlaced = !!(reg & BIT(8 + vid->channel_index));
+ }
+ return true;
+}
+
+static u32 hws_get_live_fps(struct hws_video *vid)
+{
+ struct hws_pcie_dev *pdx;
+ u32 fps;
+
+ if (!vid)
+ return 0;
+
+ pdx = vid->parent;
+ if (!pdx || !pdx->bar0_base)
+ return 0;
+
+ fps = readl(pdx->bar0_base + HWS_REG_FRAME_RATE(vid->channel_index));
+ if (!fps || fps == 0xFFFFFFFF || fps > 240)
+ return 0;
+
+ return fps;
+}
+
+static u32 hws_pick_fps_from_mode(u32 w, u32 h, bool interlaced)
+{
+ const struct hws_dv_mode *m = hws_find_dv_by_wh(w, h, interlaced);
+
+ if (m && m->refresh_hz)
+ return m->refresh_hz;
+ /* Fallback to a sane default */
+ return 60;
+}
+
+static int hws_fill_dv_timings(u32 w, u32 h, bool interlace, u32 fps,
+ struct v4l2_dv_timings *timings)
+{
+ const struct hws_dv_mode *m;
+
+ m = fps ? hws_find_dv_by_wh_fps(w, h, interlace, fps) : NULL;
+ if (!m)
+ m = hws_find_dv_by_wh(w, h, interlace);
+ if (!m)
+ return -ENOLINK;
+
+ *timings = m->timings;
+ return 0;
+}
+
+static u32 hws_input_status(struct hws_video *vid)
+{
+ struct hws_pcie_dev *pdx;
+ u32 reg;
+
+ if (!vid)
+ return V4L2_IN_ST_NO_SIGNAL;
+
+ pdx = vid->parent;
+ if (!pdx || !pdx->bar0_base)
+ return V4L2_IN_ST_NO_SIGNAL;
+
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ if (reg == 0xffffffff)
+ return V4L2_IN_ST_NO_SIGNAL;
+
+ return (reg & BIT(vid->channel_index)) ? 0 : V4L2_IN_ST_NO_SIGNAL;
+}
+
+/* Query the *current detected* DV timings on the input.
+ * If you have a real hardware detector, call it here; otherwise we
+ * derive from the cached pix state and map to the closest supported DV mode.
+ */
+int hws_vidioc_query_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ u32 w, h;
+ u32 fps;
+ bool interlace;
+
+ if (!timings)
+ return -EINVAL;
+
+ w = vid->pix.width;
+ h = vid->pix.height;
+ interlace = vid->pix.interlaced;
+ (void)hws_get_live_dv_geometry(vid, &w, &h, &interlace);
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(w, h, interlace);
+
+ return hws_fill_dv_timings(w, h, interlace, fps, timings);
+}
+
+/* Enumerate the Nth supported DV timings from our static table. */
+int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
+ struct v4l2_enum_dv_timings *edv)
+{
+ struct hws_video *vid = video_drvdata(file);
+ const struct hws_dv_mode *m;
+ u32 w, h;
+ u32 fps;
+ bool interlace;
+
+ if (!edv)
+ return -EINVAL;
+
+ if (edv->pad)
+ return -EINVAL;
+
+ w = 0;
+ h = 0;
+ interlace = false;
+ if (hws_get_live_dv_geometry(vid, &w, &h, &interlace)) {
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(w, h, interlace);
+ m = fps ? hws_find_dv_by_wh_fps(w, h, interlace, fps) : NULL;
+ if (!m)
+ m = hws_find_dv_by_wh(w, h, interlace);
+ if (m) {
+ if (edv->index)
+ return -EINVAL;
+ edv->timings = m->timings;
+ return 0;
+ }
+ }
+
+ if (edv->index >= hws_dv_modes_cnt)
+ return -EINVAL;
+
+ edv->timings = hws_dv_modes[edv->index].timings;
+ return 0;
+}
+
+/* Get the *currently configured* DV timings. */
+int hws_vidioc_g_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ u32 w, h;
+ u32 fps;
+ bool interlace;
+
+ if (!timings)
+ return -EINVAL;
+
+ w = vid->pix.width;
+ h = vid->pix.height;
+ interlace = vid->pix.interlaced;
+ if (hws_get_live_dv_geometry(vid, &w, &h, &interlace)) {
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(w, h, interlace);
+ return hws_fill_dv_timings(w, h, interlace, fps, timings);
+ }
+
+ *timings = vid->cur_dv_timings;
+ return 0;
+}
+
+static inline void hws_set_colorimetry_state(struct hws_pix_state *p)
+{
+ bool sd = p->height <= 576;
+
+ p->colorspace = sd ? V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
+ p->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ p->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ p->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+}
+
+/* Set DV timings: must match one of our supported modes.
+ * If buffers are queued and this implies a size change, we reject with -EBUSY.
+ * Otherwise we update pix state and (optionally) reprogram the HW.
+ */
+int hws_vidioc_s_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ const struct hws_dv_mode *m;
+ const struct v4l2_bt_timings *bt;
+ u32 new_w, new_h;
+ bool interlaced;
+ int ret = 0;
+ unsigned long was_busy;
+ u32 live_w, live_h;
+ u32 live_fps;
+ bool live_interlaced;
+ bool live_present;
+
+ if (!timings)
+ return -EINVAL;
+
+ m = hws_match_supported_dv(timings);
+ if (!m)
+ return -EINVAL;
+
+ bt = &m->timings.bt;
+ if (bt->interlaced)
+ return -EINVAL; /* only progressive modes are advertised */
+ new_w = bt->width;
+ new_h = bt->height;
+ interlaced = false;
+
+ lockdep_assert_held(&vid->state_lock);
+ live_present = hws_get_live_dv_geometry(vid, &live_w, &live_h,
+ &live_interlaced);
+
+ /* If vb2 has active buffers and size would change, reject. */
+ was_busy = vb2_is_busy(&vid->buffer_queue);
+ if (was_busy &&
+ (new_w != vid->pix.width || new_h != vid->pix.height ||
+ interlaced != vid->pix.interlaced)) {
+ ret = -EBUSY;
+ return ret;
+ }
+
+ /* When a live input signal is present, the receiver owns the timing.
+ * Allow setting the already-active timings so v4l2-compliance can
+ * round-trip them, but reject attempts to retime the live source.
+ */
+ if (live_present) {
+ live_fps = hws_get_live_fps(vid);
+ if (!live_fps)
+ live_fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(live_w, live_h,
+ live_interlaced);
+ if (live_w == new_w && live_h == new_h &&
+ live_interlaced == interlaced &&
+ m->refresh_hz == live_fps)
+ return 0;
+ return -EBUSY;
+ }
+
+ /* Update software pixel state (and recalc sizes) */
+ vid->pix.width = new_w;
+ vid->pix.height = new_h;
+ vid->pix.field = interlaced ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_NONE;
+ vid->pix.interlaced = interlaced;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+
+ hws_set_colorimetry_state(&vid->pix);
+
+ /* Recompute stride/sizeimage/half_size using your helper */
+ vid->pix.bytesperline = hws_calc_bpl_yuyv(new_w);
+ vid->pix.sizeimage = hws_calc_size_yuyv(new_w, new_h);
+ vid->pix.half_size = hws_calc_half_size(vid->pix.sizeimage);
+ vid->cur_dv_timings = m->timings;
+ vid->current_fps = m->refresh_hz;
+ if (!was_busy)
+ vid->alloc_sizeimage = vid->pix.sizeimage;
+ return ret;
+}
+
+/* Report DV timings capability: advertise BT.656/1120 with
+ * the min/max WxH derived from our table and basic progressive support.
+ */
+int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
+ struct v4l2_dv_timings_cap *cap)
+{
+ u32 min_w = ~0U, min_h = ~0U;
+ u32 max_w = 0, max_h = 0;
+ size_t i, n = 0;
+
+ if (!cap)
+ return -EINVAL;
+
+ memset(cap, 0, sizeof(*cap));
+ cap->type = V4L2_DV_BT_656_1120;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct v4l2_bt_timings *bt = &hws_dv_modes[i].timings.bt;
+
+ if (hws_dv_modes[i].timings.type != V4L2_DV_BT_656_1120)
+ continue;
+ n++;
+
+ if (bt->width < min_w)
+ min_w = bt->width;
+ if (bt->height < min_h)
+ min_h = bt->height;
+ if (bt->width > max_w)
+ max_w = bt->width;
+ if (bt->height > max_h)
+ max_h = bt->height;
+ }
+
+ /* If the table was empty, fail gracefully. */
+ if (!n || min_w == U32_MAX)
+ return -ENODATA;
+
+ cap->bt.min_width = min_w;
+ cap->bt.max_width = max_w;
+ cap->bt.min_height = min_h;
+ cap->bt.max_height = max_h;
+
+ /* We support both CEA-861- and VESA-style modes in the list. */
+ cap->bt.standards =
+ V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT;
+
+ /* Progressive only, unless your table includes interlaced entries. */
+ cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE;
+
+ /* Leave pixelclock/porch limits unconstrained (0) for now. */
+ return 0;
+}
+
+static int hws_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct hws_video *vid =
+ container_of(ctrl->handler, struct hws_video, control_handler);
+ struct hws_pcie_dev *pdx = vid->parent;
+ bool program = false;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ vid->current_brightness = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_CONTRAST:
+ vid->current_contrast = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_SATURATION:
+ vid->current_saturation = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_HUE:
+ vid->current_hue = ctrl->val;
+ program = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (program) {
+ hws_hw_write_bchs(pdx, vid->channel_index,
+ (u8)vid->current_brightness,
+ (u8)vid->current_contrast,
+ (u8)vid->current_hue,
+ (u8)vid->current_saturation);
+ }
+ return 0;
+}
+
+const struct v4l2_ctrl_ops hws_ctrl_ops = {
+ .s_ctrl = hws_s_ctrl,
+};
+
+int hws_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
+{
+ struct hws_video *vid = video_drvdata(file);
+ int vi_index = vid->channel_index + 1; /* keep it simple */
+
+ strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+ snprintf(cap->card, sizeof(cap->card),
+ "AVMatrix HWS Capture %d", vi_index);
+ return 0;
+}
+
+int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh, struct v4l2_fmtdesc *f)
+{
+ if (f->index != 0)
+ return -EINVAL; /* only one format */
+
+ f->pixelformat = V4L2_PIX_FMT_YUYV;
+ return 0;
+}
+
+int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct hws_video *vid = video_drvdata(file);
+
+ fmt->fmt.pix.width = vid->pix.width;
+ fmt->fmt.pix.height = vid->pix.height;
+ fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ fmt->fmt.pix.field = vid->pix.field;
+ fmt->fmt.pix.bytesperline = vid->pix.bytesperline;
+ fmt->fmt.pix.sizeimage = vid->pix.sizeimage;
+ fmt->fmt.pix.colorspace = vid->pix.colorspace;
+ fmt->fmt.pix.ycbcr_enc = vid->pix.ycbcr_enc;
+ fmt->fmt.pix.quantization = vid->pix.quantization;
+ fmt->fmt.pix.xfer_func = vid->pix.xfer_func;
+ return 0;
+}
+
+static inline void hws_set_colorimetry_fmt(struct v4l2_pix_format *p)
+{
+ bool sd = p->height <= 576;
+
+ p->colorspace = sd ? V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
+ p->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ p->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ p->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+}
+
+int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct hws_video *vid = file ? video_drvdata(file) : NULL;
+ struct hws_pcie_dev *pdev = vid ? vid->parent : NULL;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ u32 req_w = pix->width, req_h = pix->height;
+ u32 w, h, min_bpl, bpl;
+ size_t size; /* wider than u32 for overflow check */
+ size_t max_frame = pdev ? pdev->max_hw_video_buf_sz : MAX_MM_VIDEO_SIZE;
+
+ /* Only YUYV */
+ pix->pixelformat = V4L2_PIX_FMT_YUYV;
+
+ /* Defaults then clamp */
+ w = (req_w ? req_w : 640);
+ h = (req_h ? req_h : 480);
+ if (w > MAX_VIDEO_HW_W)
+ w = MAX_VIDEO_HW_W;
+ if (h > MAX_VIDEO_HW_H)
+ h = MAX_VIDEO_HW_H;
+ if (!w)
+ w = 640; /* hard fallback in case macros are odd */
+ if (!h)
+ h = 480;
+
+ /* Field policy */
+ pix->field = V4L2_FIELD_NONE;
+
+ /* Stride policy for packed 16bpp, 64B align */
+ min_bpl = ALIGN(w * 2, 64);
+
+ /* Bound requested bpl to something sane, then align */
+ bpl = pix->bytesperline;
+ if (bpl < min_bpl) {
+ bpl = min_bpl;
+ } else {
+ /* Cap at 16x width to avoid silly values that overflow sizeimage */
+ u32 max_bpl = ALIGN(w * 2 * 16, 64);
+
+ if (bpl > max_bpl)
+ bpl = max_bpl;
+ bpl = ALIGN(bpl, 64);
+ }
+ if (h && max_frame) {
+ size_t max_bpl_hw = max_frame / h;
+
+ if (max_bpl_hw < min_bpl)
+ return -ERANGE;
+ max_bpl_hw = rounddown(max_bpl_hw, 64);
+ 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 = (u32)max_bpl_hw;
+ }
+ }
+ size = (size_t)bpl * (size_t)h;
+ if (size > max_frame)
+ return -ERANGE;
+
+ pix->width = w;
+ pix->height = h;
+ pix->bytesperline = bpl;
+ pix->sizeimage = (u32)size; /* logical size, not page-aligned */
+
+ hws_set_colorimetry_fmt(pix);
+ if (pdev)
+ dev_dbg(&pdev->pdev->dev,
+ "try_fmt: w=%u h=%u bpl=%u size=%u field=%u\n",
+ pix->width, pix->height, pix->bytesperline,
+ pix->sizeimage, pix->field);
+ return 0;
+}
+
+int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
+{
+ struct hws_video *vid = video_drvdata(file);
+ int ret;
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ /* Normalize the request */
+ ret = hws_vidioc_try_fmt_vid_cap(file, priv, f);
+ if (ret)
+ return ret;
+
+ /* Don't allow buffer layout changes while buffers are queued. */
+ if (vb2_is_busy(&vid->buffer_queue)) {
+ if (f->fmt.pix.width != vid->pix.width ||
+ f->fmt.pix.height != vid->pix.height ||
+ f->fmt.pix.bytesperline != vid->pix.bytesperline)
+ return -EBUSY;
+ }
+
+ /* Apply to driver state */
+ vid->pix.width = f->fmt.pix.width;
+ vid->pix.height = f->fmt.pix.height;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+ vid->pix.field = f->fmt.pix.field;
+ vid->pix.colorspace = f->fmt.pix.colorspace;
+ vid->pix.ycbcr_enc = f->fmt.pix.ycbcr_enc;
+ vid->pix.quantization = f->fmt.pix.quantization;
+ vid->pix.xfer_func = f->fmt.pix.xfer_func;
+
+ /* Update sizes (use helper if you prefer strict alignment math) */
+ vid->pix.bytesperline = f->fmt.pix.bytesperline; /* aligned */
+ vid->pix.sizeimage = f->fmt.pix.sizeimage; /* logical */
+ vid->pix.half_size = hws_calc_half_size(vid->pix.sizeimage);
+ vid->pix.interlaced = false;
+ /* S_FMT negotiates buffer layout only. Keep detector-owned DV timing
+ * state unchanged so a harmless restart cannot clobber the live FPS.
+ */
+ /* Or:
+ * hws_calc_sizeimage(vid, vid->pix.width, vid->pix.height, false);
+ */
+
+ /* Refresh vb2 watermark when idle */
+ if (!vb2_is_busy(&vid->buffer_queue))
+ vid->alloc_sizeimage = PAGE_ALIGN(vid->pix.sizeimage);
+ dev_dbg(&vid->parent->pdev->dev,
+ "s_fmt: w=%u h=%u bpl=%u size=%u alloc=%u\n",
+ vid->pix.width, vid->pix.height, vid->pix.bytesperline,
+ vid->pix.sizeimage, vid->alloc_sizeimage);
+
+ return 0;
+}
+
+int hws_vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *param)
+{
+ struct hws_video *vid = video_drvdata(file);
+ u32 fps;
+
+ if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps : 60;
+
+ /* HDMI receivers report the detected frame period, they don't set it. */
+ param->parm.capture.capability = 0;
+ param->parm.capture.capturemode = 0;
+ param->parm.capture.timeperframe.numerator = 1;
+ param->parm.capture.timeperframe.denominator = fps;
+ param->parm.capture.extendedmode = 0;
+ param->parm.capture.readbuffers = 0;
+
+ return 0;
+}
+
+int hws_vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *input)
+{
+ struct hws_video *vid = video_drvdata(file);
+
+ if (input->index)
+ return -EINVAL;
+ input->type = V4L2_INPUT_TYPE_CAMERA;
+ strscpy(input->name, KBUILD_MODNAME, sizeof(input->name));
+ input->capabilities = V4L2_IN_CAP_DV_TIMINGS;
+ input->status = hws_input_status(vid);
+
+ return 0;
+}
+
+int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *index)
+{
+ *index = 0;
+ return 0;
+}
+
+int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.h b/drivers/media/pci/hws/hws_v4l2_ioctl.h
new file mode 100644
index 000000000000..53044f78d6fa
--- /dev/null
+++ b/drivers/media/pci/hws/hws_v4l2_ioctl.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_V4L2_IOCTL_H
+#define HWS_V4L2_IOCTL_H
+
+#include <media/v4l2-ctrls.h>
+#include <linux/fs.h>
+
+extern const struct v4l2_ctrl_ops hws_ctrl_ops;
+
+int hws_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap);
+int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh, struct v4l2_fmtdesc *f);
+int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt);
+int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f);
+int hws_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms);
+int hws_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms);
+int hws_vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *setfps);
+int hws_vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i);
+int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *i);
+int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i);
+int hws_vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *a);
+int hws_vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a);
+int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
+ struct v4l2_dv_timings_cap *cap);
+int hws_vidioc_s_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+
+int hws_vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a);
+int hws_vidioc_g_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
+ struct v4l2_enum_dv_timings *edv);
+int hws_vidioc_query_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
+
+#endif
diff --git a/drivers/media/pci/hws/hws_video.c b/drivers/media/pci/hws/hws_video.c
new file mode 100644
index 000000000000..6e1d75701b15
--- /dev/null
+++ b/drivers/media/pci/hws/hws_video.c
@@ -0,0 +1,1504 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/overflow.h>
+#include <linux/delay.h>
+#include <linux/bits.h>
+#include <linux/jiffies.h>
+#include <linux/ktime.h>
+#include <linux/interrupt.h>
+#include <linux/moduleparam.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_irq.h"
+#include "hws_v4l2_ioctl.h"
+
+#define HWS_REMAP_SLOT_OFF(ch) (0x208 + (ch) * 8) /* one 64-bit slot per ch */
+#define HWS_BUF_BASE_OFF(ch) (CVBS_IN_BUF_BASE + (ch) * PCIE_BARADDROFSIZE)
+#define HWS_HALF_SZ_OFF(ch) (CVBS_IN_BUF_BASE2 + (ch) * PCIE_BARADDROFSIZE)
+
+static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool interlace);
+static bool hws_read_active_state(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool *interlace);
+static void handle_hwv2_path(struct hws_pcie_dev *hws, unsigned int ch);
+static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch);
+static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
+ bool interlaced);
+
+/* DMA helper functions */
+static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma);
+static struct hwsvideo_buffer *
+hws_take_queued_buffer_locked(struct hws_video *vid);
+
+static inline bool list_node_unlinked(const struct list_head *n)
+{
+ return n->next == LIST_POISON1 || n->prev == LIST_POISON2;
+}
+
+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=0x%llx tag=%s\n", ch,
+ (u64)dma, tag ? tag : "");
+}
+
+static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma)
+{
+ const u32 addr_mask = PCI_E_BAR_ADD_MASK; // 0xE0000000
+ const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK; // 0x1FFFFFFF
+ struct hws_pcie_dev *hws = vid->parent;
+ unsigned int ch = vid->channel_index;
+ u32 table_off = HWS_REMAP_SLOT_OFF(ch);
+ u32 lo = lower_32_bits(dma);
+ u32 hi = upper_32_bits(dma);
+ u32 pci_addr = lo & addr_low_mask; // low 29 bits inside 512MB window
+ u32 page_lo = lo & addr_mask; // bits 31..29 only (page bits)
+
+ bool wrote = false;
+
+ /* Remap entry only when DMA crosses into a new 512 MB page */
+ if (!vid->window_valid || vid->last_dma_hi != hi ||
+ vid->last_dma_page != page_lo) {
+ writel(hi, hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
+ writel(page_lo,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
+ PCIE_BARADDROFSIZE);
+ vid->last_dma_hi = hi;
+ vid->last_dma_page = page_lo;
+ wrote = true;
+ }
+
+ /* Base pointer only needs low 29 bits */
+ if (!vid->window_valid || vid->last_pci_addr != pci_addr) {
+ writel((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
+ hws->bar0_base + HWS_BUF_BASE_OFF(ch));
+ vid->last_pci_addr = pci_addr;
+ wrote = true;
+ }
+
+ /* Half-size only changes when resolution changes */
+ if (!vid->window_valid || vid->last_half16 != vid->pix.half_size / 16) {
+ writel(vid->pix.half_size / 16,
+ hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+ vid->last_half16 = vid->pix.half_size / 16;
+ wrote = true;
+ }
+
+ vid->window_valid = true;
+
+ if (dma_window_verify && wrote) {
+ u32 r_hi =
+ readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
+ u32 r_lo =
+ readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
+ PCIE_BARADDROFSIZE);
+ u32 r_base = readl(hws->bar0_base + HWS_BUF_BASE_OFF(ch));
+ u32 r_half = readl(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+
+ dev_dbg(&hws->pdev->dev,
+ "ch%u remap verify: hi=0x%08x page_lo=0x%08x exp_page=0x%08x base=0x%08x exp_base=0x%08x half16B=0x%08x exp_half=0x%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) {
+ /* Flush posted writes before arming DMA */
+ readl_relaxed(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+ }
+}
+
+static struct hwsvideo_buffer *
+hws_take_queued_buffer_locked(struct hws_video *vid)
+{
+ struct hwsvideo_buffer *buf;
+
+ if (!vid || list_empty(&vid->capture_queue))
+ return NULL;
+
+ buf = list_first_entry(&vid->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&buf->list);
+ if (vid->queued_count)
+ vid->queued_count--;
+ return buf;
+}
+
+void hws_prime_next_locked(struct hws_video *vid)
+{
+ struct hws_pcie_dev *hws;
+ struct hwsvideo_buffer *next;
+ dma_addr_t dma;
+
+ if (!vid)
+ return;
+
+ hws = vid->parent;
+ if (!hws || !hws->bar0_base)
+ return;
+
+ if (!READ_ONCE(vid->cap_active) || !vid->active || vid->next_prepared)
+ return;
+
+ next = hws_take_queued_buffer_locked(vid);
+ if (!next)
+ return;
+
+ vid->next_prepared = next;
+ dma = vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
+ 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=0x%llx\n",
+ vid->channel_index, next, (u64)dma);
+}
+
+static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag)
+{
+ struct hws_pcie_dev *hws;
+ unsigned long flags;
+ struct hwsvideo_buffer *buf = NULL, *next = NULL;
+ bool have_next = false;
+ bool doorbell = false;
+
+ if (!v)
+ return false;
+ hws = v->parent;
+ if (!hws || READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active))
+ return false;
+ spin_lock_irqsave(&v->irq_lock, flags);
+ if (v->active) {
+ buf = v->active;
+ v->active = NULL;
+ buf->slot = 0;
+ } else if (!list_empty(&v->capture_queue)) {
+ buf = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&buf->list);
+ if (v->queued_count)
+ v->queued_count--;
+ buf->slot = 0;
+ }
+ if (v->next_prepared) {
+ next = v->next_prepared;
+ v->next_prepared = NULL;
+ next->slot = 0;
+ v->active = next;
+ have_next = true;
+ } else if (!list_empty(&v->capture_queue)) {
+ next = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&next->list);
+ if (v->queued_count)
+ v->queued_count--;
+ next->slot = 0;
+ v->active = next;
+ have_next = true;
+ } else {
+ v->active = NULL;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ if (!buf)
+ return false;
+ /* Complete buffer with a neutral frame so dequeuers keep running. */
+ {
+ struct vb2_v4l2_buffer *vb2v = &buf->vb;
+ void *dst = vb2_plane_vaddr(&vb2v->vb2_buf, 0);
+
+ if (dst)
+ memset(dst, 0x10, v->pix.sizeimage);
+ vb2_set_plane_payload(&vb2v->vb2_buf, 0, v->pix.sizeimage);
+ vb2v->sequence = (u32)atomic_inc_return(&v->sequence_number);
+ vb2v->vb2_buf.timestamp = ktime_get_ns();
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+ if (have_next && next) {
+ dma_addr_t dma =
+ vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(hws, v->channel_index, dma);
+ hws_set_dma_doorbell(hws, v->channel_index, dma,
+ tag ? tag : "nosignal_zero");
+ doorbell = true;
+ }
+ if (doorbell) {
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, v->channel_index, true);
+ }
+ return true;
+}
+
+static int hws_ctrls_init(struct hws_video *vid)
+{
+ struct v4l2_ctrl_handler *hdl = &vid->control_handler;
+
+ /* Create BCHS controls. */
+ v4l2_ctrl_handler_init(hdl, 4);
+
+ vid->ctrl_brightness = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
+ V4L2_CID_BRIGHTNESS,
+ MIN_VAMP_BRIGHTNESS_UNITS,
+ MAX_VAMP_BRIGHTNESS_UNITS, 1,
+ HWS_BRIGHTNESS_DEFAULT);
+
+ vid->ctrl_contrast =
+ v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_CONTRAST,
+ MIN_VAMP_CONTRAST_UNITS, MAX_VAMP_CONTRAST_UNITS,
+ 1, HWS_CONTRAST_DEFAULT);
+
+ vid->ctrl_saturation = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
+ V4L2_CID_SATURATION,
+ MIN_VAMP_SATURATION_UNITS,
+ MAX_VAMP_SATURATION_UNITS, 1,
+ HWS_SATURATION_DEFAULT);
+
+ vid->ctrl_hue = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_HUE,
+ MIN_VAMP_HUE_UNITS,
+ MAX_VAMP_HUE_UNITS, 1,
+ HWS_HUE_DEFAULT);
+ if (hdl->error) {
+ int err = hdl->error;
+
+ v4l2_ctrl_handler_free(hdl);
+ return err;
+ }
+ return 0;
+}
+
+int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch)
+{
+ struct hws_video *vid;
+
+ /* basic sanity */
+ if (!pdev || ch < 0 || ch >= pdev->max_channels)
+ return -EINVAL;
+
+ vid = &pdev->video[ch];
+
+ /* hard reset the per-channel struct (safe here since we init everything next) */
+ memset(vid, 0, sizeof(*vid));
+
+ /* identity */
+ vid->parent = pdev;
+ vid->channel_index = ch;
+
+ /* locks & lists */
+ mutex_init(&vid->state_lock);
+ spin_lock_init(&vid->irq_lock);
+ INIT_LIST_HEAD(&vid->capture_queue);
+ atomic_set(&vid->sequence_number, 0);
+ vid->active = NULL;
+
+ /* DMA watchdog removed; retain counters for diagnostics */
+ vid->timeout_count = 0;
+ vid->error_count = 0;
+
+ vid->queued_count = 0;
+ vid->window_valid = false;
+
+ /* default format (adjust to your HW) */
+ vid->pix.width = 1920;
+ vid->pix.height = 1080;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+ vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
+ vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
+ vid->pix.field = V4L2_FIELD_NONE;
+ vid->pix.colorspace = V4L2_COLORSPACE_REC709;
+ vid->pix.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ vid->pix.quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ vid->pix.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+ vid->pix.interlaced = false;
+ vid->pix.half_size = vid->pix.sizeimage / 2;
+ vid->alloc_sizeimage = vid->pix.sizeimage;
+ hws_set_current_dv_timings(vid, vid->pix.width,
+ vid->pix.height, vid->pix.interlaced);
+ vid->current_fps = 60;
+
+ /* color controls default (mid-scale) */
+ vid->current_brightness = 0x80;
+ vid->current_contrast = 0x80;
+ vid->current_saturation = 0x80;
+ vid->current_hue = 0x80;
+
+ /* capture state */
+ vid->cap_active = false;
+ vid->stop_requested = false;
+ vid->last_buf_half_toggle = 0;
+ vid->half_seen = false;
+ vid->signal_loss_cnt = 0;
+
+ /* Create BCHS + DV power-present as modern controls */
+ {
+ int err = hws_ctrls_init(vid);
+
+ if (err) {
+ dev_err(&pdev->pdev->dev,
+ "v4l2 ctrl init failed on ch%d: %d\n", ch, err);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static void hws_video_drain_queue_locked(struct hws_video *vid)
+{
+ /* Return in-flight first */
+ if (vid->active) {
+ vb2_buffer_done(&vid->active->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ vid->active = NULL;
+ }
+
+ /* Then everything queued */
+ while (!list_empty(&vid->capture_queue)) {
+ struct hwsvideo_buffer *b =
+ list_first_entry(&vid->capture_queue,
+ struct hwsvideo_buffer,
+ list);
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+}
+
+static void hws_video_release_registration(struct hws_video *vid)
+{
+ if (vid->buffer_queue.ops) {
+ vb2_queue_release(&vid->buffer_queue);
+ vid->buffer_queue.ops = NULL;
+ }
+
+ if (!vid->video_device)
+ return;
+
+ if (video_is_registered(vid->video_device))
+ vb2_video_unregister_device(vid->video_device);
+ else
+ video_device_release(vid->video_device);
+ vid->video_device = NULL;
+}
+
+static void hws_video_collect_done_locked(struct hws_video *vid,
+ struct list_head *done)
+{
+ struct hwsvideo_buffer *b;
+
+ if (vid->active) {
+ if (!list_node_unlinked(&vid->active->list)) {
+ list_move_tail(&vid->active->list, done);
+ } else {
+ INIT_LIST_HEAD(&vid->active->list);
+ list_add_tail(&vid->active->list, done);
+ }
+ vid->active = NULL;
+ }
+
+ if (vid->next_prepared) {
+ if (!list_node_unlinked(&vid->next_prepared->list)) {
+ list_move_tail(&vid->next_prepared->list, done);
+ } else {
+ INIT_LIST_HEAD(&vid->next_prepared->list);
+ list_add_tail(&vid->next_prepared->list, done);
+ }
+ vid->next_prepared = NULL;
+ }
+
+ while (!list_empty(&vid->capture_queue)) {
+ b = list_first_entry(&vid->capture_queue, struct hwsvideo_buffer,
+ list);
+ list_move_tail(&b->list, done);
+ }
+
+ vid->queued_count = 0;
+}
+
+void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch)
+{
+ struct hws_video *vid;
+ unsigned long flags;
+
+ if (!pdev || ch < 0 || ch >= pdev->max_channels)
+ return;
+
+ vid = &pdev->video[ch];
+
+ /* 1) Stop HW best-effort for this channel */
+ hws_enable_video_capture(vid->parent, vid->channel_index, false);
+
+ /* 2) Flip software state so IRQ/BH will be no-ops if they run */
+ WRITE_ONCE(vid->stop_requested, true);
+ WRITE_ONCE(vid->cap_active, false);
+
+ /* 3) Ensure the IRQ handler finished any in-flight completions */
+ if (vid->parent && vid->parent->irq >= 0)
+ synchronize_irq(vid->parent->irq);
+
+ /* 4) Drain SW capture queue & in-flight under lock */
+ spin_lock_irqsave(&vid->irq_lock, flags);
+ hws_video_drain_queue_locked(vid);
+ spin_unlock_irqrestore(&vid->irq_lock, flags);
+
+ /* 5) Release VB2 queue if initialized */
+ hws_video_release_registration(vid);
+
+ /* 6) Free V4L2 controls */
+ v4l2_ctrl_handler_free(&vid->control_handler);
+
+ /* 8) Reset simple state (don’t memset the whole struct here) */
+ mutex_destroy(&vid->state_lock);
+ INIT_LIST_HEAD(&vid->capture_queue);
+ vid->active = NULL;
+ vid->stop_requested = false;
+ vid->last_buf_half_toggle = 0;
+ vid->half_seen = false;
+ vid->signal_loss_cnt = 0;
+}
+
+/* Convenience cast */
+static inline struct hwsvideo_buffer *to_hwsbuf(struct vb2_buffer *vb)
+{
+ return container_of(to_vb2_v4l2_buffer(vb), struct hwsvideo_buffer, vb);
+}
+
+static int hws_buf_init(struct vb2_buffer *vb)
+{
+ struct hwsvideo_buffer *b = to_hwsbuf(vb);
+
+ INIT_LIST_HEAD(&b->list);
+ return 0;
+}
+
+static void hws_buf_finish(struct vb2_buffer *vb)
+{
+ /* vb2 core handles cache maintenance for dma-contig buffers */
+ (void)vb;
+}
+
+static void hws_buf_cleanup(struct vb2_buffer *vb)
+{
+ struct hwsvideo_buffer *b = to_hwsbuf(vb);
+
+ if (!list_empty(&b->list))
+ list_del_init(&b->list);
+}
+
+void hws_program_dma_for_addr(struct hws_pcie_dev *hws, unsigned int ch,
+ dma_addr_t dma)
+{
+ struct hws_video *vid = &hws->video[ch];
+
+ hws_program_dma_window(vid, dma);
+}
+
+void hws_enable_video_capture(struct hws_pcie_dev *hws, unsigned int chan,
+ bool on)
+{
+ u32 status;
+
+ if (!hws || hws->pci_lost || chan >= hws->max_channels)
+ return;
+
+ status = readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ status = on ? (status | BIT(chan)) : (status & ~BIT(chan));
+ writel(status, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ (void)readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+
+ WRITE_ONCE(hws->video[chan].cap_active, on);
+
+ dev_dbg(&hws->pdev->dev, "vcap %s ch%u (reg=0x%08x)\n",
+ on ? "ON" : "OFF", chan, status);
+}
+
+static void hws_seed_dma_windows(struct hws_pcie_dev *hws)
+{
+ const u32 addr_mask = PCI_E_BAR_ADD_MASK;
+ const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK;
+ u32 table = 0x208; /* one 64-bit entry per channel */
+ unsigned int ch;
+
+ if (!hws || !hws->bar0_base)
+ return;
+
+ /* If cur_max_video_ch isn’t set yet, default to max_channels */
+ if (!hws->cur_max_video_ch || hws->cur_max_video_ch > hws->max_channels)
+ hws->cur_max_video_ch = hws->max_channels;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++, table += 8) {
+ if (!hws->scratch_vid[ch].cpu)
+ continue;
+
+ /* Program 64-bit BAR remap entry for this channel */
+ {
+ dma_addr_t p = hws->scratch_vid[ch].dma;
+ u32 lo = lower_32_bits(p) & addr_mask;
+ u32 hi = upper_32_bits(p);
+ u32 pci_addr_low = lower_32_bits(p) & addr_low_mask;
+
+ writel_relaxed(hi,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE +
+ table);
+ writel_relaxed(lo,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE +
+ table + PCIE_BARADDROFSIZE);
+
+ /* Per-channel AXI base + PCI low */
+ writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE +
+ pci_addr_low,
+ hws->bar0_base + CVBS_IN_BUF_BASE +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* Half-frame length in /16 units.
+ * Prefer the current channel’s computed half_size if available.
+ * Fall back to half of the probe-owned scratch buffer.
+ */
+ {
+ u32 half_bytes = hws->video[ch].pix.half_size ?
+ hws->video[ch].pix.half_size :
+ (u32)(hws->scratch_vid[ch].size / 2);
+ writel_relaxed(half_bytes / 16,
+ hws->bar0_base +
+ CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+ }
+ }
+ }
+
+ /* Post writes so device sees them before we move on */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+}
+
+static void hws_ack_all_irqs(struct hws_pcie_dev *hws)
+{
+ u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+
+ if (st) {
+ writel(st, hws->bar0_base + HWS_REG_INT_STATUS); /* W1C */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+}
+
+static void hws_open_irq_fabric(struct hws_pcie_dev *hws)
+{
+ /* Route all sources to vector 0 (same value you’re already using) */
+ writel(0x00000000, hws->bar0_base + PCIE_INT_DEC_REG_BASE);
+ (void)readl(hws->bar0_base + PCIE_INT_DEC_REG_BASE);
+
+ /* Turn on the bridge if your IP needs it */
+ 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);
+}
+
+void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable)
+{
+ int i;
+
+ if (hws->start_run && !enable)
+ return;
+
+ /* 1) reset the decoder mode register to 0 */
+ writel(0x00000000, hws->bar0_base + HWS_REG_DEC_MODE);
+ hws_seed_dma_windows(hws);
+
+ /* 3) on a full reset, clear all per-channel status and indices */
+ if (!enable) {
+ for (i = 0; i < hws->max_channels; i++) {
+ /* helpers to arm/disable capture engines */
+ hws_enable_video_capture(hws, i, false);
+ }
+ }
+
+ /* 4) “Start run”: set bit31, wait a bit, then program low 24 bits */
+ writel(0x80000000, hws->bar0_base + HWS_REG_DEC_MODE);
+ // udelay(500);
+ 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);
+ /* 6) record that we're now running */
+ hws->start_run = true;
+}
+
+int hws_check_card_status(struct hws_pcie_dev *hws)
+{
+ u32 status;
+
+ if (!hws || !hws->bar0_base)
+ return -ENODEV;
+
+ status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+
+ /* Common “device missing” pattern */
+ if (status == 0xFFFFFFFF) {
+ hws->pci_lost = true;
+ dev_err(&hws->pdev->dev, "PCIe device not responding\n");
+ return -ENODEV;
+ }
+
+ /* If RUN/READY bit (bit0) isn’t set, (re)initialize 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);
+ /* Optional: verify the core cleared its busy bit, if you have one */
+ /* int ret = hws_check_busy(hws); */
+ /* if (ret) return ret; */
+ }
+
+ return 0;
+}
+
+void check_video_format(struct hws_pcie_dev *pdx)
+{
+ int i;
+
+ for (i = 0; i < pdx->cur_max_video_ch; i++) {
+ bool interlace = false;
+
+ if (!hws_read_active_state(pdx, i, &interlace)) {
+ /* No active video; optionally feed neutral frames to keep streaming. */
+ if (pdx->video[i].signal_loss_cnt == 0)
+ pdx->video[i].signal_loss_cnt = 1;
+ if (READ_ONCE(pdx->video[i].cap_active))
+ hws_force_no_signal_frame(&pdx->video[i],
+ "monitor_nosignal");
+ } else {
+ if (pdx->hw_ver > 0)
+ handle_hwv2_path(pdx, i);
+ else
+ /* Legacy path stub; see handle_legacy_path() comment. */
+ handle_legacy_path(pdx, i);
+
+ update_live_resolution(pdx, i, interlace);
+ pdx->video[i].signal_loss_cnt = 0;
+ }
+ }
+}
+
+static inline void hws_write_if_diff(struct hws_pcie_dev *hws, u32 reg_off,
+ u32 new_val)
+{
+ void __iomem *addr;
+ u32 old;
+
+ if (!hws || !hws->bar0_base)
+ return;
+
+ addr = hws->bar0_base + reg_off;
+
+ old = readl(addr);
+ /* Treat all-ones as device gone; avoid writing garbage. */
+ if (old == 0xFFFFFFFF) {
+ hws->pci_lost = true;
+ return;
+ }
+
+ if (old != new_val) {
+ writel(new_val, addr);
+ /* Post the write on some bridges / enforce ordering. */
+ (void)readl(addr);
+ }
+}
+
+static bool hws_read_active_state(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool *interlace)
+{
+ u32 reg;
+ bool active;
+
+ if (ch >= pdx->cur_max_video_ch)
+ return false;
+
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ active = !!(reg & BIT(ch));
+ if (interlace)
+ *interlace = !!(reg & BIT(8 + ch));
+ return active;
+}
+
+/* Modern hardware path: keep HW registers in sync with current per-channel
+ * software state. Adjust the OUT_* bits below to match your HW contract.
+ */
+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;
+
+ if (!hws || !hws->bar0_base || ch >= hws->max_channels)
+ return;
+
+ vid = &hws->video[ch];
+
+ /* 1) Input frame rate (read-only; log or export via debugfs if wanted) */
+ in_fps = readl(hws->bar0_base + HWS_REG_FRAME_RATE(ch));
+ /* dev_dbg(&hws->pdev->dev, "ch%u input fps=%u\n", ch, in_fps); */
+ (void)in_fps;
+
+ /* 2) Output resolution programming
+ * If your HW expects a separate “scaled” size, add fields to track it.
+ * For now, mirror the current format (fmt_curr) to OUT_RES.
+ */
+ want_out_res = (vid->pix.height << 16) | vid->pix.width;
+ cur_out_res = readl(hws->bar0_base + HWS_REG_OUT_RES(ch));
+ if (cur_out_res != want_out_res)
+ hws_write_if_diff(hws, HWS_REG_OUT_RES(ch), want_out_res);
+
+ /* 3) Output FPS: only program if you actually track a target.
+ * Example heuristic (disabled by default):
+ *
+ * u32 out_fps = (vid->fmt_curr.height >= 1080) ? 60 : 30;
+ * hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), out_fps);
+ */
+
+ /* 4) BCHS controls: pack from per-channel current_* fields */
+ reg = readl(hws->bar0_base + HWS_REG_BCHS(ch));
+ {
+ u8 br = reg & 0xFF;
+ u8 co = (reg >> 8) & 0xFF;
+ u8 hu = (reg >> 16) & 0xFF;
+ u8 sa = (reg >> 24) & 0xFF;
+
+ if (br != vid->current_brightness ||
+ co != vid->current_contrast || hu != vid->current_hue ||
+ sa != vid->current_saturation) {
+ u32 packed = (vid->current_saturation << 24) |
+ (vid->current_hue << 16) |
+ (vid->current_contrast << 8) |
+ vid->current_brightness;
+ hws_write_if_diff(hws, HWS_REG_BCHS(ch), packed);
+ }
+ }
+
+ /* 5) HDCP detect: read only (no cache field in your structs today) */
+ reg = readl(hws->bar0_base + HWS_REG_HDCP_STATUS);
+ /* bool hdcp = !!(reg & BIT(ch)); // use if you later add a field/control */
+}
+
+static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch)
+{
+ /*
+ * Legacy (hw_ver == 0) expected behavior:
+ * - A per-channel SW FPS accumulator incremented on each VDONE.
+ * - A once-per-second poll mapped the count to discrete FPS:
+ * >55*2 => 60, >45*2 => 50, >25*2 => 30, >20*2 => 25, else 60,
+ * then reset the accumulator to 0.
+ * - The *2 factor assumed VDONE fired per-field; if legacy VDONE is
+ * per-frame, drop the factor.
+ *
+ * Current code keeps this path as a no-op; vid->current_fps stays at the
+ * default or mode-derived value. If accurate legacy FPS reporting is
+ * needed (V4L2 g_parm/timeperframe), reintroduce the accumulator in the
+ * IRQ path and perform the mapping/reset here.
+ *
+ * No-op by default. If you introduce a SW FPS accumulator, map it here.
+ *
+ * Example skeleton:
+ *
+ * u32 sw_rate = READ_ONCE(hws->sw_fps[ch]); // incremented elsewhere
+ * if (sw_rate > THRESHOLD) {
+ * u32 fps = pick_fps_from_rate(sw_rate);
+ * hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), fps);
+ * WRITE_ONCE(hws->sw_fps[ch], 0);
+ * }
+ */
+ (void)hws;
+ (void)ch;
+}
+
+static void hws_video_apply_mode_change(struct hws_pcie_dev *pdx,
+ unsigned int ch, u16 w, u16 h,
+ bool interlaced, u32 fps)
+{
+ struct hws_video *v = &pdx->video[ch];
+ unsigned long flags;
+ u32 new_size;
+ bool queue_busy;
+ bool geometry_changed;
+ struct list_head done;
+ struct hwsvideo_buffer *b, *tmp;
+
+ if (!pdx || !pdx->bar0_base)
+ return;
+ if (ch >= pdx->max_channels)
+ return;
+ if (!w || !h || w > MAX_VIDEO_HW_W ||
+ (!interlaced && h > MAX_VIDEO_HW_H) ||
+ (interlaced && (h * 2) > MAX_VIDEO_HW_H))
+ return;
+ if (!fps || fps == 0xFFFFFFFF || fps > 240)
+ fps = (h == 576) ? 50 : 60;
+
+ geometry_changed = w != v->pix.width || h != v->pix.height ||
+ interlaced != v->pix.interlaced;
+ if (!geometry_changed && fps == v->current_fps)
+ return;
+
+ if (!geometry_changed) {
+ /* Refresh cached live timing state, but don't emit a resolution
+ * change event when only the frame rate changes.
+ */
+ mutex_lock(&v->state_lock);
+ v->pix.interlaced = interlaced;
+ v->pix.field = interlaced ? V4L2_FIELD_INTERLACED :
+ V4L2_FIELD_NONE;
+ hws_set_current_dv_timings(v, w, h, interlaced);
+ v->current_fps = fps;
+ mutex_unlock(&v->state_lock);
+ return;
+ }
+
+ if (!mutex_trylock(&v->state_lock))
+ return;
+
+ INIT_LIST_HEAD(&done);
+ queue_busy = vb2_is_busy(&v->buffer_queue);
+
+ WRITE_ONCE(v->stop_requested, true);
+ WRITE_ONCE(v->cap_active, false);
+ /* Publish software stop first so the IRQ completion path sees the stop
+ * before we touch MMIO or the lists. Pairs with READ_ONCE() checks in the
+ * VDONE handler and hws_arm_next() to prevent completions while modes
+ * change.
+ */
+ smp_wmb();
+
+ hws_enable_video_capture(pdx, ch, false);
+ readl(pdx->bar0_base + HWS_REG_INT_STATUS);
+
+ if (v->parent && v->parent->irq >= 0)
+ synchronize_irq(v->parent->irq);
+
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_video_collect_done_locked(v, &done);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* Update software pixel state */
+ v->pix.width = w;
+ v->pix.height = h;
+ v->pix.interlaced = interlaced;
+ hws_set_current_dv_timings(v, w, h, interlaced);
+ v->current_fps = fps;
+
+ new_size = hws_calc_sizeimage(v, w, h, interlaced);
+ v->window_valid = false;
+
+ /* Geometry changes require userspace renegotiation once buffers exist.
+ * Emit SOURCE_CHANGE, mark the queue in error, and let userspace
+ * STREAMOFF/REQBUFS/STREAMON rather than trying to restart capture
+ * with partially drained in-flight state.
+ */
+ if (queue_busy) {
+ struct v4l2_event ev = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+ };
+
+ ev.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
+ v4l2_event_queue(v->video_device, &ev);
+ vb2_queue_error(&v->buffer_queue);
+ } else {
+ v->alloc_sizeimage = PAGE_ALIGN(new_size);
+ WRITE_ONCE(v->stop_requested, false);
+ }
+
+ /* Program HW with new resolution */
+ hws_write_if_diff(pdx, HWS_REG_OUT_RES(ch), (h << 16) | w);
+
+ /* Legacy half-buffer programming */
+ writel(v->pix.half_size / 16,
+ pdx->bar0_base + CVBS_IN_BUF_BASE2 + ch * PCIE_BARADDROFSIZE);
+ (void)readl(pdx->bar0_base + CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* Reset per-channel toggles/counters */
+ WRITE_ONCE(v->last_buf_half_toggle, 0);
+ atomic_set(&v->sequence_number, 0);
+
+ mutex_unlock(&v->state_lock);
+
+ list_for_each_entry_safe(b, tmp, &done, list) {
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+}
+
+static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool interlace)
+{
+ u32 reg = readl(pdx->bar0_base + HWS_REG_IN_RES(ch));
+ u32 fps = readl(pdx->bar0_base + HWS_REG_FRAME_RATE(ch));
+ u16 res_w = reg & 0xFFFF;
+ u16 res_h = (reg >> 16) & 0xFFFF;
+ struct hws_video *vid = &pdx->video[ch];
+ bool geometry_changed;
+ bool fps_changed;
+
+ bool within_hw = (res_w <= MAX_VIDEO_HW_W) &&
+ ((!interlace && res_h <= MAX_VIDEO_HW_H) ||
+ (interlace && (res_h * 2) <= MAX_VIDEO_HW_H));
+
+ if (!within_hw)
+ return;
+
+ geometry_changed = res_w != vid->pix.width ||
+ res_h != vid->pix.height ||
+ interlace != vid->pix.interlaced;
+ fps_changed = fps && fps != 0xFFFFFFFF && fps <= 240 &&
+ fps != vid->current_fps;
+
+ if (geometry_changed || fps_changed)
+ hws_video_apply_mode_change(pdx, ch, res_w, res_h, interlace,
+ fps);
+}
+
+static int hws_open(struct file *file)
+{
+ return v4l2_fh_open(file);
+}
+
+static const struct v4l2_file_operations hws_fops = {
+ .owner = THIS_MODULE,
+ .open = hws_open,
+ .release = vb2_fop_release,
+ .poll = vb2_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = vb2_fop_mmap,
+};
+
+static int hws_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_src_change_event_subscribe(fh, sub);
+ case V4L2_EVENT_CTRL:
+ return v4l2_ctrl_subscribe_event(fh, sub);
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_ioctl_ops hws_ioctl_fops = {
+ /* Core caps/info */
+ .vidioc_querycap = hws_vidioc_querycap,
+
+ /* Pixel format: still needed to report YUYV etc. */
+ .vidioc_enum_fmt_vid_cap = hws_vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = hws_vidioc_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = hws_vidioc_s_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = hws_vidioc_try_fmt_vid_cap,
+
+ /* Buffer queueing / streaming */
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+
+ /* Inputs */
+ .vidioc_enum_input = hws_vidioc_enum_input,
+ .vidioc_g_input = hws_vidioc_g_input,
+ .vidioc_s_input = hws_vidioc_s_input,
+
+ /* DV timings (HDMI/DVI/VESA modes) */
+ .vidioc_query_dv_timings = hws_vidioc_query_dv_timings,
+ .vidioc_enum_dv_timings = hws_vidioc_enum_dv_timings,
+ .vidioc_g_dv_timings = hws_vidioc_g_dv_timings,
+ .vidioc_s_dv_timings = hws_vidioc_s_dv_timings,
+ .vidioc_dv_timings_cap = hws_vidioc_dv_timings_cap,
+
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = hws_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_g_parm = hws_vidioc_g_parm,
+};
+
+static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
+ bool interlaced)
+{
+ /* example for packed 16bpp (YUYV); replace with your real math/align */
+ u32 lines = h; /* full frame lines for sizeimage */
+ u32 bytesperline = ALIGN(w * 2, 64);
+ u32 sizeimage, half0;
+
+ /* publish into pix, since we now carry these in-state */
+ v->pix.bytesperline = bytesperline;
+ sizeimage = bytesperline * lines;
+
+ half0 = sizeimage / 2;
+
+ v->pix.sizeimage = sizeimage;
+ v->pix.half_size = half0; /* first half; second = sizeimage - half0 */
+ v->pix.field = interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
+
+ return v->pix.sizeimage;
+}
+
+static int hws_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
+ unsigned int *nplanes, unsigned int sizes[],
+ struct device *alloc_devs[])
+{
+ struct hws_video *vid = q->drv_priv;
+
+ (void)num_buffers;
+ (void)alloc_devs;
+
+ if (!vid->pix.sizeimage) {
+ vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
+ vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
+ }
+ if (*nplanes) {
+ if (sizes[0] < vid->pix.sizeimage)
+ return -EINVAL;
+ } else {
+ *nplanes = 1;
+ sizes[0] = PAGE_ALIGN(vid->pix.sizeimage);
+ }
+
+ vid->alloc_sizeimage = PAGE_ALIGN(vid->pix.sizeimage);
+ return 0;
+}
+
+static int hws_buffer_prepare(struct vb2_buffer *vb)
+{
+ struct hws_video *vid = vb->vb2_queue->drv_priv;
+ struct hws_pcie_dev *hws = vid->parent;
+ size_t need = vid->pix.sizeimage;
+ dma_addr_t dma_addr;
+
+ if (vb2_plane_size(vb, 0) < need)
+ return -EINVAL;
+
+ /* Validate DMA address alignment */
+ dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ if (dma_addr & 0x3F) { /* 64-byte alignment required */
+ dev_err(&hws->pdev->dev,
+ "Buffer DMA address 0x%llx not 64-byte aligned\n",
+ (unsigned long long)dma_addr);
+ return -EINVAL;
+ }
+
+ vb2_set_plane_payload(vb, 0, need);
+ return 0;
+}
+
+static void hws_buffer_queue(struct vb2_buffer *vb)
+{
+ struct hws_video *vid = vb->vb2_queue->drv_priv;
+ struct hwsvideo_buffer *buf = to_hwsbuf(vb);
+ struct hws_pcie_dev *hws = vid->parent;
+ unsigned long flags;
+
+ dev_dbg(&hws->pdev->dev,
+ "buffer_queue(ch=%u): vb=%p sizeimage=%u q_active=%d\n",
+ vid->channel_index, vb, vid->pix.sizeimage,
+ READ_ONCE(vid->cap_active));
+
+ /* Initialize buffer slot */
+ buf->slot = 0;
+
+ spin_lock_irqsave(&vid->irq_lock, flags);
+ list_add_tail(&buf->list, &vid->capture_queue);
+ vid->queued_count++;
+
+ /* If streaming and no in-flight buffer, prime HW immediately */
+ if (READ_ONCE(vid->cap_active) && !vid->active) {
+ dma_addr_t dma_addr;
+
+ dev_dbg(&hws->pdev->dev,
+ "buffer_queue(ch=%u): priming first vb=%p\n",
+ vid->channel_index, &buf->vb.vb2_buf);
+ list_del_init(&buf->list);
+ vid->queued_count--;
+ vid->active = buf;
+
+ dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(vid->parent, vid->channel_index,
+ dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base + HWS_REG_DMA_ADDR(vid->channel_index));
+
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, vid->channel_index, true);
+ hws_prime_next_locked(vid);
+ } else if (READ_ONCE(vid->cap_active) && vid->active) {
+ hws_prime_next_locked(vid);
+ }
+ spin_unlock_irqrestore(&vid->irq_lock, flags);
+}
+
+static int hws_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct hws_video *v = q->drv_priv;
+ struct hws_pcie_dev *hws = v->parent;
+ struct hwsvideo_buffer *to_program = NULL; /* local copy */
+ struct vb2_buffer *prog_vb2 = NULL;
+ unsigned long flags;
+ int ret;
+
+ dev_dbg(&hws->pdev->dev, "start_streaming: ch=%u count=%u\n",
+ v->channel_index, count);
+
+ ret = hws_check_card_status(hws);
+ if (ret) {
+ struct hwsvideo_buffer *b, *tmp;
+ unsigned long f;
+ LIST_HEAD(queued);
+
+ spin_lock_irqsave(&v->irq_lock, f);
+ if (v->active) {
+ list_add_tail(&v->active->list, &queued);
+ v->active = NULL;
+ }
+ if (v->next_prepared) {
+ list_add_tail(&v->next_prepared->list, &queued);
+ v->next_prepared = NULL;
+ }
+ while (!list_empty(&v->capture_queue)) {
+ b = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_move_tail(&b->list, &queued);
+ }
+ spin_unlock_irqrestore(&v->irq_lock, f);
+
+ list_for_each_entry_safe(b, tmp, &queued, list) {
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+ }
+ return ret;
+ }
+ (void)hws_read_active_state(hws, v->channel_index,
+ &v->pix.interlaced);
+
+ lockdep_assert_held(&v->state_lock);
+ /* init per-stream state */
+ WRITE_ONCE(v->stop_requested, false);
+ WRITE_ONCE(v->cap_active, true);
+ WRITE_ONCE(v->half_seen, false);
+ WRITE_ONCE(v->last_buf_half_toggle, 0);
+
+ /* Try to prime a buffer, but it's OK if none are queued yet */
+ spin_lock_irqsave(&v->irq_lock, flags);
+ if (!v->active && !list_empty(&v->capture_queue)) {
+ to_program = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&to_program->list);
+ v->queued_count--;
+ v->active = to_program;
+ prog_vb2 = &to_program->vb.vb2_buf;
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u took buffer %p\n",
+ v->channel_index, to_program);
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* Only program/enable HW if we actually have a buffer */
+ if (to_program) {
+ if (!prog_vb2)
+ prog_vb2 = &to_program->vb.vb2_buf;
+ {
+ dma_addr_t dma_addr;
+
+ dma_addr = vb2_dma_contig_plane_dma_addr(prog_vb2, 0);
+ hws_program_dma_for_addr(hws, v->channel_index, dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base +
+ HWS_REG_DMA_ADDR(v->channel_index));
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u programmed buffer %p dma=0x%08x\n",
+ v->channel_index, to_program,
+ lower_32_bits(dma_addr));
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, v->channel_index, true);
+ {
+ unsigned long pf;
+
+ spin_lock_irqsave(&v->irq_lock, pf);
+ hws_prime_next_locked(v);
+ spin_unlock_irqrestore(&v->irq_lock, pf);
+ }
+ } else {
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u no buffer yet (will arm on QBUF)\n",
+ v->channel_index);
+ }
+
+ return 0;
+}
+
+static void hws_log_video_state(struct hws_video *v, const char *action,
+ const char *phase)
+{
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned long flags;
+ unsigned int queued = 0;
+ unsigned int tracked = 0;
+ unsigned int seq = 0;
+ struct hwsvideo_buffer *b;
+ bool streaming = 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 = READ_ONCE(v->cap_active);
+ stop_requested = READ_ONCE(v->stop_requested);
+ active = v->active;
+ next_prepared = v->next_prepared;
+ tracked = v->queued_count;
+ seq = (u32)atomic_read(&v->sequence_number);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:%s ch=%u streaming=%d cap=%d stop=%d active=%p next=%p queued=%u tracked=%u seq=%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 = q->drv_priv;
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned long flags;
+ struct hwsvideo_buffer *b, *tmp;
+ LIST_HEAD(done);
+ unsigned int done_cnt = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ hws_log_video_state(v, "streamoff", "begin");
+
+ /* 1) Quiesce SW/HW first */
+ lockdep_assert_held(&v->state_lock);
+ WRITE_ONCE(v->cap_active, false);
+ WRITE_ONCE(v->stop_requested, true);
+
+ hws_enable_video_capture(v->parent, v->channel_index, false);
+
+ /* 2) Collect in-flight + queued under the IRQ lock */
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_video_collect_done_locked(v, &done);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* 3) Complete outside the lock */
+ list_for_each_entry_safe(b, tmp, &done, list) {
+ /* 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=%u completed=%u (%lluus)\n",
+ v->channel_index, done_cnt,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ hws_log_video_state(v, "streamoff", "end");
+}
+
+static const struct vb2_ops hwspcie_video_qops = {
+ .queue_setup = hws_queue_setup,
+ .buf_prepare = hws_buffer_prepare,
+ .buf_init = hws_buf_init,
+ .buf_finish = hws_buf_finish,
+ .buf_cleanup = hws_buf_cleanup,
+ .buf_queue = hws_buffer_queue,
+ .start_streaming = hws_start_streaming,
+ .stop_streaming = hws_stop_streaming,
+};
+
+int hws_video_register(struct hws_pcie_dev *dev)
+{
+ int i, ret;
+
+ ret = v4l2_device_register(&dev->pdev->dev, &dev->v4l2_device);
+ if (ret) {
+ dev_err(&dev->pdev->dev, "v4l2_device_register failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ for (i = 0; i < dev->cur_max_video_ch; i++) {
+ struct hws_video *ch = &dev->video[i];
+ struct video_device *vdev;
+ struct vb2_queue *q;
+
+ /* hws_video_init_channel() should have set:
+ * - ch->parent, ch->channel_index
+ * - locks (state_lock, irq_lock)
+ * - capture_queue (INIT_LIST_HEAD)
+ * - control_handler + controls
+ * - fmt_curr (width/height)
+ * Don’t reinitialize any of those here.
+ */
+
+ vdev = video_device_alloc();
+ if (!vdev) {
+ dev_err(&dev->pdev->dev,
+ "video_device_alloc ch%u failed\n", i);
+ ret = -ENOMEM;
+ goto err_unwind;
+ }
+ ch->video_device = vdev;
+
+ /* Basic V4L2 node setup */
+ snprintf(vdev->name, sizeof(vdev->name), "%s-hdmi%u",
+ KBUILD_MODNAME, i);
+ vdev->v4l2_dev = &dev->v4l2_device;
+ vdev->fops = &hws_fops; /* your file_ops */
+ vdev->ioctl_ops = &hws_ioctl_fops; /* your ioctl_ops */
+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ vdev->lock = &ch->state_lock; /* serialize file ops */
+ vdev->ctrl_handler = &ch->control_handler;
+ vdev->vfl_dir = VFL_DIR_RX;
+ vdev->release = video_device_release;
+ if (ch->control_handler.error) {
+ ret = ch->control_handler.error;
+ goto err_unwind;
+ }
+ video_set_drvdata(vdev, ch);
+
+ /* vb2 queue init (dma-contig) */
+ q = &ch->buffer_queue;
+ memset(q, 0, sizeof(*q));
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_DMABUF;
+ q->drv_priv = ch;
+ q->buf_struct_size = sizeof(struct hwsvideo_buffer);
+ q->ops = &hwspcie_video_qops; /* your vb2_ops */
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &ch->state_lock;
+ q->min_queued_buffers = 1;
+ q->dev = &dev->pdev->dev;
+
+ ret = vb2_queue_init(q);
+ vdev->queue = q;
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "vb2_queue_init ch%u failed: %d\n", i, ret);
+ goto err_unwind;
+ }
+
+ /* Make controls live (no-op if none or already set up) */
+ if (ch->control_handler.error) {
+ ret = ch->control_handler.error;
+ dev_err(&dev->pdev->dev,
+ "ctrl handler ch%u error: %d\n", i, ret);
+ goto err_unwind;
+ }
+ v4l2_ctrl_handler_setup(&ch->control_handler);
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "video_register_device ch%u failed: %d\n", i,
+ ret);
+ goto err_unwind;
+ }
+ }
+
+ return 0;
+
+err_unwind:
+ for (; i >= 0; i--) {
+ struct hws_video *ch = &dev->video[i];
+
+ hws_video_release_registration(ch);
+ }
+ v4l2_device_unregister(&dev->v4l2_device);
+ return ret;
+}
+
+void hws_video_unregister(struct hws_pcie_dev *dev)
+{
+ int i;
+
+ if (!dev)
+ return;
+
+ for (i = 0; i < dev->cur_max_video_ch; i++) {
+ struct hws_video *ch = &dev->video[i];
+
+ hws_video_release_registration(ch);
+ v4l2_ctrl_handler_free(&ch->control_handler);
+ }
+ v4l2_device_unregister(&dev->v4l2_device);
+}
+
+int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason)
+{
+ int i, ret = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ dev_dbg(&hws->pdev->dev, "video:%s:begin channels=%u\n", reason,
+ hws->cur_max_video_ch);
+ for (i = 0; i < hws->cur_max_video_ch; i++) {
+ struct hws_video *vid = &hws->video[i];
+ struct vb2_queue *q = &vid->buffer_queue;
+ u64 ch_start_ns = ktime_get_mono_fast_ns();
+ bool streaming;
+
+ if (!q || !q->ops) {
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d skipped queue-unavailable\n",
+ reason, i);
+ continue;
+ }
+
+ streaming = vb2_is_streaming(q);
+ hws_log_video_state(vid, reason, "channel");
+ if (streaming) {
+ /* Stop via vb2 (runs your .stop_streaming) */
+ int r = vb2_streamoff(q, q->type);
+
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d streamoff ret=%d (%lluus)\n",
+ reason, i, r, (unsigned long long)
+ ((ktime_get_mono_fast_ns() - ch_start_ns) / 1000));
+ if (r && !ret)
+ ret = r;
+ } else {
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d idle (%lluus)\n",
+ reason, i, (unsigned long long)
+ ((ktime_get_mono_fast_ns() - ch_start_ns) / 1000));
+ }
+ }
+ dev_dbg(&hws->pdev->dev, "video:%s:done ret=%d (%lluus)\n", reason,
+ ret,
+ (unsigned long long)((ktime_get_mono_fast_ns() - start_ns) / 1000));
+ return ret;
+}
+
+void hws_video_pm_resume(struct hws_pcie_dev *hws)
+{
+ /* Nothing mandatory to do here for vb2 — userspace will STREAMON again.
+ * If you track per-channel 'auto-restart' policy, re-arm it here.
+ */
+}
diff --git a/drivers/media/pci/hws/hws_video.h b/drivers/media/pci/hws/hws_video.h
new file mode 100644
index 000000000000..d02cfb2cdeb3
--- /dev/null
+++ b/drivers/media/pci/hws/hws_video.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_VIDEO_H
+#define HWS_VIDEO_H
+
+struct hws_video;
+
+int hws_video_register(struct hws_pcie_dev *dev);
+void hws_video_unregister(struct hws_pcie_dev *dev);
+void hws_enable_video_capture(struct hws_pcie_dev *hws,
+ unsigned int chan,
+ bool on);
+void hws_prime_next_locked(struct hws_video *vid);
+
+int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch);
+void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch);
+void check_video_format(struct hws_pcie_dev *pdx);
+int hws_check_card_status(struct hws_pcie_dev *hws);
+void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable);
+
+void hws_program_dma_for_addr(struct hws_pcie_dev *hws,
+ unsigned int ch,
+ dma_addr_t dma);
+void hws_set_dma_doorbell(struct hws_pcie_dev *hws, unsigned int ch,
+ dma_addr_t dma, const char *tag);
+
+int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason);
+void hws_video_pm_resume(struct hws_pcie_dev *hws);
+
+#endif // HWS_VIDEO_H
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4] media: pci: add AVMatrix HWS capture driver
2026-03-30 23:36 ` [PATCH v4] media: pci: add AVMatrix HWS capture driver hoff.benjamin.k
@ 2026-04-02 6:25 ` kernel test robot
2026-04-03 13:57 ` [PATCH v5] " hoff.benjamin.k
1 sibling, 0 replies; 11+ messages in thread
From: kernel test robot @ 2026-04-02 6:25 UTC (permalink / raw)
To: hoff.benjamin.k, linux-media
Cc: oe-kbuild-all, linux-kernel, mchehab, hverkuil+cisco
[-- Attachment #1: Type: text/plain, Size: 1423 bytes --]
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on linuxtv-media-pending/master]
[also build test ERROR on media-tree/master sailus-media-tree/master linus/master v7.0-rc6 next-20260331]
[cannot apply to sailus-media-tree/streams]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/hoff-benjamin-k-gmail-com/media-pci-add-AVMatrix-HWS-capture-driver/20260401-020513
base: https://git.linuxtv.org/media-ci/media-pending.git master
patch link: https://lore.kernel.org/r/20260330233636.381969-1-hoff.benjamin.k%40gmail.com
patch subject: [PATCH v4] media: pci: add AVMatrix HWS capture driver
config: i386-allmodconfig
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build):
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/202604020522.z22eZuW8-lkp@intel.com/
All errors (new ones prefixed by >>, old ones prefixed by <<):
>> ERROR: modpost: "__udivdi3" [drivers/media/pci/hws/hws.ko] undefined!
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
[-- Attachment #2: reproduce --]
[-- Type: text/plain, Size: 515 bytes --]
reproduce (this is a W=1 build):
git remote add linuxtv-media-pending https://git.linuxtv.org/media-ci/media-pending.git
git fetch linuxtv-media-pending master
git checkout linuxtv-media-pending/master
b4 shazam https://lore.kernel.org/r/20260330233636.381969-1-hoff.benjamin.k@gmail.com
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=i386 olddefconfig
make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash
[-- Attachment #3: config --]
[-- Type: text/plain, Size: 420494 bytes --]
#
# Automatically generated file; DO NOT EDIT.
# Linux/i386 7.0.0-rc2 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc-14 (Debian 14.2.0-19) 14.2.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=140200
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=24400
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=24400
CONFIG_LLD_VERSION=0
CONFIG_RUSTC_VERSION=0
CONFIG_RUSTC_LLVM_VERSION=0
CONFIG_CC_CAN_LINK=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
CONFIG_TOOLS_SUPPORT_RELR=y
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_ASSUME=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_LD_CAN_USE_KEEP_IN_OVERLAY=y
CONFIG_PAHOLE_VERSION=131
CONFIG_CONSTRUCTORS=y
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_TABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y
#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_COMPILE_TEST=y
# CONFIG_WERROR is not set
CONFIG_UAPI_HEADER_TEST=y
CONFIG_LOCALVERSION=""
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_HAVE_KERNEL_ZSTD=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
# CONFIG_KERNEL_ZSTD is not set
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_WATCH_QUEUE=y
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_AUDIT=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_AUDITSYSCALL=y
#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_GENERIC_IRQ_MIGRATION=y
CONFIG_GENERIC_IRQ_INJECTION=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_SIM=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y
CONFIG_GENERIC_IRQ_RESERVATION_MODE=y
CONFIG_GENERIC_IRQ_STAT_SNAPSHOT=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_GENERIC_IRQ_DEBUGFS=y
# end of IRQ subsystem
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_ARCH_CLOCKSOURCE_INIT=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST_IDLE=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_TIME_KUNIT_TEST=m
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=125
CONFIG_POSIX_AUX_CLOCKS=y
# end of Timers subsystem
CONFIG_BPF=y
CONFIG_HAVE_EBPF_JIT=y
#
# BPF subsystem
#
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_BPF_JIT_DEFAULT_ON=y
CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
CONFIG_BPF_LSM=y
# end of BPF subsystem
CONFIG_PREEMPT_BUILD=y
CONFIG_ARCH_HAS_PREEMPT_LAZY=y
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_LAZY=y
CONFIG_PREEMPT_COUNT=y
CONFIG_PREEMPTION=y
CONFIG_PREEMPT_DYNAMIC=y
CONFIG_SCHED_CORE=y
#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_SCHED_AVG_IRQ=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_PSI=y
CONFIG_PSI_DEFAULT_DISABLED=y
# end of CPU/Task time and stats accounting
CONFIG_CPU_ISOLATION=y
#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
CONFIG_PREEMPT_RCU=y
CONFIG_RCU_EXPERT=y
CONFIG_TREE_SRCU=y
CONFIG_FORCE_NEED_SRCU_NMI_SAFE=y
CONFIG_NEED_SRCU_NMI_SAFE=y
CONFIG_TASKS_RCU_GENERIC=y
CONFIG_FORCE_TASKS_RCU=y
CONFIG_NEED_TASKS_RCU=y
CONFIG_TASKS_RCU=y
CONFIG_FORCE_TASKS_RUDE_RCU=y
CONFIG_TASKS_RUDE_RCU=y
CONFIG_FORCE_TASKS_TRACE_RCU=y
CONFIG_TASKS_TRACE_RCU=y
CONFIG_TASKS_TRACE_RCU_NO_MB=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_RCU_NEED_SEGCBLIST=y
CONFIG_RCU_FANOUT=32
CONFIG_RCU_FANOUT_LEAF=16
CONFIG_RCU_BOOST=y
CONFIG_RCU_BOOST_DELAY=500
CONFIG_RCU_EXP_KTHREAD=y
CONFIG_RCU_NOCB_CPU=y
CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=y
CONFIG_RCU_NOCB_CPU_CB_BOOST=y
CONFIG_RCU_LAZY=y
CONFIG_RCU_LAZY_DEFAULT_OFF=y
CONFIG_RCU_DOUBLE_CHECK_CB_TIME=y
# end of RCU Subsystem
CONFIG_IKCONFIG=m
CONFIG_IKCONFIG_PROC=y
CONFIG_IKHEADERS=m
CONFIG_LOG_BUF_SHIFT=17
CONFIG_LOG_CPU_MAX_BUF_SHIFT=0
CONFIG_PRINTK_INDEX=y
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
#
# Scheduler features
#
CONFIG_UCLAMP_TASK=y
CONFIG_UCLAMP_BUCKETS_COUNT=5
CONFIG_SCHED_PROXY_EXEC=y
# end of Scheduler features
CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_GCC10_NO_ARRAY_BOUNDS=y
CONFIG_CC_NO_ARRAY_BOUNDS=y
CONFIG_GCC_NO_STRINGOP_OVERFLOW=y
CONFIG_CC_NO_STRINGOP_OVERFLOW=y
CONFIG_SLAB_OBJ_EXT=y
CONFIG_CGROUPS=y
CONFIG_PAGE_COUNTER=y
CONFIG_CGROUP_FAVOR_DYNMODS=y
CONFIG_MEMCG=y
CONFIG_MEMCG_V1=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_GROUP_SCHED_WEIGHT=y
CONFIG_GROUP_SCHED_BANDWIDTH=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_RT_GROUP_SCHED_DEFAULT_DISABLED=y
CONFIG_SCHED_MM_CID=y
CONFIG_UCLAMP_TASK_GROUP=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_DMEM=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CPUSETS=y
CONFIG_CPUSETS_V1=y
CONFIG_PROC_PID_CPUSET=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
CONFIG_CGROUP_MISC=y
CONFIG_CGROUP_DEBUG=y
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_TIME_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
CONFIG_RD_LZ4=y
CONFIG_RD_ZSTD=y
CONFIG_BOOT_CONFIG=y
CONFIG_BOOT_CONFIG_FORCE=y
CONFIG_BOOT_CONFIG_EMBED=y
CONFIG_BOOT_CONFIG_EMBED_FILE=""
CONFIG_CMDLINE_LOG_WRAP_IDEAL_LEN=1021
CONFIG_INITRAMFS_PRESERVE_MTIME=y
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_LD_ORPHAN_WARN=y
CONFIG_LD_ORPHAN_WARN_LEVEL="warn"
CONFIG_SYSCTL=y
CONFIG_HAVE_UID16=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYSFS_SYSCALL=y
CONFIG_HAVE_PCSPKR_PLATFORM=y
CONFIG_EXPERT=y
CONFIG_UID16=y
CONFIG_MULTIUSER=y
CONFIG_SGETMASK_SYSCALL=y
CONFIG_FHANDLE=y
CONFIG_POSIX_TIMERS=y
CONFIG_PRINTK=y
CONFIG_PRINTK_RINGBUFFER_KUNIT_TEST=m
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_SMALL=y
CONFIG_FUTEX=y
CONFIG_FUTEX_PI=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_IO_URING=y
CONFIG_GCOV_PROFILE_URING=y
CONFIG_IO_URING_MOCK_FILE=m
CONFIG_ADVISE_SYSCALLS=y
CONFIG_MEMBARRIER=y
CONFIG_KCMP=y
CONFIG_RSEQ=y
CONFIG_RSEQ_SLICE_EXTENSION=y
CONFIG_RSEQ_STATS=y
CONFIG_RSEQ_DEBUG_DEFAULT_ENABLE=y
CONFIG_CACHESTAT_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_SELFTEST=y
CONFIG_KALLSYMS_ALL=y
CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_GUEST_PERF_EVENTS=y
CONFIG_PERF_GUEST_MEDIATED_PMU=y
CONFIG_PERF_USE_VMALLOC=y
#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
CONFIG_DEBUG_PERF_USE_VMALLOC=y
# end of Kernel Performance Events And Counters
CONFIG_SYSTEM_DATA_VERIFICATION=y
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
#
# Kexec and crash features
#
CONFIG_CRASH_RESERVE=y
CONFIG_VMCORE_INFO=y
CONFIG_KEXEC_CORE=y
CONFIG_KEXEC=y
CONFIG_KEXEC_JUMP=y
CONFIG_CRASH_DUMP=y
CONFIG_CRASH_DUMP_KUNIT_TEST=m
CONFIG_CRASH_HOTPLUG=y
CONFIG_CRASH_MAX_MEMORY_RANGES=8192
# end of Kexec and crash features
#
# Live Update and Kexec HandOver
#
# end of Live Update and Kexec HandOver
# end of General setup
CONFIG_X86_32=y
CONFIG_FORCE_DYNAMIC_FTRACE=y
CONFIG_X86=y
CONFIG_INSTRUCTION_DECODER=y
CONFIG_OUTPUT_FORMAT="elf32-i386"
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_MMU=y
CONFIG_ARCH_MMAP_RND_BITS_MIN=8
CONFIG_ARCH_MMAP_RND_BITS_MAX=16
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_HAVE_INTEL_TXT=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_PGTABLE_LEVELS=3
#
# Processor type and features
#
CONFIG_SMP=y
CONFIG_X86_MPPARSE=y
CONFIG_X86_CPU_RESCTRL=y
CONFIG_X86_EXTENDED_PLATFORM=y
CONFIG_X86_INTEL_MID=y
CONFIG_X86_GOLDFISH=y
CONFIG_X86_INTEL_QUARK=y
CONFIG_X86_RDC321X=y
CONFIG_X86_INTEL_LPSS=y
CONFIG_X86_AMD_PLATFORM_DEVICE=y
CONFIG_IOSF_MBI=y
CONFIG_IOSF_MBI_DEBUG=y
CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
CONFIG_X86_32_IRIS=m
CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_HYPERVISOR_GUEST=y
CONFIG_PARAVIRT=y
CONFIG_PARAVIRT_SPINLOCKS=y
CONFIG_X86_HV_CALLBACK_VECTOR=y
CONFIG_XEN=y
CONFIG_XEN_PVHVM=y
CONFIG_XEN_PVHVM_SMP=y
CONFIG_XEN_PVHVM_GUEST=y
CONFIG_XEN_DEBUG_FS=y
CONFIG_XEN_PVH=y
CONFIG_KVM_GUEST=y
CONFIG_ARCH_CPUIDLE_HALTPOLL=y
CONFIG_PVH=y
CONFIG_PARAVIRT_TIME_ACCOUNTING=y
CONFIG_PARAVIRT_CLOCK=y
# CONFIG_M486SX is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
CONFIG_M686=y
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MELAN is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MATOM is not set
CONFIG_CC_HAS_MARCH_NATIVE=y
CONFIG_X86_GENERIC=y
CONFIG_X86_INTERNODE_CACHE_SHIFT=6
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_TSC=y
CONFIG_X86_HAVE_PAE=y
CONFIG_X86_CX8=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=6
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_IA32_FEAT_CTL=y
CONFIG_X86_VMX_FEATURE_NAMES=y
CONFIG_PROCESSOR_SELECT=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_CYRIX_32=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_HYGON=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_CPU_SUP_TRANSMETA_32=y
CONFIG_CPU_SUP_UMC_32=y
CONFIG_CPU_SUP_ZHAOXIN=y
CONFIG_CPU_SUP_VORTEX_32=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_DMI=y
CONFIG_BOOT_VESA_SUPPORT=y
CONFIG_NR_CPUS_RANGE_BEGIN=2
CONFIG_NR_CPUS_RANGE_END=8
CONFIG_NR_CPUS_DEFAULT=8
CONFIG_NR_CPUS=8
CONFIG_SCHED_MC_PRIO=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
CONFIG_X86_MCE=y
CONFIG_X86_MCELOG_LEGACY=y
CONFIG_X86_MCE_INTEL=y
CONFIG_X86_MCE_AMD=y
CONFIG_X86_ANCIENT_MCE=y
CONFIG_X86_MCE_THRESHOLD=y
CONFIG_X86_MCE_INJECT=m
#
# Performance monitoring
#
CONFIG_PERF_EVENTS_INTEL_UNCORE=m
CONFIG_PERF_EVENTS_INTEL_RAPL=m
CONFIG_PERF_EVENTS_INTEL_CSTATE=m
CONFIG_PERF_EVENTS_AMD_POWER=m
CONFIG_PERF_EVENTS_AMD_UNCORE=m
CONFIG_PERF_EVENTS_AMD_BRS=y
# end of Performance monitoring
CONFIG_X86_LEGACY_VM86=y
CONFIG_VM86=y
CONFIG_X86_16BIT=y
CONFIG_X86_ESPFIX32=y
CONFIG_X86_IOPL_IOPERM=y
CONFIG_TOSHIBA=m
CONFIG_X86_REBOOTFIXUPS=y
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INITRD32=y
CONFIG_MICROCODE_LATE_LOADING=y
CONFIG_MICROCODE_LATE_FORCE_MINREV=y
CONFIG_MICROCODE_DBG=y
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
CONFIG_HIGHMEM4G=y
CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_HIGHMEM=y
CONFIG_X86_PAE=y
CONFIG_X86_CPA_STATISTICS=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ILLEGAL_POINTER_VALUE=0
CONFIG_X86_PMEM_LEGACY_DEVICE=y
CONFIG_X86_PMEM_LEGACY=m
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
CONFIG_MTRR=y
CONFIG_MTRR_SANITIZER=y
CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
CONFIG_X86_PAT=y
CONFIG_X86_UMIP=y
CONFIG_CC_HAS_IBT=y
CONFIG_ARCH_PKEY_BITS=4
# CONFIG_X86_INTEL_TSX_MODE_OFF is not set
# CONFIG_X86_INTEL_TSX_MODE_ON is not set
CONFIG_X86_INTEL_TSX_MODE_AUTO=y
CONFIG_EFI=y
CONFIG_EFI_STUB=y
CONFIG_EFI_HANDOVER_PROTOCOL=y
CONFIG_EFI_RUNTIME_MAP=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_SCHED_HRTICK=y
CONFIG_ARCH_SUPPORTS_KEXEC=y
CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY=y
CONFIG_ARCH_SUPPORTS_KEXEC_SIG=y
CONFIG_ARCH_SUPPORTS_KEXEC_SIG_FORCE=y
CONFIG_ARCH_SUPPORTS_KEXEC_BZIMAGE_VERIFY_SIG=y
CONFIG_ARCH_SUPPORTS_KEXEC_JUMP=y
CONFIG_ARCH_SUPPORTS_CRASH_DUMP=y
CONFIG_ARCH_DEFAULT_CRASH_DUMP=y
CONFIG_ARCH_SUPPORTS_CRASH_HOTPLUG=y
CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION=y
CONFIG_PHYSICAL_START=0x1000000
CONFIG_RELOCATABLE=y
CONFIG_RANDOMIZE_BASE=y
CONFIG_X86_NEED_RELOCS=y
CONFIG_PHYSICAL_ALIGN=0x200000
CONFIG_HOTPLUG_CPU=y
CONFIG_COMPAT_VDSO=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
CONFIG_MODIFY_LDT_SYSCALL=y
CONFIG_STRICT_SIGALTSTACK_SIZE=y
CONFIG_X86_BUS_LOCK_DETECT=y
# end of Processor type and features
CONFIG_CC_HAS_NAMED_AS=y
CONFIG_CC_HAS_NAMED_AS_FIXED_SANITIZERS=y
CONFIG_USE_X86_SEG_SUPPORT=y
CONFIG_CC_HAS_SLS=y
CONFIG_CC_HAS_RETURN_THUNK=y
CONFIG_CC_HAS_ENTRY_PADDING=y
CONFIG_FUNCTION_PADDING_CFI=0
CONFIG_FUNCTION_PADDING_BYTES=4
CONFIG_CPU_MITIGATIONS=y
CONFIG_MITIGATION_PAGE_TABLE_ISOLATION=y
CONFIG_MITIGATION_RETPOLINE=y
CONFIG_MITIGATION_RETHUNK=y
CONFIG_MITIGATION_GDS=y
CONFIG_MITIGATION_RFDS=y
CONFIG_MITIGATION_SPECTRE_BHI=y
CONFIG_MITIGATION_MDS=y
CONFIG_MITIGATION_TAA=y
CONFIG_MITIGATION_MMIO_STALE_DATA=y
CONFIG_MITIGATION_L1TF=y
CONFIG_MITIGATION_RETBLEED=y
CONFIG_MITIGATION_SPECTRE_V1=y
CONFIG_MITIGATION_SPECTRE_V2=y
CONFIG_MITIGATION_SRBDS=y
CONFIG_MITIGATION_SSB=y
CONFIG_MITIGATION_TSA=y
CONFIG_MITIGATION_VMSCAPE=y
#
# Power management and ACPI options
#
CONFIG_ARCH_HIBERNATION_HEADER=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_SUSPEND_SKIP_SYNC=y
CONFIG_HIBERNATE_CALLBACKS=y
CONFIG_HIBERNATION=y
CONFIG_HIBERNATION_SNAPSHOT_DEV=y
CONFIG_HIBERNATION_COMP_LZO=y
# CONFIG_HIBERNATION_COMP_LZ4 is not set
CONFIG_HIBERNATION_DEF_COMP="lzo"
CONFIG_PM_STD_PARTITION=""
CONFIG_PM_SLEEP=y
CONFIG_PM_SLEEP_SMP=y
CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_USERSPACE_AUTOSLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=100
CONFIG_PM_WAKELOCKS_GC=y
CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP=y
CONFIG_PM=y
CONFIG_PM_DEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_PM_TEST_SUSPEND=y
CONFIG_PM_SLEEP_DEBUG=y
CONFIG_DPM_WATCHDOG=y
CONFIG_DPM_WATCHDOG_TIMEOUT=120
CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT=120
CONFIG_PM_TRACE=y
CONFIG_PM_TRACE_RTC=y
CONFIG_PM_CLK=y
CONFIG_PM_GENERIC_DOMAINS=y
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
CONFIG_PM_GENERIC_DOMAINS_OF=y
CONFIG_ENERGY_MODEL=y
CONFIG_ARCH_SUPPORTS_ACPI=y
CONFIG_ACPI=y
CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y
CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y
CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y
CONFIG_ACPI_THERMAL_LIB=y
CONFIG_ACPI_DEBUGGER=y
CONFIG_ACPI_DEBUGGER_USER=m
CONFIG_ACPI_SPCR_TABLE=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_EC_DEBUGFS=m
CONFIG_ACPI_AC=m
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_TINY_POWER_BUTTON=m
CONFIG_ACPI_TINY_POWER_BUTTON_SIGNAL=38
CONFIG_ACPI_VIDEO=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_TAD=m
CONFIG_ACPI_DOCK=y
CONFIG_ACPI_CPU_FREQ_PSS=y
CONFIG_ACPI_PROCESSOR_CSTATE=y
CONFIG_ACPI_PROCESSOR_IDLE=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_IPMI=m
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_PROCESSOR_AGGREGATOR=m
CONFIG_ACPI_THERMAL=m
CONFIG_ACPI_PLATFORM_PROFILE=m
CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y
CONFIG_ACPI_TABLE_UPGRADE=y
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_PCI_SLOT=y
CONFIG_ACPI_CONTAINER=y
CONFIG_ACPI_HOTPLUG_IOAPIC=y
CONFIG_ACPI_SBS=m
CONFIG_ACPI_HED=y
CONFIG_ACPI_BGRT=y
CONFIG_ACPI_REDUCED_HARDWARE_ONLY=y
CONFIG_ACPI_NHLT=y
CONFIG_HAVE_ACPI_APEI=y
CONFIG_HAVE_ACPI_APEI_NMI=y
CONFIG_ACPI_APEI=y
CONFIG_ACPI_APEI_GHES=y
CONFIG_ACPI_APEI_PCIEAER=y
CONFIG_ACPI_APEI_MEMORY_FAILURE=y
CONFIG_ACPI_APEI_EINJ=m
CONFIG_ACPI_APEI_EINJ_CXL=y
CONFIG_ACPI_APEI_ERST_DEBUG=m
CONFIG_ACPI_DPTF=y
CONFIG_DPTF_POWER=m
CONFIG_DPTF_PCH_FIVR=m
CONFIG_ACPI_WATCHDOG=y
CONFIG_ACPI_EXTLOG=m
CONFIG_ACPI_CONFIGFS=m
CONFIG_ACPI_PCC=y
CONFIG_ACPI_FFH=y
CONFIG_PMIC_OPREGION=y
CONFIG_BYTCRC_PMIC_OPREGION=y
CONFIG_CHTCRC_PMIC_OPREGION=y
CONFIG_XPOWER_PMIC_OPREGION=y
CONFIG_BXT_WC_PMIC_OPREGION=y
CONFIG_TPS68470_PMIC_OPREGION=y
CONFIG_ACPI_VIOT=y
CONFIG_X86_PM_TIMER=y
CONFIG_X86_APM_BOOT=y
CONFIG_APM=m
CONFIG_APM_IGNORE_USER_SUSPEND=y
CONFIG_APM_DO_ENABLE=y
CONFIG_APM_CPU_IDLE=y
CONFIG_APM_DISPLAY_BLANK=y
CONFIG_APM_ALLOW_INTS=y
#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
#
# CPU frequency scaling drivers
#
CONFIG_CPUFREQ_DT=m
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_X86_INTEL_PSTATE=y
CONFIG_X86_PCC_CPUFREQ=m
CONFIG_X86_AMD_PSTATE=y
CONFIG_X86_AMD_PSTATE_DEFAULT_MODE=3
CONFIG_X86_AMD_PSTATE_UT=m
CONFIG_X86_ACPI_CPUFREQ=m
CONFIG_X86_ACPI_CPUFREQ_CPB=y
CONFIG_X86_POWERNOW_K6=m
CONFIG_X86_POWERNOW_K7=m
CONFIG_X86_POWERNOW_K7_ACPI=y
CONFIG_X86_POWERNOW_K8=m
CONFIG_X86_AMD_FREQ_SENSITIVITY=m
CONFIG_X86_GX_SUSPMOD=m
CONFIG_X86_SPEEDSTEP_CENTRINO=m
CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
CONFIG_X86_SPEEDSTEP_ICH=m
CONFIG_X86_SPEEDSTEP_SMI=m
CONFIG_X86_P4_CLOCKMOD=m
CONFIG_X86_CPUFREQ_NFORCE2=m
CONFIG_X86_LONGRUN=m
CONFIG_X86_LONGHAUL=m
CONFIG_X86_E_POWERSAVER=m
#
# shared options
#
CONFIG_X86_SPEEDSTEP_LIB=m
CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y
CONFIG_CPUFREQ_ARCH_CUR_FREQ=y
CONFIG_ARM_AIROHA_SOC_CPUFREQ=m
CONFIG_ARM_ARMADA_37XX_CPUFREQ=m
CONFIG_ARM_ARMADA_8K_CPUFREQ=m
CONFIG_ARM_SCPI_CPUFREQ=m
CONFIG_ARM_BRCMSTB_AVS_CPUFREQ=m
CONFIG_ARM_IMX_CPUFREQ_DT=m
CONFIG_ARM_MEDIATEK_CPUFREQ=m
CONFIG_ARM_MEDIATEK_CPUFREQ_HW=m
CONFIG_ARM_QCOM_CPUFREQ_NVMEM=m
CONFIG_ARM_QCOM_CPUFREQ_HW=m
CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
CONFIG_ARM_S3C64XX_CPUFREQ=y
CONFIG_ARM_S5PV210_CPUFREQ=y
CONFIG_ARM_SCMI_CPUFREQ=m
CONFIG_ARM_SPEAR_CPUFREQ=y
CONFIG_ARM_STI_CPUFREQ=m
CONFIG_ARM_TEGRA20_CPUFREQ=m
CONFIG_ARM_TEGRA124_CPUFREQ=m
CONFIG_ARM_TI_CPUFREQ=y
CONFIG_ARM_PXA2xx_CPUFREQ=m
CONFIG_QORIQ_CPUFREQ=m
# end of CPU Frequency scaling
#
# CPU Idle
#
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_CPU_IDLE_GOV_TEO=y
CONFIG_CPU_IDLE_GOV_HALTPOLL=y
CONFIG_HALTPOLL_CPUIDLE=m
# end of CPU Idle
CONFIG_INTEL_IDLE=y
# end of Power management and ACPI options
#
# Bus options (PCI etc.)
#
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCI_XEN=y
CONFIG_PCI_CNB20LE_QUIRK=y
CONFIG_ISA_BUS=y
CONFIG_ISA_DMA_API=y
CONFIG_ISA=y
CONFIG_SCx200=m
CONFIG_SCx200HR_TIMER=m
CONFIG_GEODE_COMMON=y
CONFIG_ALIX=y
CONFIG_NET5501=y
CONFIG_GEOS=y
CONFIG_AMD_NB=y
CONFIG_AMD_NODE=y
# end of Bus options (PCI etc.)
#
# Binary Emulations
#
CONFIG_COMPAT_32=y
# end of Binary Emulations
CONFIG_HAVE_ATOMIC_IOMAP=y
CONFIG_KVM_COMMON=y
CONFIG_HAVE_KVM_PFNCACHE=y
CONFIG_HAVE_KVM_IRQCHIP=y
CONFIG_HAVE_KVM_IRQ_ROUTING=y
CONFIG_HAVE_KVM_DIRTY_RING=y
CONFIG_HAVE_KVM_DIRTY_RING_TSO=y
CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL=y
CONFIG_KVM_MMIO=y
CONFIG_KVM_ASYNC_PF=y
CONFIG_HAVE_KVM_MSI=y
CONFIG_HAVE_KVM_READONLY_MEM=y
CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y
CONFIG_KVM_VFIO=y
CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y
CONFIG_KVM_GENERIC_PRE_FAULT_MEMORY=y
CONFIG_HAVE_KVM_IRQ_BYPASS=m
CONFIG_HAVE_KVM_NO_POLL=y
CONFIG_VIRT_XFER_TO_GUEST_WORK=y
CONFIG_HAVE_KVM_PM_NOTIFIER=y
CONFIG_KVM_GENERIC_HARDWARE_ENABLING=y
CONFIG_KVM_ELIDE_TLB_FLUSH_IF_YOUNG=y
CONFIG_KVM_MMU_LOCKLESS_AGING=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM_X86=m
CONFIG_KVM=m
# CONFIG_KVM_WERROR is not set
CONFIG_KVM_INTEL=m
CONFIG_KVM_INTEL_PROVE_VE=y
CONFIG_KVM_AMD=m
CONFIG_KVM_IOAPIC=y
CONFIG_KVM_SMM=y
CONFIG_KVM_HYPERV=y
CONFIG_KVM_XEN=y
CONFIG_KVM_PROVE_MMU=y
CONFIG_KVM_MAX_NR_VCPUS=1024
CONFIG_X86_REQUIRED_FEATURE_ALWAYS=y
CONFIG_X86_REQUIRED_FEATURE_CX8=y
CONFIG_X86_REQUIRED_FEATURE_CMOV=y
CONFIG_X86_REQUIRED_FEATURE_FPU=y
CONFIG_X86_REQUIRED_FEATURE_PAE=y
CONFIG_X86_DISABLED_FEATURE_SYSCALL32=y
CONFIG_X86_DISABLED_FEATURE_PCID=y
CONFIG_X86_DISABLED_FEATURE_LASS=y
CONFIG_X86_DISABLED_FEATURE_PKU=y
CONFIG_X86_DISABLED_FEATURE_OSPKE=y
CONFIG_X86_DISABLED_FEATURE_UNRET=y
CONFIG_X86_DISABLED_FEATURE_CALL_DEPTH=y
CONFIG_X86_DISABLED_FEATURE_LAM=y
CONFIG_X86_DISABLED_FEATURE_ENQCMD=y
CONFIG_X86_DISABLED_FEATURE_SGX=y
CONFIG_X86_DISABLED_FEATURE_XENPV=y
CONFIG_X86_DISABLED_FEATURE_TDX_GUEST=y
CONFIG_X86_DISABLED_FEATURE_USER_SHSTK=y
CONFIG_X86_DISABLED_FEATURE_IBT=y
CONFIG_X86_DISABLED_FEATURE_FRED=y
CONFIG_X86_DISABLED_FEATURE_SEV_SNP=y
CONFIG_X86_DISABLED_FEATURE_INVLPGB=y
CONFIG_AS_WRUSS=y
CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS=y
CONFIG_ARCH_HAS_DMA_OPS=y
#
# General architecture-dependent options
#
CONFIG_HOTPLUG_SMT=y
CONFIG_ARCH_SUPPORTS_SCHED_SMT=y
CONFIG_ARCH_SUPPORTS_SCHED_CLUSTER=y
CONFIG_ARCH_SUPPORTS_SCHED_MC=y
CONFIG_SCHED_SMT=y
CONFIG_SCHED_CLUSTER=y
CONFIG_SCHED_MC=y
CONFIG_HOTPLUG_CORE_SYNC=y
CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
CONFIG_HOTPLUG_CORE_SYNC_FULL=y
CONFIG_HOTPLUG_SPLIT_STARTUP=y
CONFIG_GENERIC_IRQ_ENTRY=y
CONFIG_GENERIC_SYSCALL=y
CONFIG_GENERIC_ENTRY=y
CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y
CONFIG_STATIC_KEYS_SELFTEST=y
CONFIG_STATIC_CALL_SELFTEST=y
CONFIG_OPTPROBES=y
CONFIG_KPROBES_ON_FTRACE=y
CONFIG_UPROBES=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_KRETPROBES=y
CONFIG_KRETPROBE_ON_RETHOOK=y
CONFIG_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_KPROBES_ON_FTRACE=y
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
CONFIG_HAVE_NMI=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
CONFIG_ARCH_HAS_SET_MEMORY=y
CONFIG_ARCH_HAS_SET_DIRECT_MAP=y
CONFIG_ARCH_HAS_CPU_FINALIZE_INIT=y
CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y
CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_HAVE_ASM_MODVERSIONS=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_RSEQ=y
CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_PERF_EVENTS_NMI=y
CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y
CONFIG_MMU_GATHER_TABLE_FREE=y
CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
CONFIG_MMU_GATHER_MERGE_VMAS=y
CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_ARCH_HAVE_EXTRA_ELF_NOTES=y
CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_ARCH_SECCOMP=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_SECCOMP=y
CONFIG_SECCOMP_FILTER=y
CONFIG_SECCOMP_CACHE_DEBUG=y
CONFIG_HAVE_ARCH_KSTACK_ERASE=y
CONFIG_HAVE_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR_STRONG=y
CONFIG_ARCH_SUPPORTS_LTO_CLANG=y
CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y
CONFIG_LTO_NONE=y
CONFIG_ARCH_SUPPORTS_AUTOFDO_CLANG=y
CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_PV_STEAL_CLOCK_GEN=y
CONFIG_HAVE_MOVE_PUD=y
CONFIG_HAVE_MOVE_PMD=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
CONFIG_HAVE_ARCH_HUGE_VMAP=y
CONFIG_ARCH_WANT_PMD_MKWRITE=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
CONFIG_HAVE_EXIT_THREAD=y
CONFIG_ARCH_MMAP_RND_BITS=8
CONFIG_HAVE_PAGE_SIZE_4KB=y
CONFIG_PAGE_SIZE_4KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SHIFT=12
CONFIG_ISA_BUS_API=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OLD_SIGACTION=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_ARCH_SUPPORTS_RT=y
CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y
CONFIG_RANDOMIZE_KSTACK_OFFSET=y
CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y
CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
CONFIG_STRICT_KERNEL_RWX=y
CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
CONFIG_STRICT_MODULE_RWX=y
CONFIG_ARCH_HAS_CPU_RESCTRL=y
CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y
CONFIG_ARCH_USE_MEMREMAP_PROT=y
CONFIG_LOCK_EVENT_COUNTS=y
CONFIG_ARCH_HAS_MEM_ENCRYPT=y
CONFIG_HAVE_STATIC_CALL=y
CONFIG_HAVE_PREEMPT_DYNAMIC=y
CONFIG_HAVE_PREEMPT_DYNAMIC_CALL=y
CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_ARCH_SPLIT_ARG64=y
CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y
CONFIG_DYNAMIC_SIGFRAME=y
CONFIG_ARCH_HAS_HW_PTE_YOUNG=y
CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y
CONFIG_ARCH_HAS_KERNEL_FPU_SUPPORT=y
CONFIG_ARCH_VMLINUX_NEEDS_RELOCS=y
CONFIG_HAVE_GENERIC_TIF_BITS=y
#
# GCOV-based kernel profiling
#
CONFIG_GCOV_KERNEL=y
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling
CONFIG_HAVE_GCC_PLUGINS=y
CONFIG_GCC_PLUGINS=y
CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_CC_HAS_MIN_FUNCTION_ALIGNMENT=y
CONFIG_CC_HAS_SANE_FUNCTION_ALIGNMENT=y
CONFIG_ARCH_HAS_CPU_ATTACK_VECTORS=y
# end of General architecture-dependent options
CONFIG_RT_MUTEXES=y
CONFIG_MODULE_SIG_FORMAT=y
CONFIG_MODULES=y
CONFIG_MODULE_DEBUGFS=y
CONFIG_MODULE_DEBUG=y
CONFIG_MODULE_STATS=y
CONFIG_MODULE_DEBUG_AUTOLOAD_DUPS=y
CONFIG_MODULE_DEBUG_AUTOLOAD_DUPS_TRACE=y
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODULE_UNLOAD_TAINT_TRACKING=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_ALL=y
# CONFIG_MODULE_SIG_SHA256 is not set
# CONFIG_MODULE_SIG_SHA384 is not set
CONFIG_MODULE_SIG_SHA512=y
# CONFIG_MODULE_SIG_SHA3_256 is not set
# CONFIG_MODULE_SIG_SHA3_384 is not set
# CONFIG_MODULE_SIG_SHA3_512 is not set
CONFIG_MODULE_SIG_HASH="sha512"
CONFIG_MODULE_COMPRESS=y
CONFIG_MODULE_COMPRESS_GZIP=y
# CONFIG_MODULE_COMPRESS_XZ is not set
# CONFIG_MODULE_COMPRESS_ZSTD is not set
CONFIG_MODULE_COMPRESS_ALL=y
CONFIG_MODULE_DECOMPRESS=y
CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y
CONFIG_MODPROBE_PATH="/sbin/modprobe"
CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_UNUSED_KSYMS_WHITELIST=""
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_BLOCK=y
CONFIG_BLOCK_LEGACY_AUTOLOAD=y
CONFIG_BLK_RQ_ALLOC_TIME=y
CONFIG_BLK_CGROUP_RWSTAT=y
CONFIG_BLK_CGROUP_PUNT_BIO=y
CONFIG_BLK_DEV_BSG_COMMON=y
CONFIG_BLK_ICQ=y
CONFIG_BLK_DEV_BSGLIB=y
CONFIG_BLK_DEV_INTEGRITY=y
CONFIG_BLK_DEV_WRITE_MOUNTED=y
CONFIG_BLK_DEV_ZONED=y
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_BLK_WBT=y
CONFIG_BLK_WBT_MQ=y
CONFIG_BLK_CGROUP_IOLATENCY=y
CONFIG_BLK_CGROUP_FC_APPID=y
CONFIG_BLK_CGROUP_IOCOST=y
CONFIG_BLK_CGROUP_IOPRIO=y
CONFIG_BLK_DEBUG_FS=y
CONFIG_BLK_SED_OPAL=y
CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_CUMANA=y
CONFIG_ACORN_PARTITION_EESOX=y
CONFIG_ACORN_PARTITION_ICS=y
CONFIG_ACORN_PARTITION_ADFS=y
CONFIG_ACORN_PARTITION_POWERTEC=y
CONFIG_ACORN_PARTITION_RISCIX=y
CONFIG_AIX_PARTITION=y
CONFIG_OSF_PARTITION=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_LDM_PARTITION=y
CONFIG_LDM_DEBUG=y
CONFIG_SGI_PARTITION=y
CONFIG_ULTRIX_PARTITION=y
CONFIG_SUN_PARTITION=y
CONFIG_KARMA_PARTITION=y
CONFIG_EFI_PARTITION=y
CONFIG_SYSV68_PARTITION=y
CONFIG_CMDLINE_PARTITION=y
CONFIG_OF_PARTITION=y
# end of Partition Types
CONFIG_BLK_PM=y
CONFIG_BLOCK_HOLDER_DEPRECATED=y
CONFIG_BLK_MQ_STACKING=y
#
# IO Schedulers
#
CONFIG_MQ_IOSCHED_DEADLINE=m
CONFIG_MQ_IOSCHED_KYBER=m
CONFIG_IOSCHED_BFQ=m
CONFIG_BFQ_GROUP_IOSCHED=y
CONFIG_BFQ_CGROUP_DEBUG=y
# end of IO Schedulers
CONFIG_PREEMPT_NOTIFIERS=y
CONFIG_PADATA=y
CONFIG_ASN1=y
CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y
CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y
CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y
CONFIG_FREEZER=y
#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
CONFIG_ELFCORE=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_BINFMT_SCRIPT=m
CONFIG_BINFMT_MISC=m
CONFIG_COREDUMP=y
# end of Executable file formats
#
# Memory Management options
#
CONFIG_SWAP=y
CONFIG_ZSWAP=y
CONFIG_ZSWAP_DEFAULT_ON=y
CONFIG_ZSWAP_SHRINKER_DEFAULT_ON=y
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set
CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO=y
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set
CONFIG_ZSWAP_COMPRESSOR_DEFAULT="lzo"
CONFIG_ZSMALLOC=y
#
# Zsmalloc allocator options
#
#
# Zsmalloc is a common backend allocator for zswap & zram
#
CONFIG_ZSMALLOC_STAT=y
CONFIG_ZSMALLOC_CHAIN_SIZE=8
# end of Zsmalloc allocator options
#
# Slab allocator options
#
CONFIG_SLUB=y
CONFIG_KVFREE_RCU_BATCHED=y
CONFIG_SLAB_MERGE_DEFAULT=y
CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_SLAB_FREELIST_HARDENED=y
CONFIG_SLAB_BUCKETS=y
CONFIG_SLUB_STATS=y
CONFIG_RANDOM_KMALLOC_CACHES=y
# end of Slab allocator options
CONFIG_SHUFFLE_PAGE_ALLOCATOR=y
CONFIG_COMPAT_BRK=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_HAVE_GUP_FAST=y
CONFIG_MEMORY_ISOLATION=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
CONFIG_SPLIT_PTE_PTLOCKS=y
CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
CONFIG_SPLIT_PMD_PTLOCKS=y
CONFIG_BALLOON=y
CONFIG_BALLOON_MIGRATION=y
CONFIG_COMPACTION=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
CONFIG_PAGE_REPORTING=y
CONFIG_MIGRATION=y
CONFIG_CONTIG_ALLOC=y
CONFIG_PCP_BATCH_SCALE_MAX=5
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_MMU_NOTIFIER=y
CONFIG_KSM=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
CONFIG_MEMORY_FAILURE=y
CONFIG_HWPOISON_INJECT=m
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_PERSISTENT_HUGE_ZERO_FOLIO=y
CONFIG_MM_ID=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set
# CONFIG_TRANSPARENT_HUGEPAGE_NEVER is not set
CONFIG_TRANSPARENT_HUGEPAGE_SHMEM_HUGE_NEVER=y
# CONFIG_TRANSPARENT_HUGEPAGE_SHMEM_HUGE_ALWAYS is not set
# CONFIG_TRANSPARENT_HUGEPAGE_SHMEM_HUGE_WITHIN_SIZE is not set
# CONFIG_TRANSPARENT_HUGEPAGE_SHMEM_HUGE_ADVISE is not set
CONFIG_TRANSPARENT_HUGEPAGE_TMPFS_HUGE_NEVER=y
# CONFIG_TRANSPARENT_HUGEPAGE_TMPFS_HUGE_ALWAYS is not set
# CONFIG_TRANSPARENT_HUGEPAGE_TMPFS_HUGE_WITHIN_SIZE is not set
# CONFIG_TRANSPARENT_HUGEPAGE_TMPFS_HUGE_ADVISE is not set
CONFIG_READ_ONLY_THP_FOR_FS=y
CONFIG_NO_PAGE_MAPCOUNT=y
CONFIG_PGTABLE_HAS_HUGE_LEAVES=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_CMA=y
CONFIG_CMA_DEBUGFS=y
CONFIG_CMA_SYSFS=y
CONFIG_CMA_AREAS=8
CONFIG_PAGE_BLOCK_MAX_ORDER=10
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_PAGE_IDLE_FLAG=y
CONFIG_IDLE_PAGE_TRACKING=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y
CONFIG_ARCH_HAS_ZONE_DMA_SET=y
CONFIG_ZONE_DMA=y
CONFIG_HMM_MIRROR=y
CONFIG_GET_FREE_REGION=y
CONFIG_VMAP_PFN=y
CONFIG_ARCH_USES_PG_ARCH_2=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PERCPU_STATS=y
CONFIG_GUP_TEST=y
CONFIG_GUP_GET_PXX_LOW_HIGH=y
CONFIG_DMAPOOL_TEST=m
CONFIG_ARCH_HAS_PTE_SPECIAL=y
CONFIG_MAPPING_DIRTY_HELPERS=y
CONFIG_KMAP_LOCAL=y
CONFIG_MEMFD_CREATE=y
CONFIG_SECRETMEM=y
CONFIG_ANON_VMA_NAME=y
CONFIG_USERFAULTFD=y
CONFIG_LRU_GEN=y
CONFIG_LRU_GEN_ENABLED=y
CONFIG_LRU_GEN_STATS=y
CONFIG_LRU_GEN_WALKS_MMU=y
CONFIG_LOCK_MM_AND_FIND_VMA=y
CONFIG_EXECMEM=y
CONFIG_PT_RECLAIM=y
CONFIG_FIND_NORMAL_PAGE=y
#
# Data Access Monitoring
#
CONFIG_DAMON=y
CONFIG_DAMON_VADDR=y
CONFIG_DAMON_PADDR=y
CONFIG_DAMON_SYSFS=y
CONFIG_DAMON_RECLAIM=y
CONFIG_DAMON_LRU_SORT=y
CONFIG_DAMON_STAT=y
CONFIG_DAMON_STAT_ENABLED_DEFAULT=y
# end of Data Access Monitoring
# end of Memory Management options
CONFIG_NET=y
CONFIG_NET_INGRESS=y
CONFIG_NET_EGRESS=y
CONFIG_NET_XGRESS=y
CONFIG_NET_REDIRECT=y
CONFIG_SKB_DECRYPTED=y
CONFIG_SKB_EXTENSIONS=y
CONFIG_NET_DEVMEM=y
CONFIG_NET_SHAPER=y
CONFIG_NET_CRC32C=y
#
# Networking options
#
CONFIG_PACKET=m
CONFIG_PACKET_DIAG=m
CONFIG_INET_PSP=y
CONFIG_UNIX=y
CONFIG_AF_UNIX_OOB=y
CONFIG_UNIX_DIAG=m
CONFIG_TLS=m
CONFIG_TLS_DEVICE=y
CONFIG_TLS_TOE=y
CONFIG_XFRM=y
CONFIG_XFRM_OFFLOAD=y
CONFIG_XFRM_ALGO=m
CONFIG_XFRM_USER=m
CONFIG_XFRM_INTERFACE=m
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XFRM_STATISTICS=y
CONFIG_XFRM_AH=m
CONFIG_XFRM_ESP=m
CONFIG_XFRM_IPCOMP=m
CONFIG_NET_KEY=m
CONFIG_NET_KEY_MIGRATE=y
CONFIG_XFRM_IPTFS=m
CONFIG_XFRM_ESPINTCP=y
CONFIG_SMC=m
CONFIG_SMC_DIAG=m
CONFIG_SMC_HS_CTRL_BPF=y
CONFIG_DIBS=m
CONFIG_DIBS_LO=y
CONFIG_XDP_SOCKETS=y
CONFIG_XDP_SOCKETS_DIAG=m
CONFIG_NET_HANDSHAKE=y
CONFIG_NET_HANDSHAKE_KUNIT_TEST=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_FIB_TRIE_STATS=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_ROUTE_CLASSID=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE_DEMUX=m
CONFIG_NET_IP_TUNNEL=m
CONFIG_NET_IPGRE=m
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE_COMMON=y
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
CONFIG_NET_IPVTI=m
CONFIG_NET_UDP_TUNNEL=m
CONFIG_NET_FOU=m
CONFIG_NET_FOU_IP_TUNNELS=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_ESP_OFFLOAD=m
CONFIG_INET_ESPINTCP=y
CONFIG_INET_IPCOMP=m
CONFIG_INET_TABLE_PERTURB_ORDER=16
CONFIG_INET_XFRM_TUNNEL=m
CONFIG_INET_TUNNEL=m
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
CONFIG_INET_UDP_DIAG=m
CONFIG_INET_RAW_DIAG=m
CONFIG_INET_DIAG_DESTROY=y
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_BIC=m
CONFIG_TCP_CONG_CUBIC=m
CONFIG_TCP_CONG_WESTWOOD=m
CONFIG_TCP_CONG_HTCP=m
CONFIG_TCP_CONG_HSTCP=m
CONFIG_TCP_CONG_HYBLA=m
CONFIG_TCP_CONG_VEGAS=m
CONFIG_TCP_CONG_NV=m
CONFIG_TCP_CONG_SCALABLE=m
CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_TCP_CONG_DCTCP=m
CONFIG_TCP_CONG_CDG=m
CONFIG_TCP_CONG_BBR=m
CONFIG_DEFAULT_RENO=y
CONFIG_DEFAULT_TCP_CONG="reno"
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=m
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_ESP_OFFLOAD=m
CONFIG_INET6_ESPINTCP=y
CONFIG_INET6_IPCOMP=m
CONFIG_IPV6_MIP6=m
CONFIG_IPV6_ILA=m
CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
CONFIG_IPV6_VTI=m
CONFIG_IPV6_SIT=m
CONFIG_IPV6_SIT_6RD=y
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=m
CONFIG_IPV6_GRE=m
CONFIG_IPV6_FOU=m
CONFIG_IPV6_FOU_TUNNEL=m
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MROUTE=y
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
CONFIG_IPV6_PIMSM_V2=y
CONFIG_IPV6_SEG6_LWTUNNEL=y
CONFIG_IPV6_SEG6_HMAC=y
CONFIG_IPV6_RPL_LWTUNNEL=y
CONFIG_IPV6_IOAM6_LWTUNNEL=y
CONFIG_NETLABEL=y
CONFIG_MPTCP=y
CONFIG_INET_MPTCP_DIAG=m
CONFIG_MPTCP_KUNIT_TEST=m
CONFIG_NETWORK_SECMARK=y
CONFIG_NET_PTP_CLASSIFY=y
CONFIG_NETWORK_PHY_TIMESTAMPING=y
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=m
#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_INGRESS=y
CONFIG_NETFILTER_EGRESS=y
CONFIG_NETFILTER_SKIP_EGRESS=y
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_FAMILY_BRIDGE=y
CONFIG_NETFILTER_FAMILY_ARP=y
CONFIG_NETFILTER_BPF_LINK=y
CONFIG_NETFILTER_NETLINK_HOOK=m
CONFIG_NETFILTER_NETLINK_ACCT=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NETFILTER_NETLINK_OSF=m
CONFIG_NF_CONNTRACK=m
CONFIG_NF_LOG_SYSLOG=m
CONFIG_NETFILTER_CONNCOUNT=m
CONFIG_NF_CONNTRACK_MARK=y
CONFIG_NF_CONNTRACK_SECMARK=y
CONFIG_NF_CONNTRACK_ZONES=y
CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_TIMEOUT=y
CONFIG_NF_CONNTRACK_TIMESTAMP=y
CONFIG_NF_CONNTRACK_LABELS=y
CONFIG_NF_CONNTRACK_OVS=y
CONFIG_NF_CT_PROTO_GRE=y
CONFIG_NF_CT_PROTO_SCTP=y
CONFIG_NF_CT_PROTO_UDPLITE=y
CONFIG_NF_CONNTRACK_AMANDA=m
CONFIG_NF_CONNTRACK_FTP=m
CONFIG_NF_CONNTRACK_H323=m
CONFIG_NF_CONNTRACK_IRC=m
CONFIG_NF_CONNTRACK_BROADCAST=m
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
CONFIG_NF_CONNTRACK_SNMP=m
CONFIG_NF_CONNTRACK_PPTP=m
CONFIG_NF_CONNTRACK_SANE=m
CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m
CONFIG_NF_CT_NETLINK_TIMEOUT=m
CONFIG_NF_CT_NETLINK_HELPER=m
CONFIG_NETFILTER_NETLINK_GLUE_CT=y
CONFIG_NF_NAT=m
CONFIG_NF_NAT_AMANDA=m
CONFIG_NF_NAT_FTP=m
CONFIG_NF_NAT_IRC=m
CONFIG_NF_NAT_SIP=m
CONFIG_NF_NAT_TFTP=m
CONFIG_NF_NAT_REDIRECT=y
CONFIG_NF_NAT_MASQUERADE=y
CONFIG_NF_NAT_OVS=y
CONFIG_NETFILTER_SYNPROXY=m
CONFIG_NF_TABLES=m
CONFIG_NF_TABLES_INET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_EXTHDR_DCCP=y
CONFIG_NFT_FLOW_OFFLOAD=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_MASQ=m
CONFIG_NFT_REDIR=m
CONFIG_NFT_NAT=m
CONFIG_NFT_TUNNEL=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_QUOTA=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_REJECT_INET=m
CONFIG_NFT_COMPAT=m
CONFIG_NFT_HASH=m
CONFIG_NFT_FIB=m
CONFIG_NFT_FIB_INET=m
CONFIG_NFT_XFRM=m
CONFIG_NFT_SOCKET=m
CONFIG_NFT_OSF=m
CONFIG_NFT_TPROXY=m
CONFIG_NFT_SYNPROXY=m
CONFIG_NF_DUP_NETDEV=m
CONFIG_NFT_DUP_NETDEV=m
CONFIG_NFT_FWD_NETDEV=m
CONFIG_NFT_FIB_NETDEV=m
CONFIG_NFT_REJECT_NETDEV=m
CONFIG_NF_FLOW_TABLE_INET=m
CONFIG_NF_FLOW_TABLE=m
CONFIG_NF_FLOW_TABLE_PROCFS=y
CONFIG_NETFILTER_XTABLES=m
CONFIG_NETFILTER_XTABLES_LEGACY=y
#
# Xtables combined modules
#
CONFIG_NETFILTER_XT_MARK=m
CONFIG_NETFILTER_XT_CONNMARK=m
CONFIG_NETFILTER_XT_SET=m
#
# Xtables targets
#
CONFIG_NETFILTER_XT_TARGET_AUDIT=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
CONFIG_NETFILTER_XT_TARGET_CT=m
CONFIG_NETFILTER_XT_TARGET_DSCP=m
CONFIG_NETFILTER_XT_TARGET_HL=m
CONFIG_NETFILTER_XT_TARGET_HMARK=m
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
CONFIG_NETFILTER_XT_TARGET_LED=m
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
CONFIG_NETFILTER_XT_NAT=m
CONFIG_NETFILTER_XT_TARGET_NETMAP=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
CONFIG_NETFILTER_XT_TARGET_RATEEST=m
CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m
CONFIG_NETFILTER_XT_TARGET_TEE=m
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_TRACE=m
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
#
# Xtables matches
#
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
CONFIG_NETFILTER_XT_MATCH_BPF=m
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
CONFIG_NETFILTER_XT_MATCH_CPU=m
CONFIG_NETFILTER_XT_MATCH_DCCP=m
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
CONFIG_NETFILTER_XT_MATCH_DSCP=m
CONFIG_NETFILTER_XT_MATCH_ECN=m
CONFIG_NETFILTER_XT_MATCH_ESP=m
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
CONFIG_NETFILTER_XT_MATCH_HELPER=m
CONFIG_NETFILTER_XT_MATCH_HL=m
CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
CONFIG_NETFILTER_XT_MATCH_IPVS=m
CONFIG_NETFILTER_XT_MATCH_L2TP=m
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
CONFIG_NETFILTER_XT_MATCH_MAC=m
CONFIG_NETFILTER_XT_MATCH_MARK=m
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
CONFIG_NETFILTER_XT_MATCH_NFACCT=m
CONFIG_NETFILTER_XT_MATCH_OSF=m
CONFIG_NETFILTER_XT_MATCH_OWNER=m
CONFIG_NETFILTER_XT_MATCH_POLICY=m
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
CONFIG_NETFILTER_XT_MATCH_QUOTA=m
CONFIG_NETFILTER_XT_MATCH_RATEEST=m
CONFIG_NETFILTER_XT_MATCH_REALM=m
CONFIG_NETFILTER_XT_MATCH_RECENT=m
CONFIG_NETFILTER_XT_MATCH_SCTP=m
CONFIG_NETFILTER_XT_MATCH_SOCKET=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
CONFIG_NETFILTER_XT_MATCH_STRING=m
CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
CONFIG_NETFILTER_XT_MATCH_TIME=m
CONFIG_NETFILTER_XT_MATCH_U32=m
# end of Core Netfilter Configuration
CONFIG_IP_SET=m
CONFIG_IP_SET_MAX=256
CONFIG_IP_SET_BITMAP_IP=m
CONFIG_IP_SET_BITMAP_IPMAC=m
CONFIG_IP_SET_BITMAP_PORT=m
CONFIG_IP_SET_HASH_IP=m
CONFIG_IP_SET_HASH_IPMARK=m
CONFIG_IP_SET_HASH_IPPORT=m
CONFIG_IP_SET_HASH_IPPORTIP=m
CONFIG_IP_SET_HASH_IPPORTNET=m
CONFIG_IP_SET_HASH_IPMAC=m
CONFIG_IP_SET_HASH_MAC=m
CONFIG_IP_SET_HASH_NETPORTNET=m
CONFIG_IP_SET_HASH_NET=m
CONFIG_IP_SET_HASH_NETNET=m
CONFIG_IP_SET_HASH_NETPORT=m
CONFIG_IP_SET_HASH_NETIFACE=m
CONFIG_IP_SET_LIST_SET=m
CONFIG_IP_VS=m
CONFIG_IP_VS_IPV6=y
CONFIG_IP_VS_DEBUG=y
CONFIG_IP_VS_TAB_BITS=12
#
# IPVS transport protocol load balancing support
#
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y
#
# IPVS scheduler
#
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_FO=m
CONFIG_IP_VS_OVF=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_MH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_TWOS=m
#
# IPVS SH scheduler
#
CONFIG_IP_VS_SH_TAB_BITS=8
#
# IPVS MH scheduler
#
CONFIG_IP_VS_MH_TAB_INDEX=12
#
# IPVS application helper
#
CONFIG_IP_VS_FTP=m
CONFIG_IP_VS_NFCT=y
CONFIG_IP_VS_PE_SIP=m
#
# IP: Netfilter Configuration
#
CONFIG_NF_DEFRAG_IPV4=m
CONFIG_IP_NF_IPTABLES_LEGACY=m
CONFIG_NF_SOCKET_IPV4=m
CONFIG_NF_TPROXY_IPV4=m
CONFIG_NF_TABLES_IPV4=y
CONFIG_NFT_REJECT_IPV4=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
CONFIG_NF_DUP_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_NF_REJECT_IPV4=m
CONFIG_NF_NAT_SNMP_BASIC=m
CONFIG_NF_NAT_PPTP=m
CONFIG_NF_NAT_H323=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_RPFILTER=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_SYNPROXY=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_SECURITY=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_NFT_COMPAT_ARP=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
# end of IP: Netfilter Configuration
#
# IPv6: Netfilter Configuration
#
CONFIG_IP6_NF_IPTABLES_LEGACY=m
CONFIG_NF_SOCKET_IPV6=m
CONFIG_NF_TPROXY_IPV6=m
CONFIG_NF_TABLES_IPV6=y
CONFIG_NFT_REJECT_IPV6=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
CONFIG_NF_DUP_IPV6=m
CONFIG_NF_REJECT_IPV6=m
CONFIG_NF_LOG_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_FRAG=m
CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_MH=m
CONFIG_IP6_NF_MATCH_RPFILTER=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_MATCH_SRH=m
CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_TARGET_SYNPROXY=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_RAW=m
CONFIG_IP6_NF_SECURITY=m
CONFIG_IP6_NF_NAT=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_IP6_NF_TARGET_NPT=m
# end of IPv6: Netfilter Configuration
CONFIG_NF_DEFRAG_IPV6=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NFT_BRIDGE_META=m
CONFIG_NFT_BRIDGE_REJECT=m
CONFIG_NF_CONNTRACK_BRIDGE=m
CONFIG_BRIDGE_NF_EBTABLES_LEGACY=m
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_T_FILTER=m
CONFIG_BRIDGE_EBT_T_NAT=m
CONFIG_BRIDGE_EBT_802_3=m
CONFIG_BRIDGE_EBT_AMONG=m
CONFIG_BRIDGE_EBT_ARP=m
CONFIG_BRIDGE_EBT_IP=m
CONFIG_BRIDGE_EBT_IP6=m
CONFIG_BRIDGE_EBT_LIMIT=m
CONFIG_BRIDGE_EBT_MARK=m
CONFIG_BRIDGE_EBT_PKTTYPE=m
CONFIG_BRIDGE_EBT_STP=m
CONFIG_BRIDGE_EBT_VLAN=m
CONFIG_BRIDGE_EBT_ARPREPLY=m
CONFIG_BRIDGE_EBT_DNAT=m
CONFIG_BRIDGE_EBT_MARK_T=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_NFLOG=m
CONFIG_IP_SCTP=m
CONFIG_SCTP_DBG_OBJCNT=y
CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA256=y
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
CONFIG_INET_SCTP_DIAG=m
CONFIG_RDS=m
CONFIG_RDS_RDMA=m
CONFIG_RDS_TCP=m
CONFIG_RDS_DEBUG=y
CONFIG_GCOV_PROFILE_RDS=y
CONFIG_TIPC=m
CONFIG_TIPC_MEDIA_IB=y
CONFIG_TIPC_MEDIA_UDP=y
CONFIG_TIPC_CRYPTO=y
CONFIG_TIPC_DIAG=m
CONFIG_ATM=m
CONFIG_ATM_CLIP=m
CONFIG_ATM_CLIP_NO_ICMP=y
CONFIG_ATM_LANE=m
CONFIG_ATM_MPOA=m
CONFIG_ATM_BR2684=m
CONFIG_ATM_BR2684_IPFILTER=y
CONFIG_L2TP=m
CONFIG_L2TP_DEBUGFS=m
CONFIG_L2TP_V3=y
CONFIG_L2TP_IP=m
CONFIG_L2TP_ETH=m
CONFIG_STP=m
CONFIG_GARP=m
CONFIG_MRP=m
CONFIG_BRIDGE=m
CONFIG_BRIDGE_IGMP_SNOOPING=y
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_BRIDGE_MRP=y
CONFIG_BRIDGE_CFM=y
CONFIG_NET_DSA=m
CONFIG_NET_DSA_TAG_NONE=m
CONFIG_NET_DSA_TAG_AR9331=m
CONFIG_NET_DSA_TAG_BRCM_COMMON=m
CONFIG_NET_DSA_TAG_BRCM=m
CONFIG_NET_DSA_TAG_BRCM_LEGACY=m
CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS=m
CONFIG_NET_DSA_TAG_BRCM_PREPEND=m
CONFIG_NET_DSA_TAG_HELLCREEK=m
CONFIG_NET_DSA_TAG_GSWIP=m
CONFIG_NET_DSA_TAG_DSA_COMMON=m
CONFIG_NET_DSA_TAG_DSA=m
CONFIG_NET_DSA_TAG_EDSA=m
CONFIG_NET_DSA_TAG_MTK=m
CONFIG_NET_DSA_TAG_MXL_862XX=m
CONFIG_NET_DSA_TAG_MXL_GSW1XX=m
CONFIG_NET_DSA_TAG_KSZ=m
CONFIG_NET_DSA_TAG_OCELOT=m
CONFIG_NET_DSA_TAG_OCELOT_8021Q=m
CONFIG_NET_DSA_TAG_QCA=m
CONFIG_NET_DSA_TAG_RTL4_A=m
CONFIG_NET_DSA_TAG_RTL8_4=m
CONFIG_NET_DSA_TAG_RZN1_A5PSW=m
CONFIG_NET_DSA_TAG_LAN9303=m
CONFIG_NET_DSA_TAG_SJA1105=m
CONFIG_NET_DSA_TAG_TRAILER=m
CONFIG_NET_DSA_TAG_VSC73XX_8021Q=m
CONFIG_NET_DSA_TAG_XRS700X=m
CONFIG_NET_DSA_TAG_YT921X=m
CONFIG_VLAN_8021Q=m
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
CONFIG_LLC=m
CONFIG_LLC2=m
CONFIG_ATALK=m
CONFIG_X25=m
CONFIG_LAPB=m
CONFIG_PHONET=m
CONFIG_6LOWPAN=m
CONFIG_6LOWPAN_DEBUGFS=y
CONFIG_6LOWPAN_NHC=m
CONFIG_6LOWPAN_NHC_DEST=m
CONFIG_6LOWPAN_NHC_FRAGMENT=m
CONFIG_6LOWPAN_NHC_HOP=m
CONFIG_6LOWPAN_NHC_IPV6=m
CONFIG_6LOWPAN_NHC_MOBILITY=m
CONFIG_6LOWPAN_NHC_ROUTING=m
CONFIG_6LOWPAN_NHC_UDP=m
CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
CONFIG_6LOWPAN_GHC_UDP=m
CONFIG_6LOWPAN_GHC_ICMPV6=m
CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_IEEE802154=m
CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y
CONFIG_IEEE802154_SOCKET=m
CONFIG_IEEE802154_6LOWPAN=m
CONFIG_MAC802154=m
CONFIG_NET_SCHED=y
#
# Queueing/Scheduling
#
CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_HFSC=m
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_MULTIQ=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFB=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_CBS=m
CONFIG_NET_SCH_ETF=m
CONFIG_NET_SCH_MQPRIO_LIB=m
CONFIG_NET_SCH_TAPRIO=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_NETEM=m
CONFIG_NET_SCH_DRR=m
CONFIG_NET_SCH_MQPRIO=m
CONFIG_NET_SCH_SKBPRIO=m
CONFIG_NET_SCH_CHOKE=m
CONFIG_NET_SCH_QFQ=m
CONFIG_NET_SCH_CODEL=m
CONFIG_NET_SCH_FQ_CODEL=m
CONFIG_NET_SCH_CAKE=m
CONFIG_NET_SCH_FQ=m
CONFIG_NET_SCH_HHF=m
CONFIG_NET_SCH_PIE=m
CONFIG_NET_SCH_FQ_PIE=m
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_SCH_PLUG=m
CONFIG_NET_SCH_ETS=m
CONFIG_NET_SCH_DUALPI2=m
CONFIG_NET_SCH_DEFAULT=y
# CONFIG_DEFAULT_FQ is not set
# CONFIG_DEFAULT_CODEL is not set
# CONFIG_DEFAULT_FQ_CODEL is not set
# CONFIG_DEFAULT_FQ_PIE is not set
# CONFIG_DEFAULT_SFQ is not set
CONFIG_DEFAULT_PFIFO_FAST=y
CONFIG_DEFAULT_NET_SCH="pfifo_fast"
#
# Classification
#
CONFIG_NET_CLS=y
CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
CONFIG_CLS_U32_PERF=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_FLOW=m
CONFIG_NET_CLS_CGROUP=m
CONFIG_NET_CLS_BPF=m
CONFIG_NET_CLS_FLOWER=m
CONFIG_NET_CLS_MATCHALL=m
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_STACK=32
CONFIG_NET_EMATCH_CMP=m
CONFIG_NET_EMATCH_NBYTE=m
CONFIG_NET_EMATCH_U32=m
CONFIG_NET_EMATCH_META=m
CONFIG_NET_EMATCH_TEXT=m
CONFIG_NET_EMATCH_CANID=m
CONFIG_NET_EMATCH_IPSET=m
CONFIG_NET_EMATCH_IPT=m
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m
CONFIG_GACT_PROB=y
CONFIG_NET_ACT_MIRRED=m
CONFIG_NET_ACT_SAMPLE=m
CONFIG_NET_ACT_NAT=m
CONFIG_NET_ACT_PEDIT=m
CONFIG_NET_ACT_SIMP=m
CONFIG_NET_ACT_SKBEDIT=m
CONFIG_NET_ACT_CSUM=m
CONFIG_NET_ACT_MPLS=m
CONFIG_NET_ACT_VLAN=m
CONFIG_NET_ACT_BPF=m
CONFIG_NET_ACT_CONNMARK=m
CONFIG_NET_ACT_CTINFO=m
CONFIG_NET_ACT_SKBMOD=m
CONFIG_NET_ACT_IFE=m
CONFIG_NET_ACT_TUNNEL_KEY=m
CONFIG_NET_ACT_CT=m
CONFIG_NET_ACT_GATE=m
CONFIG_NET_IFE_SKBMARK=m
CONFIG_NET_IFE_SKBPRIO=m
CONFIG_NET_IFE_SKBTCINDEX=m
CONFIG_NET_TC_SKB_EXT=y
CONFIG_NET_SCH_FIFO=y
CONFIG_DCB=y
CONFIG_DNS_RESOLVER=m
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_BATMAN_V=y
CONFIG_BATMAN_ADV_BLA=y
CONFIG_BATMAN_ADV_DAT=y
CONFIG_BATMAN_ADV_MCAST=y
CONFIG_BATMAN_ADV_DEBUG=y
CONFIG_BATMAN_ADV_TRACING=y
CONFIG_OPENVSWITCH=m
CONFIG_OPENVSWITCH_GRE=m
CONFIG_OPENVSWITCH_VXLAN=m
CONFIG_OPENVSWITCH_GENEVE=m
CONFIG_VSOCKETS=m
CONFIG_VSOCKETS_DIAG=m
CONFIG_VSOCKETS_LOOPBACK=m
CONFIG_VMWARE_VMCI_VSOCKETS=m
CONFIG_VIRTIO_VSOCKETS=m
CONFIG_VIRTIO_VSOCKETS_COMMON=m
CONFIG_HYPERV_VSOCKETS=m
CONFIG_NETLINK_DIAG=m
CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
CONFIG_NET_NSH=m
CONFIG_HSR=m
CONFIG_PRP_DUP_DISCARD_KUNIT_TEST=m
CONFIG_NET_SWITCHDEV=y
CONFIG_NET_L3_MASTER_DEV=y
CONFIG_QRTR=m
CONFIG_QRTR_SMD=m
CONFIG_QRTR_TUN=m
CONFIG_QRTR_MHI=m
CONFIG_NET_NCSI=y
CONFIG_NCSI_OEM_CMD_GET_MAC=y
CONFIG_NCSI_OEM_CMD_KEEP_PHY=y
CONFIG_PCPU_DEV_REFCNT=y
CONFIG_MAX_SKB_FRAGS=17
CONFIG_RPS=y
CONFIG_RFS_ACCEL=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_XPS=y
CONFIG_HWBM=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_BQL=y
CONFIG_BPF_STREAM_PARSER=y
CONFIG_NET_FLOW_LIMIT=y
#
# Network testing
#
CONFIG_NET_PKTGEN=m
CONFIG_NET_DROP_MONITOR=m
# end of Network testing
# end of Networking options
CONFIG_HAMRADIO=y
#
# Packet Radio protocols
#
CONFIG_AX25=m
CONFIG_AX25_DAMA_SLAVE=y
CONFIG_NETROM=m
CONFIG_ROSE=m
#
# AX.25 network device drivers
#
CONFIG_MKISS=m
CONFIG_6PACK=m
CONFIG_BPQETHER=m
CONFIG_SCC=m
CONFIG_SCC_DELAY=y
CONFIG_SCC_TRXECHO=y
CONFIG_BAYCOM_SER_FDX=m
CONFIG_BAYCOM_SER_HDX=m
CONFIG_BAYCOM_PAR=m
CONFIG_BAYCOM_EPP=m
CONFIG_YAM=m
# end of AX.25 network device drivers
CONFIG_CAN=m
CONFIG_CAN_RAW=m
CONFIG_CAN_BCM=m
CONFIG_CAN_GW=m
CONFIG_CAN_J1939=m
CONFIG_CAN_ISOTP=m
CONFIG_BT=m
CONFIG_BT_BREDR=y
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=m
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=m
CONFIG_BT_LE=y
CONFIG_BT_LE_L2CAP_ECRED=y
CONFIG_BT_6LOWPAN=m
CONFIG_BT_LEDS=y
CONFIG_BT_MSFTEXT=y
CONFIG_BT_AOSPEXT=y
CONFIG_BT_DEBUGFS=y
CONFIG_BT_SELFTEST=y
CONFIG_BT_SELFTEST_ECDH=y
CONFIG_BT_SELFTEST_SMP=y
#
# Bluetooth device drivers
#
CONFIG_BT_INTEL=m
CONFIG_BT_BCM=m
CONFIG_BT_RTL=m
CONFIG_BT_QCA=m
CONFIG_BT_MTK=m
CONFIG_BT_HCIBTUSB=m
CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y
CONFIG_BT_HCIBTUSB_POLL_SYNC=y
CONFIG_BT_HCIBTUSB_BCM=y
CONFIG_BT_HCIBTUSB_MTK=y
CONFIG_BT_HCIBTUSB_RTL=y
CONFIG_BT_HCIBTSDIO=m
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_SERDEV=y
CONFIG_BT_HCIUART_H4=y
CONFIG_BT_HCIUART_NOKIA=m
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIUART_ATH3K=y
CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIUART_3WIRE=y
CONFIG_BT_HCIUART_INTEL=y
CONFIG_BT_HCIUART_RTL=y
CONFIG_BT_HCIUART_QCA=y
CONFIG_BT_HCIUART_AG6XX=y
CONFIG_BT_HCIUART_MRVL=y
CONFIG_BT_HCIUART_AML=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBCM4377=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
CONFIG_BT_HCIDTL1=m
CONFIG_BT_HCIBT3C=m
CONFIG_BT_HCIBLUECARD=m
CONFIG_BT_HCIVHCI=m
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
CONFIG_BT_ATH3K=m
CONFIG_BT_MTKSDIO=m
CONFIG_BT_MTKUART=m
CONFIG_BT_QCOMSMD=m
CONFIG_BT_HCIRSI=m
CONFIG_BT_VIRTIO=m
CONFIG_BT_NXPUART=m
CONFIG_BT_INTEL_PCIE=m
# end of Bluetooth device drivers
CONFIG_AF_RXRPC=m
CONFIG_AF_RXRPC_IPV6=y
CONFIG_AF_RXRPC_INJECT_LOSS=y
CONFIG_AF_RXRPC_INJECT_RX_DELAY=y
CONFIG_AF_RXRPC_DEBUG=y
CONFIG_RXKAD=y
CONFIG_RXGK=y
CONFIG_RXPERF=m
CONFIG_AF_KCM=m
CONFIG_STREAM_PARSER=y
CONFIG_MCTP=y
CONFIG_MCTP_FLOWS=y
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
CONFIG_WIRELESS_EXT=y
CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y
CONFIG_WEXT_PRIV=y
CONFIG_CFG80211=m
CONFIG_NL80211_TESTMODE=y
CONFIG_CFG80211_DEVELOPER_WARNINGS=y
CONFIG_CFG80211_CERTIFICATION_ONUS=y
CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y
CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y
CONFIG_CFG80211_EXTRA_REGDB_KEYDIR=""
CONFIG_CFG80211_REG_CELLULAR_HINTS=y
CONFIG_CFG80211_REG_RELAX_NO_IR=y
CONFIG_CFG80211_DEFAULT_PS=y
CONFIG_CFG80211_DEBUGFS=y
CONFIG_CFG80211_CRDA_SUPPORT=y
CONFIG_CFG80211_WEXT=y
CONFIG_CFG80211_KUNIT_TEST=m
CONFIG_MAC80211=m
CONFIG_MAC80211_HAS_RC=y
CONFIG_MAC80211_RC_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
CONFIG_MAC80211_KUNIT_TEST=m
CONFIG_MAC80211_MESH=y
CONFIG_MAC80211_LEDS=y
CONFIG_MAC80211_DEBUGFS=y
CONFIG_MAC80211_MESSAGE_TRACING=y
CONFIG_MAC80211_DEBUG_MENU=y
CONFIG_MAC80211_NOINLINE=y
CONFIG_MAC80211_VERBOSE_DEBUG=y
CONFIG_MAC80211_MLME_DEBUG=y
CONFIG_MAC80211_STA_DEBUG=y
CONFIG_MAC80211_HT_DEBUG=y
CONFIG_MAC80211_OCB_DEBUG=y
CONFIG_MAC80211_IBSS_DEBUG=y
CONFIG_MAC80211_PS_DEBUG=y
CONFIG_MAC80211_MPL_DEBUG=y
CONFIG_MAC80211_MPATH_DEBUG=y
CONFIG_MAC80211_MHWMP_DEBUG=y
CONFIG_MAC80211_MESH_SYNC_DEBUG=y
CONFIG_MAC80211_MESH_CSA_DEBUG=y
CONFIG_MAC80211_MESH_PS_DEBUG=y
CONFIG_MAC80211_TDLS_DEBUG=y
CONFIG_MAC80211_DEBUG_COUNTERS=y
CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
CONFIG_RFKILL=m
CONFIG_RFKILL_LEDS=y
CONFIG_RFKILL_INPUT=y
CONFIG_RFKILL_GPIO=m
CONFIG_NET_9P=m
CONFIG_NET_9P_FD=m
CONFIG_NET_9P_VIRTIO=m
CONFIG_NET_9P_XEN=m
CONFIG_NET_9P_USBG=m
CONFIG_NET_9P_RDMA=m
CONFIG_NET_9P_DEBUG=y
CONFIG_CAIF=m
CONFIG_CAIF_DEBUG=y
CONFIG_CAIF_NETDEV=m
CONFIG_CAIF_USB=m
CONFIG_CEPH_LIB=m
CONFIG_CEPH_LIB_PRETTYDEBUG=y
CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y
CONFIG_NFC=m
CONFIG_NFC_DIGITAL=m
CONFIG_NFC_NCI=m
CONFIG_NFC_NCI_SPI=m
CONFIG_NFC_NCI_UART=m
CONFIG_NFC_HCI=m
CONFIG_NFC_SHDLC=y
#
# Near Field Communication (NFC) devices
#
CONFIG_NFC_TRF7970A=m
CONFIG_NFC_MEI_PHY=m
CONFIG_NFC_SIM=m
CONFIG_NFC_PORT100=m
CONFIG_NFC_VIRTUAL_NCI=m
CONFIG_NFC_FDP=m
CONFIG_NFC_FDP_I2C=m
CONFIG_NFC_PN544=m
CONFIG_NFC_PN544_I2C=m
CONFIG_NFC_PN544_MEI=m
CONFIG_NFC_PN533=m
CONFIG_NFC_PN533_USB=m
CONFIG_NFC_PN533_I2C=m
CONFIG_NFC_PN532_UART=m
CONFIG_NFC_MICROREAD=m
CONFIG_NFC_MICROREAD_I2C=m
CONFIG_NFC_MICROREAD_MEI=m
CONFIG_NFC_MRVL=m
CONFIG_NFC_MRVL_USB=m
CONFIG_NFC_MRVL_UART=m
CONFIG_NFC_MRVL_I2C=m
CONFIG_NFC_MRVL_SPI=m
CONFIG_NFC_ST21NFCA=m
CONFIG_NFC_ST21NFCA_I2C=m
CONFIG_NFC_ST_NCI=m
CONFIG_NFC_ST_NCI_I2C=m
CONFIG_NFC_ST_NCI_SPI=m
CONFIG_NFC_NXP_NCI=m
CONFIG_NFC_NXP_NCI_I2C=m
CONFIG_NFC_S3FWRN5=m
CONFIG_NFC_S3FWRN5_I2C=m
CONFIG_NFC_S3FWRN82_UART=m
CONFIG_NFC_ST95HF=m
# end of Near Field Communication (NFC) devices
CONFIG_PSAMPLE=m
CONFIG_NET_IFE=m
CONFIG_LWTUNNEL=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_DST_CACHE=y
CONFIG_GRO_CELLS=y
CONFIG_SOCK_VALIDATE_XMIT=y
CONFIG_NET_IEEE8021Q_HELPERS=y
CONFIG_NET_SELFTESTS=m
CONFIG_NET_SOCK_MSG=y
CONFIG_NET_DEVLINK=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_POOL_STATS=y
CONFIG_FAILOVER=m
CONFIG_ETHTOOL_NETLINK=y
CONFIG_NETDEV_ADDR_LIST_TEST=m
CONFIG_NET_TEST=m
#
# Device Drivers
#
CONFIG_HAVE_EISA=y
CONFIG_EISA=y
CONFIG_EISA_VLB_PRIMING=y
CONFIG_EISA_PCI_EISA=y
CONFIG_EISA_VIRTUAL_ROOT=y
CONFIG_EISA_NAMES=y
CONFIG_HAVE_PCI=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCIEPORTBUS=y
CONFIG_HOTPLUG_PCI_PCIE=y
CONFIG_PCIEAER=y
CONFIG_PCIEAER_INJECT=m
CONFIG_PCIE_ECRC=y
CONFIG_PCIEASPM=y
CONFIG_PCIEASPM_DEFAULT=y
# CONFIG_PCIEASPM_POWERSAVE is not set
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
# CONFIG_PCIEASPM_PERFORMANCE is not set
CONFIG_PCIE_PME=y
CONFIG_PCIE_DPC=y
CONFIG_PCIE_PTM=y
CONFIG_PCIE_EDR=y
CONFIG_PCI_MSI=y
CONFIG_PCI_QUIRKS=y
CONFIG_PCI_DEBUG=y
CONFIG_PCI_REALLOC_ENABLE_AUTO=y
CONFIG_PCI_STUB=m
CONFIG_PCI_PF_STUB=m
CONFIG_PCI_ATS=y
CONFIG_PCI_IDE=y
CONFIG_PCI_TSM=y
CONFIG_PCI_DOE=y
CONFIG_PCI_ECAM=y
CONFIG_PCI_LOCKLESS_CONFIG=y
CONFIG_PCI_BRIDGE_EMUL=y
CONFIG_PCI_IOV=y
CONFIG_PCI_PRI=y
CONFIG_PCI_PASID=y
CONFIG_PCIE_TPH=y
CONFIG_PCI_LABEL=y
CONFIG_PCI_DYNAMIC_OF_NODES=y
# CONFIG_PCIE_BUS_TUNE_OFF is not set
CONFIG_PCIE_BUS_DEFAULT=y
# CONFIG_PCIE_BUS_SAFE is not set
# CONFIG_PCIE_BUS_PERFORMANCE is not set
# CONFIG_PCIE_BUS_PEER2PEER is not set
CONFIG_VGA_ARB=y
CONFIG_VGA_ARB_MAX_GPUS=16
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_COMPAQ=m
CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y
CONFIG_HOTPLUG_PCI_IBM=m
CONFIG_HOTPLUG_PCI_ACPI=y
CONFIG_HOTPLUG_PCI_ACPI_IBM=m
CONFIG_HOTPLUG_PCI_CPCI=y
CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m
CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m
CONFIG_HOTPLUG_PCI_OCTEONEP=y
CONFIG_HOTPLUG_PCI_SHPC=y
#
# PCI controller drivers
#
CONFIG_PCI_HOST_COMMON=y
CONFIG_PCI_AARDVARK=m
CONFIG_PCIE_ALTERA=m
CONFIG_PCIE_ALTERA_MSI=m
CONFIG_PCIE_APPLE_MSI_DOORBELL_ADDR=0xfffff000
CONFIG_PCIE_APPLE=m
CONFIG_PCI_VERSATILE=y
CONFIG_PCIE_ASPEED=y
CONFIG_PCIE_BRCMSTB=m
CONFIG_PCI_HOST_THUNDER_PEM=y
CONFIG_PCI_HOST_THUNDER_ECAM=y
CONFIG_PCI_FTPCI100=y
CONFIG_PCI_HOST_GENERIC=m
CONFIG_PCIE_HISI_ERR=y
CONFIG_PCI_IXP4XX=y
CONFIG_PCI_LOONGSON=y
CONFIG_PCIE_MEDIATEK=m
CONFIG_PCIE_MEDIATEK_GEN3=m
CONFIG_PCIE_MT7621=m
CONFIG_PCI_TEGRA=m
CONFIG_PCIE_RCAR_HOST=y
CONFIG_PCIE_RCAR_EP=y
CONFIG_PCI_RCAR_GEN2=y
CONFIG_PCIE_RENESAS_RZG3S_HOST=y
CONFIG_PCIE_ROCKCHIP=y
CONFIG_PCIE_ROCKCHIP_HOST=m
CONFIG_PCIE_ROCKCHIP_EP=y
CONFIG_PCI_V3_SEMI=y
CONFIG_PCI_XGENE=y
CONFIG_PCI_XGENE_MSI=y
CONFIG_PCIE_XILINX=y
CONFIG_PCIE_XILINX_DMA_PL=y
CONFIG_PCIE_XILINX_NWL=y
CONFIG_PCIE_XILINX_CPM=y
#
# Cadence-based PCIe controllers
#
CONFIG_PCIE_CADENCE=m
CONFIG_PCIE_CADENCE_HOST=m
CONFIG_PCIE_CADENCE_EP=m
CONFIG_PCIE_CADENCE_PLAT=m
CONFIG_PCIE_CADENCE_PLAT_HOST=m
CONFIG_PCIE_CADENCE_PLAT_EP=m
CONFIG_PCI_SKY1_HOST=m
CONFIG_PCIE_SG2042_HOST=m
CONFIG_PCI_J721E=m
CONFIG_PCI_J721E_HOST=m
CONFIG_PCI_J721E_EP=m
# end of Cadence-based PCIe controllers
#
# DesignWare-based PCIe controllers
#
CONFIG_PCIE_DW=y
CONFIG_PCIE_DW_DEBUGFS=y
CONFIG_PCIE_DW_HOST=y
CONFIG_PCIE_DW_EP=y
CONFIG_PCIE_AL=y
CONFIG_PCIE_AMD_MDB=y
CONFIG_PCI_MESON=m
CONFIG_PCIE_ARTPEC6=y
CONFIG_PCIE_ARTPEC6_HOST=y
CONFIG_PCIE_ARTPEC6_EP=y
# CONFIG_PCIE_BT1 is not set
CONFIG_PCI_IMX6=y
CONFIG_PCI_IMX6_HOST=y
CONFIG_PCI_IMX6_EP=y
# CONFIG_PCI_LAYERSCAPE is not set
CONFIG_PCI_LAYERSCAPE_EP=y
CONFIG_PCI_HISI=y
CONFIG_PCIE_KIRIN=m
CONFIG_PCIE_HISI_STB=y
CONFIG_PCIE_INTEL_GW=y
CONFIG_PCIE_KEEMBAY=y
CONFIG_PCIE_KEEMBAY_HOST=y
CONFIG_PCIE_KEEMBAY_EP=y
CONFIG_PCIE_ARMADA_8K=y
CONFIG_PCIE_TEGRA194=m
CONFIG_PCIE_TEGRA194_HOST=m
CONFIG_PCIE_TEGRA194_EP=m
CONFIG_PCIE_NXP_S32G=y
CONFIG_PCIE_DW_PLAT=y
CONFIG_PCIE_DW_PLAT_HOST=y
CONFIG_PCIE_DW_PLAT_EP=y
CONFIG_PCIE_QCOM_COMMON=y
CONFIG_PCIE_QCOM=y
CONFIG_PCIE_QCOM_EP=m
CONFIG_PCIE_RCAR_GEN4=m
CONFIG_PCIE_RCAR_GEN4_HOST=m
CONFIG_PCIE_RCAR_GEN4_EP=m
CONFIG_PCIE_ROCKCHIP_DW=y
CONFIG_PCIE_ROCKCHIP_DW_HOST=y
CONFIG_PCIE_ROCKCHIP_DW_EP=y
CONFIG_PCI_EXYNOS=m
CONFIG_PCIE_FU740=y
CONFIG_PCIE_UNIPHIER=y
CONFIG_PCIE_UNIPHIER_EP=y
CONFIG_PCIE_SOPHGO_DW=y
CONFIG_PCIE_SPACEMIT_K1=m
CONFIG_PCIE_SPEAR13XX=y
CONFIG_PCIE_STM32_HOST=m
CONFIG_PCIE_STM32_EP=m
CONFIG_PCI_DRA7XX=m
CONFIG_PCI_DRA7XX_HOST=m
CONFIG_PCI_DRA7XX_EP=m
CONFIG_PCI_KEYSTONE_TRISTATE=m
CONFIG_PCI_KEYSTONE_HOST=m
CONFIG_PCI_KEYSTONE_EP=m
CONFIG_PCIE_VISCONTI_HOST=y
# end of DesignWare-based PCIe controllers
#
# Mobiveil-based PCIe controllers
#
CONFIG_PCIE_MOBIVEIL=y
CONFIG_PCIE_MOBIVEIL_HOST=y
CONFIG_PCIE_LAYERSCAPE_GEN4=y
CONFIG_PCIE_MOBIVEIL_PLAT=y
# end of Mobiveil-based PCIe controllers
#
# PLDA-based PCIe controllers
#
CONFIG_PCIE_PLDA_HOST=y
CONFIG_PCIE_MICROCHIP_HOST=m
CONFIG_PCIE_STARFIVE_HOST=m
# end of PLDA-based PCIe controllers
# end of PCI controller drivers
#
# PCI Endpoint
#
CONFIG_PCI_ENDPOINT=y
CONFIG_PCI_ENDPOINT_CONFIGFS=y
CONFIG_PCI_ENDPOINT_MSI_DOORBELL=y
CONFIG_PCI_EPF_TEST=m
CONFIG_PCI_EPF_NTB=m
CONFIG_PCI_EPF_VNTB=m
CONFIG_PCI_EPF_MHI=m
# end of PCI Endpoint
#
# PCI switch controller drivers
#
CONFIG_PCI_SW_SWITCHTEC=m
# end of PCI switch controller drivers
CONFIG_PCI_PWRCTRL=y
CONFIG_PCI_PWRCTRL_SLOT=y
CONFIG_PCI_PWRCTRL_TC9563=m
CONFIG_CXL_BUS=m
CONFIG_CXL_PCI=m
CONFIG_CXL_MEM_RAW_COMMANDS=y
CONFIG_CXL_PMEM=m
CONFIG_CXL_MEM=m
CONFIG_CXL_FEATURES=y
CONFIG_CXL_EDAC_MEM_FEATURES=y
CONFIG_CXL_EDAC_SCRUB=y
CONFIG_CXL_EDAC_ECS=y
CONFIG_CXL_EDAC_MEM_REPAIR=y
CONFIG_CXL_PORT=m
CONFIG_CXL_SUSPEND=y
CONFIG_CXL_MCE=y
CONFIG_CXL_RAS=y
CONFIG_PCCARD=m
CONFIG_PCMCIA=m
CONFIG_PCMCIA_LOAD_CIS=y
CONFIG_CARDBUS=y
#
# PC-card bridges
#
CONFIG_YENTA=m
CONFIG_YENTA_O2=y
CONFIG_YENTA_RICOH=y
CONFIG_YENTA_TI=y
CONFIG_YENTA_ENE_TUNE=y
CONFIG_YENTA_TOSHIBA=y
CONFIG_PD6729=m
CONFIG_I82092=m
CONFIG_I82365=m
CONFIG_TCIC=m
CONFIG_PCMCIA_PROBE=y
CONFIG_PCCARD_NONSTATIC=y
CONFIG_RAPIDIO=m
CONFIG_RAPIDIO_TSI721=m
CONFIG_RAPIDIO_DISC_TIMEOUT=30
CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS=y
CONFIG_RAPIDIO_DMA_ENGINE=y
CONFIG_RAPIDIO_DEBUG=y
CONFIG_RAPIDIO_ENUM_BASIC=m
CONFIG_RAPIDIO_CHMAN=m
CONFIG_RAPIDIO_MPORT_CDEV=m
#
# RapidIO Switch drivers
#
CONFIG_RAPIDIO_CPS_XX=m
CONFIG_RAPIDIO_CPS_GEN2=m
CONFIG_RAPIDIO_RXS_GEN3=m
# end of RapidIO Switch drivers
CONFIG_PC104=y
#
# Generic Driver Options
#
CONFIG_AUXILIARY_BUS=y
CONFIG_UEVENT_HELPER=y
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DEVTMPFS_SAFE=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Firmware loader
#
CONFIG_FW_LOADER=y
CONFIG_FW_LOADER_DEBUG=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
CONFIG_FW_LOADER_COMPRESS=y
CONFIG_FW_LOADER_COMPRESS_XZ=y
CONFIG_FW_LOADER_COMPRESS_ZSTD=y
CONFIG_FW_CACHE=y
CONFIG_FW_UPLOAD=y
# end of Firmware loader
CONFIG_WANT_DEV_COREDUMP=y
CONFIG_ALLOW_DEV_COREDUMP=y
CONFIG_DEV_COREDUMP=y
CONFIG_DEBUG_DRIVER=y
CONFIG_DEBUG_DEVRES=y
CONFIG_DEBUG_TEST_DRIVER_REMOVE=y
CONFIG_PM_RUNTIME_KUNIT_TEST=m
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
CONFIG_DM_KUNIT_TEST=m
CONFIG_DRIVER_PE_KUNIT_TEST=m
CONFIG_SYS_HYPERVISOR=y
CONFIG_GENERIC_CPU_DEVICES=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_SOC_BUS=y
CONFIG_REGMAP=y
CONFIG_REGMAP_KUNIT=m
CONFIG_REGMAP_BUILD=y
CONFIG_REGMAP_AC97=m
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_SLIMBUS=m
CONFIG_REGMAP_SPI=y
CONFIG_REGMAP_SPMI=m
CONFIG_REGMAP_W1=m
CONFIG_REGMAP_MMIO=y
CONFIG_REGMAP_IRQ=y
CONFIG_REGMAP_RAM=m
CONFIG_REGMAP_SOUNDWIRE=m
CONFIG_REGMAP_SOUNDWIRE_MBQ=m
CONFIG_REGMAP_SCCB=m
CONFIG_REGMAP_I3C=m
CONFIG_REGMAP_SPI_AVMM=m
CONFIG_DMA_SHARED_BUFFER=y
CONFIG_DMA_FENCE_TRACE=y
CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT=y
# end of Generic Driver Options
#
# Bus devices
#
CONFIG_ARM_INTEGRATOR_LM=y
# CONFIG_BT1_APB is not set
# CONFIG_BT1_AXI is not set
CONFIG_MOXTET=m
CONFIG_HISILICON_LPC=y
CONFIG_IMX_WEIM=y
CONFIG_INTEL_IXP4XX_EB=y
CONFIG_OMAP_OCP2SCP=m
CONFIG_QCOM_EBI2=y
CONFIG_STM32_FIREWALL=y
CONFIG_FSL_MC_BUS=y
CONFIG_FSL_MC_UAPI_SUPPORT=y
CONFIG_MHI_BUS=m
CONFIG_MHI_BUS_DEBUG=y
CONFIG_MHI_BUS_PCI_GENERIC=m
CONFIG_MHI_BUS_EP=m
# end of Bus devices
CONFIG_CONNECTOR=m
#
# Firmware Drivers
#
#
# ARM System Control and Management Interface Protocol
#
CONFIG_ARM_SCMI_PROTOCOL=m
CONFIG_ARM_SCMI_NEED_DEBUGFS=y
CONFIG_ARM_SCMI_RAW_MODE_SUPPORT=y
CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX=y
CONFIG_ARM_SCMI_DEBUG_COUNTERS=y
CONFIG_ARM_SCMI_QUIRKS=y
#
# SCMI Transport Drivers
#
CONFIG_ARM_SCMI_HAVE_TRANSPORT=y
CONFIG_ARM_SCMI_HAVE_SHMEM=y
CONFIG_ARM_SCMI_HAVE_MSG=y
CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=m
CONFIG_ARM_SCMI_TRANSPORT_VIRTIO=m
CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE=y
CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE=y
# end of SCMI Transport Drivers
#
# ARM SCMI NXP i.MX Vendor Protocols
#
CONFIG_IMX_SCMI_BBM_EXT=m
CONFIG_IMX_SCMI_CPU_EXT=m
CONFIG_IMX_SCMI_LMM_EXT=m
CONFIG_IMX_SCMI_MISC_EXT=m
# end of ARM SCMI NXP i.MX Vendor Protocols
CONFIG_ARM_SCMI_POWER_CONTROL=m
# end of ARM System Control and Management Interface Protocol
CONFIG_ARM_SCPI_PROTOCOL=m
CONFIG_EDD=m
CONFIG_EDD_OFF=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DMIID=y
CONFIG_DMI_SYSFS=m
CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
CONFIG_ISCSI_IBFT_FIND=y
CONFIG_ISCSI_IBFT=m
CONFIG_FW_CFG_SYSFS=m
CONFIG_FW_CFG_SYSFS_CMDLINE=y
CONFIG_MTK_ADSP_IPC=m
CONFIG_SYSFB=y
CONFIG_SYSFB_SIMPLEFB=y
CONFIG_TH1520_AON_PROTOCOL=m
CONFIG_TI_SCI_PROTOCOL=m
CONFIG_TURRIS_MOX_RWTM=m
CONFIG_TURRIS_MOX_RWTM_KEYCTL=y
CONFIG_BCM47XX_NVRAM=y
CONFIG_BCM47XX_SPROM=y
CONFIG_TEE_BNXT_FW=m
CONFIG_FW_CS_DSP=m
CONFIG_FW_CS_DSP_KUNIT_TEST_UTILS=m
CONFIG_FW_CS_DSP_KUNIT_TEST=m
CONFIG_GOOGLE_FIRMWARE=y
CONFIG_GOOGLE_SMI=m
CONFIG_GOOGLE_CBMEM=m
CONFIG_GOOGLE_COREBOOT_TABLE=m
CONFIG_GOOGLE_MEMCONSOLE=m
CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY=m
CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT=m
CONFIG_GOOGLE_MEMCONSOLE_COREBOOT=m
CONFIG_GOOGLE_VPD=m
#
# EFI (Extensible Firmware Interface) Support
#
CONFIG_EFI_ESRT=y
CONFIG_EFI_VARS_PSTORE=m
CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y
CONFIG_EFI_DXE_MEM_ATTRIBUTES=y
CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_BOOTLOADER_CONTROL=m
CONFIG_EFI_CAPSULE_LOADER=y
CONFIG_EFI_CAPSULE_QUIRK_QUARK_CSH=y
CONFIG_EFI_TEST=m
CONFIG_EFI_DEV_PATH_PARSER=y
CONFIG_APPLE_PROPERTIES=y
CONFIG_RESET_ATTACK_MITIGATION=y
CONFIG_EFI_RCI2_TABLE=y
CONFIG_EFI_DISABLE_PCI_DMA=y
CONFIG_EFI_EARLYCON=y
CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y
CONFIG_EFI_DISABLE_RUNTIME=y
CONFIG_EFI_COCO_SECRET=y
CONFIG_OVMF_DEBUG_LOG=y
CONFIG_EFI_EMBEDDED_FIRMWARE=y
CONFIG_EFI_SBAT_FILE=""
# end of EFI (Extensible Firmware Interface) Support
CONFIG_UEFI_CPER=y
CONFIG_UEFI_CPER_X86=y
CONFIG_IMX_DSP=m
CONFIG_IMX_SCU=y
CONFIG_IMX_SCMI_CPU_DRV=m
CONFIG_IMX_SCMI_LMM_DRV=m
CONFIG_IMX_SCMI_MISC_DRV=m
CONFIG_POLARFIRE_SOC_AUTO_UPDATE=m
#
# Qualcomm firmware drivers
#
CONFIG_QCOM_SCM=y
CONFIG_QCOM_TZMEM=y
CONFIG_QCOM_TZMEM_MODE_GENERIC=y
# CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE is not set
CONFIG_QCOM_QSEECOM=y
CONFIG_QCOM_QSEECOM_UEFISECAPP=y
# end of Qualcomm firmware drivers
CONFIG_EXYNOS_ACPM_PROTOCOL=m
#
# Tegra firmware driver
#
# end of Tegra firmware driver
# end of Firmware Drivers
CONFIG_FWCTL=m
CONFIG_FWCTL_MLX5=m
CONFIG_GNSS=m
CONFIG_GNSS_SERIAL=m
CONFIG_GNSS_MTK_SERIAL=m
CONFIG_GNSS_SIRF_SERIAL=m
CONFIG_GNSS_UBX_SERIAL=m
CONFIG_GNSS_USB=m
CONFIG_MTD=m
CONFIG_MTD_TESTS=m
#
# Partition parsers
#
CONFIG_MTD_BCM63XX_PARTS=y
CONFIG_MTD_BRCM_U_BOOT=m
CONFIG_MTD_CMDLINE_PARTS=m
CONFIG_MTD_OF_PARTS=m
CONFIG_MTD_OF_PARTS_BCM4908=y
CONFIG_MTD_OF_PARTS_LINKSYS_NS=y
CONFIG_MTD_PARSER_IMAGETAG=m
CONFIG_MTD_PARSER_TPLINK_SAFELOADER=m
CONFIG_MTD_PARSER_TRX=m
CONFIG_MTD_SHARPSL_PARTS=m
CONFIG_MTD_REDBOOT_PARTS=m
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
CONFIG_MTD_REDBOOT_PARTS_READONLY=y
CONFIG_MTD_QCOMSMEM_PARTS=m
# end of Partition parsers
#
# User Modules And Translation Layers
#
CONFIG_MTD_BLKDEVS=m
CONFIG_MTD_BLOCK=m
CONFIG_MTD_BLOCK_RO=m
#
# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK.
#
CONFIG_FTL=m
CONFIG_NFTL=m
CONFIG_NFTL_RW=y
CONFIG_INFTL=m
CONFIG_RFD_FTL=m
CONFIG_SSFDC=m
CONFIG_SM_FTL=m
CONFIG_MTD_OOPS=m
CONFIG_MTD_PSTORE=m
CONFIG_MTD_SWAP=m
CONFIG_MTD_PARTITIONED_MASTER=y
#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=m
CONFIG_MTD_JEDECPROBE=m
CONFIG_MTD_GEN_PROBE=m
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_NOSWAP=y
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
CONFIG_MTD_MAP_BANK_WIDTH_8=y
CONFIG_MTD_MAP_BANK_WIDTH_16=y
CONFIG_MTD_MAP_BANK_WIDTH_32=y
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
CONFIG_MTD_CFI_I4=y
CONFIG_MTD_CFI_I8=y
CONFIG_MTD_OTP=y
CONFIG_MTD_CFI_INTELEXT=m
CONFIG_MTD_CFI_AMDSTD=m
CONFIG_MTD_CFI_STAA=m
CONFIG_MTD_CFI_UTIL=m
CONFIG_MTD_RAM=m
CONFIG_MTD_ROM=m
CONFIG_MTD_ABSENT=m
# end of RAM/ROM/Flash chip drivers
#
# Mapping drivers for chip access
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=m
CONFIG_MTD_PHYSMAP_COMPAT=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_PHYSMAP_BT1_ROM is not set
CONFIG_MTD_PHYSMAP_VERSATILE=y
CONFIG_MTD_PHYSMAP_GEMINI=y
CONFIG_MTD_PHYSMAP_GPIO_ADDR=y
CONFIG_MTD_SC520CDP=m
CONFIG_MTD_NETSC520=m
CONFIG_MTD_TS5500=m
CONFIG_MTD_SBC_GXX=m
CONFIG_MTD_SCx200_DOCFLASH=m
CONFIG_MTD_AMD76XROM=m
CONFIG_MTD_ICHXROM=m
CONFIG_MTD_ESB2ROM=m
CONFIG_MTD_CK804XROM=m
CONFIG_MTD_SCB2_FLASH=m
CONFIG_MTD_NETtel=m
CONFIG_MTD_L440GX=m
CONFIG_MTD_PCI=m
CONFIG_MTD_PCMCIA=m
CONFIG_MTD_PCMCIA_ANONYMOUS=y
CONFIG_MTD_PLATRAM=m
# end of Mapping drivers for chip access
#
# Self-contained MTD device drivers
#
CONFIG_MTD_PMC551=m
CONFIG_MTD_PMC551_BUGFIX=y
CONFIG_MTD_PMC551_DEBUG=y
CONFIG_MTD_DATAFLASH=m
CONFIG_MTD_DATAFLASH_WRITE_VERIFY=y
CONFIG_MTD_DATAFLASH_OTP=y
CONFIG_MTD_MCHP23K256=m
CONFIG_MTD_MCHP48L640=m
CONFIG_MTD_SPEAR_SMI=m
CONFIG_MTD_SST25L=m
CONFIG_MTD_SLRAM=m
CONFIG_MTD_PHRAM=m
CONFIG_MTD_MTDRAM=m
CONFIG_MTDRAM_TOTAL_SIZE=4096
CONFIG_MTDRAM_ERASE_SIZE=128
CONFIG_MTD_BLOCK2MTD=m
CONFIG_MTD_INTEL_DG=m
#
# Disk-On-Chip Device Drivers
#
CONFIG_MTD_DOCG3=m
CONFIG_BCH_CONST_M=14
CONFIG_BCH_CONST_T=4
# end of Self-contained MTD device drivers
#
# NAND
#
CONFIG_MTD_NAND_CORE=m
CONFIG_MTD_ONENAND=m
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
CONFIG_MTD_ONENAND_GENERIC=m
CONFIG_MTD_ONENAND_SAMSUNG=m
CONFIG_MTD_ONENAND_OTP=y
CONFIG_MTD_ONENAND_2X_PROGRAM=y
CONFIG_MTD_RAW_NAND=m
#
# Raw/parallel NAND flash controllers
#
CONFIG_MTD_NAND_DENALI=m
CONFIG_MTD_NAND_DENALI_PCI=m
CONFIG_MTD_NAND_DENALI_DT=m
CONFIG_MTD_NAND_AMS_DELTA=m
CONFIG_MTD_NAND_OMAP2=m
CONFIG_MTD_NAND_OMAP_BCH=y
CONFIG_MTD_NAND_OMAP_BCH_BUILD=m
CONFIG_MTD_NAND_SHARPSL=m
CONFIG_MTD_NAND_CAFE=m
CONFIG_MTD_NAND_CS553X=m
CONFIG_MTD_NAND_ATMEL=m
CONFIG_MTD_NAND_MARVELL=m
CONFIG_MTD_NAND_SLC_LPC32XX=m
CONFIG_MTD_NAND_MLC_LPC32XX=m
CONFIG_MTD_NAND_BRCMNAND=m
CONFIG_MTD_NAND_BRCMNAND_BCM63XX=m
CONFIG_MTD_NAND_BRCMNAND_BCMA=m
CONFIG_MTD_NAND_BRCMNAND_BCMBCA=m
CONFIG_MTD_NAND_BRCMNAND_BRCMSTB=m
CONFIG_MTD_NAND_BRCMNAND_IPROC=m
CONFIG_MTD_NAND_BCM47XXNFLASH=m
CONFIG_MTD_NAND_FSL_IFC=m
CONFIG_MTD_NAND_VF610_NFC=m
CONFIG_MTD_NAND_MXC=m
CONFIG_MTD_NAND_SH_FLCTL=m
CONFIG_MTD_NAND_DAVINCI=m
CONFIG_MTD_NAND_TXX9NDFMC=m
CONFIG_MTD_NAND_JZ4780=m
CONFIG_MTD_NAND_INGENIC_ECC=y
CONFIG_MTD_NAND_JZ4740_ECC=m
CONFIG_MTD_NAND_JZ4725B_BCH=m
CONFIG_MTD_NAND_JZ4780_BCH=m
CONFIG_MTD_NAND_FSMC=m
CONFIG_MTD_NAND_SUNXI=m
CONFIG_MTD_NAND_HISI504=m
CONFIG_MTD_NAND_QCOM=m
CONFIG_MTD_NAND_MTK=m
CONFIG_MTD_NAND_MXIC=m
CONFIG_MTD_NAND_TEGRA=m
CONFIG_MTD_NAND_STM32_FMC2=m
CONFIG_MTD_NAND_MESON=m
CONFIG_MTD_NAND_GPIO=m
CONFIG_MTD_NAND_PLATFORM=m
CONFIG_MTD_NAND_CADENCE=m
CONFIG_MTD_NAND_ARASAN=m
CONFIG_MTD_NAND_INTEL_LGM=m
CONFIG_MTD_NAND_RENESAS=m
CONFIG_MTD_NAND_NUVOTON_MA35=m
CONFIG_MTD_NAND_LOONGSON=m
#
# Misc
#
CONFIG_MTD_SM_COMMON=m
CONFIG_MTD_NAND_NANDSIM=m
CONFIG_MTD_NAND_RICOH=m
CONFIG_MTD_NAND_DISKONCHIP=m
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
CONFIG_MTD_SPI_NAND=m
#
# ECC engine support
#
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_ECC_SW_HAMMING=y
CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC=y
CONFIG_MTD_NAND_ECC_SW_BCH=y
CONFIG_MTD_NAND_ECC_MXIC=y
CONFIG_MTD_NAND_ECC_MEDIATEK=m
CONFIG_MTD_NAND_ECC_REALTEK=m
# end of ECC engine support
# end of NAND
#
# LPDDR & LPDDR2 PCM memory drivers
#
CONFIG_MTD_LPDDR=m
CONFIG_MTD_QINFO_PROBE=m
# end of LPDDR & LPDDR2 PCM memory drivers
CONFIG_MTD_SPI_NOR=m
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set
CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y
# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set
CONFIG_SPI_HISI_SFC=m
CONFIG_SPI_NXP_SPIFI=m
CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_FASTMAP=y
CONFIG_MTD_UBI_GLUEBI=m
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_FAULT_INJECTION=y
CONFIG_MTD_UBI_NVMEM=m
CONFIG_MTD_HYPERBUS=m
CONFIG_HBMC_AM654=m
CONFIG_DTC=y
CONFIG_OF=y
CONFIG_OF_UNITTEST=y
CONFIG_OF_KUNIT_TEST=m
# CONFIG_OF_ALL_DTBS is not set
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_KOBJ=y
CONFIG_OF_DYNAMIC=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_RESERVED_MEM=y
CONFIG_OF_RESOLVE=y
CONFIG_OF_OVERLAY=y
CONFIG_OF_OVERLAY_KUNIT_TEST=m
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
CONFIG_PARPORT_SERIAL=m
CONFIG_PARPORT_PC_FIFO=y
CONFIG_PARPORT_PC_SUPERIO=y
CONFIG_PARPORT_PC_PCMCIA=m
CONFIG_PARPORT_1284=y
CONFIG_PARPORT_NOT_PC=y
CONFIG_PNP=y
CONFIG_PNP_DEBUG_MESSAGES=y
#
# Protocols
#
CONFIG_ISAPNP=y
CONFIG_PNPBIOS=y
CONFIG_PNPBIOS_PROC_FS=y
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_NULL_BLK=m
CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION=y
CONFIG_BLK_DEV_FD=m
CONFIG_BLK_DEV_FD_RAWCMD=y
CONFIG_CDROM=m
CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m
CONFIG_ZRAM=m
CONFIG_ZRAM_BACKEND_LZ4=y
CONFIG_ZRAM_BACKEND_LZ4HC=y
CONFIG_ZRAM_BACKEND_ZSTD=y
CONFIG_ZRAM_BACKEND_DEFLATE=y
CONFIG_ZRAM_BACKEND_842=y
CONFIG_ZRAM_BACKEND_LZO=y
CONFIG_ZRAM_DEF_COMP_LZORLE=y
# CONFIG_ZRAM_DEF_COMP_LZO is not set
# CONFIG_ZRAM_DEF_COMP_LZ4 is not set
# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set
# CONFIG_ZRAM_DEF_COMP_ZSTD is not set
# CONFIG_ZRAM_DEF_COMP_DEFLATE is not set
# CONFIG_ZRAM_DEF_COMP_842 is not set
CONFIG_ZRAM_DEF_COMP="lzo-rle"
CONFIG_ZRAM_WRITEBACK=y
CONFIG_ZRAM_TRACK_ENTRY_ACTIME=y
CONFIG_ZRAM_MEMORY_TRACKING=y
CONFIG_ZRAM_MULTI_COMP=y
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
CONFIG_BLK_DEV_DRBD=m
CONFIG_DRBD_FAULT_INJECTION=y
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_ATA_OVER_ETH=m
CONFIG_XEN_BLKDEV_FRONTEND=m
CONFIG_XEN_BLKDEV_BACKEND=m
CONFIG_VIRTIO_BLK=m
CONFIG_BLK_DEV_RBD=m
CONFIG_BLK_DEV_UBLK=m
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y
CONFIG_BLK_DEV_RNBD=y
CONFIG_BLK_DEV_RNBD_CLIENT=m
CONFIG_BLK_DEV_RNBD_SERVER=m
CONFIG_BLK_DEV_ZONED_LOOP=m
#
# NVME Support
#
CONFIG_NVME_KEYRING=m
CONFIG_NVME_AUTH=m
CONFIG_NVME_CORE=m
CONFIG_BLK_DEV_NVME=m
CONFIG_NVME_MULTIPATH=y
CONFIG_NVME_VERBOSE_ERRORS=y
CONFIG_NVME_HWMON=y
CONFIG_NVME_FABRICS=m
CONFIG_NVME_RDMA=m
CONFIG_NVME_FC=m
CONFIG_NVME_TCP=m
CONFIG_NVME_TCP_TLS=y
CONFIG_NVME_HOST_AUTH=y
CONFIG_NVME_TARGET=m
CONFIG_NVME_TARGET_DEBUGFS=y
CONFIG_NVME_TARGET_PASSTHRU=y
CONFIG_NVME_TARGET_LOOP=m
CONFIG_NVME_TARGET_RDMA=m
CONFIG_NVME_TARGET_FC=m
CONFIG_NVME_TARGET_FCLOOP=m
CONFIG_NVME_TARGET_TCP=m
CONFIG_NVME_TARGET_TCP_TLS=y
CONFIG_NVME_TARGET_AUTH=y
CONFIG_NVME_TARGET_PCI_EPF=m
# end of NVME Support
#
# Misc devices
#
CONFIG_SENSORS_LIS3LV02D=m
CONFIG_AD525X_DPOT=m
CONFIG_AD525X_DPOT_I2C=m
CONFIG_AD525X_DPOT_SPI=m
CONFIG_DUMMY_IRQ=m
CONFIG_IBM_ASM=m
CONFIG_PHANTOM=m
CONFIG_RPMB=m
CONFIG_TI_FPC202=m
CONFIG_TIFM_CORE=m
CONFIG_TIFM_7XX1=m
CONFIG_ICS932S401=m
CONFIG_ATMEL_SSC=m
CONFIG_ENCLOSURE_SERVICES=m
CONFIG_SMPRO_ERRMON=m
CONFIG_SMPRO_MISC=m
CONFIG_CS5535_MFGPT=m
CONFIG_CS5535_MFGPT_DEFAULT_IRQ=7
CONFIG_CS5535_CLOCK_EVENT_SRC=m
CONFIG_GEHC_ACHC=m
CONFIG_HI6421V600_IRQ=m
CONFIG_HP_ILO=m
CONFIG_QCOM_COINCELL=m
CONFIG_QCOM_FASTRPC=m
CONFIG_APDS9802ALS=m
CONFIG_ISL29003=m
CONFIG_ISL29020=m
CONFIG_SENSORS_TSL2550=m
CONFIG_SENSORS_BH1770=m
CONFIG_SENSORS_APDS990X=m
CONFIG_HMC6352=m
CONFIG_DS1682=m
CONFIG_VMWARE_BALLOON=m
CONFIG_PCH_PHUB=m
CONFIG_LATTICE_ECP3_CONFIG=m
CONFIG_SRAM=y
CONFIG_DW_XDATA_PCIE=m
CONFIG_PCI_ENDPOINT_TEST=m
CONFIG_XILINX_SDFEC=m
CONFIG_MISC_RTSX=m
CONFIG_HISI_HIKEY_USB=m
CONFIG_OPEN_DICE=m
CONFIG_NTSYNC=m
CONFIG_VCPU_STALL_DETECTOR=m
CONFIG_TPS6594_ESM=m
CONFIG_TPS6594_PFSM=m
CONFIG_NSM=m
CONFIG_MCHP_LAN966X_PCI=m
CONFIG_C2PORT=m
CONFIG_C2PORT_DURAMAR_2150=m
#
# EEPROM support
#
CONFIG_EEPROM_AT24=m
CONFIG_EEPROM_AT25=m
CONFIG_EEPROM_MAX6875=m
CONFIG_EEPROM_93CX6=m
CONFIG_EEPROM_93XX46=m
CONFIG_EEPROM_IDT_89HPESX=m
CONFIG_EEPROM_EE1004=m
CONFIG_EEPROM_M24LR=m
# end of EEPROM support
CONFIG_CB710_CORE=m
CONFIG_CB710_DEBUG=y
CONFIG_CB710_DEBUG_ASSUMPTIONS=y
CONFIG_SENSORS_LIS3_I2C=m
CONFIG_ALTERA_STAPL=m
CONFIG_INTEL_MEI=m
CONFIG_INTEL_MEI_ME=m
CONFIG_INTEL_MEI_TXE=m
CONFIG_INTEL_MEI_GSC=m
CONFIG_INTEL_MEI_VSC_HW=m
CONFIG_INTEL_MEI_VSC=m
CONFIG_INTEL_MEI_LB=m
CONFIG_INTEL_MEI_HDCP=m
CONFIG_INTEL_MEI_PXP=m
CONFIG_INTEL_MEI_GSC_PROXY=m
CONFIG_VMWARE_VMCI=m
CONFIG_BCM_VK=m
CONFIG_BCM_VK_TTY=y
CONFIG_MISC_ALCOR_PCI=m
CONFIG_MISC_RTSX_PCI=m
CONFIG_MISC_RTSX_USB=m
CONFIG_UACCE=m
CONFIG_PVPANIC=y
CONFIG_PVPANIC_MMIO=m
CONFIG_PVPANIC_PCI=m
CONFIG_GP_PCI1XXXX=m
CONFIG_KEBA_CP500=m
CONFIG_KEBA_LAN9252=m
CONFIG_AMD_SBRMI_I2C=m
CONFIG_AMD_SBRMI_HWMON=y
CONFIG_MISC_RP1=m
# end of Misc devices
#
# SCSI device support
#
CONFIG_SCSI_MOD=m
CONFIG_RAID_ATTRS=m
CONFIG_SCSI_COMMON=m
CONFIG_SCSI=m
CONFIG_SCSI_DMA=y
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y
CONFIG_SCSI_LIB_KUNIT_TEST=m
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=m
CONFIG_CHR_DEV_ST=m
CONFIG_BLK_DEV_SR=m
CONFIG_CHR_DEV_SG=m
CONFIG_BLK_DEV_BSG=y
CONFIG_CHR_DEV_SCH=m
CONFIG_SCSI_ENCLOSURE=m
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_PROTO_TEST=m
#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=m
CONFIG_SCSI_FC_ATTRS=m
CONFIG_SCSI_ISCSI_ATTRS=m
CONFIG_SCSI_SAS_ATTRS=m
CONFIG_SCSI_SAS_LIBSAS=m
CONFIG_SCSI_SAS_ATA=y
CONFIG_SCSI_SAS_HOST_SMP=y
CONFIG_SCSI_SRP_ATTRS=m
# end of SCSI Transports
CONFIG_SCSI_LOWLEVEL=y
CONFIG_ISCSI_TCP=m
CONFIG_ISCSI_BOOT_SYSFS=m
CONFIG_SCSI_CXGB3_ISCSI=m
CONFIG_SCSI_CXGB4_ISCSI=m
CONFIG_SCSI_BNX2_ISCSI=m
CONFIG_SCSI_BNX2X_FCOE=m
CONFIG_BE2ISCSI=m
CONFIG_BLK_DEV_3W_XXXX_RAID=m
CONFIG_SCSI_HPSA=m
CONFIG_SCSI_3W_9XXX=m
CONFIG_SCSI_3W_SAS=m
CONFIG_SCSI_ACARD=m
CONFIG_SCSI_AHA1542=m
CONFIG_SCSI_AHA1740=m
CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
CONFIG_AIC7XXX_RESET_DELAY_MS=5000
CONFIG_AIC7XXX_DEBUG_ENABLE=y
CONFIG_AIC7XXX_DEBUG_MASK=0
CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
CONFIG_SCSI_AIC79XX=m
CONFIG_AIC79XX_CMDS_PER_DEVICE=32
CONFIG_AIC79XX_RESET_DELAY_MS=5000
CONFIG_AIC79XX_DEBUG_ENABLE=y
CONFIG_AIC79XX_DEBUG_MASK=0
CONFIG_AIC79XX_REG_PRETTY_PRINT=y
CONFIG_SCSI_AIC94XX=m
CONFIG_AIC94XX_DEBUG=y
CONFIG_SCSI_HISI_SAS=m
CONFIG_SCSI_HISI_SAS_PCI=m
CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE=y
CONFIG_SCSI_MVSAS=m
CONFIG_SCSI_MVSAS_DEBUG=y
CONFIG_SCSI_MVSAS_TASKLET=y
CONFIG_SCSI_MVUMI=m
CONFIG_SCSI_ADVANSYS=m
CONFIG_SCSI_ARCMSR=m
CONFIG_SCSI_ESAS2R=m
CONFIG_MEGARAID_NEWGEN=y
CONFIG_MEGARAID_MM=m
CONFIG_MEGARAID_MAILBOX=m
CONFIG_MEGARAID_LEGACY=m
CONFIG_MEGARAID_SAS=m
CONFIG_SCSI_MPT3SAS=m
CONFIG_SCSI_MPT2SAS_MAX_SGE=128
CONFIG_SCSI_MPT3SAS_MAX_SGE=128
CONFIG_SCSI_MPT2SAS=m
CONFIG_SCSI_MPI3MR=m
CONFIG_SCSI_SMARTPQI=m
CONFIG_SCSI_HPTIOP=m
CONFIG_SCSI_BUSLOGIC=m
CONFIG_SCSI_FLASHPOINT=y
CONFIG_SCSI_MYRB=m
CONFIG_SCSI_MYRS=m
CONFIG_VMWARE_PVSCSI=m
CONFIG_XEN_SCSI_FRONTEND=m
CONFIG_HYPERV_STORAGE=m
CONFIG_LIBFC=m
CONFIG_LIBFCOE=m
CONFIG_FCOE=m
CONFIG_FCOE_FNIC=m
CONFIG_SCSI_SNIC=m
CONFIG_SCSI_SNIC_DEBUG_FS=y
CONFIG_SCSI_DMX3191D=m
CONFIG_SCSI_FDOMAIN=m
CONFIG_SCSI_FDOMAIN_PCI=m
CONFIG_SCSI_FDOMAIN_ISA=m
CONFIG_SCSI_ISCI=m
CONFIG_SCSI_GENERIC_NCR5380=m
CONFIG_SCSI_IPS=m
CONFIG_SCSI_INITIO=m
CONFIG_SCSI_INIA100=m
CONFIG_SCSI_STEX=m
CONFIG_SCSI_SYM53C8XX_2=m
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
CONFIG_SCSI_SYM53C8XX_MMIO=y
CONFIG_SCSI_IPR=m
CONFIG_SCSI_IPR_TRACE=y
CONFIG_SCSI_IPR_DUMP=y
CONFIG_SCSI_QLOGIC_FAS=m
CONFIG_SCSI_QLOGIC_1280=m
CONFIG_SCSI_QLA_FC=m
CONFIG_TCM_QLA2XXX=m
CONFIG_TCM_QLA2XXX_DEBUG=y
CONFIG_SCSI_QLA_ISCSI=m
CONFIG_QEDI=m
CONFIG_QEDF=m
CONFIG_SCSI_LPFC=m
CONFIG_SCSI_LPFC_DEBUG_FS=y
CONFIG_SCSI_EFCT=m
CONFIG_SCSI_SIM710=m
CONFIG_SCSI_DC395x=m
CONFIG_SCSI_AM53C974=m
CONFIG_SCSI_NSP32=m
CONFIG_SCSI_WD719X=m
CONFIG_SCSI_DEBUG=m
CONFIG_SCSI_PMCRAID=m
CONFIG_SCSI_PM8001=m
CONFIG_SCSI_BFA_FC=m
CONFIG_SCSI_VIRTIO=m
CONFIG_SCSI_CHELSIO_FCOE=m
CONFIG_SCSI_LOWLEVEL_PCMCIA=y
CONFIG_PCMCIA_AHA152X=m
CONFIG_PCMCIA_FDOMAIN=m
CONFIG_PCMCIA_NINJA_SCSI=m
CONFIG_PCMCIA_QLOGIC=m
CONFIG_PCMCIA_SYM53C500=m
CONFIG_SCSI_DH=y
CONFIG_SCSI_DH_RDAC=m
CONFIG_SCSI_DH_HP_SW=m
CONFIG_SCSI_DH_EMC=m
CONFIG_SCSI_DH_ALUA=m
# end of SCSI device support
CONFIG_ATA=m
CONFIG_SATA_HOST=y
CONFIG_PATA_TIMINGS=y
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_FORCE=y
CONFIG_ATA_ACPI=y
CONFIG_SATA_ZPODD=y
CONFIG_SATA_PMP=y
#
# Controllers with non-SFF native interface
#
CONFIG_SATA_AHCI=m
CONFIG_SATA_MOBILE_LPM_POLICY=3
CONFIG_SATA_AHCI_PLATFORM=m
CONFIG_AHCI_BRCM=m
CONFIG_AHCI_DA850=m
CONFIG_AHCI_DM816=m
CONFIG_AHCI_DWC=m
CONFIG_AHCI_ST=m
CONFIG_AHCI_IMX=m
CONFIG_AHCI_CEVA=m
CONFIG_AHCI_MTK=m
CONFIG_AHCI_MVEBU=m
CONFIG_AHCI_SUNXI=m
CONFIG_AHCI_TEGRA=m
CONFIG_AHCI_XGENE=m
CONFIG_AHCI_QORIQ=m
CONFIG_SATA_FSL=m
CONFIG_SATA_GEMINI=m
CONFIG_SATA_AHCI_SEATTLE=m
CONFIG_SATA_INIC162X=m
CONFIG_SATA_ACARD_AHCI=m
CONFIG_SATA_SIL24=m
CONFIG_ATA_SFF=y
#
# SFF controllers with custom DMA interface
#
CONFIG_PDC_ADMA=m
CONFIG_SATA_QSTOR=m
CONFIG_SATA_SX4=m
CONFIG_ATA_BMDMA=y
#
# SATA SFF controllers with BMDMA
#
CONFIG_ATA_PIIX=m
CONFIG_SATA_DWC=m
CONFIG_SATA_DWC_OLD_DMA=y
CONFIG_SATA_HIGHBANK=m
CONFIG_SATA_MV=m
CONFIG_SATA_NV=m
CONFIG_SATA_PROMISE=m
CONFIG_SATA_RCAR=m
CONFIG_SATA_SIL=m
CONFIG_SATA_SIS=m
CONFIG_SATA_SVW=m
CONFIG_SATA_ULI=m
CONFIG_SATA_VIA=m
CONFIG_SATA_VITESSE=m
#
# PATA SFF controllers with BMDMA
#
CONFIG_PATA_ALI=m
CONFIG_PATA_AMD=m
CONFIG_PATA_ARASAN_CF=m
CONFIG_PATA_ARTOP=m
CONFIG_PATA_ATIIXP=m
CONFIG_PATA_ATP867X=m
CONFIG_PATA_CMD64X=m
CONFIG_PATA_CS5520=m
CONFIG_PATA_CS5530=m
CONFIG_PATA_CS5535=m
CONFIG_PATA_CS5536=m
CONFIG_PATA_CYPRESS=m
CONFIG_PATA_EFAR=m
CONFIG_PATA_FTIDE010=m
CONFIG_PATA_HPT366=m
CONFIG_PATA_HPT37X=m
CONFIG_PATA_HPT3X2N=m
CONFIG_PATA_HPT3X3=m
CONFIG_PATA_HPT3X3_DMA=y
CONFIG_PATA_IMX=m
CONFIG_PATA_IT8213=m
CONFIG_PATA_IT821X=m
CONFIG_PATA_JMICRON=m
CONFIG_PATA_MARVELL=m
CONFIG_PATA_NETCELL=m
CONFIG_PATA_NINJA32=m
CONFIG_PATA_NS87415=m
CONFIG_PATA_OLDPIIX=m
CONFIG_PATA_OPTIDMA=m
CONFIG_PATA_PDC2027X=m
CONFIG_PATA_PDC_OLD=m
CONFIG_PATA_RADISYS=m
CONFIG_PATA_RDC=m
CONFIG_PATA_SC1200=m
CONFIG_PATA_SCH=m
CONFIG_PATA_SERVERWORKS=m
CONFIG_PATA_SIL680=m
CONFIG_PATA_SIS=m
CONFIG_PATA_TOSHIBA=m
CONFIG_PATA_TRIFLEX=m
CONFIG_PATA_VIA=m
CONFIG_PATA_PXA=m
CONFIG_PATA_WINBOND=m
#
# PIO-only SFF controllers
#
CONFIG_PATA_CMD640_PCI=m
CONFIG_PATA_ISAPNP=m
CONFIG_PATA_IXP4XX_CF=m
CONFIG_PATA_MPIIX=m
CONFIG_PATA_NS87410=m
CONFIG_PATA_OPTI=m
CONFIG_PATA_PCMCIA=m
CONFIG_PATA_PLATFORM=m
CONFIG_PATA_OF_PLATFORM=m
CONFIG_PATA_RZ1000=m
CONFIG_PATA_PARPORT=m
#
# Parallel IDE protocol modules
#
CONFIG_PATA_PARPORT_ATEN=m
CONFIG_PATA_PARPORT_BPCK=m
CONFIG_PATA_PARPORT_BPCK6=m
CONFIG_PATA_PARPORT_COMM=m
CONFIG_PATA_PARPORT_DSTR=m
CONFIG_PATA_PARPORT_FIT2=m
CONFIG_PATA_PARPORT_FIT3=m
CONFIG_PATA_PARPORT_EPAT=m
CONFIG_PATA_PARPORT_EPATC8=y
CONFIG_PATA_PARPORT_EPIA=m
CONFIG_PATA_PARPORT_FRIQ=m
CONFIG_PATA_PARPORT_FRPW=m
CONFIG_PATA_PARPORT_KBIC=m
CONFIG_PATA_PARPORT_KTTI=m
CONFIG_PATA_PARPORT_ON20=m
CONFIG_PATA_PARPORT_ON26=m
#
# Generic fallback / legacy drivers
#
CONFIG_PATA_ACPI=m
CONFIG_ATA_GENERIC=m
CONFIG_PATA_LEGACY=m
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
CONFIG_MD_BITMAP=y
CONFIG_MD_LLBITMAP=y
CONFIG_MD_BITMAP_FILE=y
CONFIG_MD_LINEAR=m
CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
CONFIG_MD_RAID10=m
CONFIG_MD_RAID456=m
CONFIG_MD_CLUSTER=m
CONFIG_BCACHE=m
CONFIG_BCACHE_DEBUG=y
CONFIG_BCACHE_ASYNC_REGISTRATION=y
CONFIG_BLK_DEV_DM_BUILTIN=y
CONFIG_BLK_DEV_DM=m
CONFIG_DM_DEBUG=y
CONFIG_DM_BUFIO=m
CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING=y
CONFIG_DM_DEBUG_BLOCK_STACK_TRACING=y
CONFIG_DM_BIO_PRISON=m
CONFIG_DM_PERSISTENT_DATA=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_THIN_PROVISIONING=m
CONFIG_DM_CACHE=m
CONFIG_DM_CACHE_SMQ=m
CONFIG_DM_WRITECACHE=m
CONFIG_DM_ERA=m
CONFIG_DM_CLONE=m
CONFIG_DM_MIRROR=m
CONFIG_DM_LOG_USERSPACE=m
CONFIG_DM_RAID=m
CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m
CONFIG_DM_MULTIPATH_QL=m
CONFIG_DM_MULTIPATH_ST=m
CONFIG_DM_MULTIPATH_HST=m
CONFIG_DM_MULTIPATH_IOA=m
CONFIG_DM_DELAY=m
CONFIG_DM_DUST=m
CONFIG_DM_UEVENT=y
CONFIG_DM_FLAKEY=m
CONFIG_DM_VERITY=m
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y
CONFIG_DM_VERITY_FEC=y
CONFIG_DM_SWITCH=m
CONFIG_DM_LOG_WRITES=m
CONFIG_DM_INTEGRITY=m
CONFIG_DM_ZONED=m
CONFIG_DM_AUDIT=y
CONFIG_DM_PCACHE=m
CONFIG_TARGET_CORE=m
CONFIG_TCM_IBLOCK=m
CONFIG_TCM_FILEIO=m
CONFIG_TCM_PSCSI=m
CONFIG_TCM_USER2=m
CONFIG_LOOPBACK_TARGET=m
CONFIG_TCM_FC=m
CONFIG_ISCSI_TARGET=m
CONFIG_ISCSI_TARGET_CXGB4=m
CONFIG_SBP_TARGET=m
CONFIG_REMOTE_TARGET=m
CONFIG_FUSION=y
CONFIG_FUSION_SPI=m
CONFIG_FUSION_FC=m
CONFIG_FUSION_SAS=m
CONFIG_FUSION_MAX_SGE=128
CONFIG_FUSION_CTL=m
CONFIG_FUSION_LAN=m
CONFIG_FUSION_LOGGING=y
#
# IEEE 1394 (FireWire) support
#
CONFIG_FIREWIRE=m
CONFIG_FIREWIRE_KUNIT_UAPI_TEST=m
CONFIG_FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST=m
CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST=m
CONFIG_FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST=m
CONFIG_FIREWIRE_OHCI=m
CONFIG_FIREWIRE_KUNIT_OHCI_SERDES_TEST=m
CONFIG_FIREWIRE_SBP2=m
CONFIG_FIREWIRE_NET=m
CONFIG_FIREWIRE_NOSY=m
# end of IEEE 1394 (FireWire) support
CONFIG_MACINTOSH_DRIVERS=y
CONFIG_MAC_EMUMOUSEBTN=m
CONFIG_NETDEVICES=y
CONFIG_MII=m
CONFIG_NET_CORE=y
CONFIG_BONDING=m
CONFIG_DUMMY=m
CONFIG_WIREGUARD=m
CONFIG_WIREGUARD_DEBUG=y
CONFIG_OVPN=m
CONFIG_EQUALIZER=m
CONFIG_NET_FC=y
CONFIG_IFB=m
CONFIG_NET_TEAM=m
CONFIG_NET_TEAM_MODE_BROADCAST=m
CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
CONFIG_NET_TEAM_MODE_RANDOM=m
CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
CONFIG_NET_TEAM_MODE_LOADBALANCE=m
CONFIG_MACVLAN=m
CONFIG_MACVTAP=m
CONFIG_IPVLAN_L3S=y
CONFIG_IPVLAN=m
CONFIG_IPVTAP=m
CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_BAREUDP=m
CONFIG_GTP=m
CONFIG_PFCP=m
CONFIG_AMT=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_NETCONSOLE_EXTENDED_LOG=y
CONFIG_NETCONSOLE_PREPEND_RELEASE=y
CONFIG_NETPOLL=y
CONFIG_NET_POLL_CONTROLLER=y
CONFIG_NTB_NETDEV=m
CONFIG_RIONET=m
CONFIG_RIONET_TX_SIZE=128
CONFIG_RIONET_RX_SIZE=128
CONFIG_TUN=m
CONFIG_TAP=m
CONFIG_TUN_VNET_CROSS_LE=y
CONFIG_VETH=m
CONFIG_VIRTIO_NET=m
CONFIG_NLMON=m
CONFIG_NETKIT=y
CONFIG_NET_VRF=m
CONFIG_VSOCKMON=m
CONFIG_MHI_NET=m
CONFIG_SUNGEM_PHY=m
CONFIG_ARCNET=m
CONFIG_ARCNET_1201=m
CONFIG_ARCNET_1051=m
CONFIG_ARCNET_RAW=m
CONFIG_ARCNET_CAP=m
CONFIG_ARCNET_COM90xx=m
CONFIG_ARCNET_COM90xxIO=m
CONFIG_ARCNET_RIM_I=m
CONFIG_ARCNET_COM20020=m
CONFIG_ARCNET_COM20020_ISA=m
CONFIG_ARCNET_COM20020_PCI=m
CONFIG_ARCNET_COM20020_CS=m
CONFIG_ATM_DRIVERS=y
CONFIG_ATM_DUMMY=m
CONFIG_ATM_TCP=m
CONFIG_ATM_LANAI=m
CONFIG_ATM_ENI=m
CONFIG_ATM_ENI_DEBUG=y
CONFIG_ATM_ENI_TUNE_BURST=y
CONFIG_ATM_ENI_BURST_TX_16W=y
CONFIG_ATM_ENI_BURST_TX_8W=y
CONFIG_ATM_ENI_BURST_TX_4W=y
CONFIG_ATM_ENI_BURST_TX_2W=y
CONFIG_ATM_ENI_BURST_RX_16W=y
CONFIG_ATM_ENI_BURST_RX_8W=y
CONFIG_ATM_ENI_BURST_RX_4W=y
CONFIG_ATM_ENI_BURST_RX_2W=y
CONFIG_ATM_NICSTAR=m
CONFIG_ATM_NICSTAR_USE_SUNI=y
CONFIG_ATM_NICSTAR_USE_IDT77105=y
CONFIG_ATM_IDT77252=m
CONFIG_ATM_IDT77252_DEBUG=y
CONFIG_ATM_IDT77252_RCV_ALL=y
CONFIG_ATM_IDT77252_USE_SUNI=y
CONFIG_ATM_IA=m
CONFIG_ATM_IA_DEBUG=y
CONFIG_ATM_FORE200E=m
CONFIG_ATM_FORE200E_USE_TASKLET=y
CONFIG_ATM_FORE200E_TX_RETRY=16
CONFIG_ATM_FORE200E_DEBUG=0
CONFIG_ATM_HE=m
CONFIG_ATM_HE_USE_SUNI=y
CONFIG_ATM_SOLOS=m
CONFIG_CAIF_DRIVERS=y
CONFIG_CAIF_TTY=m
CONFIG_CAIF_VIRTIO=m
#
# Distributed Switch Architecture drivers
#
CONFIG_B53=m
CONFIG_B53_SPI_DRIVER=m
CONFIG_B53_MDIO_DRIVER=m
CONFIG_B53_MMAP_DRIVER=m
CONFIG_B53_SRAB_DRIVER=m
CONFIG_B53_SERDES=m
CONFIG_NET_DSA_BCM_SF2=m
CONFIG_NET_DSA_LOOP=m
CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK=m
CONFIG_NET_DSA_LANTIQ_COMMON=m
CONFIG_NET_DSA_LANTIQ_GSWIP=m
CONFIG_NET_DSA_MXL_GSW1XX=m
CONFIG_NET_DSA_MT7530=m
CONFIG_NET_DSA_MT7530_MDIO=m
CONFIG_NET_DSA_MT7530_MMIO=m
CONFIG_NET_DSA_MV88E6060=m
CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m
CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m
CONFIG_NET_DSA_MICROCHIP_KSZ_SPI=m
CONFIG_NET_DSA_MICROCHIP_KSZ_PTP=y
CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI=m
CONFIG_NET_DSA_MV88E6XXX=m
CONFIG_NET_DSA_MV88E6XXX_PTP=y
CONFIG_NET_DSA_MV88E6XXX_LEDS=y
CONFIG_NET_DSA_MXL862=m
CONFIG_NET_DSA_MSCC_FELIX_DSA_LIB=m
CONFIG_NET_DSA_MSCC_OCELOT_EXT=m
CONFIG_NET_DSA_MSCC_FELIX=m
CONFIG_NET_DSA_MSCC_SEVILLE=m
CONFIG_NET_DSA_AR9331=m
CONFIG_NET_DSA_QCA8K=m
CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT=y
CONFIG_NET_DSA_SJA1105=m
CONFIG_NET_DSA_SJA1105_PTP=y
CONFIG_NET_DSA_SJA1105_TAS=y
CONFIG_NET_DSA_SJA1105_VL=y
CONFIG_NET_DSA_XRS700X=m
CONFIG_NET_DSA_XRS700X_I2C=m
CONFIG_NET_DSA_XRS700X_MDIO=m
CONFIG_NET_DSA_REALTEK=m
CONFIG_NET_DSA_REALTEK_MDIO=y
CONFIG_NET_DSA_REALTEK_SMI=y
CONFIG_NET_DSA_REALTEK_RTL8365MB=m
CONFIG_NET_DSA_REALTEK_RTL8366RB=m
CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS=y
CONFIG_NET_DSA_RZN1_A5PSW=m
CONFIG_NET_DSA_KS8995=m
CONFIG_NET_DSA_SMSC_LAN9303=m
CONFIG_NET_DSA_SMSC_LAN9303_I2C=m
CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m
CONFIG_NET_DSA_VITESSE_VSC73XX=m
CONFIG_NET_DSA_VITESSE_VSC73XX_SPI=m
CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM=m
CONFIG_NET_DSA_YT921X=m
# end of Distributed Switch Architecture drivers
CONFIG_ETHERNET=y
CONFIG_MDIO=m
CONFIG_NET_VENDOR_3COM=y
CONFIG_EL3=m
CONFIG_3C515=m
CONFIG_PCMCIA_3C574=m
CONFIG_PCMCIA_3C589=m
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
CONFIG_NET_VENDOR_ACTIONS=y
CONFIG_OWL_EMAC=m
CONFIG_NET_VENDOR_ADAPTEC=y
CONFIG_ADAPTEC_STARFIRE=m
CONFIG_NET_VENDOR_AGERE=y
CONFIG_ET131X=m
CONFIG_NET_VENDOR_AIROHA=y
CONFIG_NET_AIROHA_NPU=m
CONFIG_NET_AIROHA=m
CONFIG_NET_AIROHA_FLOW_STATS=y
CONFIG_NET_VENDOR_ALACRITECH=y
CONFIG_SLICOSS=m
CONFIG_NET_VENDOR_ALTEON=y
CONFIG_ACENIC=m
CONFIG_ACENIC_OMIT_TIGON_I=y
CONFIG_ALTERA_TSE=m
CONFIG_NET_VENDOR_AMAZON=y
CONFIG_ENA_ETHERNET=m
CONFIG_NET_VENDOR_AMD=y
CONFIG_AMD8111_ETH=m
CONFIG_LANCE=m
CONFIG_PCNET32=m
CONFIG_PCMCIA_NMCLAN=m
CONFIG_AMD_XGBE=m
CONFIG_AMD_XGBE_DCB=y
CONFIG_AMD_XGBE_HAVE_ECC=y
CONFIG_NET_XGENE=m
CONFIG_NET_XGENE_V2=m
CONFIG_NET_VENDOR_AQUANTIA=y
CONFIG_AQTION=m
CONFIG_NET_VENDOR_ARC=y
CONFIG_ARC_EMAC_CORE=m
CONFIG_EMAC_ROCKCHIP=m
CONFIG_NET_VENDOR_ASIX=y
CONFIG_SPI_AX88796C=m
CONFIG_SPI_AX88796C_COMPRESSION=y
CONFIG_NET_VENDOR_ATHEROS=y
CONFIG_AG71XX=m
CONFIG_ATL2=m
CONFIG_ATL1=m
CONFIG_ATL1E=m
CONFIG_ATL1C=m
CONFIG_ALX=m
CONFIG_CX_ECAT=m
CONFIG_NET_VENDOR_BROADCOM=y
CONFIG_B44=m
CONFIG_B44_PCI_AUTOSELECT=y
CONFIG_B44_PCICORE_AUTOSELECT=y
CONFIG_B44_PCI=y
CONFIG_BCM4908_ENET=m
CONFIG_BCMGENET=m
CONFIG_BNX2=m
CONFIG_CNIC=m
CONFIG_TIGON3=m
CONFIG_TIGON3_HWMON=y
CONFIG_BNX2X=m
CONFIG_BNX2X_SRIOV=y
CONFIG_BGMAC=m
CONFIG_BGMAC_BCMA=m
CONFIG_BGMAC_PLATFORM=m
CONFIG_SYSTEMPORT=m
CONFIG_BNXT=m
CONFIG_BNXT_SRIOV=y
CONFIG_BNXT_FLOWER_OFFLOAD=y
CONFIG_BNXT_DCB=y
CONFIG_BNXT_HWMON=y
CONFIG_BNGE=m
CONFIG_BCMASP=m
CONFIG_NET_VENDOR_CADENCE=y
CONFIG_MACB=m
CONFIG_MACB_USE_HWSTAMP=y
CONFIG_MACB_PCI=m
CONFIG_NET_CALXEDA_XGMAC=m
CONFIG_NET_VENDOR_CAVIUM=y
CONFIG_NET_VENDOR_CHELSIO=y
CONFIG_CHELSIO_T1=m
CONFIG_CHELSIO_T1_1G=y
CONFIG_CHELSIO_T3=m
CONFIG_CHELSIO_T4=m
CONFIG_CHELSIO_T4_DCB=y
CONFIG_CHELSIO_T4_FCOE=y
CONFIG_CHELSIO_T4VF=m
CONFIG_CHELSIO_LIB=m
CONFIG_CHELSIO_INLINE_CRYPTO=y
CONFIG_CRYPTO_DEV_CHELSIO_TLS=m
CONFIG_CHELSIO_IPSEC_INLINE=m
CONFIG_CHELSIO_TLS_DEVICE=m
CONFIG_NET_VENDOR_CIRRUS=y
CONFIG_CS89x0=m
CONFIG_CS89x0_PLATFORM=m
CONFIG_EP93XX_ETH=m
CONFIG_NET_VENDOR_CISCO=y
CONFIG_ENIC=m
CONFIG_NET_VENDOR_CORTINA=y
CONFIG_GEMINI_ETHERNET=m
CONFIG_NET_VENDOR_DAVICOM=y
CONFIG_DM9000=m
CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
CONFIG_DM9051=m
CONFIG_NET_VENDOR_DEC=y
CONFIG_NET_TULIP=y
CONFIG_DE2104X=m
CONFIG_DE2104X_DSL=0
CONFIG_TULIP=m
CONFIG_TULIP_MWI=y
CONFIG_TULIP_MMIO=y
CONFIG_TULIP_NAPI=y
CONFIG_TULIP_NAPI_HW_MITIGATION=y
CONFIG_WINBOND_840=m
CONFIG_DM9102=m
CONFIG_ULI526X=m
CONFIG_PCMCIA_XIRCOM=m
CONFIG_NET_VENDOR_DLINK=y
CONFIG_DL2K=m
CONFIG_SUNDANCE=m
CONFIG_SUNDANCE_MMIO=y
CONFIG_NET_VENDOR_EMULEX=y
CONFIG_BE2NET=m
CONFIG_BE2NET_HWMON=y
CONFIG_BE2NET_BE2=y
CONFIG_BE2NET_BE3=y
CONFIG_BE2NET_LANCER=y
CONFIG_BE2NET_SKYHAWK=y
CONFIG_NET_VENDOR_ENGLEDER=y
CONFIG_TSNEP=m
CONFIG_TSNEP_SELFTESTS=y
CONFIG_NET_VENDOR_EZCHIP=y
CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=m
CONFIG_NET_VENDOR_FARADAY=y
CONFIG_FTMAC100=m
CONFIG_FTGMAC100=m
CONFIG_NET_VENDOR_FREESCALE=y
CONFIG_FEC=m
CONFIG_FSL_FMAN=m
CONFIG_FSL_PQ_MDIO=m
CONFIG_FSL_XGMAC_MDIO=m
CONFIG_GIANFAR=m
CONFIG_FSL_DPAA_ETH=m
CONFIG_FSL_DPAA2_ETH=m
CONFIG_FSL_DPAA2_ETH_DCB=y
CONFIG_FSL_DPAA2_PTP_CLOCK=m
CONFIG_FSL_DPAA2_SWITCH=m
CONFIG_FSL_ENETC_CORE=m
CONFIG_NXP_ENETC_PF_COMMON=m
CONFIG_NXP_NETC_LIB=m
CONFIG_NXP_NTMP=y
CONFIG_FSL_ENETC=m
CONFIG_NXP_ENETC4=m
CONFIG_FSL_ENETC_VF=m
CONFIG_FSL_ENETC_IERB=m
CONFIG_FSL_ENETC_MDIO=m
CONFIG_FSL_ENETC_PTP_CLOCK=m
CONFIG_FSL_ENETC_QOS=y
CONFIG_NXP_NETC_BLK_CTRL=m
CONFIG_NET_VENDOR_FUJITSU=y
CONFIG_PCMCIA_FMVJ18X=m
CONFIG_NET_VENDOR_FUNGIBLE=y
CONFIG_FUN_CORE=m
CONFIG_FUN_ETH=m
CONFIG_NET_VENDOR_GOOGLE=y
CONFIG_GVE=m
CONFIG_NET_VENDOR_HISILICON=y
CONFIG_HIX5HD2_GMAC=m
CONFIG_HISI_FEMAC=m
CONFIG_HIP04_ETH=m
CONFIG_HI13X1_GMAC=y
CONFIG_HNS_MDIO=m
CONFIG_HNS=m
CONFIG_HNS_DSAF=m
CONFIG_HNS_ENET=m
CONFIG_HNS3=m
CONFIG_HNS3_HCLGE=m
CONFIG_HNS3_DCB=y
CONFIG_HNS3_HCLGEVF=m
CONFIG_HIBMCGE=m
CONFIG_NET_VENDOR_HUAWEI=y
CONFIG_HINIC=m
CONFIG_NET_VENDOR_I825XX=y
CONFIG_NET_VENDOR_INTEL=y
CONFIG_LIBETH=m
CONFIG_LIBETH_XDP=m
CONFIG_LIBIE=m
CONFIG_LIBIE_ADMINQ=m
CONFIG_LIBIE_FWLOG=m
CONFIG_E100=m
CONFIG_E1000=m
CONFIG_E1000E=m
CONFIG_E1000E_HWTS=y
CONFIG_IGB=m
CONFIG_IGB_HWMON=y
CONFIG_IGBVF=m
CONFIG_IXGBE=m
CONFIG_IXGBE_HWMON=y
CONFIG_IXGBE_DCB=y
CONFIG_IXGBE_IPSEC=y
CONFIG_IXGBEVF=m
CONFIG_IXGBEVF_IPSEC=y
CONFIG_I40E=m
CONFIG_I40E_DCB=y
CONFIG_IAVF=m
CONFIG_I40EVF=m
CONFIG_ICE=m
CONFIG_ICE_HWMON=y
CONFIG_ICE_SWITCHDEV=y
CONFIG_ICE_HWTS=y
CONFIG_FM10K=m
CONFIG_IGC=m
CONFIG_IGC_LEDS=y
CONFIG_IDPF=m
CONFIG_IDPF_SINGLEQ=y
CONFIG_JME=m
CONFIG_KORINA=m
CONFIG_NET_VENDOR_ADI=y
CONFIG_ADIN1110=m
CONFIG_NET_VENDOR_LITEX=y
CONFIG_LITEX_LITEETH=m
CONFIG_NET_VENDOR_MARVELL=y
CONFIG_MV643XX_ETH=m
CONFIG_MVMDIO=m
CONFIG_MVNETA_BM_ENABLE=m
CONFIG_MVNETA=m
CONFIG_MVNETA_BM=m
CONFIG_MVPP2=m
CONFIG_MVPP2_PTP=y
CONFIG_PXA168_ETH=m
CONFIG_SKGE=m
CONFIG_SKGE_DEBUG=y
CONFIG_SKGE_GENESIS=y
CONFIG_SKY2=m
CONFIG_SKY2_DEBUG=y
CONFIG_PRESTERA=m
CONFIG_PRESTERA_PCI=m
CONFIG_NET_VENDOR_MEDIATEK=y
CONFIG_NET_MEDIATEK_SOC_WED=y
CONFIG_NET_MEDIATEK_SOC=m
CONFIG_NET_MEDIATEK_STAR_EMAC=m
CONFIG_NET_VENDOR_MELLANOX=y
CONFIG_MLX4_EN=m
CONFIG_MLX4_EN_DCB=y
CONFIG_MLX4_CORE=m
CONFIG_MLX4_DEBUG=y
CONFIG_MLX4_CORE_GEN2=y
CONFIG_MLX5_CORE=m
CONFIG_MLX5_FPGA=y
CONFIG_MLX5_CORE_EN=y
CONFIG_MLX5_EN_ARFS=y
CONFIG_MLX5_EN_RXNFC=y
CONFIG_MLX5_MPFS=y
CONFIG_MLX5_ESWITCH=y
CONFIG_MLX5_BRIDGE=y
CONFIG_MLX5_CLS_ACT=y
CONFIG_MLX5_TC_CT=y
CONFIG_MLX5_TC_SAMPLE=y
CONFIG_MLX5_CORE_EN_DCB=y
CONFIG_MLX5_CORE_IPOIB=y
CONFIG_MLX5_MACSEC=y
CONFIG_MLX5_EN_IPSEC=y
CONFIG_MLX5_EN_TLS=y
CONFIG_MLX5_SW_STEERING=y
CONFIG_MLX5_HW_STEERING=y
CONFIG_MLX5_SF=y
CONFIG_MLX5_SF_MANAGER=y
CONFIG_MLX5_DPLL=m
CONFIG_MLX5_EN_PSP=y
CONFIG_MLXSW_CORE=m
CONFIG_MLXSW_CORE_HWMON=y
CONFIG_MLXSW_CORE_THERMAL=y
CONFIG_MLXSW_PCI=m
CONFIG_MLXSW_I2C=m
CONFIG_MLXSW_SPECTRUM=m
CONFIG_MLXSW_SPECTRUM_DCB=y
CONFIG_MLXSW_MINIMAL=m
CONFIG_MLXFW=m
CONFIG_MLXBF_GIGE=m
CONFIG_NET_VENDOR_META=y
CONFIG_FBNIC=m
CONFIG_NET_VENDOR_MICREL=y
CONFIG_KS8842=m
CONFIG_KS8851=m
CONFIG_KS8851_MLL=m
CONFIG_KSZ884X_PCI=m
CONFIG_NET_VENDOR_MICROCHIP=y
CONFIG_ENC28J60=m
CONFIG_ENC28J60_WRITEVERIFY=y
CONFIG_ENCX24J600=m
CONFIG_LAN743X=m
CONFIG_LAN865X=m
CONFIG_LAN966X_SWITCH=m
CONFIG_LAN966X_DCB=y
CONFIG_SPARX5_SWITCH=m
CONFIG_SPARX5_DCB=y
CONFIG_LAN969X_SWITCH=y
CONFIG_VCAP=y
CONFIG_FDMA=y
CONFIG_NET_VENDOR_MICROSEMI=y
CONFIG_MSCC_OCELOT_SWITCH_LIB=m
CONFIG_MSCC_OCELOT_SWITCH=m
CONFIG_NET_VENDOR_MICROSOFT=y
CONFIG_NET_VENDOR_MUCSE=y
CONFIG_MGBE=m
CONFIG_NET_VENDOR_MYRI=y
CONFIG_MYRI10GE=m
CONFIG_FEALNX=m
CONFIG_NET_VENDOR_NI=y
CONFIG_NI_XGE_MANAGEMENT_ENET=m
CONFIG_NET_VENDOR_NATSEMI=y
CONFIG_NATSEMI=m
CONFIG_NS83820=m
CONFIG_NET_VENDOR_NETRONOME=y
CONFIG_NFP=m
CONFIG_NFP_APP_FLOWER=y
CONFIG_NFP_APP_ABM_NIC=y
CONFIG_NFP_NET_IPSEC=y
CONFIG_NFP_DEBUG=y
CONFIG_NET_VENDOR_8390=y
CONFIG_PCMCIA_AXNET=m
CONFIG_AX88796=m
CONFIG_AX88796_93CX6=y
CONFIG_NE2000=m
CONFIG_NE2K_PCI=m
CONFIG_PCMCIA_PCNET=m
CONFIG_ULTRA=m
CONFIG_WD80x3=m
CONFIG_NET_VENDOR_NVIDIA=y
CONFIG_FORCEDETH=m
CONFIG_LPC_ENET=m
CONFIG_NET_VENDOR_OKI=y
CONFIG_PCH_GBE=m
CONFIG_ETHOC=m
CONFIG_OA_TC6=m
CONFIG_NET_VENDOR_PACKET_ENGINES=y
CONFIG_HAMACHI=m
CONFIG_YELLOWFIN=m
CONFIG_NET_VENDOR_PENSANDO=y
CONFIG_NET_VENDOR_QLOGIC=y
CONFIG_QLA3XXX=m
CONFIG_QLCNIC=m
CONFIG_QLCNIC_SRIOV=y
CONFIG_QLCNIC_DCB=y
CONFIG_QLCNIC_HWMON=y
CONFIG_NETXEN_NIC=m
CONFIG_QED=m
CONFIG_QED_LL2=y
CONFIG_QED_SRIOV=y
CONFIG_QEDE=m
CONFIG_QED_ISCSI=y
CONFIG_QED_FCOE=y
CONFIG_QED_OOO=y
CONFIG_NET_VENDOR_BROCADE=y
CONFIG_BNA=m
CONFIG_NET_VENDOR_QUALCOMM=y
CONFIG_QCA7000=m
CONFIG_QCA7000_SPI=m
CONFIG_QCA7000_UART=m
CONFIG_QCOM_EMAC=m
CONFIG_QCOM_PPE=m
CONFIG_RMNET=m
CONFIG_NET_VENDOR_RDC=y
CONFIG_R6040=m
CONFIG_NET_VENDOR_REALTEK=y
CONFIG_8139CP=m
CONFIG_8139TOO=m
CONFIG_8139TOO_PIO=y
CONFIG_8139TOO_TUNE_TWISTER=y
CONFIG_8139TOO_8129=y
CONFIG_8139_OLD_RX_RESET=y
CONFIG_R8169=m
CONFIG_R8169_LEDS=y
CONFIG_RTASE=m
CONFIG_NET_VENDOR_RENESAS=y
CONFIG_SH_ETH=m
CONFIG_RAVB=m
CONFIG_RENESAS_ETHER_SWITCH=m
CONFIG_RENESAS_GEN4_PTP=m
CONFIG_RTSN=m
CONFIG_NET_VENDOR_ROCKER=y
CONFIG_ROCKER=m
CONFIG_NET_VENDOR_SAMSUNG=y
CONFIG_SXGBE_ETH=m
CONFIG_NET_VENDOR_SEEQ=y
CONFIG_NET_VENDOR_SILAN=y
CONFIG_SC92031=m
CONFIG_NET_VENDOR_SIS=y
CONFIG_SIS900=m
CONFIG_SIS190=m
CONFIG_NET_VENDOR_SOLARFLARE=y
CONFIG_SFC=m
CONFIG_SFC_MTD=y
CONFIG_SFC_MCDI_MON=y
CONFIG_SFC_SRIOV=y
CONFIG_SFC_MCDI_LOGGING=y
CONFIG_SFC_FALCON=m
CONFIG_SFC_FALCON_MTD=y
CONFIG_SFC_SIENA=m
CONFIG_SFC_SIENA_MTD=y
CONFIG_SFC_SIENA_MCDI_MON=y
CONFIG_SFC_SIENA_SRIOV=y
CONFIG_SFC_SIENA_MCDI_LOGGING=y
CONFIG_NET_VENDOR_SMSC=y
CONFIG_SMC9194=m
CONFIG_SMC91X=m
CONFIG_PCMCIA_SMC91C92=m
CONFIG_EPIC100=m
CONFIG_SMSC911X=m
CONFIG_SMSC9420=m
CONFIG_NET_VENDOR_SOCIONEXT=y
CONFIG_SNI_AVE=m
CONFIG_SNI_NETSEC=m
CONFIG_NET_VENDOR_SPACEMIT=y
CONFIG_SPACEMIT_K1_EMAC=m
CONFIG_NET_VENDOR_STMICRO=y
CONFIG_STMMAC_ETH=m
CONFIG_STMMAC_SELFTESTS=y
CONFIG_STMMAC_PLATFORM=m
CONFIG_DWMAC_DWC_QOS_ETH=m
CONFIG_DWMAC_GENERIC=m
CONFIG_DWMAC_ANARION=m
CONFIG_DWMAC_EIC7700=m
CONFIG_DWMAC_INGENIC=m
CONFIG_DWMAC_IPQ806X=m
CONFIG_DWMAC_LPC18XX=m
CONFIG_DWMAC_MEDIATEK=m
CONFIG_DWMAC_MESON=m
CONFIG_DWMAC_QCOM_ETHQOS=m
CONFIG_DWMAC_RENESAS_GBETH=m
CONFIG_DWMAC_ROCKCHIP=m
CONFIG_DWMAC_RZN1=m
CONFIG_DWMAC_S32=m
CONFIG_DWMAC_SOCFPGA=m
CONFIG_DWMAC_SOPHGO=m
CONFIG_DWMAC_STARFIVE=m
CONFIG_DWMAC_STI=m
CONFIG_DWMAC_STM32=m
CONFIG_DWMAC_SUNXI=m
CONFIG_DWMAC_SUN8I=m
CONFIG_DWMAC_SUN55I=m
CONFIG_DWMAC_THEAD=m
CONFIG_DWMAC_IMX8=m
CONFIG_DWMAC_INTEL_PLAT=m
CONFIG_DWMAC_LOONGSON1=m
CONFIG_DWMAC_TEGRA=m
CONFIG_DWMAC_VISCONTI=m
CONFIG_STMMAC_LIBPCI=m
CONFIG_DWMAC_INTEL=m
CONFIG_DWMAC_LOONGSON=m
CONFIG_DWMAC_MOTORCOMM=m
CONFIG_STMMAC_PCI=m
CONFIG_NET_VENDOR_SUN=y
CONFIG_HAPPYMEAL=m
CONFIG_SUNGEM=m
CONFIG_CASSINI=m
CONFIG_NIU=m
CONFIG_NET_VENDOR_SUNPLUS=y
CONFIG_SP7021_EMAC=m
CONFIG_NET_VENDOR_SYNOPSYS=y
CONFIG_DWC_XLGMAC=m
CONFIG_DWC_XLGMAC_PCI=m
CONFIG_NET_VENDOR_TEHUTI=y
CONFIG_TEHUTI=m
CONFIG_TEHUTI_TN40=m
CONFIG_NET_VENDOR_TI=y
CONFIG_TI_DAVINCI_EMAC=m
CONFIG_TI_DAVINCI_MDIO=m
CONFIG_TI_CPSW_PHY_SEL=y
CONFIG_TI_CPSW=m
CONFIG_TI_CPSW_SWITCHDEV=m
CONFIG_TI_CPTS=m
CONFIG_TLAN=m
CONFIG_TI_ICSS_IEP=m
CONFIG_TI_PRUETH=m
CONFIG_NET_VENDOR_VERTEXCOM=y
CONFIG_MSE102X=m
CONFIG_NET_VENDOR_VIA=y
CONFIG_VIA_RHINE=m
CONFIG_VIA_RHINE_MMIO=y
CONFIG_VIA_VELOCITY=m
CONFIG_NET_VENDOR_WANGXUN=y
CONFIG_LIBWX=m
CONFIG_NGBE=m
CONFIG_TXGBE=m
CONFIG_TXGBEVF=m
CONFIG_NGBEVF=m
CONFIG_NET_VENDOR_WIZNET=y
CONFIG_WIZNET_W5100=m
CONFIG_WIZNET_W5300=m
# CONFIG_WIZNET_BUS_DIRECT is not set
# CONFIG_WIZNET_BUS_INDIRECT is not set
CONFIG_WIZNET_BUS_ANY=y
CONFIG_WIZNET_W5100_SPI=m
CONFIG_NET_VENDOR_XILINX=y
CONFIG_XILINX_EMACLITE=m
CONFIG_XILINX_AXI_EMAC=m
CONFIG_XILINX_LL_TEMAC=m
CONFIG_NET_VENDOR_XIRCOM=y
CONFIG_PCMCIA_XIRC2PS=m
CONFIG_FDDI=m
CONFIG_DEFXX=m
CONFIG_SKFP=m
CONFIG_QCOM_IPA=m
CONFIG_MDIO_BUS=m
CONFIG_PHYLINK=m
CONFIG_PHYLIB=m
CONFIG_SWPHY=y
CONFIG_PHY_PACKAGE=m
CONFIG_LED_TRIGGER_PHY=y
CONFIG_OPEN_ALLIANCE_HELPERS=y
CONFIG_PHYLIB_LEDS=y
CONFIG_FIXED_PHY=m
CONFIG_SFP=m
#
# MII PHY device drivers
#
CONFIG_AS21XXX_PHY=m
CONFIG_AIR_EN8811H_PHY=m
CONFIG_AMD_PHY=m
CONFIG_MESON_GXL_PHY=m
CONFIG_ADIN_PHY=m
CONFIG_ADIN1100_PHY=m
CONFIG_AQUANTIA_PHY=m
CONFIG_AX88796B_PHY=m
CONFIG_BROADCOM_PHY=m
CONFIG_BCM54140_PHY=m
CONFIG_BCM63XX_PHY=m
CONFIG_BCM7XXX_PHY=m
CONFIG_BCM84881_PHY=m
CONFIG_BCM87XX_PHY=m
CONFIG_BCM_CYGNUS_PHY=m
CONFIG_BCM_NET_PHYLIB=m
CONFIG_BCM_NET_PHYPTP=m
CONFIG_CICADA_PHY=m
CONFIG_CORTINA_PHY=m
CONFIG_DAVICOM_PHY=m
CONFIG_ICPLUS_PHY=m
CONFIG_LXT_PHY=m
CONFIG_INTEL_XWAY_PHY=m
CONFIG_LSI_ET1011C_PHY=m
CONFIG_MARVELL_PHY=m
CONFIG_MARVELL_10G_PHY=m
CONFIG_MARVELL_88Q2XXX_PHY=m
CONFIG_MARVELL_88X2222_PHY=m
CONFIG_MAXLINEAR_GPHY=m
CONFIG_MAXLINEAR_86110_PHY=m
CONFIG_MEDIATEK_2P5GE_PHY=m
CONFIG_MEDIATEK_GE_PHY=m
CONFIG_MEDIATEK_GE_SOC_PHY=m
CONFIG_MTK_NET_PHYLIB=m
CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_T1S_PHY=m
CONFIG_MICROCHIP_PHY=m
CONFIG_MICROCHIP_T1_PHY=m
CONFIG_MICROCHIP_PHY_RDS_PTP=m
CONFIG_MICROSEMI_PHY=m
CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
CONFIG_NXP_CBTX_PHY=m
CONFIG_NXP_C45_TJA11XX_PHY=m
CONFIG_NXP_TJA11XX_PHY=m
CONFIG_NCN26000_PHY=m
CONFIG_QCOM_NET_PHYLIB=m
CONFIG_AT803X_PHY=m
CONFIG_QCA83XX_PHY=m
CONFIG_QCA808X_PHY=m
CONFIG_QCA807X_PHY=m
CONFIG_QSEMI_PHY=m
CONFIG_REALTEK_PHY=m
CONFIG_REALTEK_PHY_HWMON=y
CONFIG_RENESAS_PHY=m
CONFIG_ROCKCHIP_PHY=m
CONFIG_SMSC_PHY=m
CONFIG_STE10XP=m
CONFIG_TERANETICS_PHY=m
CONFIG_DP83822_PHY=m
CONFIG_DP83TC811_PHY=m
CONFIG_DP83848_PHY=m
CONFIG_DP83867_PHY=m
CONFIG_DP83869_PHY=m
CONFIG_DP83TD510_PHY=m
CONFIG_DP83TG720_PHY=m
CONFIG_VITESSE_PHY=m
CONFIG_XILINX_GMII2RGMII=m
CONFIG_PSE_CONTROLLER=y
CONFIG_PSE_REGULATOR=m
CONFIG_PSE_PD692X0=m
CONFIG_PSE_SI3474=m
CONFIG_PSE_TPS23881=m
CONFIG_CAN_DEV=m
CONFIG_CAN_VCAN=m
CONFIG_CAN_VXCAN=m
CONFIG_CAN_NETLINK=y
CONFIG_CAN_CALC_BITTIMING=y
CONFIG_CAN_RX_OFFLOAD=y
CONFIG_CAN_AT91=m
CONFIG_CAN_BXCAN=m
CONFIG_CAN_CAN327=m
CONFIG_CAN_DUMMY=m
CONFIG_CAN_FLEXCAN=m
CONFIG_CAN_GRCAN=m
CONFIG_CAN_JANZ_ICAN3=m
CONFIG_CAN_KVASER_PCIEFD=m
CONFIG_CAN_SLCAN=m
CONFIG_CAN_SUN4I=m
CONFIG_CAN_TI_HECC=m
CONFIG_CAN_XILINXCAN=m
CONFIG_CAN_C_CAN=m
CONFIG_CAN_C_CAN_PLATFORM=m
CONFIG_CAN_C_CAN_PCI=m
CONFIG_CAN_CC770=m
CONFIG_CAN_CC770_ISA=m
CONFIG_CAN_CC770_PLATFORM=m
CONFIG_CAN_CTUCANFD=m
CONFIG_CAN_CTUCANFD_PCI=m
CONFIG_CAN_CTUCANFD_PLATFORM=m
CONFIG_CAN_ESD_402_PCI=m
CONFIG_CAN_IFI_CANFD=m
CONFIG_CAN_M_CAN=m
CONFIG_CAN_M_CAN_PCI=m
CONFIG_CAN_M_CAN_PLATFORM=m
CONFIG_CAN_M_CAN_TCAN4X5X=m
CONFIG_CAN_PEAK_PCIEFD=m
CONFIG_CAN_RCAR=m
CONFIG_CAN_RCAR_CANFD=m
CONFIG_CAN_ROCKCHIP_CANFD=m
CONFIG_CAN_SJA1000=m
CONFIG_CAN_EMS_PCI=m
CONFIG_CAN_EMS_PCMCIA=m
CONFIG_CAN_F81601=m
CONFIG_CAN_KVASER_PCI=m
CONFIG_CAN_PEAK_PCI=m
CONFIG_CAN_PEAK_PCIEC=y
CONFIG_CAN_PEAK_PCMCIA=m
CONFIG_CAN_PLX_PCI=m
CONFIG_CAN_SJA1000_ISA=m
CONFIG_CAN_SJA1000_PLATFORM=m
CONFIG_CAN_TSCAN1=m
CONFIG_CAN_SOFTING=m
CONFIG_CAN_SOFTING_CS=m
#
# CAN SPI interfaces
#
CONFIG_CAN_HI311X=m
CONFIG_CAN_MCP251X=m
CONFIG_CAN_MCP251XFD=m
CONFIG_CAN_MCP251XFD_SANITY=y
# end of CAN SPI interfaces
#
# CAN USB interfaces
#
CONFIG_CAN_8DEV_USB=m
CONFIG_CAN_EMS_USB=m
CONFIG_CAN_ESD_USB=m
CONFIG_CAN_ETAS_ES58X=m
CONFIG_CAN_F81604=m
CONFIG_CAN_GS_USB=m
CONFIG_CAN_KVASER_USB=m
CONFIG_CAN_MCBA_USB=m
CONFIG_CAN_NCT6694=m
CONFIG_CAN_PEAK_USB=m
CONFIG_CAN_UCAN=m
# end of CAN USB interfaces
CONFIG_CAN_DEBUG_DEVICES=y
#
# MCTP Device Drivers
#
CONFIG_MCTP_SERIAL=m
CONFIG_MCTP_TRANSPORT_I2C=m
CONFIG_MCTP_TRANSPORT_I3C=m
CONFIG_MCTP_TRANSPORT_USB=m
# end of MCTP Device Drivers
CONFIG_FWNODE_MDIO=m
CONFIG_OF_MDIO=m
CONFIG_ACPI_MDIO=m
CONFIG_MDIO_AIROHA=m
CONFIG_MDIO_SUN4I=m
CONFIG_MDIO_XGENE=m
CONFIG_MDIO_ASPEED=m
CONFIG_MDIO_BITBANG=m
CONFIG_MDIO_BCM_IPROC=m
CONFIG_MDIO_BCM_UNIMAC=m
CONFIG_MDIO_CAVIUM=m
CONFIG_MDIO_GPIO=m
CONFIG_MDIO_HISI_FEMAC=m
CONFIG_MDIO_I2C=m
CONFIG_MDIO_MVUSB=m
CONFIG_MDIO_MSCC_MIIM=m
CONFIG_MDIO_MOXART=m
CONFIG_MDIO_OCTEON=m
CONFIG_MDIO_IPQ4019=m
CONFIG_MDIO_IPQ8064=m
CONFIG_MDIO_REALTEK_RTL9300=m
CONFIG_MDIO_REGMAP=m
#
# MDIO Multiplexers
#
CONFIG_MDIO_BUS_MUX=m
CONFIG_MDIO_BUS_MUX_MESON_G12A=m
CONFIG_MDIO_BUS_MUX_MESON_GXL=m
CONFIG_MDIO_BUS_MUX_BCM6368=m
CONFIG_MDIO_BUS_MUX_BCM_IPROC=m
CONFIG_MDIO_BUS_MUX_GPIO=m
CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m
CONFIG_MDIO_BUS_MUX_MMIOREG=m
#
# PCS device drivers
#
CONFIG_PCS_XPCS=m
CONFIG_PCS_LYNX=m
CONFIG_PCS_MTK_LYNXI=m
CONFIG_PCS_RZN1_MIIC=m
# end of PCS device drivers
CONFIG_PLIP=m
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=m
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOATM=m
CONFIG_PPPOE=m
# CONFIG_PPPOE_HASH_BITS_1 is not set
# CONFIG_PPPOE_HASH_BITS_2 is not set
CONFIG_PPPOE_HASH_BITS_4=y
# CONFIG_PPPOE_HASH_BITS_8 is not set
CONFIG_PPPOE_HASH_BITS=4
CONFIG_PPTP=m
CONFIG_PPPOL2TP=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_SLIP=m
CONFIG_SLHC=m
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y
#
# Host-side USB support is needed for USB Network Adapter support
#
CONFIG_USB_NET_DRIVERS=m
CONFIG_USB_CATC=m
CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_RTL8152=m
CONFIG_USB_LAN78XX=m
CONFIG_USB_USBNET=m
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_AX88179_178A=m
CONFIG_USB_NET_CDCETHER=m
CONFIG_USB_NET_CDC_EEM=m
CONFIG_USB_NET_CDC_NCM=m
CONFIG_USB_NET_HUAWEI_CDC_NCM=m
CONFIG_USB_NET_CDC_MBIM=m
CONFIG_USB_NET_DM9601=m
CONFIG_USB_NET_SR9700=m
CONFIG_USB_NET_SR9800=m
CONFIG_USB_NET_SMSC75XX=m
CONFIG_USB_NET_SMSC95XX=m
CONFIG_USB_NET_GL620A=m
CONFIG_USB_NET_NET1080=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
CONFIG_USB_NET_RNDIS_HOST=m
CONFIG_USB_NET_CDC_SUBSET_ENABLE=m
CONFIG_USB_NET_CDC_SUBSET=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_BELKIN=y
CONFIG_USB_ARMLINUX=y
CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_USB_NET_ZAURUS=m
CONFIG_USB_NET_CX82310_ETH=m
CONFIG_USB_NET_KALMIA=m
CONFIG_USB_NET_QMI_WWAN=m
CONFIG_USB_HSO=m
CONFIG_USB_NET_INT51X1=m
CONFIG_USB_CDC_PHONET=m
CONFIG_USB_IPHETH=m
CONFIG_USB_SIERRA_NET=m
CONFIG_USB_VL600=m
CONFIG_USB_NET_CH9200=m
CONFIG_USB_NET_AQC111=m
CONFIG_USB_RTL8153_ECM=m
CONFIG_WLAN=y
CONFIG_WLAN_VENDOR_ADMTEK=y
CONFIG_ADM8211=m
CONFIG_ATH_COMMON=m
CONFIG_WLAN_VENDOR_ATH=y
CONFIG_ATH_DEBUG=y
CONFIG_ATH_TRACEPOINTS=y
CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y
CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING=y
CONFIG_ATH5K=m
CONFIG_ATH5K_DEBUG=y
CONFIG_ATH5K_TRACER=y
CONFIG_ATH5K_PCI=y
CONFIG_ATH5K_TEST_CHANNELS=y
CONFIG_ATH9K_HW=m
CONFIG_ATH9K_COMMON=m
CONFIG_ATH9K_COMMON_DEBUG=y
CONFIG_ATH9K_DFS_DEBUGFS=y
CONFIG_ATH9K_BTCOEX_SUPPORT=y
CONFIG_ATH9K=m
CONFIG_ATH9K_PCI=y
CONFIG_ATH9K_AHB=y
CONFIG_ATH9K_DEBUGFS=y
CONFIG_ATH9K_STATION_STATISTICS=y
CONFIG_ATH9K_TX99=y
CONFIG_ATH9K_DFS_CERTIFIED=y
CONFIG_ATH9K_DYNACK=y
CONFIG_ATH9K_WOW=y
CONFIG_ATH9K_RFKILL=y
CONFIG_ATH9K_CHANNEL_CONTEXT=y
CONFIG_ATH9K_PCOEM=y
CONFIG_ATH9K_PCI_NO_EEPROM=m
CONFIG_ATH9K_HTC=m
CONFIG_ATH9K_HTC_DEBUGFS=y
CONFIG_ATH9K_HWRNG=y
CONFIG_ATH9K_COMMON_SPECTRAL=y
CONFIG_CARL9170=m
CONFIG_CARL9170_LEDS=y
CONFIG_CARL9170_DEBUGFS=y
CONFIG_CARL9170_WPC=y
CONFIG_CARL9170_HWRNG=y
CONFIG_ATH6KL=m
CONFIG_ATH6KL_SDIO=m
CONFIG_ATH6KL_USB=m
CONFIG_ATH6KL_DEBUG=y
CONFIG_ATH6KL_TRACING=y
CONFIG_ATH6KL_REGDOMAIN=y
CONFIG_AR5523=m
CONFIG_WIL6210=m
CONFIG_WIL6210_ISR_COR=y
CONFIG_WIL6210_TRACING=y
CONFIG_WIL6210_DEBUGFS=y
CONFIG_ATH10K=m
CONFIG_ATH10K_CE=y
CONFIG_ATH10K_PCI=m
CONFIG_ATH10K_AHB=y
CONFIG_ATH10K_SDIO=m
CONFIG_ATH10K_USB=m
CONFIG_ATH10K_SNOC=m
CONFIG_ATH10K_DEBUG=y
CONFIG_ATH10K_DEBUGFS=y
CONFIG_ATH10K_LEDS=y
CONFIG_ATH10K_SPECTRAL=y
CONFIG_ATH10K_TRACING=y
CONFIG_ATH10K_DFS_CERTIFIED=y
CONFIG_WCN36XX=m
CONFIG_WCN36XX_DEBUGFS=y
CONFIG_ATH11K=m
CONFIG_ATH11K_AHB=m
CONFIG_ATH11K_PCI=m
CONFIG_ATH11K_DEBUG=y
CONFIG_ATH11K_DEBUGFS=y
CONFIG_ATH11K_TRACING=y
CONFIG_ATH11K_SPECTRAL=y
CONFIG_ATH11K_CFR=y
CONFIG_ATH12K=m
CONFIG_ATH12K_AHB=y
CONFIG_ATH12K_DEBUG=y
CONFIG_ATH12K_DEBUGFS=y
CONFIG_ATH12K_TRACING=y
CONFIG_ATH12K_COREDUMP=y
CONFIG_WLAN_VENDOR_ATMEL=y
CONFIG_AT76C50X_USB=m
CONFIG_WLAN_VENDOR_BROADCOM=y
CONFIG_B43=m
CONFIG_B43_BCMA=y
CONFIG_B43_SSB=y
CONFIG_B43_BUSES_BCMA_AND_SSB=y
# CONFIG_B43_BUSES_BCMA is not set
# CONFIG_B43_BUSES_SSB is not set
CONFIG_B43_PCI_AUTOSELECT=y
CONFIG_B43_PCICORE_AUTOSELECT=y
CONFIG_B43_SDIO=y
CONFIG_B43_BCMA_PIO=y
CONFIG_B43_PIO=y
CONFIG_B43_PHY_G=y
CONFIG_B43_PHY_N=y
CONFIG_B43_PHY_LP=y
CONFIG_B43_PHY_HT=y
CONFIG_B43_LEDS=y
CONFIG_B43_HWRNG=y
CONFIG_B43_DEBUG=y
CONFIG_B43LEGACY=m
CONFIG_B43LEGACY_PCI_AUTOSELECT=y
CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
CONFIG_B43LEGACY_LEDS=y
CONFIG_B43LEGACY_HWRNG=y
CONFIG_B43LEGACY_DEBUG=y
CONFIG_B43LEGACY_DMA=y
CONFIG_B43LEGACY_PIO=y
CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
# CONFIG_B43LEGACY_DMA_MODE is not set
# CONFIG_B43LEGACY_PIO_MODE is not set
CONFIG_BRCMUTIL=m
CONFIG_BRCMSMAC=m
CONFIG_BRCMSMAC_LEDS=y
CONFIG_BRCMFMAC=m
CONFIG_BRCMFMAC_PROTO_BCDC=y
CONFIG_BRCMFMAC_PROTO_MSGBUF=y
CONFIG_BRCMFMAC_SDIO=y
CONFIG_BRCMFMAC_USB=y
CONFIG_BRCMFMAC_PCIE=y
CONFIG_BRCM_TRACING=y
CONFIG_BRCMDBG=y
CONFIG_WLAN_VENDOR_INTEL=y
CONFIG_IPW2100=m
CONFIG_IPW2100_MONITOR=y
CONFIG_IPW2100_DEBUG=y
CONFIG_IPW2200=m
CONFIG_IPW2200_MONITOR=y
CONFIG_IPW2200_RADIOTAP=y
CONFIG_IPW2200_PROMISCUOUS=y
CONFIG_IPW2200_QOS=y
CONFIG_IPW2200_DEBUG=y
CONFIG_LIBIPW=m
CONFIG_LIBIPW_DEBUG=y
CONFIG_IWLEGACY=m
CONFIG_IWL4965=m
CONFIG_IWL3945=m
#
# iwl3945 / iwl4965 Debugging Options
#
CONFIG_IWLEGACY_DEBUG=y
CONFIG_IWLEGACY_DEBUGFS=y
# end of iwl3945 / iwl4965 Debugging Options
CONFIG_IWLWIFI=m
CONFIG_IWLWIFI_KUNIT_TESTS=m
CONFIG_IWLWIFI_LEDS=y
CONFIG_IWLDVM=m
CONFIG_IWLMVM=m
CONFIG_IWLMLD=m
CONFIG_IWLWIFI_OPMODE_MODULAR=y
#
# Debugging Options
#
CONFIG_IWLWIFI_DEBUG=y
CONFIG_IWLWIFI_DEBUGFS=y
CONFIG_IWLWIFI_DEVICE_TRACING=y
# end of Debugging Options
CONFIG_WLAN_VENDOR_INTERSIL=y
CONFIG_P54_COMMON=m
CONFIG_P54_USB=m
CONFIG_P54_PCI=m
CONFIG_P54_SPI=m
CONFIG_P54_SPI_DEFAULT_EEPROM=y
CONFIG_P54_LEDS=y
CONFIG_WLAN_VENDOR_MARVELL=y
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
CONFIG_LIBERTAS_SDIO=m
CONFIG_LIBERTAS_SPI=m
CONFIG_LIBERTAS_DEBUG=y
CONFIG_LIBERTAS_MESH=y
CONFIG_LIBERTAS_THINFIRM=m
CONFIG_LIBERTAS_THINFIRM_DEBUG=y
CONFIG_LIBERTAS_THINFIRM_USB=m
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
CONFIG_MWIFIEX_PCIE=m
CONFIG_MWIFIEX_USB=m
CONFIG_MWL8K=m
CONFIG_WLAN_VENDOR_MEDIATEK=y
CONFIG_MT7601U=m
CONFIG_MT76_CORE=m
CONFIG_MT76_LEDS=y
CONFIG_MT76_USB=m
CONFIG_MT76_SDIO=m
CONFIG_MT76x02_LIB=m
CONFIG_MT76x02_USB=m
CONFIG_MT76_CONNAC_LIB=m
CONFIG_MT792x_LIB=m
CONFIG_MT792x_USB=m
CONFIG_MT76_NPU=y
CONFIG_MT76x0_COMMON=m
CONFIG_MT76x0U=m
CONFIG_MT76x0E=m
CONFIG_MT76x2_COMMON=m
CONFIG_MT76x2E=m
CONFIG_MT76x2U=m
CONFIG_MT7603E=m
CONFIG_MT7615_COMMON=m
CONFIG_MT7615E=m
CONFIG_MT7622_WMAC=y
CONFIG_MT7663_USB_SDIO_COMMON=m
CONFIG_MT7663U=m
CONFIG_MT7663S=m
CONFIG_MT7915E=m
CONFIG_MT798X_WMAC=y
CONFIG_MT7921_COMMON=m
CONFIG_MT7921E=m
CONFIG_MT7921S=m
CONFIG_MT7921U=m
CONFIG_MT7996E=m
CONFIG_MT7996_NPU=y
CONFIG_MT7925_COMMON=m
CONFIG_MT7925E=m
CONFIG_MT7925U=m
CONFIG_WLAN_VENDOR_MICROCHIP=y
CONFIG_WILC1000=m
CONFIG_WILC1000_SDIO=m
CONFIG_WILC1000_SPI=m
CONFIG_WILC1000_HW_OOB_INTR=y
CONFIG_WLAN_VENDOR_PURELIFI=y
CONFIG_PLFXLC=m
CONFIG_WLAN_VENDOR_RALINK=y
CONFIG_RT2X00=m
CONFIG_RT2400PCI=m
CONFIG_RT2500PCI=m
CONFIG_RT61PCI=m
CONFIG_RT2800PCI=m
CONFIG_RT2800PCI_RT33XX=y
CONFIG_RT2800PCI_RT35XX=y
CONFIG_RT2800PCI_RT53XX=y
CONFIG_RT2800PCI_RT3290=y
CONFIG_RT2500USB=m
CONFIG_RT73USB=m
CONFIG_RT2800USB=m
CONFIG_RT2800USB_RT33XX=y
CONFIG_RT2800USB_RT35XX=y
CONFIG_RT2800USB_RT3573=y
CONFIG_RT2800USB_RT53XX=y
CONFIG_RT2800USB_RT55XX=y
CONFIG_RT2800USB_UNKNOWN=y
CONFIG_RT2800SOC=m
CONFIG_RT2800_LIB=m
CONFIG_RT2800_LIB_MMIO=m
CONFIG_RT2X00_LIB_MMIO=m
CONFIG_RT2X00_LIB_PCI=m
CONFIG_RT2X00_LIB_USB=m
CONFIG_RT2X00_LIB=m
CONFIG_RT2X00_LIB_FIRMWARE=y
CONFIG_RT2X00_LIB_CRYPTO=y
CONFIG_RT2X00_LIB_LEDS=y
CONFIG_RT2X00_LIB_DEBUGFS=y
CONFIG_RT2X00_DEBUG=y
CONFIG_WLAN_VENDOR_REALTEK=y
CONFIG_RTL8180=m
CONFIG_RTL8187=m
CONFIG_RTL8187_LEDS=y
CONFIG_RTL_CARDS=m
CONFIG_RTL8192CE=m
CONFIG_RTL8192SE=m
CONFIG_RTL8192DE=m
CONFIG_RTL8723AE=m
CONFIG_RTL8723BE=m
CONFIG_RTL8188EE=m
CONFIG_RTL8192EE=m
CONFIG_RTL8821AE=m
CONFIG_RTL8192CU=m
CONFIG_RTL8192DU=m
CONFIG_RTLWIFI=m
CONFIG_RTLWIFI_PCI=m
CONFIG_RTLWIFI_USB=m
CONFIG_RTLWIFI_DEBUG=y
CONFIG_RTL8192C_COMMON=m
CONFIG_RTL8192D_COMMON=m
CONFIG_RTL8723_COMMON=m
CONFIG_RTLBTCOEXIST=m
CONFIG_RTL8XXXU=m
CONFIG_RTL8XXXU_UNTESTED=y
CONFIG_RTW88=m
CONFIG_RTW88_CORE=m
CONFIG_RTW88_PCI=m
CONFIG_RTW88_SDIO=m
CONFIG_RTW88_USB=m
CONFIG_RTW88_8822B=m
CONFIG_RTW88_8822C=m
CONFIG_RTW88_8723X=m
CONFIG_RTW88_8703B=m
CONFIG_RTW88_8723D=m
CONFIG_RTW88_8821C=m
CONFIG_RTW88_88XXA=m
CONFIG_RTW88_8821A=m
CONFIG_RTW88_8812A=m
CONFIG_RTW88_8814A=m
CONFIG_RTW88_8822BE=m
CONFIG_RTW88_8822BS=m
CONFIG_RTW88_8822BU=m
CONFIG_RTW88_8822CE=m
CONFIG_RTW88_8822CS=m
CONFIG_RTW88_8822CU=m
CONFIG_RTW88_8723DE=m
CONFIG_RTW88_8723DS=m
CONFIG_RTW88_8723CS=m
CONFIG_RTW88_8723DU=m
CONFIG_RTW88_8821CE=m
CONFIG_RTW88_8821CS=m
CONFIG_RTW88_8821CU=m
CONFIG_RTW88_8821AU=m
CONFIG_RTW88_8812AU=m
CONFIG_RTW88_8814AE=m
CONFIG_RTW88_8814AU=m
CONFIG_RTW88_DEBUG=y
CONFIG_RTW88_DEBUGFS=y
CONFIG_RTW88_LEDS=y
CONFIG_RTW89=m
CONFIG_RTW89_CORE=m
CONFIG_RTW89_PCI=m
CONFIG_RTW89_USB=m
CONFIG_RTW89_8851B=m
CONFIG_RTW89_8852A=m
CONFIG_RTW89_8852B_COMMON=m
CONFIG_RTW89_8852B=m
CONFIG_RTW89_8852BT=m
CONFIG_RTW89_8852C=m
CONFIG_RTW89_8922A=m
CONFIG_RTW89_8851BE=m
CONFIG_RTW89_8851BU=m
CONFIG_RTW89_8852AE=m
CONFIG_RTW89_8852AU=m
CONFIG_RTW89_8852BE=m
CONFIG_RTW89_8852BU=m
CONFIG_RTW89_8852BTE=m
CONFIG_RTW89_8852CE=m
CONFIG_RTW89_8852CU=m
CONFIG_RTW89_8922AE=m
CONFIG_RTW89_DEBUG=y
CONFIG_RTW89_DEBUGMSG=y
CONFIG_RTW89_DEBUGFS=y
CONFIG_WLAN_VENDOR_RSI=y
CONFIG_RSI_91X=m
CONFIG_RSI_DEBUGFS=y
CONFIG_RSI_SDIO=m
CONFIG_RSI_USB=m
CONFIG_RSI_COEX=y
CONFIG_WLAN_VENDOR_SILABS=y
CONFIG_WFX=m
CONFIG_WLAN_VENDOR_ST=y
CONFIG_CW1200=m
CONFIG_CW1200_WLAN_SDIO=m
CONFIG_CW1200_WLAN_SPI=m
CONFIG_WLAN_VENDOR_TI=y
CONFIG_WL1251=m
CONFIG_WL1251_SPI=m
CONFIG_WL1251_SDIO=m
CONFIG_WL12XX=m
CONFIG_WL18XX=m
CONFIG_WLCORE=m
CONFIG_WLCORE_SPI=m
CONFIG_WLCORE_SDIO=m
CONFIG_WLAN_VENDOR_ZYDAS=y
CONFIG_ZD1211RW=m
CONFIG_ZD1211RW_DEBUG=y
CONFIG_WLAN_VENDOR_QUANTENNA=y
CONFIG_QTNFMAC=m
CONFIG_QTNFMAC_PCIE=m
CONFIG_MAC80211_HWSIM=m
CONFIG_VIRT_WIFI=m
CONFIG_WAN=y
CONFIG_HDLC=m
CONFIG_HDLC_RAW=m
CONFIG_HDLC_RAW_ETH=m
CONFIG_HDLC_CISCO=m
CONFIG_HDLC_FR=m
CONFIG_HDLC_PPP=m
CONFIG_HDLC_X25=m
CONFIG_FRAMER=m
CONFIG_GENERIC_FRAMER=y
CONFIG_FRAMER_PEF2256=m
CONFIG_PCI200SYN=m
CONFIG_WANXL=m
CONFIG_PC300TOO=m
CONFIG_N2=m
CONFIG_C101=m
CONFIG_FARSYNC=m
CONFIG_FSL_UCC_HDLC=m
CONFIG_SLIC_DS26522=m
CONFIG_LAPBETHER=m
CONFIG_IEEE802154_DRIVERS=m
CONFIG_IEEE802154_FAKELB=m
CONFIG_IEEE802154_AT86RF230=m
CONFIG_IEEE802154_MRF24J40=m
CONFIG_IEEE802154_CC2520=m
CONFIG_IEEE802154_ATUSB=m
CONFIG_IEEE802154_ADF7242=m
CONFIG_IEEE802154_CA8210=m
CONFIG_IEEE802154_CA8210_DEBUGFS=y
CONFIG_IEEE802154_MCR20A=m
CONFIG_IEEE802154_HWSIM=m
#
# Wireless WAN
#
CONFIG_WWAN=m
CONFIG_WWAN_DEBUGFS=y
CONFIG_WWAN_HWSIM=m
CONFIG_MHI_WWAN_CTRL=m
CONFIG_MHI_WWAN_MBIM=m
CONFIG_QCOM_BAM_DMUX=m
CONFIG_RPMSG_WWAN_CTRL=m
CONFIG_IOSM=m
CONFIG_MTK_T7XX=m
# end of Wireless WAN
CONFIG_XEN_NETDEV_FRONTEND=m
CONFIG_XEN_NETDEV_BACKEND=m
CONFIG_VMXNET3=m
CONFIG_FUJITSU_ES=m
CONFIG_USB4_NET=m
CONFIG_HYPERV_NET=m
CONFIG_NETDEVSIM=m
CONFIG_NET_FAILOVER=m
CONFIG_NETDEV_LEGACY_INIT=y
CONFIG_ISDN=y
CONFIG_ISDN_CAPI=y
CONFIG_MISDN=m
CONFIG_MISDN_DSP=m
CONFIG_MISDN_L1OIP=m
#
# mISDN hardware drivers
#
CONFIG_MISDN_HFCPCI=m
CONFIG_MISDN_HFCMULTI=m
CONFIG_MISDN_HFCUSB=m
CONFIG_MISDN_AVMFRITZ=m
CONFIG_MISDN_SPEEDFAX=m
CONFIG_MISDN_INFINEON=m
CONFIG_MISDN_W6692=m
CONFIG_MISDN_NETJET=m
CONFIG_MISDN_HDLC=m
CONFIG_MISDN_IPAC=m
CONFIG_MISDN_ISAR=m
#
# Input device support
#
CONFIG_INPUT=y
CONFIG_INPUT_LEDS=m
CONFIG_INPUT_FF_MEMLESS=m
CONFIG_INPUT_SPARSEKMAP=m
CONFIG_INPUT_MATRIXKMAP=m
CONFIG_INPUT_VIVALDIFMAP=m
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=m
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=m
CONFIG_INPUT_EVDEV=m
CONFIG_INPUT_KUNIT_TEST=m
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ADC=m
CONFIG_KEYBOARD_ADP5520=m
CONFIG_KEYBOARD_ADP5585=m
CONFIG_KEYBOARD_ADP5588=m
CONFIG_KEYBOARD_APPLESPI=m
CONFIG_KEYBOARD_ATKBD=m
CONFIG_KEYBOARD_QT1050=m
CONFIG_KEYBOARD_QT1070=m
CONFIG_KEYBOARD_QT2160=m
CONFIG_KEYBOARD_CLPS711X=m
CONFIG_KEYBOARD_DLINK_DIR685=m
CONFIG_KEYBOARD_LKKBD=m
CONFIG_KEYBOARD_EP93XX=m
CONFIG_KEYBOARD_GPIO=m
CONFIG_KEYBOARD_GPIO_POLLED=m
CONFIG_KEYBOARD_TCA8418=m
CONFIG_KEYBOARD_MATRIX=m
CONFIG_KEYBOARD_LM8323=m
CONFIG_KEYBOARD_LM8333=m
CONFIG_KEYBOARD_LPC32XX=m
CONFIG_KEYBOARD_MAX7359=m
CONFIG_KEYBOARD_MAX7360=m
CONFIG_KEYBOARD_MPR121=m
CONFIG_KEYBOARD_SNVS_PWRKEY=m
CONFIG_KEYBOARD_IMX=m
CONFIG_KEYBOARD_IMX_BBM_SCMI=m
CONFIG_KEYBOARD_IMX_SC_KEY=m
CONFIG_KEYBOARD_NEWTON=m
CONFIG_KEYBOARD_TEGRA=m
CONFIG_KEYBOARD_OPENCORES=m
CONFIG_KEYBOARD_PINEPHONE=m
CONFIG_KEYBOARD_PXA27x=m
CONFIG_KEYBOARD_PMIC8XXX=m
CONFIG_KEYBOARD_SAMSUNG=m
CONFIG_KEYBOARD_GOLDFISH_EVENTS=m
CONFIG_KEYBOARD_STOWAWAY=m
CONFIG_KEYBOARD_ST_KEYSCAN=m
CONFIG_KEYBOARD_SUNKBD=m
CONFIG_KEYBOARD_SH_KEYSC=m
CONFIG_KEYBOARD_STMPE=m
CONFIG_KEYBOARD_IQS62X=m
CONFIG_KEYBOARD_OMAP4=m
CONFIG_KEYBOARD_SPEAR=m
CONFIG_KEYBOARD_TC3589X=m
CONFIG_KEYBOARD_TM2_TOUCHKEY=m
CONFIG_KEYBOARD_TWL4030=m
CONFIG_KEYBOARD_XTKBD=m
CONFIG_KEYBOARD_CROS_EC=m
CONFIG_KEYBOARD_CAP11XX=m
CONFIG_KEYBOARD_BCM=m
CONFIG_KEYBOARD_MT6779=m
CONFIG_KEYBOARD_MTK_PMIC=m
CONFIG_KEYBOARD_CYPRESS_SF=m
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=m
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_BYD=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
CONFIG_MOUSE_PS2_CYPRESS=y
CONFIG_MOUSE_PS2_LIFEBOOK=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_MOUSE_PS2_ELANTECH_SMBUS=y
CONFIG_MOUSE_PS2_SENTELIC=y
CONFIG_MOUSE_PS2_TOUCHKIT=y
CONFIG_MOUSE_PS2_FOCALTECH=y
CONFIG_MOUSE_PS2_VMMOUSE=y
CONFIG_MOUSE_PS2_SMBUS=y
CONFIG_MOUSE_SERIAL=m
CONFIG_MOUSE_APPLETOUCH=m
CONFIG_MOUSE_BCM5974=m
CONFIG_MOUSE_CYAPA=m
CONFIG_MOUSE_ELAN_I2C=m
CONFIG_MOUSE_ELAN_I2C_I2C=y
CONFIG_MOUSE_ELAN_I2C_SMBUS=y
CONFIG_MOUSE_INPORT=m
CONFIG_MOUSE_ATIXL=y
CONFIG_MOUSE_LOGIBM=m
CONFIG_MOUSE_PC110PAD=m
CONFIG_MOUSE_VSXXXAA=m
CONFIG_MOUSE_GPIO=m
CONFIG_MOUSE_SYNAPTICS_I2C=m
CONFIG_MOUSE_SYNAPTICS_USB=m
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_ANALOG=m
CONFIG_JOYSTICK_A3D=m
CONFIG_JOYSTICK_ADC=m
CONFIG_JOYSTICK_ADI=m
CONFIG_JOYSTICK_COBRA=m
CONFIG_JOYSTICK_GF2K=m
CONFIG_JOYSTICK_GRIP=m
CONFIG_JOYSTICK_GRIP_MP=m
CONFIG_JOYSTICK_GUILLEMOT=m
CONFIG_JOYSTICK_INTERACT=m
CONFIG_JOYSTICK_SIDEWINDER=m
CONFIG_JOYSTICK_TMDC=m
CONFIG_JOYSTICK_IFORCE=m
CONFIG_JOYSTICK_IFORCE_USB=m
CONFIG_JOYSTICK_IFORCE_232=m
CONFIG_JOYSTICK_WARRIOR=m
CONFIG_JOYSTICK_MAGELLAN=m
CONFIG_JOYSTICK_SPACEORB=m
CONFIG_JOYSTICK_SPACEBALL=m
CONFIG_JOYSTICK_STINGER=m
CONFIG_JOYSTICK_TWIDJOY=m
CONFIG_JOYSTICK_ZHENHUA=m
CONFIG_JOYSTICK_DB9=m
CONFIG_JOYSTICK_GAMECON=m
CONFIG_JOYSTICK_TURBOGRAFX=m
CONFIG_JOYSTICK_AS5011=m
CONFIG_JOYSTICK_JOYDUMP=m
CONFIG_JOYSTICK_XPAD=m
CONFIG_JOYSTICK_XPAD_FF=y
CONFIG_JOYSTICK_XPAD_LEDS=y
CONFIG_JOYSTICK_WALKERA0701=m
CONFIG_JOYSTICK_PSXPAD_SPI=m
CONFIG_JOYSTICK_PSXPAD_SPI_FF=y
CONFIG_JOYSTICK_PXRC=m
CONFIG_JOYSTICK_QWIIC=m
CONFIG_JOYSTICK_FSIA6B=m
CONFIG_JOYSTICK_SENSEHAT=m
CONFIG_JOYSTICK_SEESAW=m
CONFIG_INPUT_TABLET=y
CONFIG_TABLET_USB_ACECAD=m
CONFIG_TABLET_USB_AIPTEK=m
CONFIG_TABLET_USB_HANWANG=m
CONFIG_TABLET_USB_KBTAB=m
CONFIG_TABLET_USB_PEGASUS=m
CONFIG_TABLET_SERIAL_WACOM4=m
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_88PM860X=m
CONFIG_TOUCHSCREEN_ADS7846=m
CONFIG_TOUCHSCREEN_AD7877=m
CONFIG_TOUCHSCREEN_AD7879=m
CONFIG_TOUCHSCREEN_AD7879_I2C=m
CONFIG_TOUCHSCREEN_AD7879_SPI=m
CONFIG_TOUCHSCREEN_ADC=m
CONFIG_TOUCHSCREEN_APPLE_Z2=m
CONFIG_TOUCHSCREEN_AR1021_I2C=m
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
CONFIG_TOUCHSCREEN_ATMEL_MXT_T37=y
CONFIG_TOUCHSCREEN_AUO_PIXCIR=m
CONFIG_TOUCHSCREEN_BU21013=m
CONFIG_TOUCHSCREEN_BU21029=m
CONFIG_TOUCHSCREEN_CHIPONE_ICN8318=m
CONFIG_TOUCHSCREEN_CHIPONE_ICN8505=m
CONFIG_TOUCHSCREEN_CY8CTMA140=m
CONFIG_TOUCHSCREEN_CY8CTMG110=m
CONFIG_TOUCHSCREEN_CYTTSP_CORE=m
CONFIG_TOUCHSCREEN_CYTTSP_I2C=m
CONFIG_TOUCHSCREEN_CYTTSP_SPI=m
CONFIG_TOUCHSCREEN_CYTTSP5=m
CONFIG_TOUCHSCREEN_DA9034=m
CONFIG_TOUCHSCREEN_DA9052=m
CONFIG_TOUCHSCREEN_DYNAPRO=m
CONFIG_TOUCHSCREEN_HAMPSHIRE=m
CONFIG_TOUCHSCREEN_EETI=m
CONFIG_TOUCHSCREEN_EGALAX=m
CONFIG_TOUCHSCREEN_EGALAX_SERIAL=m
CONFIG_TOUCHSCREEN_EXC3000=m
CONFIG_TOUCHSCREEN_FUJITSU=m
CONFIG_TOUCHSCREEN_GOODIX=m
CONFIG_TOUCHSCREEN_GOODIX_BERLIN_CORE=m
CONFIG_TOUCHSCREEN_GOODIX_BERLIN_I2C=m
CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI=m
CONFIG_TOUCHSCREEN_HIDEEP=m
CONFIG_TOUCHSCREEN_HIMAX_HX852X=m
CONFIG_TOUCHSCREEN_HYCON_HY46XX=m
CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX=m
CONFIG_TOUCHSCREEN_HYNITRON_CST816X=m
CONFIG_TOUCHSCREEN_ILI210X=m
CONFIG_TOUCHSCREEN_ILITEK=m
CONFIG_TOUCHSCREEN_IPROC=m
CONFIG_TOUCHSCREEN_S6SY761=m
CONFIG_TOUCHSCREEN_GUNZE=m
CONFIG_TOUCHSCREEN_EKTF2127=m
CONFIG_TOUCHSCREEN_ELAN=m
CONFIG_TOUCHSCREEN_ELO=m
CONFIG_TOUCHSCREEN_WACOM_W8001=m
CONFIG_TOUCHSCREEN_WACOM_I2C=m
CONFIG_TOUCHSCREEN_MAX11801=m
CONFIG_TOUCHSCREEN_MMS114=m
CONFIG_TOUCHSCREEN_MELFAS_MIP4=m
CONFIG_TOUCHSCREEN_MSG2638=m
CONFIG_TOUCHSCREEN_MTOUCH=m
CONFIG_TOUCHSCREEN_NOVATEK_NVT_TS=m
CONFIG_TOUCHSCREEN_IMAGIS=m
CONFIG_TOUCHSCREEN_IMX6UL_TSC=m
CONFIG_TOUCHSCREEN_INEXIO=m
CONFIG_TOUCHSCREEN_MK712=m
CONFIG_TOUCHSCREEN_HTCPEN=m
CONFIG_TOUCHSCREEN_PENMOUNT=m
CONFIG_TOUCHSCREEN_EDT_FT5X06=m
CONFIG_TOUCHSCREEN_RASPBERRYPI_FW=m
CONFIG_TOUCHSCREEN_MIGOR=m
CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
CONFIG_TOUCHSCREEN_TOUCHWIN=m
CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m
CONFIG_TOUCHSCREEN_PIXCIR=m
CONFIG_TOUCHSCREEN_WDT87XX_I2C=m
CONFIG_TOUCHSCREEN_WM831X=m
CONFIG_TOUCHSCREEN_WM97XX=m
CONFIG_TOUCHSCREEN_WM9705=y
CONFIG_TOUCHSCREEN_WM9712=y
CONFIG_TOUCHSCREEN_WM9713=y
CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
CONFIG_TOUCHSCREEN_MXS_LRADC=m
CONFIG_TOUCHSCREEN_MX25=m
CONFIG_TOUCHSCREEN_MC13783=m
CONFIG_TOUCHSCREEN_USB_EGALAX=y
CONFIG_TOUCHSCREEN_USB_PANJIT=y
CONFIG_TOUCHSCREEN_USB_3M=y
CONFIG_TOUCHSCREEN_USB_ITM=y
CONFIG_TOUCHSCREEN_USB_ETURBO=y
CONFIG_TOUCHSCREEN_USB_GUNZE=y
CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
CONFIG_TOUCHSCREEN_USB_GOTOP=y
CONFIG_TOUCHSCREEN_USB_JASTEC=y
CONFIG_TOUCHSCREEN_USB_ELO=y
CONFIG_TOUCHSCREEN_USB_E2I=y
CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y
CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y
CONFIG_TOUCHSCREEN_USB_NEXIO=y
CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y
CONFIG_TOUCHSCREEN_TOUCHIT213=m
CONFIG_TOUCHSCREEN_TS4800=m
CONFIG_TOUCHSCREEN_TSC_SERIO=m
CONFIG_TOUCHSCREEN_TSC200X_CORE=m
CONFIG_TOUCHSCREEN_TSC2004=m
CONFIG_TOUCHSCREEN_TSC2005=m
CONFIG_TOUCHSCREEN_TSC2007=m
CONFIG_TOUCHSCREEN_TSC2007_IIO=y
CONFIG_TOUCHSCREEN_PCAP=m
CONFIG_TOUCHSCREEN_RM_TS=m
CONFIG_TOUCHSCREEN_SILEAD=m
CONFIG_TOUCHSCREEN_SIS_I2C=m
CONFIG_TOUCHSCREEN_ST1232=m
CONFIG_TOUCHSCREEN_STMFTS=m
CONFIG_TOUCHSCREEN_STMPE=m
CONFIG_TOUCHSCREEN_SUN4I=m
CONFIG_TOUCHSCREEN_SUR40=m
CONFIG_TOUCHSCREEN_SURFACE3_SPI=m
CONFIG_TOUCHSCREEN_SX8654=m
CONFIG_TOUCHSCREEN_TPS6507X=m
CONFIG_TOUCHSCREEN_ZET6223=m
CONFIG_TOUCHSCREEN_ZFORCE=m
CONFIG_TOUCHSCREEN_COLIBRI_VF50=m
CONFIG_TOUCHSCREEN_ROHM_BU21023=m
CONFIG_TOUCHSCREEN_IQS5XX=m
CONFIG_TOUCHSCREEN_IQS7211=m
CONFIG_TOUCHSCREEN_ZINITIX=m
CONFIG_TOUCHSCREEN_HIMAX_HX83112B=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_88PM860X_ONKEY=m
CONFIG_INPUT_88PM80X_ONKEY=m
CONFIG_INPUT_88PM886_ONKEY=m
CONFIG_INPUT_AD714X=m
CONFIG_INPUT_AD714X_I2C=m
CONFIG_INPUT_AD714X_SPI=m
CONFIG_INPUT_ARIEL_PWRBUTTON=m
CONFIG_INPUT_ARIZONA_HAPTICS=m
CONFIG_INPUT_ATC260X_ONKEY=m
CONFIG_INPUT_ATMEL_CAPTOUCH=m
CONFIG_INPUT_AW86927=m
CONFIG_INPUT_BBNSM_PWRKEY=m
CONFIG_INPUT_BMA150=m
CONFIG_INPUT_CS40L50_VIBRA=m
CONFIG_INPUT_E3X0_BUTTON=m
CONFIG_INPUT_PCSPKR=m
CONFIG_INPUT_PF1550_ONKEY=m
CONFIG_INPUT_PM8941_PWRKEY=m
CONFIG_INPUT_PM8XXX_VIBRATOR=m
CONFIG_INPUT_PMIC8XXX_PWRKEY=m
CONFIG_INPUT_MAX7360_ROTARY=m
CONFIG_INPUT_MAX77650_ONKEY=m
CONFIG_INPUT_MAX77693_HAPTIC=m
CONFIG_INPUT_MAX8925_ONKEY=m
CONFIG_INPUT_MAX8997_HAPTIC=m
CONFIG_INPUT_MC13783_PWRBUTTON=m
CONFIG_INPUT_MMA8450=m
CONFIG_INPUT_APANEL=m
CONFIG_INPUT_GPIO_BEEPER=m
CONFIG_INPUT_GPIO_DECODER=m
CONFIG_INPUT_GPIO_VIBRA=m
CONFIG_INPUT_CPCAP_PWRBUTTON=m
CONFIG_INPUT_WISTRON_BTNS=m
CONFIG_INPUT_ATLAS_BTNS=m
CONFIG_INPUT_ATI_REMOTE2=m
CONFIG_INPUT_KEYSPAN_REMOTE=m
CONFIG_INPUT_KXTJ9=m
CONFIG_INPUT_POWERMATE=m
CONFIG_INPUT_YEALINK=m
CONFIG_INPUT_CM109=m
CONFIG_INPUT_REGULATOR_HAPTIC=m
CONFIG_INPUT_RETU_PWRBUTTON=m
CONFIG_INPUT_TPS65218_PWRBUTTON=m
CONFIG_INPUT_TPS65219_PWRBUTTON=m
CONFIG_INPUT_TPS6594_PWRBUTTON=m
CONFIG_INPUT_AXP20X_PEK=m
CONFIG_INPUT_TWL4030_PWRBUTTON=m
CONFIG_INPUT_TWL4030_VIBRA=m
CONFIG_INPUT_TWL6040_VIBRA=m
CONFIG_INPUT_UINPUT=m
CONFIG_INPUT_PALMAS_PWRBUTTON=m
CONFIG_INPUT_PCF8574=m
CONFIG_INPUT_PWM_BEEPER=m
CONFIG_INPUT_PWM_VIBRA=m
CONFIG_INPUT_RK805_PWRKEY=m
CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
CONFIG_INPUT_DA7280_HAPTICS=m
CONFIG_INPUT_DA9052_ONKEY=m
CONFIG_INPUT_DA9055_ONKEY=m
CONFIG_INPUT_DA9063_ONKEY=m
CONFIG_INPUT_WM831X_ON=m
CONFIG_INPUT_PCAP=m
CONFIG_INPUT_ADXL34X=m
CONFIG_INPUT_ADXL34X_I2C=m
CONFIG_INPUT_ADXL34X_SPI=m
CONFIG_INPUT_IBM_PANEL=m
CONFIG_INPUT_IMS_PCU=m
CONFIG_INPUT_IQS269A=m
CONFIG_INPUT_IQS626A=m
CONFIG_INPUT_IQS7222=m
CONFIG_INPUT_CMA3000=m
CONFIG_INPUT_CMA3000_I2C=m
CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m
CONFIG_INPUT_IDEAPAD_SLIDEBAR=m
CONFIG_INPUT_SOC_BUTTON_ARRAY=m
CONFIG_INPUT_DRV260X_HAPTICS=m
CONFIG_INPUT_DRV2665_HAPTICS=m
CONFIG_INPUT_DRV2667_HAPTICS=m
CONFIG_INPUT_HISI_POWERKEY=m
CONFIG_INPUT_QNAP_MCU=m
CONFIG_INPUT_RAVE_SP_PWRBUTTON=m
CONFIG_INPUT_SC27XX_VIBRA=m
CONFIG_INPUT_RT5120_PWRKEY=m
CONFIG_INPUT_STPMIC1_ONKEY=m
CONFIG_RMI4_CORE=m
CONFIG_RMI4_I2C=m
CONFIG_RMI4_SPI=m
CONFIG_RMI4_SMB=m
CONFIG_RMI4_F03=y
CONFIG_RMI4_F03_SERIO=m
CONFIG_RMI4_2D_SENSOR=y
CONFIG_RMI4_F11=y
CONFIG_RMI4_F12=y
CONFIG_RMI4_F1A=y
CONFIG_RMI4_F21=y
CONFIG_RMI4_F30=y
CONFIG_RMI4_F34=y
CONFIG_RMI4_F3A=y
CONFIG_RMI4_F54=y
CONFIG_RMI4_F55=y
#
# Hardware I/O ports
#
CONFIG_SERIO=m
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
CONFIG_SERIO_I8042=m
CONFIG_SERIO_SERPORT=m
CONFIG_SERIO_CT82C710=m
CONFIG_SERIO_PARKBD=m
CONFIG_SERIO_PCIPS2=m
CONFIG_SERIO_LIBPS2=m
CONFIG_SERIO_RAW=m
CONFIG_SERIO_ALTERA_PS2=m
CONFIG_SERIO_PS2MULT=m
CONFIG_SERIO_ARC_PS2=m
CONFIG_SERIO_APBPS2=m
CONFIG_SERIO_OLPC_APSP=m
CONFIG_HYPERV_KEYBOARD=m
CONFIG_SERIO_SUN4I_PS2=m
CONFIG_SERIO_GPIO_PS2=m
CONFIG_USERIO=m
CONFIG_GAMEPORT=m
CONFIG_GAMEPORT_NS558=m
CONFIG_GAMEPORT_L4=m
CONFIG_GAMEPORT_EMU10K1=m
CONFIG_GAMEPORT_FM801=m
# end of Hardware I/O ports
# end of Input device support
#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LEGACY_TIOCSTI=y
CONFIG_LDISC_AUTOLOAD=y
#
# Serial drivers
#
CONFIG_SERIAL_EARLYCON=y
CONFIG_SERIAL_8250=m
CONFIG_SERIAL_8250_PNP=y
CONFIG_SERIAL_8250_16550A_VARIANTS=y
CONFIG_SERIAL_8250_FINTEK=y
CONFIG_SERIAL_8250_DMA=y
CONFIG_SERIAL_8250_PCILIB=y
CONFIG_SERIAL_8250_PCI=m
CONFIG_SERIAL_8250_EXAR=m
CONFIG_SERIAL_8250_CS=m
CONFIG_SERIAL_8250_MEN_MCB=m
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_FOURPORT=m
CONFIG_SERIAL_8250_ACCENT=m
CONFIG_SERIAL_8250_BOCA=m
CONFIG_SERIAL_8250_EXAR_ST16C554=m
CONFIG_SERIAL_8250_HUB6=m
CONFIG_SERIAL_8250_PCI1XXXX=m
CONFIG_SERIAL_8250_ASPEED_VUART=m
CONFIG_SERIAL_8250_BCM2835AUX=m
CONFIG_SERIAL_8250_FSL=m
CONFIG_SERIAL_8250_DFL=m
CONFIG_SERIAL_8250_DW=m
CONFIG_SERIAL_8250_EM=m
CONFIG_SERIAL_8250_IOC3=m
CONFIG_SERIAL_8250_KEBA=m
CONFIG_SERIAL_8250_RT288X=y
CONFIG_SERIAL_8250_OMAP=m
CONFIG_SERIAL_8250_LOONGSON=m
CONFIG_SERIAL_8250_LPC18XX=m
CONFIG_SERIAL_8250_MT6577=m
CONFIG_SERIAL_8250_UNIPHIER=m
CONFIG_SERIAL_8250_INGENIC=m
CONFIG_SERIAL_8250_LPSS=m
CONFIG_SERIAL_8250_MID=m
CONFIG_SERIAL_8250_PERICOM=m
CONFIG_SERIAL_8250_PXA=m
CONFIG_SERIAL_8250_TEGRA=m
CONFIG_SERIAL_8250_BCM7271=m
CONFIG_SERIAL_8250_NI=m
CONFIG_SERIAL_OF_PLATFORM=m
CONFIG_SERIAL_8250_DWLIB=y
#
# Non-8250 serial port support
#
CONFIG_SERIAL_AMBA_PL010=m
CONFIG_SERIAL_ATMEL=y
CONFIG_SERIAL_ATMEL_CONSOLE=y
CONFIG_SERIAL_ATMEL_PDC=y
CONFIG_SERIAL_ATMEL_TTYAT=y
CONFIG_SERIAL_MESON=m
CONFIG_SERIAL_MESON_CONSOLE=y
CONFIG_SERIAL_CLPS711X=m
CONFIG_SERIAL_SAMSUNG=m
CONFIG_SERIAL_SAMSUNG_UARTS=4
CONFIG_SERIAL_SAMSUNG_CONSOLE=y
CONFIG_SERIAL_TEGRA=m
CONFIG_SERIAL_TEGRA_TCU=m
CONFIG_SERIAL_TEGRA_UTC=m
CONFIG_SERIAL_TEGRA_UTC_CONSOLE=y
CONFIG_SERIAL_MAX3100=m
CONFIG_SERIAL_MAX310X=m
CONFIG_SERIAL_IMX=m
CONFIG_SERIAL_IMX_CONSOLE=y
CONFIG_SERIAL_IMX_EARLYCON=y
CONFIG_SERIAL_UARTLITE=m
CONFIG_SERIAL_UARTLITE_NR_UARTS=1
CONFIG_SERIAL_SH_SCI=m
CONFIG_SERIAL_SH_SCI_NR_UARTS=2
CONFIG_SERIAL_SH_SCI_DMA=y
CONFIG_SERIAL_RSCI=m
CONFIG_SERIAL_HS_LPC32XX=m
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
CONFIG_SERIAL_ICOM=m
CONFIG_SERIAL_JSM=m
CONFIG_SERIAL_MSM=m
CONFIG_SERIAL_QCOM_GENI=m
CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
CONFIG_SERIAL_QCOM_GENI_UART_PORTS=8
CONFIG_SERIAL_VT8500=y
CONFIG_SERIAL_VT8500_CONSOLE=y
CONFIG_SERIAL_OMAP=m
CONFIG_SERIAL_SIFIVE=m
CONFIG_SERIAL_LANTIQ=m
CONFIG_SERIAL_QE=m
CONFIG_SERIAL_SCCNXP=m
CONFIG_SERIAL_SC16IS7XX=m
CONFIG_SERIAL_SC16IS7XX_I2C=m
CONFIG_SERIAL_SC16IS7XX_SPI=m
CONFIG_SERIAL_TIMBERDALE=m
CONFIG_SERIAL_BCM63XX=m
CONFIG_SERIAL_ALTERA_JTAGUART=m
CONFIG_SERIAL_ALTERA_UART=m
CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4
CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200
CONFIG_SERIAL_PCH_UART=m
CONFIG_SERIAL_MXS_AUART=m
CONFIG_SERIAL_XILINX_PS_UART=m
CONFIG_SERIAL_MPS2_UART=y
CONFIG_SERIAL_MPS2_UART_CONSOLE=y
CONFIG_SERIAL_ARC=m
CONFIG_SERIAL_ARC_NR_PORTS=1
CONFIG_SERIAL_RP2=m
CONFIG_SERIAL_RP2_NR_UARTS=32
CONFIG_SERIAL_FSL_LPUART=m
CONFIG_SERIAL_FSL_LINFLEXUART=m
CONFIG_SERIAL_CONEXANT_DIGICOLOR=m
CONFIG_SERIAL_ST_ASC=m
CONFIG_SERIAL_MEN_Z135=m
CONFIG_SERIAL_SPRD=m
CONFIG_SERIAL_STM32=m
CONFIG_SERIAL_STM32_CONSOLE=y
CONFIG_SERIAL_MVEBU_UART=y
CONFIG_SERIAL_MVEBU_CONSOLE=y
CONFIG_SERIAL_OWL=m
CONFIG_SERIAL_RDA=y
CONFIG_SERIAL_RDA_CONSOLE=y
CONFIG_SERIAL_MILBEAUT_USIO=m
CONFIG_SERIAL_MILBEAUT_USIO_PORTS=4
CONFIG_SERIAL_LITEUART=m
CONFIG_SERIAL_LITEUART_MAX_PORTS=1
CONFIG_SERIAL_SUNPLUS=m
CONFIG_SERIAL_SUNPLUS_CONSOLE=y
CONFIG_SERIAL_NUVOTON_MA35D1=m
# CONFIG_SERIAL_ESP32 is not set
# CONFIG_SERIAL_ESP32_ACM is not set
# end of Serial drivers
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_NONSTANDARD=y
CONFIG_MOXA_INTELLIO=m
CONFIG_MOXA_SMARTIO=m
CONFIG_N_HDLC=m
CONFIG_GOLDFISH_TTY=m
CONFIG_IPWIRELESS=m
CONFIG_N_GSM=m
CONFIG_NOZOMI=m
CONFIG_NULL_TTY=m
CONFIG_HVC_DRIVER=y
CONFIG_HVC_IRQ=y
CONFIG_HVC_XEN=y
CONFIG_HVC_XEN_FRONTEND=y
CONFIG_RPMSG_TTY=m
CONFIG_SERIAL_DEV_BUS=m
CONFIG_TTY_PRINTK=m
CONFIG_TTY_PRINTK_LEVEL=6
CONFIG_PRINTER=m
CONFIG_LP_CONSOLE=y
CONFIG_PPDEV=m
CONFIG_VIRTIO_CONSOLE=m
CONFIG_IPMI_HANDLER=m
CONFIG_IPMI_DMI_DECODE=y
CONFIG_IPMI_PLAT_DATA=y
CONFIG_IPMI_PANIC_EVENT=y
CONFIG_IPMI_PANIC_STRING=y
CONFIG_IPMI_DEVICE_INTERFACE=m
CONFIG_IPMI_SI=m
CONFIG_IPMI_SSIF=m
CONFIG_IPMI_IPMB=m
CONFIG_IPMI_WATCHDOG=m
CONFIG_IPMI_POWEROFF=m
CONFIG_IPMI_KCS_BMC=m
CONFIG_ASPEED_KCS_IPMI_BMC=m
CONFIG_NPCM7XX_KCS_IPMI_BMC=m
CONFIG_IPMI_KCS_BMC_CDEV_IPMI=m
CONFIG_IPMI_KCS_BMC_SERIO=m
CONFIG_ASPEED_BT_IPMI_BMC=m
CONFIG_SSIF_IPMI_BMC=m
CONFIG_IPMB_DEVICE_INTERFACE=m
CONFIG_HW_RANDOM=m
CONFIG_HW_RANDOM_TIMERIOMEM=m
CONFIG_HW_RANDOM_INTEL=m
CONFIG_HW_RANDOM_AMD=m
CONFIG_HW_RANDOM_AIROHA=m
CONFIG_HW_RANDOM_ATMEL=m
CONFIG_HW_RANDOM_BA431=m
CONFIG_HW_RANDOM_BCM2835=m
CONFIG_HW_RANDOM_BCM74110=m
CONFIG_HW_RANDOM_IPROC_RNG200=m
CONFIG_HW_RANDOM_GEODE=m
CONFIG_HW_RANDOM_VIA=m
CONFIG_HW_RANDOM_IXP4XX=m
CONFIG_HW_RANDOM_OMAP=m
CONFIG_HW_RANDOM_OMAP3_ROM=m
CONFIG_HW_RANDOM_VIRTIO=m
CONFIG_HW_RANDOM_MXC_RNGA=m
CONFIG_HW_RANDOM_IMX_RNGC=m
CONFIG_HW_RANDOM_INGENIC_RNG=m
CONFIG_HW_RANDOM_INGENIC_TRNG=m
CONFIG_HW_RANDOM_HISI=m
CONFIG_HW_RANDOM_HISTB=m
CONFIG_HW_RANDOM_ST=m
CONFIG_HW_RANDOM_XGENE=m
CONFIG_HW_RANDOM_STM32=m
CONFIG_HW_RANDOM_PIC32=m
CONFIG_HW_RANDOM_POLARFIRE_SOC=m
CONFIG_HW_RANDOM_MESON=m
CONFIG_HW_RANDOM_MTK=m
CONFIG_HW_RANDOM_EXYNOS=m
CONFIG_HW_RANDOM_NPCM=m
CONFIG_HW_RANDOM_KEYSTONE=m
CONFIG_HW_RANDOM_CCTRNG=m
CONFIG_HW_RANDOM_XIPHERA=m
CONFIG_HW_RANDOM_JH7110=m
CONFIG_HW_RANDOM_ROCKCHIP=m
CONFIG_DTLK=m
CONFIG_APPLICOM=m
CONFIG_SONYPI=m
CONFIG_SCx200_GPIO=m
CONFIG_PC8736x_GPIO=m
CONFIG_NSC_GPIO=m
CONFIG_DEVMEM=y
CONFIG_NVRAM=m
CONFIG_DEVPORT=y
CONFIG_HPET=y
CONFIG_HPET_MMAP=y
CONFIG_HPET_MMAP_DEFAULT=y
CONFIG_HANGCHECK_TIMER=m
CONFIG_TCG_TPM=y
CONFIG_TCG_TPM2_HMAC=y
CONFIG_TCG_TIS_CORE=y
CONFIG_TCG_TIS=y
CONFIG_TCG_TIS_SPI=m
CONFIG_TCG_TIS_SPI_CR50=y
CONFIG_TCG_TIS_I2C=m
CONFIG_TCG_TIS_SYNQUACER=m
CONFIG_TCG_TIS_I2C_CR50=m
CONFIG_TCG_TIS_I2C_ATMEL=m
CONFIG_TCG_TIS_I2C_INFINEON=m
CONFIG_TCG_TIS_I2C_NUVOTON=m
CONFIG_TCG_NSC=m
CONFIG_TCG_ATMEL=m
CONFIG_TCG_INFINEON=m
CONFIG_TCG_XEN=m
CONFIG_TCG_CRB=y
CONFIG_TCG_VTPM_PROXY=m
CONFIG_TCG_TIS_ST33ZP24=m
CONFIG_TCG_TIS_ST33ZP24_I2C=m
CONFIG_TCG_TIS_ST33ZP24_SPI=m
CONFIG_TELCLOCK=m
CONFIG_XILLYBUS_CLASS=m
CONFIG_XILLYBUS=m
CONFIG_XILLYBUS_PCIE=m
CONFIG_XILLYBUS_OF=m
CONFIG_XILLYUSB=m
# end of Character devices
#
# I2C support
#
CONFIG_I2C=y
CONFIG_ACPI_I2C_OPREGION=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_MUX=m
#
# Multiplexer I2C Chip support
#
CONFIG_I2C_ARB_GPIO_CHALLENGE=m
CONFIG_I2C_MUX_GPIO=m
CONFIG_I2C_MUX_GPMUX=m
CONFIG_I2C_MUX_LTC4306=m
CONFIG_I2C_MUX_PCA9541=m
CONFIG_I2C_MUX_PCA954x=m
CONFIG_I2C_MUX_PINCTRL=m
CONFIG_I2C_MUX_REG=m
CONFIG_I2C_DEMUX_PINCTRL=m
CONFIG_I2C_MUX_MLXCPLD=m
CONFIG_I2C_MUX_MULE=m
# end of Multiplexer I2C Chip support
CONFIG_I2C_ATR=m
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_SMBUS=m
CONFIG_I2C_ALGOBIT=m
CONFIG_I2C_ALGOPCF=m
CONFIG_I2C_ALGOPCA=m
#
# I2C Hardware Bus support
#
#
# PC SMBus host controller drivers
#
CONFIG_I2C_CCGX_UCSI=m
CONFIG_I2C_ALI1535=m
CONFIG_I2C_ALI1563=m
CONFIG_I2C_ALI15X3=m
CONFIG_I2C_AMD756=m
CONFIG_I2C_AMD8111=m
CONFIG_I2C_AMD_MP2=m
CONFIG_I2C_AMD_ASF=m
CONFIG_I2C_HIX5HD2=m
CONFIG_I2C_I801=m
CONFIG_I2C_I801_MUX=y
CONFIG_I2C_ISCH=m
CONFIG_I2C_ISMT=m
CONFIG_I2C_PIIX4=m
CONFIG_I2C_NFORCE2=m
CONFIG_I2C_NVIDIA_GPU=m
CONFIG_I2C_SIS5595=m
CONFIG_I2C_SIS630=m
CONFIG_I2C_SIS96X=m
CONFIG_I2C_VIA=m
CONFIG_I2C_VIAPRO=m
CONFIG_I2C_ZHAOXIN=m
#
# ACPI drivers
#
CONFIG_I2C_SCMI=m
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
CONFIG_I2C_ALTERA=m
CONFIG_I2C_ASPEED=m
CONFIG_I2C_AT91=m
CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL=y
CONFIG_I2C_AXXIA=m
CONFIG_I2C_BCM2835=m
CONFIG_I2C_BCM_IPROC=m
CONFIG_I2C_BCM_KONA=m
CONFIG_I2C_BRCMSTB=m
CONFIG_I2C_CADENCE=m
CONFIG_I2C_CBUS_GPIO=m
CONFIG_I2C_CGBC=m
CONFIG_I2C_DAVINCI=m
CONFIG_I2C_DESIGNWARE_CORE=m
CONFIG_I2C_DESIGNWARE_PLATFORM=m
CONFIG_I2C_DESIGNWARE_AMDISP=m
CONFIG_I2C_DESIGNWARE_BAYTRAIL=y
CONFIG_I2C_DESIGNWARE_PCI=m
CONFIG_I2C_DIGICOLOR=m
CONFIG_I2C_EG20T=m
CONFIG_I2C_EMEV2=m
CONFIG_I2C_EXYNOS5=m
CONFIG_I2C_GPIO=m
CONFIG_I2C_GPIO_FAULT_INJECTOR=y
CONFIG_I2C_GXP=m
CONFIG_I2C_HIGHLANDER=m
CONFIG_I2C_HISI=m
CONFIG_I2C_IMG=m
CONFIG_I2C_IMX=m
CONFIG_I2C_IMX_LPI2C=m
CONFIG_I2C_IOP3XX=m
CONFIG_I2C_JZ4780=m
CONFIG_I2C_K1=m
CONFIG_I2C_KEBA=m
CONFIG_I2C_KEMPLD=m
CONFIG_I2C_LPC2K=m
CONFIG_I2C_LS2X=m
CONFIG_I2C_MLXBF=m
CONFIG_I2C_MESON=m
CONFIG_I2C_MICROCHIP_CORE=m
CONFIG_I2C_MT65XX=m
CONFIG_I2C_MT7621=m
CONFIG_I2C_MV64XXX=m
CONFIG_I2C_MXS=m
CONFIG_I2C_NOMADIK=m
CONFIG_I2C_NPCM=m
CONFIG_I2C_OCORES=m
CONFIG_I2C_OMAP=m
CONFIG_I2C_OWL=m
CONFIG_I2C_APPLE=m
CONFIG_I2C_PCA_PLATFORM=m
CONFIG_I2C_PNX=m
CONFIG_I2C_PXA=m
CONFIG_I2C_PXA_PCI=y
CONFIG_I2C_QCOM_CCI=m
CONFIG_I2C_QCOM_GENI=m
CONFIG_I2C_QUP=m
CONFIG_I2C_RIIC=m
CONFIG_I2C_RK3X=m
CONFIG_I2C_RTL9300=m
CONFIG_I2C_RZV2M=m
CONFIG_I2C_S3C2410=m
CONFIG_I2C_SH_MOBILE=m
CONFIG_I2C_SIMTEC=m
CONFIG_I2C_SPRD=m
CONFIG_I2C_ST=m
CONFIG_I2C_STM32F4=m
CONFIG_I2C_STM32F7=m
CONFIG_I2C_SUN6I_P2WI=m
CONFIG_I2C_SYNQUACER=m
CONFIG_I2C_TEGRA_BPMP=m
CONFIG_I2C_UNIPHIER=m
CONFIG_I2C_UNIPHIER_F=m
CONFIG_I2C_VERSATILE=m
CONFIG_I2C_WMT=m
CONFIG_I2C_XILINX=m
CONFIG_I2C_XLP9XX=m
CONFIG_I2C_RCAR=m
#
# External I2C/SMBus adapter drivers
#
CONFIG_I2C_DIOLAN_U2C=m
CONFIG_I2C_DLN2=m
CONFIG_I2C_LJCA=m
CONFIG_I2C_NCT6694=m
CONFIG_I2C_USBIO=m
CONFIG_I2C_CP2615=m
CONFIG_I2C_PARPORT=m
CONFIG_I2C_PCI1XXXX=m
CONFIG_I2C_ROBOTFUZZ_OSIF=m
CONFIG_I2C_TAOS_EVM=m
CONFIG_I2C_TINY_USB=m
CONFIG_I2C_VIPERBOARD=m
#
# Other I2C/SMBus bus drivers
#
CONFIG_I2C_ELEKTOR=m
CONFIG_I2C_MLXCPLD=m
CONFIG_I2C_PCA_ISA=m
CONFIG_I2C_CROS_EC_TUNNEL=m
CONFIG_SCx200_ACB=m
CONFIG_I2C_FSI=m
CONFIG_I2C_VIRTIO=m
# end of I2C Hardware Bus support
CONFIG_I2C_STUB=m
CONFIG_I2C_SLAVE=y
CONFIG_I2C_SLAVE_EEPROM=m
CONFIG_I2C_SLAVE_TESTUNIT=m
CONFIG_I2C_DEBUG_CORE=y
CONFIG_I2C_DEBUG_ALGO=y
CONFIG_I2C_DEBUG_BUS=y
# end of I2C support
CONFIG_I3C=m
CONFIG_ADI_I3C_MASTER=m
CONFIG_CDNS_I3C_MASTER=m
CONFIG_DW_I3C_MASTER=m
CONFIG_AST2600_I3C_MASTER=m
CONFIG_SVC_I3C_MASTER=m
CONFIG_MIPI_I3C_HCI=m
CONFIG_MIPI_I3C_HCI_PCI=m
CONFIG_RENESAS_I3C=m
CONFIG_SPI=y
CONFIG_SPI_DEBUG=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SPI_OFFLOAD=y
#
# SPI Master Controller Drivers
#
CONFIG_SPI_AIROHA_SNFI=m
CONFIG_SPI_ALTERA=m
CONFIG_SPI_ALTERA_CORE=m
CONFIG_SPI_ALTERA_DFL=m
CONFIG_SPI_AMLOGIC_SPIFC_A1=m
CONFIG_SPI_AMLOGIC_SPIFC_A4=m
CONFIG_SPI_AMLOGIC_SPISG=m
CONFIG_SPI_APPLE=m
CONFIG_SPI_AR934X=m
CONFIG_SPI_ATH79=m
CONFIG_SPI_ARMADA_3700=m
CONFIG_SPI_ASPEED_SMC=m
CONFIG_SPI_ATMEL=m
CONFIG_SPI_AT91_USART=m
CONFIG_SPI_ATMEL_QUADSPI=m
CONFIG_SPI_AXI_SPI_ENGINE=m
CONFIG_SPI_AXIADO=m
CONFIG_SPI_BCM2835=m
CONFIG_SPI_BCM2835AUX=m
CONFIG_SPI_BCM63XX=m
CONFIG_SPI_BCM63XX_HSSPI=m
CONFIG_SPI_BCM_QSPI=m
CONFIG_SPI_BCMBCA_HSSPI=m
CONFIG_SPI_BITBANG=m
CONFIG_SPI_BUTTERFLY=m
CONFIG_SPI_CADENCE=m
CONFIG_SPI_CADENCE_QUADSPI=m
CONFIG_SPI_CH341=m
CONFIG_SPI_CLPS711X=m
CONFIG_SPI_CS42L43=m
CONFIG_SPI_DAVINCI=m
CONFIG_SPI_DESIGNWARE=m
CONFIG_SPI_DW_DMA=y
CONFIG_SPI_DW_PCI=m
CONFIG_SPI_DW_MMIO=m
CONFIG_SPI_DLN2=m
CONFIG_SPI_EP93XX=m
CONFIG_SPI_FSI=m
CONFIG_SPI_FSL_LPSPI=m
CONFIG_SPI_FSL_QUADSPI=m
CONFIG_SPI_GXP=m
CONFIG_SPI_HISI_KUNPENG=m
CONFIG_SPI_HISI_SFC_V3XX=m
CONFIG_SPI_NXP_FLEXSPI=m
CONFIG_SPI_NXP_XSPI=m
CONFIG_SPI_GPIO=m
CONFIG_SPI_IMG_SPFI=m
CONFIG_SPI_IMX=m
CONFIG_SPI_INGENIC=m
CONFIG_SPI_INTEL=m
CONFIG_SPI_INTEL_PCI=m
CONFIG_SPI_INTEL_PLATFORM=m
CONFIG_SPI_JCORE=m
CONFIG_SPI_KSPI2=m
CONFIG_SPI_LM70_LLP=m
CONFIG_SPI_LOONGSON_CORE=m
CONFIG_SPI_LOONGSON_PCI=m
CONFIG_SPI_LOONGSON_PLATFORM=m
CONFIG_SPI_LP8841_RTC=m
CONFIG_SPI_FSL_LIB=m
CONFIG_SPI_FSL_SPI=m
CONFIG_SPI_FSL_DSPI=m
CONFIG_SPI_LJCA=m
CONFIG_SPI_MESON_SPICC=m
CONFIG_SPI_MESON_SPIFC=m
CONFIG_SPI_MICROCHIP_CORE_QSPI=m
CONFIG_SPI_MICROCHIP_CORE_SPI=m
CONFIG_SPI_MT65XX=m
CONFIG_SPI_MT7621=m
CONFIG_SPI_MTK_NOR=m
CONFIG_SPI_MTK_SNFI=m
CONFIG_SPI_WPCM_FIU=m
CONFIG_SPI_NPCM_FIU=m
CONFIG_SPI_NPCM_PSPI=m
CONFIG_SPI_LANTIQ_SSC=m
CONFIG_SPI_OC_TINY=m
CONFIG_SPI_OMAP24XX=m
CONFIG_SPI_TI_QSPI=m
CONFIG_SPI_ORION=m
CONFIG_SPI_PCI1XXXX=m
CONFIG_SPI_PIC32=m
CONFIG_SPI_PIC32_SQI=m
CONFIG_SPI_POLARFIRE_SOC=m
CONFIG_SPI_PXA2XX=m
CONFIG_SPI_PXA2XX_PCI=m
CONFIG_SPI_REALTEK_SNAND=m
CONFIG_SPI_ROCKCHIP=m
CONFIG_SPI_ROCKCHIP_SFC=m
CONFIG_SPI_RB4XX=m
CONFIG_SPI_RPCIF=m
CONFIG_SPI_RSPI=m
CONFIG_SPI_RZV2H_RSPI=m
CONFIG_SPI_RZV2M_CSI=m
CONFIG_SPI_QCOM_QSPI=m
CONFIG_SPI_QPIC_SNAND=m
CONFIG_SPI_QUP=m
CONFIG_SPI_QCOM_GENI=m
CONFIG_SPI_S3C64XX=m
CONFIG_SPI_SC18IS602=m
CONFIG_SPI_SH_MSIOF=m
CONFIG_SPI_SH=m
CONFIG_SPI_SH_HSPI=m
CONFIG_SPI_SIFIVE=m
CONFIG_SPI_SLAVE_MT27XX=m
CONFIG_SPI_SN_F_OSPI=m
CONFIG_SPI_SG2044_NOR=m
CONFIG_SPI_SPRD=m
CONFIG_SPI_SPRD_ADI=m
CONFIG_SPI_STM32=m
CONFIG_SPI_STM32_OSPI=m
CONFIG_SPI_STM32_QSPI=m
CONFIG_SPI_ST_SSC4=m
CONFIG_SPI_SUN4I=m
CONFIG_SPI_SUN6I=m
CONFIG_SPI_SUNPLUS_SP7021=m
CONFIG_SPI_SYNQUACER=m
CONFIG_SPI_MXIC=m
CONFIG_SPI_TEGRA210_QUAD=m
CONFIG_SPI_TEGRA114=m
CONFIG_SPI_TEGRA20_SFLASH=m
CONFIG_SPI_TEGRA20_SLINK=m
CONFIG_SPI_TOPCLIFF_PCH=m
CONFIG_SPI_UNIPHIER=m
CONFIG_SPI_VIRTIO=m
CONFIG_SPI_XCOMM=m
CONFIG_SPI_XILINX=m
CONFIG_SPI_XLP=m
CONFIG_SPI_XTENSA_XTFPGA=m
CONFIG_SPI_ZYNQ_QSPI=m
CONFIG_SPI_ZYNQMP_GQSPI=m
CONFIG_SPI_AMD=m
#
# SPI Multiplexer support
#
CONFIG_SPI_MUX=m
#
# SPI Protocol Masters
#
CONFIG_SPI_SPIDEV=m
CONFIG_SPI_LOOPBACK_TEST=m
CONFIG_SPI_TLE62X0=m
CONFIG_SPI_SLAVE=y
CONFIG_SPI_SLAVE_TIME=m
CONFIG_SPI_SLAVE_SYSTEM_CONTROL=m
CONFIG_SPI_DYNAMIC=y
#
# SPI Offload triggers
#
CONFIG_SPI_OFFLOAD_TRIGGER_ADI_UTIL_SD=m
CONFIG_SPI_OFFLOAD_TRIGGER_PWM=m
CONFIG_SPMI=m
CONFIG_SPMI_APPLE=m
CONFIG_SPMI_HISI3670=m
CONFIG_SPMI_MSM_PMIC_ARB=m
CONFIG_SPMI_MTK_PMIF=m
CONFIG_HSI=m
CONFIG_HSI_BOARDINFO=y
#
# HSI controllers
#
#
# HSI clients
#
CONFIG_HSI_CHAR=m
CONFIG_PPS=m
CONFIG_PPS_DEBUG=y
#
# PPS clients support
#
CONFIG_PPS_CLIENT_KTIMER=m
CONFIG_PPS_CLIENT_LDISC=m
CONFIG_PPS_CLIENT_PARPORT=m
CONFIG_PPS_CLIENT_GPIO=m
CONFIG_PPS_GENERATOR=m
CONFIG_PPS_GENERATOR_DUMMY=m
CONFIG_PPS_GENERATOR_TIO=m
#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=m
CONFIG_PTP_1588_CLOCK_OPTIONAL=m
CONFIG_PTP_1588_CLOCK_DTE=m
CONFIG_PTP_1588_CLOCK_QORIQ=m
CONFIG_DP83640_PHY=m
CONFIG_PTP_1588_CLOCK_INES=m
CONFIG_PTP_1588_CLOCK_PCH=m
CONFIG_PTP_1588_CLOCK_KVM=m
CONFIG_PTP_1588_CLOCK_IDT82P33=m
CONFIG_PTP_1588_CLOCK_IDTCM=m
CONFIG_PTP_1588_CLOCK_FC3W=m
CONFIG_PTP_1588_CLOCK_MOCK=m
CONFIG_PTP_1588_CLOCK_VMW=m
CONFIG_PTP_1588_CLOCK_OCP=m
CONFIG_PTP_DFL_TOD=m
CONFIG_PTP_NETC_V4_TIMER=m
# end of PTP clock support
#
# DPLL device support
#
CONFIG_DPLL=y
CONFIG_DPLL_REFCNT_TRACKER=y
CONFIG_ZL3073X=m
CONFIG_ZL3073X_I2C=m
CONFIG_ZL3073X_SPI=m
# end of DPLL device support
CONFIG_PINCTRL=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_PINMUX=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_PINCONF=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_PINCTRL=y
CONFIG_DEBUG_PINCTRL=y
CONFIG_PINCTRL_AMD=y
CONFIG_PINCTRL_AMDISP=m
CONFIG_PINCTRL_AS3722=m
CONFIG_PINCTRL_AT91=y
CONFIG_PINCTRL_AT91PIO4=y
CONFIG_PINCTRL_AXP209=m
CONFIG_PINCTRL_AW9523=m
CONFIG_PINCTRL_BM1880=y
CONFIG_PINCTRL_CY8C95X0=m
CONFIG_PINCTRL_DA850_PUPD=m
CONFIG_PINCTRL_DA9062=m
CONFIG_PINCTRL_EIC7700=m
CONFIG_PINCTRL_EQUILIBRIUM=m
CONFIG_PINCTRL_EYEQ5=y
CONFIG_PINCTRL_INGENIC=y
CONFIG_PINCTRL_K210=y
CONFIG_PINCTRL_K230=y
CONFIG_PINCTRL_LOONGSON2=m
CONFIG_PINCTRL_LPC18XX=y
CONFIG_PINCTRL_MAX7360=m
CONFIG_PINCTRL_MAX77620=m
CONFIG_PINCTRL_MCP23S08_I2C=m
CONFIG_PINCTRL_MCP23S08_SPI=m
CONFIG_PINCTRL_MCP23S08=m
CONFIG_PINCTRL_MICROCHIP_SGPIO=m
CONFIG_PINCTRL_OCELOT=m
CONFIG_PINCTRL_PALMAS=m
CONFIG_PINCTRL_PEF2256=m
CONFIG_PINCTRL_PISTACHIO=y
CONFIG_PINCTRL_RK805=m
CONFIG_PINCTRL_ROCKCHIP=m
CONFIG_PINCTRL_SCMI=m
CONFIG_PINCTRL_SINGLE=m
CONFIG_PINCTRL_STMFX=m
CONFIG_PINCTRL_SX150X=m
CONFIG_PINCTRL_TB10X=y
CONFIG_PINCTRL_TPS6594=m
CONFIG_PINCTRL_TH1520=m
CONFIG_PINCTRL_UPBOARD=m
CONFIG_PINCTRL_ZYNQ=y
CONFIG_PINCTRL_MLXBF3=m
CONFIG_PINCTRL_RP1=m
CONFIG_PINCTRL_OWL=y
CONFIG_PINCTRL_S500=y
CONFIG_PINCTRL_S700=y
CONFIG_PINCTRL_S900=y
CONFIG_PINCTRL_ASPEED=y
CONFIG_PINCTRL_ASPEED_G4=y
CONFIG_PINCTRL_ASPEED_G5=y
CONFIG_PINCTRL_ASPEED_G6=y
CONFIG_PINCTRL_BCM281XX=y
CONFIG_PINCTRL_BCM2835=m
CONFIG_PINCTRL_BCM4908=m
CONFIG_PINCTRL_BCM63XX=y
CONFIG_PINCTRL_BCM6318=y
CONFIG_PINCTRL_BCM6328=y
CONFIG_PINCTRL_BCM6358=y
CONFIG_PINCTRL_BCM6362=y
CONFIG_PINCTRL_BCM6368=y
CONFIG_PINCTRL_BCM63268=y
CONFIG_PINCTRL_BRCMSTB=m
CONFIG_PINCTRL_BCM2712=m
CONFIG_PINCTRL_IPROC_GPIO=y
CONFIG_PINCTRL_CYGNUS_MUX=y
CONFIG_PINCTRL_NS=y
CONFIG_PINCTRL_NSP_GPIO=y
CONFIG_PINCTRL_NS2_MUX=y
CONFIG_PINCTRL_NSP_MUX=y
CONFIG_PINCTRL_BERLIN=y
CONFIG_PINCTRL_AS370=y
CONFIG_PINCTRL_BERLIN_BG4CT=y
CONFIG_PINCTRL_CS42L43=m
CONFIG_PINCTRL_LOCHNAGAR=m
CONFIG_PINCTRL_MADERA=m
CONFIG_PINCTRL_CS47L15=y
CONFIG_PINCTRL_CS47L35=y
CONFIG_PINCTRL_CS47L85=y
CONFIG_PINCTRL_CS47L90=y
CONFIG_PINCTRL_CS47L92=y
CONFIG_PINCTRL_SKY1_BASE=m
CONFIG_PINCTRL_SKY1=m
CONFIG_PINCTRL_IMX=y
CONFIG_PINCTRL_IMX_SCMI=m
CONFIG_PINCTRL_IMX_SCU=y
CONFIG_PINCTRL_IMX1_CORE=y
CONFIG_PINCTRL_IMX1=y
CONFIG_PINCTRL_IMX27=y
CONFIG_PINCTRL_IMX25=y
CONFIG_PINCTRL_IMX35=y
CONFIG_PINCTRL_IMX50=y
CONFIG_PINCTRL_IMX51=y
CONFIG_PINCTRL_IMX53=y
CONFIG_PINCTRL_IMX6Q=y
CONFIG_PINCTRL_IMX6SL=y
CONFIG_PINCTRL_IMX6SLL=y
CONFIG_PINCTRL_IMX6SX=y
CONFIG_PINCTRL_IMX6UL=y
CONFIG_PINCTRL_IMX7D=y
CONFIG_PINCTRL_IMX7ULP=y
CONFIG_PINCTRL_IMX8MM=m
CONFIG_PINCTRL_IMX8MN=m
CONFIG_PINCTRL_IMX8MP=m
CONFIG_PINCTRL_IMX8MQ=m
CONFIG_PINCTRL_IMX8QM=m
CONFIG_PINCTRL_IMX8QXP=m
CONFIG_PINCTRL_IMX8DXL=m
CONFIG_PINCTRL_IMX8ULP=m
CONFIG_PINCTRL_IMXRT1050=y
CONFIG_PINCTRL_IMX93=m
CONFIG_PINCTRL_VF610=y
CONFIG_PINCTRL_IMXRT1170=y
#
# Intel pinctrl drivers
#
CONFIG_PINCTRL_BAYTRAIL=y
CONFIG_PINCTRL_CHERRYVIEW=m
CONFIG_PINCTRL_LYNXPOINT=m
CONFIG_PINCTRL_INTEL=y
CONFIG_PINCTRL_INTEL_PLATFORM=m
CONFIG_PINCTRL_ALDERLAKE=m
CONFIG_PINCTRL_BROXTON=m
CONFIG_PINCTRL_CANNONLAKE=m
CONFIG_PINCTRL_CEDARFORK=m
CONFIG_PINCTRL_DENVERTON=m
CONFIG_PINCTRL_ELKHARTLAKE=m
CONFIG_PINCTRL_EMMITSBURG=m
CONFIG_PINCTRL_GEMINILAKE=m
CONFIG_PINCTRL_ICELAKE=m
CONFIG_PINCTRL_JASPERLAKE=m
CONFIG_PINCTRL_LAKEFIELD=m
CONFIG_PINCTRL_LEWISBURG=m
CONFIG_PINCTRL_METEORLAKE=m
CONFIG_PINCTRL_METEORPOINT=m
CONFIG_PINCTRL_SUNRISEPOINT=m
CONFIG_PINCTRL_TIGERLAKE=m
CONFIG_PINCTRL_TANGIER=m
CONFIG_PINCTRL_MERRIFIELD=m
CONFIG_PINCTRL_MOOREFIELD=m
# end of Intel pinctrl drivers
#
# MediaTek pinctrl drivers
#
CONFIG_EINT_MTK=y
CONFIG_PINCTRL_MTK=y
CONFIG_PINCTRL_MTK_V2=y
CONFIG_PINCTRL_MTK_MOORE=y
CONFIG_PINCTRL_MTK_PARIS=y
CONFIG_PINCTRL_MT2701=y
CONFIG_PINCTRL_MT7623=y
CONFIG_PINCTRL_MT7629=y
CONFIG_PINCTRL_MT8135=y
CONFIG_PINCTRL_MT8127=y
CONFIG_PINCTRL_AIROHA=m
CONFIG_PINCTRL_MT2712=y
CONFIG_PINCTRL_MT6765=m
CONFIG_PINCTRL_MT6779=m
CONFIG_PINCTRL_MT6795=y
CONFIG_PINCTRL_MT6797=y
CONFIG_PINCTRL_MT6878=y
CONFIG_PINCTRL_MT6893=y
CONFIG_PINCTRL_MT7622=y
CONFIG_PINCTRL_MT7981=y
CONFIG_PINCTRL_MT7986=y
CONFIG_PINCTRL_MT7988=y
CONFIG_PINCTRL_MT8167=y
CONFIG_PINCTRL_MT8173=y
CONFIG_PINCTRL_MT8183=y
CONFIG_PINCTRL_MT8186=y
CONFIG_PINCTRL_MT8188=y
CONFIG_PINCTRL_MT8189=y
CONFIG_PINCTRL_MT8192=y
CONFIG_PINCTRL_MT8195=y
CONFIG_PINCTRL_MT8196=y
CONFIG_PINCTRL_MT8365=y
CONFIG_PINCTRL_MT8516=y
CONFIG_PINCTRL_MT6397=y
# end of MediaTek pinctrl drivers
CONFIG_PINCTRL_MESON=m
CONFIG_PINCTRL_MESON8=y
CONFIG_PINCTRL_MESON8B=y
CONFIG_PINCTRL_MESON_GXBB=m
CONFIG_PINCTRL_MESON_GXL=m
CONFIG_PINCTRL_MESON8_PMX=m
CONFIG_PINCTRL_MESON_AXG=m
CONFIG_PINCTRL_MESON_AXG_PMX=m
CONFIG_PINCTRL_MESON_G12A=m
CONFIG_PINCTRL_MESON_A1=m
CONFIG_PINCTRL_MESON_S4=m
CONFIG_PINCTRL_AMLOGIC_A4=y
CONFIG_PINCTRL_AMLOGIC_C3=m
CONFIG_PINCTRL_AMLOGIC_T7=m
CONFIG_PINCTRL_PIC64GX=y
CONFIG_PINCTRL_POLARFIRE_SOC=y
CONFIG_PINCTRL_NOMADIK=y
CONFIG_PINCTRL_WPCM450=m
CONFIG_PINCTRL_NPCM7XX=y
CONFIG_PINCTRL_NPCM8XX=m
CONFIG_PINCTRL_MA35=y
CONFIG_PINCTRL_MA35D1=y
CONFIG_PINCTRL_PXA=y
CONFIG_PINCTRL_PXA25X=m
CONFIG_PINCTRL_PXA27X=m
CONFIG_PINCTRL_MSM=m
CONFIG_PINCTRL_APQ8064=m
CONFIG_PINCTRL_APQ8084=m
CONFIG_PINCTRL_GLYMUR=m
CONFIG_PINCTRL_IPQ4019=m
CONFIG_PINCTRL_IPQ5018=m
CONFIG_PINCTRL_IPQ8064=m
CONFIG_PINCTRL_IPQ5332=m
CONFIG_PINCTRL_IPQ5424=m
CONFIG_PINCTRL_IPQ8074=m
CONFIG_PINCTRL_IPQ6018=m
CONFIG_PINCTRL_IPQ9574=m
CONFIG_PINCTRL_KAANAPALI=m
CONFIG_PINCTRL_MSM8226=m
CONFIG_PINCTRL_MSM8660=m
CONFIG_PINCTRL_MSM8960=m
CONFIG_PINCTRL_MDM9607=m
CONFIG_PINCTRL_MDM9615=m
CONFIG_PINCTRL_MSM8X74=m
CONFIG_PINCTRL_MSM8909=m
CONFIG_PINCTRL_MSM8916=m
CONFIG_PINCTRL_MSM8917=m
CONFIG_PINCTRL_MSM8953=m
CONFIG_PINCTRL_MSM8976=m
CONFIG_PINCTRL_MSM8994=m
CONFIG_PINCTRL_MSM8996=m
CONFIG_PINCTRL_MSM8998=m
CONFIG_PINCTRL_QCM2290=m
CONFIG_PINCTRL_QCS404=m
CONFIG_PINCTRL_QCS615=m
CONFIG_PINCTRL_QCS8300=m
CONFIG_PINCTRL_QDF2XXX=m
CONFIG_PINCTRL_QDU1000=m
CONFIG_PINCTRL_SA8775P=m
CONFIG_PINCTRL_SAR2130P=m
CONFIG_PINCTRL_SC7180=m
CONFIG_PINCTRL_SC7280=m
CONFIG_PINCTRL_SC8180X=m
CONFIG_PINCTRL_SC8280XP=m
CONFIG_PINCTRL_SDM660=m
CONFIG_PINCTRL_SDM670=m
CONFIG_PINCTRL_SDM845=m
CONFIG_PINCTRL_SDX55=m
CONFIG_PINCTRL_SDX65=m
CONFIG_PINCTRL_SDX75=m
CONFIG_PINCTRL_SM4450=m
CONFIG_PINCTRL_SM6115=m
CONFIG_PINCTRL_SM6125=m
CONFIG_PINCTRL_SM6350=m
CONFIG_PINCTRL_SM6375=m
CONFIG_PINCTRL_SM7150=m
CONFIG_PINCTRL_MILOS=m
CONFIG_PINCTRL_SM8150=m
CONFIG_PINCTRL_SM8250=m
CONFIG_PINCTRL_SM8350=m
CONFIG_PINCTRL_SM8450=m
CONFIG_PINCTRL_SM8550=m
CONFIG_PINCTRL_SM8650=m
CONFIG_PINCTRL_SM8750=m
CONFIG_PINCTRL_X1E80100=m
CONFIG_PINCTRL_TLMM_TEST=m
CONFIG_PINCTRL_QCOM_SPMI_PMIC=m
CONFIG_PINCTRL_QCOM_SSBI_PMIC=m
CONFIG_PINCTRL_LPASS_LPI=m
CONFIG_PINCTRL_SC7280_LPASS_LPI=m
CONFIG_PINCTRL_SDM660_LPASS_LPI=m
CONFIG_PINCTRL_SM4250_LPASS_LPI=m
CONFIG_PINCTRL_SM6115_LPASS_LPI=m
CONFIG_PINCTRL_SM8250_LPASS_LPI=m
CONFIG_PINCTRL_SM8450_LPASS_LPI=m
CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m
CONFIG_PINCTRL_SM8550_LPASS_LPI=m
CONFIG_PINCTRL_SM8650_LPASS_LPI=m
#
# Renesas pinctrl drivers
#
CONFIG_PINCTRL_RENESAS=y
CONFIG_PINCTRL_SH_PFC=y
CONFIG_PINCTRL_SH_PFC_GPIO=y
CONFIG_PINCTRL_SH_FUNC_GPIO=y
CONFIG_PINCTRL_PFC_EMEV2=y
CONFIG_PINCTRL_PFC_R8A73A4=y
CONFIG_PINCTRL_PFC_R8A7740=y
CONFIG_PINCTRL_PFC_R8A7742=y
CONFIG_PINCTRL_PFC_R8A7743=y
CONFIG_PINCTRL_PFC_R8A7744=y
CONFIG_PINCTRL_PFC_R8A7745=y
CONFIG_PINCTRL_PFC_R8A77470=y
CONFIG_PINCTRL_PFC_R8A774A1=y
CONFIG_PINCTRL_PFC_R8A774B1=y
CONFIG_PINCTRL_PFC_R8A774C0=y
CONFIG_PINCTRL_PFC_R8A774E1=y
CONFIG_PINCTRL_PFC_R8A7778=y
CONFIG_PINCTRL_PFC_R8A7779=y
CONFIG_PINCTRL_PFC_R8A7790=y
CONFIG_PINCTRL_PFC_R8A7791=y
CONFIG_PINCTRL_PFC_R8A7792=y
CONFIG_PINCTRL_PFC_R8A7793=y
CONFIG_PINCTRL_PFC_R8A7794=y
CONFIG_PINCTRL_PFC_R8A77951=y
CONFIG_PINCTRL_PFC_R8A77960=y
CONFIG_PINCTRL_PFC_R8A77961=y
CONFIG_PINCTRL_PFC_R8A77965=y
CONFIG_PINCTRL_PFC_R8A77970=y
CONFIG_PINCTRL_PFC_R8A77980=y
CONFIG_PINCTRL_PFC_R8A77990=y
CONFIG_PINCTRL_PFC_R8A77995=y
CONFIG_PINCTRL_PFC_R8A779A0=y
CONFIG_PINCTRL_PFC_R8A779F0=y
CONFIG_PINCTRL_PFC_R8A779G0=y
CONFIG_PINCTRL_PFC_R8A779H0=y
CONFIG_PINCTRL_PFC_SH7203=y
CONFIG_PINCTRL_PFC_SH7264=y
CONFIG_PINCTRL_PFC_SH7269=y
CONFIG_PINCTRL_PFC_SH73A0=y
CONFIG_PINCTRL_PFC_SH7720=y
CONFIG_PINCTRL_PFC_SH7722=y
CONFIG_PINCTRL_PFC_SH7723=y
CONFIG_PINCTRL_PFC_SH7724=y
CONFIG_PINCTRL_PFC_SH7734=y
CONFIG_PINCTRL_PFC_SH7757=y
CONFIG_PINCTRL_PFC_SH7785=y
CONFIG_PINCTRL_PFC_SH7786=y
CONFIG_PINCTRL_PFC_SHX3=y
CONFIG_PINCTRL_RZA1=y
CONFIG_PINCTRL_RZA2=y
CONFIG_PINCTRL_RZG2L=y
CONFIG_PINCTRL_RZN1=y
CONFIG_PINCTRL_RZV2M=y
# end of Renesas pinctrl drivers
CONFIG_PINCTRL_SAMSUNG=y
CONFIG_PINCTRL_EXYNOS=y
CONFIG_PINCTRL_EXYNOS_ARM=y
CONFIG_PINCTRL_EXYNOS_ARM64=y
CONFIG_PINCTRL_S3C64XX=y
CONFIG_PINCTRL_SOPHGO_COMMON=m
CONFIG_PINCTRL_SOPHGO_CV18XX_OPS=y
CONFIG_PINCTRL_SOPHGO_CV1800B=m
CONFIG_PINCTRL_SOPHGO_CV1812H=m
CONFIG_PINCTRL_SOPHGO_SG2000=m
CONFIG_PINCTRL_SOPHGO_SG2002=m
CONFIG_PINCTRL_SOPHGO_SG2042_OPS=y
CONFIG_PINCTRL_SOPHGO_SG2042=m
CONFIG_PINCTRL_SOPHGO_SG2044=m
CONFIG_PINCTRL_SPACEMIT_K1=y
CONFIG_PINCTRL_SPRD=m
CONFIG_PINCTRL_SPRD_SC9860=m
CONFIG_PINCTRL_STARFIVE_JH7100=m
CONFIG_PINCTRL_STARFIVE_JH7110=y
CONFIG_PINCTRL_STARFIVE_JH7110_SYS=m
CONFIG_PINCTRL_STARFIVE_JH7110_AON=m
CONFIG_PINCTRL_STM32=y
CONFIG_PINCTRL_STM32F429=y
CONFIG_PINCTRL_STM32F469=y
CONFIG_PINCTRL_STM32F746=y
CONFIG_PINCTRL_STM32F769=y
CONFIG_PINCTRL_STM32H743=y
CONFIG_PINCTRL_STM32MP135=y
CONFIG_PINCTRL_STM32MP157=y
CONFIG_PINCTRL_STM32MP257=m
CONFIG_PINCTRL_STM32_HDP=m
CONFIG_PINCTRL_TI_IODELAY=m
CONFIG_PINCTRL_UNIPHIER=y
CONFIG_PINCTRL_UNIPHIER_LD4=y
CONFIG_PINCTRL_UNIPHIER_PRO4=y
CONFIG_PINCTRL_UNIPHIER_SLD8=y
CONFIG_PINCTRL_UNIPHIER_PRO5=y
CONFIG_PINCTRL_UNIPHIER_PXS2=y
CONFIG_PINCTRL_UNIPHIER_LD6B=y
CONFIG_PINCTRL_UNIPHIER_LD11=y
CONFIG_PINCTRL_UNIPHIER_LD20=y
CONFIG_PINCTRL_UNIPHIER_PXS3=y
CONFIG_PINCTRL_UNIPHIER_NX1=y
CONFIG_PINCTRL_VISCONTI=y
CONFIG_PINCTRL_TMPV7700=y
CONFIG_GPIOLIB_LEGACY=y
CONFIG_GPIOLIB=y
CONFIG_GPIOLIB_FASTPATH_LIMIT=512
CONFIG_OF_GPIO=y
CONFIG_GPIO_ACPI=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_SHARED=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_SYSFS_LEGACY=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_CDEV_V1=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_REGMAP=y
CONFIG_GPIO_SWNODE_UNDEFINED=y
CONFIG_GPIO_MAX730X=m
CONFIG_GPIO_IDIO_16=m
#
# Memory mapped GPIO drivers
#
CONFIG_GPIO_74XX_MMIO=m
CONFIG_GPIO_ALTERA=m
CONFIG_GPIO_AMDPT=m
CONFIG_GPIO_ASPEED=m
CONFIG_GPIO_ASPEED_SGPIO=y
CONFIG_GPIO_ATH79=m
CONFIG_GPIO_RASPBERRYPI_EXP=m
CONFIG_GPIO_BCM_KONA=y
CONFIG_GPIO_BCM_XGS_IPROC=m
CONFIG_GPIO_BLZP1600=m
CONFIG_GPIO_BRCMSTB=m
CONFIG_GPIO_CADENCE=m
CONFIG_GPIO_CLPS711X=m
CONFIG_GPIO_DAVINCI=m
CONFIG_GPIO_DWAPB=m
CONFIG_GPIO_EIC_SPRD=m
CONFIG_GPIO_EM=m
CONFIG_GPIO_EP93XX=y
CONFIG_GPIO_EXAR=m
CONFIG_GPIO_GE_FPGA=y
CONFIG_GPIO_FTGPIO010=y
CONFIG_GPIO_GENERIC_PLATFORM=m
CONFIG_GPIO_GRANITERAPIDS=m
CONFIG_GPIO_GRGPIO=m
CONFIG_GPIO_HISI=m
CONFIG_GPIO_HLWD=m
CONFIG_GPIO_ICH=m
CONFIG_GPIO_IMX_SCU=y
CONFIG_GPIO_IXP4XX=y
CONFIG_GPIO_LOGICVC=m
CONFIG_GPIO_LOONGSON_64BIT=m
CONFIG_GPIO_LPC18XX=m
CONFIG_GPIO_LPC32XX=m
CONFIG_GPIO_MB86S7X=m
CONFIG_GPIO_MENZ127=m
CONFIG_GPIO_MPC8XXX=y
CONFIG_GPIO_MT7621=y
CONFIG_GPIO_MVEBU=y
CONFIG_GPIO_MXC=m
CONFIG_GPIO_MXS=y
CONFIG_GPIO_NOMADIK=y
CONFIG_GPIO_NPCM_SGPIO=y
CONFIG_GPIO_OMAP=m
CONFIG_GPIO_PL061=m
CONFIG_GPIO_POLARFIRE_SOC=y
CONFIG_GPIO_PXA=y
CONFIG_GPIO_RCAR=m
CONFIG_GPIO_RDA=y
CONFIG_GPIO_REALTEK_OTTO=m
CONFIG_GPIO_ROCKCHIP=m
CONFIG_GPIO_RTD=m
CONFIG_GPIO_SAMA5D2_PIOBU=m
CONFIG_GPIO_SIFIVE=m
CONFIG_GPIO_SIOX=m
CONFIG_GPIO_SNPS_CREG=y
CONFIG_GPIO_SPACEMIT_K1=m
CONFIG_GPIO_SPRD=m
CONFIG_GPIO_STP_XWAY=y
CONFIG_GPIO_SYSCON=m
CONFIG_GPIO_TANGIER=m
CONFIG_GPIO_TB10X=y
CONFIG_GPIO_TEGRA=m
CONFIG_GPIO_TEGRA186=m
CONFIG_GPIO_TS4800=m
CONFIG_GPIO_UNIPHIER=m
CONFIG_GPIO_VF610=m
CONFIG_GPIO_VISCONTI=m
CONFIG_GPIO_WCD934X=m
CONFIG_GPIO_XGENE_SB=m
CONFIG_GPIO_XILINX=m
CONFIG_GPIO_XLP=m
CONFIG_GPIO_ZYNQ=m
CONFIG_GPIO_ZYNQMP_MODEPIN=m
CONFIG_GPIO_LOONGSON1=m
CONFIG_GPIO_AMD_FCH=m
CONFIG_GPIO_MSC313=y
CONFIG_GPIO_IDT3243X=m
# end of Memory mapped GPIO drivers
#
# Port-mapped I/O GPIO drivers
#
CONFIG_GPIO_VX855=m
CONFIG_GPIO_I8255=m
CONFIG_GPIO_104_DIO_48E=m
CONFIG_GPIO_104_IDIO_16=m
CONFIG_GPIO_104_IDI_48=m
CONFIG_GPIO_F7188X=m
CONFIG_GPIO_GPIO_MM=m
CONFIG_GPIO_IT87=m
CONFIG_GPIO_SCH=m
CONFIG_GPIO_SCH311X=m
CONFIG_GPIO_TS5500=m
CONFIG_GPIO_WINBOND=m
CONFIG_GPIO_WS16C48=m
# end of Port-mapped I/O GPIO drivers
#
# I2C GPIO expanders
#
CONFIG_GPIO_ADNP=m
CONFIG_GPIO_FXL6408=m
CONFIG_GPIO_DS4520=m
CONFIG_GPIO_GW_PLD=m
CONFIG_GPIO_MAX7300=m
CONFIG_GPIO_MAX732X=m
CONFIG_GPIO_PCA953X=m
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_PCA9570=m
CONFIG_GPIO_PCF857X=m
CONFIG_GPIO_TPIC2810=m
CONFIG_GPIO_TS4900=m
# end of I2C GPIO expanders
#
# MFD GPIO expanders
#
CONFIG_GPIO_ADP5520=m
CONFIG_GPIO_ADP5585=m
CONFIG_GPIO_ARIZONA=m
CONFIG_GPIO_BD71815=m
CONFIG_GPIO_BD71828=m
CONFIG_GPIO_BD72720=m
CONFIG_GPIO_BD9571MWV=m
CONFIG_GPIO_CGBC=m
CONFIG_GPIO_CROS_EC=m
CONFIG_GPIO_CRYSTAL_COVE=m
CONFIG_GPIO_CS5535=m
CONFIG_GPIO_DA9052=m
CONFIG_GPIO_DA9055=m
CONFIG_GPIO_DLN2=m
CONFIG_HTC_EGPIO=y
CONFIG_GPIO_ELKHARTLAKE=m
CONFIG_GPIO_JANZ_TTL=m
CONFIG_GPIO_KEMPLD=m
CONFIG_GPIO_LJCA=m
CONFIG_GPIO_LP3943=m
CONFIG_GPIO_LP873X=m
CONFIG_GPIO_LP87565=m
CONFIG_GPIO_MADERA=m
CONFIG_GPIO_MAX7360=m
CONFIG_GPIO_MAX77620=m
CONFIG_GPIO_MAX77650=m
CONFIG_GPIO_MAX77759=m
CONFIG_GPIO_NCT6694=m
CONFIG_GPIO_PALMAS=m
CONFIG_GPIO_PMIC_EIC_SPRD=m
CONFIG_GPIO_QIXIS_FPGA=m
CONFIG_GPIO_RC5T583=y
CONFIG_GPIO_SL28CPLD=m
CONFIG_GPIO_STMPE=m
CONFIG_GPIO_TC3589X=y
CONFIG_GPIO_TIMBERDALE=y
CONFIG_GPIO_TN48M_CPLD=m
CONFIG_GPIO_TPS65086=m
CONFIG_GPIO_TPS65218=m
CONFIG_GPIO_TPS65219=m
CONFIG_GPIO_TPS6586X=y
CONFIG_GPIO_TPS65910=y
CONFIG_GPIO_TPS65912=m
CONFIG_GPIO_TPS68470=m
CONFIG_GPIO_TQMX86=m
CONFIG_GPIO_TWL4030=m
CONFIG_GPIO_TWL6040=m
CONFIG_GPIO_WHISKEY_COVE=m
CONFIG_GPIO_WM831X=m
CONFIG_GPIO_WM8350=m
CONFIG_GPIO_WM8994=m
# end of MFD GPIO expanders
#
# PCI GPIO expanders
#
CONFIG_GPIO_AMD8111=m
CONFIG_GPIO_BT8XX=m
CONFIG_GPIO_MERRIFIELD=m
CONFIG_GPIO_MLXBF3=m
CONFIG_GPIO_ML_IOH=m
CONFIG_GPIO_PCH=m
CONFIG_GPIO_PCI_IDIO_16=m
CONFIG_GPIO_PCIE_IDIO_24=m
CONFIG_GPIO_RDC321X=m
CONFIG_GPIO_SODAVILLE=y
# end of PCI GPIO expanders
#
# SPI GPIO expanders
#
CONFIG_GPIO_74X164=m
CONFIG_GPIO_MAX3191X=m
CONFIG_GPIO_MAX7301=m
CONFIG_GPIO_MC33880=m
CONFIG_GPIO_PISOSR=m
CONFIG_GPIO_XRA1403=m
CONFIG_GPIO_MOXTET=m
# end of SPI GPIO expanders
#
# USB GPIO expanders
#
CONFIG_GPIO_VIPERBOARD=m
CONFIG_GPIO_MPSSE=m
CONFIG_GPIO_USBIO=m
# end of USB GPIO expanders
#
# Virtual GPIO drivers
#
CONFIG_GPIO_AGGREGATOR=m
CONFIG_GPIO_LATCH=m
CONFIG_GPIO_LINE_MUX=m
CONFIG_GPIO_MOCKUP=m
CONFIG_GPIO_VIRTIO=m
CONFIG_GPIO_SIM=m
CONFIG_GPIO_SHARED_PROXY=m
# end of Virtual GPIO drivers
#
# GPIO Debugging utilities
#
CONFIG_GPIO_SLOPPY_LOGIC_ANALYZER=m
CONFIG_GPIO_VIRTUSER=m
# end of GPIO Debugging utilities
CONFIG_DEV_SYNC_PROBE=m
CONFIG_W1=m
CONFIG_W1_CON=y
#
# 1-wire Bus Masters
#
CONFIG_W1_MASTER_AMD_AXI=m
CONFIG_W1_MASTER_MATROX=m
CONFIG_W1_MASTER_DS2490=m
CONFIG_W1_MASTER_DS2482=m
CONFIG_W1_MASTER_MXC=m
CONFIG_W1_MASTER_GPIO=m
CONFIG_HDQ_MASTER_OMAP=m
CONFIG_W1_MASTER_SGI=m
CONFIG_W1_MASTER_UART=m
# end of 1-wire Bus Masters
#
# 1-wire Slaves
#
CONFIG_W1_SLAVE_THERM=m
CONFIG_W1_SLAVE_SMEM=m
CONFIG_W1_SLAVE_DS2405=m
CONFIG_W1_SLAVE_DS2408=m
CONFIG_W1_SLAVE_DS2408_READBACK=y
CONFIG_W1_SLAVE_DS2413=m
CONFIG_W1_SLAVE_DS2406=m
CONFIG_W1_SLAVE_DS2423=m
CONFIG_W1_SLAVE_DS2805=m
CONFIG_W1_SLAVE_DS2430=m
CONFIG_W1_SLAVE_DS2431=m
CONFIG_W1_SLAVE_DS2433=m
CONFIG_W1_SLAVE_DS2433_CRC=y
CONFIG_W1_SLAVE_DS2438=m
CONFIG_W1_SLAVE_DS250X=m
CONFIG_W1_SLAVE_DS2780=m
CONFIG_W1_SLAVE_DS2781=m
CONFIG_W1_SLAVE_DS28E04=m
CONFIG_W1_SLAVE_DS28E17=m
# end of 1-wire Slaves
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_AS3722=y
CONFIG_POWER_RESET_ATC260X=m
CONFIG_POWER_RESET_BRCMKONA=y
CONFIG_POWER_RESET_BRCMSTB=y
CONFIG_POWER_RESET_EP93XX=y
CONFIG_POWER_RESET_GEMINI_POWEROFF=y
CONFIG_POWER_RESET_GPIO=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_LINKSTATION=m
CONFIG_POWER_RESET_OCELOT_RESET=y
CONFIG_POWER_RESET_ODROID_GO_ULTRA_POWEROFF=y
CONFIG_POWER_RESET_PIIX4_POWEROFF=m
CONFIG_POWER_RESET_LTC2952=y
CONFIG_POWER_RESET_MT6323=y
CONFIG_POWER_RESET_REGULATOR=y
CONFIG_POWER_RESET_RESTART=y
CONFIG_POWER_RESET_TH1520_AON=m
CONFIG_POWER_RESET_TORADEX_EC=m
CONFIG_POWER_RESET_TPS65086=y
CONFIG_POWER_RESET_KEYSTONE=y
CONFIG_POWER_RESET_SPACEMIT_P1=m
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
CONFIG_POWER_RESET_RMOBILE=m
CONFIG_REBOOT_MODE=m
CONFIG_SYSCON_REBOOT_MODE=m
CONFIG_POWER_RESET_SC27XX=m
CONFIG_NVMEM_REBOOT_MODE=m
CONFIG_POWER_MLXBF=m
CONFIG_POWER_SEQUENCING=y
CONFIG_POWER_SEQUENCING_QCOM_WCN=m
CONFIG_POWER_SEQUENCING_TH1520_GPU=m
CONFIG_POWER_SEQUENCING_PCIE_M2=m
CONFIG_POWER_SUPPLY=y
CONFIG_POWER_SUPPLY_DEBUG=y
CONFIG_ADC_BATTERY_HELPER=m
CONFIG_GENERIC_ADC_BATTERY=m
CONFIG_IP5XXX_POWER=m
CONFIG_MAX8925_POWER=m
CONFIG_WM831X_BACKUP=m
CONFIG_WM831X_POWER=m
CONFIG_WM8350_POWER=m
CONFIG_TEST_POWER=m
CONFIG_BATTERY_88PM860X=m
CONFIG_CHARGER_ADP5061=m
CONFIG_BATTERY_ACT8945A=m
CONFIG_BATTERY_CHAGALL=m
CONFIG_BATTERY_CPCAP=m
CONFIG_BATTERY_CW2015=m
CONFIG_BATTERY_DS2760=m
CONFIG_BATTERY_DS2780=m
CONFIG_BATTERY_DS2781=m
CONFIG_BATTERY_DS2782=m
CONFIG_BATTERY_HUAWEI_GAOKUN=m
CONFIG_BATTERY_LEGO_EV3=m
CONFIG_BATTERY_LENOVO_YOGA_C630=m
CONFIG_BATTERY_QCOM_BATTMGR=m
CONFIG_BATTERY_OLPC=m
CONFIG_BATTERY_SAMSUNG_SDI=y
CONFIG_BATTERY_INGENIC=m
CONFIG_BATTERY_SBS=m
CONFIG_CHARGER_SBS=m
CONFIG_MANAGER_SBS=m
CONFIG_BATTERY_BQ27XXX=m
CONFIG_BATTERY_BQ27XXX_I2C=m
CONFIG_BATTERY_BQ27XXX_HDQ=m
CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM=y
CONFIG_BATTERY_DA9030=m
CONFIG_BATTERY_DA9052=m
CONFIG_CHARGER_DA9150=m
CONFIG_BATTERY_DA9150=m
CONFIG_CHARGER_AXP20X=m
CONFIG_BATTERY_AXP20X=m
CONFIG_AXP20X_POWER=m
CONFIG_AXP288_CHARGER=m
CONFIG_AXP288_FUEL_GAUGE=m
CONFIG_BATTERY_MAX17040=m
CONFIG_BATTERY_MAX17042=m
CONFIG_BATTERY_MAX1720X=m
CONFIG_BATTERY_MAX1721X=m
CONFIG_BATTERY_TWL4030_MADC=m
CONFIG_CHARGER_88PM860X=m
CONFIG_CHARGER_PF1550=m
CONFIG_BATTERY_RX51=m
CONFIG_CHARGER_CPCAP=m
CONFIG_CHARGER_ISP1704=m
CONFIG_CHARGER_MAX8903=m
CONFIG_CHARGER_TWL4030=m
CONFIG_CHARGER_TWL6030=m
CONFIG_CHARGER_LP8727=m
CONFIG_CHARGER_LP8788=m
CONFIG_CHARGER_GPIO=m
CONFIG_CHARGER_MANAGER=m
CONFIG_CHARGER_LT3651=m
CONFIG_CHARGER_LTC4162L=m
CONFIG_CHARGER_MAX14577=m
CONFIG_CHARGER_DETECTOR_MAX14656=m
CONFIG_CHARGER_MAX77650=m
CONFIG_CHARGER_MAX77693=m
CONFIG_CHARGER_MAX77705=m
CONFIG_CHARGER_MAX77976=m
CONFIG_CHARGER_MAX8971=m
CONFIG_CHARGER_MAX8997=m
CONFIG_CHARGER_MAX8998=m
CONFIG_CHARGER_MP2629=m
CONFIG_CHARGER_MT6360=m
CONFIG_CHARGER_MT6370=m
CONFIG_CHARGER_QCOM_SMBB=m
CONFIG_BATTERY_PM8916_BMS_VM=m
CONFIG_CHARGER_PM8916_LBC=m
CONFIG_CHARGER_BQ2415X=m
CONFIG_CHARGER_BQ24190=m
CONFIG_CHARGER_BQ24257=m
CONFIG_CHARGER_BQ24735=m
CONFIG_CHARGER_BQ2515X=m
CONFIG_CHARGER_BQ257XX=m
CONFIG_CHARGER_BQ25890=m
CONFIG_CHARGER_BQ25980=m
CONFIG_CHARGER_BQ256XX=m
CONFIG_CHARGER_RK817=m
CONFIG_CHARGER_SMB347=m
CONFIG_CHARGER_TPS65090=m
CONFIG_CHARGER_TPS65217=m
CONFIG_BATTERY_GAUGE_LTC2941=m
CONFIG_BATTERY_GOLDFISH=m
CONFIG_BATTERY_RT5033=m
CONFIG_CHARGER_RT5033=m
CONFIG_CHARGER_RT9455=m
CONFIG_CHARGER_RT9467=m
CONFIG_CHARGER_RT9471=m
CONFIG_CHARGER_RT9756=m
CONFIG_CHARGER_CROS_USBPD=m
CONFIG_CHARGER_CROS_PCHG=m
CONFIG_CHARGER_CROS_CONTROL=m
CONFIG_CHARGER_SC2731=m
CONFIG_FUEL_GAUGE_SC27XX=m
CONFIG_FUEL_GAUGE_STC3117=m
CONFIG_CHARGER_UCS1002=m
CONFIG_CHARGER_BD71828=m
CONFIG_CHARGER_BD99954=m
CONFIG_CHARGER_WILCO=m
CONFIG_RN5T618_POWER=m
CONFIG_BATTERY_ACER_A500=m
CONFIG_BATTERY_SURFACE=m
CONFIG_CHARGER_SURFACE=m
CONFIG_BATTERY_UG3105=m
CONFIG_CHARGER_QCOM_SMB2=m
CONFIG_FUEL_GAUGE_MM8013=m
CONFIG_HWMON=m
CONFIG_HWMON_VID=m
CONFIG_HWMON_DEBUG_CHIP=y
#
# Native drivers
#
CONFIG_SENSORS_ABITUGURU=m
CONFIG_SENSORS_ABITUGURU3=m
CONFIG_SENSORS_SMPRO=m
CONFIG_SENSORS_AD7314=m
CONFIG_SENSORS_AD7414=m
CONFIG_SENSORS_AD7418=m
CONFIG_SENSORS_ADM1025=m
CONFIG_SENSORS_ADM1026=m
CONFIG_SENSORS_ADM1029=m
CONFIG_SENSORS_ADM1031=m
CONFIG_SENSORS_ADM1177=m
CONFIG_SENSORS_ADM9240=m
CONFIG_SENSORS_ADT7X10=m
CONFIG_SENSORS_ADT7310=m
CONFIG_SENSORS_ADT7410=m
CONFIG_SENSORS_ADT7411=m
CONFIG_SENSORS_ADT7462=m
CONFIG_SENSORS_ADT7470=m
CONFIG_SENSORS_ADT7475=m
CONFIG_SENSORS_AHT10=m
CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m
CONFIG_SENSORS_AS370=m
CONFIG_SENSORS_ASC7621=m
CONFIG_SENSORS_ASUS_ROG_RYUJIN=m
CONFIG_SENSORS_AXI_FAN_CONTROL=m
CONFIG_SENSORS_K8TEMP=m
CONFIG_SENSORS_K10TEMP=m
CONFIG_SENSORS_KBATT=m
CONFIG_SENSORS_KFAN=m
CONFIG_SENSORS_FAM15H_POWER=m
CONFIG_SENSORS_APPLESMC=m
CONFIG_SENSORS_ARM_SCMI=m
CONFIG_SENSORS_ARM_SCPI=m
CONFIG_SENSORS_ASB100=m
CONFIG_SENSORS_ASPEED=m
CONFIG_SENSORS_ASPEED_G6=m
CONFIG_SENSORS_ATXP1=m
# CONFIG_SENSORS_BT1_PVT is not set
CONFIG_SENSORS_CGBC=m
CONFIG_SENSORS_CHIPCAP2=m
CONFIG_SENSORS_CORSAIR_CPRO=m
CONFIG_SENSORS_CORSAIR_PSU=m
CONFIG_SENSORS_CROS_EC=m
CONFIG_SENSORS_DRIVETEMP=m
CONFIG_SENSORS_DS620=m
CONFIG_SENSORS_DS1621=m
CONFIG_SENSORS_DELL_SMM=m
CONFIG_I8K=y
CONFIG_SENSORS_DA9052_ADC=m
CONFIG_SENSORS_DA9055=m
CONFIG_SENSORS_I5K_AMB=m
CONFIG_SENSORS_SPARX5=m
CONFIG_SENSORS_F71805F=m
CONFIG_SENSORS_F71882FG=m
CONFIG_SENSORS_F75375S=m
CONFIG_SENSORS_GSC=m
CONFIG_SENSORS_MC13783_ADC=m
CONFIG_SENSORS_MC33XS2410=m
CONFIG_SENSORS_FSCHMD=m
CONFIG_SENSORS_FTSTEUTATES=m
CONFIG_SENSORS_GIGABYTE_WATERFORCE=m
CONFIG_SENSORS_GL518SM=m
CONFIG_SENSORS_GL520SM=m
CONFIG_SENSORS_GPD=m
CONFIG_SENSORS_G760A=m
CONFIG_SENSORS_G762=m
CONFIG_SENSORS_GPIO_FAN=m
CONFIG_SENSORS_GXP_FAN_CTRL=m
CONFIG_SENSORS_HIH6130=m
CONFIG_SENSORS_HS3001=m
CONFIG_SENSORS_HTU31=m
CONFIG_SENSORS_IBMAEM=m
CONFIG_SENSORS_IBMPEX=m
CONFIG_SENSORS_IIO_HWMON=m
CONFIG_SENSORS_I5500=m
CONFIG_SENSORS_CORETEMP=m
CONFIG_SENSORS_ISL28022=m
CONFIG_SENSORS_IT87=m
CONFIG_SENSORS_JC42=m
CONFIG_SENSORS_POWERZ=m
CONFIG_SENSORS_POWR1220=m
CONFIG_SENSORS_LAN966X=m
CONFIG_SENSORS_LENOVO_EC=m
CONFIG_SENSORS_LINEAGE=m
CONFIG_SENSORS_LOCHNAGAR=m
CONFIG_SENSORS_LTC2945=m
CONFIG_SENSORS_LTC2947=m
CONFIG_SENSORS_LTC2947_I2C=m
CONFIG_SENSORS_LTC2947_SPI=m
CONFIG_SENSORS_LTC2990=m
CONFIG_SENSORS_LTC2991=m
CONFIG_SENSORS_LTC2992=m
CONFIG_SENSORS_LTC4151=m
CONFIG_SENSORS_LTC4215=m
CONFIG_SENSORS_LTC4222=m
CONFIG_SENSORS_LTC4245=m
CONFIG_SENSORS_LTC4260=m
CONFIG_SENSORS_LTC4261=m
CONFIG_SENSORS_LTC4282=m
CONFIG_SENSORS_MAX1111=m
CONFIG_SENSORS_MAX127=m
CONFIG_SENSORS_MAX16065=m
CONFIG_SENSORS_MAX1619=m
CONFIG_SENSORS_MAX1668=m
CONFIG_SENSORS_MAX197=m
CONFIG_SENSORS_MAX31722=m
CONFIG_SENSORS_MAX31730=m
CONFIG_SENSORS_MAX31760=m
CONFIG_MAX31827=m
CONFIG_SENSORS_MAX6620=m
CONFIG_SENSORS_MAX6621=m
CONFIG_SENSORS_MAX6639=m
CONFIG_SENSORS_MAX6650=m
CONFIG_SENSORS_MAX6697=m
CONFIG_SENSORS_MAX31790=m
CONFIG_SENSORS_MAX77705=m
CONFIG_SENSORS_MC34VR500=m
CONFIG_SENSORS_MCP3021=m
CONFIG_SENSORS_MLXREG_FAN=m
CONFIG_SENSORS_TC654=m
CONFIG_SENSORS_TPS23861=m
CONFIG_SENSORS_MENF21BMC_HWMON=m
CONFIG_SENSORS_MR75203=m
CONFIG_SENSORS_ADCXX=m
CONFIG_SENSORS_LM63=m
CONFIG_SENSORS_LM70=m
CONFIG_SENSORS_LM73=m
CONFIG_SENSORS_LM75=m
CONFIG_SENSORS_LM77=m
CONFIG_SENSORS_LM78=m
CONFIG_SENSORS_LM80=m
CONFIG_SENSORS_LM83=m
CONFIG_SENSORS_LM85=m
CONFIG_SENSORS_LM87=m
CONFIG_SENSORS_LM90=m
CONFIG_SENSORS_LM92=m
CONFIG_SENSORS_LM93=m
CONFIG_SENSORS_LM95234=m
CONFIG_SENSORS_LM95241=m
CONFIG_SENSORS_LM95245=m
CONFIG_SENSORS_PC87360=m
CONFIG_SENSORS_PC87427=m
CONFIG_SENSORS_NTC_THERMISTOR=m
CONFIG_SENSORS_NCT6683=m
CONFIG_SENSORS_NCT6694=m
CONFIG_SENSORS_NCT6775_CORE=m
CONFIG_SENSORS_NCT6775=m
CONFIG_SENSORS_NCT6775_I2C=m
CONFIG_SENSORS_NCT7363=m
CONFIG_SENSORS_NCT7802=m
CONFIG_SENSORS_NCT7904=m
CONFIG_SENSORS_NPCM7XX=m
CONFIG_SENSORS_NSA320=m
CONFIG_SENSORS_NZXT_KRAKEN2=m
CONFIG_SENSORS_NZXT_KRAKEN3=m
CONFIG_SENSORS_NZXT_SMART2=m
CONFIG_SENSORS_OCC_P8_I2C=m
CONFIG_SENSORS_OCC_P9_SBE=m
CONFIG_SENSORS_OCC=m
CONFIG_SENSORS_PCF8591=m
CONFIG_SENSORS_PECI_CPUTEMP=m
CONFIG_SENSORS_PECI_DIMMTEMP=m
CONFIG_SENSORS_PECI=m
CONFIG_PMBUS=m
CONFIG_SENSORS_PMBUS=m
CONFIG_SENSORS_ACBEL_FSG032=m
CONFIG_SENSORS_ADM1266=m
CONFIG_SENSORS_ADM1275=m
CONFIG_SENSORS_ADP1050=m
CONFIG_SENSORS_ADP1050_REGULATOR=y
CONFIG_SENSORS_BEL_PFE=m
CONFIG_SENSORS_BPA_RS600=m
CONFIG_SENSORS_CRPS=m
CONFIG_SENSORS_DELTA_AHE50DC_FAN=m
CONFIG_SENSORS_FSP_3Y=m
CONFIG_SENSORS_HAC300S=m
CONFIG_SENSORS_IBM_CFFPS=m
CONFIG_SENSORS_DPS920AB=m
CONFIG_SENSORS_INA233=m
CONFIG_SENSORS_INSPUR_IPSPS=m
CONFIG_SENSORS_IR35221=m
CONFIG_SENSORS_IR36021=m
CONFIG_SENSORS_IR38064=m
CONFIG_SENSORS_IR38064_REGULATOR=y
CONFIG_SENSORS_IRPS5401=m
CONFIG_SENSORS_ISL68137=m
CONFIG_SENSORS_LM25066=m
CONFIG_SENSORS_LM25066_REGULATOR=y
CONFIG_SENSORS_LT3074=m
CONFIG_SENSORS_LT3074_REGULATOR=m
CONFIG_SENSORS_LT7182S=m
CONFIG_SENSORS_LTC2978=m
CONFIG_SENSORS_LTC2978_REGULATOR=y
CONFIG_SENSORS_LTC3815=m
CONFIG_SENSORS_LTC4286=y
CONFIG_SENSORS_MAX15301=m
CONFIG_SENSORS_MAX16064=m
CONFIG_SENSORS_MAX16601=m
CONFIG_SENSORS_MAX17616=m
CONFIG_SENSORS_MAX20730=m
CONFIG_SENSORS_MAX20751=m
CONFIG_SENSORS_MAX31785=m
CONFIG_SENSORS_MAX34440=m
CONFIG_SENSORS_MAX8688=m
CONFIG_SENSORS_MP2856=m
CONFIG_SENSORS_MP2869=m
CONFIG_SENSORS_MP2888=m
CONFIG_SENSORS_MP2891=m
CONFIG_SENSORS_MP2925=m
CONFIG_SENSORS_MP29502=m
CONFIG_SENSORS_MP2975=m
CONFIG_SENSORS_MP2993=m
CONFIG_SENSORS_MP2975_REGULATOR=y
CONFIG_SENSORS_MP5023=m
CONFIG_SENSORS_MP5920=m
CONFIG_SENSORS_MP5926=m
CONFIG_SENSORS_MP5990=m
CONFIG_SENSORS_MP9941=m
CONFIG_SENSORS_MP9945=m
CONFIG_SENSORS_MPQ7932_REGULATOR=y
CONFIG_SENSORS_MPQ7932=m
CONFIG_SENSORS_MPQ8785=m
CONFIG_SENSORS_PIM4328=m
CONFIG_SENSORS_PLI1209BC=m
CONFIG_SENSORS_PLI1209BC_REGULATOR=y
CONFIG_SENSORS_PM6764TR=m
CONFIG_SENSORS_PXE1610=m
CONFIG_SENSORS_Q54SJ108A2=m
CONFIG_SENSORS_STEF48H28=m
CONFIG_SENSORS_STPDDC60=m
CONFIG_SENSORS_TDA38640=m
CONFIG_SENSORS_TDA38640_REGULATOR=y
CONFIG_SENSORS_TPS25990=m
CONFIG_SENSORS_TPS25990_REGULATOR=y
CONFIG_SENSORS_TPS40422=m
CONFIG_SENSORS_TPS53679=m
CONFIG_SENSORS_TPS546D24=m
CONFIG_SENSORS_UCD9000=m
CONFIG_SENSORS_UCD9200=m
CONFIG_SENSORS_XDP710=m
CONFIG_SENSORS_XDPE152=m
CONFIG_SENSORS_XDPE122=m
CONFIG_SENSORS_XDPE122_REGULATOR=y
CONFIG_SENSORS_ZL6100=m
CONFIG_SENSORS_PT5161L=m
CONFIG_SENSORS_PWM_FAN=m
CONFIG_SENSORS_QNAP_MCU_HWMON=m
CONFIG_SENSORS_RASPBERRYPI_HWMON=m
# CONFIG_SENSORS_SA67MCU is not set
CONFIG_SENSORS_SL28CPLD=m
CONFIG_SENSORS_SBTSI=m
CONFIG_SENSORS_SHT15=m
CONFIG_SENSORS_SHT21=m
CONFIG_SENSORS_SHT3x=m
CONFIG_SENSORS_SHT4x=m
CONFIG_SENSORS_SHTC1=m
CONFIG_SENSORS_SIS5595=m
CONFIG_SENSORS_SY7636A=m
CONFIG_SENSORS_DME1737=m
CONFIG_SENSORS_EMC1403=m
CONFIG_SENSORS_EMC2103=m
CONFIG_SENSORS_EMC2305=m
CONFIG_SENSORS_EMC6W201=m
CONFIG_SENSORS_SMSC47M1=m
CONFIG_SENSORS_SMSC47M192=m
CONFIG_SENSORS_SMSC47B397=m
CONFIG_SENSORS_SCH56XX_COMMON=m
CONFIG_SENSORS_SCH5627=m
CONFIG_SENSORS_SCH5636=m
CONFIG_SENSORS_STTS751=m
CONFIG_SENSORS_SFCTEMP=m
CONFIG_SENSORS_SG2042_MCU=m
CONFIG_SENSORS_SURFACE_FAN=m
CONFIG_SENSORS_SURFACE_TEMP=m
CONFIG_SENSORS_ADC128D818=m
CONFIG_SENSORS_ADS7828=m
CONFIG_SENSORS_ADS7871=m
CONFIG_SENSORS_AMC6821=m
CONFIG_SENSORS_INA209=m
CONFIG_SENSORS_INA2XX=m
CONFIG_SENSORS_INA238=m
CONFIG_SENSORS_INA3221=m
CONFIG_SENSORS_SPD5118=m
CONFIG_SENSORS_SPD5118_DETECT=y
CONFIG_SENSORS_TC74=m
CONFIG_SENSORS_THMC50=m
CONFIG_SENSORS_TMP102=m
CONFIG_SENSORS_TMP103=m
CONFIG_SENSORS_TMP108=m
CONFIG_SENSORS_TMP401=m
CONFIG_SENSORS_TMP421=m
CONFIG_SENSORS_TMP464=m
CONFIG_SENSORS_TMP513=m
CONFIG_SENSORS_TSC1641=m
CONFIG_SENSORS_VIA_CPUTEMP=m
CONFIG_SENSORS_VIA686A=m
CONFIG_SENSORS_VT1211=m
CONFIG_SENSORS_VT8231=m
CONFIG_SENSORS_W83773G=m
CONFIG_SENSORS_W83781D=m
CONFIG_SENSORS_W83791D=m
CONFIG_SENSORS_W83792D=m
CONFIG_SENSORS_W83793=m
CONFIG_SENSORS_W83795=m
CONFIG_SENSORS_W83795_FANCTRL=y
CONFIG_SENSORS_W83L785TS=m
CONFIG_SENSORS_W83L786NG=m
CONFIG_SENSORS_W83627HF=m
CONFIG_SENSORS_W83627EHF=m
CONFIG_SENSORS_WM831X=m
CONFIG_SENSORS_WM8350=m
CONFIG_SENSORS_XGENE=m
CONFIG_SENSORS_INTEL_M10_BMC_HWMON=m
#
# ACPI drivers
#
CONFIG_SENSORS_ACPI_POWER=m
CONFIG_SENSORS_ATK0110=m
CONFIG_SENSORS_ASUS_WMI=m
CONFIG_SENSORS_ASUS_EC=m
CONFIG_SENSORS_HP_WMI=m
CONFIG_THERMAL=y
CONFIG_THERMAL_NETLINK=y
CONFIG_THERMAL_STATISTICS=y
CONFIG_THERMAL_DEBUGFS=y
CONFIG_THERMAL_CORE_TESTING=m
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_OF=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set
# CONFIG_THERMAL_DEFAULT_GOV_BANG_BANG is not set
CONFIG_THERMAL_GOV_FAIR_SHARE=y
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_GOV_BANG_BANG=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_CPU_THERMAL=y
CONFIG_CPU_FREQ_THERMAL=y
CONFIG_CPU_IDLE_THERMAL=y
CONFIG_DEVFREQ_THERMAL=y
CONFIG_PCIE_THERMAL=y
CONFIG_THERMAL_EMULATION=y
CONFIG_THERMAL_MMIO=m
CONFIG_HISI_THERMAL=m
CONFIG_IMX_THERMAL=m
CONFIG_IMX_SC_THERMAL=m
CONFIG_IMX8MM_THERMAL=m
CONFIG_IMX91_THERMAL=m
CONFIG_K3_THERMAL=m
CONFIG_MAX77620_THERMAL=m
CONFIG_QORIQ_THERMAL=m
CONFIG_AIROHA_THERMAL=m
CONFIG_SPEAR_THERMAL=m
CONFIG_SUN8I_THERMAL=m
CONFIG_ROCKCHIP_THERMAL=m
CONFIG_KIRKWOOD_THERMAL=m
CONFIG_DOVE_THERMAL=m
CONFIG_ARMADA_THERMAL=m
CONFIG_DA9062_THERMAL=m
#
# Mediatek thermal drivers
#
CONFIG_MTK_THERMAL=m
CONFIG_MTK_SOC_THERMAL=m
CONFIG_MTK_LVTS_THERMAL=m
CONFIG_MTK_LVTS_THERMAL_DEBUGFS=y
# end of Mediatek thermal drivers
#
# Intel thermal drivers
#
CONFIG_INTEL_POWERCLAMP=m
CONFIG_X86_THERMAL_VECTOR=y
CONFIG_INTEL_TCC=y
CONFIG_X86_PKG_TEMP_THERMAL=m
CONFIG_INTEL_QUARK_DTS_THERMAL=m
#
# ACPI INT340X thermal drivers
#
# end of ACPI INT340X thermal drivers
CONFIG_INTEL_BXT_PMIC_THERMAL=m
CONFIG_INTEL_PCH_THERMAL=m
CONFIG_INTEL_TCC_COOLING=m
CONFIG_INTEL_HFI_THERMAL=y
# end of Intel thermal drivers
#
# Broadcom thermal drivers
#
CONFIG_BCM2711_THERMAL=m
CONFIG_BCM2835_THERMAL=m
CONFIG_BRCMSTB_THERMAL=m
CONFIG_BCM_NS_THERMAL=m
CONFIG_BCM_SR_THERMAL=m
# end of Broadcom thermal drivers
#
# Texas Instruments thermal drivers
#
CONFIG_TI_SOC_THERMAL=m
CONFIG_TI_THERMAL=y
CONFIG_OMAP3_THERMAL=y
CONFIG_OMAP4_THERMAL=y
CONFIG_OMAP5_THERMAL=y
CONFIG_DRA752_THERMAL=y
# end of Texas Instruments thermal drivers
#
# Samsung thermal drivers
#
CONFIG_EXYNOS_THERMAL=m
# end of Samsung thermal drivers
CONFIG_RCAR_THERMAL=m
CONFIG_RCAR_GEN3_THERMAL=m
CONFIG_RZG2L_THERMAL=m
CONFIG_RZG3E_THERMAL=m
CONFIG_RZG3S_THERMAL=m
#
# NVIDIA Tegra thermal drivers
#
CONFIG_TEGRA_SOCTHERM=m
CONFIG_TEGRA_BPMP_THERMAL=m
CONFIG_TEGRA30_TSENSOR=m
# end of NVIDIA Tegra thermal drivers
CONFIG_GENERIC_ADC_THERMAL=m
#
# Qualcomm thermal drivers
#
CONFIG_QCOM_TSENS=m
CONFIG_QCOM_SPMI_ADC_TM5=m
CONFIG_QCOM_SPMI_TEMP_ALARM=m
CONFIG_QCOM_LMH=m
# end of Qualcomm thermal drivers
CONFIG_UNIPHIER_THERMAL=m
CONFIG_SPRD_THERMAL=m
CONFIG_KHADAS_MCU_FAN_THERMAL=m
CONFIG_LOONGSON2_THERMAL=m
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_CORE=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
CONFIG_WATCHDOG_OPEN_TIMEOUT=0
CONFIG_WATCHDOG_SYSFS=y
CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT=y
#
# Watchdog Pretimeout Governors
#
CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m
CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=m
CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=m
# CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP is not set
CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y
#
# Watchdog Device Drivers
#
CONFIG_SOFT_WATCHDOG=m
CONFIG_SOFT_WATCHDOG_PRETIMEOUT=y
CONFIG_BD957XMUF_WATCHDOG=m
CONFIG_BD96801_WATCHDOG=m
CONFIG_CROS_EC_WATCHDOG=m
CONFIG_DA9052_WATCHDOG=m
CONFIG_DA9055_WATCHDOG=m
CONFIG_DA9063_WATCHDOG=m
CONFIG_DA9062_WATCHDOG=m
CONFIG_GPIO_WATCHDOG=m
CONFIG_LENOVO_SE10_WDT=m
CONFIG_LENOVO_SE30_WDT=m
CONFIG_MENF21BMC_WATCHDOG=m
CONFIG_MENZ069_WATCHDOG=m
CONFIG_WDAT_WDT=m
CONFIG_WM831X_WATCHDOG=m
CONFIG_WM8350_WATCHDOG=m
CONFIG_XILINX_WATCHDOG=m
CONFIG_XILINX_WINDOW_WATCHDOG=m
CONFIG_ZIIRAVE_WATCHDOG=m
CONFIG_RAVE_SP_WATCHDOG=m
CONFIG_MLX_WDT=m
CONFIG_SL28CPLD_WATCHDOG=m
CONFIG_AIROHA_WATCHDOG=m
CONFIG_ARMADA_37XX_WATCHDOG=m
CONFIG_ASM9260_WATCHDOG=m
CONFIG_AT91RM9200_WATCHDOG=m
CONFIG_AT91SAM9X_WATCHDOG=m
CONFIG_SAMA5D4_WATCHDOG=m
CONFIG_CADENCE_WATCHDOG=m
CONFIG_FTWDT010_WATCHDOG=m
CONFIG_S3C2410_WATCHDOG=m
CONFIG_SA1100_WATCHDOG=m
CONFIG_DW_WATCHDOG=m
CONFIG_EP93XX_WATCHDOG=m
CONFIG_OMAP_WATCHDOG=m
CONFIG_PNX4008_WATCHDOG=m
CONFIG_DAVINCI_WATCHDOG=m
CONFIG_K3_RTI_WATCHDOG=m
CONFIG_RN5T618_WATCHDOG=m
CONFIG_SUNXI_WATCHDOG=m
CONFIG_NPCM7XX_WATCHDOG=m
CONFIG_TWL4030_WATCHDOG=m
CONFIG_STMP3XXX_RTC_WATCHDOG=m
CONFIG_TS4800_WATCHDOG=m
CONFIG_TS72XX_WATCHDOG=m
CONFIG_MAX63XX_WATCHDOG=m
CONFIG_MAX77620_WATCHDOG=m
CONFIG_NCT6694_WATCHDOG=m
CONFIG_IMX2_WDT=m
CONFIG_IMX7ULP_WDT=m
CONFIG_S32G_WDT=m
CONFIG_RETU_WATCHDOG=m
CONFIG_MOXART_WDT=m
CONFIG_ST_LPC_WATCHDOG=m
CONFIG_TEGRA_WATCHDOG=m
CONFIG_QCOM_WDT=m
CONFIG_MESON_GXBB_WATCHDOG=m
CONFIG_MESON_WATCHDOG=m
CONFIG_MEDIATEK_WATCHDOG=m
CONFIG_DIGICOLOR_WATCHDOG=m
CONFIG_LPC18XX_WATCHDOG=m
CONFIG_RENESAS_WDT=m
CONFIG_RENESAS_WWDT=m
CONFIG_RENESAS_RZAWDT=m
CONFIG_RENESAS_RZN1WDT=m
CONFIG_RENESAS_RZG2LWDT=m
CONFIG_RENESAS_RZV2HWDT=m
CONFIG_ASPEED_WATCHDOG=m
CONFIG_STM32_WATCHDOG=m
CONFIG_STPMIC1_WATCHDOG=m
CONFIG_UNIPHIER_WATCHDOG=m
CONFIG_RTD119X_WATCHDOG=y
CONFIG_REALTEK_OTTO_WDT=m
CONFIG_SPRD_WATCHDOG=m
CONFIG_PM8916_WATCHDOG=m
CONFIG_VISCONTI_WATCHDOG=m
CONFIG_MSC313E_WATCHDOG=m
CONFIG_APPLE_WATCHDOG=m
CONFIG_SUNPLUS_WATCHDOG=m
CONFIG_ACQUIRE_WDT=m
CONFIG_ADVANTECH_WDT=m
CONFIG_ADVANTECH_EC_WDT=m
CONFIG_ALIM1535_WDT=m
CONFIG_ALIM7101_WDT=m
CONFIG_CGBC_WDT=m
CONFIG_EBC_C384_WDT=m
CONFIG_EXAR_WDT=m
CONFIG_F71808E_WDT=m
CONFIG_SP5100_TCO=m
CONFIG_GEODE_WDT=m
CONFIG_SC520_WDT=m
CONFIG_SBC_FITPC2_WATCHDOG=m
CONFIG_EUROTECH_WDT=m
CONFIG_IB700_WDT=m
CONFIG_IBMASR=m
CONFIG_WAFER_WDT=m
CONFIG_I6300ESB_WDT=m
CONFIG_IE6XX_WDT=m
CONFIG_INTEL_MID_WATCHDOG=m
CONFIG_INTEL_OC_WATCHDOG=m
CONFIG_ITCO_WDT=m
CONFIG_IT8712F_WDT=m
CONFIG_IT87_WDT=m
CONFIG_HP_WATCHDOG=m
CONFIG_HPWDT_NMI_DECODING=y
CONFIG_KEMPLD_WDT=m
CONFIG_SC1200_WDT=m
CONFIG_SCx200_WDT=m
CONFIG_PC87413_WDT=m
CONFIG_NV_TCO=m
CONFIG_RDC321X_WDT=m
CONFIG_60XX_WDT=m
CONFIG_SBC8360_WDT=m
CONFIG_SBC7240_WDT=m
CONFIG_SMSC_SCH311X_WDT=m
CONFIG_SMSC37B787_WDT=m
CONFIG_TQMX86_WDT=m
CONFIG_VIA_WDT=m
CONFIG_W83627HF_WDT=m
CONFIG_W83877F_WDT=m
CONFIG_W83977F_WDT=m
CONFIG_MACHZ_WDT=m
CONFIG_SBC_EPX_C3_WATCHDOG=m
CONFIG_INTEL_MEI_WDT=m
CONFIG_NI903X_WDT=m
CONFIG_NIC7018_WDT=m
CONFIG_SIEMENS_SIMATIC_IPC_WDT=m
CONFIG_BCM47XX_WDT=m
CONFIG_JZ4740_WDT=m
CONFIG_BCM2835_WDT=m
CONFIG_BCM_KONA_WDT=m
CONFIG_BCM_KONA_WDT_DEBUG=y
CONFIG_BCM7038_WDT=m
CONFIG_IMGPDC_WDT=m
CONFIG_LOONGSON1_WDT=m
CONFIG_GXP_WATCHDOG=m
CONFIG_MT7621_WDT=m
CONFIG_MPC5200_WDT=y
CONFIG_MEN_A21_WDT=m
CONFIG_STARFIVE_WATCHDOG=m
CONFIG_XEN_WDT=m
CONFIG_UML_WATCHDOG=m
#
# ISA-based Watchdog Cards
#
CONFIG_PCWATCHDOG=m
CONFIG_MIXCOMWD=m
CONFIG_WDT=m
#
# PCI-based Watchdog Cards
#
CONFIG_PCIPCWATCHDOG=m
CONFIG_WDTPCI=m
#
# USB-based Watchdog Cards
#
CONFIG_USBPCWATCHDOG=m
CONFIG_SSB_POSSIBLE=y
CONFIG_SSB=m
CONFIG_SSB_SPROM=y
CONFIG_SSB_BLOCKIO=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
CONFIG_SSB_B43_PCI_BRIDGE=y
CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
CONFIG_SSB_PCMCIAHOST=y
CONFIG_SSB_SDIOHOST_POSSIBLE=y
CONFIG_SSB_SDIOHOST=y
CONFIG_SSB_HOST_SOC=y
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_SSB_DRIVER_GPIO=y
CONFIG_BCMA_POSSIBLE=y
CONFIG_BCMA=m
CONFIG_BCMA_BLOCKIO=y
CONFIG_BCMA_HOST_PCI_POSSIBLE=y
CONFIG_BCMA_HOST_PCI=y
CONFIG_BCMA_HOST_SOC=y
CONFIG_BCMA_DRIVER_PCI=y
CONFIG_BCMA_DRIVER_MIPS=y
CONFIG_BCMA_PFLASH=y
CONFIG_BCMA_SFLASH=y
CONFIG_BCMA_NFLASH=y
CONFIG_BCMA_DRIVER_GMAC_CMN=y
CONFIG_BCMA_DRIVER_GPIO=y
CONFIG_BCMA_DEBUG=y
#
# Multifunction device drivers
#
CONFIG_MFD_CORE=y
CONFIG_MFD_CS5535=m
CONFIG_MFD_ADP5585=m
CONFIG_MFD_ALTERA_SYSMGR=y
CONFIG_MFD_ACT8945A=m
CONFIG_MFD_SUN4I_GPADC=m
CONFIG_MFD_AS3711=y
CONFIG_MFD_SMPRO=m
CONFIG_MFD_AS3722=m
CONFIG_PMIC_ADP5520=y
CONFIG_MFD_AAT2870_CORE=y
CONFIG_MFD_AT91_USART=y
CONFIG_MFD_ATMEL_FLEXCOM=m
CONFIG_MFD_ATMEL_HLCDC=m
CONFIG_MFD_ATMEL_SMC=y
CONFIG_MFD_BCM590XX=m
CONFIG_MFD_BD9571MWV=m
CONFIG_MFD_AXP20X=m
CONFIG_MFD_AXP20X_I2C=m
CONFIG_MFD_CGBC=m
CONFIG_MFD_CROS_EC_DEV=m
CONFIG_MFD_CS40L50_CORE=m
CONFIG_MFD_CS40L50_I2C=m
CONFIG_MFD_CS40L50_SPI=m
CONFIG_MFD_CS42L43=m
CONFIG_MFD_CS42L43_I2C=m
CONFIG_MFD_CS42L43_SDW=m
CONFIG_MFD_LOCHNAGAR=y
CONFIG_MFD_MADERA=m
CONFIG_MFD_MADERA_I2C=m
CONFIG_MFD_MADERA_SPI=m
CONFIG_MFD_CS47L15=y
CONFIG_MFD_CS47L35=y
CONFIG_MFD_CS47L85=y
CONFIG_MFD_CS47L90=y
CONFIG_MFD_CS47L92=y
CONFIG_MFD_TN48M_CPLD=m
CONFIG_PMIC_DA903X=y
CONFIG_PMIC_DA9052=y
CONFIG_MFD_DA9052_SPI=y
CONFIG_MFD_DA9052_I2C=y
CONFIG_MFD_DA9055=y
CONFIG_MFD_DA9062=m
CONFIG_MFD_DA9063=m
CONFIG_MFD_DA9150=m
CONFIG_MFD_DLN2=m
CONFIG_MFD_ENE_KB3930=m
CONFIG_MFD_EXYNOS_LPASS=m
CONFIG_MFD_GATEWORKS_GSC=m
CONFIG_MFD_MC13XXX=m
CONFIG_MFD_MC13XXX_SPI=m
CONFIG_MFD_MC13XXX_I2C=m
CONFIG_MFD_MP2629=m
CONFIG_MFD_MXS_LRADC=m
CONFIG_MFD_MX25_TSADC=m
CONFIG_MFD_PF1550=m
CONFIG_MFD_HI6421_PMIC=m
CONFIG_MFD_HI6421_SPMI=m
CONFIG_MFD_HI655X_PMIC=m
CONFIG_MFD_INTEL_QUARK_I2C_GPIO=m
CONFIG_LPC_ICH=m
CONFIG_LPC_SCH=m
CONFIG_INTEL_SOC_PMIC=y
CONFIG_INTEL_SOC_PMIC_BXTWC=m
CONFIG_INTEL_SOC_PMIC_MRFLD=m
CONFIG_MFD_INTEL_LPSS=m
CONFIG_MFD_INTEL_LPSS_ACPI=m
CONFIG_MFD_INTEL_LPSS_PCI=m
CONFIG_MFD_INTEL_PMC_BXT=m
CONFIG_MFD_IQS62X=m
CONFIG_MFD_JANZ_CMODIO=m
CONFIG_MFD_KEMPLD=m
CONFIG_MFD_88PM800=m
CONFIG_MFD_88PM805=m
CONFIG_MFD_88PM860X=y
CONFIG_MFD_88PM886_PMIC=y
CONFIG_MFD_MAX5970=m
CONFIG_MFD_MAX14577=m
CONFIG_MFD_MAX77541=m
CONFIG_MFD_MAX77620=m
CONFIG_MFD_MAX77650=m
CONFIG_MFD_MAX77686=m
CONFIG_MFD_MAX77693=m
CONFIG_MFD_MAX77705=m
CONFIG_MFD_MAX77714=m
CONFIG_MFD_MAX77759=m
CONFIG_MFD_MAX77843=y
CONFIG_MFD_MAX8907=m
CONFIG_MFD_MAX8925=y
CONFIG_MFD_MAX8997=y
CONFIG_MFD_MAX8998=y
CONFIG_MFD_MT6360=m
CONFIG_MFD_MT6370=m
CONFIG_MFD_MT6397=m
CONFIG_MFD_MENF21BMC=m
CONFIG_MFD_NCT6694=m
CONFIG_MFD_OCELOT=m
CONFIG_EZX_PCAP=y
CONFIG_MFD_CPCAP=m
CONFIG_MFD_VIPERBOARD=m
CONFIG_MFD_NTXEC=m
CONFIG_MFD_RETU=m
CONFIG_MFD_PM8XXX=m
CONFIG_MFD_SPACEMIT_P1=m
CONFIG_MFD_SPMI_PMIC=m
CONFIG_MFD_SY7636A=m
CONFIG_MFD_RDC321X=m
CONFIG_MFD_RT4831=m
CONFIG_MFD_RT5033=m
CONFIG_MFD_RT5120=m
CONFIG_MFD_RC5T583=y
CONFIG_MFD_RK8XX=m
CONFIG_MFD_RK8XX_I2C=m
CONFIG_MFD_RK8XX_SPI=m
CONFIG_MFD_RN5T618=m
CONFIG_MFD_SEC_CORE=m
CONFIG_MFD_SEC_ACPM=m
CONFIG_MFD_SEC_I2C=m
CONFIG_MFD_SI476X_CORE=m
CONFIG_MFD_SIMPLE_MFD_I2C=m
CONFIG_MFD_SL28CPLD=m
CONFIG_MFD_SM501=m
CONFIG_MFD_SM501_GPIO=y
CONFIG_MFD_SKY81452=m
CONFIG_MFD_SC27XX_PMIC=m
CONFIG_RZ_MTU3=m
CONFIG_ABX500_CORE=y
CONFIG_MFD_STMPE=m
#
# STMicroelectronics STMPE Interface Drivers
#
CONFIG_STMPE_I2C=m
CONFIG_STMPE_SPI=m
# end of STMicroelectronics STMPE Interface Drivers
CONFIG_MFD_SUN6I_PRCM=y
CONFIG_MFD_SYSCON=y
CONFIG_MFD_TI_AM335X_TSCADC=m
CONFIG_MFD_LP3943=m
CONFIG_MFD_LP8788=y
CONFIG_MFD_TI_LMU=m
CONFIG_MFD_BQ257XX=m
CONFIG_MFD_OMAP_USB_HOST=y
CONFIG_MFD_PALMAS=m
CONFIG_TPS6105X=m
CONFIG_TPS65010=m
CONFIG_TPS6507X=m
CONFIG_MFD_TPS65086=m
CONFIG_MFD_TPS65090=y
CONFIG_MFD_TPS65217=m
CONFIG_MFD_TI_LP873X=m
CONFIG_MFD_TI_LP87565=m
CONFIG_MFD_TPS65218=m
CONFIG_MFD_TPS65219=m
CONFIG_MFD_TPS6586X=y
CONFIG_MFD_TPS65910=y
CONFIG_MFD_TPS65912=m
CONFIG_MFD_TPS65912_I2C=m
CONFIG_MFD_TPS65912_SPI=m
CONFIG_MFD_TPS6594=m
CONFIG_MFD_TPS6594_I2C=m
CONFIG_MFD_TPS6594_SPI=m
CONFIG_TWL4030_CORE=y
CONFIG_MFD_TWL4030_AUDIO=y
CONFIG_TWL6040_CORE=y
CONFIG_MFD_LM3533=m
CONFIG_MFD_TIMBERDALE=m
CONFIG_MFD_TC3589X=y
CONFIG_MFD_TQMX86=m
CONFIG_MFD_VX855=m
CONFIG_MFD_ARIZONA=m
CONFIG_MFD_ARIZONA_I2C=m
CONFIG_MFD_ARIZONA_SPI=m
CONFIG_MFD_CS47L24=y
CONFIG_MFD_WM5102=y
CONFIG_MFD_WM5110=y
CONFIG_MFD_WM8997=y
CONFIG_MFD_WM8998=y
CONFIG_MFD_WM8400=y
CONFIG_MFD_WM831X=y
CONFIG_MFD_WM831X_I2C=y
CONFIG_MFD_WM831X_SPI=y
CONFIG_MFD_WM8350=y
CONFIG_MFD_WM8350_I2C=y
CONFIG_MFD_WM8994=m
CONFIG_MFD_STW481X=m
CONFIG_MFD_ROHM_BD718XX=m
CONFIG_MFD_ROHM_BD71828=m
CONFIG_MFD_ROHM_BD957XMUF=m
CONFIG_MFD_ROHM_BD96801=m
CONFIG_MFD_STM32_LPTIMER=m
CONFIG_MFD_STM32_TIMERS=m
CONFIG_MFD_STPMIC1=m
CONFIG_MFD_STMFX=m
CONFIG_MFD_WCD934X=m
CONFIG_MFD_ATC260X=m
CONFIG_MFD_ATC260X_I2C=m
CONFIG_MFD_KHADAS_MCU=m
CONFIG_MFD_ACER_A500_EC=m
CONFIG_MFD_QCOM_PM8008=m
CONFIG_RAVE_SP_CORE=m
CONFIG_MFD_INTEL_M10_BMC_CORE=m
CONFIG_MFD_INTEL_M10_BMC_SPI=m
CONFIG_MFD_INTEL_M10_BMC_PMCI=m
CONFIG_MFD_QNAP_MCU=m
CONFIG_MFD_RSMU_I2C=m
CONFIG_MFD_RSMU_SPI=m
CONFIG_MFD_UPBOARD_FPGA=m
CONFIG_MFD_MAX7360=m
# end of Multifunction device drivers
CONFIG_REGULATOR=y
CONFIG_REGULATOR_DEBUG=y
CONFIG_REGULATOR_FIXED_VOLTAGE=m
CONFIG_REGULATOR_VIRTUAL_CONSUMER=m
CONFIG_REGULATOR_USERSPACE_CONSUMER=m
CONFIG_REGULATOR_NETLINK_EVENTS=y
CONFIG_REGULATOR_88PG86X=m
CONFIG_REGULATOR_88PM800=m
CONFIG_REGULATOR_88PM8607=m
CONFIG_REGULATOR_88PM886=m
CONFIG_REGULATOR_ACT8865=m
CONFIG_REGULATOR_ACT8945A=m
CONFIG_REGULATOR_AD5398=m
CONFIG_REGULATOR_ADP5055=m
CONFIG_REGULATOR_ANATOP=m
CONFIG_REGULATOR_AAT2870=m
CONFIG_REGULATOR_ARIZONA_LDO1=m
CONFIG_REGULATOR_ARIZONA_MICSUPP=m
CONFIG_REGULATOR_ARM_SCMI=m
CONFIG_REGULATOR_AS3711=m
CONFIG_REGULATOR_AS3722=m
CONFIG_REGULATOR_ATC260X=m
CONFIG_REGULATOR_AW37503=m
CONFIG_REGULATOR_AXP20X=m
CONFIG_REGULATOR_BCM590XX=m
CONFIG_REGULATOR_BD71815=m
CONFIG_REGULATOR_BD71828=m
CONFIG_REGULATOR_BD718XX=m
CONFIG_REGULATOR_BD9571MWV=m
CONFIG_REGULATOR_BD957XMUF=m
CONFIG_REGULATOR_BD96801=m
CONFIG_REGULATOR_BQ257XX=m
CONFIG_REGULATOR_CPCAP=m
CONFIG_REGULATOR_CROS_EC=m
CONFIG_REGULATOR_DA903X=m
CONFIG_REGULATOR_DA9052=m
CONFIG_REGULATOR_DA9055=m
CONFIG_REGULATOR_DA9062=m
CONFIG_REGULATOR_DA9063=m
CONFIG_REGULATOR_DA9121=m
CONFIG_REGULATOR_DA9210=m
CONFIG_REGULATOR_DA9211=m
CONFIG_REGULATOR_FAN53555=m
CONFIG_REGULATOR_FAN53880=m
CONFIG_REGULATOR_GPIO=m
CONFIG_REGULATOR_HI6421=m
CONFIG_REGULATOR_HI6421V530=m
CONFIG_REGULATOR_HI655X=m
CONFIG_REGULATOR_HI6421V600=m
CONFIG_REGULATOR_ISL9305=m
CONFIG_REGULATOR_ISL6271A=m
CONFIG_REGULATOR_FP9931=m
CONFIG_REGULATOR_LM363X=m
CONFIG_REGULATOR_LOCHNAGAR=m
CONFIG_REGULATOR_LP3971=m
CONFIG_REGULATOR_LP3972=m
CONFIG_REGULATOR_LP872X=m
CONFIG_REGULATOR_LP873X=m
CONFIG_REGULATOR_LP8755=m
CONFIG_REGULATOR_LP87565=m
CONFIG_REGULATOR_LP8788=m
CONFIG_REGULATOR_LTC3589=m
CONFIG_REGULATOR_LTC3676=m
CONFIG_REGULATOR_MAX14577=m
CONFIG_REGULATOR_MAX1586=m
CONFIG_REGULATOR_MAX5970=m
CONFIG_REGULATOR_MAX77503=m
CONFIG_REGULATOR_MAX77541=m
CONFIG_REGULATOR_MAX77620=m
CONFIG_REGULATOR_MAX77650=m
CONFIG_REGULATOR_MAX77675=m
CONFIG_REGULATOR_MAX77857=m
CONFIG_REGULATOR_MAX8649=m
CONFIG_REGULATOR_MAX8660=m
CONFIG_REGULATOR_MAX8893=m
CONFIG_REGULATOR_MAX8907=m
CONFIG_REGULATOR_MAX8925=m
CONFIG_REGULATOR_MAX8952=m
CONFIG_REGULATOR_MAX8973=m
CONFIG_REGULATOR_MAX8997=m
CONFIG_REGULATOR_MAX8998=m
CONFIG_REGULATOR_MAX20086=m
CONFIG_REGULATOR_MAX20411=m
CONFIG_REGULATOR_MAX77686=m
CONFIG_REGULATOR_MAX77693=m
CONFIG_REGULATOR_MAX77802=m
CONFIG_REGULATOR_MAX77826=m
CONFIG_REGULATOR_MAX77838=m
CONFIG_REGULATOR_MC13XXX_CORE=m
CONFIG_REGULATOR_MC13783=m
CONFIG_REGULATOR_MC13892=m
CONFIG_REGULATOR_MCP16502=m
CONFIG_REGULATOR_MP5416=m
CONFIG_REGULATOR_MP8859=m
CONFIG_REGULATOR_MP886X=m
CONFIG_REGULATOR_MPQ7920=m
CONFIG_REGULATOR_MT6311=m
CONFIG_REGULATOR_MT6315=m
CONFIG_REGULATOR_MT6316=m
CONFIG_REGULATOR_MT6323=m
CONFIG_REGULATOR_MT6331=m
CONFIG_REGULATOR_MT6332=m
CONFIG_REGULATOR_MT6357=m
CONFIG_REGULATOR_MT6358=m
CONFIG_REGULATOR_MT6359=m
CONFIG_REGULATOR_MT6360=m
CONFIG_REGULATOR_MT6363=m
CONFIG_REGULATOR_MT6370=m
CONFIG_REGULATOR_MT6380=m
CONFIG_REGULATOR_MT6397=m
CONFIG_REGULATOR_PALMAS=m
CONFIG_REGULATOR_PBIAS=m
CONFIG_REGULATOR_PCA9450=m
CONFIG_REGULATOR_PF9453=m
CONFIG_REGULATOR_PCAP=m
CONFIG_REGULATOR_PF0900=m
CONFIG_REGULATOR_PF530X=m
CONFIG_REGULATOR_PF8X00=m
CONFIG_REGULATOR_PFUZE100=m
CONFIG_REGULATOR_PV88060=m
CONFIG_REGULATOR_PV88080=m
CONFIG_REGULATOR_PV88090=m
CONFIG_REGULATOR_PF1550=m
CONFIG_REGULATOR_PWM=m
CONFIG_REGULATOR_QCOM_PM8008=m
CONFIG_REGULATOR_QCOM_REFGEN=m
CONFIG_REGULATOR_QCOM_RPMH=m
CONFIG_REGULATOR_QCOM_SMD_RPM=m
CONFIG_REGULATOR_QCOM_SPMI=m
CONFIG_REGULATOR_QCOM_USB_VBUS=m
CONFIG_REGULATOR_RAA215300=m
CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m
CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2=m
CONFIG_REGULATOR_RC5T583=m
CONFIG_REGULATOR_RK808=m
CONFIG_REGULATOR_RN5T618=m
CONFIG_REGULATOR_ROHM=m
CONFIG_REGULATOR_RT4801=m
CONFIG_REGULATOR_RT4803=m
CONFIG_REGULATOR_RT4831=m
CONFIG_REGULATOR_RT5033=m
CONFIG_REGULATOR_RT5120=m
CONFIG_REGULATOR_RT5133=m
CONFIG_REGULATOR_RT5190A=m
CONFIG_REGULATOR_RT5739=m
CONFIG_REGULATOR_RT5759=m
CONFIG_REGULATOR_RT6160=m
CONFIG_REGULATOR_RT6190=m
CONFIG_REGULATOR_RT6245=m
CONFIG_REGULATOR_RT8092=m
CONFIG_REGULATOR_RTQ2134=m
CONFIG_REGULATOR_RTMV20=m
CONFIG_REGULATOR_RTQ6752=m
CONFIG_REGULATOR_RTQ2208=m
CONFIG_REGULATOR_S2DOS05=m
CONFIG_REGULATOR_S2MPA01=m
CONFIG_REGULATOR_S2MPS11=m
CONFIG_REGULATOR_S5M8767=m
CONFIG_REGULATOR_SC2731=m
CONFIG_REGULATOR_SKY81452=m
CONFIG_REGULATOR_SLG51000=m
CONFIG_REGULATOR_SPACEMIT_P1=m
CONFIG_REGULATOR_STM32_BOOSTER=m
CONFIG_REGULATOR_STM32_VREFBUF=m
CONFIG_REGULATOR_STM32_PWR=y
CONFIG_REGULATOR_STPMIC1=m
CONFIG_REGULATOR_TI_ABB=m
CONFIG_REGULATOR_STW481X_VMMC=y
CONFIG_REGULATOR_SUN20I=m
CONFIG_REGULATOR_SY7636A=m
CONFIG_REGULATOR_SY8106A=m
CONFIG_REGULATOR_SY8824X=m
CONFIG_REGULATOR_SY8827N=m
CONFIG_REGULATOR_TPS51632=m
CONFIG_REGULATOR_TPS6105X=m
CONFIG_REGULATOR_TPS62360=m
CONFIG_REGULATOR_TPS6286X=m
CONFIG_REGULATOR_TPS6287X=m
CONFIG_REGULATOR_TPS65023=m
CONFIG_REGULATOR_TPS6507X=m
CONFIG_REGULATOR_TPS65086=m
CONFIG_REGULATOR_TPS65090=m
CONFIG_REGULATOR_TPS65132=m
CONFIG_REGULATOR_TPS65185=m
CONFIG_REGULATOR_TPS65217=m
CONFIG_REGULATOR_TPS65218=m
CONFIG_REGULATOR_TPS65219=m
CONFIG_REGULATOR_TPS6594=m
CONFIG_REGULATOR_TPS6524X=m
CONFIG_REGULATOR_TPS6586X=m
CONFIG_REGULATOR_TPS65910=m
CONFIG_REGULATOR_TPS65912=m
CONFIG_REGULATOR_TPS68470=m
CONFIG_REGULATOR_TWL4030=m
CONFIG_REGULATOR_UNIPHIER=m
CONFIG_REGULATOR_RZG2L_VBCTRL=m
CONFIG_REGULATOR_VCTRL=m
CONFIG_REGULATOR_WM831X=m
CONFIG_REGULATOR_WM8350=m
CONFIG_REGULATOR_WM8400=m
CONFIG_REGULATOR_WM8994=m
CONFIG_REGULATOR_QCOM_LABIBB=m
CONFIG_RC_CORE=m
CONFIG_LIRC=y
CONFIG_RC_MAP=m
CONFIG_RC_DECODERS=y
CONFIG_IR_IMON_DECODER=m
CONFIG_IR_JVC_DECODER=m
CONFIG_IR_MCE_KBD_DECODER=m
CONFIG_IR_NEC_DECODER=m
CONFIG_IR_RC5_DECODER=m
CONFIG_IR_RC6_DECODER=m
CONFIG_IR_RCMM_DECODER=m
CONFIG_IR_SANYO_DECODER=m
CONFIG_IR_SHARP_DECODER=m
CONFIG_IR_SONY_DECODER=m
CONFIG_IR_XMP_DECODER=m
CONFIG_RC_DEVICES=y
CONFIG_IR_ENE=m
CONFIG_IR_FINTEK=m
CONFIG_IR_GPIO_CIR=m
CONFIG_IR_GPIO_TX=m
CONFIG_IR_HIX5HD2=m
CONFIG_IR_IGORPLUGUSB=m
CONFIG_IR_IGUANA=m
CONFIG_IR_IMON=m
CONFIG_IR_IMON_RAW=m
CONFIG_IR_ITE_CIR=m
CONFIG_IR_MCEUSB=m
CONFIG_IR_MESON=m
CONFIG_IR_MESON_TX=m
CONFIG_IR_MTK=m
CONFIG_IR_NUVOTON=m
CONFIG_IR_PWM_TX=m
CONFIG_IR_REDRAT3=m
CONFIG_IR_SERIAL=m
CONFIG_IR_SERIAL_TRANSMITTER=y
CONFIG_IR_SPI=m
CONFIG_IR_STREAMZAP=m
CONFIG_IR_SUNXI=m
CONFIG_IR_TOY=m
CONFIG_IR_TTUSBIR=m
CONFIG_IR_WINBOND_CIR=m
CONFIG_RC_ATI_REMOTE=m
CONFIG_RC_LOOPBACK=m
CONFIG_RC_ST=m
CONFIG_RC_XBOX_DVD=m
CONFIG_IR_IMG=m
CONFIG_IR_IMG_RAW=y
CONFIG_IR_IMG_HW=y
CONFIG_IR_IMG_NEC=y
CONFIG_IR_IMG_JVC=y
CONFIG_IR_IMG_SONY=y
CONFIG_IR_IMG_SHARP=y
CONFIG_IR_IMG_SANYO=y
CONFIG_IR_IMG_RC5=y
CONFIG_IR_IMG_RC6=y
CONFIG_CEC_CORE=m
CONFIG_CEC_NOTIFIER=y
CONFIG_CEC_PIN=y
#
# CEC support
#
CONFIG_MEDIA_CEC_RC=y
CONFIG_CEC_PIN_ERROR_INJ=y
CONFIG_MEDIA_CEC_SUPPORT=y
CONFIG_CEC_CH7322=m
CONFIG_CEC_NXP_TDA9950=m
CONFIG_CEC_CROS_EC=m
CONFIG_CEC_MESON_AO=m
CONFIG_CEC_MESON_G12A_AO=m
CONFIG_CEC_GPIO=m
CONFIG_CEC_SAMSUNG_S5P=m
CONFIG_CEC_STI=m
CONFIG_CEC_STM32=m
CONFIG_CEC_TEGRA=m
CONFIG_CEC_SECO=m
CONFIG_CEC_SECO_RC=y
CONFIG_USB_EXTRON_DA_HD_4K_PLUS_CEC=m
CONFIG_USB_PULSE8_CEC=m
CONFIG_USB_RAINSHADOW_CEC=m
# end of CEC support
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_SUPPORT_FILTER=y
CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
#
# Media device types
#
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
CONFIG_MEDIA_RADIO_SUPPORT=y
CONFIG_MEDIA_SDR_SUPPORT=y
CONFIG_MEDIA_PLATFORM_SUPPORT=y
CONFIG_MEDIA_TEST_SUPPORT=y
# end of Media device types
CONFIG_VIDEO_DEV=m
CONFIG_MEDIA_CONTROLLER=y
CONFIG_DVB_CORE=m
#
# Video4Linux options
#
CONFIG_VIDEO_V4L2_I2C=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
CONFIG_VIDEO_TUNER=m
CONFIG_V4L2_JPEG_HELPER=m
CONFIG_V4L2_H264=m
CONFIG_V4L2_VP9=m
CONFIG_V4L2_MEM2MEM_DEV=m
CONFIG_V4L2_FLASH_LED_CLASS=m
CONFIG_V4L2_FWNODE=m
CONFIG_V4L2_ASYNC=m
CONFIG_V4L2_CCI=m
CONFIG_V4L2_CCI_I2C=m
CONFIG_V4L2_ISP=m
# end of Video4Linux options
#
# Media controller options
#
CONFIG_MEDIA_CONTROLLER_DVB=y
# end of Media controller options
#
# Digital TV options
#
CONFIG_DVB_MMAP=y
CONFIG_DVB_NET=y
CONFIG_DVB_MAX_ADAPTERS=16
CONFIG_DVB_DYNAMIC_MINORS=y
CONFIG_DVB_DEMUX_SECTION_LOSS_LOG=y
CONFIG_DVB_ULE_DEBUG=y
# end of Digital TV options
#
# Media drivers
#
#
# Drivers filtered as selected at 'Filter media drivers'
#
#
# Media drivers
#
CONFIG_MEDIA_USB_SUPPORT=y
#
# Webcam devices
#
CONFIG_USB_GSPCA=m
CONFIG_USB_GSPCA_BENQ=m
CONFIG_USB_GSPCA_CONEX=m
CONFIG_USB_GSPCA_CPIA1=m
CONFIG_USB_GSPCA_DTCS033=m
CONFIG_USB_GSPCA_ETOMS=m
CONFIG_USB_GSPCA_FINEPIX=m
CONFIG_USB_GSPCA_JEILINJ=m
CONFIG_USB_GSPCA_JL2005BCD=m
CONFIG_USB_GSPCA_KINECT=m
CONFIG_USB_GSPCA_KONICA=m
CONFIG_USB_GSPCA_MARS=m
CONFIG_USB_GSPCA_MR97310A=m
CONFIG_USB_GSPCA_NW80X=m
CONFIG_USB_GSPCA_OV519=m
CONFIG_USB_GSPCA_OV534=m
CONFIG_USB_GSPCA_OV534_9=m
CONFIG_USB_GSPCA_PAC207=m
CONFIG_USB_GSPCA_PAC7302=m
CONFIG_USB_GSPCA_PAC7311=m
CONFIG_USB_GSPCA_SE401=m
CONFIG_USB_GSPCA_SN9C2028=m
CONFIG_USB_GSPCA_SN9C20X=m
CONFIG_USB_GSPCA_SONIXB=m
CONFIG_USB_GSPCA_SONIXJ=m
CONFIG_USB_GSPCA_SPCA1528=m
CONFIG_USB_GSPCA_SPCA500=m
CONFIG_USB_GSPCA_SPCA501=m
CONFIG_USB_GSPCA_SPCA505=m
CONFIG_USB_GSPCA_SPCA506=m
CONFIG_USB_GSPCA_SPCA508=m
CONFIG_USB_GSPCA_SPCA561=m
CONFIG_USB_GSPCA_SQ905=m
CONFIG_USB_GSPCA_SQ905C=m
CONFIG_USB_GSPCA_SQ930X=m
CONFIG_USB_GSPCA_STK014=m
CONFIG_USB_GSPCA_STK1135=m
CONFIG_USB_GSPCA_STV0680=m
CONFIG_USB_GSPCA_SUNPLUS=m
CONFIG_USB_GSPCA_T613=m
CONFIG_USB_GSPCA_TOPRO=m
CONFIG_USB_GSPCA_TOUPTEK=m
CONFIG_USB_GSPCA_TV8532=m
CONFIG_USB_GSPCA_VC032X=m
CONFIG_USB_GSPCA_VICAM=m
CONFIG_USB_GSPCA_XIRLINK_CIT=m
CONFIG_USB_GSPCA_ZC3XX=m
CONFIG_USB_GL860=m
CONFIG_USB_M5602=m
CONFIG_USB_STV06XX=m
CONFIG_USB_PWC=m
CONFIG_USB_PWC_DEBUG=y
CONFIG_USB_PWC_INPUT_EVDEV=y
CONFIG_USB_S2255=m
CONFIG_VIDEO_USBTV=m
CONFIG_USB_VIDEO_CLASS=m
CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
#
# Analog TV USB devices
#
CONFIG_VIDEO_GO7007=m
CONFIG_VIDEO_GO7007_USB=m
CONFIG_VIDEO_GO7007_LOADER=m
CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m
CONFIG_VIDEO_HDPVR=m
CONFIG_VIDEO_PVRUSB2=m
CONFIG_VIDEO_PVRUSB2_SYSFS=y
CONFIG_VIDEO_PVRUSB2_DVB=y
CONFIG_VIDEO_PVRUSB2_DEBUGIFC=y
CONFIG_VIDEO_STK1160=m
#
# Analog/digital TV USB devices
#
CONFIG_VIDEO_AU0828=m
CONFIG_VIDEO_AU0828_V4L2=y
CONFIG_VIDEO_AU0828_RC=y
CONFIG_VIDEO_CX231XX=m
CONFIG_VIDEO_CX231XX_RC=y
CONFIG_VIDEO_CX231XX_ALSA=m
CONFIG_VIDEO_CX231XX_DVB=m
#
# Digital TV USB devices
#
CONFIG_DVB_AS102=m
CONFIG_DVB_B2C2_FLEXCOP_USB=m
CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG=y
CONFIG_DVB_USB_V2=m
CONFIG_DVB_USB_AF9015=m
CONFIG_DVB_USB_AF9035=m
CONFIG_DVB_USB_ANYSEE=m
CONFIG_DVB_USB_AU6610=m
CONFIG_DVB_USB_AZ6007=m
CONFIG_DVB_USB_CE6230=m
CONFIG_DVB_USB_DVBSKY=m
CONFIG_DVB_USB_EC168=m
CONFIG_DVB_USB_GL861=m
CONFIG_DVB_USB_LME2510=m
CONFIG_DVB_USB_MXL111SF=m
CONFIG_DVB_USB_RTL28XXU=m
CONFIG_DVB_USB_ZD1301=m
CONFIG_DVB_USB=m
CONFIG_DVB_USB_DEBUG=y
CONFIG_DVB_USB_A800=m
CONFIG_DVB_USB_AF9005=m
CONFIG_DVB_USB_AF9005_REMOTE=m
CONFIG_DVB_USB_AZ6027=m
CONFIG_DVB_USB_CINERGY_T2=m
CONFIG_DVB_USB_CXUSB=m
CONFIG_DVB_USB_CXUSB_ANALOG=y
CONFIG_DVB_USB_DIB0700=m
CONFIG_DVB_USB_DIB3000MC=m
CONFIG_DVB_USB_DIBUSB_MB=m
CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y
CONFIG_DVB_USB_DIBUSB_MC=m
CONFIG_DVB_USB_DIGITV=m
CONFIG_DVB_USB_DTT200U=m
CONFIG_DVB_USB_DTV5100=m
CONFIG_DVB_USB_DW2102=m
CONFIG_DVB_USB_GP8PSK=m
CONFIG_DVB_USB_M920X=m
CONFIG_DVB_USB_NOVA_T_USB2=m
CONFIG_DVB_USB_OPERA1=m
CONFIG_DVB_USB_PCTV452E=m
CONFIG_DVB_USB_TECHNISAT_USB2=m
CONFIG_DVB_USB_TTUSB2=m
CONFIG_DVB_USB_UMT_010=m
CONFIG_DVB_USB_VP702X=m
CONFIG_DVB_USB_VP7045=m
CONFIG_SMS_USB_DRV=m
CONFIG_DVB_TTUSB_BUDGET=m
CONFIG_DVB_TTUSB_DEC=m
#
# Webcam, TV (analog/digital) USB devices
#
CONFIG_VIDEO_EM28XX=m
CONFIG_VIDEO_EM28XX_V4L2=m
CONFIG_VIDEO_EM28XX_ALSA=m
CONFIG_VIDEO_EM28XX_DVB=m
CONFIG_VIDEO_EM28XX_RC=m
#
# Software defined radio USB devices
#
CONFIG_USB_AIRSPY=m
CONFIG_USB_HACKRF=m
CONFIG_USB_MSI2500=m
CONFIG_MEDIA_PCI_SUPPORT=y
#
# Media capture support
#
CONFIG_VIDEO_HWS=m
CONFIG_VIDEO_MGB4=m
CONFIG_VIDEO_SOLO6X10=m
CONFIG_VIDEO_TW5864=m
CONFIG_VIDEO_TW68=m
CONFIG_VIDEO_TW686X=m
CONFIG_VIDEO_ZORAN=m
CONFIG_VIDEO_ZORAN_DC30=y
CONFIG_VIDEO_ZORAN_ZR36060=y
CONFIG_VIDEO_ZORAN_BUZ=y
CONFIG_VIDEO_ZORAN_DC10=y
CONFIG_VIDEO_ZORAN_LML33=y
CONFIG_VIDEO_ZORAN_LML33R10=y
CONFIG_VIDEO_ZORAN_AVS6EYES=y
#
# Media capture/analog TV support
#
CONFIG_VIDEO_DT3155=m
CONFIG_VIDEO_IVTV=m
CONFIG_VIDEO_IVTV_ALSA=m
CONFIG_VIDEO_FB_IVTV=m
CONFIG_VIDEO_FB_IVTV_FORCE_PAT=y
CONFIG_VIDEO_HEXIUM_GEMINI=m
CONFIG_VIDEO_HEXIUM_ORION=m
CONFIG_VIDEO_MXB=m
#
# Media capture/analog/hybrid TV support
#
CONFIG_VIDEO_BT848=m
CONFIG_DVB_BT8XX=m
CONFIG_VIDEO_COBALT=m
CONFIG_VIDEO_CX18=m
CONFIG_VIDEO_CX18_ALSA=m
CONFIG_VIDEO_CX23885=m
CONFIG_MEDIA_ALTERA_CI=m
CONFIG_VIDEO_CX25821=m
CONFIG_VIDEO_CX25821_ALSA=m
CONFIG_VIDEO_CX88=m
CONFIG_VIDEO_CX88_ALSA=m
CONFIG_VIDEO_CX88_BLACKBIRD=m
CONFIG_VIDEO_CX88_DVB=m
CONFIG_VIDEO_CX88_ENABLE_VP3054=y
CONFIG_VIDEO_CX88_VP3054=m
CONFIG_VIDEO_CX88_MPEG=m
CONFIG_VIDEO_SAA7134=m
CONFIG_VIDEO_SAA7134_ALSA=m
CONFIG_VIDEO_SAA7134_RC=y
CONFIG_VIDEO_SAA7134_DVB=m
CONFIG_VIDEO_SAA7134_GO7007=m
CONFIG_VIDEO_SAA7164=m
#
# Media digital TV PCI Adapters
#
CONFIG_DVB_B2C2_FLEXCOP_PCI=m
CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG=y
CONFIG_DVB_DDBRIDGE=m
CONFIG_DVB_DDBRIDGE_MSIENABLE=y
CONFIG_DVB_DM1105=m
CONFIG_MANTIS_CORE=m
CONFIG_DVB_MANTIS=m
CONFIG_DVB_HOPPER=m
CONFIG_DVB_NETUP_UNIDVB=m
CONFIG_DVB_NGENE=m
CONFIG_DVB_PLUTO2=m
CONFIG_DVB_PT1=m
CONFIG_DVB_PT3=m
CONFIG_DVB_SMIPCIE=m
CONFIG_DVB_BUDGET_CORE=m
CONFIG_DVB_BUDGET=m
CONFIG_DVB_BUDGET_CI=m
CONFIG_DVB_BUDGET_AV=m
CONFIG_VIDEO_PCI_SKELETON=m
CONFIG_VIDEO_IPU3_CIO2=m
CONFIG_VIDEO_INTEL_IPU6=m
CONFIG_INTEL_VSC=m
CONFIG_IPU_BRIDGE=m
CONFIG_RADIO_ADAPTERS=m
CONFIG_RADIO_MAXIRADIO=m
CONFIG_RADIO_SAA7706H=m
CONFIG_RADIO_SHARK=m
CONFIG_RADIO_SHARK2=m
CONFIG_RADIO_SI4713=m
CONFIG_RADIO_SI476X=m
CONFIG_RADIO_TEA575X=m
CONFIG_RADIO_TEA5764=m
CONFIG_RADIO_TEF6862=m
CONFIG_RADIO_TIMBERDALE=m
CONFIG_USB_DSBR=m
CONFIG_USB_KEENE=m
CONFIG_USB_MA901=m
CONFIG_USB_MR800=m
CONFIG_USB_RAREMONO=m
CONFIG_RADIO_SI470X=m
CONFIG_USB_SI470X=m
CONFIG_I2C_SI470X=m
CONFIG_USB_SI4713=m
CONFIG_PLATFORM_SI4713=m
CONFIG_I2C_SI4713=m
CONFIG_V4L_RADIO_ISA_DRIVERS=y
CONFIG_RADIO_AZTECH=m
CONFIG_RADIO_CADET=m
CONFIG_RADIO_GEMTEK=m
CONFIG_RADIO_ISA=m
CONFIG_RADIO_MIROPCM20=m
CONFIG_RADIO_RTRACK=m
CONFIG_RADIO_RTRACK2=m
CONFIG_RADIO_SF16FMI=m
CONFIG_RADIO_SF16FMR2=m
CONFIG_RADIO_TERRATEC=m
CONFIG_RADIO_TRUST=m
CONFIG_RADIO_TYPHOON=m
CONFIG_RADIO_ZOLTRIX=m
CONFIG_MEDIA_PLATFORM_DRIVERS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_SDR_PLATFORM_DRIVERS=y
CONFIG_DVB_PLATFORM_DRIVERS=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m
CONFIG_VIDEO_MUX=m
#
# Allegro DVT media platform drivers
#
CONFIG_VIDEO_ALLEGRO_DVT=m
#
# Amlogic media platform drivers
#
CONFIG_VIDEO_C3_ISP=m
CONFIG_VIDEO_C3_MIPI_ADAPTER=m
CONFIG_VIDEO_C3_MIPI_CSI2=m
CONFIG_VIDEO_MESON_GE2D=m
#
# Amphion drivers
#
CONFIG_VIDEO_AMPHION_VPU=m
#
# ARM media platform drivers
#
CONFIG_VIDEO_MALI_C55=m
#
# Aspeed media platform drivers
#
CONFIG_VIDEO_ASPEED=m
#
# Atmel media platform drivers
#
CONFIG_VIDEO_ATMEL_ISI=m
CONFIG_VIDEO_BCM2835_UNICAM=m
#
# Cadence media platform drivers
#
CONFIG_VIDEO_CADENCE_CSI2RX=m
CONFIG_VIDEO_CADENCE_CSI2TX=m
#
# Chips&Media media platform drivers
#
CONFIG_VIDEO_CODA=m
CONFIG_VIDEO_IMX_VDOA=m
CONFIG_VIDEO_WAVE_VPU=m
CONFIG_VIDEO_E5010_JPEG_ENC=m
#
# Intel media platform drivers
#
CONFIG_VIDEO_PXA27x=m
#
# Marvell media platform drivers
#
CONFIG_VIDEO_CAFE_CCIC=m
CONFIG_VIDEO_MMP_CAMERA=m
#
# Mediatek media platform drivers
#
CONFIG_VIDEO_MEDIATEK_JPEG=m
CONFIG_VIDEO_MEDIATEK_MDP=m
CONFIG_VIDEO_MEDIATEK_VCODEC_SCP=y
CONFIG_VIDEO_MEDIATEK_VCODEC_VPU=y
CONFIG_VIDEO_MEDIATEK_VCODEC=m
CONFIG_VIDEO_MEDIATEK_VPU=m
CONFIG_VIDEO_MEDIATEK_MDP3=m
#
# Microchip Technology, Inc. media platform drivers
#
CONFIG_VIDEO_MICROCHIP_ISC=m
CONFIG_VIDEO_MICROCHIP_XISC=m
CONFIG_VIDEO_MICROCHIP_ISC_BASE=m
CONFIG_VIDEO_MICROCHIP_CSI2DC=m
#
# Nuvoton media platform drivers
#
CONFIG_VIDEO_NPCM_VCD_ECE=m
#
# NVidia media platform drivers
#
CONFIG_VIDEO_TEGRA_VDE=m
#
# NXP media platform drivers
#
CONFIG_VIDEO_IMX7_CSI=m
CONFIG_VIDEO_IMX8MQ_MIPI_CSI2=m
CONFIG_VIDEO_IMX_MIPI_CSIS=m
CONFIG_VIDEO_IMX8_ISI=m
CONFIG_VIDEO_IMX8_ISI_M2M=y
CONFIG_VIDEO_IMX_PXP=m
CONFIG_VIDEO_MX2_EMMAPRP=m
CONFIG_VIDEO_DW100=m
CONFIG_VIDEO_IMX8_JPEG=m
#
# Qualcomm media platform drivers
#
CONFIG_VIDEO_QCOM_CAMSS=m
CONFIG_VIDEO_QCOM_IRIS=m
CONFIG_VIDEO_QCOM_VENUS=m
#
# Raspberry Pi media platform drivers
#
CONFIG_VIDEO_RASPBERRYPI_PISP_BE=m
CONFIG_VIDEO_RP1_CFE=m
#
# Renesas media platform drivers
#
CONFIG_VIDEO_RENESAS_CEU=m
CONFIG_VIDEO_RCAR_CSI2=m
CONFIG_VIDEO_SH_VOU=m
CONFIG_VIDEO_RCAR_ISP=m
CONFIG_VIDEO_RCAR_VIN=m
CONFIG_VIDEO_RZG2L_CSI2=m
CONFIG_VIDEO_RZG2L_CRU=m
CONFIG_VIDEO_RZV2H_IVC=m
CONFIG_VIDEO_RENESAS_FCP=m
CONFIG_VIDEO_RENESAS_FDP1=m
CONFIG_VIDEO_RENESAS_JPU=m
CONFIG_VIDEO_RENESAS_VSP1=m
CONFIG_VIDEO_RCAR_DRIF=m
#
# Rockchip media platform drivers
#
CONFIG_VIDEO_ROCKCHIP_RGA=m
CONFIG_VIDEO_ROCKCHIP_CIF=m
CONFIG_VIDEO_ROCKCHIP_ISP1=m
CONFIG_VIDEO_ROCKCHIP_VDEC=m
#
# Samsung media platform drivers
#
CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=m
CONFIG_VIDEO_EXYNOS4_IS_COMMON=m
CONFIG_VIDEO_S5P_FIMC=m
CONFIG_VIDEO_S5P_MIPI_CSIS=m
CONFIG_VIDEO_EXYNOS_FIMC_LITE=m
CONFIG_VIDEO_EXYNOS4_FIMC_IS=m
CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE=y
CONFIG_VIDEO_S3C_CAMIF=m
CONFIG_VIDEO_SAMSUNG_S5P_G2D=m
CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
#
# STMicroelectronics media platform drivers
#
CONFIG_VIDEO_STI_BDISP=m
CONFIG_VIDEO_STI_DELTA=m
CONFIG_VIDEO_STI_DELTA_MJPEG=y
CONFIG_VIDEO_STI_DELTA_DRIVER=m
CONFIG_VIDEO_STI_HVA=m
CONFIG_VIDEO_STI_HVA_DEBUGFS=y
CONFIG_VIDEO_STM32_CSI=m
CONFIG_VIDEO_STM32_DCMI=m
CONFIG_VIDEO_STM32_DCMIPP=m
CONFIG_VIDEO_STM32_DMA2D=m
#
# Sunxi media platform drivers
#
CONFIG_VIDEO_SUN4I_CSI=m
CONFIG_VIDEO_SUN6I_CSI=m
CONFIG_VIDEO_SUN6I_MIPI_CSI2=m
CONFIG_VIDEO_SUN8I_A83T_MIPI_CSI2=m
CONFIG_VIDEO_SUN8I_DEINTERLACE=m
CONFIG_VIDEO_SUN8I_ROTATE=m
CONFIG_VIDEO_SYNOPSYS_HDMIRX=m
CONFIG_VIDEO_SYNOPSYS_HDMIRX_LOAD_DEFAULT_EDID=y
CONFIG_VIDEO_DW_MIPI_CSI2RX=m
#
# Texas Instruments drivers
#
CONFIG_VIDEO_TI_VPDMA=m
CONFIG_VIDEO_TI_SC=m
CONFIG_VIDEO_TI_CSC=m
CONFIG_VIDEO_TI_CAL=m
CONFIG_VIDEO_TI_CAL_MC=y
CONFIG_VIDEO_TI_VIP=m
CONFIG_VIDEO_TI_VPE=m
CONFIG_VIDEO_TI_VPE_DEBUG=y
CONFIG_VIDEO_TI_J721E_CSI2RX=m
CONFIG_VIDEO_AM437X_VPFE=m
CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY=m
CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE=m
CONFIG_VIDEO_OMAP2_VOUT_VRFB=y
CONFIG_VIDEO_OMAP2_VOUT=m
CONFIG_VIDEO_OMAP3=m
CONFIG_VIDEO_OMAP3_DEBUG=y
#
# Verisilicon media platform drivers
#
CONFIG_VIDEO_HANTRO=m
CONFIG_VIDEO_HANTRO_HEVC_RFC=y
CONFIG_VIDEO_HANTRO_IMX8M=y
CONFIG_VIDEO_HANTRO_SAMA5D4=y
CONFIG_VIDEO_HANTRO_ROCKCHIP=y
CONFIG_VIDEO_HANTRO_SUNXI=y
CONFIG_VIDEO_HANTRO_STM32MP25=y
#
# VIA media platform drivers
#
CONFIG_VIDEO_VIA_CAMERA=m
#
# Xilinx media platform drivers
#
CONFIG_VIDEO_XILINX=m
CONFIG_VIDEO_XILINX_CSI2RXSS=m
CONFIG_VIDEO_XILINX_TPG=m
CONFIG_VIDEO_XILINX_VTC=m
#
# MMC/SDIO DVB adapters
#
CONFIG_SMS_SDIO_DRV=m
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_VIDEO_VIM2M=m
CONFIG_VIDEO_VICODEC=m
CONFIG_VIDEO_VIMC=m
CONFIG_VIDEO_VIVID=m
CONFIG_VIDEO_VIVID_CEC=y
CONFIG_VIDEO_VIVID_OSD=y
CONFIG_VIDEO_VIVID_MAX_DEVS=64
CONFIG_VIDEO_VISL=m
CONFIG_VISL_DEBUGFS=y
CONFIG_DVB_TEST_DRIVERS=y
CONFIG_DVB_VIDTV=m
#
# FireWire (IEEE 1394) Adapters
#
CONFIG_DVB_FIREDTV=m
CONFIG_DVB_FIREDTV_INPUT=y
CONFIG_MEDIA_COMMON_OPTIONS=y
#
# common driver options
#
CONFIG_CYPRESS_FIRMWARE=m
CONFIG_TTPCI_EEPROM=m
CONFIG_UVC_COMMON=m
CONFIG_VIDEO_CX2341X=m
CONFIG_VIDEO_TVEEPROM=m
CONFIG_DVB_B2C2_FLEXCOP=m
CONFIG_DVB_B2C2_FLEXCOP_DEBUG=y
CONFIG_VIDEO_SAA7146=m
CONFIG_VIDEO_SAA7146_VV=m
CONFIG_SMS_SIANO_MDTV=m
CONFIG_SMS_SIANO_RC=y
CONFIG_SMS_SIANO_DEBUGFS=y
CONFIG_VIDEO_V4L2_TPG=m
CONFIG_VIDEOBUF2_CORE=m
CONFIG_VIDEOBUF2_V4L2=m
CONFIG_VIDEOBUF2_MEMOPS=m
CONFIG_VIDEOBUF2_DMA_CONTIG=m
CONFIG_VIDEOBUF2_VMALLOC=m
CONFIG_VIDEOBUF2_DMA_SG=m
CONFIG_VIDEOBUF2_DVB=m
# end of Media drivers
#
# Media ancillary drivers
#
CONFIG_MEDIA_ATTACH=y
#
# IR I2C driver auto-selected by 'Autoselect ancillary drivers'
#
CONFIG_VIDEO_IR_I2C=m
CONFIG_VIDEO_CAMERA_SENSOR=y
CONFIG_VIDEO_APTINA_PLL=m
CONFIG_VIDEO_CCS_PLL=m
CONFIG_VIDEO_ALVIUM_CSI2=m
CONFIG_VIDEO_AR0521=m
CONFIG_VIDEO_GC0308=m
CONFIG_VIDEO_GC0310=m
CONFIG_VIDEO_GC05A2=m
CONFIG_VIDEO_GC08A3=m
CONFIG_VIDEO_GC2145=m
CONFIG_VIDEO_HI556=m
CONFIG_VIDEO_HI846=m
CONFIG_VIDEO_HI847=m
CONFIG_VIDEO_IMX111=m
CONFIG_VIDEO_IMX208=m
CONFIG_VIDEO_IMX214=m
CONFIG_VIDEO_IMX219=m
CONFIG_VIDEO_IMX258=m
CONFIG_VIDEO_IMX274=m
CONFIG_VIDEO_IMX283=m
CONFIG_VIDEO_IMX290=m
CONFIG_VIDEO_IMX296=m
CONFIG_VIDEO_IMX319=m
CONFIG_VIDEO_IMX334=m
CONFIG_VIDEO_IMX335=m
CONFIG_VIDEO_IMX355=m
CONFIG_VIDEO_IMX412=m
CONFIG_VIDEO_IMX415=m
CONFIG_VIDEO_MAX9271_LIB=m
CONFIG_VIDEO_MT9M001=m
CONFIG_VIDEO_MT9M111=m
CONFIG_VIDEO_MT9M114=m
CONFIG_VIDEO_MT9P031=m
CONFIG_VIDEO_MT9T112=m
CONFIG_VIDEO_MT9V011=m
CONFIG_VIDEO_MT9V032=m
CONFIG_VIDEO_MT9V111=m
CONFIG_VIDEO_OG01A1B=m
CONFIG_VIDEO_OG0VE1B=m
CONFIG_VIDEO_OS05B10=m
CONFIG_VIDEO_OV01A10=m
CONFIG_VIDEO_OV02A10=m
CONFIG_VIDEO_OV02E10=m
CONFIG_VIDEO_OV02C10=m
CONFIG_VIDEO_OV08D10=m
CONFIG_VIDEO_OV08X40=m
CONFIG_VIDEO_OV13858=m
CONFIG_VIDEO_OV13B10=m
CONFIG_VIDEO_OV2640=m
CONFIG_VIDEO_OV2659=m
CONFIG_VIDEO_OV2680=m
CONFIG_VIDEO_OV2685=m
CONFIG_VIDEO_OV2732=m
CONFIG_VIDEO_OV2735=m
CONFIG_VIDEO_OV2740=m
CONFIG_VIDEO_OV4689=m
CONFIG_VIDEO_OV5640=m
CONFIG_VIDEO_OV5645=m
CONFIG_VIDEO_OV5647=m
CONFIG_VIDEO_OV5648=m
CONFIG_VIDEO_OV5670=m
CONFIG_VIDEO_OV5675=m
CONFIG_VIDEO_OV5693=m
CONFIG_VIDEO_OV5695=m
CONFIG_VIDEO_OV6211=m
CONFIG_VIDEO_OV64A40=m
CONFIG_VIDEO_OV7251=m
CONFIG_VIDEO_OV7640=m
CONFIG_VIDEO_OV7670=m
CONFIG_VIDEO_OV772X=m
CONFIG_VIDEO_OV7740=m
CONFIG_VIDEO_OV8856=m
CONFIG_VIDEO_OV8858=m
CONFIG_VIDEO_OV8865=m
CONFIG_VIDEO_OV9282=m
CONFIG_VIDEO_OV9640=m
CONFIG_VIDEO_OV9650=m
CONFIG_VIDEO_OV9734=m
CONFIG_VIDEO_RDACM20=m
CONFIG_VIDEO_RDACM21=m
CONFIG_VIDEO_RJ54N1=m
CONFIG_VIDEO_S5C73M3=m
CONFIG_VIDEO_S5K3M5=m
CONFIG_VIDEO_S5K5BAF=m
CONFIG_VIDEO_S5K6A3=m
CONFIG_VIDEO_S5KJN1=m
CONFIG_VIDEO_T4KA3=m
CONFIG_VIDEO_VD55G1=m
CONFIG_VIDEO_VD56G3=m
CONFIG_VIDEO_VGXY61=m
CONFIG_VIDEO_CCS=m
CONFIG_VIDEO_ET8EK8=m
#
# Camera ISPs
#
CONFIG_VIDEO_THP7312=m
# end of Camera ISPs
CONFIG_VIDEO_CAMERA_LENS=y
CONFIG_VIDEO_AD5820=m
CONFIG_VIDEO_AK7375=m
CONFIG_VIDEO_DW9714=m
CONFIG_VIDEO_DW9719=m
CONFIG_VIDEO_DW9768=m
CONFIG_VIDEO_DW9807_VCM=m
#
# Flash devices
#
CONFIG_VIDEO_ADP1653=m
CONFIG_VIDEO_LM3560=m
CONFIG_VIDEO_LM3646=m
# end of Flash devices
#
# Audio decoders, processors and mixers
#
CONFIG_VIDEO_CS3308=m
CONFIG_VIDEO_CS5345=m
CONFIG_VIDEO_CS53L32A=m
CONFIG_VIDEO_MSP3400=m
CONFIG_VIDEO_SONY_BTF_MPX=m
CONFIG_VIDEO_TDA1997X=m
CONFIG_VIDEO_TDA7432=m
CONFIG_VIDEO_TDA9840=m
CONFIG_VIDEO_TEA6415C=m
CONFIG_VIDEO_TEA6420=m
CONFIG_VIDEO_TLV320AIC23B=m
CONFIG_VIDEO_TVAUDIO=m
CONFIG_VIDEO_UDA1342=m
CONFIG_VIDEO_VP27SMPX=m
CONFIG_VIDEO_WM8739=m
CONFIG_VIDEO_WM8775=m
# end of Audio decoders, processors and mixers
#
# RDS decoders
#
CONFIG_VIDEO_SAA6588=m
# end of RDS decoders
#
# Video decoders
#
CONFIG_VIDEO_ADV7180=m
CONFIG_VIDEO_ADV7183=m
CONFIG_VIDEO_ADV748X=m
CONFIG_VIDEO_ADV7604=m
CONFIG_VIDEO_ADV7604_CEC=y
CONFIG_VIDEO_ADV7842=m
CONFIG_VIDEO_ADV7842_CEC=y
CONFIG_VIDEO_BT819=m
CONFIG_VIDEO_BT856=m
CONFIG_VIDEO_BT866=m
CONFIG_VIDEO_ISL7998X=m
CONFIG_VIDEO_LT6911UXE=m
CONFIG_VIDEO_KS0127=m
CONFIG_VIDEO_MAX9286=m
CONFIG_VIDEO_ML86V7667=m
CONFIG_VIDEO_SAA7110=m
CONFIG_VIDEO_SAA711X=m
CONFIG_VIDEO_TC358743=m
CONFIG_VIDEO_TC358743_CEC=y
CONFIG_VIDEO_TC358746=m
CONFIG_VIDEO_TVP514X=m
CONFIG_VIDEO_TVP5150=m
CONFIG_VIDEO_TVP7002=m
CONFIG_VIDEO_TW2804=m
CONFIG_VIDEO_TW9900=m
CONFIG_VIDEO_TW9903=m
CONFIG_VIDEO_TW9906=m
CONFIG_VIDEO_TW9910=m
CONFIG_VIDEO_VPX3220=m
#
# Video and audio decoders
#
CONFIG_VIDEO_SAA717X=m
CONFIG_VIDEO_CX25840=m
# end of Video decoders
#
# Video encoders
#
CONFIG_VIDEO_ADV7170=m
CONFIG_VIDEO_ADV7175=m
CONFIG_VIDEO_ADV7343=m
CONFIG_VIDEO_ADV7393=m
CONFIG_VIDEO_ADV7511=m
CONFIG_VIDEO_ADV7511_CEC=y
CONFIG_VIDEO_AK881X=m
CONFIG_VIDEO_SAA7127=m
CONFIG_VIDEO_SAA7185=m
CONFIG_VIDEO_THS8200=m
# end of Video encoders
#
# Video improvement chips
#
CONFIG_VIDEO_UPD64031A=m
CONFIG_VIDEO_UPD64083=m
# end of Video improvement chips
#
# Audio/Video compression chips
#
CONFIG_VIDEO_SAA6752HS=m
# end of Audio/Video compression chips
#
# SDR tuner chips
#
CONFIG_SDR_MAX2175=m
# end of SDR tuner chips
#
# Miscellaneous helper chips
#
CONFIG_VIDEO_I2C=m
CONFIG_VIDEO_M52790=m
CONFIG_VIDEO_ST_MIPID02=m
CONFIG_VIDEO_THS7303=m
# end of Miscellaneous helper chips
#
# Video serializers and deserializers
#
CONFIG_VIDEO_DS90UB913=m
CONFIG_VIDEO_DS90UB953=m
CONFIG_VIDEO_DS90UB960=m
CONFIG_VIDEO_MAX96714=m
CONFIG_VIDEO_MAX96717=m
# end of Video serializers and deserializers
#
# Media SPI Adapters
#
CONFIG_CXD2880_SPI_DRV=m
CONFIG_VIDEO_GS1662=m
# end of Media SPI Adapters
CONFIG_MEDIA_TUNER=m
#
# Customize TV tuners
#
CONFIG_MEDIA_TUNER_E4000=m
CONFIG_MEDIA_TUNER_FC0011=m
CONFIG_MEDIA_TUNER_FC0012=m
CONFIG_MEDIA_TUNER_FC0013=m
CONFIG_MEDIA_TUNER_FC2580=m
CONFIG_MEDIA_TUNER_IT913X=m
CONFIG_MEDIA_TUNER_M88RS6000T=m
CONFIG_MEDIA_TUNER_MAX2165=m
CONFIG_MEDIA_TUNER_MC44S803=m
CONFIG_MEDIA_TUNER_MSI001=m
CONFIG_MEDIA_TUNER_MT2060=m
CONFIG_MEDIA_TUNER_MT2063=m
CONFIG_MEDIA_TUNER_MT20XX=m
CONFIG_MEDIA_TUNER_MT2131=m
CONFIG_MEDIA_TUNER_MT2266=m
CONFIG_MEDIA_TUNER_MXL301RF=m
CONFIG_MEDIA_TUNER_MXL5005S=m
CONFIG_MEDIA_TUNER_MXL5007T=m
CONFIG_MEDIA_TUNER_QM1D1B0004=m
CONFIG_MEDIA_TUNER_QM1D1C0042=m
CONFIG_MEDIA_TUNER_QT1010=m
CONFIG_MEDIA_TUNER_R820T=m
CONFIG_MEDIA_TUNER_SI2157=m
CONFIG_MEDIA_TUNER_SIMPLE=m
CONFIG_MEDIA_TUNER_TDA18212=m
CONFIG_MEDIA_TUNER_TDA18218=m
CONFIG_MEDIA_TUNER_TDA18250=m
CONFIG_MEDIA_TUNER_TDA18271=m
CONFIG_MEDIA_TUNER_TDA827X=m
CONFIG_MEDIA_TUNER_TDA8290=m
CONFIG_MEDIA_TUNER_TDA9887=m
CONFIG_MEDIA_TUNER_TEA5761=m
CONFIG_MEDIA_TUNER_TEA5767=m
CONFIG_MEDIA_TUNER_TUA9001=m
CONFIG_MEDIA_TUNER_XC2028=m
CONFIG_MEDIA_TUNER_XC4000=m
CONFIG_MEDIA_TUNER_XC5000=m
# end of Customize TV tuners
#
# Customise DVB Frontends
#
#
# Multistandard (satellite) frontends
#
CONFIG_DVB_M88DS3103=m
CONFIG_DVB_MXL5XX=m
CONFIG_DVB_STB0899=m
CONFIG_DVB_STB6100=m
CONFIG_DVB_STV090x=m
CONFIG_DVB_STV0910=m
CONFIG_DVB_STV6110x=m
CONFIG_DVB_STV6111=m
#
# Multistandard (cable + terrestrial) frontends
#
CONFIG_DVB_DRXK=m
CONFIG_DVB_MN88472=m
CONFIG_DVB_MN88473=m
CONFIG_DVB_SI2165=m
CONFIG_DVB_TDA18271C2DD=m
#
# DVB-S (satellite) frontends
#
CONFIG_DVB_CX24110=m
CONFIG_DVB_CX24116=m
CONFIG_DVB_CX24117=m
CONFIG_DVB_CX24120=m
CONFIG_DVB_CX24123=m
CONFIG_DVB_DS3000=m
CONFIG_DVB_MB86A16=m
CONFIG_DVB_MT312=m
CONFIG_DVB_S5H1420=m
CONFIG_DVB_SI21XX=m
CONFIG_DVB_STB6000=m
CONFIG_DVB_STV0288=m
CONFIG_DVB_STV0299=m
CONFIG_DVB_STV0900=m
CONFIG_DVB_STV6110=m
CONFIG_DVB_TDA10071=m
CONFIG_DVB_TDA10086=m
CONFIG_DVB_TDA8083=m
CONFIG_DVB_TDA8261=m
CONFIG_DVB_TDA826X=m
CONFIG_DVB_TS2020=m
CONFIG_DVB_TUA6100=m
CONFIG_DVB_TUNER_CX24113=m
CONFIG_DVB_TUNER_ITD1000=m
CONFIG_DVB_VES1X93=m
CONFIG_DVB_ZL10036=m
CONFIG_DVB_ZL10039=m
#
# DVB-T (terrestrial) frontends
#
CONFIG_DVB_AF9013=m
CONFIG_DVB_AS102_FE=m
CONFIG_DVB_CX22700=m
CONFIG_DVB_CX22702=m
CONFIG_DVB_CXD2820R=m
CONFIG_DVB_CXD2841ER=m
CONFIG_DVB_DIB3000MB=m
CONFIG_DVB_DIB3000MC=m
CONFIG_DVB_DIB7000M=m
CONFIG_DVB_DIB7000P=m
CONFIG_DVB_DIB9000=m
CONFIG_DVB_DRXD=m
CONFIG_DVB_EC100=m
CONFIG_DVB_GP8PSK_FE=m
CONFIG_DVB_L64781=m
CONFIG_DVB_MT352=m
CONFIG_DVB_NXT6000=m
CONFIG_DVB_RTL2830=m
CONFIG_DVB_RTL2832=m
CONFIG_DVB_RTL2832_SDR=m
CONFIG_DVB_S5H1432=m
CONFIG_DVB_SI2168=m
CONFIG_DVB_SP887X=m
CONFIG_DVB_STV0367=m
CONFIG_DVB_TDA10048=m
CONFIG_DVB_TDA1004X=m
CONFIG_DVB_ZD1301_DEMOD=m
CONFIG_DVB_ZL10353=m
CONFIG_DVB_CXD2880=m
#
# DVB-C (cable) frontends
#
CONFIG_DVB_STV0297=m
CONFIG_DVB_TDA10021=m
CONFIG_DVB_TDA10023=m
CONFIG_DVB_VES1820=m
#
# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
#
CONFIG_DVB_AU8522=m
CONFIG_DVB_AU8522_DTV=m
CONFIG_DVB_AU8522_V4L=m
CONFIG_DVB_BCM3510=m
CONFIG_DVB_LG2160=m
CONFIG_DVB_LGDT3305=m
CONFIG_DVB_LGDT3306A=m
CONFIG_DVB_LGDT330X=m
CONFIG_DVB_MXL692=m
CONFIG_DVB_NXT200X=m
CONFIG_DVB_OR51132=m
CONFIG_DVB_OR51211=m
CONFIG_DVB_S5H1409=m
CONFIG_DVB_S5H1411=m
#
# ISDB-T (terrestrial) frontends
#
CONFIG_DVB_DIB8000=m
CONFIG_DVB_MB86A20S=m
CONFIG_DVB_S921=m
#
# ISDB-S (satellite) & ISDB-T (terrestrial) frontends
#
CONFIG_DVB_MN88443X=m
CONFIG_DVB_TC90522=m
#
# Digital terrestrial only tuners/PLL
#
CONFIG_DVB_PLL=m
CONFIG_DVB_TUNER_DIB0070=m
CONFIG_DVB_TUNER_DIB0090=m
#
# SEC control devices for DVB-S
#
CONFIG_DVB_A8293=m
CONFIG_DVB_AF9033=m
CONFIG_DVB_ASCOT2E=m
CONFIG_DVB_ATBM8830=m
CONFIG_DVB_HELENE=m
CONFIG_DVB_HORUS3A=m
CONFIG_DVB_ISL6405=m
CONFIG_DVB_ISL6421=m
CONFIG_DVB_ISL6423=m
CONFIG_DVB_IX2505V=m
CONFIG_DVB_LGS8GL5=m
CONFIG_DVB_LGS8GXX=m
CONFIG_DVB_LNBH25=m
CONFIG_DVB_LNBH29=m
CONFIG_DVB_LNBP21=m
CONFIG_DVB_LNBP22=m
CONFIG_DVB_M88RS2000=m
CONFIG_DVB_TDA665x=m
CONFIG_DVB_DRX39XYJ=m
#
# Common Interface (EN50221) controller drivers
#
CONFIG_DVB_CXD2099=m
CONFIG_DVB_SP2=m
# end of Customise DVB Frontends
#
# Tools to develop new frontends
#
CONFIG_DVB_DUMMY_FE=m
# end of Media ancillary drivers
#
# Graphics support
#
CONFIG_APERTURE_HELPERS=y
CONFIG_SCREEN_INFO=y
CONFIG_VIDEO=y
CONFIG_AUXDISPLAY=y
CONFIG_CHARLCD=m
CONFIG_HD44780_COMMON=m
CONFIG_HD44780=m
CONFIG_LCD2S=m
CONFIG_PARPORT_PANEL=m
CONFIG_PANEL_PARPORT=0
CONFIG_PANEL_PROFILE=5
CONFIG_PANEL_CHANGE_MESSAGE=y
CONFIG_PANEL_BOOT_MESSAGE=""
# CONFIG_CHARLCD_BL_OFF is not set
# CONFIG_CHARLCD_BL_ON is not set
CONFIG_CHARLCD_BL_FLASH=y
CONFIG_KS0108=m
CONFIG_KS0108_PORT=0x378
CONFIG_KS0108_DELAY=2
CONFIG_CFAG12864B=m
CONFIG_CFAG12864B_RATE=20
CONFIG_LINEDISP=m
CONFIG_IMG_ASCII_LCD=m
CONFIG_HT16K33=m
CONFIG_MAX6959=m
CONFIG_SEG_LED_GPIO=m
CONFIG_PANEL=m
CONFIG_AGP=m
CONFIG_AGP_ALI=m
CONFIG_AGP_ATI=m
CONFIG_AGP_AMD=m
CONFIG_AGP_AMD64=m
CONFIG_AGP_INTEL=m
CONFIG_AGP_NVIDIA=m
CONFIG_AGP_SIS=m
CONFIG_AGP_SWORKS=m
CONFIG_AGP_VIA=m
CONFIG_AGP_EFFICEON=m
CONFIG_INTEL_GTT=m
CONFIG_TEGRA_HOST1X_CONTEXT_BUS=y
CONFIG_TEGRA_HOST1X=m
CONFIG_TEGRA_HOST1X_FIREWALL=y
CONFIG_IMX_IPUV3_CORE=m
CONFIG_DRM=m
#
# DRM debugging options
#
# CONFIG_DRM_WERROR is not set
CONFIG_DRM_DEBUG_MM=y
CONFIG_DRM_KUNIT_TEST_HELPERS=m
CONFIG_DRM_KUNIT_TEST=m
CONFIG_DRM_TTM_KUNIT_TEST=m
CONFIG_DRM_SCHED_KUNIT_TEST=m
CONFIG_DRM_EXPORT_FOR_TESTS=y
# end of DRM debugging options
CONFIG_DRM_MIPI_DBI=m
CONFIG_DRM_MIPI_DSI=y
CONFIG_DRM_KMS_HELPER=m
CONFIG_DRM_DRAW=y
CONFIG_DRM_PANIC=y
CONFIG_DRM_PANIC_FOREGROUND_COLOR=0xffffff
CONFIG_DRM_PANIC_BACKGROUND_COLOR=0x000000
CONFIG_DRM_PANIC_DEBUG=y
CONFIG_DRM_PANIC_SCREEN="user"
CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS=y
CONFIG_DRM_DEBUG_MODESET_LOCK=y
CONFIG_DRM_CLIENT=y
CONFIG_DRM_CLIENT_LIB=m
CONFIG_DRM_CLIENT_SELECTION=m
CONFIG_DRM_CLIENT_SETUP=y
#
# Supported DRM clients
#
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=100
CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM=y
CONFIG_DRM_CLIENT_LOG=y
CONFIG_DRM_CLIENT_DEFAULT_FBDEV=y
# CONFIG_DRM_CLIENT_DEFAULT_LOG is not set
CONFIG_DRM_CLIENT_DEFAULT="fbdev"
# end of Supported DRM clients
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
CONFIG_DRM_DISPLAY_DP_AUX_BUS=m
CONFIG_DRM_DISPLAY_HELPER=m
CONFIG_DRM_BRIDGE_CONNECTOR=y
CONFIG_DRM_DISPLAY_DP_AUX_CEC=y
CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV=y
CONFIG_DRM_DISPLAY_DP_HELPER=y
CONFIG_DRM_DISPLAY_DP_TUNNEL=y
CONFIG_DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG=y
CONFIG_DRM_DISPLAY_DSC_HELPER=y
CONFIG_DRM_DISPLAY_HDCP_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_AUDIO_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_CEC_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_CEC_NOTIFIER_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_STATE_HELPER=y
CONFIG_DRM_TTM=m
CONFIG_DRM_EXEC=m
CONFIG_DRM_GPUVM=m
CONFIG_DRM_GPUSVM=m
CONFIG_DRM_BUDDY=m
CONFIG_DRM_VRAM_HELPER=m
CONFIG_DRM_TTM_HELPER=m
CONFIG_DRM_GEM_DMA_HELPER=m
CONFIG_DRM_GEM_SHMEM_HELPER=m
CONFIG_DRM_SUBALLOC_HELPER=m
CONFIG_DRM_SCHED=m
CONFIG_DRM_PANEL_BACKLIGHT_QUIRKS=m
CONFIG_DRM_LIB_RANDOM=y
CONFIG_DRM_PRIVACY_SCREEN=y
CONFIG_DRM_AMDGPU=m
CONFIG_DRM_AMDGPU_SI=y
CONFIG_DRM_AMDGPU_CIK=y
CONFIG_DRM_AMDGPU_USERPTR=y
CONFIG_DRM_AMD_ISP=y
#
# ACP (Audio CoProcessor) Configuration
#
CONFIG_DRM_AMD_ACP=y
# end of ACP (Audio CoProcessor) Configuration
#
# Display Engine Configuration
#
CONFIG_DRM_AMD_DC=y
CONFIG_DRM_AMD_DC_FP=y
CONFIG_DRM_AMD_DC_SI=y
CONFIG_DEBUG_KERNEL_DC=y
CONFIG_DRM_AMD_SECURE_DISPLAY=y
# end of Display Engine Configuration
#
# ARM devices
#
CONFIG_DRM_HDLCD=m
CONFIG_DRM_HDLCD_SHOW_UNDERRUN=y
CONFIG_DRM_MALI_DISPLAY=m
CONFIG_DRM_KOMEDA=m
# end of ARM devices
CONFIG_DRM_ASPEED_GFX=m
CONFIG_DRM_AST=m
CONFIG_DRM_ATMEL_HLCDC=m
CONFIG_DRM_BRIDGE=y
CONFIG_DRM_PANEL_BRIDGE=y
CONFIG_DRM_AUX_BRIDGE=m
CONFIG_DRM_AUX_HPD_BRIDGE=m
#
# Display Interface Bridges
#
CONFIG_DRM_CHIPONE_ICN6211=m
CONFIG_DRM_CHRONTEL_CH7033=m
CONFIG_DRM_CROS_EC_ANX7688=m
CONFIG_DRM_DISPLAY_CONNECTOR=m
CONFIG_DRM_FSL_LDB=m
CONFIG_DRM_I2C_NXP_TDA998X=m
CONFIG_DRM_INNO_HDMI=m
CONFIG_DRM_ITE_IT6263=m
CONFIG_DRM_ITE_IT6505=m
CONFIG_DRM_LONTIUM_LT8912B=m
CONFIG_DRM_LONTIUM_LT9211=m
CONFIG_DRM_LONTIUM_LT9611=m
CONFIG_DRM_LONTIUM_LT9611UXC=m
CONFIG_DRM_ITE_IT66121=m
CONFIG_DRM_LVDS_CODEC=m
CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW=m
CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER=m
CONFIG_DRM_NWL_MIPI_DSI=m
CONFIG_DRM_NXP_PTN3460=m
CONFIG_DRM_PARADE_PS8622=m
CONFIG_DRM_PARADE_PS8640=m
CONFIG_DRM_SAMSUNG_DSIM=m
CONFIG_DRM_SIL_SII8620=m
CONFIG_DRM_SII902X=m
CONFIG_DRM_SII9234=m
CONFIG_DRM_SIMPLE_BRIDGE=m
CONFIG_DRM_SOLOMON_SSD2825=m
CONFIG_DRM_THINE_THC63LVD1024=m
CONFIG_DRM_TOSHIBA_TC358762=m
CONFIG_DRM_TOSHIBA_TC358764=m
CONFIG_DRM_TOSHIBA_TC358767=m
CONFIG_DRM_TOSHIBA_TC358768=m
CONFIG_DRM_TOSHIBA_TC358775=m
CONFIG_DRM_TI_DLPC3433=m
CONFIG_DRM_TI_TDP158=m
CONFIG_DRM_TI_TFP410=m
CONFIG_DRM_TI_SN65DSI83=m
CONFIG_DRM_TI_SN65DSI86=m
CONFIG_DRM_TI_TPD12S015=m
CONFIG_DRM_WAVESHARE_BRIDGE=m
CONFIG_DRM_ANALOGIX_ANX6345=m
CONFIG_DRM_ANALOGIX_ANX78XX=m
CONFIG_DRM_ANALOGIX_DP=m
CONFIG_DRM_ANALOGIX_ANX7625=m
CONFIG_DRM_I2C_ADV7511=m
CONFIG_DRM_I2C_ADV7511_AUDIO=y
CONFIG_DRM_I2C_ADV7511_CEC=y
CONFIG_DRM_CDNS_DSI=m
CONFIG_DRM_CDNS_DSI_J721E=y
CONFIG_DRM_CDNS_MHDP8546=m
CONFIG_DRM_CDNS_MHDP8546_J721E=y
CONFIG_DRM_IMX_LDB_HELPER=m
CONFIG_DRM_IMX_LEGACY_BRIDGE=m
CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE=m
CONFIG_DRM_IMX8MP_HDMI_PAI=m
CONFIG_DRM_IMX8MP_HDMI_PVI=m
CONFIG_DRM_IMX8QM_LDB=m
CONFIG_DRM_IMX8QXP_LDB=m
CONFIG_DRM_IMX8QXP_PIXEL_COMBINER=m
CONFIG_DRM_IMX8QXP_PIXEL_LINK=m
CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI=m
CONFIG_DRM_IMX93_MIPI_DSI=m
CONFIG_DRM_DW_DP=m
CONFIG_DRM_DW_HDMI=m
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
CONFIG_DRM_DW_HDMI_I2S_AUDIO=m
CONFIG_DRM_DW_HDMI_GP_AUDIO=m
CONFIG_DRM_DW_HDMI_CEC=m
CONFIG_DRM_DW_HDMI_QP=m
CONFIG_DRM_DW_HDMI_QP_CEC=y
CONFIG_DRM_DW_MIPI_DSI=m
CONFIG_DRM_DW_MIPI_DSI2=m
# end of Display Interface Bridges
CONFIG_DRM_ETNAVIV=m
CONFIG_DRM_ETNAVIV_THERMAL=y
CONFIG_DRM_EXYNOS=m
#
# CRTCs
#
CONFIG_DRM_EXYNOS_FIMD=y
CONFIG_DRM_EXYNOS5433_DECON=y
CONFIG_DRM_EXYNOS7_DECON=y
CONFIG_DRM_EXYNOS_MIXER=y
CONFIG_DRM_EXYNOS_VIDI=y
#
# Encoders and Bridges
#
CONFIG_DRM_EXYNOS_DPI=y
CONFIG_DRM_EXYNOS_DSI=y
CONFIG_DRM_EXYNOS_DP=y
CONFIG_DRM_EXYNOS_HDMI=y
CONFIG_DRM_EXYNOS_MIC=y
#
# Sub-drivers
#
CONFIG_DRM_EXYNOS_G2D=y
CONFIG_DRM_EXYNOS_IPP=y
CONFIG_DRM_EXYNOS_FIMC=y
CONFIG_DRM_EXYNOS_ROTATOR=y
CONFIG_DRM_EXYNOS_SCALER=y
CONFIG_DRM_EXYNOS_GSC=y
CONFIG_DRM_GMA500=m
CONFIG_DRM_GUD=m
CONFIG_DRM_HISI_HIBMC=m
CONFIG_DRM_HISI_KIRIN=m
CONFIG_DRM_HYPERV=m
CONFIG_DRM_I915=m
CONFIG_DRM_I915_FORCE_PROBE=""
CONFIG_DRM_I915_CAPTURE_ERROR=y
CONFIG_DRM_I915_COMPRESS_ERROR=y
CONFIG_DRM_I915_USERPTR=y
CONFIG_DRM_I915_PXP=y
CONFIG_DRM_I915_DP_TUNNEL=y
#
# drm/i915 Debugging
#
CONFIG_DRM_I915_REPLAY_GPU_HANGS_API=y
CONFIG_DRM_I915_DEBUG_MMIO=y
CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS=y
CONFIG_DRM_I915_SW_FENCE_CHECK_DAG=y
CONFIG_DRM_I915_DEBUG_GUC=y
CONFIG_DRM_I915_SELFTEST=y
CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS=y
CONFIG_DRM_I915_DEBUG_VBLANK_EVADE=y
CONFIG_DRM_I915_DEBUG_RUNTIME_PM=y
CONFIG_DRM_I915_DEBUG_WAKEREF=y
# end of drm/i915 Debugging
#
# drm/i915 Profile Guided Optimisation
#
CONFIG_DRM_I915_REQUEST_TIMEOUT=20000
CONFIG_DRM_I915_FENCE_TIMEOUT=10000
CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND=250
CONFIG_DRM_I915_HEARTBEAT_INTERVAL=2500
CONFIG_DRM_I915_PREEMPT_TIMEOUT=640
CONFIG_DRM_I915_PREEMPT_TIMEOUT_COMPUTE=7500
CONFIG_DRM_I915_MAX_REQUEST_BUSYWAIT=8000
CONFIG_DRM_I915_STOP_TIMEOUT=100
CONFIG_DRM_I915_TIMESLICE_DURATION=1
# end of drm/i915 Profile Guided Optimisation
CONFIG_DRM_IMX8_DC=m
CONFIG_DRM_IMX_DCSS=m
CONFIG_DRM_IMX=m
CONFIG_DRM_IMX_PARALLEL_DISPLAY=m
CONFIG_DRM_IMX_TVE=m
CONFIG_DRM_IMX_LDB=m
CONFIG_DRM_IMX_HDMI=m
CONFIG_DRM_IMX_LCDC=m
CONFIG_DRM_INGENIC=m
CONFIG_DRM_INGENIC_IPU=y
CONFIG_DRM_KMB_DISPLAY=m
CONFIG_DRM_LIMA=m
CONFIG_DRM_LOGICVC=m
CONFIG_DRM_LOONGSON=m
CONFIG_DRM_MCDE=m
CONFIG_DRM_MEDIATEK=m
CONFIG_DRM_MEDIATEK_DP=m
CONFIG_DRM_MEDIATEK_HDMI_COMMON=m
CONFIG_DRM_MEDIATEK_HDMI=m
CONFIG_DRM_MEDIATEK_HDMI_V2=m
CONFIG_DRM_MESON=m
CONFIG_DRM_MESON_DW_HDMI=m
CONFIG_DRM_MESON_DW_MIPI_DSI=m
CONFIG_DRM_MGAG200=m
CONFIG_DRM_MSM=m
CONFIG_DRM_MSM_GPU_STATE=y
CONFIG_DRM_MSM_GPU_SUDO=y
CONFIG_DRM_MSM_KMS=y
CONFIG_DRM_MSM_KMS_FBDEV=y
CONFIG_DRM_MSM_MDSS=y
CONFIG_DRM_MSM_MDP4=y
CONFIG_DRM_MSM_MDP5=y
CONFIG_DRM_MSM_DPU=y
CONFIG_DRM_MSM_DP=y
CONFIG_DRM_MSM_DSI=y
CONFIG_DRM_MSM_DSI_28NM_PHY=y
CONFIG_DRM_MSM_DSI_20NM_PHY=y
CONFIG_DRM_MSM_DSI_28NM_8960_PHY=y
CONFIG_DRM_MSM_DSI_14NM_PHY=y
CONFIG_DRM_MSM_DSI_10NM_PHY=y
CONFIG_DRM_MSM_DSI_7NM_PHY=y
CONFIG_DRM_MSM_HDMI=y
CONFIG_DRM_MSM_HDMI_HDCP=y
CONFIG_DRM_MXS=y
CONFIG_DRM_MXSFB=m
CONFIG_DRM_IMX_LCDIF=m
CONFIG_DRM_NOUVEAU=m
CONFIG_NOUVEAU_DEBUG=5
CONFIG_NOUVEAU_DEBUG_DEFAULT=3
CONFIG_NOUVEAU_DEBUG_MMU=y
CONFIG_NOUVEAU_DEBUG_PUSH=y
CONFIG_DRM_NOUVEAU_BACKLIGHT=y
CONFIG_DRM_NOUVEAU_CH7006=m
CONFIG_DRM_NOUVEAU_SIL164=m
CONFIG_DRM_OMAP=m
CONFIG_OMAP2_DSS_DEBUG=y
CONFIG_OMAP2_DSS_DEBUGFS=y
CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS=y
CONFIG_OMAP2_DSS_DPI=y
CONFIG_OMAP2_DSS_VENC=y
CONFIG_OMAP2_DSS_HDMI_COMMON=y
CONFIG_OMAP4_DSS_HDMI=y
CONFIG_OMAP4_DSS_HDMI_CEC=y
CONFIG_OMAP5_DSS_HDMI=y
CONFIG_OMAP2_DSS_SDI=y
CONFIG_OMAP2_DSS_DSI=y
CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET=y
CONFIG_DRM_PANEL=y
#
# Display Panels
#
CONFIG_DRM_PANEL_ABT_Y030XX067A=m
CONFIG_DRM_PANEL_ARM_VERSATILE=m
CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596=m
CONFIG_DRM_PANEL_AUO_A030JTN01=m
CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0=m
CONFIG_DRM_PANEL_BOE_HIMAX8279D=m
CONFIG_DRM_PANEL_BOE_TD4320=m
CONFIG_DRM_PANEL_BOE_TH101MB31UIG002_28A=m
CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
CONFIG_DRM_PANEL_BOE_TV101WUM_LL2=m
CONFIG_DRM_PANEL_EBBG_FT8719=m
CONFIG_DRM_PANEL_ELIDA_KD35T133=m
CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m
CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m
CONFIG_DRM_PANEL_DSI_CM=m
CONFIG_DRM_PANEL_LVDS=m
CONFIG_DRM_PANEL_HIMAX_HX8279=m
CONFIG_DRM_PANEL_HIMAX_HX83102=m
CONFIG_DRM_PANEL_HIMAX_HX83112A=m
CONFIG_DRM_PANEL_HIMAX_HX83112B=m
CONFIG_DRM_PANEL_HIMAX_HX8394=m
CONFIG_DRM_PANEL_HYDIS_HV101HD1=m
CONFIG_DRM_PANEL_ILITEK_IL9322=m
CONFIG_DRM_PANEL_ILITEK_ILI9341=m
CONFIG_DRM_PANEL_ILITEK_ILI9805=m
# CONFIG_DRM_PANEL_ILITEK_ILI9806E is not set
CONFIG_DRM_PANEL_ILITEK_ILI9881C=m
CONFIG_DRM_PANEL_ILITEK_ILI9882T=m
CONFIG_DRM_PANEL_INNOLUX_EJ030NA=m
CONFIG_DRM_PANEL_INNOLUX_P079ZCA=m
CONFIG_DRM_PANEL_JADARD_JD9365DA_H3=m
CONFIG_DRM_PANEL_JDI_LPM102A188A=m
CONFIG_DRM_PANEL_JDI_LT070ME05000=m
CONFIG_DRM_PANEL_JDI_R63452=m
CONFIG_DRM_PANEL_KHADAS_TS050=m
CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=m
CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W=m
CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829=m
CONFIG_DRM_PANEL_LINCOLNTECH_LCD197=m
CONFIG_DRM_PANEL_LG_LB035Q02=m
CONFIG_DRM_PANEL_LG_LD070WX3=m
CONFIG_DRM_PANEL_LG_LG4573=m
CONFIG_DRM_PANEL_LG_SW43408=m
CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966=m
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
CONFIG_DRM_PANEL_NEC_NL8048HL11=m
CONFIG_DRM_PANEL_NEWVISION_NV3051D=m
CONFIG_DRM_PANEL_NEWVISION_NV3052C=m
CONFIG_DRM_PANEL_NOVATEK_NT35510=m
CONFIG_DRM_PANEL_NOVATEK_NT35560=m
CONFIG_DRM_PANEL_NOVATEK_NT35950=m
CONFIG_DRM_PANEL_NOVATEK_NT36523=m
CONFIG_DRM_PANEL_NOVATEK_NT36672A=m
CONFIG_DRM_PANEL_NOVATEK_NT36672E=m
CONFIG_DRM_PANEL_NOVATEK_NT37801=m
CONFIG_DRM_PANEL_NOVATEK_NT39016=m
CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO=m
CONFIG_DRM_PANEL_ORISETECH_OTA5601A=m
CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m
CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS=m
CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00=m
CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m
CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
CONFIG_DRM_PANEL_RAYDIUM_RM67200=m
CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
CONFIG_DRM_PANEL_RAYDIUM_RM692E5=m
CONFIG_DRM_PANEL_RAYDIUM_RM69380=m
CONFIG_DRM_PANEL_RENESAS_R61307=m
CONFIG_DRM_PANEL_RENESAS_R69328=m
CONFIG_DRM_PANEL_RONBO_RB070D30=m
CONFIG_DRM_PANEL_SAMSUNG_AMS581VF01=m
CONFIG_DRM_PANEL_SAMSUNG_AMS639RQ08=m
CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS427AP24=m
CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=m
CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=m
CONFIG_DRM_PANEL_SAMSUNG_DB7430=m
CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
CONFIG_DRM_PANEL_SAMSUNG_LTL106HL02=m
CONFIG_DRM_PANEL_SAMSUNG_S6E3FA7=m
CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=m
CONFIG_DRM_PANEL_SAMSUNG_S6D27A1=m
CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0=m
CONFIG_DRM_PANEL_SAMSUNG_S6E3FC2X01=m
CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2=m
CONFIG_DRM_PANEL_SAMSUNG_S6E3HA8=m
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m
CONFIG_DRM_PANEL_SAMSUNG_S6E63M0=m
CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_SPI=m
CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_DSI=m
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA5X01_AMS561RA01=m
CONFIG_DRM_PANEL_SAMSUNG_SOFEF00=m
CONFIG_DRM_PANEL_SEIKO_43WVF1G=m
CONFIG_DRM_PANEL_SHARP_LQ079L1SX01=m
CONFIG_DRM_PANEL_SHARP_LQ101R1SX01=m
CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m
CONFIG_DRM_PANEL_SHARP_LS043T1LE01=m
CONFIG_DRM_PANEL_SHARP_LS060T1SX01=m
CONFIG_DRM_PANEL_SITRONIX_ST7701=m
CONFIG_DRM_PANEL_SITRONIX_ST7703=m
CONFIG_DRM_PANEL_SITRONIX_ST7789V=m
CONFIG_DRM_PANEL_SONY_ACX565AKM=m
CONFIG_DRM_PANEL_SONY_TD4353_JDI=m
CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521=m
CONFIG_DRM_PANEL_STARTEK_KD070FHFID015=m
CONFIG_DRM_PANEL_EDP=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_PANEL_SUMMIT=m
CONFIG_DRM_PANEL_SYNAPTICS_R63353=m
CONFIG_DRM_PANEL_SYNAPTICS_TDDI=m
CONFIG_DRM_PANEL_TDO_TL070WSH30=m
CONFIG_DRM_PANEL_TPO_TD028TTEC1=m
CONFIG_DRM_PANEL_TPO_TD043MTEA1=m
CONFIG_DRM_PANEL_TPO_TPG110=m
CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
CONFIG_DRM_PANEL_VISIONOX_G2647FB105=m
CONFIG_DRM_PANEL_VISIONOX_R66451=m
CONFIG_DRM_PANEL_VISIONOX_RM69299=m
CONFIG_DRM_PANEL_VISIONOX_RM692E5=m
CONFIG_DRM_PANEL_VISIONOX_VTDR6130=m
CONFIG_DRM_PANEL_WIDECHIPS_WS2401=m
CONFIG_DRM_PANEL_XINPENG_XPP055C272=m
# end of Display Panels
CONFIG_DRM_PANFROST=m
CONFIG_DRM_PANTHOR=m
CONFIG_DRM_PL111=m
CONFIG_DRM_QXL=m
CONFIG_DRM_RADEON=m
CONFIG_DRM_RADEON_USERPTR=y
CONFIG_DRM_RCAR_DU=m
CONFIG_DRM_RCAR_USE_CMM=y
CONFIG_DRM_RCAR_CMM=m
CONFIG_DRM_RCAR_DW_HDMI=m
CONFIG_DRM_RCAR_USE_LVDS=y
CONFIG_DRM_RCAR_LVDS=m
CONFIG_DRM_RCAR_USE_MIPI_DSI=y
CONFIG_DRM_RCAR_MIPI_DSI=m
CONFIG_DRM_RZG2L_DU=m
CONFIG_DRM_RZG2L_USE_MIPI_DSI=y
CONFIG_DRM_RZG2L_MIPI_DSI=m
CONFIG_DRM_SHMOBILE=m
CONFIG_DRM_ROCKCHIP=m
CONFIG_ROCKCHIP_VOP=y
CONFIG_ROCKCHIP_VOP2=y
CONFIG_ROCKCHIP_ANALOGIX_DP=y
CONFIG_ROCKCHIP_CDN_DP=y
CONFIG_ROCKCHIP_DW_DP=y
CONFIG_ROCKCHIP_DW_HDMI=y
CONFIG_ROCKCHIP_DW_HDMI_QP=y
CONFIG_ROCKCHIP_DW_MIPI_DSI=y
CONFIG_ROCKCHIP_DW_MIPI_DSI2=y
CONFIG_ROCKCHIP_INNO_HDMI=y
CONFIG_ROCKCHIP_LVDS=y
CONFIG_ROCKCHIP_RGB=y
CONFIG_ROCKCHIP_RK3066_HDMI=y
CONFIG_DRM_ST7571=m
CONFIG_DRM_ST7571_I2C=m
CONFIG_DRM_ST7571_SPI=m
CONFIG_DRM_ST7586=m
CONFIG_DRM_ST7735R=m
CONFIG_DRM_ST7920=m
CONFIG_DRM_SSD130X=m
CONFIG_DRM_SSD130X_I2C=m
CONFIG_DRM_SSD130X_SPI=m
CONFIG_DRM_SPRD=m
CONFIG_DRM_STI=m
CONFIG_DRM_STM=m
CONFIG_DRM_STM_DSI=m
CONFIG_DRM_STM_LVDS=m
CONFIG_DRM_SUN4I=m
CONFIG_DRM_SUN4I_HDMI=m
CONFIG_DRM_SUN4I_HDMI_CEC=y
CONFIG_DRM_SUN4I_BACKEND=m
CONFIG_DRM_SUN6I_DSI=m
CONFIG_DRM_SUN8I_DW_HDMI=m
CONFIG_DRM_SUN8I_MIXER=m
CONFIG_DRM_SUN8I_TCON_TOP=m
#
# Drivers for system framebuffers
#
CONFIG_DRM_SYSFB_HELPER=m
CONFIG_DRM_EFIDRM=m
CONFIG_DRM_OFDRM=m
CONFIG_DRM_SIMPLEDRM=m
CONFIG_DRM_VESADRM=m
# end of Drivers for system framebuffers
CONFIG_DRM_TEGRA=m
CONFIG_DRM_TEGRA_DEBUG=y
CONFIG_DRM_TEGRA_STAGING=y
CONFIG_DRM_TIDSS=m
CONFIG_DRM_APPLETBDRM=m
CONFIG_DRM_ARCPGU=m
CONFIG_DRM_BOCHS=m
CONFIG_DRM_CIRRUS_QEMU=m
CONFIG_DRM_GM12U320=m
CONFIG_DRM_PANEL_MIPI_DBI=m
CONFIG_DRM_PIXPAPER=m
CONFIG_TINYDRM_HX8357D=m
CONFIG_TINYDRM_ILI9163=m
CONFIG_TINYDRM_ILI9225=m
CONFIG_TINYDRM_ILI9341=m
CONFIG_TINYDRM_ILI9486=m
CONFIG_TINYDRM_MI0283QT=m
CONFIG_TINYDRM_REPAPER=m
CONFIG_TINYDRM_SHARP_MEMORY=m
CONFIG_DRM_TVE200=m
CONFIG_DRM_UDL=m
CONFIG_DRM_V3D=m
CONFIG_DRM_VBOXVIDEO=m
CONFIG_DRM_VC4=m
CONFIG_DRM_VC4_HDMI_CEC=y
CONFIG_DRM_VC4_KUNIT_TEST=m
CONFIG_DRM_VGEM=m
CONFIG_DRM_VIRTIO_GPU=m
CONFIG_DRM_VIRTIO_GPU_KMS=y
CONFIG_DRM_VKMS=m
CONFIG_DRM_VKMS_KUNIT_TEST=m
CONFIG_DRM_VMWGFX=m
CONFIG_DRM_VMWGFX_MKSSTATS=y
CONFIG_DRM_XE=m
CONFIG_DRM_XE_DISPLAY=y
CONFIG_DRM_XE_DP_TUNNEL=y
CONFIG_DRM_XE_FORCE_PROBE=""
#
# drm/Xe Debugging
#
CONFIG_DRM_XE_DEBUG_VM=y
CONFIG_DRM_XE_DEBUG_SRIOV=y
CONFIG_DRM_XE_DEBUG_MEMIRQ=y
CONFIG_DRM_XE_DEBUG_MEM=y
CONFIG_DRM_XE_KUNIT_TEST=m
CONFIG_DRM_XE_USERPTR_INVAL_INJECT=y
# end of drm/Xe Debugging
#
# drm/xe Profile Guided Optimisation
#
CONFIG_DRM_XE_JOB_TIMEOUT_MAX=10000
CONFIG_DRM_XE_JOB_TIMEOUT_MIN=1
CONFIG_DRM_XE_TIMESLICE_MAX=10000000
CONFIG_DRM_XE_TIMESLICE_MIN=1
CONFIG_DRM_XE_PREEMPT_TIMEOUT=640000
CONFIG_DRM_XE_PREEMPT_TIMEOUT_MAX=10000000
CONFIG_DRM_XE_PREEMPT_TIMEOUT_MIN=1
CONFIG_DRM_XE_ENABLE_SCHEDTIMEOUT_LIMIT=y
# end of drm/xe Profile Guided Optimisation
CONFIG_DRM_XEN=y
CONFIG_DRM_XEN_FRONTEND=m
CONFIG_DRM_ZYNQMP_DPSUB=m
CONFIG_DRM_ZYNQMP_DPSUB_AUDIO=y
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=m
#
# Frame buffer Devices
#
CONFIG_FB=m
CONFIG_FB_HECUBA=m
CONFIG_FB_SVGALIB=m
CONFIG_FB_CIRRUS=m
CONFIG_FB_PM2=m
CONFIG_FB_PM2_FIFO_DISCONNECT=y
CONFIG_FB_CLPS711X=m
CONFIG_FB_IMX=m
CONFIG_FB_CYBER2000=m
CONFIG_FB_CYBER2000_DDC=y
CONFIG_FB_ARC=m
CONFIG_FB_VGA16=m
CONFIG_FB_UVESA=m
CONFIG_FB_N411=m
CONFIG_FB_HGA=m
CONFIG_FB_PVR2=m
CONFIG_FB_OPENCORES=m
CONFIG_FB_S1D13XXX=m
CONFIG_FB_ATMEL=m
CONFIG_FB_NVIDIA=m
CONFIG_FB_NVIDIA_I2C=y
CONFIG_FB_NVIDIA_DEBUG=y
CONFIG_FB_NVIDIA_BACKLIGHT=y
CONFIG_FB_RIVA=m
CONFIG_FB_RIVA_I2C=y
CONFIG_FB_RIVA_DEBUG=y
CONFIG_FB_RIVA_BACKLIGHT=y
CONFIG_FB_I740=m
CONFIG_FB_I810=m
CONFIG_FB_I810_GTF=y
CONFIG_FB_I810_I2C=y
CONFIG_FB_MATROX=m
CONFIG_FB_MATROX_MILLENIUM=y
CONFIG_FB_MATROX_MYSTIQUE=y
CONFIG_FB_MATROX_G=y
CONFIG_FB_MATROX_I2C=m
CONFIG_FB_MATROX_MAVEN=m
CONFIG_FB_RADEON=m
CONFIG_FB_RADEON_I2C=y
CONFIG_FB_RADEON_BACKLIGHT=y
CONFIG_FB_RADEON_DEBUG=y
CONFIG_FB_ATY128=m
CONFIG_FB_ATY128_BACKLIGHT=y
CONFIG_FB_ATY=m
CONFIG_FB_ATY_CT=y
CONFIG_FB_ATY_GENERIC_LCD=y
CONFIG_FB_ATY_GX=y
CONFIG_FB_ATY_BACKLIGHT=y
CONFIG_FB_S3=m
CONFIG_FB_S3_DDC=y
CONFIG_FB_SAVAGE=m
CONFIG_FB_SAVAGE_I2C=y
CONFIG_FB_SAVAGE_ACCEL=y
CONFIG_FB_SIS=m
CONFIG_FB_SIS_300=y
CONFIG_FB_SIS_315=y
CONFIG_FB_VIA=m
CONFIG_FB_VIA_DIRECT_PROCFS=y
CONFIG_FB_VIA_X_COMPATIBILITY=y
CONFIG_FB_NEOMAGIC=m
CONFIG_FB_KYRO=m
CONFIG_FB_3DFX=m
CONFIG_FB_3DFX_ACCEL=y
CONFIG_FB_3DFX_I2C=y
CONFIG_FB_VOODOO1=m
CONFIG_FB_VT8623=m
CONFIG_FB_TRIDENT=m
CONFIG_FB_ARK=m
CONFIG_FB_PM3=m
CONFIG_FB_CARMINE=m
CONFIG_FB_CARMINE_DRAM_EVAL=y
# CONFIG_CARMINE_DRAM_CUSTOM is not set
CONFIG_FB_GEODE=y
CONFIG_FB_GEODE_LX=m
CONFIG_FB_GEODE_GX=m
CONFIG_FB_GEODE_GX1=m
CONFIG_FB_PXA168=m
CONFIG_FB_SH_MOBILE_LCDC=m
CONFIG_FB_S3C=m
CONFIG_FB_S3C_DEBUG_REGWRITE=y
CONFIG_FB_SM501=m
CONFIG_FB_SMSCUFX=m
CONFIG_FB_UDL=m
CONFIG_FB_IBM_GXT4500=m
CONFIG_FB_GOLDFISH=m
CONFIG_FB_VIRTUAL=m
CONFIG_XEN_FBDEV_FRONTEND=m
CONFIG_FB_METRONOME=m
CONFIG_FB_MB862XX=m
CONFIG_FB_MB862XX_PCI_GDC=y
CONFIG_FB_MB862XX_I2C=y
CONFIG_FB_BROADSHEET=m
CONFIG_FB_SIMPLE=m
CONFIG_FB_SSD1307=m
CONFIG_FB_SM712=m
CONFIG_MMP_DISP=m
CONFIG_MMP_DISP_CONTROLLER=y
CONFIG_MMP_DISP_SPI=y
CONFIG_MMP_PANEL_TPOHVGA=y
CONFIG_MMP_FB=m
CONFIG_FB_CORE=m
CONFIG_FB_NOTIFY=y
CONFIG_FB_DEVICE=y
CONFIG_FB_DDC=m
CONFIG_FB_CFB_FILLRECT=m
CONFIG_FB_CFB_COPYAREA=m
CONFIG_FB_CFB_IMAGEBLIT=m
CONFIG_FB_CFB_REV_PIXELS_IN_BYTE=y
CONFIG_FB_SYS_FILLRECT=m
CONFIG_FB_SYS_COPYAREA=m
CONFIG_FB_SYS_IMAGEBLIT=m
CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA=y
CONFIG_FB_FOREIGN_ENDIAN=y
CONFIG_FB_BOTH_ENDIAN=y
# CONFIG_FB_BIG_ENDIAN is not set
# CONFIG_FB_LITTLE_ENDIAN is not set
CONFIG_FB_SYSMEM_FOPS=m
CONFIG_FB_DEFERRED_IO=y
CONFIG_FB_DMAMEM_HELPERS=y
CONFIG_FB_DMAMEM_HELPERS_DEFERRED=y
CONFIG_FB_IOMEM_FOPS=m
CONFIG_FB_IOMEM_HELPERS=y
CONFIG_FB_SYSMEM_HELPERS=y
CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y
CONFIG_FB_BACKLIGHT=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
# end of Frame buffer Devices
#
# Backlight & LCD device support
#
CONFIG_LCD_CLASS_DEVICE=m
CONFIG_LCD_L4F00242T03=m
CONFIG_LCD_LMS283GF05=m
CONFIG_LCD_LTV350QV=m
CONFIG_LCD_ILI922X=m
CONFIG_LCD_ILI9320=m
CONFIG_LCD_TDO24M=m
CONFIG_LCD_VGG2432A4=m
CONFIG_LCD_PLATFORM=m
CONFIG_LCD_AMS369FG06=m
CONFIG_LCD_LMS501KF03=m
CONFIG_LCD_HX8357=m
CONFIG_LCD_OTM3225A=m
CONFIG_BACKLIGHT_CLASS_DEVICE=m
CONFIG_BACKLIGHT_ATMEL_LCDC=y
CONFIG_BACKLIGHT_AW99706=m
CONFIG_BACKLIGHT_KTD253=m
CONFIG_BACKLIGHT_KTD2801=m
CONFIG_BACKLIGHT_KTZ8866=m
CONFIG_BACKLIGHT_LM3533=m
CONFIG_BACKLIGHT_OMAP1=m
CONFIG_BACKLIGHT_PWM=m
CONFIG_BACKLIGHT_CGBC=m
CONFIG_BACKLIGHT_DA903X=m
CONFIG_BACKLIGHT_DA9052=m
CONFIG_BACKLIGHT_MAX8925=m
CONFIG_BACKLIGHT_MT6370=m
CONFIG_BACKLIGHT_APPLE=m
CONFIG_BACKLIGHT_APPLE_DWI=m
CONFIG_BACKLIGHT_QCOM_WLED=m
CONFIG_BACKLIGHT_RT4831=m
CONFIG_BACKLIGHT_SAHARA=m
CONFIG_BACKLIGHT_WM831X=m
CONFIG_BACKLIGHT_ADP5520=m
CONFIG_BACKLIGHT_ADP8860=m
CONFIG_BACKLIGHT_ADP8870=m
CONFIG_BACKLIGHT_88PM860X=m
CONFIG_BACKLIGHT_AAT2870=m
CONFIG_BACKLIGHT_LM3509=m
CONFIG_BACKLIGHT_LM3630A=m
CONFIG_BACKLIGHT_LM3639=m
CONFIG_BACKLIGHT_LP855X=m
CONFIG_BACKLIGHT_LP8788=m
CONFIG_BACKLIGHT_MP3309C=m
CONFIG_BACKLIGHT_PANDORA=m
CONFIG_BACKLIGHT_SKY81452=m
CONFIG_BACKLIGHT_TPS65217=m
CONFIG_BACKLIGHT_AS3711=m
CONFIG_BACKLIGHT_GPIO=m
CONFIG_BACKLIGHT_LV5207LP=m
CONFIG_BACKLIGHT_BD6107=m
CONFIG_BACKLIGHT_ARCXCNN=m
CONFIG_BACKLIGHT_RAVE_SP=m
CONFIG_BACKLIGHT_LED=m
# end of Backlight & LCD device support
CONFIG_VGASTATE=m
CONFIG_VIDEOMODE_HELPERS=y
CONFIG_HDMI=y
CONFIG_FIRMWARE_EDID=y
#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_MDA_CONSOLE=m
CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=80
CONFIG_DUMMY_CONSOLE_ROWS=25
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# end of Console display driver support
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_MONO_FILE="drivers/video/logo/logo_linux_mono.pbm"
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_VGA16_FILE="drivers/video/logo/logo_linux_vga16.ppm"
CONFIG_LOGO_LINUX_CLUT224=y
CONFIG_LOGO_LINUX_CLUT224_FILE="drivers/video/logo/logo_linux_clut224.ppm"
CONFIG_TRACE_GPU_MEM=y
# end of Graphics support
CONFIG_DRM_ACCEL=y
CONFIG_DRM_ACCEL_ARM_ETHOSU=m
CONFIG_DRM_ACCEL_QAIC=m
CONFIG_DRM_ACCEL_ROCKET=m
CONFIG_SOUND=m
CONFIG_SOUND_OSS_CORE=y
CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
CONFIG_SND_PCM_ELD=y
CONFIG_SND_PCM_IEC958=y
CONFIG_SND_DMAENGINE_PCM=m
CONFIG_SND_HWDEP=m
CONFIG_SND_SEQ_DEVICE=m
CONFIG_SND_RAWMIDI=m
CONFIG_SND_UMP=m
CONFIG_SND_UMP_LEGACY_RAWMIDI=y
CONFIG_SND_CORE_TEST=m
CONFIG_SND_COMPRESS_OFFLOAD=m
CONFIG_SND_COMPRESS_ACCEL=y
CONFIG_SND_JACK=y
CONFIG_SND_JACK_INPUT_DEV=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_PCM_TIMER=y
CONFIG_SND_HRTIMER=m
CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_MAX_CARDS=32
CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_PROC_FS=y
CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_SND_CTL_FAST_LOOKUP=y
CONFIG_SND_DEBUG=y
CONFIG_SND_DEBUG_VERBOSE=y
CONFIG_SND_PCM_XRUN_DEBUG=y
CONFIG_SND_CTL_INPUT_VALIDATION=y
CONFIG_SND_CTL_DEBUG=y
CONFIG_SND_JACK_INJECTION_DEBUG=y
CONFIG_SND_UTIMER=y
CONFIG_SND_VMASTER=y
CONFIG_SND_DMA_SGBUF=y
CONFIG_SND_CTL_LED=m
CONFIG_SND_SEQUENCER=m
CONFIG_SND_SEQ_DUMMY=m
CONFIG_SND_SEQUENCER_OSS=m
CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
CONFIG_SND_SEQ_MIDI_EVENT=m
CONFIG_SND_SEQ_MIDI=m
CONFIG_SND_SEQ_MIDI_EMUL=m
CONFIG_SND_SEQ_VIRMIDI=m
CONFIG_SND_SEQ_UMP=y
CONFIG_SND_SEQ_UMP_CLIENT=m
CONFIG_SND_MPU401_UART=m
CONFIG_SND_OPL3_LIB=m
CONFIG_SND_OPL4_LIB=m
CONFIG_SND_OPL3_LIB_SEQ=m
CONFIG_SND_OPL4_LIB_SEQ=m
CONFIG_SND_VX_LIB=m
CONFIG_SND_AC97_CODEC=m
CONFIG_SND_DRIVERS=y
CONFIG_SND_PCSP=m
CONFIG_SND_DUMMY=m
CONFIG_SND_ALOOP=m
CONFIG_SND_PCMTEST=m
CONFIG_SND_VIRMIDI=m
CONFIG_SND_MTPAV=m
CONFIG_SND_MTS64=m
CONFIG_SND_SERIAL_U16550=m
CONFIG_SND_SERIAL_GENERIC=m
CONFIG_SND_MPU401=m
CONFIG_SND_PORTMAN2X4=m
CONFIG_SND_AC97_POWER_SAVE=y
CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0
CONFIG_SND_WSS_LIB=m
CONFIG_SND_SB_COMMON=m
CONFIG_SND_SB8_DSP=m
CONFIG_SND_SB16_DSP=m
CONFIG_SND_ISA=y
CONFIG_SND_ADLIB=m
CONFIG_SND_AD1816A=m
CONFIG_SND_AD1848=m
CONFIG_SND_ALS100=m
CONFIG_SND_AZT1605=m
CONFIG_SND_AZT2316=m
CONFIG_SND_AZT2320=m
CONFIG_SND_CMI8328=m
CONFIG_SND_CMI8330=m
CONFIG_SND_CS4231=m
CONFIG_SND_CS4236=m
CONFIG_SND_ES1688=m
CONFIG_SND_ES18XX=m
CONFIG_SND_SC6000=m
CONFIG_SND_GUSCLASSIC=m
CONFIG_SND_GUSEXTREME=m
CONFIG_SND_GUSMAX=m
CONFIG_SND_INTERWAVE=m
CONFIG_SND_INTERWAVE_STB=m
CONFIG_SND_JAZZ16=m
CONFIG_SND_OPL3SA2=m
CONFIG_SND_OPTI92X_AD1848=m
CONFIG_SND_OPTI92X_CS4231=m
CONFIG_SND_OPTI93X=m
CONFIG_SND_MIRO=m
CONFIG_SND_SB8=m
CONFIG_SND_SB16=m
CONFIG_SND_SBAWE=m
CONFIG_SND_SBAWE_SEQ=m
CONFIG_SND_SB16_CSP=y
CONFIG_SND_SSCAPE=m
CONFIG_SND_WAVEFRONT=m
CONFIG_SND_MSND_PINNACLE=m
CONFIG_SND_MSND_CLASSIC=m
CONFIG_SND_PCI=y
CONFIG_SND_AD1889=m
CONFIG_SND_ALS300=m
CONFIG_SND_ALS4000=m
CONFIG_SND_ALI5451=m
CONFIG_SND_ASIHPI=m
CONFIG_SND_ATIIXP=m
CONFIG_SND_ATIIXP_MODEM=m
CONFIG_SND_AU8810=m
CONFIG_SND_AU8820=m
CONFIG_SND_AU8830=m
CONFIG_SND_AW2=m
CONFIG_SND_AZT3328=m
CONFIG_SND_BT87X=m
CONFIG_SND_BT87X_OVERCLOCK=y
CONFIG_SND_CA0106=m
CONFIG_SND_CMIPCI=m
CONFIG_SND_OXYGEN_LIB=m
CONFIG_SND_OXYGEN=m
CONFIG_SND_CS4281=m
CONFIG_SND_CS46XX=m
CONFIG_SND_CS46XX_NEW_DSP=y
CONFIG_SND_CS5530=m
CONFIG_SND_CS5535AUDIO=m
CONFIG_SND_CTXFI=m
CONFIG_SND_DARLA20=m
CONFIG_SND_GINA20=m
CONFIG_SND_LAYLA20=m
CONFIG_SND_DARLA24=m
CONFIG_SND_GINA24=m
CONFIG_SND_LAYLA24=m
CONFIG_SND_MONA=m
CONFIG_SND_MIA=m
CONFIG_SND_ECHO3G=m
CONFIG_SND_INDIGO=m
CONFIG_SND_INDIGOIO=m
CONFIG_SND_INDIGODJ=m
CONFIG_SND_INDIGOIOX=m
CONFIG_SND_INDIGODJX=m
CONFIG_SND_EMU10K1=m
CONFIG_SND_EMU10K1_SEQ=m
CONFIG_SND_EMU10K1X=m
CONFIG_SND_ENS1370=m
CONFIG_SND_ENS1371=m
CONFIG_SND_ES1938=m
CONFIG_SND_ES1968=m
CONFIG_SND_ES1968_INPUT=y
CONFIG_SND_ES1968_RADIO=y
CONFIG_SND_FM801=m
CONFIG_SND_FM801_TEA575X_BOOL=y
CONFIG_SND_HDSP=m
CONFIG_SND_HDSPM=m
CONFIG_SND_ICE1712=m
CONFIG_SND_ICE1724=m
CONFIG_SND_INTEL8X0=m
CONFIG_SND_INTEL8X0M=m
CONFIG_SND_KORG1212=m
CONFIG_SND_LOLA=m
CONFIG_SND_LX6464ES=m
CONFIG_SND_MAESTRO3=m
CONFIG_SND_MAESTRO3_INPUT=y
CONFIG_SND_MIXART=m
CONFIG_SND_NM256=m
CONFIG_SND_PCXHR=m
CONFIG_SND_RIPTIDE=m
CONFIG_SND_RME32=m
CONFIG_SND_RME96=m
CONFIG_SND_RME9652=m
CONFIG_SND_SIS7019=m
CONFIG_SND_SONICVIBES=m
CONFIG_SND_TRIDENT=m
CONFIG_SND_VIA82XX=m
CONFIG_SND_VIA82XX_MODEM=m
CONFIG_SND_VIRTUOSO=m
CONFIG_SND_VX222=m
CONFIG_SND_YMFPCI=m
#
# HD-Audio
#
CONFIG_SND_HDA=m
CONFIG_SND_HDA_HWDEP=y
CONFIG_SND_HDA_RECONFIG=y
CONFIG_SND_HDA_INPUT_BEEP=y
CONFIG_SND_HDA_INPUT_BEEP_MODE=1
CONFIG_SND_HDA_PATCH_LOADER=y
CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
CONFIG_SND_HDA_CTL_DEV_ID=y
CONFIG_SND_HDA_PREALLOC_SIZE=0
CONFIG_SND_HDA_INTEL=m
CONFIG_SND_HDA_CIX_IPBLOQ=m
CONFIG_SND_HDA_ACPI=m
CONFIG_SND_HDA_GENERIC_LEDS=y
CONFIG_SND_HDA_CODEC_ANALOG=m
CONFIG_SND_HDA_CODEC_SIGMATEL=m
CONFIG_SND_HDA_CODEC_VIA=m
CONFIG_SND_HDA_CODEC_CONEXANT=m
CONFIG_SND_HDA_CODEC_SENARYTECH=m
CONFIG_SND_HDA_CODEC_CA0110=m
CONFIG_SND_HDA_CODEC_CA0132=m
CONFIG_SND_HDA_CODEC_CA0132_DSP=y
CONFIG_SND_HDA_CODEC_CMEDIA=m
CONFIG_SND_HDA_CODEC_CM9825=m
CONFIG_SND_HDA_CODEC_SI3054=m
CONFIG_SND_HDA_GENERIC=m
CONFIG_SND_HDA_CODEC_REALTEK=m
CONFIG_SND_HDA_CODEC_REALTEK_LIB=m
CONFIG_SND_HDA_CODEC_ALC260=m
CONFIG_SND_HDA_CODEC_ALC262=m
CONFIG_SND_HDA_CODEC_ALC268=m
CONFIG_SND_HDA_CODEC_ALC269=m
CONFIG_SND_HDA_CODEC_ALC662=m
CONFIG_SND_HDA_CODEC_ALC680=m
CONFIG_SND_HDA_CODEC_ALC861=m
CONFIG_SND_HDA_CODEC_ALC861VD=m
CONFIG_SND_HDA_CODEC_ALC880=m
CONFIG_SND_HDA_CODEC_ALC882=m
CONFIG_SND_HDA_CODEC_CIRRUS=m
CONFIG_SND_HDA_CODEC_CS420X=m
CONFIG_SND_HDA_CODEC_CS421X=m
CONFIG_SND_HDA_CODEC_CS8409=m
CONFIG_SND_HDA_CODEC_HDMI=m
CONFIG_SND_HDA_CODEC_HDMI_GENERIC=m
CONFIG_SND_HDA_CODEC_HDMI_SIMPLE=m
CONFIG_SND_HDA_CODEC_HDMI_INTEL=m
CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM=y
CONFIG_SND_HDA_CODEC_HDMI_ATI=m
CONFIG_SND_HDA_CODEC_HDMI_NVIDIA=m
CONFIG_SND_HDA_CODEC_HDMI_NVIDIA_MCP=m
CONFIG_SND_HDA_CODEC_HDMI_TEGRA=m
CONFIG_SND_HDA_CIRRUS_SCODEC=m
CONFIG_SND_HDA_CIRRUS_SCODEC_KUNIT_TEST=m
CONFIG_SND_HDA_SCODEC_CS35L41=m
CONFIG_SND_HDA_SCODEC_COMPONENT=m
CONFIG_SND_HDA_SCODEC_CS35L41_I2C=m
CONFIG_SND_HDA_SCODEC_CS35L41_SPI=m
CONFIG_SND_HDA_SCODEC_CS35L56=m
CONFIG_SND_HDA_SCODEC_CS35L56_I2C=m
CONFIG_SND_HDA_SCODEC_CS35L56_SPI=m
#
# CS35L56 driver options
#
CONFIG_SND_HDA_SCODEC_CS35L56_CAL_DEBUGFS=y
# end of CS35L56 driver options
CONFIG_SND_HDA_SCODEC_TAS2781=m
CONFIG_SND_HDA_SCODEC_TAS2781_I2C=m
CONFIG_SND_HDA_SCODEC_TAS2781_SPI=m
CONFIG_SND_HDA_CORE=m
CONFIG_SND_HDA_DSP_LOADER=y
CONFIG_SND_HDA_ALIGNED_MMIO=y
CONFIG_SND_HDA_COMPONENT=y
CONFIG_SND_HDA_I915=y
CONFIG_SND_HDA_EXT_CORE=m
CONFIG_SND_INTEL_NHLT=y
CONFIG_SND_INTEL_DSP_CONFIG=m
CONFIG_SND_INTEL_SOUNDWIRE_ACPI=m
CONFIG_SND_INTEL_BYT_PREFER_SOF=y
# end of HD-Audio
CONFIG_SND_PXA2XX_LIB=m
CONFIG_SND_SPI=y
CONFIG_SND_AT73C213=m
CONFIG_SND_AT73C213_TARGET_BITRATE=48000
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=m
CONFIG_SND_USB_AUDIO_MIDI_V2=y
CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y
CONFIG_SND_USB_UA101=m
CONFIG_SND_USB_USX2Y=m
CONFIG_SND_USB_CAIAQ=m
CONFIG_SND_USB_CAIAQ_INPUT=y
CONFIG_SND_USB_US122L=m
CONFIG_SND_USB_US144MKII=m
CONFIG_SND_USB_6FIRE=m
CONFIG_SND_USB_HIFACE=m
CONFIG_SND_BCD2000=m
CONFIG_SND_USB_AUDIO_QMI=m
CONFIG_SND_USB_LINE6=m
CONFIG_SND_USB_POD=m
CONFIG_SND_USB_PODHD=m
CONFIG_SND_USB_TONEPORT=m
CONFIG_SND_USB_VARIAX=m
CONFIG_SND_FIREWIRE=y
CONFIG_SND_FIREWIRE_LIB=m
CONFIG_SND_DICE=m
CONFIG_SND_OXFW=m
CONFIG_SND_ISIGHT=m
CONFIG_SND_FIREWORKS=m
CONFIG_SND_BEBOB=m
CONFIG_SND_FIREWIRE_DIGI00X=m
CONFIG_SND_FIREWIRE_TASCAM=m
CONFIG_SND_FIREWIRE_MOTU=m
CONFIG_SND_FIREFACE=m
CONFIG_SND_PCMCIA=y
CONFIG_SND_VXPOCKET=m
CONFIG_SND_PDAUDIOCF=m
CONFIG_SND_SOC=m
CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
CONFIG_SND_SOC_COMPRESS=y
CONFIG_SND_SOC_TOPOLOGY=y
CONFIG_SND_SOC_TOPOLOGY_BUILD=y
CONFIG_SND_SOC_TOPOLOGY_KUNIT_TEST=m
CONFIG_SND_SOC_CARD_KUNIT_TEST=m
CONFIG_SND_SOC_UTILS_KUNIT_TEST=m
CONFIG_SND_SOC_OPS_KUNIT_TEST=m
CONFIG_SND_SOC_ACPI=m
CONFIG_SND_SOC_USB=m
#
# Analog Devices
#
CONFIG_SND_SOC_ADI_AXI_I2S=m
CONFIG_SND_SOC_ADI_AXI_SPDIF=m
# end of Analog Devices
#
# AMD
#
CONFIG_SND_SOC_AMD_ACP=m
CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH=m
CONFIG_SND_SOC_AMD_CZ_RT5645_MACH=m
CONFIG_SND_SOC_AMD_ST_ES8336_MACH=m
CONFIG_SND_SOC_AMD_ACP3x=m
CONFIG_SND_SOC_AMD_RV_RT5682_MACH=m
CONFIG_SND_SOC_AMD_RENOIR=m
CONFIG_SND_SOC_AMD_RENOIR_MACH=m
CONFIG_SND_SOC_AMD_ACP5x=m
CONFIG_SND_SOC_AMD_VANGOGH_MACH=m
CONFIG_SND_SOC_AMD_ACP6x=m
CONFIG_SND_SOC_AMD_YC_MACH=m
CONFIG_SND_AMD_ACP_CONFIG=m
CONFIG_SND_SOC_AMD_ACP_COMMON=m
CONFIG_SND_SOC_ACPI_AMD_MATCH=m
CONFIG_SND_SOC_ACPI_AMD_SDCA_QUIRKS=m
CONFIG_SND_SOC_AMD_ACP_PDM=m
CONFIG_SND_SOC_AMD_ACP_LEGACY_COMMON=m
CONFIG_SND_SOC_AMD_ACP_I2S=m
CONFIG_SND_SOC_AMD_ACPI_MACH=m
CONFIG_SND_SOC_AMD_ACP_PCM=m
CONFIG_SND_SOC_AMD_ACP_PCI=m
CONFIG_SND_AMD_ASOC_RENOIR=m
CONFIG_SND_AMD_ASOC_REMBRANDT=m
CONFIG_SND_AMD_ASOC_ACP63=m
CONFIG_SND_AMD_ASOC_ACP70=m
CONFIG_SND_SOC_AMD_MACH_COMMON=m
CONFIG_SND_SOC_AMD_LEGACY_MACH=m
CONFIG_SND_SOC_AMD_SOF_MACH=m
CONFIG_SND_SOC_AMD_SDW_MACH_COMMON=m
CONFIG_SND_SOC_AMD_SOF_SDW_MACH=m
CONFIG_SND_SOC_AMD_LEGACY_SDW_MACH=m
CONFIG_SND_AMD_SOUNDWIRE_ACPI=m
# CONFIG_SND_SOC_AMD_RPL_ACP6x is not set
CONFIG_SND_SOC_AMD_ACP63_TOPLEVEL=m
CONFIG_SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE=m
CONFIG_SND_SOC_AMD_SOUNDWIRE=m
CONFIG_SND_SOC_AMD_PS=m
CONFIG_SND_SOC_AMD_PS_MACH=m
# end of AMD
#
# Apple
#
CONFIG_SND_SOC_APPLE_MCA=m
# end of Apple
#
# Atmel
#
CONFIG_SND_ATMEL_SOC_PDC=y
CONFIG_SND_ATMEL_SOC_DMA=y
CONFIG_SND_ATMEL_SOC_SSC=m
CONFIG_SND_ATMEL_SOC_SSC_PDC=m
CONFIG_SND_ATMEL_SOC_SSC_DMA=m
CONFIG_SND_AT91_SOC_SAM9G20_WM8731=m
CONFIG_SND_ATMEL_SOC_WM8904=m
CONFIG_SND_AT91_SOC_SAM9X5_WM8731=m
CONFIG_SND_ATMEL_SOC_CLASSD=m
CONFIG_SND_ATMEL_SOC_PDMIC=m
CONFIG_SND_ATMEL_SOC_I2S=m
CONFIG_SND_SOC_MIKROE_PROTO=m
CONFIG_SND_MCHP_SOC_I2S_MCC=m
CONFIG_SND_MCHP_SOC_SPDIFTX=m
CONFIG_SND_MCHP_SOC_SPDIFRX=m
CONFIG_SND_MCHP_SOC_PDMC=m
# end of Atmel
#
# Au1x
#
# end of Au1x
#
# Broadcom
#
CONFIG_SND_BCM2835_SOC_I2S=m
CONFIG_SND_SOC_CYGNUS=m
CONFIG_SND_BCM63XX_I2S_WHISTLER=m
# end of Broadcom
#
# Cirrus Logic
#
CONFIG_SND_EP93XX_SOC=m
CONFIG_SND_EP93XX_SOC_I2S=m
CONFIG_SND_EP93XX_SOC_I2S_WATCHDOG=y
# end of Cirrus Logic
#
# DesignWare
#
CONFIG_SND_DESIGNWARE_I2S=m
CONFIG_SND_DESIGNWARE_PCM=y
# end of DesignWare
#
# Freescale
#
#
# Common SoC Audio options for Freescale CPUs:
#
CONFIG_SND_SOC_FSL_ASRC=m
CONFIG_SND_SOC_FSL_SAI=m
CONFIG_SND_SOC_FSL_MQS=m
CONFIG_SND_SOC_FSL_AUDMIX=m
CONFIG_SND_SOC_FSL_SSI=m
CONFIG_SND_SOC_FSL_SPDIF=m
CONFIG_SND_SOC_FSL_ESAI=m
CONFIG_SND_SOC_FSL_MICFIL=m
CONFIG_SND_SOC_FSL_EASRC=m
CONFIG_SND_SOC_FSL_XCVR=m
CONFIG_SND_SOC_FSL_AUD2HTX=m
CONFIG_SND_SOC_FSL_UTILS=m
CONFIG_SND_SOC_FSL_RPMSG=m
CONFIG_SND_SOC_FSL_LPC3XXX=m
CONFIG_SND_SOC_IMX_PCM_DMA=m
CONFIG_SND_SOC_IMX_AUDIO_RPMSG=m
CONFIG_SND_SOC_IMX_PCM_RPMSG=m
CONFIG_SND_SOC_IMX_AUDMUX=m
CONFIG_SND_IMX_SOC=m
#
# SoC Audio support for Freescale i.MX boards:
#
CONFIG_SND_SOC_IMX_ES8328=m
CONFIG_SND_SOC_IMX_SGTL5000=m
CONFIG_SND_SOC_FSL_ASOC_CARD=m
CONFIG_SND_SOC_IMX_AUDMIX=m
CONFIG_SND_SOC_IMX_HDMI=m
CONFIG_SND_SOC_IMX_RPMSG=m
CONFIG_SND_SOC_IMX_CARD=m
# end of Freescale
#
# Google
#
CONFIG_SND_SOC_CHV3_I2S=m
# end of Google
#
# Hisilicon
#
CONFIG_SND_I2S_HI6210_I2S=m
# end of Hisilicon
#
# JZ4740
#
CONFIG_SND_JZ4740_SOC_I2S=m
# end of JZ4740
#
# Kirkwood
#
CONFIG_SND_KIRKWOOD_SOC=m
CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB=m
# end of Kirkwood
#
# Loongson
#
CONFIG_SND_SOC_LOONGSON_CARD=m
CONFIG_SND_SOC_LOONGSON_I2S_PCI=m
CONFIG_SND_SOC_LOONGSON_I2S_PLATFORM=m
# end of Loongson
CONFIG_SND_LOONGSON1_AC97=m
#
# Imagination Technologies
#
CONFIG_SND_SOC_IMG_I2S_IN=m
CONFIG_SND_SOC_IMG_I2S_OUT=m
CONFIG_SND_SOC_IMG_PARALLEL_OUT=m
CONFIG_SND_SOC_IMG_SPDIF_IN=m
CONFIG_SND_SOC_IMG_SPDIF_OUT=m
CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC=m
# end of Imagination Technologies
#
# Intel
#
CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
CONFIG_SND_SOC_INTEL_CATPT=m
CONFIG_SND_SST_ATOM_HIFI2_PLATFORM=m
CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI=m
CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI=m
CONFIG_SND_SOC_ACPI_INTEL_MATCH=m
CONFIG_SND_SOC_ACPI_INTEL_SDCA_QUIRKS=m
CONFIG_SND_SOC_INTEL_KEEMBAY=m
CONFIG_SND_SOC_INTEL_AVS=m
#
# Intel AVS Machine drivers
#
#
# Available DSP configurations
#
CONFIG_SND_SOC_INTEL_AVS_CARDNAME_OBSOLETE=y
CONFIG_SND_SOC_INTEL_AVS_MACH_DA7219=m
CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC=m
CONFIG_SND_SOC_INTEL_AVS_MACH_ES8336=m
CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO=m
CONFIG_SND_SOC_INTEL_AVS_MACH_I2S_TEST=m
CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98927=m
CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A=m
CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373=m
CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825=m
CONFIG_SND_SOC_INTEL_AVS_MACH_PCM3168A=m
CONFIG_SND_SOC_INTEL_AVS_MACH_PROBE=m
CONFIG_SND_SOC_INTEL_AVS_MACH_RT274=m
CONFIG_SND_SOC_INTEL_AVS_MACH_RT286=m
CONFIG_SND_SOC_INTEL_AVS_MACH_RT298=m
CONFIG_SND_SOC_INTEL_AVS_MACH_RT5514=m
CONFIG_SND_SOC_INTEL_AVS_MACH_RT5640=m
CONFIG_SND_SOC_INTEL_AVS_MACH_RT5663=m
CONFIG_SND_SOC_INTEL_AVS_MACH_RT5682=m
CONFIG_SND_SOC_INTEL_AVS_MACH_SSM4567=m
# end of Intel AVS Machine drivers
CONFIG_SND_SOC_INTEL_MACH=y
CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES=y
CONFIG_SND_SOC_INTEL_HDA_DSP_COMMON=m
CONFIG_SND_SOC_INTEL_SOF_MAXIM_COMMON=m
CONFIG_SND_SOC_INTEL_SOF_REALTEK_COMMON=m
CONFIG_SND_SOC_INTEL_SOF_CIRRUS_COMMON=m
CONFIG_SND_SOC_INTEL_SOF_NUVOTON_COMMON=m
CONFIG_SND_SOC_INTEL_SOF_TI_COMMON=m
CONFIG_SND_SOC_INTEL_SOF_BOARD_HELPERS=m
CONFIG_SND_SOC_INTEL_HASWELL_MACH=m
CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH=m
CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH=m
CONFIG_SND_SOC_INTEL_BROADWELL_MACH=m
CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH=m
CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH=m
CONFIG_SND_SOC_INTEL_BYTCR_WM5102_MACH=m
CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH=m
CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH=m
CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH=m
CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH=m
CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH=m
CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH=m
CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH=m
CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=m
CONFIG_SND_SOC_INTEL_SOF_WM8804_MACH=m
CONFIG_SND_SOC_INTEL_GLK_DA7219_MAX98357A_MACH=m
CONFIG_SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH=m
CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH=m
CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH=m
CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH=m
CONFIG_SND_SOC_INTEL_SOF_PCM512x_MACH=m
CONFIG_SND_SOC_INTEL_SOF_ES8336_MACH=m
CONFIG_SND_SOC_INTEL_SOF_NAU8825_MACH=m
CONFIG_SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH=m
CONFIG_SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH=m
CONFIG_SND_SOC_INTEL_SOF_DA7219_MACH=m
CONFIG_SND_SOC_INTEL_SOF_SSP_AMP_MACH=m
CONFIG_SND_SOC_INTEL_EHL_RT5660_MACH=m
CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH=m
# end of Intel
#
# Mediatek
#
CONFIG_SND_SOC_MEDIATEK=m
CONFIG_SND_SOC_MT8186=m
CONFIG_SND_SOC_MT8186_MT6366=m
CONFIG_SND_SOC_MTK_BTCVSD=m
CONFIG_SND_SOC_MT8188=m
CONFIG_SND_SOC_MT8188_MT6359=m
CONFIG_SND_SOC_MT8195=m
CONFIG_SND_SOC_MT8195_MT6359=m
CONFIG_SND_SOC_MT8365=m
CONFIG_SND_SOC_MT8365_MT6357=m
# end of Mediatek
#
# Amlogic
#
CONFIG_SND_MESON_AIU=m
CONFIG_SND_MESON_AXG_FIFO=m
CONFIG_SND_MESON_AXG_FRDDR=m
CONFIG_SND_MESON_AXG_TODDR=m
CONFIG_SND_MESON_AXG_TDM_FORMATTER=m
CONFIG_SND_MESON_AXG_TDM_INTERFACE=m
CONFIG_SND_MESON_AXG_TDMIN=m
CONFIG_SND_MESON_AXG_TDMOUT=m
CONFIG_SND_MESON_AXG_SOUND_CARD=m
CONFIG_SND_MESON_AXG_SPDIFOUT=m
CONFIG_SND_MESON_AXG_SPDIFIN=m
CONFIG_SND_MESON_AXG_PDM=m
CONFIG_SND_MESON_CARD_UTILS=m
CONFIG_SND_MESON_CODEC_GLUE=m
CONFIG_SND_MESON_GX_SOUND_CARD=m
CONFIG_SND_MESON_G12A_TOACODEC=m
CONFIG_SND_MESON_G12A_TOHDMITX=m
CONFIG_SND_SOC_MESON_T9015=m
# end of Amlogic
CONFIG_SND_MXS_SOC=m
CONFIG_SND_SOC_MXS_SGTL5000=m
#
# PXA
#
CONFIG_SND_PXA2XX_SOC=m
# end of PXA
CONFIG_SND_SOC_QCOM=m
CONFIG_SND_SOC_LPASS_CPU=m
CONFIG_SND_SOC_LPASS_HDMI=m
CONFIG_SND_SOC_LPASS_PLATFORM=m
CONFIG_SND_SOC_LPASS_CDC_DMA=m
CONFIG_SND_SOC_LPASS_IPQ806X=m
CONFIG_SND_SOC_LPASS_APQ8016=m
CONFIG_SND_SOC_LPASS_SC7180=m
CONFIG_SND_SOC_LPASS_SC7280=m
CONFIG_SND_SOC_STORM=m
CONFIG_SND_SOC_APQ8016_SBC=m
CONFIG_SND_SOC_QCOM_COMMON=m
CONFIG_SND_SOC_QCOM_SDW=m
CONFIG_SND_SOC_QDSP6_COMMON=m
CONFIG_SND_SOC_QDSP6_CORE=m
CONFIG_SND_SOC_QDSP6_AFE=m
CONFIG_SND_SOC_QDSP6_AFE_DAI=m
CONFIG_SND_SOC_QDSP6_AFE_CLOCKS=m
CONFIG_SND_SOC_QDSP6_ADM=m
CONFIG_SND_SOC_QDSP6_ROUTING=m
CONFIG_SND_SOC_QDSP6_ASM=m
CONFIG_SND_SOC_QDSP6_ASM_DAI=m
CONFIG_SND_SOC_QDSP6_APM_DAI=m
CONFIG_SND_SOC_QDSP6_APM_LPASS_DAI=m
CONFIG_SND_SOC_QDSP6_APM=m
CONFIG_SND_SOC_QDSP6_PRM_LPASS_CLOCKS=m
CONFIG_SND_SOC_QDSP6_PRM=m
CONFIG_SND_SOC_QCOM_OFFLOAD_UTILS=m
CONFIG_SND_SOC_QDSP6_USB=m
CONFIG_SND_SOC_QDSP6=m
CONFIG_SND_SOC_MSM8996=m
CONFIG_SND_SOC_SDM845=m
CONFIG_SND_SOC_SM8250=m
CONFIG_SND_SOC_SC8280XP=m
CONFIG_SND_SOC_SC7180=m
CONFIG_SND_SOC_SC7280=m
CONFIG_SND_SOC_X1E80100=m
#
# Renesas
#
CONFIG_SND_SOC_SH4_FSI=m
CONFIG_SND_SOC_RCAR=m
CONFIG_SND_SOC_MSIOF=m
CONFIG_SND_SOC_RZ=m
# end of Renesas
#
# Rockchip
#
CONFIG_SND_SOC_ROCKCHIP_I2S=m
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=m
CONFIG_SND_SOC_ROCKCHIP_PDM=m
CONFIG_SND_SOC_ROCKCHIP_SAI=m
CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
CONFIG_SND_SOC_ROCKCHIP_MAX98090=m
CONFIG_SND_SOC_ROCKCHIP_RT5645=m
CONFIG_SND_SOC_RK3288_HDMI_ANALOG=m
CONFIG_SND_SOC_RK3399_GRU_SOUND=m
# end of Rockchip
CONFIG_SND_SOC_SAMSUNG=m
CONFIG_SND_SAMSUNG_PCM=m
CONFIG_SND_SAMSUNG_SPDIF=m
CONFIG_SND_SAMSUNG_I2S=m
CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994=m
CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF=m
CONFIG_SND_SOC_SMDK_WM8994_PCM=m
CONFIG_SND_SOC_SPEYSIDE=m
CONFIG_SND_SOC_TOBERMORY=m
CONFIG_SND_SOC_BELLS=m
CONFIG_SND_SOC_LOWLAND=m
CONFIG_SND_SOC_LITTLEMILL=m
CONFIG_SND_SOC_SNOW=m
CONFIG_SND_SOC_ODROID=m
CONFIG_SND_SOC_ARNDALE=m
CONFIG_SND_SOC_SAMSUNG_TM2_WM5110=m
CONFIG_SND_SOC_SAMSUNG_ARIES_WM8994=m
CONFIG_SND_SOC_SAMSUNG_MIDAS_WM1811=m
#
# SoundWire (SDCA)
#
CONFIG_SND_SOC_SDCA=m
CONFIG_SND_SOC_SDCA_HID=y
CONFIG_SND_SOC_SDCA_IRQ=y
CONFIG_SND_SOC_SDCA_FDL=y
CONFIG_SND_SOC_SDCA_OPTIONAL=m
CONFIG_SND_SOC_SDCA_CLASS=m
CONFIG_SND_SOC_SDCA_CLASS_FUNCTION=m
# end of SoundWire (SDCA)
#
# Sophgo
#
CONFIG_SND_SOC_CV1800B_TDM=m
CONFIG_SND_SOC_CV1800B_ADC_CODEC=m
CONFIG_SND_SOC_CV1800B_DAC_CODEC=m
# end of Sophgo
#
# SpacemiT
#
CONFIG_SND_SOC_K1_I2S=m
# end of SpacemiT
#
# ST SPEAr
#
# end of ST SPEAr
#
# Spreadtrum
#
CONFIG_SND_SOC_SPRD=m
CONFIG_SND_SOC_SPRD_MCDT=m
# end of Spreadtrum
#
# StarFive
#
CONFIG_SND_SOC_JH7110_PWMDAC=m
CONFIG_SND_SOC_JH7110_TDM=m
# end of StarFive
CONFIG_SND_SOC_STI=m
#
# STMicroelectronics STM32
#
CONFIG_SND_SOC_STM32_SAI=m
CONFIG_SND_SOC_STM32_I2S=m
CONFIG_SND_SOC_STM32_SPDIFRX=m
CONFIG_SND_SOC_STM32_DFSDM=m
# end of STMicroelectronics STM32
#
# Allwinner
#
CONFIG_SND_SUN4I_CODEC=m
CONFIG_SND_SUN8I_CODEC=m
CONFIG_SND_SUN8I_CODEC_ANALOG=m
CONFIG_SND_SUN50I_CODEC_ANALOG=m
CONFIG_SND_SUN4I_I2S=m
CONFIG_SND_SUN4I_SPDIF=m
CONFIG_SND_SUN50I_DMIC=m
CONFIG_SND_SUN8I_ADDA_PR_REGMAP=m
# end of Allwinner
#
# Tegra
#
CONFIG_SND_SOC_TEGRA=m
CONFIG_SND_SOC_TEGRA20_AC97=m
CONFIG_SND_SOC_TEGRA20_DAS=m
CONFIG_SND_SOC_TEGRA20_I2S=m
CONFIG_SND_SOC_TEGRA20_SPDIF=m
CONFIG_SND_SOC_TEGRA30_AHUB=m
CONFIG_SND_SOC_TEGRA30_I2S=m
CONFIG_SND_SOC_TEGRA210_AHUB=m
CONFIG_SND_SOC_TEGRA210_DMIC=m
CONFIG_SND_SOC_TEGRA210_I2S=m
CONFIG_SND_SOC_TEGRA210_OPE=m
CONFIG_SND_SOC_TEGRA186_ASRC=m
CONFIG_SND_SOC_TEGRA186_DSPK=m
CONFIG_SND_SOC_TEGRA210_ADMAIF=m
CONFIG_SND_SOC_TEGRA210_MVC=m
CONFIG_SND_SOC_TEGRA210_SFC=m
CONFIG_SND_SOC_TEGRA210_AMX=m
CONFIG_SND_SOC_TEGRA210_ADX=m
CONFIG_SND_SOC_TEGRA210_MIXER=m
CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD=m
CONFIG_SND_SOC_TEGRA_MACHINE_DRV=m
CONFIG_SND_SOC_TEGRA_RT5631=m
CONFIG_SND_SOC_TEGRA_RT5640=m
CONFIG_SND_SOC_TEGRA_WM8753=m
CONFIG_SND_SOC_TEGRA_WM8903=m
CONFIG_SND_SOC_TEGRA_WM9712=m
CONFIG_SND_SOC_TEGRA_TRIMSLICE=m
CONFIG_SND_SOC_TEGRA_ALC5632=m
CONFIG_SND_SOC_TEGRA_MAX98090=m
CONFIG_SND_SOC_TEGRA_MAX98088=m
CONFIG_SND_SOC_TEGRA_RT5677=m
CONFIG_SND_SOC_TEGRA_SGTL5000=m
# end of Tegra
#
# Texas Instruments
#
CONFIG_SND_SOC_TI_EDMA_PCM=m
CONFIG_SND_SOC_TI_SDMA_PCM=m
CONFIG_SND_SOC_TI_UDMA_PCM=m
#
# Texas Instruments DAI support for:
#
CONFIG_SND_SOC_DAVINCI_ASP=m
CONFIG_SND_SOC_DAVINCI_MCASP=m
CONFIG_SND_SOC_OMAP_DMIC=m
CONFIG_SND_SOC_OMAP_MCBSP=m
CONFIG_SND_SOC_OMAP_MCPDM=m
#
# Audio support for boards with Texas Instruments SoCs
#
CONFIG_SND_SOC_OMAP3_TWL4030=m
CONFIG_SND_SOC_OMAP_ABE_TWL6040=m
CONFIG_SND_SOC_OMAP_AMS_DELTA=m
CONFIG_SND_SOC_OMAP_HDMI=m
CONFIG_SND_SOC_J721E_EVM=m
# end of Texas Instruments
#
# UniPhier
#
CONFIG_SND_SOC_UNIPHIER_AIO=m
CONFIG_SND_SOC_UNIPHIER_LD11=m
CONFIG_SND_SOC_UNIPHIER_PXS2=m
CONFIG_SND_SOC_UNIPHIER_EVEA_CODEC=m
# end of UniPhier
#
# Xilinx
#
CONFIG_SND_SOC_XILINX_I2S=m
CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=m
CONFIG_SND_SOC_XILINX_SPDIF=m
# end of Xilinx
#
# Xtensa
#
CONFIG_SND_SOC_XTFPGA_I2S=m
# end of Xtensa
CONFIG_SND_SOC_SOF_TOPLEVEL=y
CONFIG_SND_SOC_SOF_PCI_DEV=m
CONFIG_SND_SOC_SOF_PCI=m
CONFIG_SND_SOC_SOF_ACPI=m
CONFIG_SND_SOC_SOF_ACPI_DEV=m
CONFIG_SND_SOC_SOF_OF=m
CONFIG_SND_SOC_SOF_OF_DEV=m
CONFIG_SND_SOC_SOF_COMPRESS=y
CONFIG_SND_SOC_SOF_DEBUG_PROBES=m
CONFIG_SND_SOC_SOF_CLIENT=m
CONFIG_SND_SOC_SOF_DEVELOPER_SUPPORT=y
CONFIG_SND_SOC_SOF_FORCE_PROBE_WORKQUEUE=y
CONFIG_SND_SOC_SOF_NOCODEC=m
CONFIG_SND_SOC_SOF_NOCODEC_SUPPORT=y
CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS=y
CONFIG_SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION=y
CONFIG_SND_SOC_SOF_DEBUG=y
CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE=y
CONFIG_SND_SOC_SOF_DEBUG_XRUN_STOP=y
CONFIG_SND_SOC_SOF_DEBUG_VERBOSE_IPC=y
CONFIG_SND_SOC_SOF_DEBUG_FORCE_IPC_POSITION=y
CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE=y
CONFIG_SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE=y
CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST=m
CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST_NUM=2
CONFIG_SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR=m
CONFIG_SND_SOC_SOF_DEBUG_IPC_KERNEL_INJECTOR=m
CONFIG_SND_SOC_SOF_DEBUG_RETAIN_DSP_CONTEXT=y
CONFIG_SND_SOC_SOF=m
CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE=y
CONFIG_SND_SOC_SOF_IPC3=y
CONFIG_SND_SOC_SOF_IPC4=y
CONFIG_SND_SOC_SOF_AMD_TOPLEVEL=m
CONFIG_SND_SOC_SOF_AMD_COMMON=m
CONFIG_SND_SOC_SOF_AMD_RENOIR=m
CONFIG_SND_SOC_SOF_AMD_VANGOGH=m
CONFIG_SND_SOC_SOF_AMD_REMBRANDT=m
CONFIG_SND_SOC_SOF_ACP_PROBES=m
CONFIG_SND_SOC_SOF_AMD_SOUNDWIRE_LINK_BASELINE=m
CONFIG_SND_SOC_SOF_AMD_SOUNDWIRE=m
CONFIG_SND_SOC_SOF_AMD_ACP63=m
CONFIG_SND_SOC_SOF_AMD_ACP70=m
CONFIG_SND_SOC_SOF_IMX_TOPLEVEL=y
CONFIG_SND_SOC_SOF_IMX_COMMON=m
CONFIG_SND_SOC_SOF_IMX8=m
CONFIG_SND_SOC_SOF_IMX9=m
CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL=y
CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC=m
CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP=m
CONFIG_SND_SOC_SOF_INTEL_COMMON=m
CONFIG_SND_SOC_SOF_BAYTRAIL=m
CONFIG_SND_SOC_SOF_BROADWELL=m
CONFIG_SND_SOC_SOF_MERRIFIELD=m
CONFIG_SND_SOC_SOF_INTEL_SKL=m
CONFIG_SND_SOC_SOF_SKYLAKE=m
CONFIG_SND_SOC_SOF_KABYLAKE=m
CONFIG_SND_SOC_SOF_INTEL_APL=m
CONFIG_SND_SOC_SOF_APOLLOLAKE=m
CONFIG_SND_SOC_SOF_GEMINILAKE=m
CONFIG_SND_SOC_SOF_INTEL_CNL=m
CONFIG_SND_SOC_SOF_CANNONLAKE=m
CONFIG_SND_SOC_SOF_COFFEELAKE=m
CONFIG_SND_SOC_SOF_COMETLAKE=m
CONFIG_SND_SOC_SOF_INTEL_ICL=m
CONFIG_SND_SOC_SOF_ICELAKE=m
CONFIG_SND_SOC_SOF_JASPERLAKE=m
CONFIG_SND_SOC_SOF_INTEL_TGL=m
CONFIG_SND_SOC_SOF_TIGERLAKE=m
CONFIG_SND_SOC_SOF_ELKHARTLAKE=m
CONFIG_SND_SOC_SOF_ALDERLAKE=m
CONFIG_SND_SOC_SOF_INTEL_MTL=m
CONFIG_SND_SOC_SOF_METEORLAKE=m
CONFIG_SND_SOC_SOF_INTEL_LNL=m
CONFIG_SND_SOC_SOF_LUNARLAKE=m
CONFIG_SND_SOC_SOF_INTEL_PTL=m
CONFIG_SND_SOC_SOF_PANTHERLAKE=m
CONFIG_SND_SOC_SOF_INTEL_NVL=m
CONFIG_SND_SOC_SOF_NOVALAKE=m
CONFIG_SND_SOC_SOF_HDA_COMMON=m
CONFIG_SND_SOC_SOF_HDA_GENERIC=m
CONFIG_SND_SOC_SOF_HDA_MLINK=m
CONFIG_SND_SOC_SOF_HDA_LINK=y
CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC=y
CONFIG_SND_SOF_SOF_HDA_SDW_BPT=m
CONFIG_SND_SOC_SOF_HDA_LINK_BASELINE=m
CONFIG_SND_SOC_SOF_HDA=m
CONFIG_SND_SOC_SOF_HDA_PROBES=m
CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE=m
CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE=m
CONFIG_SND_SOC_SOF_MTK_TOPLEVEL=y
CONFIG_SND_SOC_SOF_MTK_COMMON=m
CONFIG_SND_SOC_SOF_MT8186=m
CONFIG_SND_SOC_SOF_MT8195=m
CONFIG_SND_SOC_SOF_XTENSA=m
CONFIG_SND_SOC_I2C_AND_SPI=m
#
# CODEC drivers
#
CONFIG_SND_SOC_ALL_CODECS=m
CONFIG_SND_SOC_88PM860X=m
CONFIG_SND_SOC_ARIZONA=m
CONFIG_SND_SOC_WM_HUBS=m
CONFIG_SND_SOC_WM_ADSP=m
CONFIG_SND_SOC_AB8500_CODEC=m
CONFIG_SND_SOC_AC97_CODEC=m
CONFIG_SND_SOC_AD1836=m
CONFIG_SND_SOC_AD193X=m
CONFIG_SND_SOC_AD193X_SPI=m
CONFIG_SND_SOC_AD193X_I2C=m
CONFIG_SND_SOC_AD1980=m
CONFIG_SND_SOC_AD73311=m
CONFIG_SND_SOC_ADAU_UTILS=m
CONFIG_SND_SOC_ADAU1372=m
CONFIG_SND_SOC_ADAU1372_I2C=m
CONFIG_SND_SOC_ADAU1372_SPI=m
CONFIG_SND_SOC_ADAU1373=m
CONFIG_SND_SOC_ADAU1701=m
CONFIG_SND_SOC_ADAU17X1=m
CONFIG_SND_SOC_ADAU1761=m
CONFIG_SND_SOC_ADAU1761_I2C=m
CONFIG_SND_SOC_ADAU1761_SPI=m
CONFIG_SND_SOC_ADAU1781=m
CONFIG_SND_SOC_ADAU1781_I2C=m
CONFIG_SND_SOC_ADAU1781_SPI=m
CONFIG_SND_SOC_ADAU1977=m
CONFIG_SND_SOC_ADAU1977_SPI=m
CONFIG_SND_SOC_ADAU1977_I2C=m
CONFIG_SND_SOC_ADAU7002=m
CONFIG_SND_SOC_ADAU7118=m
CONFIG_SND_SOC_ADAU7118_HW=m
CONFIG_SND_SOC_ADAU7118_I2C=m
CONFIG_SND_SOC_ADAV80X=m
CONFIG_SND_SOC_ADAV801=m
CONFIG_SND_SOC_ADAV803=m
CONFIG_SND_SOC_ADS117X=m
CONFIG_SND_SOC_AK4104=m
CONFIG_SND_SOC_AK4118=m
CONFIG_SND_SOC_AK4375=m
CONFIG_SND_SOC_AK4458=m
CONFIG_SND_SOC_AK4535=m
CONFIG_SND_SOC_AK4554=m
CONFIG_SND_SOC_AK4613=m
CONFIG_SND_SOC_AK4619=m
CONFIG_SND_SOC_AK4642=m
CONFIG_SND_SOC_AK4671=m
CONFIG_SND_SOC_AK5386=m
CONFIG_SND_SOC_AK5558=m
CONFIG_SND_SOC_ALC5623=m
CONFIG_SND_SOC_ALC5632=m
CONFIG_SND_SOC_AUDIO_IIO_AUX=m
CONFIG_SND_SOC_AW8738=m
CONFIG_SND_SOC_AW88395_LIB=m
CONFIG_SND_SOC_AW88395=m
CONFIG_SND_SOC_AW88166=m
CONFIG_SND_SOC_AW88261=m
CONFIG_SND_SOC_AW88081=m
CONFIG_SND_SOC_AW87390=m
CONFIG_SND_SOC_AW88399=m
CONFIG_SND_SOC_BD28623=m
CONFIG_SND_SOC_BT_SCO=m
CONFIG_SND_SOC_CHV3_CODEC=m
CONFIG_SND_SOC_CPCAP=m
CONFIG_SND_SOC_CQ0093VC=m
CONFIG_SND_SOC_CROS_EC_CODEC=m
CONFIG_SND_SOC_CS_AMP_LIB=m
CONFIG_SND_SOC_CS_AMP_LIB_TEST_HOOKS=y
CONFIG_SND_SOC_CS_AMP_LIB_TEST=m
CONFIG_SND_SOC_CS35L32=m
CONFIG_SND_SOC_CS35L33=m
CONFIG_SND_SOC_CS35L34=m
CONFIG_SND_SOC_CS35L35=m
CONFIG_SND_SOC_CS35L36=m
CONFIG_SND_SOC_CS35L41_LIB=m
CONFIG_SND_SOC_CS35L41=m
CONFIG_SND_SOC_CS35L41_SPI=m
CONFIG_SND_SOC_CS35L41_I2C=m
CONFIG_SND_SOC_CS35L45=m
CONFIG_SND_SOC_CS35L45_SPI=m
CONFIG_SND_SOC_CS35L45_I2C=m
CONFIG_SND_SOC_CS35L56=m
CONFIG_SND_SOC_CS35L56_SHARED=m
CONFIG_SND_SOC_CS35L56_I2C=m
CONFIG_SND_SOC_CS35L56_SPI=m
CONFIG_SND_SOC_CS35L56_SDW=m
CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON=y
#
# CS35L56 driver options
#
CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS=y
CONFIG_SND_SOC_CS35L56_CAL_SET_CTRL=y
CONFIG_SND_SOC_CS35L56_TEST=m
CONFIG_SND_SOC_CS35L56_SHARED_TEST=m
# end of CS35L56 driver options
CONFIG_SND_SOC_CS40L50=m
CONFIG_SND_SOC_CS42L42_CORE=m
CONFIG_SND_SOC_CS42L42=m
CONFIG_SND_SOC_CS42L42_SDW=m
CONFIG_SND_SOC_CS42L43=m
CONFIG_SND_SOC_CS42L43_SDW=m
CONFIG_SND_SOC_CS42L51=m
CONFIG_SND_SOC_CS42L51_I2C=m
CONFIG_SND_SOC_CS42L52=m
CONFIG_SND_SOC_CS42L56=m
CONFIG_SND_SOC_CS42L73=m
CONFIG_SND_SOC_CS42L83=m
CONFIG_SND_SOC_CS42L84=m
CONFIG_SND_SOC_CS4234=m
CONFIG_SND_SOC_CS4265=m
CONFIG_SND_SOC_CS4270=m
CONFIG_SND_SOC_CS4271=m
CONFIG_SND_SOC_CS4271_I2C=m
CONFIG_SND_SOC_CS4271_SPI=m
CONFIG_SND_SOC_CS42XX8=m
CONFIG_SND_SOC_CS42XX8_I2C=m
CONFIG_SND_SOC_CS43130=m
CONFIG_SND_SOC_CS4341=m
CONFIG_SND_SOC_CS4349=m
CONFIG_SND_SOC_CS47L15=m
CONFIG_SND_SOC_CS47L24=m
CONFIG_SND_SOC_CS47L35=m
CONFIG_SND_SOC_CS47L85=m
CONFIG_SND_SOC_CS47L90=m
CONFIG_SND_SOC_CS47L92=m
CONFIG_SND_SOC_CS48L32=m
CONFIG_SND_SOC_CS53L30=m
CONFIG_SND_SOC_CS530X=m
CONFIG_SND_SOC_CS530X_I2C=m
CONFIG_SND_SOC_CS530X_SPI=m
CONFIG_SND_SOC_CX20442=m
CONFIG_SND_SOC_CX2072X=m
CONFIG_SND_SOC_JZ4740_CODEC=m
CONFIG_SND_SOC_JZ4725B_CODEC=m
CONFIG_SND_SOC_JZ4760_CODEC=m
CONFIG_SND_SOC_JZ4770_CODEC=m
CONFIG_SND_SOC_DA7210=m
CONFIG_SND_SOC_DA7213=m
CONFIG_SND_SOC_DA7218=m
CONFIG_SND_SOC_DA7219=m
CONFIG_SND_SOC_DA732X=m
CONFIG_SND_SOC_DA9055=m
CONFIG_SND_SOC_DMIC=m
CONFIG_SND_SOC_HDMI_CODEC=m
CONFIG_SND_SOC_ES7134=m
CONFIG_SND_SOC_ES7241=m
CONFIG_SND_SOC_ES83XX_DSM_COMMON=m
CONFIG_SND_SOC_ES8311=m
CONFIG_SND_SOC_ES8316=m
CONFIG_SND_SOC_ES8323=m
CONFIG_SND_SOC_ES8326=m
CONFIG_SND_SOC_ES8328=m
CONFIG_SND_SOC_ES8328_I2C=m
CONFIG_SND_SOC_ES8328_SPI=m
CONFIG_SND_SOC_ES8375=m
CONFIG_SND_SOC_ES8389=m
CONFIG_SND_SOC_FRAMER=m
CONFIG_SND_SOC_FS_AMP_LIB=m
CONFIG_SND_SOC_FS210X=m
CONFIG_SND_SOC_GTM601=m
CONFIG_SND_SOC_HDAC_HDMI=m
CONFIG_SND_SOC_HDAC_HDA=m
CONFIG_SND_SOC_HDA=m
CONFIG_SND_SOC_ICS43432=m
CONFIG_SND_SOC_IDT821034=m
CONFIG_SND_SOC_INNO_RK3036=m
CONFIG_SND_SOC_ISABELLE=m
CONFIG_SND_SOC_LM49453=m
CONFIG_SND_SOC_LOCHNAGAR_SC=m
CONFIG_SND_SOC_MADERA=m
CONFIG_SND_SOC_MAX98088=m
CONFIG_SND_SOC_MAX98090=m
CONFIG_SND_SOC_MAX98095=m
CONFIG_SND_SOC_MAX98357A=m
CONFIG_SND_SOC_MAX98371=m
CONFIG_SND_SOC_MAX98504=m
CONFIG_SND_SOC_MAX9867=m
CONFIG_SND_SOC_MAX98925=m
CONFIG_SND_SOC_MAX98926=m
CONFIG_SND_SOC_MAX98927=m
CONFIG_SND_SOC_MAX98520=m
CONFIG_SND_SOC_MAX98363=m
CONFIG_SND_SOC_MAX98373=m
CONFIG_SND_SOC_MAX98373_I2C=m
CONFIG_SND_SOC_MAX98373_SDW=m
CONFIG_SND_SOC_MAX98388=m
CONFIG_SND_SOC_MAX98390=m
CONFIG_SND_SOC_MAX98396=m
CONFIG_SND_SOC_MAX9850=m
CONFIG_SND_SOC_MAX9860=m
CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
CONFIG_SND_SOC_PCM1681=m
CONFIG_SND_SOC_PCM1754=m
CONFIG_SND_SOC_PCM1789=m
CONFIG_SND_SOC_PCM1789_I2C=m
CONFIG_SND_SOC_PCM179X=m
CONFIG_SND_SOC_PCM179X_I2C=m
CONFIG_SND_SOC_PCM179X_SPI=m
CONFIG_SND_SOC_PCM186X=m
CONFIG_SND_SOC_PCM186X_I2C=m
CONFIG_SND_SOC_PCM186X_SPI=m
CONFIG_SND_SOC_PCM3008=m
CONFIG_SND_SOC_PCM3060=m
CONFIG_SND_SOC_PCM3060_I2C=m
CONFIG_SND_SOC_PCM3060_SPI=m
CONFIG_SND_SOC_PCM3168A=m
CONFIG_SND_SOC_PCM3168A_I2C=m
CONFIG_SND_SOC_PCM3168A_SPI=m
CONFIG_SND_SOC_PCM5102A=m
CONFIG_SND_SOC_PCM512x=m
CONFIG_SND_SOC_PCM512x_I2C=m
CONFIG_SND_SOC_PCM512x_SPI=m
CONFIG_SND_SOC_PCM6240=m
CONFIG_SND_SOC_PEB2466=m
CONFIG_SND_SOC_PM4125=m
CONFIG_SND_SOC_PM4125_SDW=m
CONFIG_SND_SOC_RK3308=m
CONFIG_SND_SOC_RK3328=m
CONFIG_SND_SOC_RK817=m
CONFIG_SND_SOC_RL6231=m
CONFIG_SND_SOC_RT_SDW_COMMON=m
CONFIG_SND_SOC_RL6347A=m
CONFIG_SND_SOC_RT274=m
CONFIG_SND_SOC_RT286=m
CONFIG_SND_SOC_RT298=m
CONFIG_SND_SOC_RT1011=m
CONFIG_SND_SOC_RT1015=m
CONFIG_SND_SOC_RT1015P=m
CONFIG_SND_SOC_RT1016=m
CONFIG_SND_SOC_RT1017_SDCA_SDW=m
CONFIG_SND_SOC_RT1019=m
CONFIG_SND_SOC_RT1305=m
CONFIG_SND_SOC_RT1308=m
CONFIG_SND_SOC_RT1308_SDW=m
CONFIG_SND_SOC_RT1316_SDW=m
CONFIG_SND_SOC_RT1318=m
CONFIG_SND_SOC_RT1318_SDW=m
CONFIG_SND_SOC_RT1320_SDW=m
CONFIG_SND_SOC_RT5514=m
CONFIG_SND_SOC_RT5514_SPI=m
CONFIG_SND_SOC_RT5575=m
CONFIG_SND_SOC_RT5575_SPI=y
CONFIG_SND_SOC_RT5616=m
CONFIG_SND_SOC_RT5631=m
CONFIG_SND_SOC_RT5640=m
CONFIG_SND_SOC_RT5645=m
CONFIG_SND_SOC_RT5651=m
CONFIG_SND_SOC_RT5659=m
CONFIG_SND_SOC_RT5660=m
CONFIG_SND_SOC_RT5663=m
CONFIG_SND_SOC_RT5665=m
CONFIG_SND_SOC_RT5668=m
CONFIG_SND_SOC_RT5670=m
CONFIG_SND_SOC_RT5677=m
CONFIG_SND_SOC_RT5677_SPI=m
CONFIG_SND_SOC_RT5682=m
CONFIG_SND_SOC_RT5682_I2C=m
CONFIG_SND_SOC_RT5682_SDW=m
CONFIG_SND_SOC_RT5682S=m
CONFIG_SND_SOC_RT700=m
CONFIG_SND_SOC_RT700_SDW=m
CONFIG_SND_SOC_RT711=m
CONFIG_SND_SOC_RT711_SDW=m
CONFIG_SND_SOC_RT711_SDCA_SDW=m
CONFIG_SND_SOC_RT712_SDCA_SDW=m
CONFIG_SND_SOC_RT712_SDCA_DMIC_SDW=m
CONFIG_SND_SOC_RT721_SDCA_SDW=m
CONFIG_SND_SOC_RT722_SDCA_SDW=m
CONFIG_SND_SOC_RT715=m
CONFIG_SND_SOC_RT715_SDW=m
CONFIG_SND_SOC_RT715_SDCA_SDW=m
CONFIG_SND_SOC_RT9120=m
CONFIG_SND_SOC_RT9123=m
CONFIG_SND_SOC_RT9123P=m
CONFIG_SND_SOC_RTQ9124=m
CONFIG_SND_SOC_RTQ9128=m
CONFIG_SND_SOC_SDW_MOCKUP=m
CONFIG_SND_SOC_SGTL5000=m
CONFIG_SND_SOC_SI476X=m
CONFIG_SND_SOC_SIGMADSP=m
CONFIG_SND_SOC_SIGMADSP_I2C=m
CONFIG_SND_SOC_SIGMADSP_REGMAP=m
CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m
CONFIG_SND_SOC_SIMPLE_MUX=m
CONFIG_SND_SOC_SMA1303=m
CONFIG_SND_SOC_SMA1307=m
CONFIG_SND_SOC_SPDIF=m
CONFIG_SND_SOC_SRC4XXX_I2C=m
CONFIG_SND_SOC_SRC4XXX=m
CONFIG_SND_SOC_SSM2305=m
CONFIG_SND_SOC_SSM2518=m
CONFIG_SND_SOC_SSM2602=m
CONFIG_SND_SOC_SSM2602_SPI=m
CONFIG_SND_SOC_SSM2602_I2C=m
CONFIG_SND_SOC_SSM3515=m
CONFIG_SND_SOC_SSM4567=m
CONFIG_SND_SOC_STA32X=m
CONFIG_SND_SOC_STA350=m
CONFIG_SND_SOC_STA529=m
CONFIG_SND_SOC_STAC9766=m
CONFIG_SND_SOC_STI_SAS=m
CONFIG_SND_SOC_TAS2552=m
CONFIG_SND_SOC_TAS2562=m
CONFIG_SND_SOC_TAS2764=m
CONFIG_SND_SOC_TAS2770=m
CONFIG_SND_SOC_TAS2780=m
CONFIG_SND_SOC_TAS2781_COMLIB=m
CONFIG_SND_SOC_TAS2781_COMLIB_I2C=m
CONFIG_SND_SOC_TAS2781_FMWLIB=m
CONFIG_SND_SOC_TAS2781_I2C=m
CONFIG_SND_SOC_TAS2783_SDW=m
CONFIG_SND_SOC_TAS5086=m
CONFIG_SND_SOC_TAS571X=m
CONFIG_SND_SOC_TAS5720=m
CONFIG_SND_SOC_TAS5805M=m
CONFIG_SND_SOC_TAS6424=m
CONFIG_SND_SOC_TDA7419=m
CONFIG_SND_SOC_TFA9879=m
CONFIG_SND_SOC_TFA989X=m
CONFIG_SND_SOC_TLV320ADC3XXX=m
CONFIG_SND_SOC_TLV320AIC23=m
CONFIG_SND_SOC_TLV320AIC23_I2C=m
CONFIG_SND_SOC_TLV320AIC23_SPI=m
CONFIG_SND_SOC_TLV320AIC26=m
CONFIG_SND_SOC_TLV320AIC31XX=m
CONFIG_SND_SOC_TLV320AIC32X4=m
CONFIG_SND_SOC_TLV320AIC32X4_I2C=m
CONFIG_SND_SOC_TLV320AIC32X4_SPI=m
CONFIG_SND_SOC_TLV320AIC3X=m
CONFIG_SND_SOC_TLV320AIC3X_I2C=m
CONFIG_SND_SOC_TLV320AIC3X_SPI=m
CONFIG_SND_SOC_TLV320DAC33=m
CONFIG_SND_SOC_TLV320ADCX140=m
CONFIG_SND_SOC_TS3A227E=m
CONFIG_SND_SOC_TSCS42XX=m
CONFIG_SND_SOC_TSCS454=m
CONFIG_SND_SOC_TWL4030=m
CONFIG_SND_SOC_TWL6040=m
CONFIG_SND_SOC_UDA1334=m
CONFIG_SND_SOC_UDA1342=m
CONFIG_SND_SOC_UDA1380=m
CONFIG_SND_SOC_WCD_CLASSH=m
CONFIG_SND_SOC_WCD_COMMON=m
CONFIG_SND_SOC_WCD9335=m
CONFIG_SND_SOC_WCD_MBHC=m
CONFIG_SND_SOC_WCD934X=m
CONFIG_SND_SOC_WCD937X=m
CONFIG_SND_SOC_WCD937X_SDW=m
CONFIG_SND_SOC_WCD938X=m
CONFIG_SND_SOC_WCD938X_SDW=m
CONFIG_SND_SOC_WCD939X=m
CONFIG_SND_SOC_WCD939X_SDW=m
CONFIG_SND_SOC_WM0010=m
CONFIG_SND_SOC_WM1250_EV1=m
CONFIG_SND_SOC_WM2000=m
CONFIG_SND_SOC_WM2200=m
CONFIG_SND_SOC_WM5100=m
CONFIG_SND_SOC_WM5102=m
CONFIG_SND_SOC_WM5110=m
CONFIG_SND_SOC_WM8350=m
CONFIG_SND_SOC_WM8400=m
CONFIG_SND_SOC_WM8510=m
CONFIG_SND_SOC_WM8523=m
CONFIG_SND_SOC_WM8524=m
CONFIG_SND_SOC_WM8580=m
CONFIG_SND_SOC_WM8711=m
CONFIG_SND_SOC_WM8727=m
CONFIG_SND_SOC_WM8728=m
CONFIG_SND_SOC_WM8731=m
CONFIG_SND_SOC_WM8731_I2C=m
CONFIG_SND_SOC_WM8731_SPI=m
CONFIG_SND_SOC_WM8737=m
CONFIG_SND_SOC_WM8741=m
CONFIG_SND_SOC_WM8750=m
CONFIG_SND_SOC_WM8753=m
CONFIG_SND_SOC_WM8770=m
CONFIG_SND_SOC_WM8776=m
CONFIG_SND_SOC_WM8782=m
CONFIG_SND_SOC_WM8804=m
CONFIG_SND_SOC_WM8804_I2C=m
CONFIG_SND_SOC_WM8804_SPI=m
CONFIG_SND_SOC_WM8900=m
CONFIG_SND_SOC_WM8903=m
CONFIG_SND_SOC_WM8904=m
CONFIG_SND_SOC_WM8940=m
CONFIG_SND_SOC_WM8955=m
CONFIG_SND_SOC_WM8960=m
CONFIG_SND_SOC_WM8961=m
CONFIG_SND_SOC_WM8962=m
CONFIG_SND_SOC_WM8971=m
CONFIG_SND_SOC_WM8974=m
CONFIG_SND_SOC_WM8978=m
CONFIG_SND_SOC_WM8983=m
CONFIG_SND_SOC_WM8985=m
CONFIG_SND_SOC_WM8988=m
CONFIG_SND_SOC_WM8990=m
CONFIG_SND_SOC_WM8991=m
CONFIG_SND_SOC_WM8993=m
CONFIG_SND_SOC_WM8994=m
CONFIG_SND_SOC_WM8995=m
CONFIG_SND_SOC_WM8996=m
CONFIG_SND_SOC_WM8997=m
CONFIG_SND_SOC_WM8998=m
CONFIG_SND_SOC_WM9081=m
CONFIG_SND_SOC_WM9090=m
CONFIG_SND_SOC_WM9705=m
CONFIG_SND_SOC_WM9712=m
CONFIG_SND_SOC_WM9713=m
CONFIG_SND_SOC_WSA881X=m
CONFIG_SND_SOC_WSA883X=m
CONFIG_SND_SOC_WSA884X=m
CONFIG_SND_SOC_ZL38060=m
CONFIG_SND_SOC_LM4857=m
CONFIG_SND_SOC_MAX9759=m
CONFIG_SND_SOC_MAX9768=m
CONFIG_SND_SOC_MAX9877=m
CONFIG_SND_SOC_MC13783=m
CONFIG_SND_SOC_ML26124=m
CONFIG_SND_SOC_MT6351=m
CONFIG_SND_SOC_MT6357=m
CONFIG_SND_SOC_MT6358=m
CONFIG_SND_SOC_MT6359=m
CONFIG_SND_SOC_MT6359_ACCDET=m
CONFIG_SND_SOC_MT6660=m
CONFIG_SND_SOC_NAU8315=m
CONFIG_SND_SOC_NAU8325=m
CONFIG_SND_SOC_NAU8540=m
CONFIG_SND_SOC_NAU8810=m
CONFIG_SND_SOC_NAU8821=m
CONFIG_SND_SOC_NAU8822=m
CONFIG_SND_SOC_NAU8824=m
CONFIG_SND_SOC_NAU8825=m
CONFIG_SND_SOC_NTPFW=m
CONFIG_SND_SOC_NTP8918=m
CONFIG_SND_SOC_NTP8835=m
CONFIG_SND_SOC_TPA6130A2=m
CONFIG_SND_SOC_LPASS_MACRO_COMMON=m
CONFIG_SND_SOC_LPASS_WSA_MACRO=m
CONFIG_SND_SOC_LPASS_VA_MACRO=m
CONFIG_SND_SOC_LPASS_RX_MACRO=m
CONFIG_SND_SOC_LPASS_TX_MACRO=m
# end of CODEC drivers
CONFIG_SND_SOC_SDW_UTILS=m
#
# Generic drivers
#
CONFIG_SND_SIMPLE_CARD_UTILS=m
CONFIG_SND_SIMPLE_CARD=m
CONFIG_SND_AUDIO_GRAPH_CARD=m
CONFIG_SND_AUDIO_GRAPH_CARD2=m
CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE=m
CONFIG_SND_TEST_COMPONENT=m
# end of Generic drivers
CONFIG_SND_X86=y
CONFIG_HDMI_LPE_AUDIO=m
CONFIG_SND_SYNTH_EMUX=m
CONFIG_SND_XEN_FRONTEND=m
CONFIG_SND_VIRTIO=m
CONFIG_AC97_BUS=m
CONFIG_HID_SUPPORT=y
CONFIG_HID=m
CONFIG_HID_BATTERY_STRENGTH=y
CONFIG_HIDRAW=y
CONFIG_UHID=m
CONFIG_HID_GENERIC=m
CONFIG_HID_HAPTIC=y
#
# Special HID drivers
#
CONFIG_HID_A4TECH=m
CONFIG_HID_ACCUTOUCH=m
CONFIG_HID_ACRUX=m
CONFIG_HID_ACRUX_FF=y
CONFIG_HID_APPLE=m
CONFIG_HID_APPLEIR=m
CONFIG_HID_APPLETB_BL=m
CONFIG_HID_APPLETB_KBD=m
CONFIG_HID_ASUS=m
CONFIG_HID_AUREAL=m
CONFIG_HID_BELKIN=m
CONFIG_HID_BETOP_FF=m
CONFIG_HID_BIGBEN_FF=m
CONFIG_HID_CHERRY=m
CONFIG_HID_CHICONY=m
CONFIG_HID_CORSAIR=m
CONFIG_HID_COUGAR=m
CONFIG_HID_MACALLY=m
CONFIG_HID_PRODIKEYS=m
CONFIG_HID_CMEDIA=m
CONFIG_HID_CP2112=m
CONFIG_HID_CREATIVE_SB0540=m
CONFIG_HID_CYPRESS=m
CONFIG_HID_DRAGONRISE=m
CONFIG_DRAGONRISE_FF=y
CONFIG_HID_EMS_FF=m
CONFIG_HID_ELAN=m
CONFIG_HID_ELECOM=m
CONFIG_HID_ELO=m
CONFIG_HID_EVISION=m
CONFIG_HID_EZKEY=m
CONFIG_HID_FT260=m
CONFIG_HID_GEMBIRD=m
CONFIG_HID_GFRM=m
CONFIG_HID_GLORIOUS=m
CONFIG_HID_HOLTEK=m
CONFIG_HOLTEK_FF=y
CONFIG_HID_VIVALDI_COMMON=m
CONFIG_HID_GOODIX_SPI=m
CONFIG_HID_GOOGLE_HAMMER=m
CONFIG_HID_GOOGLE_STADIA_FF=m
CONFIG_HID_VIVALDI=m
CONFIG_HID_GT683R=m
CONFIG_HID_KEYTOUCH=m
CONFIG_HID_KYE=m
CONFIG_HID_KYSONA=m
CONFIG_HID_UCLOGIC=m
CONFIG_HID_WALTOP=m
CONFIG_HID_VIEWSONIC=m
CONFIG_HID_VRC2=m
CONFIG_HID_XIAOMI=m
CONFIG_HID_GYRATION=m
CONFIG_HID_ICADE=m
CONFIG_HID_ITE=m
CONFIG_HID_JABRA=m
CONFIG_HID_TWINHAN=m
CONFIG_HID_KENSINGTON=m
CONFIG_HID_LCPOWER=m
CONFIG_HID_LED=m
CONFIG_HID_LENOVO=m
CONFIG_HID_LETSKETCH=m
CONFIG_HID_LOGITECH=m
CONFIG_HID_LOGITECH_DJ=m
CONFIG_HID_LOGITECH_HIDPP=m
CONFIG_LOGITECH_FF=y
CONFIG_LOGIRUMBLEPAD2_FF=y
CONFIG_LOGIG940_FF=y
CONFIG_LOGIWHEELS_FF=y
CONFIG_HID_MAGICMOUSE=m
CONFIG_HID_MALTRON=m
CONFIG_HID_MAYFLASH=m
CONFIG_HID_MEGAWORLD_FF=m
CONFIG_HID_REDRAGON=m
CONFIG_HID_MICROSOFT=m
CONFIG_HID_MONTEREY=m
CONFIG_HID_MULTITOUCH=m
CONFIG_HID_NINTENDO=m
CONFIG_NINTENDO_FF=y
CONFIG_HID_NTI=m
CONFIG_HID_NTRIG=m
CONFIG_HID_NVIDIA_SHIELD=m
CONFIG_NVIDIA_SHIELD_FF=y
CONFIG_HID_ORTEK=m
CONFIG_HID_PANTHERLORD=m
CONFIG_PANTHERLORD_FF=y
CONFIG_HID_PENMOUNT=m
CONFIG_HID_PETALYNX=m
CONFIG_HID_PICOLCD=m
CONFIG_HID_PICOLCD_FB=y
CONFIG_HID_PICOLCD_BACKLIGHT=y
CONFIG_HID_PICOLCD_LCD=y
CONFIG_HID_PICOLCD_LEDS=y
CONFIG_HID_PICOLCD_CIR=y
CONFIG_HID_PLANTRONICS=m
CONFIG_HID_PLAYSTATION=m
CONFIG_PLAYSTATION_FF=y
CONFIG_HID_PXRC=m
CONFIG_HID_RAPOO=m
CONFIG_HID_RAZER=m
CONFIG_HID_PRIMAX=m
CONFIG_HID_RETRODE=m
CONFIG_HID_ROCCAT=m
CONFIG_HID_SAITEK=m
CONFIG_HID_SAMSUNG=m
CONFIG_HID_SEMITEK=m
CONFIG_HID_SIGMAMICRO=m
CONFIG_HID_SONY=m
CONFIG_SONY_FF=y
CONFIG_HID_SPEEDLINK=m
CONFIG_HID_STEAM=m
CONFIG_STEAM_FF=y
CONFIG_HID_STEELSERIES=m
CONFIG_HID_SUNPLUS=m
CONFIG_HID_RMI=m
CONFIG_HID_GREENASIA=m
CONFIG_GREENASIA_FF=y
CONFIG_HID_HYPERV_MOUSE=m
CONFIG_HID_SMARTJOYPLUS=m
CONFIG_SMARTJOYPLUS_FF=y
CONFIG_HID_TIVO=m
CONFIG_HID_TOPSEED=m
CONFIG_HID_TOPRE=m
CONFIG_HID_THINGM=m
CONFIG_HID_THRUSTMASTER=m
CONFIG_THRUSTMASTER_FF=y
CONFIG_HID_UDRAW_PS3=m
CONFIG_HID_U2FZERO=m
CONFIG_HID_UNIVERSAL_PIDFF=m
CONFIG_HID_WACOM=m
CONFIG_HID_WIIMOTE=m
CONFIG_HID_WINWING=m
CONFIG_HID_XINMO=m
CONFIG_HID_ZEROPLUS=m
CONFIG_ZEROPLUS_FF=y
CONFIG_HID_ZYDACRON=m
CONFIG_HID_SENSOR_HUB=m
CONFIG_HID_SENSOR_CUSTOM_SENSOR=m
CONFIG_HID_ALPS=m
CONFIG_HID_MCP2200=m
CONFIG_HID_MCP2221=m
CONFIG_HID_KUNIT_TEST=m
# end of Special HID drivers
#
# HID-BPF support
#
CONFIG_HID_BPF=y
# end of HID-BPF support
CONFIG_I2C_HID=m
CONFIG_I2C_HID_ACPI=m
CONFIG_I2C_HID_OF=m
CONFIG_I2C_HID_OF_ELAN=m
CONFIG_I2C_HID_OF_GOODIX=m
CONFIG_I2C_HID_CORE=m
#
# Intel ISH HID support
#
CONFIG_INTEL_ISH_HID=m
CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER=m
# end of Intel ISH HID support
#
# AMD SFH HID Support
#
CONFIG_AMD_SFH_HID=m
# end of AMD SFH HID Support
#
# Surface System Aggregator Module HID support
#
CONFIG_SURFACE_HID=m
CONFIG_SURFACE_KBD=m
# end of Surface System Aggregator Module HID support
CONFIG_SURFACE_HID_CORE=m
#
# USB HID support
#
CONFIG_USB_HID=m
CONFIG_HID_PID=y
CONFIG_USB_HIDDEV=y
#
# USB HID Boot Protocol drivers
#
CONFIG_USB_KBD=m
CONFIG_USB_MOUSE=m
# end of USB HID Boot Protocol drivers
# end of USB HID support
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=m
CONFIG_USB_LED_TRIG=y
CONFIG_USB_ULPI_BUS=m
CONFIG_USB_CONN_GPIO=m
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=m
CONFIG_USB_PCI=y
CONFIG_USB_PCI_AMD=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
#
# Miscellaneous USB options
#
CONFIG_USB_DEFAULT_PERSIST=y
CONFIG_USB_FEW_INIT_RETRIES=y
CONFIG_USB_DYNAMIC_MINORS=y
CONFIG_USB_OTG=y
CONFIG_USB_OTG_PRODUCTLIST=y
CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB=y
CONFIG_USB_OTG_FSM=m
CONFIG_USB_LEDS_TRIGGER_USBPORT=m
CONFIG_USB_AUTOSUSPEND_DELAY=2
CONFIG_USB_DEFAULT_AUTHORIZATION_MODE=1
CONFIG_USB_MON=m
#
# USB Host Controller Drivers
#
CONFIG_USB_C67X00_HCD=m
CONFIG_USB_XHCI_HCD=m
CONFIG_USB_XHCI_DBGCAP=y
CONFIG_USB_XHCI_PCI=m
CONFIG_USB_XHCI_PCI_RENESAS=m
CONFIG_USB_XHCI_PLATFORM=m
CONFIG_USB_XHCI_HISTB=m
CONFIG_USB_XHCI_MTK=m
CONFIG_USB_XHCI_MVEBU=m
CONFIG_USB_XHCI_RCAR=m
CONFIG_USB_XHCI_RZV2M=y
CONFIG_USB_XHCI_SIDEBAND=y
CONFIG_USB_EHCI_BRCMSTB=m
CONFIG_USB_BRCMSTB=m
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_EHCI_PCI=m
CONFIG_USB_EHCI_FSL=m
CONFIG_USB_EHCI_HCD_NPCM7XX=m
CONFIG_USB_EHCI_HCD_OMAP=m
CONFIG_USB_EHCI_HCD_ORION=m
CONFIG_USB_EHCI_HCD_SPEAR=m
CONFIG_USB_EHCI_HCD_STI=m
CONFIG_USB_EHCI_HCD_AT91=m
CONFIG_USB_EHCI_SH=y
CONFIG_USB_EHCI_EXYNOS=m
CONFIG_USB_EHCI_MV=m
CONFIG_USB_EHCI_HCD_PLATFORM=m
CONFIG_USB_OXU210HP_HCD=m
CONFIG_USB_ISP116X_HCD=m
CONFIG_USB_MAX3421_HCD=m
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_OHCI_HCD_SPEAR=m
CONFIG_USB_OHCI_HCD_STI=m
CONFIG_USB_OHCI_HCD_S3C2410=m
CONFIG_USB_OHCI_HCD_LPC32XX=m
CONFIG_USB_OHCI_HCD_AT91=m
CONFIG_USB_OHCI_HCD_OMAP3=m
CONFIG_USB_OHCI_HCD_DAVINCI=m
CONFIG_USB_OHCI_HCD_PCI=m
CONFIG_USB_OHCI_HCD_SSB=y
CONFIG_USB_OHCI_EXYNOS=m
CONFIG_USB_OHCI_HCD_PLATFORM=m
CONFIG_USB_UHCI_HCD=m
CONFIG_USB_SL811_HCD=m
CONFIG_USB_SL811_HCD_ISO=y
CONFIG_USB_SL811_CS=m
CONFIG_USB_R8A66597_HCD=m
CONFIG_USB_RENESAS_USBHS_HCD=m
CONFIG_USB_HCD_BCMA=m
CONFIG_USB_HCD_SSB=m
CONFIG_USB_HCD_TEST_MODE=y
CONFIG_USB_XEN_HCD=m
CONFIG_USB_RENESAS_USBHS=m
#
# USB Device Class drivers
#
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
CONFIG_USB_WDM=m
CONFIG_USB_TMC=m
#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=m
CONFIG_USB_STORAGE_DEBUG=y
CONFIG_USB_STORAGE_REALTEK=m
CONFIG_REALTEK_AUTOPM=y
CONFIG_USB_STORAGE_DATAFAB=m
CONFIG_USB_STORAGE_FREECOM=m
CONFIG_USB_STORAGE_ISD200=m
CONFIG_USB_STORAGE_USBAT=m
CONFIG_USB_STORAGE_SDDR09=m
CONFIG_USB_STORAGE_SDDR55=m
CONFIG_USB_STORAGE_JUMPSHOT=m
CONFIG_USB_STORAGE_ALAUDA=m
CONFIG_USB_STORAGE_ONETOUCH=m
CONFIG_USB_STORAGE_KARMA=m
CONFIG_USB_STORAGE_CYPRESS_ATACB=m
CONFIG_USB_STORAGE_ENE_UB6250=m
CONFIG_USB_UAS=m
#
# USB Imaging devices
#
CONFIG_USB_MDC800=m
CONFIG_USB_MICROTEK=m
CONFIG_USBIP_CORE=m
CONFIG_USBIP_VHCI_HCD=m
CONFIG_USBIP_VHCI_HC_PORTS=8
CONFIG_USBIP_VHCI_NR_HCS=1
CONFIG_USBIP_HOST=m
CONFIG_USBIP_VUDC=m
CONFIG_USBIP_DEBUG=y
#
# USB dual-mode controller drivers
#
CONFIG_USB_CDNS_SUPPORT=m
CONFIG_USB_CDNS_HOST=y
CONFIG_USB_CDNS3=m
CONFIG_USB_CDNS3_GADGET=y
CONFIG_USB_CDNS3_HOST=y
CONFIG_USB_CDNS3_PCI_WRAP=m
CONFIG_USB_CDNS3_TI=m
CONFIG_USB_CDNS3_IMX=m
CONFIG_USB_CDNS3_STARFIVE=m
CONFIG_USB_CDNSP_PCI=m
CONFIG_USB_CDNSP_GADGET=y
CONFIG_USB_CDNSP_HOST=y
CONFIG_USB_FOTG210=m
CONFIG_USB_FOTG210_HCD=y
CONFIG_USB_FOTG210_UDC=y
CONFIG_USB_MTU3=m
# CONFIG_USB_MTU3_HOST is not set
# CONFIG_USB_MTU3_GADGET is not set
CONFIG_USB_MTU3_DUAL_ROLE=y
CONFIG_USB_MTU3_DEBUG=y
CONFIG_USB_MUSB_HDRC=m
# CONFIG_USB_MUSB_HOST is not set
# CONFIG_USB_MUSB_GADGET is not set
CONFIG_USB_MUSB_DUAL_ROLE=y
#
# Platform Glue Layer
#
CONFIG_USB_MUSB_TUSB6010=m
CONFIG_USB_MUSB_OMAP2PLUS=m
CONFIG_USB_MUSB_DSPS=m
CONFIG_USB_MUSB_UX500=m
CONFIG_USB_MUSB_MEDIATEK=m
CONFIG_USB_MUSB_POLARFIRE_SOC=m
#
# MUSB DMA mode
#
CONFIG_MUSB_PIO_ONLY=y
CONFIG_USB_DWC3=m
CONFIG_USB_DWC3_ULPI=y
# CONFIG_USB_DWC3_HOST is not set
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_DWC3_DUAL_ROLE=y
#
# Platform Glue Driver Support
#
CONFIG_USB_DWC3_OMAP=m
CONFIG_USB_DWC3_EXYNOS=m
CONFIG_USB_DWC3_PCI=m
CONFIG_USB_DWC3_HAPS=m
CONFIG_USB_DWC3_KEYSTONE=m
CONFIG_USB_DWC3_MESON_G12A=m
CONFIG_USB_DWC3_OF_SIMPLE=m
CONFIG_USB_DWC3_ST=m
CONFIG_USB_DWC3_QCOM=m
CONFIG_USB_DWC3_IMX8MP=m
CONFIG_USB_DWC3_XILINX=m
CONFIG_USB_DWC3_AM62=m
CONFIG_USB_DWC3_OCTEON=m
CONFIG_USB_DWC3_GENERIC_PLAT=m
CONFIG_USB_DWC3_GOOGLE=m
CONFIG_USB_DWC2=m
# CONFIG_USB_DWC2_HOST is not set
#
# Gadget/Dual-role mode requires USB Gadget support to be enabled
#
# CONFIG_USB_DWC2_PERIPHERAL is not set
CONFIG_USB_DWC2_DUAL_ROLE=y
CONFIG_USB_DWC2_PCI=m
CONFIG_USB_DWC2_DEBUG=y
CONFIG_USB_DWC2_VERBOSE=y
CONFIG_USB_DWC2_TRACK_MISSED_SOFS=y
CONFIG_USB_DWC2_DEBUG_PERIODIC=y
CONFIG_USB_CHIPIDEA=m
CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_USB_CHIPIDEA_PCI=m
CONFIG_USB_CHIPIDEA_MSM=m
CONFIG_USB_CHIPIDEA_NPCM=m
CONFIG_USB_CHIPIDEA_IMX=m
CONFIG_USB_CHIPIDEA_GENERIC=m
CONFIG_USB_CHIPIDEA_TEGRA=m
CONFIG_USB_ISP1760=m
CONFIG_USB_ISP1760_HCD=y
CONFIG_USB_ISP1761_UDC=y
# CONFIG_USB_ISP1760_HOST_ROLE is not set
# CONFIG_USB_ISP1760_GADGET_ROLE is not set
CONFIG_USB_ISP1760_DUAL_ROLE=y
#
# USB port drivers
#
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_SIMPLE=m
CONFIG_USB_SERIAL_AIRCABLE=m
CONFIG_USB_SERIAL_ARK3116=m
CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_CH341=m
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
CONFIG_USB_SERIAL_CP210X=m
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_VISOR=m
CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
CONFIG_USB_SERIAL_F81232=m
CONFIG_USB_SERIAL_F8153X=m
CONFIG_USB_SERIAL_GARMIN=m
CONFIG_USB_SERIAL_IPW=m
CONFIG_USB_SERIAL_IUU=m
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
CONFIG_USB_SERIAL_KEYSPAN=m
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_METRO=m
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7715_PARPORT=y
CONFIG_USB_SERIAL_MOS7840=m
CONFIG_USB_SERIAL_MXUPORT=m
CONFIG_USB_SERIAL_NAVMAN=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_OTI6858=m
CONFIG_USB_SERIAL_QCAUX=m
CONFIG_USB_SERIAL_QUALCOMM=m
CONFIG_USB_SERIAL_SPCP8X5=m
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SAFE_PADDED=y
CONFIG_USB_SERIAL_SIERRAWIRELESS=m
CONFIG_USB_SERIAL_SYMBOL=m
CONFIG_USB_SERIAL_TI=m
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_WWAN=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_SERIAL_OMNINET=m
CONFIG_USB_SERIAL_OPTICON=m
CONFIG_USB_SERIAL_XSENS_MT=m
CONFIG_USB_SERIAL_WISHBONE=m
CONFIG_USB_SERIAL_SSU100=m
CONFIG_USB_SERIAL_QT2=m
CONFIG_USB_SERIAL_UPD78F0730=m
CONFIG_USB_SERIAL_XR=m
CONFIG_USB_SERIAL_DEBUG=m
#
# USB Miscellaneous drivers
#
CONFIG_USB_USS720=m
CONFIG_USB_EMI62=m
CONFIG_USB_EMI26=m
CONFIG_USB_ADUTUX=m
CONFIG_USB_SEVSEG=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_LCD=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_APPLEDISPLAY=m
CONFIG_USB_QCOM_EUD=m
CONFIG_APPLE_MFI_FASTCHARGE=m
CONFIG_USB_LJCA=m
CONFIG_USB_USBIO=m
CONFIG_USB_SISUSBVGA=m
CONFIG_USB_LD=m
CONFIG_USB_TRANCEVIBRATOR=m
CONFIG_USB_IOWARRIOR=m
CONFIG_USB_TEST=m
CONFIG_USB_EHSET_TEST_FIXTURE=m
CONFIG_USB_ISIGHTFW=m
CONFIG_USB_YUREX=m
CONFIG_USB_EZUSB_FX2=m
CONFIG_USB_HUB_USB251XB=m
CONFIG_USB_HSIC_USB3503=m
CONFIG_USB_HSIC_USB4604=m
CONFIG_USB_LINK_LAYER_TEST=m
CONFIG_USB_CHAOSKEY=m
CONFIG_BRCM_USB_PINMAP=m
CONFIG_USB_ONBOARD_DEV=m
CONFIG_USB_ONBOARD_DEV_USB5744=y
CONFIG_USB_ATM=m
CONFIG_USB_SPEEDTOUCH=m
CONFIG_USB_CXACRU=m
CONFIG_USB_UEAGLEATM=m
CONFIG_USB_XUSBATM=m
#
# USB Physical Layer drivers
#
CONFIG_USB_PHY=y
CONFIG_KEYSTONE_USB_PHY=m
CONFIG_NOP_USB_XCEIV=m
CONFIG_AM335X_CONTROL_USB=m
CONFIG_AM335X_PHY_USB=m
CONFIG_TWL6030_USB=m
CONFIG_USB_GPIO_VBUS=m
CONFIG_TAHVO_USB=m
CONFIG_TAHVO_USB_HOST_BY_DEFAULT=y
CONFIG_USB_ISP1301=m
CONFIG_USB_TEGRA_PHY=m
CONFIG_USB_ULPI=y
CONFIG_USB_ULPI_VIEWPORT=y
# end of USB Physical Layer drivers
CONFIG_USB_GADGET=m
CONFIG_USB_GADGET_DEBUG=y
CONFIG_USB_GADGET_VERBOSE=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_GADGET_VBUS_DRAW=2
CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
CONFIG_U_SERIAL_CONSOLE=y
#
# USB Peripheral Controller
#
CONFIG_USB_LPC32XX=m
CONFIG_USB_GR_UDC=m
CONFIG_USB_R8A66597=m
CONFIG_USB_RENESAS_USBHS_UDC=m
CONFIG_USB_RZV2M_USB3DRD=m
CONFIG_USB_RENESAS_USB3=m
CONFIG_USB_RENESAS_USBF=m
CONFIG_USB_PXA27X=m
CONFIG_USB_SNP_CORE=m
CONFIG_USB_SNP_UDC_PLAT=m
CONFIG_USB_M66592=m
CONFIG_USB_BDC_UDC=m
CONFIG_USB_AMD5536UDC=m
CONFIG_USB_NET2280=m
CONFIG_USB_GOKU=m
CONFIG_USB_EG20T=m
CONFIG_USB_GADGET_XILINX=m
CONFIG_USB_MAX3420_UDC=m
CONFIG_USB_ASPEED_UDC=m
CONFIG_USB_ASPEED_VHUB=m
CONFIG_USB_CDNS2_UDC=m
CONFIG_USB_DUMMY_HCD=m
# end of USB Peripheral Controller
CONFIG_USB_LIBCOMPOSITE=m
CONFIG_USB_F_ACM=m
CONFIG_USB_F_SS_LB=m
CONFIG_USB_U_SERIAL=m
CONFIG_USB_U_ETHER=m
CONFIG_USB_U_AUDIO=m
CONFIG_USB_F_SERIAL=m
CONFIG_USB_F_OBEX=m
CONFIG_USB_F_NCM=m
CONFIG_USB_F_ECM=m
CONFIG_USB_F_PHONET=m
CONFIG_USB_F_EEM=m
CONFIG_USB_F_SUBSET=m
CONFIG_USB_F_RNDIS=m
CONFIG_USB_F_MASS_STORAGE=m
CONFIG_USB_F_FS=m
CONFIG_USB_F_UAC1=m
CONFIG_USB_F_UAC1_LEGACY=m
CONFIG_USB_F_UAC2=m
CONFIG_USB_F_UVC=m
CONFIG_USB_F_MIDI=m
CONFIG_USB_F_MIDI2=m
CONFIG_USB_F_HID=m
CONFIG_USB_F_PRINTER=m
CONFIG_USB_F_TCM=m
CONFIG_USB_CONFIGFS=m
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_ACM=y
CONFIG_USB_CONFIGFS_OBEX=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_ECM=y
CONFIG_USB_CONFIGFS_ECM_SUBSET=y
CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_EEM=y
CONFIG_USB_CONFIGFS_PHONET=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_LB_SS=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_UAC1=y
CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y
CONFIG_USB_CONFIGFS_F_UAC2=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_MIDI2=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_UVC=y
CONFIG_USB_CONFIGFS_F_PRINTER=y
CONFIG_USB_CONFIGFS_F_TCM=y
#
# USB Gadget precomposed configurations
#
CONFIG_USB_ZERO=m
CONFIG_USB_ZERO_HNPTEST=y
CONFIG_USB_AUDIO=m
CONFIG_GADGET_UAC1=y
CONFIG_GADGET_UAC1_LEGACY=y
CONFIG_USB_ETH=m
CONFIG_USB_ETH_RNDIS=y
CONFIG_USB_ETH_EEM=y
CONFIG_USB_G_NCM=m
CONFIG_USB_GADGETFS=m
CONFIG_USB_FUNCTIONFS=m
CONFIG_USB_FUNCTIONFS_ETH=y
CONFIG_USB_FUNCTIONFS_RNDIS=y
CONFIG_USB_FUNCTIONFS_GENERIC=y
CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_GADGET_TARGET=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_MIDI_GADGET=m
CONFIG_USB_G_PRINTER=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_USB_G_NOKIA=m
CONFIG_USB_G_ACM_MS=m
CONFIG_USB_G_MULTI=m
CONFIG_USB_G_MULTI_RNDIS=y
CONFIG_USB_G_MULTI_CDC=y
CONFIG_USB_G_HID=m
CONFIG_USB_G_DBGP=m
# CONFIG_USB_G_DBGP_PRINTK is not set
CONFIG_USB_G_DBGP_SERIAL=y
CONFIG_USB_G_WEBCAM=m
CONFIG_USB_RAW_GADGET=m
# end of USB Gadget precomposed configurations
CONFIG_TYPEC=m
CONFIG_TYPEC_TCPM=m
CONFIG_TYPEC_TCPCI=m
CONFIG_TYPEC_RT1711H=m
CONFIG_TYPEC_MT6360=m
CONFIG_TYPEC_TCPCI_MT6370=m
CONFIG_TYPEC_TCPCI_MAXIM=m
CONFIG_TYPEC_FUSB302=m
CONFIG_TYPEC_WCOVE=m
CONFIG_TYPEC_QCOM_PMIC=m
CONFIG_TYPEC_UCSI=m
CONFIG_UCSI_CCG=m
CONFIG_UCSI_ACPI=m
CONFIG_UCSI_STM32G0=m
CONFIG_UCSI_PMIC_GLINK=m
CONFIG_CROS_EC_UCSI=m
CONFIG_UCSI_LENOVO_YOGA_C630=m
CONFIG_UCSI_HUAWEI_GAOKUN=m
CONFIG_TYPEC_TPS6598X=m
CONFIG_TYPEC_ANX7411=m
CONFIG_TYPEC_RT1719=m
CONFIG_TYPEC_HD3SS3220=m
CONFIG_TYPEC_STUSB160X=m
CONFIG_TYPEC_WUSB3801=m
#
# USB Type-C Multiplexer/DeMultiplexer Switch support
#
CONFIG_TYPEC_MUX_FSA4480=m
CONFIG_TYPEC_MUX_GPIO_SBU=m
CONFIG_TYPEC_MUX_PI3USB30532=m
CONFIG_TYPEC_MUX_INTEL_PMC=m
CONFIG_TYPEC_MUX_IT5205=m
CONFIG_TYPEC_MUX_NB7VPQ904M=m
CONFIG_TYPEC_MUX_PS883X=m
CONFIG_TYPEC_MUX_PTN36502=m
CONFIG_TYPEC_MUX_TUSB1046=m
CONFIG_TYPEC_MUX_WCD939X_USBSS=m
# end of USB Type-C Multiplexer/DeMultiplexer Switch support
#
# USB Type-C Alternate Mode drivers
#
CONFIG_TYPEC_DP_ALTMODE=m
CONFIG_TYPEC_NVIDIA_ALTMODE=m
CONFIG_TYPEC_TBT_ALTMODE=m
# end of USB Type-C Alternate Mode drivers
CONFIG_USB_ROLE_SWITCH=m
CONFIG_USB_ROLES_INTEL_XHCI=m
CONFIG_MMC=m
CONFIG_PWRSEQ_EMMC=m
CONFIG_PWRSEQ_SD8787=m
CONFIG_PWRSEQ_SIMPLE=m
CONFIG_MMC_BLOCK=m
CONFIG_MMC_BLOCK_MINORS=8
CONFIG_SDIO_UART=m
CONFIG_MMC_TEST=m
CONFIG_MMC_CRYPTO=y
#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_DEBUG=y
CONFIG_MMC_SUNPLUS=m
CONFIG_MMC_PXA=m
CONFIG_MMC_SDHCI=m
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_UHS2=m
CONFIG_MMC_SDHCI_PCI=m
CONFIG_MMC_RICOH_MMC=y
CONFIG_MMC_SDHCI_ACPI=m
CONFIG_MMC_SDHCI_PLTFM=m
CONFIG_MMC_SDHCI_OF_ARASAN=m
CONFIG_MMC_SDHCI_OF_ASPEED=m
CONFIG_MMC_SDHCI_OF_ASPEED_TEST=y
CONFIG_MMC_SDHCI_OF_AT91=m
CONFIG_MMC_SDHCI_OF_ESDHC=m
CONFIG_MMC_SDHCI_OF_DWCMSHC=m
CONFIG_MMC_SDHCI_OF_K1=m
CONFIG_MMC_SDHCI_OF_SPARX5=m
CONFIG_MMC_SDHCI_OF_MA35D1=m
CONFIG_MMC_SDHCI_CADENCE=m
CONFIG_MMC_SDHCI_ESDHC_IMX=m
CONFIG_MMC_SDHCI_DOVE=m
CONFIG_MMC_SDHCI_TEGRA=m
CONFIG_MMC_SDHCI_S3C=m
CONFIG_MMC_SDHCI_PXAV3=m
CONFIG_MMC_SDHCI_PXAV2=m
CONFIG_MMC_SDHCI_SPEAR=m
CONFIG_MMC_SDHCI_S3C_DMA=y
CONFIG_MMC_SDHCI_BCM_KONA=m
CONFIG_MMC_SDHCI_F_SDH30=m
CONFIG_MMC_SDHCI_MILBEAUT=m
CONFIG_MMC_SDHCI_IPROC=m
CONFIG_MMC_SDHCI_NPCM=m
CONFIG_MMC_MESON_GX=m
CONFIG_MMC_MESON_MX_SDHC=m
CONFIG_MMC_MESON_MX_SDIO=m
CONFIG_MMC_MOXART=m
CONFIG_MMC_SDHCI_ST=m
CONFIG_MMC_OMAP_HS=m
CONFIG_MMC_WBSD=m
CONFIG_MMC_ALCOR=m
CONFIG_MMC_SDHCI_MSM=m
CONFIG_MMC_MXC=m
CONFIG_MMC_TIFM_SD=m
CONFIG_MMC_DAVINCI=m
CONFIG_MMC_SPI=m
CONFIG_MMC_SDRICOH_CS=m
CONFIG_MMC_SDHCI_SPRD=m
CONFIG_MMC_TMIO_CORE=m
CONFIG_MMC_SDHI=m
CONFIG_MMC_SDHI_SYS_DMAC=m
CONFIG_MMC_SDHI_INTERNAL_DMAC=m
CONFIG_MMC_UNIPHIER=m
CONFIG_MMC_CB710=m
CONFIG_MMC_VIA_SDMMC=m
CONFIG_MMC_DW=m
CONFIG_MMC_DW_PLTFM=m
CONFIG_MMC_DW_BLUEFIELD=m
CONFIG_MMC_DW_EXYNOS=m
CONFIG_MMC_DW_HI3798CV200=m
CONFIG_MMC_DW_HI3798MV200=m
CONFIG_MMC_DW_K3=m
CONFIG_MMC_DW_PCI=m
CONFIG_MMC_DW_ROCKCHIP=m
CONFIG_MMC_SH_MMCIF=m
CONFIG_MMC_VUB300=m
CONFIG_MMC_USHC=m
CONFIG_MMC_WMT=m
CONFIG_MMC_USDHI6ROL0=m
CONFIG_MMC_REALTEK_PCI=m
CONFIG_MMC_REALTEK_USB=m
CONFIG_MMC_SUNXI=m
CONFIG_MMC_CQHCI=m
CONFIG_MMC_HSQ=m
CONFIG_MMC_TOSHIBA_PCI=m
CONFIG_MMC_BCM2835=m
CONFIG_MMC_MTK=m
CONFIG_MMC_SDHCI_BRCMSTB=m
CONFIG_MMC_SDHCI_XENON=m
CONFIG_MMC_SDHCI_OMAP=m
CONFIG_MMC_SDHCI_AM654=m
CONFIG_MMC_OWL=m
CONFIG_MMC_LOONGSON2=m
CONFIG_MMC_SDHCI_EXTERNAL_DMA=y
CONFIG_MMC_LITEX=m
CONFIG_SCSI_UFSHCD=m
CONFIG_SCSI_UFS_BSG=y
CONFIG_SCSI_UFS_CRYPTO=y
CONFIG_SCSI_UFS_FAULT_INJECTION=y
CONFIG_SCSI_UFS_HWMON=y
CONFIG_SCSI_UFSHCD_PCI=m
CONFIG_SCSI_UFS_DWC_TC_PCI=m
CONFIG_SCSI_UFSHCD_PLATFORM=m
CONFIG_SCSI_UFS_CDNS_PLATFORM=m
CONFIG_SCSI_UFS_DWC_TC_PLATFORM=m
CONFIG_SCSI_UFS_HISI=m
CONFIG_SCSI_UFS_RENESAS=m
CONFIG_SCSI_UFS_TI_J721E=m
CONFIG_SCSI_UFS_EXYNOS=m
CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE=y
CONFIG_SCSI_UFS_SPRD=m
CONFIG_SCSI_UFS_ROCKCHIP=m
CONFIG_SCSI_UFS_AMD_VERSAL2=m
CONFIG_MEMSTICK=m
CONFIG_MEMSTICK_DEBUG=y
#
# MemoryStick drivers
#
CONFIG_MEMSTICK_UNSAFE_RESUME=y
CONFIG_MSPRO_BLOCK=m
CONFIG_MS_BLOCK=m
#
# MemoryStick Host Controller Drivers
#
CONFIG_MEMSTICK_TIFM_MS=m
CONFIG_MEMSTICK_JMICRON_38X=m
CONFIG_MEMSTICK_R592=m
CONFIG_MEMSTICK_REALTEK_USB=m
CONFIG_LEDS_EXPRESSWIRE=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=m
CONFIG_LEDS_CLASS_FLASH=m
CONFIG_LEDS_CLASS_MULTICOLOR=m
CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y
CONFIG_LEDS_KUNIT_TEST=m
#
# LED drivers
#
CONFIG_LEDS_88PM860X=m
CONFIG_LEDS_AN30259A=m
CONFIG_LEDS_APU=m
CONFIG_LEDS_ARIEL=m
CONFIG_LEDS_OSRAM_AMS_AS3668=m
CONFIG_LEDS_AW200XX=m
CONFIG_LEDS_AW2013=m
CONFIG_LEDS_BCM6328=m
CONFIG_LEDS_BCM6358=m
CONFIG_LEDS_CPCAP=m
CONFIG_LEDS_CR0014114=m
CONFIG_LEDS_CROS_EC=m
CONFIG_LEDS_EL15203000=m
CONFIG_LEDS_TURRIS_OMNIA=m
CONFIG_LEDS_LM3530=m
CONFIG_LEDS_LM3532=m
CONFIG_LEDS_LM3533=m
CONFIG_LEDS_LM3642=m
CONFIG_LEDS_LM3692X=m
CONFIG_LEDS_MT6323=m
CONFIG_LEDS_NET48XX=m
CONFIG_LEDS_WRAP=m
CONFIG_LEDS_COBALT_QUBE=m
CONFIG_LEDS_SUN50I_A100=m
CONFIG_LEDS_PCA9532=m
CONFIG_LEDS_PCA9532_GPIO=y
CONFIG_LEDS_GPIO=m
CONFIG_LEDS_LP3944=m
CONFIG_LEDS_LP3952=m
CONFIG_LEDS_LP50XX=m
CONFIG_LEDS_LP55XX_COMMON=m
CONFIG_LEDS_LP5521=m
CONFIG_LEDS_LP5523=m
CONFIG_LEDS_LP5562=m
CONFIG_LEDS_LP5569=m
CONFIG_LEDS_LP8501=m
CONFIG_LEDS_LP8788=m
CONFIG_LEDS_LP8860=m
CONFIG_LEDS_LP8864=m
CONFIG_LEDS_PCA955X=m
CONFIG_LEDS_PCA955X_GPIO=y
CONFIG_LEDS_PCA963X=m
CONFIG_LEDS_PCA995X=m
CONFIG_LEDS_QNAP_MCU=m
CONFIG_LEDS_WM831X_STATUS=m
CONFIG_LEDS_WM8350=m
CONFIG_LEDS_DA903X=m
CONFIG_LEDS_DA9052=m
CONFIG_LEDS_DAC124S085=m
CONFIG_LEDS_PWM=m
CONFIG_LEDS_REGULATOR=m
CONFIG_LEDS_BD2606MVV=m
CONFIG_LEDS_BD2802=m
CONFIG_LEDS_INTEL_SS4200=m
CONFIG_LEDS_LT3593=m
CONFIG_LEDS_ADP5520=m
CONFIG_LEDS_MAX5970=m
CONFIG_LEDS_MC13783=m
CONFIG_LEDS_NS2=m
CONFIG_LEDS_NETXBIG=m
CONFIG_LEDS_TCA6507=m
CONFIG_LEDS_TLC591XX=m
CONFIG_LEDS_MAX77650=m
CONFIG_LEDS_MAX77705=m
CONFIG_LEDS_MAX8997=m
CONFIG_LEDS_LM355x=m
CONFIG_LEDS_OT200=m
CONFIG_LEDS_MENF21BMC=m
CONFIG_LEDS_IS31FL319X=m
CONFIG_LEDS_IS31FL32XX=m
CONFIG_LEDS_SC27XX_BLTC=m
CONFIG_LEDS_UPBOARD=m
#
# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)
#
CONFIG_LEDS_BLINKM=m
CONFIG_LEDS_BLINKM_MULTICOLOR=y
CONFIG_LEDS_PM8058=m
CONFIG_LEDS_MLXCPLD=m
CONFIG_LEDS_MLXREG=m
CONFIG_LEDS_USER=m
CONFIG_LEDS_NIC78BX=m
CONFIG_LEDS_SPI_BYTE=m
CONFIG_LEDS_TI_LMU_COMMON=m
CONFIG_LEDS_LM3697=m
CONFIG_LEDS_LM36274=m
CONFIG_LEDS_ST1202=m
CONFIG_LEDS_TPS6105X=m
CONFIG_LEDS_IP30=m
CONFIG_LEDS_ACER_A500=m
CONFIG_LEDS_BCM63138=m
CONFIG_LEDS_LGM=m
#
# Flash and Torch LED drivers
#
CONFIG_LEDS_AAT1290=m
CONFIG_LEDS_AS3645A=m
CONFIG_LEDS_KTD2692=m
CONFIG_LEDS_LM3601X=m
CONFIG_LEDS_MAX77693=m
CONFIG_LEDS_MT6360=m
CONFIG_LEDS_MT6370_FLASH=m
CONFIG_LEDS_QCOM_FLASH=m
CONFIG_LEDS_RT4505=m
CONFIG_LEDS_RT8515=m
CONFIG_LEDS_SGM3140=m
CONFIG_LEDS_SY7802=m
CONFIG_LEDS_TPS6131X=m
#
# RGB LED drivers
#
CONFIG_LEDS_GROUP_MULTICOLOR=m
CONFIG_LEDS_KTD202X=m
CONFIG_LEDS_LP5812=m
CONFIG_LEDS_NCP5623=m
CONFIG_LEDS_PWM_MULTICOLOR=m
CONFIG_LEDS_QCOM_LPG=m
CONFIG_LEDS_MT6370_RGB=m
#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_DISK=y
CONFIG_LEDS_TRIGGER_MTD=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
CONFIG_LEDS_TRIGGER_BACKLIGHT=m
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_ACTIVITY=m
CONFIG_LEDS_TRIGGER_GPIO=m
CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
#
# iptables trigger is under Netfilter config (LED target)
#
CONFIG_LEDS_TRIGGER_TRANSIENT=m
CONFIG_LEDS_TRIGGER_CAMERA=m
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_LEDS_TRIGGER_NETDEV=m
CONFIG_LEDS_TRIGGER_PATTERN=m
CONFIG_LEDS_TRIGGER_TTY=m
CONFIG_LEDS_TRIGGER_INPUT_EVENTS=m
#
# Simatic LED drivers
#
CONFIG_LEDS_SIEMENS_SIMATIC_IPC=m
CONFIG_LEDS_SIEMENS_SIMATIC_IPC_APOLLOLAKE=m
CONFIG_LEDS_SIEMENS_SIMATIC_IPC_F7188X=m
CONFIG_LEDS_SIEMENS_SIMATIC_IPC_ELKHARTLAKE=m
CONFIG_ACCESSIBILITY=y
CONFIG_A11Y_BRAILLE_CONSOLE=y
#
# Speakup console speech
#
CONFIG_SPEAKUP=m
CONFIG_SPEAKUP_SERIALIO=y
CONFIG_SPEAKUP_SYNTH_ACNTSA=m
CONFIG_SPEAKUP_SYNTH_ACNTPC=m
CONFIG_SPEAKUP_SYNTH_APOLLO=m
CONFIG_SPEAKUP_SYNTH_AUDPTR=m
CONFIG_SPEAKUP_SYNTH_BNS=m
CONFIG_SPEAKUP_SYNTH_DECTLK=m
CONFIG_SPEAKUP_SYNTH_DECEXT=m
CONFIG_SPEAKUP_SYNTH_DECPC=m
CONFIG_SPEAKUP_SYNTH_DTLK=m
CONFIG_SPEAKUP_SYNTH_KEYPC=m
CONFIG_SPEAKUP_SYNTH_LTLK=m
CONFIG_SPEAKUP_SYNTH_SOFT=m
CONFIG_SPEAKUP_SYNTH_SPKOUT=m
CONFIG_SPEAKUP_SYNTH_TXPRT=m
CONFIG_SPEAKUP_SYNTH_DUMMY=m
# end of Speakup console speech
CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_MAD=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_INFINIBAND_USER_MEM=y
CONFIG_INFINIBAND_ON_DEMAND_PAGING=y
CONFIG_INFINIBAND_ADDR_TRANS=y
CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y
CONFIG_INFINIBAND_CXGB4=m
CONFIG_INFINIBAND_IRDMA=m
CONFIG_MLX4_INFINIBAND=m
CONFIG_MLX5_INFINIBAND=m
CONFIG_INFINIBAND_MTHCA=m
CONFIG_INFINIBAND_MTHCA_DEBUG=y
CONFIG_INFINIBAND_OCRDMA=m
CONFIG_INFINIBAND_USNIC=m
CONFIG_INFINIBAND_VMWARE_PVRDMA=m
CONFIG_INFINIBAND_IPOIB=m
CONFIG_INFINIBAND_IPOIB_CM=y
CONFIG_INFINIBAND_IPOIB_DEBUG=y
CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
CONFIG_INFINIBAND_SRP=m
CONFIG_INFINIBAND_SRPT=m
CONFIG_INFINIBAND_ISER=m
CONFIG_INFINIBAND_ISERT=m
CONFIG_INFINIBAND_RTRS=m
CONFIG_INFINIBAND_RTRS_CLIENT=m
CONFIG_INFINIBAND_RTRS_SERVER=m
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EDAC=m
CONFIG_EDAC_DEBUG=y
CONFIG_EDAC_DECODE_MCE=m
CONFIG_EDAC_GHES=m
CONFIG_EDAC_SCRUB=y
CONFIG_EDAC_ECS=y
CONFIG_EDAC_MEM_REPAIR=y
CONFIG_EDAC_AMD64=m
CONFIG_EDAC_AL_MC=m
CONFIG_EDAC_AMD76X=m
CONFIG_EDAC_E7XXX=m
CONFIG_EDAC_E752X=m
CONFIG_EDAC_I82875P=m
CONFIG_EDAC_I82975X=m
CONFIG_EDAC_I3000=m
CONFIG_EDAC_I3200=m
CONFIG_EDAC_IE31200=m
CONFIG_EDAC_X38=m
CONFIG_EDAC_I5400=m
CONFIG_EDAC_I7CORE=m
CONFIG_EDAC_I82860=m
CONFIG_EDAC_I5100=m
CONFIG_EDAC_I7300=m
CONFIG_EDAC_XGENE=m
CONFIG_EDAC_ZYNQMP=m
CONFIG_EDAC_NPCM=m
CONFIG_EDAC_VERSAL=m
CONFIG_RTC_LIB=y
CONFIG_RTC_MC146818_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
CONFIG_RTC_SYSTOHC=y
CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
CONFIG_RTC_DEBUG=y
CONFIG_RTC_LIB_KUNIT_TEST=m
CONFIG_RTC_NVMEM=y
#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_INTF_DEV_UIE_EMUL=y
CONFIG_RTC_DRV_TEST=m
#
# I2C RTC drivers
#
CONFIG_RTC_DRV_88PM860X=m
CONFIG_RTC_DRV_88PM80X=m
CONFIG_RTC_DRV_88PM886=m
CONFIG_RTC_DRV_ABB5ZES3=m
CONFIG_RTC_DRV_ABEOZ9=m
CONFIG_RTC_DRV_ABX80X=m
CONFIG_RTC_DRV_BRCMSTB=m
CONFIG_RTC_DRV_AS3722=m
CONFIG_RTC_DRV_DS1307=m
CONFIG_RTC_DRV_DS1307_CENTURY=y
CONFIG_RTC_DRV_DS1374=m
CONFIG_RTC_DRV_DS1374_WDT=y
CONFIG_RTC_DRV_DS1672=m
CONFIG_RTC_DRV_HYM8563=m
CONFIG_RTC_DRV_LP8788=m
CONFIG_RTC_DRV_MAX6900=m
CONFIG_RTC_DRV_MAX8907=m
CONFIG_RTC_DRV_MAX8925=m
CONFIG_RTC_DRV_MAX8998=m
CONFIG_RTC_DRV_MAX8997=m
CONFIG_RTC_DRV_MAX31335=m
CONFIG_RTC_DRV_MAX77686=m
CONFIG_RTC_DRV_SPACEMIT_P1=m
CONFIG_RTC_DRV_NVIDIA_VRS10=m
CONFIG_RTC_DRV_NCT3018Y=m
CONFIG_RTC_DRV_NCT6694=m
CONFIG_RTC_DRV_RK808=m
CONFIG_RTC_DRV_RS5C372=m
CONFIG_RTC_DRV_ISL1208=m
CONFIG_RTC_DRV_ISL12022=m
CONFIG_RTC_DRV_ISL12026=m
CONFIG_RTC_DRV_X1205=m
CONFIG_RTC_DRV_PCF8523=m
CONFIG_RTC_DRV_PCF85363=m
CONFIG_RTC_DRV_PCF8563=m
CONFIG_RTC_DRV_PCF8583=m
CONFIG_RTC_DRV_M41T80=m
CONFIG_RTC_DRV_M41T80_WDT=y
CONFIG_RTC_DRV_BD70528=m
CONFIG_RTC_DRV_BQ32K=m
CONFIG_RTC_DRV_TWL4030=m
CONFIG_RTC_DRV_PALMAS=m
CONFIG_RTC_DRV_TPS6586X=m
CONFIG_RTC_DRV_TPS6594=m
CONFIG_RTC_DRV_TPS65910=m
CONFIG_RTC_DRV_RC5T583=m
CONFIG_RTC_DRV_RC5T619=m
CONFIG_RTC_DRV_S35390A=m
CONFIG_RTC_DRV_FM3130=m
CONFIG_RTC_DRV_RX8010=m
CONFIG_RTC_DRV_RX8111=m
CONFIG_RTC_DRV_RX8581=m
CONFIG_RTC_DRV_RX8025=m
CONFIG_RTC_DRV_EM3027=m
CONFIG_RTC_DRV_RV3028=m
CONFIG_RTC_DRV_RV3032=m
CONFIG_RTC_DRV_RV8803=m
CONFIG_RTC_DRV_S5M=m
CONFIG_RTC_DRV_SD2405AL=m
CONFIG_RTC_DRV_SD3078=m
#
# SPI RTC drivers
#
CONFIG_RTC_DRV_M41T93=m
CONFIG_RTC_DRV_M41T94=m
CONFIG_RTC_DRV_DS1302=m
CONFIG_RTC_DRV_DS1305=m
CONFIG_RTC_DRV_DS1343=m
CONFIG_RTC_DRV_DS1347=m
CONFIG_RTC_DRV_DS1390=m
CONFIG_RTC_DRV_MAX6916=m
CONFIG_RTC_DRV_R9701=m
CONFIG_RTC_DRV_RX4581=m
CONFIG_RTC_DRV_RS5C348=m
CONFIG_RTC_DRV_MAX6902=m
CONFIG_RTC_DRV_PCF2123=m
CONFIG_RTC_DRV_MCP795=m
CONFIG_RTC_I2C_AND_SPI=y
#
# SPI and I2C RTC drivers
#
CONFIG_RTC_DRV_DS3232=m
CONFIG_RTC_DRV_DS3232_HWMON=y
CONFIG_RTC_DRV_PCF2127=m
CONFIG_RTC_DRV_PCF85063=m
CONFIG_RTC_DRV_RV3029C2=m
CONFIG_RTC_DRV_RV3029_HWMON=y
CONFIG_RTC_DRV_RX6110=m
#
# Platform RTC drivers
#
CONFIG_RTC_DRV_CMOS=m
CONFIG_RTC_DRV_ATCRTC100=m
CONFIG_RTC_DRV_DS1286=m
CONFIG_RTC_DRV_DS1511=m
CONFIG_RTC_DRV_DS1553=m
CONFIG_RTC_DRV_DS1685_FAMILY=m
CONFIG_RTC_DRV_DS1685=y
# CONFIG_RTC_DRV_DS1689 is not set
# CONFIG_RTC_DRV_DS17285 is not set
# CONFIG_RTC_DRV_DS17485 is not set
# CONFIG_RTC_DRV_DS17885 is not set
CONFIG_RTC_DRV_DS1742=m
CONFIG_RTC_DRV_DS2404=m
CONFIG_RTC_DRV_DA9052=m
CONFIG_RTC_DRV_DA9055=m
CONFIG_RTC_DRV_DA9063=m
CONFIG_RTC_DRV_STK17TA8=m
CONFIG_RTC_DRV_M48T86=m
CONFIG_RTC_DRV_M48T35=m
CONFIG_RTC_DRV_M48T59=m
CONFIG_RTC_DRV_MSM6242=m
CONFIG_RTC_DRV_BQ4802=m
CONFIG_RTC_DRV_RP5C01=m
CONFIG_RTC_DRV_GAMECUBE=m
CONFIG_RTC_DRV_WM831X=m
CONFIG_RTC_DRV_WM8350=m
CONFIG_RTC_DRV_SC27XX=m
CONFIG_RTC_DRV_SPEAR=m
CONFIG_RTC_DRV_ZYNQMP=m
CONFIG_RTC_DRV_CROS_EC=m
CONFIG_RTC_DRV_NTXEC=m
#
# on-CPU RTC drivers
#
CONFIG_RTC_DRV_ASM9260=m
CONFIG_RTC_DRV_CV1800=m
CONFIG_RTC_DRV_DIGICOLOR=m
CONFIG_RTC_DRV_IMXDI=m
CONFIG_RTC_DRV_FSL_FTM_ALARM=m
CONFIG_RTC_DRV_MESON=m
CONFIG_RTC_DRV_MESON_VRTC=m
CONFIG_RTC_DRV_OMAP=m
CONFIG_RTC_DRV_S3C=m
CONFIG_RTC_DRV_EP93XX=m
CONFIG_RTC_DRV_AT91RM9200=m
CONFIG_RTC_DRV_AT91SAM9=m
CONFIG_RTC_DRV_RZN1=m
CONFIG_RTC_DRV_GENERIC=m
CONFIG_RTC_DRV_VT8500=m
CONFIG_RTC_DRV_SUN6I=y
CONFIG_RTC_DRV_SUNXI=m
CONFIG_RTC_DRV_MV=m
CONFIG_RTC_DRV_ARMADA38X=m
CONFIG_RTC_DRV_CADENCE=m
CONFIG_RTC_DRV_FTRTC010=m
CONFIG_RTC_DRV_STMP=m
CONFIG_RTC_DRV_PCAP=m
CONFIG_RTC_DRV_MC13XXX=m
CONFIG_RTC_DRV_JZ4740=m
CONFIG_RTC_DRV_LOONGSON=m
CONFIG_RTC_DRV_LPC24XX=m
CONFIG_RTC_DRV_LPC32XX=m
CONFIG_RTC_DRV_PM8XXX=m
CONFIG_RTC_DRV_TEGRA=m
CONFIG_RTC_DRV_MXC=m
CONFIG_RTC_DRV_MXC_V2=m
CONFIG_RTC_DRV_SNVS=m
CONFIG_RTC_DRV_BBNSM=m
CONFIG_RTC_DRV_IMX_BBM_SCMI=m
CONFIG_RTC_DRV_MOXART=m
CONFIG_RTC_DRV_MT2712=m
CONFIG_RTC_DRV_MT6397=m
CONFIG_RTC_DRV_MT7622=m
CONFIG_RTC_DRV_XGENE=m
CONFIG_RTC_DRV_R7301=m
CONFIG_RTC_DRV_STM32=m
CONFIG_RTC_DRV_CPCAP=m
CONFIG_RTC_DRV_RTD119X=y
CONFIG_RTC_DRV_ASPEED=m
CONFIG_RTC_DRV_TI_K3=m
CONFIG_RTC_DRV_MA35D1=m
CONFIG_RTC_DRV_GOLDFISH=m
CONFIG_RTC_DRV_WILCO_EC=m
CONFIG_RTC_DRV_MSC313=m
CONFIG_RTC_DRV_SSD202D=m
CONFIG_RTC_DRV_AMLOGIC_A4=m
CONFIG_RTC_DRV_S32G=m
#
# HID Sensor RTC drivers
#
CONFIG_RTC_DRV_HID_SENSOR_TIME=m
CONFIG_DMADEVICES=y
CONFIG_DMADEVICES_DEBUG=y
CONFIG_DMADEVICES_VDEBUG=y
#
# DMA Devices
#
CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_DMA_ACPI=y
CONFIG_DMA_OF=y
CONFIG_ALTERA_MSGDMA=m
CONFIG_APPLE_ADMAC=m
CONFIG_ARM_DMA350=m
CONFIG_AT_HDMAC=m
CONFIG_AXI_DMAC=m
CONFIG_BCM_SBA_RAID=m
CONFIG_DMA_BCM2835=m
CONFIG_DMA_JZ4780=m
CONFIG_DMA_SA11X0=m
CONFIG_DMA_SUN6I=m
CONFIG_DW_AXI_DMAC=m
CONFIG_EP93XX_DMA=y
CONFIG_FSL_EDMA=m
CONFIG_HISI_DMA=m
CONFIG_IMG_MDC_DMA=m
CONFIG_INTEL_IDMA64=m
CONFIG_K3_DMA=m
CONFIG_LOONGSON1_APB_DMA=m
CONFIG_LOONGSON2_APB_DMA=m
CONFIG_MILBEAUT_HDMAC=m
CONFIG_MILBEAUT_XDMAC=m
CONFIG_MMP_PDMA=m
CONFIG_MMP_TDMA=m
CONFIG_MV_XOR=y
# CONFIG_MXS_DMA is not set
CONFIG_NBPFAXI_DMA=m
CONFIG_PCH_DMA=m
CONFIG_PXA_DMA=y
CONFIG_PLX_DMA=m
CONFIG_SOPHGO_CV1800B_DMAMUX=m
CONFIG_ST_FDMA=m
CONFIG_SPRD_DMA=m
CONFIG_TEGRA186_GPC_DMA=m
CONFIG_TEGRA20_APB_DMA=m
CONFIG_TEGRA210_ADMA=m
CONFIG_TIMB_DMA=m
CONFIG_UNIPHIER_MDMAC=m
CONFIG_UNIPHIER_XDMAC=m
CONFIG_XGENE_DMA=m
CONFIG_XILINX_DMA=m
CONFIG_XILINX_XDMA=m
CONFIG_XILINX_ZYNQMP_DMA=m
CONFIG_XILINX_ZYNQMP_DPDMA=m
CONFIG_AMD_QDMA=m
CONFIG_MTK_HSDMA=m
CONFIG_MTK_CQDMA=m
CONFIG_MTK_UART_APDMA=m
CONFIG_QCOM_HIDMA_MGMT=m
CONFIG_QCOM_HIDMA=m
CONFIG_DW_DMAC_CORE=m
CONFIG_DW_DMAC=m
CONFIG_RZN1_DMAMUX=m
CONFIG_DW_DMAC_PCI=m
CONFIG_DW_EDMA=m
CONFIG_DW_EDMA_PCIE=m
CONFIG_HSU_DMA=m
CONFIG_HSU_DMA_PCI=m
CONFIG_SF_PDMA=m
CONFIG_RENESAS_DMA=y
CONFIG_SH_DMAE_BASE=y
CONFIG_SH_DMAE=m
CONFIG_RCAR_DMAC=m
CONFIG_RENESAS_USB_DMAC=m
CONFIG_RZ_DMAC=m
CONFIG_TI_EDMA=m
CONFIG_DMA_OMAP=m
CONFIG_TI_DMA_CROSSBAR=y
CONFIG_INTEL_LDMA=y
CONFIG_STM32_DMA=y
CONFIG_STM32_DMAMUX=y
CONFIG_STM32_MDMA=y
CONFIG_STM32_DMA3=m
#
# DMA Clients
#
CONFIG_ASYNC_TX_DMA=y
CONFIG_DMATEST=m
CONFIG_DMA_ENGINE_RAID=y
#
# DMABUF options
#
CONFIG_SYNC_FILE=y
CONFIG_SW_SYNC=y
CONFIG_UDMABUF=y
# CONFIG_DMABUF_MOVE_NOTIFY is not set
CONFIG_DMABUF_DEBUG=y
CONFIG_DMABUF_SELFTESTS=m
CONFIG_DMABUF_HEAPS=y
CONFIG_DMABUF_HEAPS_SYSTEM=y
CONFIG_DMABUF_HEAPS_CMA=y
# end of DMABUF options
CONFIG_UIO=m
CONFIG_UIO_CIF=m
CONFIG_UIO_PDRV_GENIRQ=m
CONFIG_UIO_DMEM_GENIRQ=m
CONFIG_UIO_AEC=m
CONFIG_UIO_SERCOS3=m
CONFIG_UIO_PCI_GENERIC=m
CONFIG_UIO_NETX=m
CONFIG_UIO_MF624=m
CONFIG_UIO_HV_GENERIC=m
CONFIG_UIO_DFL=m
CONFIG_VFIO=m
CONFIG_VFIO_DEVICE_CDEV=y
CONFIG_VFIO_GROUP=y
CONFIG_VFIO_CONTAINER=y
CONFIG_VFIO_IOMMU_TYPE1=m
CONFIG_VFIO_NOIOMMU=y
CONFIG_VFIO_VIRQFD=y
CONFIG_VFIO_DEBUGFS=y
#
# VFIO support for PCI devices
#
CONFIG_VFIO_PCI_CORE=m
CONFIG_VFIO_PCI_INTX=y
CONFIG_VFIO_PCI=m
CONFIG_VFIO_PCI_VGA=y
CONFIG_VFIO_PCI_IGD=y
CONFIG_MLX5_VFIO_PCI=m
CONFIG_VIRTIO_VFIO_PCI=m
CONFIG_VIRTIO_VFIO_PCI_ADMIN_LEGACY=y
CONFIG_QAT_VFIO_PCI=m
CONFIG_XE_VFIO_PCI=m
# end of VFIO support for PCI devices
#
# VFIO support for platform devices
#
CONFIG_VFIO_PLATFORM_BASE=m
CONFIG_VFIO_PLATFORM=m
CONFIG_VFIO_AMBA=m
#
# VFIO platform reset drivers
#
CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET=m
CONFIG_VFIO_PLATFORM_AMDXGBE_RESET=m
CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET=m
# end of VFIO platform reset drivers
# end of VFIO support for platform devices
CONFIG_VFIO_MDEV=m
#
# VFIO support for FSL_MC bus devices
#
CONFIG_VFIO_FSL_MC=m
# end of VFIO support for FSL_MC bus devices
CONFIG_VFIO_CDX=m
CONFIG_IRQ_BYPASS_MANAGER=m
CONFIG_VIRT_DRIVERS=y
CONFIG_VMGENID=m
CONFIG_VBOXGUEST=m
CONFIG_NITRO_ENCLAVES=m
CONFIG_TSM_GUEST=y
CONFIG_TSM_MEASUREMENTS=y
CONFIG_TSM=y
CONFIG_VIRTIO_ANCHOR=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_PCI_LIB=m
CONFIG_VIRTIO_PCI_LIB_LEGACY=m
CONFIG_VIRTIO_MENU=y
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_PCI_ADMIN_LEGACY=y
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTIO_VDPA=m
CONFIG_VIRTIO_PMEM=m
CONFIG_VIRTIO_BALLOON=m
CONFIG_VIRTIO_INPUT=m
CONFIG_VIRTIO_MMIO=m
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
CONFIG_VIRTIO_DMA_SHARED_BUFFER=m
CONFIG_VIRTIO_DEBUG=y
CONFIG_VIRTIO_RTC=m
CONFIG_VIRTIO_RTC_PTP=y
CONFIG_VIRTIO_RTC_CLASS=y
CONFIG_VDPA=m
CONFIG_VDPA_SIM=m
CONFIG_VDPA_SIM_NET=m
CONFIG_VDPA_SIM_BLOCK=m
CONFIG_VDPA_USER=m
CONFIG_IFCVF=m
CONFIG_MLX5_VDPA=y
CONFIG_MLX5_VDPA_NET=m
CONFIG_MLX5_VDPA_STEERING_DEBUG=y
CONFIG_VP_VDPA=m
CONFIG_ALIBABA_ENI_VDPA=m
CONFIG_SNET_VDPA=m
CONFIG_OCTEONEP_VDPA=m
CONFIG_VHOST_IOTLB=m
CONFIG_VHOST_RING=m
CONFIG_VHOST_TASK=y
CONFIG_VHOST=m
CONFIG_VHOST_MENU=y
CONFIG_VHOST_NET=m
CONFIG_VHOST_SCSI=m
CONFIG_VHOST_VSOCK=m
CONFIG_VHOST_VDPA=m
CONFIG_VHOST_CROSS_ENDIAN_LEGACY=y
CONFIG_VHOST_ENABLE_FORK_OWNER_CONTROL=y
#
# Microsoft Hyper-V guest support
#
CONFIG_HYPERV=y
CONFIG_HYPERV_TIMER=y
CONFIG_HYPERV_UTILS=m
CONFIG_HYPERV_BALLOON=m
CONFIG_HYPERV_VMBUS=m
# end of Microsoft Hyper-V guest support
#
# Xen driver support
#
CONFIG_XEN_BALLOON=y
CONFIG_XEN_SCRUB_PAGES_DEFAULT=y
CONFIG_XEN_DEV_EVTCHN=m
CONFIG_XEN_BACKEND=y
CONFIG_XENFS=m
CONFIG_XEN_COMPAT_XENFS=y
CONFIG_XEN_SYS_HYPERVISOR=y
CONFIG_XEN_XENBUS_FRONTEND=y
CONFIG_XEN_GNTDEV=m
CONFIG_XEN_GNTDEV_DMABUF=y
CONFIG_XEN_GRANT_DEV_ALLOC=m
CONFIG_XEN_GRANT_DMA_ALLOC=y
CONFIG_XEN_PCI_STUB=y
CONFIG_XEN_PCIDEV_BACKEND=m
CONFIG_XEN_PVCALLS_FRONTEND=m
CONFIG_XEN_PVCALLS_BACKEND=m
CONFIG_XEN_SCSI_BACKEND=m
CONFIG_XEN_PRIVCMD=m
CONFIG_XEN_PRIVCMD_EVENTFD=y
CONFIG_XEN_AUTO_XLATE=y
CONFIG_XEN_ACPI=y
CONFIG_XEN_FRONT_PGDIR_SHBUF=m
CONFIG_XEN_GRANT_DMA_IOMMU=y
CONFIG_XEN_GRANT_DMA_OPS=y
CONFIG_XEN_VIRTIO=y
CONFIG_XEN_VIRTIO_FORCE_GRANT=y
# end of Xen driver support
CONFIG_GREYBUS=m
CONFIG_GREYBUS_BEAGLEPLAY=m
CONFIG_GREYBUS_ES2=m
CONFIG_COMEDI=m
CONFIG_COMEDI_DEBUG=y
CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB=2048
CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB=20480
CONFIG_COMEDI_MISC_DRIVERS=y
CONFIG_COMEDI_BOND=m
CONFIG_COMEDI_TEST=m
CONFIG_COMEDI_PARPORT=m
CONFIG_COMEDI_SSV_DNP=m
CONFIG_COMEDI_ISA_DRIVERS=y
CONFIG_COMEDI_PCL711=m
CONFIG_COMEDI_PCL724=m
CONFIG_COMEDI_PCL726=m
CONFIG_COMEDI_PCL730=m
CONFIG_COMEDI_PCL812=m
CONFIG_COMEDI_PCL816=m
CONFIG_COMEDI_PCL818=m
CONFIG_COMEDI_PCM3724=m
CONFIG_COMEDI_AMPLC_DIO200_ISA=m
CONFIG_COMEDI_AMPLC_PC236_ISA=m
CONFIG_COMEDI_AMPLC_PC263_ISA=m
CONFIG_COMEDI_RTI800=m
CONFIG_COMEDI_RTI802=m
CONFIG_COMEDI_DAC02=m
CONFIG_COMEDI_DAS16M1=m
CONFIG_COMEDI_DAS08_ISA=m
CONFIG_COMEDI_DAS16=m
CONFIG_COMEDI_DAS800=m
CONFIG_COMEDI_DAS1800=m
CONFIG_COMEDI_DAS6402=m
CONFIG_COMEDI_DT2801=m
CONFIG_COMEDI_DT2811=m
CONFIG_COMEDI_DT2814=m
CONFIG_COMEDI_DT2815=m
CONFIG_COMEDI_DT2817=m
CONFIG_COMEDI_DT282X=m
CONFIG_COMEDI_DMM32AT=m
CONFIG_COMEDI_FL512=m
CONFIG_COMEDI_AIO_AIO12_8=m
CONFIG_COMEDI_AIO_IIRO_16=m
CONFIG_COMEDI_II_PCI20KC=m
CONFIG_COMEDI_C6XDIGIO=m
CONFIG_COMEDI_MPC624=m
CONFIG_COMEDI_ADQ12B=m
CONFIG_COMEDI_NI_AT_A2150=m
CONFIG_COMEDI_NI_AT_AO=m
CONFIG_COMEDI_NI_ATMIO=m
CONFIG_COMEDI_NI_ATMIO16D=m
CONFIG_COMEDI_NI_LABPC_ISA=m
CONFIG_COMEDI_PCMAD=m
CONFIG_COMEDI_PCMDA12=m
CONFIG_COMEDI_PCMMIO=m
CONFIG_COMEDI_PCMUIO=m
CONFIG_COMEDI_MULTIQ3=m
CONFIG_COMEDI_S526=m
CONFIG_COMEDI_PCI_DRIVERS=m
CONFIG_COMEDI_8255_PCI=m
CONFIG_COMEDI_ADDI_WATCHDOG=m
CONFIG_COMEDI_ADDI_APCI_1032=m
CONFIG_COMEDI_ADDI_APCI_1500=m
CONFIG_COMEDI_ADDI_APCI_1516=m
CONFIG_COMEDI_ADDI_APCI_1564=m
CONFIG_COMEDI_ADDI_APCI_16XX=m
CONFIG_COMEDI_ADDI_APCI_2032=m
CONFIG_COMEDI_ADDI_APCI_2200=m
CONFIG_COMEDI_ADDI_APCI_3120=m
CONFIG_COMEDI_ADDI_APCI_3501=m
CONFIG_COMEDI_ADDI_APCI_3XXX=m
CONFIG_COMEDI_ADL_PCI6208=m
CONFIG_COMEDI_ADL_PCI7250=m
CONFIG_COMEDI_ADL_PCI7X3X=m
CONFIG_COMEDI_ADL_PCI8164=m
CONFIG_COMEDI_ADL_PCI9111=m
CONFIG_COMEDI_ADL_PCI9118=m
CONFIG_COMEDI_ADV_PCI1710=m
CONFIG_COMEDI_ADV_PCI1720=m
CONFIG_COMEDI_ADV_PCI1723=m
CONFIG_COMEDI_ADV_PCI1724=m
CONFIG_COMEDI_ADV_PCI1760=m
CONFIG_COMEDI_ADV_PCI_DIO=m
CONFIG_COMEDI_AMPLC_DIO200_PCI=m
CONFIG_COMEDI_AMPLC_PC236_PCI=m
CONFIG_COMEDI_AMPLC_PC263_PCI=m
CONFIG_COMEDI_AMPLC_PCI224=m
CONFIG_COMEDI_AMPLC_PCI230=m
CONFIG_COMEDI_CONTEC_PCI_DIO=m
CONFIG_COMEDI_DAS08_PCI=m
CONFIG_COMEDI_DT3000=m
CONFIG_COMEDI_DYNA_PCI10XX=m
CONFIG_COMEDI_GSC_HPDI=m
CONFIG_COMEDI_MF6X4=m
CONFIG_COMEDI_ICP_MULTI=m
CONFIG_COMEDI_DAQBOARD2000=m
CONFIG_COMEDI_JR3_PCI=m
CONFIG_COMEDI_KE_COUNTER=m
CONFIG_COMEDI_CB_PCIDAS64=m
CONFIG_COMEDI_CB_PCIDAS=m
CONFIG_COMEDI_CB_PCIDDA=m
CONFIG_COMEDI_CB_PCIMDAS=m
CONFIG_COMEDI_CB_PCIMDDA=m
CONFIG_COMEDI_ME4000=m
CONFIG_COMEDI_ME_DAQ=m
CONFIG_COMEDI_NI_6527=m
CONFIG_COMEDI_NI_65XX=m
CONFIG_COMEDI_NI_660X=m
CONFIG_COMEDI_NI_670X=m
CONFIG_COMEDI_NI_LABPC_PCI=m
CONFIG_COMEDI_NI_PCIDIO=m
CONFIG_COMEDI_NI_PCIMIO=m
CONFIG_COMEDI_RTD520=m
CONFIG_COMEDI_S626=m
CONFIG_COMEDI_MITE=m
CONFIG_COMEDI_NI_TIOCMD=m
CONFIG_COMEDI_PCMCIA_DRIVERS=m
CONFIG_COMEDI_CB_DAS16_CS=m
CONFIG_COMEDI_DAS08_CS=m
CONFIG_COMEDI_NI_DAQ_700_CS=m
CONFIG_COMEDI_NI_DAQ_DIO24_CS=m
CONFIG_COMEDI_NI_LABPC_CS=m
CONFIG_COMEDI_NI_MIO_CS=m
CONFIG_COMEDI_QUATECH_DAQP_CS=m
CONFIG_COMEDI_USB_DRIVERS=m
CONFIG_COMEDI_DT9812=m
CONFIG_COMEDI_NI_USB6501=m
CONFIG_COMEDI_USBDUX=m
CONFIG_COMEDI_USBDUXFAST=m
CONFIG_COMEDI_USBDUXSIGMA=m
CONFIG_COMEDI_VMK80XX=m
CONFIG_COMEDI_8254=m
CONFIG_COMEDI_8255=m
CONFIG_COMEDI_8255_SA=m
CONFIG_COMEDI_KCOMEDILIB=m
CONFIG_COMEDI_AMPLC_DIO200=m
CONFIG_COMEDI_AMPLC_PC236=m
CONFIG_COMEDI_DAS08=m
CONFIG_COMEDI_ISADMA=m
CONFIG_COMEDI_NI_LABPC=m
CONFIG_COMEDI_NI_LABPC_ISADMA=m
CONFIG_COMEDI_NI_TIO=m
CONFIG_COMEDI_NI_ROUTING=m
CONFIG_COMEDI_TESTS=m
CONFIG_COMEDI_TESTS_EXAMPLE=m
CONFIG_COMEDI_TESTS_NI_ROUTES=m
CONFIG_GPIB=m
CONFIG_GPIB_COMMON=m
CONFIG_GPIB_AGILENT_82350B=m
CONFIG_GPIB_AGILENT_82357A=m
CONFIG_GPIB_CEC_PCI=m
CONFIG_GPIB_NI_PCI_ISA=m
CONFIG_GPIB_CB7210=m
CONFIG_GPIB_NI_USB=m
CONFIG_GPIB_FLUKE=m
CONFIG_GPIB_FMH=m
CONFIG_GPIB_GPIO=m
CONFIG_GPIB_HP82335=m
CONFIG_GPIB_HP82341=m
CONFIG_GPIB_INES=m
CONFIG_GPIB_PCMCIA=y
CONFIG_GPIB_LPVO=m
CONFIG_GPIB_PC2=m
CONFIG_GPIB_TMS9914=m
CONFIG_GPIB_NEC7210=m
CONFIG_STAGING=y
CONFIG_RTL8723BS=m
CONFIG_OCTEON_ETHERNET=m
#
# IIO staging drivers
#
#
# Accelerometers
#
CONFIG_ADIS16203=m
# end of Accelerometers
#
# Analog to digital converters
#
CONFIG_AD7816=m
# end of Analog to digital converters
#
# Analog digital bi-direction converters
#
CONFIG_ADT7316=m
CONFIG_ADT7316_SPI=m
CONFIG_ADT7316_I2C=m
# end of Analog digital bi-direction converters
#
# Direct Digital Synthesis
#
CONFIG_AD9832=m
CONFIG_AD9834=m
# end of Direct Digital Synthesis
#
# Network Analyzer, Impedance Converters
#
CONFIG_AD5933=m
# end of Network Analyzer, Impedance Converters
# end of IIO staging drivers
CONFIG_FB_SM750=m
CONFIG_STAGING_MEDIA=y
CONFIG_INTEL_ATOMISP=y
CONFIG_VIDEO_ATOMISP=m
CONFIG_VIDEO_ATOMISP_OV2722=m
CONFIG_VIDEO_ATOMISP_GC2235=m
CONFIG_DVB_AV7110_IR=y
CONFIG_DVB_AV7110=m
CONFIG_DVB_AV7110_OSD=y
CONFIG_DVB_SP8870=m
CONFIG_VIDEO_IMX_MEDIA=m
CONFIG_VIDEO_IPU3_IMGU=m
CONFIG_VIDEO_INTEL_IPU7=m
CONFIG_VIDEO_MAX96712=m
CONFIG_VIDEO_MESON_VDEC=m
CONFIG_VIDEO_SUNXI=y
CONFIG_VIDEO_SUNXI_CEDRUS=m
CONFIG_VIDEO_SUN6I_ISP=m
CONFIG_VIDEO_TEGRA=m
CONFIG_STAGING_MEDIA_DEPRECATED=y
#
# Atmel media platform drivers
#
CONFIG_VIDEO_ATMEL_ISC=m
CONFIG_VIDEO_ATMEL_XISC=m
CONFIG_VIDEO_ATMEL_ISC_BASE=m
CONFIG_FB_TFT=m
CONFIG_FB_TFT_AGM1264K_FL=m
CONFIG_FB_TFT_BD663474=m
CONFIG_FB_TFT_HX8340BN=m
CONFIG_FB_TFT_HX8347D=m
CONFIG_FB_TFT_HX8353D=m
CONFIG_FB_TFT_HX8357D=m
CONFIG_FB_TFT_ILI9163=m
CONFIG_FB_TFT_ILI9320=m
CONFIG_FB_TFT_ILI9325=m
CONFIG_FB_TFT_ILI9340=m
CONFIG_FB_TFT_ILI9341=m
CONFIG_FB_TFT_ILI9481=m
CONFIG_FB_TFT_ILI9486=m
CONFIG_FB_TFT_PCD8544=m
CONFIG_FB_TFT_RA8875=m
CONFIG_FB_TFT_S6D02A1=m
CONFIG_FB_TFT_S6D1121=m
CONFIG_FB_TFT_SEPS525=m
CONFIG_FB_TFT_SH1106=m
CONFIG_FB_TFT_SSD1289=m
CONFIG_FB_TFT_SSD1305=m
CONFIG_FB_TFT_SSD1306=m
CONFIG_FB_TFT_SSD1331=m
CONFIG_FB_TFT_SSD1351=m
CONFIG_FB_TFT_ST7735R=m
CONFIG_FB_TFT_ST7789V=m
CONFIG_FB_TFT_TINYLCD=m
CONFIG_FB_TFT_TLS8204=m
CONFIG_FB_TFT_UC1611=m
CONFIG_FB_TFT_UC1701=m
CONFIG_FB_TFT_UPD161704=m
CONFIG_MOST_COMPONENTS=m
CONFIG_MOST_NET=m
CONFIG_MOST_VIDEO=m
CONFIG_MOST_DIM2=m
CONFIG_GREYBUS_AUDIO=m
CONFIG_GREYBUS_AUDIO_APB_CODEC=m
CONFIG_GREYBUS_BOOTROM=m
CONFIG_GREYBUS_FIRMWARE=m
CONFIG_GREYBUS_HID=m
CONFIG_GREYBUS_LIGHT=m
CONFIG_GREYBUS_LOG=m
CONFIG_GREYBUS_LOOPBACK=m
CONFIG_GREYBUS_POWER=m
CONFIG_GREYBUS_RAW=m
CONFIG_GREYBUS_VIBRATOR=m
CONFIG_GREYBUS_BRIDGED_PHY=m
CONFIG_GREYBUS_GPIO=m
CONFIG_GREYBUS_I2C=m
CONFIG_GREYBUS_PWM=m
CONFIG_GREYBUS_SDIO=m
CONFIG_GREYBUS_SPI=m
CONFIG_GREYBUS_UART=m
CONFIG_GREYBUS_USB=m
CONFIG_GREYBUS_ARCHE=m
CONFIG_SND_BCM2835=m
CONFIG_XIL_AXIS_FIFO=m
CONFIG_VME_BUS=y
#
# VME Bridge Drivers
#
CONFIG_VME_TSI148=m
CONFIG_VME_FAKE=m
#
# VME Device Drivers
#
CONFIG_VME_USER=m
CONFIG_GOLDFISH=y
CONFIG_GOLDFISH_PIPE=m
CONFIG_CHROME_PLATFORMS=y
CONFIG_CHROMEOS_ACPI=m
CONFIG_CHROMEOS_LAPTOP=m
CONFIG_CHROMEOS_PSTORE=m
CONFIG_CHROMEOS_TBMC=m
CONFIG_CHROMEOS_OF_HW_PROBER=m
CONFIG_CROS_EC=m
CONFIG_CROS_EC_I2C=m
CONFIG_CROS_EC_RPMSG=m
CONFIG_CROS_EC_ISHTP=m
CONFIG_CROS_EC_SPI=m
CONFIG_CROS_EC_UART=m
CONFIG_CROS_EC_LPC=m
CONFIG_CROS_EC_PROTO=m
CONFIG_CROS_KBD_LED_BACKLIGHT=m
CONFIG_CROS_EC_CHARDEV=m
CONFIG_CROS_EC_LIGHTBAR=m
CONFIG_CROS_EC_VBC=m
CONFIG_CROS_EC_DEBUGFS=m
CONFIG_CROS_EC_SENSORHUB=m
CONFIG_CROS_EC_SYSFS=m
CONFIG_CROS_EC_TYPEC_ALTMODES=y
CONFIG_CROS_EC_TYPEC=m
CONFIG_CROS_HPS_I2C=m
CONFIG_CROS_USBPD_LOGGER=m
CONFIG_CROS_USBPD_NOTIFY=m
CONFIG_CHROMEOS_PRIVACY_SCREEN=m
CONFIG_CROS_TYPEC_SWITCH=m
CONFIG_WILCO_EC=m
CONFIG_WILCO_EC_DEBUGFS=m
CONFIG_WILCO_EC_EVENTS=m
CONFIG_WILCO_EC_TELEMETRY=m
CONFIG_CROS_KUNIT_EC_PROTO_TEST=m
CONFIG_CZNIC_PLATFORMS=y
CONFIG_TURRIS_OMNIA_MCU=m
CONFIG_TURRIS_OMNIA_MCU_GPIO=y
CONFIG_TURRIS_OMNIA_MCU_SYSOFF_WAKEUP=y
CONFIG_TURRIS_OMNIA_MCU_WATCHDOG=y
CONFIG_TURRIS_OMNIA_MCU_TRNG=y
CONFIG_TURRIS_OMNIA_MCU_KEYCTL=y
CONFIG_TURRIS_SIGNING_KEY=m
CONFIG_MELLANOX_PLATFORM=y
CONFIG_MLX_PLATFORM=m
CONFIG_MLXREG_DPU=m
CONFIG_MLXREG_HOTPLUG=m
CONFIG_MLXREG_IO=m
CONFIG_MLXREG_LC=m
CONFIG_NVSW_SN2201=m
CONFIG_OLPC_EC=y
CONFIG_OLPC_XO175=y
CONFIG_OLPC_XO175_EC=m
CONFIG_SURFACE_PLATFORMS=y
CONFIG_SURFACE3_WMI=m
CONFIG_SURFACE_3_POWER_OPREGION=m
CONFIG_SURFACE_ACPI_NOTIFY=m
CONFIG_SURFACE_AGGREGATOR_CDEV=m
CONFIG_SURFACE_AGGREGATOR_HUB=m
CONFIG_SURFACE_AGGREGATOR_REGISTRY=m
CONFIG_SURFACE_AGGREGATOR_TABLET_SWITCH=m
CONFIG_SURFACE_DTX=m
CONFIG_SURFACE_GPE=m
CONFIG_SURFACE_HOTPLUG=m
CONFIG_SURFACE_PLATFORM_PROFILE=m
CONFIG_SURFACE_PRO3_BUTTON=m
CONFIG_SURFACE_AGGREGATOR=m
CONFIG_SURFACE_AGGREGATOR_BUS=y
CONFIG_SURFACE_AGGREGATOR_ERROR_INJECTION=y
CONFIG_X86_PLATFORM_DEVICES=y
CONFIG_WMI_BMOF=m
CONFIG_HUAWEI_WMI=m
CONFIG_X86_PLATFORM_DRIVERS_UNIWILL=y
CONFIG_UNIWILL_LAPTOP=m
CONFIG_MXM_WMI=m
CONFIG_NVIDIA_WMI_EC_BACKLIGHT=m
CONFIG_XIAOMI_WMI=m
CONFIG_REDMI_WMI=m
CONFIG_GIGABYTE_WMI=m
CONFIG_ACERHDF=m
CONFIG_ACER_WIRELESS=m
CONFIG_ACER_WMI=m
CONFIG_AMD_HSMP=m
#
# AMD HSMP Driver
#
CONFIG_AMD_HSMP_ACPI=m
CONFIG_AMD_HSMP_PLAT=m
# end of AMD HSMP Driver
CONFIG_AMD_PMC=m
CONFIG_AMD_MP2_STB=y
CONFIG_AMD_HFI=y
CONFIG_AMD_WBRF=y
CONFIG_ADV_SWBUTTON=m
CONFIG_APPLE_GMUX=m
CONFIG_ASUS_LAPTOP=m
CONFIG_ASUS_WIRELESS=m
CONFIG_ASUS_ARMOURY=m
CONFIG_ASUS_WMI=m
CONFIG_ASUS_WMI_DEPRECATED_ATTRS=y
CONFIG_ASUS_NB_WMI=m
CONFIG_ASUS_TF103C_DOCK=m
CONFIG_AYANEO_EC=m
CONFIG_MERAKI_MX100=m
CONFIG_EEEPC_LAPTOP=m
CONFIG_EEEPC_WMI=m
CONFIG_X86_PLATFORM_DRIVERS_DELL=y
CONFIG_ALIENWARE_WMI=m
CONFIG_ALIENWARE_WMI_LEGACY=y
CONFIG_ALIENWARE_WMI_WMAX=y
CONFIG_DCDBAS=m
CONFIG_DELL_LAPTOP=m
CONFIG_DELL_RBU=m
CONFIG_DELL_RBTN=m
CONFIG_DELL_PC=m
CONFIG_DELL_SMBIOS=m
CONFIG_DELL_SMBIOS_WMI=y
CONFIG_DELL_SMBIOS_SMM=y
CONFIG_DELL_SMO8800=m
CONFIG_DELL_UART_BACKLIGHT=m
CONFIG_DELL_WMI=m
CONFIG_DELL_WMI_PRIVACY=y
CONFIG_DELL_WMI_AIO=m
CONFIG_DELL_WMI_DESCRIPTOR=m
CONFIG_DELL_WMI_DDV=m
CONFIG_DELL_WMI_LED=m
CONFIG_DELL_WMI_SYSMAN=m
CONFIG_AMILO_RFKILL=m
CONFIG_FUJITSU_LAPTOP=m
CONFIG_FUJITSU_TABLET=m
CONFIG_GPD_POCKET_FAN=m
CONFIG_X86_PLATFORM_DRIVERS_HP=y
CONFIG_HP_ACCEL=m
CONFIG_HP_WMI=m
CONFIG_TC1100_WMI=m
CONFIG_HP_BIOSCFG=m
CONFIG_WIRELESS_HOTKEY=m
CONFIG_IBM_RTL=m
CONFIG_SENSORS_HDAPS=m
CONFIG_INTEL_ATOMISP2_PDX86=y
CONFIG_INTEL_ATOMISP2_LED=m
CONFIG_INTEL_SAR_INT1092=m
CONFIG_INTEL_SKL_INT3472=m
CONFIG_INTEL_PMC_CORE=m
CONFIG_INTEL_PMC_SSRAM_TELEMETRY=m
CONFIG_INTEL_PMT_CLASS=m
CONFIG_INTEL_PMT_TELEMETRY=m
CONFIG_INTEL_PMT_CRASHLOG=m
CONFIG_INTEL_PMT_DISCOVERY=m
CONFIG_INTEL_PMT_KUNIT_TEST=m
#
# Intel Speed Select Technology interface support
#
CONFIG_INTEL_SPEED_SELECT_INTERFACE=m
# end of Intel Speed Select Technology interface support
CONFIG_INTEL_WMI=y
CONFIG_INTEL_WMI_SBL_FW_UPDATE=m
CONFIG_INTEL_WMI_THUNDERBOLT=m
#
# Intel Uncore Frequency Control
#
# end of Intel Uncore Frequency Control
CONFIG_INTEL_HID_EVENT=m
CONFIG_INTEL_VBTN=m
CONFIG_INTEL_EHL_PSE_IO=m
CONFIG_INTEL_INT0002_VGPIO=m
CONFIG_INTEL_OAKTRAIL=m
CONFIG_INTEL_BXTWC_PMIC_TMU=m
CONFIG_INTEL_BYTCRC_PWRSRC=m
CONFIG_INTEL_CHTWC_INT33FE=m
CONFIG_INTEL_ISHTP_ECLITE=m
CONFIG_INTEL_MRFLD_PWRBTN=m
CONFIG_INTEL_PUNIT_IPC=m
CONFIG_INTEL_RST=m
CONFIG_INTEL_SMARTCONNECT=m
CONFIG_INTEL_VSEC=m
CONFIG_IDEAPAD_LAPTOP=m
CONFIG_LENOVO_WMI_HOTKEY_UTILITIES=m
CONFIG_LENOVO_WMI_CAMERA=m
CONFIG_LENOVO_YMC=m
CONFIG_THINKPAD_ACPI=m
CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y
CONFIG_THINKPAD_ACPI_DEBUGFACILITIES=y
CONFIG_THINKPAD_ACPI_DEBUG=y
CONFIG_THINKPAD_ACPI_UNSAFE_LEDS=y
CONFIG_THINKPAD_ACPI_VIDEO=y
CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y
CONFIG_THINKPAD_LMI=m
CONFIG_YOGABOOK=m
CONFIG_YT2_1380=m
CONFIG_LENOVO_WMI_CAPDATA=m
CONFIG_LENOVO_WMI_EVENTS=m
CONFIG_LENOVO_WMI_HELPERS=m
CONFIG_LENOVO_WMI_GAMEZONE=m
CONFIG_LENOVO_WMI_TUNING=m
CONFIG_ACPI_QUICKSTART=m
CONFIG_MEEGOPAD_ANX7428=m
CONFIG_MSI_EC=m
CONFIG_MSI_LAPTOP=m
CONFIG_MSI_WMI=m
CONFIG_MSI_WMI_PLATFORM=m
CONFIG_XO15_EBOOK=m
CONFIG_XO1_RFKILL=m
CONFIG_PCENGINES_APU2=m
CONFIG_PORTWELL_EC=m
CONFIG_BARCO_P50_GPIO=m
CONFIG_SAMSUNG_GALAXYBOOK=m
CONFIG_SAMSUNG_LAPTOP=m
CONFIG_SAMSUNG_Q10=m
CONFIG_ACPI_TOSHIBA=m
CONFIG_TOSHIBA_BT_RFKILL=m
CONFIG_TOSHIBA_HAPS=m
CONFIG_TOSHIBA_WMI=m
CONFIG_ACPI_CMPC=m
CONFIG_COMPAL_LAPTOP=m
CONFIG_LG_LAPTOP=m
CONFIG_PANASONIC_LAPTOP=m
CONFIG_SONY_LAPTOP=m
CONFIG_SONYPI_COMPAT=y
CONFIG_SYSTEM76_ACPI=m
CONFIG_TOPSTAR_LAPTOP=m
CONFIG_SERIAL_MULTI_INSTANTIATE=m
CONFIG_TOUCHSCREEN_DMI=y
CONFIG_INSPUR_PLATFORM_PROFILE=m
CONFIG_DASHARO_ACPI=m
CONFIG_X86_ANDROID_TABLETS=m
CONFIG_FW_ATTR_CLASS=m
CONFIG_INTEL_IMR=y
CONFIG_INTEL_IPS=m
CONFIG_INTEL_SCU_IPC=y
CONFIG_INTEL_SCU=y
CONFIG_INTEL_SCU_PCI=y
CONFIG_INTEL_SCU_PLATFORM=m
CONFIG_INTEL_SCU_WDT=y
CONFIG_INTEL_SCU_IPC_UTIL=m
CONFIG_SIEMENS_SIMATIC_IPC=m
CONFIG_SIEMENS_SIMATIC_IPC_BATT=m
CONFIG_SIEMENS_SIMATIC_IPC_BATT_APOLLOLAKE=m
CONFIG_SIEMENS_SIMATIC_IPC_BATT_ELKHARTLAKE=m
CONFIG_SIEMENS_SIMATIC_IPC_BATT_F7188X=m
CONFIG_SILICOM_PLATFORM=m
CONFIG_WINMATE_FM07_KEYS=m
CONFIG_SEL3350_PLATFORM=m
CONFIG_OXP_EC=m
CONFIG_TUXEDO_NB04_WMI_AB=m
CONFIG_P2SB=y
CONFIG_ARM64_PLATFORM_DEVICES=y
CONFIG_EC_ACER_ASPIRE1=m
CONFIG_EC_HUAWEI_GAOKUN=m
CONFIG_EC_LENOVO_YOGA_C630=m
CONFIG_EC_LENOVO_THINKPAD_T14S=m
CONFIG_BCM_VIDEOCORE=m
CONFIG_BCM2835_VCHIQ=m
CONFIG_VCHIQ_CDEV=y
CONFIG_BCM2835_VCHIQ_MMAL=m
CONFIG_ACPI_WMI=m
CONFIG_ACPI_WMI_LEGACY_DEVICE_NAMES=y
CONFIG_ACPI_WMI_MARSHALLING_KUNIT_TEST=m
CONFIG_ACPI_WMI_STRING_KUNIT_TEST=m
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_WM831X=m
#
# Clock driver for ARM Reference designs
#
CONFIG_CLK_ICST=y
CONFIG_CLK_SP810=y
# end of Clock driver for ARM Reference designs
CONFIG_CLK_HSDK=y
CONFIG_LMK04832=m
CONFIG_COMMON_CLK_APPLE_NCO=m
CONFIG_COMMON_CLK_MAX77686=m
CONFIG_COMMON_CLK_MAX9485=m
CONFIG_COMMON_CLK_RK808=m
CONFIG_COMMON_CLK_RP1=m
CONFIG_COMMON_CLK_HI655X=m
CONFIG_COMMON_CLK_SCMI=m
CONFIG_COMMON_CLK_SCPI=m
CONFIG_COMMON_CLK_SI5341=m
CONFIG_COMMON_CLK_SI5351=m
CONFIG_COMMON_CLK_SI514=m
CONFIG_COMMON_CLK_SI544=m
CONFIG_COMMON_CLK_SI570=m
CONFIG_COMMON_CLK_BM1880=y
CONFIG_COMMON_CLK_CDCE706=m
CONFIG_COMMON_CLK_TPS68470=m
CONFIG_COMMON_CLK_CDCE925=m
CONFIG_COMMON_CLK_CS2000_CP=m
CONFIG_COMMON_CLK_EN7523=y
CONFIG_COMMON_CLK_EP93XX=m
CONFIG_COMMON_CLK_EYEQ=y
CONFIG_COMMON_CLK_FSL_FLEXSPI=m
CONFIG_COMMON_CLK_FSL_SAI=y
CONFIG_COMMON_CLK_GEMINI=y
CONFIG_COMMON_CLK_LAN966X=m
CONFIG_COMMON_CLK_S2MPS11=m
CONFIG_CLK_TWL=m
CONFIG_CLK_TWL6040=m
CONFIG_COMMON_CLK_AXI_CLKGEN=m
CONFIG_CLK_QORIQ=y
CONFIG_CLK_LS1028A_PLLDIG=m
CONFIG_COMMON_CLK_XGENE=y
CONFIG_COMMON_CLK_LOCHNAGAR=m
CONFIG_COMMON_CLK_NPCM8XX=m
CONFIG_COMMON_CLK_LOONGSON2=y
CONFIG_COMMON_CLK_PALMAS=m
CONFIG_COMMON_CLK_PWM=m
CONFIG_COMMON_CLK_RS9_PCIE=m
CONFIG_COMMON_CLK_SI521XX=m
CONFIG_COMMON_CLK_VC3=m
CONFIG_COMMON_CLK_VC5=m
CONFIG_COMMON_CLK_VC7=m
CONFIG_COMMON_CLK_MMP2_AUDIO=m
CONFIG_COMMON_CLK_BD718XX=m
CONFIG_COMMON_CLK_FIXED_MMIO=y
CONFIG_COMMON_CLK_SP7021=m
CONFIG_COMMON_CLK_RPMI=m
CONFIG_CLK_ACTIONS=y
CONFIG_CLK_OWL_S500=y
CONFIG_CLK_OWL_S700=y
CONFIG_CLK_OWL_S900=y
CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=m
CONFIG_COMMON_CLK_ASPEED=y
CONFIG_COMMON_CLK_AST2700=y
# CONFIG_CLK_BAIKAL_T1 is not set
CONFIG_CLK_BCM2711_DVP=m
CONFIG_CLK_BCM2835=y
CONFIG_CLK_BCM_63XX=y
CONFIG_CLK_BCM_63XX_GATE=y
CONFIG_CLK_BCM63268_TIMER=y
CONFIG_CLK_BCM_KONA=y
CONFIG_COMMON_CLK_IPROC=y
CONFIG_CLK_BCM_CYGNUS=y
CONFIG_CLK_BCM_HR2=y
CONFIG_CLK_BCM_NSP=y
CONFIG_CLK_BCM_NS2=y
CONFIG_CLK_BCM_SR=y
CONFIG_CLK_RASPBERRYPI=m
CONFIG_COMMON_CLK_HI3516CV300=m
CONFIG_COMMON_CLK_HI3519=m
CONFIG_COMMON_CLK_HI3559A=y
CONFIG_COMMON_CLK_HI3660=y
CONFIG_COMMON_CLK_HI3670=y
CONFIG_COMMON_CLK_HI3798CV200=m
CONFIG_COMMON_CLK_HI6220=y
CONFIG_RESET_HISI=y
CONFIG_STUB_CLK_HI6220=y
CONFIG_STUB_CLK_HI3660=y
CONFIG_COMMON_CLK_BOSTON=y
CONFIG_MXC_CLK=m
CONFIG_CLK_IMX8MM=m
CONFIG_CLK_IMX8MN=m
CONFIG_CLK_IMX8MP=m
CONFIG_CLK_IMX8MQ=m
CONFIG_CLK_IMX8ULP=m
CONFIG_CLK_IMX93=m
CONFIG_CLK_IMX95_BLK_CTL=m
CONFIG_CLK_IMXRT1050=m
#
# Ingenic SoCs drivers
#
CONFIG_INGENIC_CGU_COMMON=y
CONFIG_INGENIC_CGU_JZ4740=y
CONFIG_INGENIC_CGU_JZ4755=y
CONFIG_INGENIC_CGU_JZ4725B=y
CONFIG_INGENIC_CGU_JZ4760=y
CONFIG_INGENIC_CGU_JZ4770=y
CONFIG_INGENIC_CGU_JZ4780=y
CONFIG_INGENIC_CGU_X1000=y
CONFIG_INGENIC_CGU_X1830=y
CONFIG_INGENIC_TCU_CLK=y
# end of Ingenic SoCs drivers
CONFIG_COMMON_CLK_KEYSTONE=m
CONFIG_TI_SCI_CLK=m
CONFIG_TI_SCI_CLK_PROBE_FROM_FW=y
CONFIG_TI_SYSCON_CLK=m
#
# Clock driver for MediaTek SoC
#
CONFIG_COMMON_CLK_MEDIATEK=y
CONFIG_COMMON_CLK_MEDIATEK_FHCTL=y
CONFIG_COMMON_CLK_MT2701=y
CONFIG_COMMON_CLK_MT2701_MMSYS=y
CONFIG_COMMON_CLK_MT2701_IMGSYS=y
CONFIG_COMMON_CLK_MT2701_VDECSYS=y
CONFIG_COMMON_CLK_MT2701_HIFSYS=y
CONFIG_COMMON_CLK_MT2701_ETHSYS=y
CONFIG_COMMON_CLK_MT2701_BDPSYS=y
CONFIG_COMMON_CLK_MT2701_AUDSYS=y
CONFIG_COMMON_CLK_MT2701_G3DSYS=y
CONFIG_COMMON_CLK_MT2712=m
CONFIG_COMMON_CLK_MT2712_BDPSYS=m
CONFIG_COMMON_CLK_MT2712_IMGSYS=m
CONFIG_COMMON_CLK_MT2712_JPGDECSYS=m
CONFIG_COMMON_CLK_MT2712_MFGCFG=m
CONFIG_COMMON_CLK_MT2712_MMSYS=m
CONFIG_COMMON_CLK_MT2712_VDECSYS=m
CONFIG_COMMON_CLK_MT2712_VENCSYS=m
CONFIG_COMMON_CLK_MT6735=m
CONFIG_COMMON_CLK_MT6735_IMGSYS=m
CONFIG_COMMON_CLK_MT6735_MFGCFG=m
CONFIG_COMMON_CLK_MT6735_VDECSYS=m
CONFIG_COMMON_CLK_MT6735_VENCSYS=m
CONFIG_COMMON_CLK_MT6765=y
CONFIG_COMMON_CLK_MT6765_AUDIOSYS=m
CONFIG_COMMON_CLK_MT6765_CAMSYS=m
CONFIG_COMMON_CLK_MT6765_GCESYS=m
CONFIG_COMMON_CLK_MT6765_MMSYS=m
CONFIG_COMMON_CLK_MT6765_IMGSYS=m
CONFIG_COMMON_CLK_MT6765_VCODECSYS=m
CONFIG_COMMON_CLK_MT6765_MFGSYS=m
CONFIG_COMMON_CLK_MT6765_MIPI0ASYS=m
CONFIG_COMMON_CLK_MT6765_MIPI0BSYS=m
CONFIG_COMMON_CLK_MT6765_MIPI1ASYS=m
CONFIG_COMMON_CLK_MT6765_MIPI1BSYS=m
CONFIG_COMMON_CLK_MT6765_MIPI2ASYS=m
CONFIG_COMMON_CLK_MT6765_MIPI2BSYS=m
CONFIG_COMMON_CLK_MT6779=m
CONFIG_COMMON_CLK_MT6779_MMSYS=m
CONFIG_COMMON_CLK_MT6779_IMGSYS=m
CONFIG_COMMON_CLK_MT6779_IPESYS=m
CONFIG_COMMON_CLK_MT6779_CAMSYS=m
CONFIG_COMMON_CLK_MT6779_VDECSYS=m
CONFIG_COMMON_CLK_MT6779_VENCSYS=m
CONFIG_COMMON_CLK_MT6779_MFGCFG=m
CONFIG_COMMON_CLK_MT6779_AUDSYS=m
CONFIG_COMMON_CLK_MT6795=m
CONFIG_COMMON_CLK_MT6795_MFGCFG=m
CONFIG_COMMON_CLK_MT6795_MMSYS=m
CONFIG_COMMON_CLK_MT6795_VDECSYS=m
CONFIG_COMMON_CLK_MT6795_VENCSYS=m
CONFIG_COMMON_CLK_MT6797=y
CONFIG_COMMON_CLK_MT6797_MMSYS=m
CONFIG_COMMON_CLK_MT6797_IMGSYS=m
CONFIG_COMMON_CLK_MT6797_VDECSYS=m
CONFIG_COMMON_CLK_MT6797_VENCSYS=m
CONFIG_COMMON_CLK_MT7622=m
CONFIG_COMMON_CLK_MT7622_ETHSYS=m
CONFIG_COMMON_CLK_MT7622_HIFSYS=m
CONFIG_COMMON_CLK_MT7622_AUDSYS=m
CONFIG_COMMON_CLK_MT7629=y
CONFIG_COMMON_CLK_MT7629_ETHSYS=y
CONFIG_COMMON_CLK_MT7629_HIFSYS=y
CONFIG_COMMON_CLK_MT7981=y
CONFIG_COMMON_CLK_MT7981_ETHSYS=m
CONFIG_COMMON_CLK_MT7986=m
CONFIG_COMMON_CLK_MT7986_ETHSYS=m
CONFIG_COMMON_CLK_MT7988=m
CONFIG_COMMON_CLK_MT8135=m
CONFIG_COMMON_CLK_MT8167=m
CONFIG_COMMON_CLK_MT8167_AUDSYS=m
CONFIG_COMMON_CLK_MT8167_IMGSYS=m
CONFIG_COMMON_CLK_MT8167_MFGCFG=m
CONFIG_COMMON_CLK_MT8167_MMSYS=m
CONFIG_COMMON_CLK_MT8167_VDECSYS=m
CONFIG_COMMON_CLK_MT8173=m
CONFIG_COMMON_CLK_MT8173_IMGSYS=m
CONFIG_COMMON_CLK_MT8173_MMSYS=m
CONFIG_COMMON_CLK_MT8173_VDECSYS=m
CONFIG_COMMON_CLK_MT8173_VENCSYS=m
CONFIG_COMMON_CLK_MT8183=m
CONFIG_COMMON_CLK_MT8183_AUDIOSYS=m
CONFIG_COMMON_CLK_MT8183_CAMSYS=m
CONFIG_COMMON_CLK_MT8183_IMGSYS=m
CONFIG_COMMON_CLK_MT8183_IPU_CORE0=m
CONFIG_COMMON_CLK_MT8183_IPU_CORE1=m
CONFIG_COMMON_CLK_MT8183_IPU_ADL=m
CONFIG_COMMON_CLK_MT8183_IPU_CONN=m
CONFIG_COMMON_CLK_MT8183_MFGCFG=m
CONFIG_COMMON_CLK_MT8183_MMSYS=m
CONFIG_COMMON_CLK_MT8183_VDECSYS=m
CONFIG_COMMON_CLK_MT8183_VENCSYS=m
CONFIG_COMMON_CLK_MT8186=m
CONFIG_COMMON_CLK_MT8186_CAMSYS=m
CONFIG_COMMON_CLK_MT8186_IMGSYS=m
CONFIG_COMMON_CLK_MT8186_IPESYS=m
CONFIG_COMMON_CLK_MT8186_WPESYS=m
CONFIG_COMMON_CLK_MT8186_IMP_IIC_WRAP=m
CONFIG_COMMON_CLK_MT8186_MCUSYS=m
CONFIG_COMMON_CLK_MT8186_MDPSYS=m
CONFIG_COMMON_CLK_MT8186_MFGCFG=m
CONFIG_COMMON_CLK_MT8186_MMSYS=m
CONFIG_COMMON_CLK_MT8186_VDECSYS=m
CONFIG_COMMON_CLK_MT8186_VENCSYS=m
CONFIG_COMMON_CLK_MT8188=m
CONFIG_COMMON_CLK_MT8188_ADSP_AUDIO26M=m
CONFIG_COMMON_CLK_MT8188_CAMSYS=m
CONFIG_COMMON_CLK_MT8188_IMGSYS=m
CONFIG_COMMON_CLK_MT8188_IMP_IIC_WRAP=m
CONFIG_COMMON_CLK_MT8188_IPESYS=m
CONFIG_COMMON_CLK_MT8188_MFGCFG=m
CONFIG_COMMON_CLK_MT8188_VDECSYS=m
CONFIG_COMMON_CLK_MT8188_VDOSYS=m
CONFIG_COMMON_CLK_MT8188_VENCSYS=m
CONFIG_COMMON_CLK_MT8188_VPPSYS=m
CONFIG_COMMON_CLK_MT8188_WPESYS=m
CONFIG_COMMON_CLK_MT8192=m
CONFIG_COMMON_CLK_MT8192_AUDSYS=m
CONFIG_COMMON_CLK_MT8192_CAMSYS=m
CONFIG_COMMON_CLK_MT8192_IMGSYS=m
CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP=m
CONFIG_COMMON_CLK_MT8192_IPESYS=m
CONFIG_COMMON_CLK_MT8192_MDPSYS=m
CONFIG_COMMON_CLK_MT8192_MFGCFG=m
CONFIG_COMMON_CLK_MT8192_MMSYS=m
CONFIG_COMMON_CLK_MT8192_MSDC=m
CONFIG_COMMON_CLK_MT8192_SCP_ADSP=m
CONFIG_COMMON_CLK_MT8192_VDECSYS=m
CONFIG_COMMON_CLK_MT8192_VENCSYS=m
CONFIG_COMMON_CLK_MT8195=y
CONFIG_COMMON_CLK_MT8195_APUSYS=m
CONFIG_COMMON_CLK_MT8195_IMP_IIC_WRAP=m
CONFIG_COMMON_CLK_MT8195_MFGCFG=m
CONFIG_COMMON_CLK_MT8195_SCP_ADSP=m
CONFIG_COMMON_CLK_MT8195_VDOSYS=m
CONFIG_COMMON_CLK_MT8195_VPPSYS=m
CONFIG_COMMON_CLK_MT8195_CAMSYS=m
CONFIG_COMMON_CLK_MT8195_IMGSYS=m
CONFIG_COMMON_CLK_MT8195_IPESYS=m
CONFIG_COMMON_CLK_MT8195_WPESYS=m
CONFIG_COMMON_CLK_MT8195_VDECSYS=m
CONFIG_COMMON_CLK_MT8195_VENCSYS=m
CONFIG_COMMON_CLK_MT8196=m
CONFIG_COMMON_CLK_MT8196_IMP_IIC_WRAP=m
CONFIG_COMMON_CLK_MT8196_MCUSYS=m
CONFIG_COMMON_CLK_MT8196_MDPSYS=m
CONFIG_COMMON_CLK_MT8196_MFGCFG=m
CONFIG_COMMON_CLK_MT8196_MMSYS=m
CONFIG_COMMON_CLK_MT8196_PEXTPSYS=m
CONFIG_COMMON_CLK_MT8196_UFSSYS=m
CONFIG_COMMON_CLK_MT8196_VDECSYS=m
CONFIG_COMMON_CLK_MT8196_VENCSYS=m
CONFIG_COMMON_CLK_MT8365=m
CONFIG_COMMON_CLK_MT8365_APU=m
CONFIG_COMMON_CLK_MT8365_CAM=m
CONFIG_COMMON_CLK_MT8365_MFG=m
CONFIG_COMMON_CLK_MT8365_MMSYS=m
CONFIG_COMMON_CLK_MT8365_VDEC=m
CONFIG_COMMON_CLK_MT8365_VENC=m
CONFIG_COMMON_CLK_MT8516=m
CONFIG_COMMON_CLK_MT8516_AUDSYS=m
# end of Clock driver for MediaTek SoC
CONFIG_COMMON_CLK_PXA1908=y
#
# Clock support for Amlogic platforms
#
# CONFIG_COMMON_CLK_AXG_AUDIO is not set
# end of Clock support for Amlogic platforms
CONFIG_MSTAR_MSC313_CPUPLL=y
CONFIG_MSTAR_MSC313_MPLL=y
CONFIG_MCHP_CLK_MPFS=y
CONFIG_ARMADA_AP_CP_HELPER=y
CONFIG_ARMADA_AP_CPU_CLK=y
CONFIG_COMMON_CLK_NUVOTON=y
CONFIG_CLK_MA35D1=y
CONFIG_COMMON_CLK_PISTACHIO=y
CONFIG_QCOM_GDSC=y
CONFIG_COMMON_CLK_QCOM=m
CONFIG_CLK_GLYMUR_DISPCC=m
CONFIG_CLK_GLYMUR_GCC=m
CONFIG_CLK_GLYMUR_TCSRCC=m
CONFIG_CLK_KAANAPALI_CAMCC=m
CONFIG_CLK_KAANAPALI_DISPCC=m
CONFIG_CLK_KAANAPALI_GCC=m
CONFIG_CLK_KAANAPALI_GPUCC=m
CONFIG_CLK_KAANAPALI_TCSRCC=m
CONFIG_CLK_KAANAPALI_VIDEOCC=m
CONFIG_CLK_X1E80100_CAMCC=m
CONFIG_CLK_X1E80100_DISPCC=m
CONFIG_CLK_X1E80100_GCC=m
CONFIG_CLK_X1E80100_GPUCC=m
CONFIG_CLK_X1E80100_TCSRCC=m
CONFIG_CLK_X1P42100_GPUCC=m
CONFIG_CLK_QCM2290_GPUCC=m
CONFIG_QCOM_A53PLL=m
CONFIG_QCOM_A7PLL=m
CONFIG_QCOM_CLK_APCS_MSM8916=m
CONFIG_QCOM_CLK_APCS_SDX55=m
CONFIG_QCOM_CLK_SMD_RPM=m
CONFIG_QCOM_CLK_RPMH=m
CONFIG_APQ_GCC_8084=m
CONFIG_APQ_MMCC_8084=m
CONFIG_IPQ_APSS_PLL=m
CONFIG_IPQ_APSS_5424=m
CONFIG_IPQ_APSS_6018=m
CONFIG_IPQ_CMN_PLL=m
CONFIG_IPQ_GCC_4019=m
CONFIG_IPQ_GCC_5018=m
CONFIG_IPQ_GCC_5332=m
CONFIG_IPQ_GCC_5424=m
CONFIG_IPQ_GCC_6018=m
CONFIG_IPQ_GCC_806X=m
CONFIG_IPQ_LCC_806X=m
CONFIG_IPQ_GCC_8074=m
CONFIG_IPQ_GCC_9574=m
CONFIG_IPQ_NSSCC_5424=m
CONFIG_IPQ_NSSCC_9574=m
CONFIG_IPQ_NSSCC_QCA8K=m
CONFIG_MSM_GCC_8660=m
CONFIG_MSM_GCC_8909=m
CONFIG_MSM_GCC_8916=m
CONFIG_MSM_GCC_8917=m
CONFIG_MSM_GCC_8939=m
CONFIG_MSM_GCC_8960=m
CONFIG_MSM_LCC_8960=m
CONFIG_MDM_GCC_9607=m
CONFIG_MDM_GCC_9615=m
CONFIG_MSM_MMCC_8960=m
CONFIG_MSM_GCC_8953=m
CONFIG_MSM_GCC_8974=m
CONFIG_MSM_MMCC_8974=m
CONFIG_MSM_GCC_8976=m
CONFIG_MSM_MMCC_8994=m
CONFIG_MSM_GCC_8994=m
CONFIG_MSM_GCC_8996=m
CONFIG_MSM_MMCC_8996=m
CONFIG_MSM_GCC_8998=m
CONFIG_MSM_GPUCC_8998=m
CONFIG_MSM_MMCC_8998=m
CONFIG_QCM_GCC_2290=m
CONFIG_QCM_DISPCC_2290=m
CONFIG_QCS_DISPCC_615=m
CONFIG_QCS_CAMCC_615=m
CONFIG_QCS_GCC_404=m
CONFIG_SA_CAMCC_8775P=m
CONFIG_QCS_GCC_8300=m
CONFIG_QCS_GCC_615=m
CONFIG_QCS_GPUCC_615=m
CONFIG_QCS_VIDEOCC_615=m
CONFIG_SC_CAMCC_7180=m
CONFIG_SC_CAMCC_7280=m
CONFIG_SC_CAMCC_8180X=m
CONFIG_SC_CAMCC_8280XP=m
CONFIG_SA_DISPCC_8775P=m
CONFIG_SC_DISPCC_7180=m
CONFIG_SC_DISPCC_7280=m
CONFIG_SC_DISPCC_8280XP=m
CONFIG_SA_GCC_8775P=m
CONFIG_SA_GPUCC_8775P=m
CONFIG_SAR_GCC_2130P=m
CONFIG_SAR_GPUCC_2130P=m
CONFIG_SC_GCC_7180=m
CONFIG_SC_GCC_7280=m
CONFIG_SC_GCC_8180X=m
CONFIG_SC_GCC_8280XP=m
CONFIG_SC_GPUCC_7180=m
CONFIG_SC_GPUCC_7280=m
CONFIG_SC_GPUCC_8280XP=m
CONFIG_SC_LPASSCC_7280=m
CONFIG_SC_LPASSCC_8280XP=m
CONFIG_SC_LPASS_CORECC_7180=m
CONFIG_SC_LPASS_CORECC_7280=m
CONFIG_SC_VIDEOCC_7180=m
CONFIG_SC_VIDEOCC_7280=m
CONFIG_SDM_CAMCC_845=m
CONFIG_SDM_GCC_660=m
CONFIG_SDM_MMCC_660=m
CONFIG_SDM_GPUCC_660=m
CONFIG_QCS_TURING_404=m
CONFIG_QCS_Q6SSTOP_404=m
CONFIG_QDU_GCC_1000=m
CONFIG_QDU_ECPRICC_1000=m
CONFIG_SDM_GCC_845=m
CONFIG_SDM_GPUCC_845=m
CONFIG_SDM_VIDEOCC_845=m
CONFIG_SDM_DISPCC_845=m
CONFIG_SDM_LPASSCC_845=m
CONFIG_SDX_GCC_55=m
CONFIG_SDX_GCC_65=m
CONFIG_SDX_GCC_75=m
CONFIG_SM_CAMCC_4450=m
CONFIG_SM_CAMCC_6350=m
CONFIG_SM_CAMCC_7150=m
CONFIG_SM_CAMCC_MILOS=m
CONFIG_SM_CAMCC_8150=m
CONFIG_SM_CAMCC_8250=m
CONFIG_SM_CAMCC_8450=m
CONFIG_SM_CAMCC_8550=m
CONFIG_SM_CAMCC_8650=m
CONFIG_SM_CAMCC_8750=m
CONFIG_SM_DISPCC_4450=m
CONFIG_SM_DISPCC_6115=m
CONFIG_SM_DISPCC_6125=m
CONFIG_SM_DISPCC_7150=m
CONFIG_SM_DISPCC_8250=m
CONFIG_SM_DISPCC_6350=m
CONFIG_SM_DISPCC_6375=m
CONFIG_SM_DISPCC_MILOS=m
CONFIG_SM_DISPCC_8450=m
CONFIG_SM_DISPCC_8550=m
CONFIG_SM_DISPCC_8750=m
CONFIG_SM_GCC_4450=m
CONFIG_SM_GCC_6115=m
CONFIG_SM_GCC_6125=m
CONFIG_SM_GCC_6350=m
CONFIG_SM_GCC_6375=m
CONFIG_SM_GCC_7150=m
CONFIG_SM_GCC_MILOS=m
CONFIG_SM_GCC_8150=m
CONFIG_SM_GCC_8250=m
CONFIG_SM_GCC_8350=m
CONFIG_SM_GCC_8450=m
CONFIG_SM_GCC_8550=m
CONFIG_SM_GCC_8650=m
CONFIG_SM_GCC_8750=m
CONFIG_SM_GPUCC_4450=m
CONFIG_SM_GPUCC_6115=m
CONFIG_SM_GPUCC_6125=m
CONFIG_SM_GPUCC_6375=m
CONFIG_SM_GPUCC_6350=m
CONFIG_SM_GPUCC_MILOS=m
CONFIG_SM_GPUCC_8150=m
CONFIG_SM_GPUCC_8250=m
CONFIG_SM_GPUCC_8350=m
CONFIG_SM_GPUCC_8450=m
CONFIG_SM_GPUCC_8550=m
CONFIG_SM_GPUCC_8650=m
CONFIG_SM_LPASSCC_6115=m
CONFIG_SM_TCSRCC_8550=m
CONFIG_SM_TCSRCC_8650=m
CONFIG_SM_TCSRCC_8750=m
CONFIG_SA_VIDEOCC_8775P=m
CONFIG_SM_VIDEOCC_6350=m
CONFIG_SM_VIDEOCC_7150=m
CONFIG_SM_VIDEOCC_MILOS=m
CONFIG_SM_VIDEOCC_8150=m
CONFIG_SM_VIDEOCC_8250=m
CONFIG_SM_VIDEOCC_8350=m
CONFIG_SM_VIDEOCC_8550=m
CONFIG_SM_VIDEOCC_8750=m
CONFIG_SPMI_PMIC_CLKDIV=m
CONFIG_QCOM_HFPLL=m
CONFIG_KPSS_XCC=m
CONFIG_CLK_GFM_LPASS_SM8250=m
CONFIG_SM_VIDEOCC_8450=m
CONFIG_CLK_MT7621=y
CONFIG_CLK_MTMIPS=y
CONFIG_CLK_RENESAS=y
CONFIG_CLK_EMEV2=y
CONFIG_CLK_RZA1=y
CONFIG_CLK_R7S9210=y
CONFIG_CLK_R8A73A4=y
CONFIG_CLK_R8A7740=y
CONFIG_CLK_R8A7742=y
CONFIG_CLK_R8A7743=y
CONFIG_CLK_R8A7745=y
CONFIG_CLK_R8A77470=y
CONFIG_CLK_R8A774A1=y
CONFIG_CLK_R8A774B1=y
CONFIG_CLK_R8A774C0=y
CONFIG_CLK_R8A774E1=y
CONFIG_CLK_R8A7778=y
CONFIG_CLK_R8A7779=y
CONFIG_CLK_R8A7790=y
CONFIG_CLK_R8A7791=y
CONFIG_CLK_R8A7792=y
CONFIG_CLK_R8A7794=y
CONFIG_CLK_R8A7795=y
CONFIG_CLK_R8A77960=y
CONFIG_CLK_R8A77961=y
CONFIG_CLK_R8A77965=y
CONFIG_CLK_R8A77970=y
CONFIG_CLK_R8A77980=y
CONFIG_CLK_R8A77990=y
CONFIG_CLK_R8A77995=y
CONFIG_CLK_R8A779A0=y
CONFIG_CLK_R8A779F0=y
CONFIG_CLK_R8A779G0=y
CONFIG_CLK_R8A779H0=y
CONFIG_CLK_R9A06G032=y
CONFIG_CLK_R9A07G043=y
CONFIG_CLK_R9A07G044=y
CONFIG_CLK_R9A07G054=y
CONFIG_CLK_R9A08G045=y
CONFIG_CLK_R9A09G011=y
CONFIG_CLK_R9A09G047=y
CONFIG_CLK_R9A09G056=y
CONFIG_CLK_R9A09G057=y
CONFIG_CLK_R9A09G077=y
CONFIG_CLK_R9A09G087=y
CONFIG_CLK_SH73A0=y
CONFIG_CLK_RCAR_CPG_LIB=y
CONFIG_CLK_RCAR_GEN2_CPG=y
CONFIG_CLK_RCAR_GEN3_CPG=y
CONFIG_CLK_RCAR_GEN4_CPG=y
CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
CONFIG_CLK_RZG2L=y
CONFIG_CLK_RZV2H=y
CONFIG_CLK_RENESAS_VBATTB=m
CONFIG_CLK_RENESAS_CPG_MSSR=y
CONFIG_CLK_RENESAS_CPG_MSTP=y
CONFIG_CLK_RENESAS_DIV6=y
CONFIG_COMMON_CLK_SAMSUNG=y
CONFIG_S3C64XX_COMMON_CLK=y
CONFIG_S5PV210_COMMON_CLK=y
CONFIG_EXYNOS_3250_COMMON_CLK=y
CONFIG_EXYNOS_4_COMMON_CLK=y
CONFIG_EXYNOS_5250_COMMON_CLK=y
CONFIG_EXYNOS_5260_COMMON_CLK=y
CONFIG_EXYNOS_5410_COMMON_CLK=y
CONFIG_EXYNOS_5420_COMMON_CLK=y
CONFIG_EXYNOS_ARM64_COMMON_CLK=y
CONFIG_EXYNOS_AUDSS_CLK_CON=m
CONFIG_EXYNOS_CLKOUT=m
CONFIG_EXYNOS_ACPM_CLK=m
CONFIG_TESLA_FSD_COMMON_CLK=y
CONFIG_CLK_SIFIVE=y
CONFIG_CLK_SIFIVE_PRCI=m
CONFIG_CLK_INTEL_SOCFPGA=y
CONFIG_CLK_INTEL_SOCFPGA32=y
CONFIG_CLK_INTEL_SOCFPGA64=y
CONFIG_CLK_SOPHGO_CV1800=m
CONFIG_CLK_SOPHGO_SG2042_PLL=m
CONFIG_CLK_SOPHGO_SG2042_CLKGEN=m
CONFIG_CLK_SOPHGO_SG2042_RPGATE=m
CONFIG_CLK_SOPHGO_SG2044=m
CONFIG_CLK_SOPHGO_SG2044_PLL=m
#
# Clock support for SpacemiT platforms
#
CONFIG_SPACEMIT_CCU=m
CONFIG_SPACEMIT_K1_CCU=m
CONFIG_SPACEMIT_K3_CCU=m
# end of Clock support for SpacemiT platforms
CONFIG_SPRD_COMMON_CLK=m
CONFIG_SPRD_SC9860_CLK=m
CONFIG_SPRD_SC9863A_CLK=m
CONFIG_SPRD_UMS512_CLK=m
CONFIG_CLK_STARFIVE_JH71X0=y
CONFIG_CLK_STARFIVE_JH7100=y
CONFIG_CLK_STARFIVE_JH7100_AUDIO=m
CONFIG_CLK_STARFIVE_JH7110_PLL=y
CONFIG_CLK_STARFIVE_JH7110_SYS=y
CONFIG_CLK_STARFIVE_JH7110_AON=m
CONFIG_CLK_STARFIVE_JH7110_STG=m
CONFIG_CLK_STARFIVE_JH7110_ISP=m
CONFIG_CLK_STARFIVE_JH7110_VOUT=m
CONFIG_CLK_SUNXI=y
CONFIG_CLK_SUNXI_CLOCKS=y
CONFIG_CLK_SUNXI_PRCM_SUN6I=y
CONFIG_CLK_SUNXI_PRCM_SUN8I=y
CONFIG_CLK_SUNXI_PRCM_SUN9I=y
CONFIG_SUNXI_CCU=m
CONFIG_SUNIV_F1C100S_CCU=m
CONFIG_SUN20I_D1_CCU=m
CONFIG_SUN20I_D1_R_CCU=m
CONFIG_SUN50I_A64_CCU=m
CONFIG_SUN50I_A100_CCU=m
CONFIG_SUN50I_A100_R_CCU=m
CONFIG_SUN50I_H6_CCU=m
CONFIG_SUN50I_H616_CCU=m
CONFIG_SUN50I_H6_R_CCU=m
CONFIG_SUN55I_A523_CCU=m
CONFIG_SUN55I_A523_MCU_CCU=m
CONFIG_SUN55I_A523_R_CCU=m
CONFIG_SUN4I_A10_CCU=m
CONFIG_SUN6I_A31_CCU=m
CONFIG_SUN6I_RTC_CCU=m
CONFIG_SUN8I_A23_CCU=m
CONFIG_SUN8I_A33_CCU=m
CONFIG_SUN8I_A83T_CCU=m
CONFIG_SUN8I_H3_CCU=m
CONFIG_SUN8I_V3S_CCU=m
CONFIG_SUN8I_DE2_CCU=m
CONFIG_SUN8I_R40_CCU=m
CONFIG_SUN9I_A80_CCU=m
CONFIG_SUN8I_R_CCU=m
CONFIG_COMMON_CLK_STM32MP=y
CONFIG_COMMON_CLK_STM32MP135=y
CONFIG_COMMON_CLK_STM32MP157=y
CONFIG_COMMON_CLK_STM32MP215=y
CONFIG_COMMON_CLK_STM32MP257=y
CONFIG_COMMON_CLK_TI_ADPLL=m
CONFIG_CLK_UNIPHIER=y
CONFIG_COMMON_CLK_VISCONTI=y
CONFIG_CLK_LGM_CGU=y
CONFIG_XILINX_VCU=m
CONFIG_COMMON_CLK_XLNX_CLKWZRD=m
CONFIG_COMMON_CLK_ZYNQMP=y
CONFIG_CLK_KUNIT_TEST=m
CONFIG_CLK_FIXED_RATE_KUNIT_TEST=m
CONFIG_CLK_GATE_KUNIT_TEST=m
CONFIG_CLK_FD_KUNIT_TEST=m
CONFIG_HWSPINLOCK=y
CONFIG_HWSPINLOCK_OMAP=m
CONFIG_HWSPINLOCK_QCOM=m
CONFIG_HWSPINLOCK_SPRD=m
CONFIG_HWSPINLOCK_STM32=m
CONFIG_HWSPINLOCK_SUN6I=m
CONFIG_HSEM_U8500=m
#
# Clock Source drivers
#
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_CLKSRC_I8253=y
CONFIG_CLKEVT_I8253=y
CONFIG_I8253_LOCK=y
CONFIG_CLKBLD_I8253=y
CONFIG_CLKSRC_MMIO=y
CONFIG_BCM2835_TIMER=y
CONFIG_BCM_KONA_TIMER=y
CONFIG_DAVINCI_TIMER=y
CONFIG_DIGICOLOR_TIMER=y
CONFIG_OMAP_DM_TIMER=y
CONFIG_DW_APB_TIMER=y
CONFIG_ECONET_EN751221_TIMER=y
CONFIG_FTTMR010_TIMER=y
CONFIG_IXP4XX_TIMER=y
CONFIG_MESON6_TIMER=y
CONFIG_OWL_TIMER=y
CONFIG_RDA_TIMER=y
CONFIG_REALTEK_OTTO_TIMER=y
CONFIG_SUN4I_TIMER=y
CONFIG_SUN5I_HSTIMER=y
CONFIG_TEGRA_TIMER=y
CONFIG_TEGRA186_TIMER=y
CONFIG_VT8500_TIMER=y
CONFIG_NPCM7XX_TIMER=y
CONFIG_CADENCE_TTC_TIMER=y
CONFIG_ASM9260_TIMER=y
CONFIG_CLKSRC_DBX500_PRCMU=y
CONFIG_CLPS711X_TIMER=y
CONFIG_MXS_TIMER=y
CONFIG_NSPIRE_TIMER=y
CONFIG_INTEGRATOR_AP_TIMER=y
CONFIG_CLKSRC_PISTACHIO=y
CONFIG_CLKSRC_STM32_LP=y
CONFIG_ARMV7M_SYSTICK=y
CONFIG_ATMEL_PIT=y
CONFIG_ATMEL_ST=y
CONFIG_CLKSRC_SAMSUNG_PWM=y
CONFIG_FSL_FTM_TIMER=y
CONFIG_NXP_PIT_TIMER=y
CONFIG_MTK_TIMER=y
CONFIG_MTK_CPUX_TIMER=y
CONFIG_SPRD_TIMER=y
CONFIG_CLKSRC_JCORE_PIT=y
CONFIG_SH_TIMER_CMT=y
CONFIG_SH_TIMER_MTU2=y
CONFIG_RENESAS_OSTM=y
CONFIG_SH_TIMER_TMU=y
CONFIG_EM_TIMER_STI=y
CONFIG_CLKSRC_PXA=y
CONFIG_TIMER_IMX_SYS_CTR=y
CONFIG_CLKSRC_LOONGSON1_PWM=y
CONFIG_CLKSRC_ST_LPC=y
CONFIG_GXP_TIMER=y
CONFIG_MSC313E_TIMER=y
CONFIG_INGENIC_TIMER=y
CONFIG_INGENIC_SYSOST=y
CONFIG_INGENIC_OST=y
CONFIG_GOLDFISH_TIMER=y
CONFIG_RALINK_TIMER=y
CONFIG_NXP_STM_TIMER=y
# end of Clock Source drivers
CONFIG_MAILBOX=y
CONFIG_ARM_MHU_V3=m
CONFIG_AST2700_MBOX=m
CONFIG_CV1800_MBOX=m
CONFIG_EXYNOS_MBOX=m
CONFIG_IMX_MBOX=m
CONFIG_PLATFORM_MHU=m
CONFIG_ARMADA_37XX_RWTM_MBOX=m
CONFIG_OMAP2PLUS_MBOX=m
CONFIG_ROCKCHIP_MBOX=y
CONFIG_PCC=y
CONFIG_ALTERA_MBOX=m
CONFIG_TI_MESSAGE_MANAGER=m
CONFIG_HI3660_MBOX=m
CONFIG_HI6220_MBOX=m
CONFIG_MAILBOX_TEST=m
CONFIG_POLARFIRE_SOC_MAILBOX=m
CONFIG_QCOM_APCS_IPC=m
CONFIG_BCM_PDC_MBOX=m
CONFIG_STM32_IPCC=m
CONFIG_MTK_ADSP_MBOX=m
CONFIG_MTK_CMDQ_MBOX=m
CONFIG_MTK_GPUEB_MBOX=m
CONFIG_MTK_VCP_MBOX=m
CONFIG_SUN6I_MSGBOX=m
CONFIG_SPRD_MBOX=m
CONFIG_QCOM_IPCC=m
CONFIG_THEAD_TH1520_MBOX=m
CONFIG_CIX_MBOX=m
CONFIG_BCM74110_MAILBOX=m
CONFIG_IOMMU_IOVA=y
CONFIG_IOMMU_API=y
CONFIG_IOMMUFD_DRIVER=y
CONFIG_IOMMU_SUPPORT=y
#
# Generic IOMMU Pagetable Support
#
CONFIG_IOMMU_IO_PGTABLE=y
CONFIG_IOMMU_IO_PGTABLE_LPAE=y
CONFIG_IOMMU_IO_PGTABLE_LPAE_KUNIT_TEST=m
CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST=y
CONFIG_IOMMU_IO_PGTABLE_DART=y
# end of Generic IOMMU Pagetable Support
CONFIG_IOMMU_DEBUGFS=y
# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set
CONFIG_IOMMU_DEFAULT_DMA_LAZY=y
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
CONFIG_OF_IOMMU=y
CONFIG_IOMMU_DMA=y
CONFIG_IOMMU_IOPF=y
CONFIG_ARM_SMMU=m
CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y
CONFIG_ARM_SMMU_MMU_500_CPRE_ERRATA=y
CONFIG_QCOM_IOMMU=y
CONFIG_DMAR_TABLE=y
CONFIG_DMAR_PERF=y
CONFIG_DMAR_DEBUG=y
CONFIG_INTEL_IOMMU=y
CONFIG_INTEL_IOMMU_DEBUGFS=y
CONFIG_INTEL_IOMMU_DEFAULT_ON=y
CONFIG_INTEL_IOMMU_FLOPPY_WA=y
CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON=y
CONFIG_INTEL_IOMMU_PERF_EVENTS=y
CONFIG_IOMMUFD_DRIVER_CORE=y
CONFIG_IOMMUFD=m
CONFIG_IOMMUFD_TEST=y
CONFIG_OMAP_IOMMU=y
CONFIG_OMAP_IOMMU_DEBUG=y
CONFIG_ROCKCHIP_IOMMU=y
CONFIG_SUN50I_IOMMU=y
CONFIG_EXYNOS_IOMMU=y
CONFIG_EXYNOS_IOMMU_DEBUG=y
CONFIG_IPMMU_VMSA=y
CONFIG_APPLE_DART=m
CONFIG_MTK_IOMMU=m
CONFIG_MTK_IOMMU_V1=m
CONFIG_HYPERV_IOMMU=y
CONFIG_VIRTIO_IOMMU=m
CONFIG_SPRD_IOMMU=m
CONFIG_IOMMU_DEBUG_PAGEALLOC=y
CONFIG_GENERIC_PT=y
CONFIG_DEBUG_GENERIC_PT=y
CONFIG_IOMMU_PT=y
CONFIG_IOMMU_PT_AMDV1=m
CONFIG_IOMMU_PT_VTDSS=y
CONFIG_IOMMU_PT_X86_64=y
CONFIG_IOMMU_PT_KUNIT_TEST=m
#
# Remoteproc drivers
#
CONFIG_REMOTEPROC=y
CONFIG_REMOTEPROC_CDEV=y
CONFIG_INGENIC_VPU_RPROC=m
CONFIG_MTK_SCP=m
CONFIG_MESON_MX_AO_ARC_REMOTEPROC=m
CONFIG_PRU_REMOTEPROC=m
CONFIG_RCAR_REMOTEPROC=m
CONFIG_ST_SLIM_REMOTEPROC=m
CONFIG_STM32_RPROC=m
CONFIG_TI_K3_DSP_REMOTEPROC=m
CONFIG_TI_K3_M4_REMOTEPROC=m
CONFIG_TI_K3_R5_REMOTEPROC=m
# end of Remoteproc drivers
#
# Rpmsg drivers
#
CONFIG_RPMSG=m
CONFIG_RPMSG_CHAR=m
CONFIG_RPMSG_CTRL=m
CONFIG_RPMSG_NS=m
CONFIG_RPMSG_MTK_SCP=m
CONFIG_RPMSG_QCOM_GLINK=m
CONFIG_RPMSG_QCOM_GLINK_RPM=m
CONFIG_RPMSG_QCOM_GLINK_SMEM=m
CONFIG_RPMSG_QCOM_SMD=m
CONFIG_RPMSG_VIRTIO=m
# end of Rpmsg drivers
CONFIG_SOUNDWIRE=m
#
# SoundWire Devices
#
CONFIG_SOUNDWIRE_AMD=m
CONFIG_SOUNDWIRE_CADENCE=m
CONFIG_SOUNDWIRE_INTEL=m
CONFIG_SOUNDWIRE_QCOM=m
CONFIG_SOUNDWIRE_GENERIC_ALLOCATION=m
#
# SOC (System On Chip) specific Drivers
#
#
# Amlogic SoC drivers
#
CONFIG_MESON_CANVAS=m
CONFIG_MESON_CLK_MEASURE=m
CONFIG_MESON_GX_SOCINFO=y
CONFIG_MESON_MX_SOCINFO=y
# end of Amlogic SoC drivers
#
# Apple SoC drivers
#
CONFIG_APPLE_SART=m
CONFIG_APPLE_TUNABLE=m
# end of Apple SoC drivers
#
# ASPEED SoC drivers
#
CONFIG_ASPEED_LPC_CTRL=m
CONFIG_ASPEED_LPC_SNOOP=m
CONFIG_ASPEED_UART_ROUTING=m
CONFIG_ASPEED_P2A_CTRL=m
CONFIG_ASPEED_SOCINFO=y
# end of ASPEED SoC drivers
CONFIG_AT91_SOC_ID=y
CONFIG_AT91_SOC_SFR=m
#
# Broadcom SoC drivers
#
CONFIG_SOC_BRCMSTB=y
# end of Broadcom SoC drivers
#
# NXP/Freescale QorIQ SoC drivers
#
CONFIG_FSL_DPAA=y
CONFIG_FSL_DPAA_CHECKING=y
CONFIG_FSL_BMAN_TEST=m
CONFIG_FSL_BMAN_TEST_API=y
CONFIG_FSL_QMAN_TEST=m
CONFIG_FSL_QMAN_TEST_API=y
CONFIG_FSL_QMAN_TEST_STASH=y
CONFIG_QUICC_ENGINE=y
CONFIG_UCC_SLOW=y
CONFIG_UCC_FAST=y
CONFIG_UCC=y
CONFIG_CPM_TSA=m
CONFIG_QE_TDM=y
CONFIG_FSL_GUTS=y
CONFIG_FSL_MC_DPIO=m
CONFIG_DPAA2_CONSOLE=m
# end of NXP/Freescale QorIQ SoC drivers
#
# fujitsu SoC drivers
#
# end of fujitsu SoC drivers
#
# Hisilicon SoC drivers
#
CONFIG_KUNPENG_HCCS=m
# end of Hisilicon SoC drivers
#
# i.MX SoC drivers
#
CONFIG_SOC_IMX8M=m
CONFIG_SOC_IMX9=m
# end of i.MX SoC drivers
#
# IXP4xx SoC drivers
#
CONFIG_IXP4XX_QMGR=m
CONFIG_IXP4XX_NPE=m
# end of IXP4xx SoC drivers
#
# Enable LiteX SoC Builder specific drivers
#
CONFIG_LITEX=y
CONFIG_LITEX_SOC_CONTROLLER=m
# end of Enable LiteX SoC Builder specific drivers
CONFIG_LOONGSON2_GUTS=m
#
# MediaTek SoC drivers
#
CONFIG_MTK_CMDQ=m
CONFIG_MTK_DEVAPC=m
CONFIG_MTK_INFRACFG=y
CONFIG_MTK_PMIC_WRAP=m
CONFIG_MTK_REGULATOR_COUPLER=y
CONFIG_MTK_MMSYS=m
CONFIG_MTK_SVS=m
CONFIG_MTK_SOCINFO=m
# end of MediaTek SoC drivers
CONFIG_POLARFIRE_SOC_SYS_CTRL=m
CONFIG_WPCM450_SOC=m
#
# Qualcomm SoC drivers
#
CONFIG_QCOM_AOSS_QMP=m
CONFIG_QCOM_COMMAND_DB=m
CONFIG_QCOM_GENI_SE=m
CONFIG_QCOM_GSBI=m
CONFIG_QCOM_LLCC=m
CONFIG_QCOM_MDT_LOADER=m
CONFIG_QCOM_PD_MAPPER=m
CONFIG_QCOM_PDR_HELPERS=m
CONFIG_QCOM_PDR_MSG=m
CONFIG_QCOM_PMIC_PDCHARGER_ULOG=m
CONFIG_QCOM_PMIC_GLINK=m
CONFIG_QCOM_QMI_HELPERS=m
CONFIG_QCOM_RAMP_CTRL=m
CONFIG_QCOM_RMTFS_MEM=m
CONFIG_QCOM_RPM_MASTER_STATS=m
CONFIG_QCOM_RPMH=m
CONFIG_QCOM_SMEM=m
CONFIG_QCOM_SMD_RPM=m
CONFIG_QCOM_SMEM_STATE=y
CONFIG_QCOM_SMP2P=m
CONFIG_QCOM_SMSM=m
CONFIG_QCOM_SOCINFO=m
CONFIG_QCOM_SPM=m
CONFIG_QCOM_STATS=m
CONFIG_QCOM_WCNSS_CTRL=m
CONFIG_QCOM_APR=m
CONFIG_QCOM_ICC_BWMON=m
CONFIG_QCOM_INLINE_CRYPTO_ENGINE=m
CONFIG_QCOM_PBS=m
# end of Qualcomm SoC drivers
CONFIG_QCOM_UBWC_CONFIG=m
CONFIG_SOC_RENESAS=y
CONFIG_PWC_RZV2M=y
CONFIG_RST_RCAR=y
CONFIG_RZN1_IRQMUX=y
CONFIG_SYSC_RZ=y
CONFIG_SYSC_R9A08G045=y
CONFIG_SYS_R9A09G047=y
CONFIG_SYS_R9A09G056=y
CONFIG_SYS_R9A09G057=y
CONFIG_ROCKCHIP_GRF=y
CONFIG_ROCKCHIP_IODOMAIN=m
CONFIG_ROCKCHIP_DTPM=m
CONFIG_SOC_SAMSUNG=y
CONFIG_EXYNOS_ASV_ARM=y
CONFIG_EXYNOS_CHIPID=m
CONFIG_EXYNOS_USI=m
CONFIG_EXYNOS_REGULATOR_COUPLER=y
#
# Sophgo SoC drivers
#
CONFIG_SOPHGO_CV1800_RTCSYS=m
CONFIG_SOPHGO_SG2044_TOPSYS=m
# end of Sophgo SoC drivers
CONFIG_SUNXI_SRAM=y
CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER=y
CONFIG_SOC_TEGRA30_VOLTAGE_COUPLER=y
CONFIG_SOC_TI=y
CONFIG_TI_K3_SOCINFO=y
CONFIG_TI_PRUSS=m
CONFIG_UX500_SOC_ID=y
CONFIG_SOC_INTEGRATOR_CM=y
CONFIG_SOC_REALVIEW=y
#
# VIA/WonderMedia SoC drivers
#
CONFIG_WMT_SOCINFO=y
# end of VIA/WonderMedia SoC drivers
#
# Xilinx SoC drivers
#
# end of Xilinx SoC drivers
# end of SOC (System On Chip) specific Drivers
#
# PM Domains
#
CONFIG_OWL_PM_DOMAINS_HELPER=y
CONFIG_OWL_PM_DOMAINS=y
#
# Amlogic PM Domains
#
CONFIG_MESON_EE_PM_DOMAINS=m
# end of Amlogic PM Domains
CONFIG_APPLE_PMGR_PWRSTATE=y
CONFIG_ARM_SCMI_PERF_DOMAIN=m
CONFIG_ARM_SCMI_POWER_DOMAIN=m
CONFIG_ARM_SCPI_POWER_DOMAIN=m
#
# Broadcom PM Domains
#
CONFIG_BCM2835_POWER=y
CONFIG_BCM_PMB=y
CONFIG_BCM63XX_POWER=y
# end of Broadcom PM Domains
#
# i.MX PM Domains
#
CONFIG_IMX_GPCV2_PM_DOMAINS=y
CONFIG_IMX8M_BLK_CTRL=y
CONFIG_IMX9_BLK_CTRL=y
CONFIG_IMX_SCU_PD=y
# end of i.MX PM Domains
#
# Marvell PM Domains
#
CONFIG_PXA1908_PM_DOMAINS=m
# end of Marvell PM Domains
#
# MediaTek PM Domains
#
CONFIG_MTK_SCPSYS=y
CONFIG_MTK_SCPSYS_PM_DOMAINS=y
CONFIG_MTK_MFG_PM_DOMAIN=y
# end of MediaTek PM Domains
#
# Qualcomm PM Domains
#
CONFIG_QCOM_RPMHPD=m
CONFIG_QCOM_RPMPD=m
# end of Qualcomm PM Domains
#
# Renesas PM Domains
#
CONFIG_SYSC_RCAR=y
CONFIG_SYSC_RCAR_GEN4=y
CONFIG_SYSC_RMOBILE=y
CONFIG_SYSC_R8A7742=y
CONFIG_SYSC_R8A7743=y
CONFIG_SYSC_R8A7745=y
CONFIG_SYSC_R8A77470=y
CONFIG_SYSC_R8A774A1=y
CONFIG_SYSC_R8A774B1=y
CONFIG_SYSC_R8A774C0=y
CONFIG_SYSC_R8A774E1=y
CONFIG_SYSC_R8A7779=y
CONFIG_SYSC_R8A7790=y
CONFIG_SYSC_R8A7791=y
CONFIG_SYSC_R8A7792=y
CONFIG_SYSC_R8A7794=y
CONFIG_SYSC_R8A7795=y
CONFIG_SYSC_R8A77960=y
CONFIG_SYSC_R8A77961=y
CONFIG_SYSC_R8A77965=y
CONFIG_SYSC_R8A77970=y
CONFIG_SYSC_R8A77980=y
CONFIG_SYSC_R8A77990=y
CONFIG_SYSC_R8A77995=y
CONFIG_SYSC_R8A779A0=y
CONFIG_SYSC_R8A779F0=y
CONFIG_SYSC_R8A779G0=y
CONFIG_SYSC_R8A779H0=y
# end of Renesas PM Domains
CONFIG_EXYNOS_PM_DOMAINS=y
CONFIG_UX500_PM_DOMAIN=y
CONFIG_JH71XX_PMU=y
CONFIG_SUN20I_PPU=m
CONFIG_SUN50I_H6_PRCM_PPU=m
CONFIG_SUN55I_PCK600=m
CONFIG_TH1520_PM_DOMAINS=m
CONFIG_TI_SCI_PM_DOMAINS=m
# end of PM Domains
CONFIG_PM_DEVFREQ=y
#
# DEVFREQ Governors
#
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=m
CONFIG_DEVFREQ_GOV_PERFORMANCE=m
CONFIG_DEVFREQ_GOV_POWERSAVE=m
CONFIG_DEVFREQ_GOV_USERSPACE=m
CONFIG_DEVFREQ_GOV_PASSIVE=m
#
# DEVFREQ Drivers
#
CONFIG_ARM_EXYNOS_BUS_DEVFREQ=m
CONFIG_ARM_IMX_BUS_DEVFREQ=m
CONFIG_ARM_TEGRA_DEVFREQ=m
CONFIG_ARM_MEDIATEK_CCI_DEVFREQ=m
CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ=m
CONFIG_PM_DEVFREQ_EVENT=y
CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP=m
CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU=m
CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=m
CONFIG_EXTCON=y
#
# Extcon Device Drivers
#
CONFIG_EXTCON_ADC_JACK=m
CONFIG_EXTCON_AXP288=m
CONFIG_EXTCON_FSA9480=m
CONFIG_EXTCON_GPIO=m
CONFIG_EXTCON_INTEL_INT3496=m
CONFIG_EXTCON_INTEL_MRFLD=m
CONFIG_EXTCON_LC824206XA=m
CONFIG_EXTCON_MAX14577=m
CONFIG_EXTCON_MAX3355=m
CONFIG_EXTCON_MAX77693=m
CONFIG_EXTCON_MAX77843=m
CONFIG_EXTCON_MAX8997=m
CONFIG_EXTCON_MAX14526=m
CONFIG_EXTCON_PALMAS=m
CONFIG_EXTCON_PTN5150=m
CONFIG_EXTCON_QCOM_SPMI_MISC=m
CONFIG_EXTCON_RT8973A=m
CONFIG_EXTCON_SM5502=m
CONFIG_EXTCON_USB_GPIO=m
CONFIG_EXTCON_USBC_CROS_EC=m
CONFIG_EXTCON_USBC_TUSB320=m
CONFIG_EXTCON_RTK_TYPE_C=m
CONFIG_MEMORY=y
CONFIG_DDR=y
CONFIG_ATMEL_EBI=y
CONFIG_BRCMSTB_DPFE=m
CONFIG_BRCMSTB_MEMC=m
# CONFIG_BT1_L2_CTL is not set
CONFIG_TI_AEMIF=m
CONFIG_TI_EMIF=m
CONFIG_OMAP_GPMC=m
CONFIG_OMAP_GPMC_DEBUG=y
CONFIG_FPGA_DFL_EMIF=m
CONFIG_MVEBU_DEVBUS=y
CONFIG_FSL_CORENET_CF=m
CONFIG_FSL_IFC=y
CONFIG_JZ4780_NEMC=y
CONFIG_MTK_SMI=m
CONFIG_DA8XX_DDRCTL=y
CONFIG_RENESAS_RPCIF=m
CONFIG_STM32_FMC2_EBI=m
CONFIG_STM32_OMM=m
CONFIG_SAMSUNG_MC=y
CONFIG_EXYNOS5422_DMC=m
CONFIG_EXYNOS_SROM=y
CONFIG_TEGRA_MC=y
CONFIG_TEGRA20_EMC=m
CONFIG_TEGRA30_EMC=m
CONFIG_TEGRA124_EMC=m
CONFIG_TEGRA210_EMC_TABLE=y
CONFIG_TEGRA210_EMC=m
CONFIG_IIO=m
CONFIG_IIO_BUFFER=y
CONFIG_IIO_BUFFER_CB=m
CONFIG_IIO_BUFFER_DMA=m
CONFIG_IIO_BUFFER_DMAENGINE=m
CONFIG_IIO_BUFFER_HW_CONSUMER=m
CONFIG_IIO_KFIFO_BUF=m
CONFIG_IIO_TRIGGERED_BUFFER=m
CONFIG_IIO_CONFIGFS=m
CONFIG_IIO_GTS_HELPER=m
CONFIG_IIO_TRIGGER=y
CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
CONFIG_IIO_SW_DEVICE=m
CONFIG_IIO_SW_TRIGGER=m
CONFIG_IIO_TRIGGERED_EVENT=m
CONFIG_IIO_BACKEND=m
#
# Accelerometers
#
CONFIG_ADIS16201=m
CONFIG_ADIS16209=m
CONFIG_ADXL313=m
CONFIG_ADXL313_I2C=m
CONFIG_ADXL313_SPI=m
CONFIG_ADXL345=m
CONFIG_ADXL345_I2C=m
CONFIG_ADXL345_SPI=m
CONFIG_ADXL355=m
CONFIG_ADXL355_I2C=m
CONFIG_ADXL355_SPI=m
CONFIG_ADXL367=m
CONFIG_ADXL367_SPI=m
CONFIG_ADXL367_I2C=m
CONFIG_ADXL372=m
CONFIG_ADXL372_SPI=m
CONFIG_ADXL372_I2C=m
CONFIG_ADXL380=m
CONFIG_ADXL380_SPI=m
CONFIG_ADXL380_I2C=m
CONFIG_BMA220=m
CONFIG_BMA220_I2C=m
CONFIG_BMA220_SPI=m
CONFIG_BMA400=m
CONFIG_BMA400_I2C=m
CONFIG_BMA400_SPI=m
CONFIG_BMC150_ACCEL=m
CONFIG_BMC150_ACCEL_I2C=m
CONFIG_BMC150_ACCEL_SPI=m
CONFIG_BMI088_ACCEL=m
CONFIG_BMI088_ACCEL_I2C=m
CONFIG_BMI088_ACCEL_SPI=m
CONFIG_DA280=m
CONFIG_DA311=m
CONFIG_DMARD06=m
CONFIG_DMARD09=m
CONFIG_DMARD10=m
CONFIG_FXLS8962AF=m
CONFIG_FXLS8962AF_I2C=m
CONFIG_FXLS8962AF_SPI=m
CONFIG_HID_SENSOR_ACCEL_3D=m
CONFIG_IIO_CROS_EC_ACCEL_LEGACY=m
CONFIG_IIO_ST_ACCEL_3AXIS=m
CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m
CONFIG_IIO_ST_ACCEL_SPI_3AXIS=m
CONFIG_IIO_KX022A=m
CONFIG_IIO_KX022A_SPI=m
CONFIG_IIO_KX022A_I2C=m
CONFIG_KXSD9=m
CONFIG_KXSD9_SPI=m
CONFIG_KXSD9_I2C=m
CONFIG_KXCJK1013=m
CONFIG_MC3230=m
CONFIG_MMA7455=m
CONFIG_MMA7455_I2C=m
CONFIG_MMA7455_SPI=m
CONFIG_MMA7660=m
CONFIG_MMA8452=m
CONFIG_MMA9551_CORE=m
CONFIG_MMA9551=m
CONFIG_MMA9553=m
CONFIG_MSA311=m
CONFIG_MXC4005=m
CONFIG_MXC6255=m
CONFIG_SCA3000=m
CONFIG_SCA3300=m
CONFIG_STK8312=m
CONFIG_STK8BA50=m
# end of Accelerometers
#
# Analog to digital converters
#
CONFIG_IIO_ADC_HELPER=m
CONFIG_88PM886_GPADC=m
CONFIG_AD_SIGMA_DELTA=m
CONFIG_AD4000=m
CONFIG_AD4030=m
CONFIG_AD4062=m
CONFIG_AD4080=m
CONFIG_AD4130=m
CONFIG_AD4134=m
CONFIG_AD4170_4=m
CONFIG_AD4695=m
CONFIG_AD4851=m
CONFIG_AD7091R=m
CONFIG_AD7091R5=m
CONFIG_AD7091R8=m
CONFIG_AD7124=m
CONFIG_AD7173=m
CONFIG_AD7191=m
CONFIG_AD7192=m
CONFIG_AD7266=m
CONFIG_AD7280=m
CONFIG_AD7291=m
CONFIG_AD7292=m
CONFIG_AD7298=m
CONFIG_AD7380=m
CONFIG_AD7405=m
CONFIG_AD7476=m
CONFIG_AD7606=m
CONFIG_AD7606_IFACE_PARALLEL=m
CONFIG_AD7606_IFACE_SPI=m
CONFIG_AD7625=m
CONFIG_AD7766=m
CONFIG_AD7768_1=m
CONFIG_AD7779=m
CONFIG_AD7780=m
CONFIG_AD7791=m
CONFIG_AD7793=m
CONFIG_AD7887=m
CONFIG_AD7923=m
CONFIG_AD7944=m
CONFIG_AD7949=m
CONFIG_AD799X=m
CONFIG_AD9467=m
CONFIG_ADE9000=m
CONFIG_ADI_AXI_ADC=m
CONFIG_ASPEED_ADC=m
CONFIG_AT91_ADC=m
CONFIG_AT91_SAMA5D2_ADC=m
CONFIG_AXP20X_ADC=m
CONFIG_AXP288_ADC=m
CONFIG_BCM_IPROC_ADC=m
CONFIG_BERLIN2_ADC=m
CONFIG_CC10001_ADC=m
CONFIG_CPCAP_ADC=m
CONFIG_DA9150_GPADC=m
CONFIG_DLN2_ADC=m
CONFIG_ENVELOPE_DETECTOR=m
CONFIG_EP93XX_ADC=m
CONFIG_EXYNOS_ADC=m
CONFIG_MXS_LRADC_ADC=m
CONFIG_FSL_MX25_ADC=m
CONFIG_GEHC_PMC_ADC=m
CONFIG_HI8435=m
CONFIG_HX711=m
CONFIG_INA2XX_ADC=m
CONFIG_INGENIC_ADC=m
CONFIG_INTEL_MRFLD_ADC=m
CONFIG_IMX7D_ADC=m
CONFIG_IMX8QXP_ADC=m
CONFIG_IMX93_ADC=m
CONFIG_LP8788_ADC=m
CONFIG_LPC18XX_ADC=m
CONFIG_LPC32XX_ADC=m
CONFIG_LTC2309=m
CONFIG_LTC2471=m
CONFIG_LTC2485=m
CONFIG_LTC2496=m
CONFIG_LTC2497=m
CONFIG_MAX1027=m
CONFIG_MAX11100=m
CONFIG_MAX1118=m
CONFIG_MAX11205=m
CONFIG_MAX11410=m
CONFIG_MAX1241=m
CONFIG_MAX1363=m
CONFIG_MAX14001=m
CONFIG_MAX34408=m
CONFIG_MAX77541_ADC=m
CONFIG_MAX9611=m
CONFIG_MCP320X=m
CONFIG_MCP3422=m
CONFIG_MCP3564=m
CONFIG_MCP3911=m
CONFIG_MEDIATEK_MT6359_AUXADC=m
CONFIG_MEDIATEK_MT6360_ADC=m
CONFIG_MEDIATEK_MT6370_ADC=m
CONFIG_MEDIATEK_MT6577_AUXADC=m
CONFIG_MEN_Z188_ADC=m
CONFIG_MESON_SARADC=m
CONFIG_MP2629_ADC=m
CONFIG_NAU7802=m
CONFIG_NCT7201=m
CONFIG_NPCM_ADC=m
CONFIG_NXP_SAR_ADC=m
CONFIG_PAC1921=m
CONFIG_PAC1934=m
CONFIG_PALMAS_GPADC=m
CONFIG_QCOM_VADC_COMMON=m
CONFIG_QCOM_PM8XXX_XOADC=m
CONFIG_QCOM_SPMI_RRADC=m
CONFIG_QCOM_SPMI_IADC=m
CONFIG_QCOM_SPMI_VADC=m
CONFIG_QCOM_SPMI_ADC5=m
CONFIG_RCAR_GYRO_ADC=m
CONFIG_RN5T618_ADC=m
CONFIG_ROHM_BD79112=m
CONFIG_ROHM_BD79124=m
CONFIG_ROCKCHIP_SARADC=m
CONFIG_RICHTEK_RTQ6056=m
CONFIG_RZG2L_ADC=m
CONFIG_RZN1_ADC=m
CONFIG_RZT2H_ADC=m
CONFIG_SC27XX_ADC=m
CONFIG_SOPHGO_CV1800B_ADC=m
CONFIG_SPEAR_ADC=m
CONFIG_SD_ADC_MODULATOR=m
CONFIG_STM32_ADC_CORE=m
CONFIG_STM32_ADC=m
CONFIG_STM32_DFSDM_CORE=m
CONFIG_STM32_DFSDM_ADC=m
CONFIG_STMPE_ADC=m
CONFIG_SUN4I_GPADC=m
CONFIG_SUN20I_GPADC=m
CONFIG_TI_ADC081C=m
CONFIG_TI_ADC0832=m
CONFIG_TI_ADC084S021=m
CONFIG_TI_ADC108S102=m
CONFIG_TI_ADC12138=m
CONFIG_TI_ADC128S052=m
CONFIG_TI_ADC161S626=m
CONFIG_TI_ADS1015=m
CONFIG_TI_ADS1018=m
CONFIG_TI_ADS1100=m
CONFIG_TI_ADS1119=m
CONFIG_TI_ADS124S08=m
CONFIG_TI_ADS1298=m
CONFIG_TI_ADS131E08=m
CONFIG_TI_ADS131M02=m
CONFIG_TI_ADS7138=m
CONFIG_TI_ADS7924=m
CONFIG_TI_ADS7950=m
CONFIG_TI_ADS8344=m
CONFIG_TI_ADS8688=m
CONFIG_TI_AM335X_ADC=m
CONFIG_TI_LMP92064=m
CONFIG_TI_TLC4541=m
CONFIG_TI_TSC2046=m
CONFIG_TWL4030_MADC=m
CONFIG_TWL6030_GPADC=m
CONFIG_VF610_ADC=m
CONFIG_VIPERBOARD_ADC=m
CONFIG_XILINX_XADC=m
CONFIG_XILINX_AMS=m
# end of Analog to digital converters
#
# Analog to digital and digital to analog converters
#
CONFIG_AD74115=m
CONFIG_AD74413R=m
CONFIG_STX104=m
# end of Analog to digital and digital to analog converters
#
# Analog Front Ends
#
CONFIG_IIO_RESCALE=m
# end of Analog Front Ends
#
# Amplifiers
#
CONFIG_AD8366=m
CONFIG_ADA4250=m
CONFIG_ADL8113=m
CONFIG_HMC425=m
# end of Amplifiers
#
# Capacitance to digital converters
#
CONFIG_AD7150=m
CONFIG_AD7746=m
# end of Capacitance to digital converters
#
# Chemical Sensors
#
CONFIG_AOSONG_AGS02MA=m
CONFIG_ATLAS_PH_SENSOR=m
CONFIG_ATLAS_EZO_SENSOR=m
CONFIG_BME680=m
CONFIG_BME680_I2C=m
CONFIG_BME680_SPI=m
CONFIG_CCS811=m
CONFIG_ENS160=m
CONFIG_ENS160_I2C=m
CONFIG_ENS160_SPI=m
CONFIG_IAQCORE=m
CONFIG_MHZ19B=m
CONFIG_PMS7003=m
CONFIG_SCD30_CORE=m
CONFIG_SCD30_I2C=m
CONFIG_SCD30_SERIAL=m
CONFIG_SCD4X=m
CONFIG_SEN0322=m
CONFIG_SENSIRION_SGP30=m
CONFIG_SENSIRION_SGP40=m
CONFIG_SPS30=m
CONFIG_SPS30_I2C=m
CONFIG_SPS30_SERIAL=m
CONFIG_SENSEAIR_SUNRISE_CO2=m
CONFIG_VZ89X=m
# end of Chemical Sensors
CONFIG_IIO_CROS_EC_SENSORS_CORE=m
CONFIG_IIO_CROS_EC_SENSORS=m
CONFIG_IIO_CROS_EC_SENSORS_LID_ANGLE=m
CONFIG_IIO_CROS_EC_ACTIVITY=m
#
# Hid Sensor IIO Common
#
CONFIG_HID_SENSOR_IIO_COMMON=m
CONFIG_HID_SENSOR_IIO_TRIGGER=m
# end of Hid Sensor IIO Common
CONFIG_IIO_INV_SENSORS_TIMESTAMP=m
CONFIG_IIO_MS_SENSORS_I2C=m
#
# IIO SCMI Sensors
#
CONFIG_IIO_SCMI=m
# end of IIO SCMI Sensors
#
# SSP Sensor Common
#
CONFIG_IIO_SSP_SENSORS_COMMONS=m
CONFIG_IIO_SSP_SENSORHUB=m
# end of SSP Sensor Common
CONFIG_IIO_ST_SENSORS_I2C=m
CONFIG_IIO_ST_SENSORS_SPI=m
CONFIG_IIO_ST_SENSORS_CORE=m
#
# Digital to analog converters
#
CONFIG_AD3530R=m
CONFIG_AD3552R_HS=m
CONFIG_AD3552R_LIB=m
CONFIG_AD3552R=m
CONFIG_AD5064=m
CONFIG_AD5360=m
CONFIG_AD5380=m
CONFIG_AD5421=m
CONFIG_AD5446=m
CONFIG_AD5446_SPI=m
CONFIG_AD5446_I2C=m
CONFIG_AD5449=m
CONFIG_AD5592R_BASE=m
CONFIG_AD5592R=m
CONFIG_AD5593R=m
CONFIG_AD5504=m
CONFIG_AD5624R_SPI=m
CONFIG_AD9739A=m
CONFIG_ADI_AXI_DAC=m
CONFIG_LTC2688=m
CONFIG_AD5686=m
CONFIG_AD5686_SPI=m
CONFIG_AD5696_I2C=m
CONFIG_AD5755=m
CONFIG_AD5758=m
CONFIG_AD5761=m
CONFIG_AD5764=m
CONFIG_AD5766=m
CONFIG_AD5770R=m
CONFIG_AD5791=m
CONFIG_AD7293=m
CONFIG_AD7303=m
CONFIG_AD8460=m
CONFIG_AD8801=m
CONFIG_BD79703=m
CONFIG_CIO_DAC=m
CONFIG_DPOT_DAC=m
CONFIG_DS4424=m
CONFIG_LPC18XX_DAC=m
CONFIG_LTC1660=m
CONFIG_LTC2632=m
CONFIG_LTC2664=m
CONFIG_M62332=m
CONFIG_MAX517=m
CONFIG_MAX22007=m
CONFIG_MAX5522=m
CONFIG_MAX5821=m
CONFIG_MCP4725=m
CONFIG_MCP4728=m
CONFIG_MCP47FEB02=m
CONFIG_MCP4821=m
CONFIG_MCP4922=m
CONFIG_STM32_DAC=m
CONFIG_STM32_DAC_CORE=m
CONFIG_TI_DAC082S085=m
CONFIG_TI_DAC5571=m
CONFIG_TI_DAC7311=m
CONFIG_TI_DAC7612=m
CONFIG_VF610_DAC=m
# end of Digital to analog converters
#
# IIO dummy driver
#
CONFIG_IIO_DUMMY_EVGEN=m
CONFIG_IIO_SIMPLE_DUMMY=m
CONFIG_IIO_SIMPLE_DUMMY_EVENTS=y
CONFIG_IIO_SIMPLE_DUMMY_BUFFER=y
# end of IIO dummy driver
#
# Filters
#
# end of Filters
#
# Frequency Synthesizers DDS/PLL
#
#
# Clock Generator/Distribution
#
CONFIG_AD9523=m
# end of Clock Generator/Distribution
#
# Phase-Locked Loop (PLL) frequency synthesizers
#
CONFIG_ADF4350=m
CONFIG_ADF4371=m
CONFIG_ADF4377=m
CONFIG_ADMFM2000=m
CONFIG_ADMV1013=m
CONFIG_ADMV4420=m
CONFIG_ADRF6780=m
# end of Phase-Locked Loop (PLL) frequency synthesizers
# end of Frequency Synthesizers DDS/PLL
#
# Digital gyroscope sensors
#
CONFIG_ADIS16080=m
CONFIG_ADIS16130=m
CONFIG_ADIS16136=m
CONFIG_ADIS16260=m
CONFIG_ADXRS290=m
CONFIG_ADXRS450=m
CONFIG_BMG160=m
CONFIG_BMG160_I2C=m
CONFIG_BMG160_SPI=m
CONFIG_FXAS21002C=m
CONFIG_FXAS21002C_I2C=m
CONFIG_FXAS21002C_SPI=m
CONFIG_HID_SENSOR_GYRO_3D=m
CONFIG_MPU3050=m
CONFIG_MPU3050_I2C=m
CONFIG_IIO_ST_GYRO_3AXIS=m
CONFIG_IIO_ST_GYRO_I2C_3AXIS=m
CONFIG_IIO_ST_GYRO_SPI_3AXIS=m
CONFIG_ITG3200=m
# end of Digital gyroscope sensors
#
# Health Sensors
#
#
# Heart Rate Monitors
#
CONFIG_AFE4403=m
CONFIG_AFE4404=m
CONFIG_MAX30100=m
CONFIG_MAX30102=m
# end of Heart Rate Monitors
# end of Health Sensors
#
# Humidity sensors
#
CONFIG_AM2315=m
CONFIG_DHT11=m
CONFIG_ENS210=m
CONFIG_HDC100X=m
CONFIG_HDC2010=m
CONFIG_HDC3020=m
CONFIG_HID_SENSOR_HUMIDITY=m
CONFIG_HTS221=m
CONFIG_HTS221_I2C=m
CONFIG_HTS221_SPI=m
CONFIG_HTU21=m
CONFIG_SI7005=m
CONFIG_SI7020=m
# end of Humidity sensors
#
# Inertial measurement units
#
CONFIG_ADIS16400=m
CONFIG_ADIS16460=m
CONFIG_ADIS16475=m
CONFIG_ADIS16480=m
CONFIG_ADIS16550=m
CONFIG_BMI160=m
CONFIG_BMI160_I2C=m
CONFIG_BMI160_SPI=m
CONFIG_BMI270=m
CONFIG_BMI270_I2C=m
CONFIG_BMI270_SPI=m
CONFIG_BMI323=m
CONFIG_BMI323_I2C=m
CONFIG_BMI323_SPI=m
CONFIG_BOSCH_BNO055=m
CONFIG_BOSCH_BNO055_SERIAL=m
CONFIG_BOSCH_BNO055_I2C=m
CONFIG_FXOS8700=m
CONFIG_FXOS8700_I2C=m
CONFIG_FXOS8700_SPI=m
CONFIG_KMX61=m
CONFIG_INV_ICM42600=m
CONFIG_INV_ICM42600_I2C=m
CONFIG_INV_ICM42600_SPI=m
CONFIG_INV_ICM45600=m
CONFIG_INV_ICM45600_I2C=m
CONFIG_INV_ICM45600_SPI=m
CONFIG_INV_ICM45600_I3C=m
CONFIG_INV_MPU6050_IIO=m
CONFIG_INV_MPU6050_I2C=m
CONFIG_INV_MPU6050_SPI=m
CONFIG_SMI240=m
CONFIG_SMI330=m
CONFIG_SMI330_I2C=m
CONFIG_SMI330_SPI=m
CONFIG_IIO_ST_LSM6DSX=m
CONFIG_IIO_ST_LSM6DSX_I2C=m
CONFIG_IIO_ST_LSM6DSX_SPI=m
CONFIG_IIO_ST_LSM6DSX_I3C=m
CONFIG_IIO_ST_LSM9DS0=m
CONFIG_IIO_ST_LSM9DS0_I2C=m
CONFIG_IIO_ST_LSM9DS0_SPI=m
# end of Inertial measurement units
CONFIG_IIO_ADIS_LIB=m
CONFIG_IIO_ADIS_LIB_BUFFER=y
#
# Light sensors
#
CONFIG_ACPI_ALS=m
CONFIG_ADJD_S311=m
CONFIG_ADUX1020=m
CONFIG_AL3000A=m
CONFIG_AL3010=m
CONFIG_AL3320A=m
CONFIG_APDS9160=m
CONFIG_APDS9300=m
CONFIG_APDS9306=m
CONFIG_APDS9960=m
CONFIG_AS73211=m
CONFIG_BH1745=m
CONFIG_BH1750=m
CONFIG_BH1780=m
CONFIG_CM32181=m
CONFIG_CM3232=m
CONFIG_CM3323=m
CONFIG_CM3605=m
CONFIG_CM36651=m
CONFIG_IIO_CROS_EC_LIGHT_PROX=m
CONFIG_GP2AP002=m
CONFIG_GP2AP020A00F=m
CONFIG_IQS621_ALS=m
CONFIG_SENSORS_ISL29018=m
CONFIG_SENSORS_ISL29028=m
CONFIG_ISL29125=m
CONFIG_ISL76682=m
CONFIG_HID_SENSOR_ALS=m
CONFIG_HID_SENSOR_PROX=m
CONFIG_JSA1212=m
CONFIG_ROHM_BU27034=m
CONFIG_RPR0521=m
CONFIG_SENSORS_LM3533=m
CONFIG_LTR390=m
CONFIG_LTR501=m
CONFIG_LTRF216A=m
CONFIG_LV0104CS=m
CONFIG_MAX44000=m
CONFIG_MAX44009=m
CONFIG_NOA1305=m
CONFIG_OPT3001=m
CONFIG_OPT4001=m
CONFIG_OPT4060=m
CONFIG_PA12203001=m
CONFIG_SI1133=m
CONFIG_SI1145=m
CONFIG_STK3310=m
CONFIG_ST_UVIS25=m
CONFIG_ST_UVIS25_I2C=m
CONFIG_ST_UVIS25_SPI=m
CONFIG_TCS3414=m
CONFIG_TCS3472=m
CONFIG_SENSORS_TSL2563=m
CONFIG_TSL2583=m
CONFIG_TSL2591=m
CONFIG_TSL2772=m
CONFIG_TSL4531=m
CONFIG_US5182D=m
CONFIG_VCNL4000=m
CONFIG_VCNL4035=m
CONFIG_VEML3235=m
CONFIG_VEML6030=m
CONFIG_VEML6040=m
CONFIG_VEML6046X00=m
CONFIG_VEML6070=m
CONFIG_VEML6075=m
CONFIG_VL6180=m
CONFIG_ZOPT2201=m
# end of Light sensors
#
# Magnetometer sensors
#
CONFIG_AF8133J=m
CONFIG_AK8974=m
CONFIG_AK8975=m
CONFIG_AK09911=m
CONFIG_ALS31300=m
CONFIG_BMC150_MAGN=m
CONFIG_BMC150_MAGN_I2C=m
CONFIG_BMC150_MAGN_SPI=m
CONFIG_MAG3110=m
CONFIG_HID_SENSOR_MAGNETOMETER_3D=m
CONFIG_MMC35240=m
CONFIG_MMC5633=m
CONFIG_IIO_ST_MAGN_3AXIS=m
CONFIG_IIO_ST_MAGN_I2C_3AXIS=m
CONFIG_IIO_ST_MAGN_SPI_3AXIS=m
CONFIG_INFINEON_TLV493D=m
CONFIG_SENSORS_HMC5843=m
CONFIG_SENSORS_HMC5843_I2C=m
CONFIG_SENSORS_HMC5843_SPI=m
CONFIG_SENSORS_RM3100=m
CONFIG_SENSORS_RM3100_I2C=m
CONFIG_SENSORS_RM3100_SPI=m
CONFIG_SI7210=m
CONFIG_TI_TMAG5273=m
CONFIG_YAMAHA_YAS530=m
# end of Magnetometer sensors
#
# Multiplexers
#
CONFIG_IIO_MUX=m
# end of Multiplexers
#
# Inclinometer sensors
#
CONFIG_HID_SENSOR_INCLINOMETER_3D=m
CONFIG_HID_SENSOR_DEVICE_ROTATION=m
# end of Inclinometer sensors
CONFIG_IIO_GTS_KUNIT_TEST=m
CONFIG_IIO_RESCALE_KUNIT_TEST=m
CONFIG_IIO_FORMAT_KUNIT_TEST=m
CONFIG_IIO_MULTIPLY_KUNIT_TEST=m
#
# Triggers - standalone
#
CONFIG_IIO_HRTIMER_TRIGGER=m
CONFIG_IIO_INTERRUPT_TRIGGER=m
CONFIG_IIO_STM32_LPTIMER_TRIGGER=m
CONFIG_IIO_STM32_TIMER_TRIGGER=m
CONFIG_IIO_TIGHTLOOP_TRIGGER=m
CONFIG_IIO_SYSFS_TRIGGER=m
# end of Triggers - standalone
#
# Linear and angular position sensors
#
CONFIG_IQS624_POS=m
CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=m
# end of Linear and angular position sensors
#
# Digital potentiometers
#
CONFIG_AD5110=m
CONFIG_AD5272=m
CONFIG_DS1803=m
CONFIG_MAX5432=m
CONFIG_MAX5481=m
CONFIG_MAX5487=m
CONFIG_MCP4018=m
CONFIG_MCP4131=m
CONFIG_MCP4531=m
CONFIG_MCP41010=m
CONFIG_TPL0102=m
CONFIG_X9250=m
# end of Digital potentiometers
#
# Digital potentiostats
#
CONFIG_LMP91000=m
# end of Digital potentiostats
#
# Pressure sensors
#
CONFIG_ABP060MG=m
CONFIG_ABP2030PA=m
CONFIG_ABP2030PA_I2C=m
CONFIG_ABP2030PA_SPI=m
CONFIG_ROHM_BM1390=m
CONFIG_BMP280=m
CONFIG_BMP280_I2C=m
CONFIG_BMP280_SPI=m
CONFIG_IIO_CROS_EC_BARO=m
CONFIG_DLHL60D=m
CONFIG_DPS310=m
CONFIG_HID_SENSOR_PRESS=m
CONFIG_HP03=m
CONFIG_HSC030PA=m
CONFIG_HSC030PA_I2C=m
CONFIG_HSC030PA_SPI=m
CONFIG_ICP10100=m
CONFIG_MPL115=m
CONFIG_MPL115_I2C=m
CONFIG_MPL115_SPI=m
CONFIG_MPL3115=m
CONFIG_MPRLS0025PA=m
CONFIG_MPRLS0025PA_I2C=m
CONFIG_MPRLS0025PA_SPI=m
CONFIG_MS5611=m
CONFIG_MS5611_I2C=m
CONFIG_MS5611_SPI=m
CONFIG_MS5637=m
CONFIG_SDP500=m
CONFIG_IIO_ST_PRESS=m
CONFIG_IIO_ST_PRESS_I2C=m
CONFIG_IIO_ST_PRESS_SPI=m
CONFIG_T5403=m
CONFIG_HP206C=m
CONFIG_ZPA2326=m
CONFIG_ZPA2326_I2C=m
CONFIG_ZPA2326_SPI=m
CONFIG_ADP810=m
# end of Pressure sensors
#
# Lightning sensors
#
CONFIG_AS3935=m
# end of Lightning sensors
#
# Proximity and distance sensors
#
CONFIG_CROS_EC_MKBP_PROXIMITY=m
CONFIG_D3323AA=m
CONFIG_HX9023S=m
CONFIG_IRSD200=m
CONFIG_ISL29501=m
CONFIG_LIDAR_LITE_V2=m
CONFIG_MB1232=m
CONFIG_PING=m
CONFIG_RFD77402=m
CONFIG_SRF04=m
CONFIG_SX_COMMON=m
CONFIG_SX9310=m
CONFIG_SX9324=m
CONFIG_SX9360=m
CONFIG_SX9500=m
CONFIG_SRF08=m
CONFIG_VCNL3020=m
CONFIG_VL53L0X_I2C=m
CONFIG_AW96103=m
# end of Proximity and distance sensors
#
# Resolver to digital converters
#
CONFIG_AD2S90=m
CONFIG_AD2S1200=m
CONFIG_AD2S1210=m
# end of Resolver to digital converters
#
# Temperature sensors
#
CONFIG_IQS620AT_TEMP=m
CONFIG_LTC2983=m
CONFIG_MAXIM_THERMOCOUPLE=m
CONFIG_HID_SENSOR_TEMP=m
CONFIG_MLX90614=m
CONFIG_MLX90632=m
CONFIG_MLX90635=m
CONFIG_TMP006=m
CONFIG_TMP007=m
CONFIG_TMP117=m
CONFIG_TSYS01=m
CONFIG_TSYS02D=m
CONFIG_MAX30208=m
CONFIG_MAX31856=m
CONFIG_MAX31865=m
CONFIG_MCP9600=m
# end of Temperature sensors
CONFIG_NTB=m
CONFIG_NTB_MSI=y
CONFIG_NTB_IDT=m
CONFIG_NTB_EPF=m
CONFIG_NTB_SWITCHTEC=m
CONFIG_NTB_PINGPONG=m
CONFIG_NTB_TOOL=m
CONFIG_NTB_PERF=m
CONFIG_NTB_MSI_TEST=m
CONFIG_NTB_TRANSPORT=m
CONFIG_PWM=y
CONFIG_PWM_DEBUG=y
CONFIG_PWM_PROVIDE_GPIO=y
CONFIG_PWM_ADP5585=m
CONFIG_PWM_AIROHA=m
CONFIG_PWM_APPLE=m
CONFIG_PWM_ARGON_FAN_HAT=m
CONFIG_PWM_ATMEL=m
CONFIG_PWM_ATMEL_HLCDC_PWM=m
CONFIG_PWM_ATMEL_TCB=m
CONFIG_PWM_AXI_PWMGEN=m
CONFIG_PWM_BCM2835=m
CONFIG_PWM_BCM_IPROC=m
CONFIG_PWM_BCM_KONA=m
CONFIG_PWM_BERLIN=m
CONFIG_PWM_BRCMSTB=m
CONFIG_PWM_CLK=m
CONFIG_PWM_CLPS711X=m
CONFIG_PWM_CRC=m
CONFIG_PWM_CROS_EC=m
CONFIG_PWM_DWC_CORE=m
CONFIG_PWM_DWC=m
CONFIG_PWM_EP93XX=m
CONFIG_PWM_FSL_FTM=m
CONFIG_PWM_GPIO=m
CONFIG_PWM_HIBVT=m
CONFIG_PWM_IMG=m
CONFIG_PWM_IMX1=m
CONFIG_PWM_IMX27=m
CONFIG_PWM_IMX_TPM=m
CONFIG_PWM_INTEL_LGM=m
CONFIG_PWM_IQS620A=m
CONFIG_PWM_JZ4740=m
CONFIG_PWM_KEEMBAY=m
CONFIG_PWM_LOONGSON=m
CONFIG_PWM_LP3943=m
CONFIG_PWM_LPC18XX_SCT=m
CONFIG_PWM_LPC32XX=m
CONFIG_PWM_LPSS=m
CONFIG_PWM_LPSS_PCI=m
CONFIG_PWM_LPSS_PLATFORM=m
CONFIG_PWM_MAX7360=m
CONFIG_PWM_MC33XS2410=m
CONFIG_PWM_MEDIATEK=m
CONFIG_PWM_MESON=m
CONFIG_PWM_MICROCHIP_CORE=m
CONFIG_PWM_MTK_DISP=m
CONFIG_PWM_MXS=m
CONFIG_PWM_NTXEC=m
CONFIG_PWM_OMAP_DMTIMER=m
CONFIG_PWM_PCA9685=m
CONFIG_PWM_PXA=m
CONFIG_PWM_RASPBERRYPI_POE=m
CONFIG_PWM_RENESAS_RCAR=m
CONFIG_PWM_RENESAS_RZG2L_GPT=m
CONFIG_PWM_RENESAS_RZ_MTU3=m
CONFIG_PWM_RENESAS_TPU=m
CONFIG_PWM_ROCKCHIP=m
CONFIG_PWM_SAMSUNG=m
CONFIG_PWM_SIFIVE=m
CONFIG_PWM_SL28CPLD=m
CONFIG_PWM_SOPHGO_SG2042=m
CONFIG_PWM_SPEAR=m
CONFIG_PWM_SPRD=m
CONFIG_PWM_STI=m
CONFIG_PWM_STM32=m
CONFIG_PWM_STM32_LP=m
CONFIG_PWM_STMPE=m
CONFIG_PWM_SUN4I=m
CONFIG_PWM_SUNPLUS=m
CONFIG_PWM_TEGRA=m
CONFIG_PWM_TIECAP=m
CONFIG_PWM_TIEHRPWM=m
CONFIG_PWM_TWL=m
CONFIG_PWM_TWL_LED=m
CONFIG_PWM_VISCONTI=m
CONFIG_PWM_VT8500=m
CONFIG_PWM_XILINX=m
#
# IRQ chip support
#
CONFIG_IRQCHIP=y
CONFIG_IRQ_MSI_LIB=y
CONFIG_AL_FIC=y
CONFIG_BCM7038_L1_IRQ=m
CONFIG_BCM7120_L2_IRQ=m
CONFIG_BRCMSTB_L2_IRQ=m
CONFIG_LAN966X_OIC=m
CONFIG_MADERA_IRQ=m
CONFIG_JCORE_AIC=y
CONFIG_RENESAS_INTC_IRQPIN=y
CONFIG_RENESAS_IRQC=y
CONFIG_RENESAS_RZA1_IRQC=y
CONFIG_RENESAS_RZG2L_IRQC=y
CONFIG_RENESAS_RZT2H_ICU=y
CONFIG_RENESAS_RZV2H_ICU=y
CONFIG_SL28CPLD_INTC=y
CONFIG_TS4800_IRQ=m
CONFIG_XILINX_INTC=y
CONFIG_INGENIC_TCU_IRQ=y
CONFIG_STM32MP_EXTI=m
CONFIG_IRQ_UNIPHIER_AIDET=y
CONFIG_MESON_IRQ_GPIO=m
CONFIG_IMX_IRQSTEER=y
CONFIG_IMX_INTMUX=y
CONFIG_TI_SCI_INTR_IRQCHIP=m
CONFIG_TI_PRUSS_INTC=m
CONFIG_STARFIVE_JH8100_INTC=y
CONFIG_EXYNOS_IRQ_COMBINER=y
CONFIG_MST_IRQ=y
CONFIG_MCHP_EIC=y
CONFIG_SOPHGO_SG2042_MSI=y
CONFIG_SUNPLUS_SP7021_INTC=y
# end of IRQ chip support
CONFIG_IPACK_BUS=m
CONFIG_BOARD_TPCI200=m
CONFIG_SERIAL_IPOCTAL=m
CONFIG_RESET_CONTROLLER=y
CONFIG_RESET_A10SR=m
CONFIG_RESET_ASPEED=m
CONFIG_RESET_ATH79=y
CONFIG_RESET_AXS10X=y
CONFIG_RESET_BCM6345=y
CONFIG_RESET_BERLIN=m
CONFIG_RESET_BRCMSTB=m
CONFIG_RESET_BRCMSTB_RESCAL=m
CONFIG_RESET_EIC7700=y
CONFIG_RESET_EYEQ=y
CONFIG_RESET_GPIO=m
CONFIG_RESET_HSDK=y
CONFIG_RESET_IMX7=m
CONFIG_RESET_IMX8MP_AUDIOMIX=m
CONFIG_RESET_INTEL_GW=y
CONFIG_RESET_K210=y
CONFIG_RESET_K230=m
CONFIG_RESET_LANTIQ=y
CONFIG_RESET_LPC18XX=y
CONFIG_RESET_MCHP_SPARX5=m
CONFIG_RESET_NPCM=y
CONFIG_RESET_NUVOTON_MA35D1=y
CONFIG_RESET_PISTACHIO=y
CONFIG_RESET_POLARFIRE_SOC=y
CONFIG_RESET_QCOM_AOSS=m
CONFIG_RESET_QCOM_PDC=m
CONFIG_RESET_RASPBERRYPI=m
CONFIG_RESET_RZG2L_USBPHY_CTRL=m
CONFIG_RESET_RZV2H_USB2PHY=m
CONFIG_RESET_SCMI=m
CONFIG_RESET_SIMPLE=y
CONFIG_RESET_SOCFPGA=y
CONFIG_RESET_SUNPLUS=y
CONFIG_RESET_SUNXI=y
CONFIG_RESET_TH1520=m
CONFIG_RESET_TI_SCI=m
CONFIG_RESET_TI_SYSCON=m
CONFIG_RESET_TI_TPS380X=m
CONFIG_RESET_TN48M_CPLD=m
CONFIG_RESET_UNIPHIER=m
CONFIG_RESET_UNIPHIER_GLUE=m
CONFIG_RESET_ZYNQ=y
CONFIG_RESET_ZYNQMP=y
CONFIG_RESET_MESON_COMMON=m
CONFIG_RESET_MESON=m
CONFIG_RESET_MESON_AUX=m
CONFIG_RESET_MESON_AUDIO_ARB=m
CONFIG_COMMON_RESET_HI3660=m
CONFIG_COMMON_RESET_HI6220=m
#
# Reset support for SpacemiT platforms
#
CONFIG_RESET_SPACEMIT_COMMON=m
CONFIG_RESET_SPACEMIT_K1=m
CONFIG_RESET_SPACEMIT_K3=m
# end of Reset support for SpacemiT platforms
CONFIG_RESET_STARFIVE_JH71X0=y
CONFIG_RESET_STARFIVE_JH7100=y
CONFIG_RESET_STARFIVE_JH7110=y
CONFIG_STIH407_RESET=y
CONFIG_RESET_TEGRA_BPMP=y
#
# PHY Subsystem
#
CONFIG_PHY_COMMON_PROPS=y
CONFIG_PHY_COMMON_PROPS_TEST=m
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PHY_MIPI_DPHY=y
CONFIG_PHY_GOOGLE_USB=m
CONFIG_PHY_LPC18XX_USB_OTG=m
CONFIG_PHY_PISTACHIO_USB=m
CONFIG_PHY_SNPS_EUSB2=m
CONFIG_PHY_XGENE=m
CONFIG_USB_LGM_PHY=m
CONFIG_PHY_CAN_TRANSCEIVER=m
CONFIG_PHY_AIROHA_PCIE=m
CONFIG_PHY_NXP_PTN3222=m
CONFIG_PHY_SPACEMIT_K1_PCIE=m
CONFIG_PHY_SUN4I_USB=m
CONFIG_PHY_SUN6I_MIPI_DPHY=m
CONFIG_PHY_SUN9I_USB=m
CONFIG_PHY_SUN50I_USB3=m
CONFIG_PHY_MESON8_HDMI_TX=m
CONFIG_PHY_MESON8B_USB2=m
CONFIG_PHY_MESON_GXL_USB2=m
CONFIG_PHY_MESON_G12A_MIPI_DPHY_ANALOG=m
CONFIG_PHY_MESON_G12A_USB2=m
CONFIG_PHY_MESON_G12A_USB3_PCIE=m
CONFIG_PHY_MESON_AXG_PCIE=m
CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG=m
CONFIG_PHY_MESON_AXG_MIPI_DPHY=m
CONFIG_PHY_APPLE_ATC=m
#
# PHY drivers for Broadcom platforms
#
CONFIG_PHY_BCM63XX_USBH=m
CONFIG_PHY_CYGNUS_PCIE=m
CONFIG_PHY_BCM_SR_USB=m
CONFIG_BCM_KONA_USB2_PHY=m
CONFIG_PHY_BCM_NS_USB2=m
CONFIG_PHY_BCM_NS_USB3=m
CONFIG_PHY_NS2_PCIE=m
CONFIG_PHY_NS2_USB_DRD=m
CONFIG_PHY_BRCM_SATA=m
CONFIG_PHY_BRCM_USB=m
CONFIG_PHY_BCM_SR_PCIE=m
# end of PHY drivers for Broadcom platforms
CONFIG_PHY_CADENCE_TORRENT=m
CONFIG_PHY_CADENCE_DPHY=m
CONFIG_PHY_CADENCE_DPHY_RX=m
CONFIG_PHY_CADENCE_SIERRA=m
CONFIG_PHY_CADENCE_SALVO=m
CONFIG_PHY_FSL_IMX8MQ_USB=m
CONFIG_PHY_MIXEL_LVDS_PHY=m
CONFIG_PHY_MIXEL_MIPI_DPHY=m
CONFIG_PHY_FSL_IMX8M_PCIE=m
CONFIG_PHY_FSL_IMX8QM_HSIO=m
CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY=m
CONFIG_PHY_FSL_LYNX_28G=m
CONFIG_PHY_HI6220_USB=m
CONFIG_PHY_HI3660_USB=m
CONFIG_PHY_HI3670_USB=m
CONFIG_PHY_HI3670_PCIE=m
CONFIG_PHY_HISTB_COMBPHY=m
CONFIG_PHY_HISI_INNO_USB2=m
CONFIG_PHY_INGENIC_USB=m
CONFIG_PHY_LANTIQ_VRX200_PCIE=m
CONFIG_PHY_LANTIQ_RCU_USB2=m
CONFIG_ARMADA375_USBCLUSTER_PHY=y
CONFIG_PHY_BERLIN_SATA=m
CONFIG_PHY_BERLIN_USB=m
CONFIG_PHY_MVEBU_A3700_UTMI=m
CONFIG_PHY_MVEBU_A38X_COMPHY=m
CONFIG_PHY_MVEBU_CP110_UTMI=m
CONFIG_PHY_PXA_28NM_HSIC=m
CONFIG_PHY_PXA_28NM_USB2=m
CONFIG_PHY_PXA_USB=m
CONFIG_PHY_MMP3_USB=m
CONFIG_PHY_MMP3_HSIC=m
CONFIG_PHY_MTK_PCIE=m
CONFIG_PHY_MTK_XFI_TPHY=m
CONFIG_PHY_MTK_TPHY=m
CONFIG_PHY_MTK_UFS=m
CONFIG_PHY_MTK_XSPHY=m
CONFIG_PHY_MTK_HDMI=m
CONFIG_PHY_MTK_MIPI_CSI_0_5=m
CONFIG_PHY_MTK_MIPI_DSI=m
CONFIG_PHY_MTK_DP=m
CONFIG_PHY_SPARX5_SERDES=m
CONFIG_PHY_LAN966X_SERDES=m
CONFIG_PHY_CPCAP_USB=m
CONFIG_PHY_MAPPHONE_MDM6600=m
CONFIG_PHY_OCELOT_SERDES=m
CONFIG_PHY_MA35_USB=m
CONFIG_PHY_ATH79_USB=m
CONFIG_PHY_QCOM_EDP=m
CONFIG_PHY_QCOM_IPQ4019_USB=m
CONFIG_PHY_QCOM_PCIE2=m
CONFIG_PHY_QCOM_QMP=m
CONFIG_PHY_QCOM_QMP_COMBO=m
CONFIG_PHY_QCOM_QMP_PCIE=m
CONFIG_PHY_QCOM_QMP_PCIE_8996=m
CONFIG_PHY_QCOM_QMP_UFS=m
CONFIG_PHY_QCOM_QMP_USB=m
CONFIG_PHY_QCOM_QMP_USB_LEGACY=m
CONFIG_PHY_QCOM_QUSB2=m
CONFIG_PHY_QCOM_EUSB2_REPEATER=m
CONFIG_PHY_QCOM_M31_USB=m
CONFIG_PHY_QCOM_M31_EUSB=m
CONFIG_PHY_QCOM_USB_HS=m
CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=m
CONFIG_PHY_QCOM_USB_HSIC=m
CONFIG_PHY_QCOM_USB_HS_28NM=m
CONFIG_PHY_QCOM_USB_SS=m
CONFIG_PHY_QCOM_IPQ806X_USB=m
CONFIG_PHY_QCOM_SGMII_ETH=m
CONFIG_PHY_MT7621_PCI=m
CONFIG_PHY_RALINK_USB=m
CONFIG_PHY_RTK_RTD_USB2PHY=m
CONFIG_PHY_RTK_RTD_USB3PHY=m
CONFIG_PHY_R8A779F0_ETHERNET_SERDES=m
CONFIG_PHY_RCAR_GEN3_USB3=m
CONFIG_PHY_RZ_G3E_USB3=m
CONFIG_PHY_ROCKCHIP_DPHY_RX0=m
CONFIG_PHY_ROCKCHIP_INNO_HDMI=m
CONFIG_PHY_ROCKCHIP_INNO_USB2=m
CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY=m
CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=m
CONFIG_PHY_ROCKCHIP_PCIE=m
CONFIG_PHY_ROCKCHIP_SAMSUNG_DCPHY=m
CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=m
CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=m
CONFIG_PHY_ROCKCHIP_TYPEC=m
CONFIG_PHY_EXYNOS_DP_VIDEO=m
CONFIG_PHY_EXYNOS_MIPI_VIDEO=m
CONFIG_PHY_EXYNOS_PCIE=y
CONFIG_PHY_SAMSUNG_UFS=m
CONFIG_PHY_SAMSUNG_USB2=m
CONFIG_PHY_S5PV210_USB2=y
CONFIG_PHY_EXYNOS5_USBDRD=m
CONFIG_PHY_UNIPHIER_USB2=m
CONFIG_PHY_UNIPHIER_USB3=m
CONFIG_PHY_UNIPHIER_PCIE=m
CONFIG_PHY_UNIPHIER_AHCI=m
CONFIG_PHY_SOPHGO_CV1800_USB2=m
CONFIG_PHY_SPACEMIT_K1_USB2=m
CONFIG_PHY_ST_SPEAR1310_MIPHY=m
CONFIG_PHY_ST_SPEAR1340_MIPHY=m
CONFIG_PHY_STIH407_USB=m
CONFIG_PHY_STM32_COMBOPHY=m
CONFIG_PHY_STM32_USBPHYC=m
CONFIG_PHY_STARFIVE_JH7110_DPHY_RX=m
CONFIG_PHY_STARFIVE_JH7110_DPHY_TX=m
CONFIG_PHY_STARFIVE_JH7110_PCIE=m
CONFIG_PHY_STARFIVE_JH7110_USB=m
CONFIG_PHY_SUNPLUS_USB=m
CONFIG_PHY_TEGRA194_P2U=m
CONFIG_PHY_DA8XX_USB=m
CONFIG_PHY_DM816X_USB=m
CONFIG_PHY_AM654_SERDES=m
CONFIG_PHY_J721E_WIZ=m
CONFIG_OMAP_CONTROL_PHY=m
CONFIG_OMAP_USB2=m
CONFIG_TI_PIPE3=m
CONFIG_PHY_TUSB1210=m
CONFIG_TWL4030_USB=m
CONFIG_PHY_TI_GMII_SEL=m
CONFIG_PHY_INTEL_KEEMBAY_EMMC=m
CONFIG_PHY_INTEL_KEEMBAY_USB=m
CONFIG_PHY_INTEL_LGM_COMBO=y
CONFIG_PHY_INTEL_LGM_EMMC=m
CONFIG_PHY_XILINX_ZYNQMP=m
# end of PHY Subsystem
CONFIG_POWERCAP=y
CONFIG_INTEL_RAPL_CORE=m
CONFIG_INTEL_RAPL=m
CONFIG_IDLE_INJECT=y
CONFIG_ARM_SCMI_POWERCAP=m
CONFIG_DTPM=y
CONFIG_DTPM_CPU=y
CONFIG_DTPM_DEVFREQ=y
CONFIG_MCB=m
CONFIG_MCB_PCI=m
CONFIG_MCB_LPC=m
#
# Performance monitor support
#
CONFIG_ARM_CCN=m
CONFIG_ARM_CMN=m
CONFIG_ARM_NI=m
CONFIG_FSL_IMX8_DDR_PMU=m
CONFIG_ARM_DMC620_PMU=m
CONFIG_ALIBABA_UNCORE_DRW_PMU=m
CONFIG_HNS3_PMU=m
CONFIG_DWC_PCIE_PMU=m
CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m
CONFIG_NVIDIA_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m
CONFIG_AMPERE_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m
CONFIG_MESON_DDR_PMU=m
CONFIG_CXL_PMU=m
# end of Performance monitor support
CONFIG_RAS=y
CONFIG_RAS_CEC=y
CONFIG_RAS_CEC_DEBUG=y
# CONFIG_AMD_ATL is not set
CONFIG_USB4=m
CONFIG_USB4_DEBUGFS_WRITE=y
CONFIG_USB4_DEBUGFS_MARGINING=y
CONFIG_USB4_DMA_TEST=m
#
# Android
#
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_BINDERFS=y
CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"
CONFIG_ANDROID_BINDER_ALLOC_KUNIT_TEST=m
# end of Android
CONFIG_LIBNVDIMM=m
CONFIG_BLK_DEV_PMEM=m
CONFIG_ND_CLAIM=y
CONFIG_ND_BTT=m
CONFIG_BTT=y
CONFIG_OF_PMEM=m
CONFIG_RAMDAX=m
CONFIG_NVDIMM_KEYS=y
CONFIG_NVDIMM_SECURITY_TEST=y
CONFIG_DAX=m
CONFIG_DEV_DAX=m
CONFIG_NVMEM=y
CONFIG_NVMEM_SYSFS=y
CONFIG_NVMEM_LAYOUTS=y
#
# Layout Types
#
CONFIG_NVMEM_LAYOUT_SL28_VPD=m
CONFIG_NVMEM_LAYOUT_ONIE_TLV=m
CONFIG_NVMEM_LAYOUT_U_BOOT_ENV=m
# end of Layout Types
CONFIG_NVMEM_AN8855_EFUSE=m
CONFIG_NVMEM_APPLE_EFUSES=m
CONFIG_NVMEM_APPLE_SPMI=m
CONFIG_NVMEM_BCM_OCOTP=m
CONFIG_NVMEM_BRCM_NVRAM=m
CONFIG_NVMEM_IMX_IIM=m
CONFIG_NVMEM_IMX_OCOTP=m
CONFIG_NVMEM_IMX_OCOTP_ELE=m
CONFIG_NVMEM_JZ4780_EFUSE=m
CONFIG_NVMEM_LAN9662_OTPC=m
CONFIG_NVMEM_LAYERSCAPE_SFP=m
CONFIG_NVMEM_LPC18XX_EEPROM=m
CONFIG_NVMEM_LPC18XX_OTP=m
CONFIG_NVMEM_MAX77759=m
CONFIG_NVMEM_MESON_MX_EFUSE=m
CONFIG_NVMEM_MICROCHIP_OTPC=m
CONFIG_NVMEM_MTK_EFUSE=m
CONFIG_NVMEM_MXS_OCOTP=m
CONFIG_NVMEM_NINTENDO_OTP=m
CONFIG_NVMEM_QCOM_QFPROM=m
CONFIG_NVMEM_QCOM_SEC_QFPROM=m
CONFIG_NVMEM_QNAP_MCU_EEPROM=m
CONFIG_NVMEM_RAVE_SP_EEPROM=m
CONFIG_NVMEM_RCAR_EFUSE=m
CONFIG_NVMEM_RMEM=m
CONFIG_NVMEM_ROCKCHIP_EFUSE=m
CONFIG_NVMEM_ROCKCHIP_OTP=m
CONFIG_NVMEM_SC27XX_EFUSE=m
CONFIG_NVMEM_SNVS_LPGPR=m
CONFIG_NVMEM_SPMI_SDAM=m
CONFIG_NVMEM_SPRD_EFUSE=m
CONFIG_NVMEM_STM32_ROMEM=m
CONFIG_NVMEM_SUNPLUS_OCOTP=m
CONFIG_NVMEM_U_BOOT_ENV=m
CONFIG_NVMEM_UNIPHIER_EFUSE=m
CONFIG_NVMEM_VF610_OCOTP=m
CONFIG_NVMEM_QORIQ_EFUSE=m
#
# HW tracing support
#
CONFIG_STM=m
CONFIG_STM_PROTO_BASIC=m
CONFIG_STM_PROTO_SYS_T=m
CONFIG_STM_DUMMY=m
CONFIG_STM_SOURCE_CONSOLE=m
CONFIG_STM_SOURCE_HEARTBEAT=m
CONFIG_STM_SOURCE_FTRACE=m
CONFIG_INTEL_TH=m
CONFIG_INTEL_TH_PCI=m
CONFIG_INTEL_TH_ACPI=m
CONFIG_INTEL_TH_GTH=m
CONFIG_INTEL_TH_STH=m
CONFIG_INTEL_TH_MSU=m
CONFIG_INTEL_TH_PTI=m
CONFIG_INTEL_TH_DEBUG=y
# end of HW tracing support
CONFIG_FPGA=m
CONFIG_FPGA_MGR_SOCFPGA=m
CONFIG_FPGA_MGR_SOCFPGA_A10=m
CONFIG_ALTERA_PR_IP_CORE=m
CONFIG_ALTERA_PR_IP_CORE_PLAT=m
CONFIG_FPGA_MGR_ALTERA_PS_SPI=m
CONFIG_FPGA_MGR_ALTERA_CVP=m
CONFIG_FPGA_MGR_ZYNQ_FPGA=m
CONFIG_FPGA_MGR_XILINX_CORE=m
CONFIG_FPGA_MGR_XILINX_SELECTMAP=m
CONFIG_FPGA_MGR_XILINX_SPI=m
CONFIG_FPGA_MGR_ICE40_SPI=m
CONFIG_FPGA_MGR_MACHXO2_SPI=m
CONFIG_FPGA_BRIDGE=m
CONFIG_ALTERA_FREEZE_BRIDGE=m
CONFIG_XILINX_PR_DECOUPLER=m
CONFIG_FPGA_REGION=m
CONFIG_OF_FPGA_REGION=m
CONFIG_FPGA_DFL=m
CONFIG_FPGA_DFL_FME=m
CONFIG_FPGA_DFL_FME_MGR=m
CONFIG_FPGA_DFL_FME_BRIDGE=m
CONFIG_FPGA_DFL_FME_REGION=m
CONFIG_FPGA_DFL_AFU=m
CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000=m
CONFIG_FPGA_DFL_PCI=m
CONFIG_FPGA_MGR_ZYNQMP_FPGA=m
CONFIG_FPGA_MGR_VERSAL_FPGA=m
CONFIG_FPGA_M10_BMC_SEC_UPDATE=m
CONFIG_FPGA_MGR_MICROCHIP_SPI=m
CONFIG_FPGA_MGR_LATTICE_SYSCONFIG=m
CONFIG_FPGA_MGR_LATTICE_SYSCONFIG_SPI=m
CONFIG_FSI=m
CONFIG_FSI_NEW_DEV_NODE=y
CONFIG_FSI_MASTER_GPIO=m
CONFIG_FSI_MASTER_HUB=m
CONFIG_FSI_MASTER_AST_CF=m
CONFIG_FSI_MASTER_ASPEED=m
CONFIG_FSI_MASTER_I2CR=m
CONFIG_FSI_SCOM=m
CONFIG_FSI_SBEFIFO=m
CONFIG_FSI_OCC=m
CONFIG_I2CR_SCOM=m
CONFIG_TEE=m
CONFIG_TEE_DMABUF_HEAPS=y
CONFIG_OPTEE_STATIC_PROTMEM_POOL=y
CONFIG_QCOMTEE=m
CONFIG_MULTIPLEXER=m
#
# Multiplexer drivers
#
CONFIG_MUX_ADG792A=m
CONFIG_MUX_ADGS1408=m
CONFIG_MUX_GPIO=m
CONFIG_MUX_MMIO=m
# end of Multiplexer drivers
CONFIG_PM_OPP=y
CONFIG_SIOX=m
CONFIG_SIOX_BUS_GPIO=m
CONFIG_SLIMBUS=m
CONFIG_SLIM_QCOM_NGD_CTRL=m
CONFIG_INTERCONNECT=y
CONFIG_INTERCONNECT_IMX=m
CONFIG_INTERCONNECT_IMX8MM=m
CONFIG_INTERCONNECT_IMX8MN=m
CONFIG_INTERCONNECT_IMX8MQ=m
CONFIG_INTERCONNECT_IMX8MP=m
CONFIG_INTERCONNECT_MTK=y
CONFIG_INTERCONNECT_QCOM_OSM_L3=m
CONFIG_INTERCONNECT_SAMSUNG=y
CONFIG_INTERCONNECT_EXYNOS=m
CONFIG_INTERCONNECT_CLK=m
CONFIG_INTERCONNECT_KUNIT_TEST=m
CONFIG_I8254=m
CONFIG_COUNTER=m
CONFIG_104_QUAD_8=m
CONFIG_FTM_QUADDEC=m
CONFIG_INTEL_QEP=m
CONFIG_INTERRUPT_CNT=m
CONFIG_MICROCHIP_TCB_CAPTURE=m
CONFIG_RZ_MTU3_CNT=m
CONFIG_STM32_LPTIMER_CNT=m
CONFIG_STM32_TIMER_CNT=m
CONFIG_TI_ECAP_CAPTURE=m
CONFIG_TI_EQEP=m
CONFIG_MOST=m
CONFIG_MOST_USB_HDM=m
CONFIG_MOST_CDEV=m
CONFIG_MOST_SND=m
CONFIG_PECI=m
CONFIG_PECI_CPU=m
CONFIG_PECI_ASPEED=m
CONFIG_PECI_NPCM=m
CONFIG_HTE=y
CONFIG_HTE_TEGRA194=m
CONFIG_HTE_TEGRA194_TEST=m
CONFIG_CDX_BUS=y
CONFIG_CDX_CONTROLLER=m
# end of Device Drivers
#
# File systems
#
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_VALIDATE_FS_PARSER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_STACK=y
CONFIG_BUFFER_HEAD=y
CONFIG_LEGACY_DIRECT_IO=y
CONFIG_EXT2_FS=m
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT4_FS=m
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_DEBUG=y
CONFIG_EXT4_KUNIT_TESTS=m
CONFIG_JBD2=m
CONFIG_JBD2_DEBUG=y
CONFIG_FS_MBCACHE=m
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
CONFIG_JFS_SECURITY=y
CONFIG_JFS_DEBUG=y
CONFIG_JFS_STATISTICS=y
CONFIG_XFS_FS=m
CONFIG_XFS_SUPPORT_V4=y
CONFIG_XFS_SUPPORT_ASCII_CI=y
CONFIG_XFS_QUOTA=y
CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
CONFIG_XFS_DRAIN_INTENTS=y
CONFIG_XFS_LIVE_HOOKS=y
CONFIG_XFS_MEMORY_BUFS=y
CONFIG_XFS_BTREE_IN_MEM=y
CONFIG_XFS_ONLINE_SCRUB=y
CONFIG_XFS_ONLINE_SCRUB_STATS=y
CONFIG_XFS_ONLINE_REPAIR=y
CONFIG_XFS_DEBUG=y
CONFIG_XFS_DEBUG_EXPENSIVE=y
CONFIG_XFS_ASSERT_FATAL=y
CONFIG_GFS2_FS=m
CONFIG_GFS2_FS_LOCKING_DLM=y
CONFIG_OCFS2_FS=m
CONFIG_OCFS2_FS_O2CB=m
CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
CONFIG_OCFS2_FS_STATS=y
CONFIG_OCFS2_DEBUG_MASKLOG=y
CONFIG_OCFS2_DEBUG_FS=y
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_BTRFS_FS_RUN_SANITY_TESTS=y
CONFIG_BTRFS_DEBUG=y
CONFIG_BTRFS_ASSERT=y
CONFIG_BTRFS_EXPERIMENTAL=y
CONFIG_NILFS2_FS=m
CONFIG_F2FS_FS=m
CONFIG_F2FS_STAT_FS=y
CONFIG_F2FS_FS_XATTR=y
CONFIG_F2FS_FS_POSIX_ACL=y
CONFIG_F2FS_FS_SECURITY=y
CONFIG_F2FS_CHECK_FS=y
CONFIG_F2FS_FAULT_INJECTION=y
CONFIG_F2FS_FS_COMPRESSION=y
CONFIG_F2FS_FS_LZO=y
CONFIG_F2FS_FS_LZORLE=y
CONFIG_F2FS_FS_LZ4=y
CONFIG_F2FS_FS_LZ4HC=y
CONFIG_F2FS_FS_ZSTD=y
CONFIG_F2FS_IOSTAT=y
CONFIG_F2FS_UNFAIR_RWSEM=y
CONFIG_ZONEFS_FS=m
CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
CONFIG_EXPORTFS_BLOCK_OPS=y
CONFIG_FILE_LOCKING=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=m
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
CONFIG_FS_VERITY=y
CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QUOTA_DEBUG=y
CONFIG_QUOTA_TREE=m
CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m
CONFIG_QUOTACTL=y
CONFIG_AUTOFS_FS=m
CONFIG_FUSE_FS=m
CONFIG_CUSE=m
CONFIG_VIRTIO_FS=m
CONFIG_FUSE_PASSTHROUGH=y
CONFIG_FUSE_IO_URING=y
CONFIG_OVERLAY_FS=m
CONFIG_OVERLAY_FS_REDIRECT_DIR=y
CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
CONFIG_OVERLAY_FS_INDEX=y
CONFIG_OVERLAY_FS_METACOPY=y
CONFIG_OVERLAY_FS_DEBUG=y
#
# Caches
#
CONFIG_NETFS_SUPPORT=m
CONFIG_NETFS_STATS=y
CONFIG_NETFS_DEBUG=y
CONFIG_FSCACHE=y
CONFIG_FSCACHE_STATS=y
CONFIG_CACHEFILES=m
CONFIG_CACHEFILES_DEBUG=y
CONFIG_CACHEFILES_ERROR_INJECTION=y
CONFIG_CACHEFILES_ONDEMAND=y
# end of Caches
#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
# end of CD-ROM/DVD Filesystems
#
# DOS/FAT/EXFAT/NT Filesystems
#
CONFIG_FAT_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_FAT_DEFAULT_UTF8=y
CONFIG_FAT_KUNIT_TEST=m
CONFIG_EXFAT_FS=m
CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8"
CONFIG_NTFS3_FS=m
CONFIG_NTFS3_LZX_XPRESS=y
CONFIG_NTFS3_FS_POSIX_ACL=y
CONFIG_NTFS_FS=m
# end of DOS/FAT/EXFAT/NT Filesystems
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_VMCORE=y
CONFIG_PROC_VMCORE_DEVICE_DUMP=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_PROC_CHILDREN=y
CONFIG_PROC_PID_ARCH_STATUS=y
CONFIG_PROC_CPU_RESCTRL=y
CONFIG_KERNFS=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TMPFS_XATTR=y
CONFIG_TMPFS_QUOTA=y
CONFIG_ARCH_SUPPORTS_HUGETLBFS=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=y
CONFIG_EFIVAR_FS=m
# end of Pseudo filesystems
CONFIG_MISC_FILESYSTEMS=y
CONFIG_ORANGEFS_FS=m
CONFIG_ADFS_FS=m
CONFIG_ADFS_FS_RW=y
CONFIG_AFFS_FS=m
CONFIG_ECRYPT_FS=m
CONFIG_ECRYPT_FS_MESSAGING=y
CONFIG_HFS_FS=m
CONFIG_HFS_KUNIT_TEST=m
CONFIG_HFSPLUS_FS=m
CONFIG_HFSPLUS_KUNIT_TEST=m
CONFIG_BEFS_FS=m
CONFIG_BEFS_DEBUG=y
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
CONFIG_JFFS2_FS=m
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
CONFIG_JFFS2_FS_WBUF_VERIFY=y
CONFIG_JFFS2_SUMMARY=y
CONFIG_JFFS2_FS_XATTR=y
CONFIG_JFFS2_FS_POSIX_ACL=y
CONFIG_JFFS2_FS_SECURITY=y
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_LZO=y
CONFIG_JFFS2_RTIME=y
CONFIG_JFFS2_RUBIN=y
# CONFIG_JFFS2_CMODE_NONE is not set
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
CONFIG_UBIFS_FS=m
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_ZLIB=y
CONFIG_UBIFS_FS_ZSTD=y
CONFIG_UBIFS_ATIME_SUPPORT=y
CONFIG_UBIFS_FS_XATTR=y
CONFIG_UBIFS_FS_SECURITY=y
CONFIG_UBIFS_FS_AUTHENTICATION=y
CONFIG_CRAMFS=m
CONFIG_CRAMFS_BLOCKDEV=y
CONFIG_CRAMFS_MTD=y
CONFIG_SQUASHFS=m
CONFIG_SQUASHFS_FILE_CACHE=y
# CONFIG_SQUASHFS_FILE_DIRECT is not set
CONFIG_SQUASHFS_DECOMP_SINGLE=y
CONFIG_SQUASHFS_DECOMP_MULTI=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT=y
CONFIG_SQUASHFS_MOUNT_DECOMP_THREADS=y
CONFIG_SQUASHFS_XATTR=y
CONFIG_SQUASHFS_COMP_CACHE_FULL=y
CONFIG_SQUASHFS_ZLIB=y
CONFIG_SQUASHFS_LZ4=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_ZSTD=y
CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
CONFIG_SQUASHFS_EMBEDDED=y
CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
CONFIG_VXFS_FS=m
CONFIG_MINIX_FS=m
CONFIG_OMFS_FS=m
CONFIG_HPFS_FS=m
CONFIG_QNX4FS_FS=m
CONFIG_QNX6FS_FS=m
CONFIG_QNX6FS_DEBUG=y
CONFIG_RESCTRL_FS=y
CONFIG_RESCTRL_FS_PSEUDO_LOCK=y
CONFIG_ROMFS_FS=m
CONFIG_ROMFS_BACKED_BY_BLOCK=y
# CONFIG_ROMFS_BACKED_BY_MTD is not set
# CONFIG_ROMFS_BACKED_BY_BOTH is not set
CONFIG_ROMFS_ON_BLOCK=y
CONFIG_PSTORE=y
CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240
CONFIG_PSTORE_COMPRESS=y
CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_PMSG=y
CONFIG_PSTORE_FTRACE=y
CONFIG_PSTORE_RAM=m
CONFIG_PSTORE_ZONE=m
CONFIG_PSTORE_BLK=m
CONFIG_PSTORE_BLK_BLKDEV=""
CONFIG_PSTORE_BLK_KMSG_SIZE=64
CONFIG_PSTORE_BLK_MAX_REASON=2
CONFIG_PSTORE_BLK_PMSG_SIZE=64
CONFIG_PSTORE_BLK_CONSOLE_SIZE=64
CONFIG_PSTORE_BLK_FTRACE_SIZE=64
CONFIG_UFS_FS=m
CONFIG_UFS_FS_WRITE=y
CONFIG_UFS_DEBUG=y
CONFIG_EROFS_FS=m
CONFIG_EROFS_FS_DEBUG=y
CONFIG_EROFS_FS_XATTR=y
CONFIG_EROFS_FS_POSIX_ACL=y
CONFIG_EROFS_FS_SECURITY=y
CONFIG_EROFS_FS_BACKED_BY_FILE=y
CONFIG_EROFS_FS_ZIP=y
CONFIG_EROFS_FS_ZIP_LZMA=y
CONFIG_EROFS_FS_ZIP_DEFLATE=y
CONFIG_EROFS_FS_ZIP_ZSTD=y
CONFIG_EROFS_FS_ZIP_ACCEL=y
CONFIG_EROFS_FS_ONDEMAND=y
CONFIG_EROFS_FS_PCPU_KTHREAD=y
CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI=y
CONFIG_VBOXSF_FS=m
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=m
CONFIG_NFS_V2=m
CONFIG_NFS_V3=m
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_NFS_V4_0=y
CONFIG_NFS_V4_2=y
CONFIG_PNFS_FILE_LAYOUT=m
CONFIG_PNFS_BLOCK=m
CONFIG_PNFS_FLEXFILE_LAYOUT=m
CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
CONFIG_NFS_V4_1_MIGRATION=y
CONFIG_NFS_V4_SECURITY_LABEL=y
CONFIG_NFS_FSCACHE=y
CONFIG_NFS_USE_LEGACY_DNS=y
CONFIG_NFS_DEBUG=y
CONFIG_NFS_DISABLE_UDP_SUPPORT=y
CONFIG_NFS_V4_2_READ_PLUS=y
CONFIG_NFSD=m
CONFIG_NFSD_V2=y
CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_PNFS=y
CONFIG_NFSD_BLOCKLAYOUT=y
CONFIG_NFSD_SCSILAYOUT=y
CONFIG_NFSD_FLEXFILELAYOUT=y
CONFIG_NFSD_V4_2_INTER_SSC=y
CONFIG_NFSD_V4_SECURITY_LABEL=y
CONFIG_NFSD_LEGACY_CLIENT_TRACKING=y
# CONFIG_NFSD_V4_DELEG_TIMESTAMPS is not set
CONFIG_NFSD_V4_POSIX_ACLS=y
CONFIG_GRACE_PERIOD=m
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_ACL_SUPPORT=m
CONFIG_NFS_COMMON=y
CONFIG_NFS_COMMON_LOCALIO_SUPPORT=m
CONFIG_NFS_LOCALIO=y
CONFIG_NFS_V4_2_SSC_HELPER=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_SUNRPC_BACKCHANNEL=y
CONFIG_SUNRPC_SWAP=y
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1=y
CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA=y
CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2=y
CONFIG_RPCSEC_GSS_KRB5_KUNIT_TEST=m
CONFIG_SUNRPC_DEBUG=y
CONFIG_SUNRPC_DEBUG_TRACE=y
CONFIG_SUNRPC_XPRT_RDMA=m
CONFIG_CEPH_FS=m
CONFIG_CEPH_FSCACHE=y
CONFIG_CEPH_FS_POSIX_ACL=y
CONFIG_CEPH_FS_SECURITY_LABEL=y
CONFIG_CIFS=m
CONFIG_CIFS_STATS2=y
CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_CIFS_DEBUG=y
CONFIG_CIFS_DEBUG2=y
CONFIG_CIFS_DEBUG_DUMP_KEYS=y
CONFIG_CIFS_DFS_UPCALL=y
CONFIG_CIFS_SWN_UPCALL=y
CONFIG_CIFS_SMB_DIRECT=y
CONFIG_CIFS_FSCACHE=y
CONFIG_CIFS_COMPRESSION=y
CONFIG_SMB_SERVER=m
CONFIG_SMB_SERVER_SMBDIRECT=y
CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN=y
CONFIG_SMB_SERVER_KERBEROS5=y
CONFIG_SMBFS=m
CONFIG_SMB_KUNIT_TESTS=m
CONFIG_CODA_FS=m
CONFIG_AFS_FS=m
CONFIG_AFS_DEBUG=y
CONFIG_AFS_FSCACHE=y
CONFIG_AFS_DEBUG_CURSOR=y
CONFIG_9P_FS=m
CONFIG_9P_FSCACHE=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_CODEPAGE_852=m
CONFIG_NLS_CODEPAGE_855=m
CONFIG_NLS_CODEPAGE_857=m
CONFIG_NLS_CODEPAGE_860=m
CONFIG_NLS_CODEPAGE_861=m
CONFIG_NLS_CODEPAGE_862=m
CONFIG_NLS_CODEPAGE_863=m
CONFIG_NLS_CODEPAGE_864=m
CONFIG_NLS_CODEPAGE_865=m
CONFIG_NLS_CODEPAGE_866=m
CONFIG_NLS_CODEPAGE_869=m
CONFIG_NLS_CODEPAGE_936=m
CONFIG_NLS_CODEPAGE_950=m
CONFIG_NLS_CODEPAGE_932=m
CONFIG_NLS_CODEPAGE_949=m
CONFIG_NLS_CODEPAGE_874=m
CONFIG_NLS_ISO8859_8=m
CONFIG_NLS_CODEPAGE_1250=m
CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
CONFIG_NLS_ISO8859_9=m
CONFIG_NLS_ISO8859_13=m
CONFIG_NLS_ISO8859_14=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_MAC_ROMAN=m
CONFIG_NLS_MAC_CELTIC=m
CONFIG_NLS_MAC_CENTEURO=m
CONFIG_NLS_MAC_CROATIAN=m
CONFIG_NLS_MAC_CYRILLIC=m
CONFIG_NLS_MAC_GAELIC=m
CONFIG_NLS_MAC_GREEK=m
CONFIG_NLS_MAC_ICELAND=m
CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_NLS_UTF8=m
CONFIG_NLS_UCS2_UTILS=m
CONFIG_DLM=m
CONFIG_DLM_DEBUG=y
CONFIG_UNICODE=m
CONFIG_UNICODE_NORMALIZATION_KUNIT_TEST=m
CONFIG_IO_WQ=y
# end of File systems
#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_REQUEST_CACHE=y
CONFIG_PERSISTENT_KEYRINGS=y
CONFIG_BIG_KEYS=y
CONFIG_TRUSTED_KEYS=m
CONFIG_HAVE_TRUSTED_KEYS=y
CONFIG_TRUSTED_KEYS_TPM=y
CONFIG_TRUSTED_KEYS_TEE=y
CONFIG_TRUSTED_KEYS_CAAM=y
CONFIG_ENCRYPTED_KEYS=y
CONFIG_USER_DECRYPTED_DATA=y
CONFIG_KEY_DH_OPERATIONS=y
CONFIG_KEY_NOTIFICATIONS=y
CONFIG_SECURITY_DMESG_RESTRICT=y
CONFIG_PROC_MEM_ALWAYS_FORCE=y
# CONFIG_PROC_MEM_FORCE_PTRACE is not set
# CONFIG_PROC_MEM_NO_FORCE is not set
CONFIG_SECURITY=y
CONFIG_HAS_SECURITY_AUDIT=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_INFINIBAND=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_PATH=y
CONFIG_INTEL_TXT=y
CONFIG_LSM_MMAP_MIN_ADDR=65536
CONFIG_STATIC_USERMODEHELPER=y
CONFIG_STATIC_USERMODEHELPER_PATH="/sbin/usermode-helper"
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
CONFIG_SECURITY_SELINUX_AVC_STATS=y
CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9
CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256
CONFIG_SECURITY_SELINUX_AVC_HASH_BITS=9
CONFIG_SECURITY_SELINUX_DEBUG=y
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_SMACK_BRINGUP=y
CONFIG_SECURITY_SMACK_NETFILTER=y
CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y
CONFIG_SECURITY_TOMOYO=y
CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048
CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024
CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER=y
CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING=y
CONFIG_SECURITY_APPARMOR=y
CONFIG_SECURITY_APPARMOR_DEBUG=y
CONFIG_SECURITY_APPARMOR_DEBUG_ASSERTS=y
CONFIG_SECURITY_APPARMOR_DEBUG_MESSAGES=y
CONFIG_SECURITY_APPARMOR_INTROSPECT_POLICY=y
CONFIG_SECURITY_APPARMOR_HASH=y
CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y
CONFIG_SECURITY_APPARMOR_EXPORT_BINARY=y
CONFIG_SECURITY_APPARMOR_PARANOID_LOAD=y
CONFIG_SECURITY_APPARMOR_KUNIT_TEST=m
CONFIG_SECURITY_LOADPIN=y
CONFIG_SECURITY_LOADPIN_ENFORCE=y
CONFIG_SECURITY_YAMA=y
CONFIG_SECURITY_SAFESETID=y
CONFIG_SECURITY_LOCKDOWN_LSM=y
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y
# CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set
# CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set
CONFIG_SECURITY_LANDLOCK=y
CONFIG_SECURITY_IPE=y
CONFIG_IPE_BOOT_POLICY=""
CONFIG_IPE_POLICY_SIG_SECONDARY_KEYRING=y
CONFIG_IPE_POLICY_SIG_PLATFORM_KEYRING=y
#
# IPE Trust Providers
#
CONFIG_IPE_PROP_DM_VERITY=y
CONFIG_IPE_PROP_DM_VERITY_SIGNATURE=y
CONFIG_IPE_PROP_FS_VERITY=y
CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG=y
# end of IPE Trust Providers
CONFIG_INTEGRITY=y
CONFIG_INTEGRITY_SIGNATURE=y
CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
CONFIG_INTEGRITY_TRUSTED_KEYRING=y
CONFIG_INTEGRITY_PLATFORM_KEYRING=y
CONFIG_INTEGRITY_MACHINE_KEYRING=y
CONFIG_INTEGRITY_CA_MACHINE_KEYRING=y
CONFIG_INTEGRITY_CA_MACHINE_KEYRING_MAX=y
CONFIG_LOAD_UEFI_KEYS=y
CONFIG_INTEGRITY_AUDIT=y
CONFIG_IMA=y
CONFIG_IMA_MEASURE_PCR_IDX=10
CONFIG_IMA_LSM_RULES=y
CONFIG_IMA_NG_TEMPLATE=y
# CONFIG_IMA_SIG_TEMPLATE is not set
CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng"
CONFIG_IMA_DEFAULT_HASH_SHA1=y
# CONFIG_IMA_DEFAULT_HASH_SHA256 is not set
# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set
CONFIG_IMA_DEFAULT_HASH="sha1"
CONFIG_IMA_WRITE_POLICY=y
CONFIG_IMA_READ_POLICY=y
CONFIG_IMA_APPRAISE=y
CONFIG_IMA_ARCH_POLICY=y
CONFIG_IMA_APPRAISE_BUILD_POLICY=y
CONFIG_IMA_APPRAISE_REQUIRE_FIRMWARE_SIGS=y
CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS=y
CONFIG_IMA_APPRAISE_REQUIRE_MODULE_SIGS=y
CONFIG_IMA_APPRAISE_REQUIRE_POLICY_SIGS=y
CONFIG_IMA_APPRAISE_BOOTPARAM=y
CONFIG_IMA_APPRAISE_MODSIG=y
CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY=y
CONFIG_IMA_BLACKLIST_KEYRING=y
CONFIG_IMA_LOAD_X509=y
CONFIG_IMA_X509_PATH="/etc/keys/x509_ima.der"
CONFIG_IMA_APPRAISE_SIGNED_INIT=y
CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y
CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS=y
CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT=y
CONFIG_IMA_DISABLE_HTABLE=y
CONFIG_EVM=y
CONFIG_EVM_ATTR_FSUUID=y
CONFIG_EVM_EXTRA_SMACK_XATTRS=y
CONFIG_EVM_ADD_XATTRS=y
CONFIG_EVM_LOAD_X509=y
CONFIG_EVM_X509_PATH="/etc/keys/x509_evm.der"
CONFIG_DEFAULT_SECURITY_SELINUX=y
# CONFIG_DEFAULT_SECURITY_SMACK is not set
# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
# CONFIG_DEFAULT_SECURITY_APPARMOR is not set
# CONFIG_DEFAULT_SECURITY_DAC is not set
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,selinux,smack,tomoyo,apparmor,ipe,bpf"
#
# Kernel hardening options
#
#
# Memory initialization
#
CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y
# CONFIG_INIT_STACK_NONE is not set
CONFIG_INIT_STACK_ALL_PATTERN=y
# CONFIG_INIT_STACK_ALL_ZERO is not set
CONFIG_KSTACK_ERASE=y
CONFIG_GCC_PLUGIN_STACKLEAK=y
CONFIG_KSTACK_ERASE_TRACK_MIN_SIZE=100
CONFIG_KSTACK_ERASE_METRICS=y
CONFIG_KSTACK_ERASE_RUNTIME_DISABLE=y
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
CONFIG_INIT_ON_FREE_DEFAULT_ON=y
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
CONFIG_ZERO_CALL_USED_REGS=y
# end of Memory initialization
#
# Bounds checking
#
CONFIG_FORTIFY_SOURCE=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_HARDENED_USERCOPY_DEFAULT_ON=y
# end of Bounds checking
#
# Hardening of kernel data structures
#
CONFIG_LIST_HARDENED=y
CONFIG_BUG_ON_DATA_CORRUPTION=y
# end of Hardening of kernel data structures
# CONFIG_RANDSTRUCT_NONE is not set
CONFIG_RANDSTRUCT_FULL=y
# CONFIG_RANDSTRUCT_PERFORMANCE is not set
CONFIG_RANDSTRUCT=y
CONFIG_GCC_PLUGIN_RANDSTRUCT=y
# end of Kernel hardening options
# end of Security options
CONFIG_XOR_BLOCKS=m
CONFIG_ASYNC_CORE=m
CONFIG_ASYNC_MEMCPY=m
CONFIG_ASYNC_XOR=m
CONFIG_ASYNC_PQ=m
CONFIG_ASYNC_RAID6_RECOV=m
CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA=y
CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA=y
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_FIPS_NAME="Linux Kernel Cryptographic API"
CONFIG_CRYPTO_FIPS_CUSTOM_VERSION=y
CONFIG_CRYPTO_FIPS_VERSION="(none)"
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=m
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_SIG=y
CONFIG_CRYPTO_SIG2=y
CONFIG_CRYPTO_SKCIPHER=y
CONFIG_CRYPTO_SKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_AKCIPHER2=y
CONFIG_CRYPTO_AKCIPHER=y
CONFIG_CRYPTO_KPP2=y
CONFIG_CRYPTO_KPP=y
CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_HKDF=m
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_USER=m
CONFIG_CRYPTO_SELFTESTS=y
CONFIG_CRYPTO_SELFTESTS_FULL=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_PCRYPT=m
CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_AUTHENC=m
CONFIG_CRYPTO_KRB5ENC=m
CONFIG_CRYPTO_BENCHMARK=m
CONFIG_CRYPTO_ENGINE=m
# end of Crypto core or helper
#
# Public-key cryptography
#
CONFIG_CRYPTO_RSA=y
CONFIG_CRYPTO_DH=y
CONFIG_CRYPTO_DH_RFC7919_GROUPS=y
CONFIG_CRYPTO_ECC=y
CONFIG_CRYPTO_ECDH=y
CONFIG_CRYPTO_ECDSA=m
CONFIG_CRYPTO_ECRDSA=m
CONFIG_CRYPTO_MLDSA=m
# end of Public-key cryptography
#
# Block ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_ARIA=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_BLOWFISH_COMMON=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST_COMMON=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SEED=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_SM4=m
CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
# end of Block ciphers
#
# Length-preserving ciphers and modes
#
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_CHACHA20=m
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XCTR=m
CONFIG_CRYPTO_XTS=m
# end of Length-preserving ciphers and modes
#
# AEAD (authenticated encryption with associated data) ciphers
#
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_CHACHA20POLY1305=m
CONFIG_CRYPTO_CCM=m
CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_GENIV=m
CONFIG_CRYPTO_SEQIV=m
CONFIG_CRYPTO_ECHAINIV=m
CONFIG_CRYPTO_ESSIV=m
# end of AEAD (authenticated encryption with associated data) ciphers
#
# Hashes, digests, and MACs
#
CONFIG_CRYPTO_BLAKE2B=m
CONFIG_CRYPTO_CMAC=m
CONFIG_CRYPTO_GHASH=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_SHA3=y
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_STREEBOG=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_XXHASH=m
# end of Hashes, digests, and MACs
#
# CRCs (cyclic redundancy checks)
#
CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_CRC32=m
# end of CRCs (cyclic redundancy checks)
#
# Compression
#
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_842=m
CONFIG_CRYPTO_LZ4=m
CONFIG_CRYPTO_LZ4HC=m
CONFIG_CRYPTO_ZSTD=m
# end of Compression
#
# Random number generation
#
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_HASH=y
CONFIG_CRYPTO_DRBG_CTR=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_JITTERENTROPY_MEMSIZE_2=y
# CONFIG_CRYPTO_JITTERENTROPY_MEMSIZE_128 is not set
# CONFIG_CRYPTO_JITTERENTROPY_MEMSIZE_1024 is not set
# CONFIG_CRYPTO_JITTERENTROPY_MEMSIZE_8192 is not set
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
CONFIG_CRYPTO_JITTERENTROPY_OSR=3
CONFIG_CRYPTO_JITTERENTROPY_TESTINTERFACE=y
CONFIG_CRYPTO_KDF800108_CTR=y
CONFIG_CRYPTO_DF80090A=y
# end of Random number generation
#
# Userspace interface
#
CONFIG_CRYPTO_USER_API=m
CONFIG_CRYPTO_USER_API_HASH=m
CONFIG_CRYPTO_USER_API_SKCIPHER=m
CONFIG_CRYPTO_USER_API_RNG=m
CONFIG_CRYPTO_USER_API_RNG_CAVP=y
CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y
# end of Userspace interface
#
# Accelerated Cryptographic Algorithms for CPU (x86)
#
CONFIG_CRYPTO_AES_NI_INTEL=m
CONFIG_CRYPTO_SERPENT_SSE2_586=m
CONFIG_CRYPTO_TWOFISH_586=m
# end of Accelerated Cryptographic Algorithms for CPU (x86)
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_ALLWINNER=y
CONFIG_CRYPTO_DEV_SUN8I_CE=m
CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG=y
CONFIG_CRYPTO_DEV_SUN8I_CE_HASH=y
CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG=y
CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG=y
CONFIG_CRYPTO_DEV_SUN8I_SS=m
CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG=y
CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG=y
CONFIG_CRYPTO_DEV_SUN8I_SS_HASH=y
CONFIG_CRYPTO_DEV_PADLOCK=m
CONFIG_CRYPTO_DEV_PADLOCK_AES=m
CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
CONFIG_CRYPTO_DEV_GEODE=m
CONFIG_CRYPTO_DEV_SL3516=m
CONFIG_CRYPTO_DEV_SL3516_DEBUG=y
CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=m
CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=m
CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=m
CONFIG_CRYPTO_DEV_FSL_CAAM=m
CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG=y
CONFIG_CRYPTO_DEV_FSL_CAAM_JR=m
CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
CONFIG_CRYPTO_DEV_FSL_CAAM_INTC=y
CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD=255
CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD=2048
CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI=y
CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_BLOB_GEN=y
CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST=y
CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=m
CONFIG_CRYPTO_DEV_EXYNOS_RNG=m
CONFIG_CRYPTO_DEV_S5P=m
CONFIG_CRYPTO_DEV_ATMEL_AUTHENC=y
CONFIG_CRYPTO_DEV_ATMEL_AES=m
CONFIG_CRYPTO_DEV_ATMEL_TDES=m
CONFIG_CRYPTO_DEV_ATMEL_SHA=m
CONFIG_CRYPTO_DEV_ATMEL_I2C=m
CONFIG_CRYPTO_DEV_ATMEL_ECC=m
CONFIG_CRYPTO_DEV_ATMEL_SHA204A=m
CONFIG_CRYPTO_DEV_CCP=y
CONFIG_CRYPTO_DEV_CCP_DD=m
CONFIG_CRYPTO_DEV_SP_CCP=y
CONFIG_CRYPTO_DEV_CCP_CRYPTO=m
CONFIG_CRYPTO_DEV_CCP_DEBUGFS=y
CONFIG_CRYPTO_DEV_MARVELL=m
CONFIG_CRYPTO_DEV_MARVELL_CESA=m
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4=m
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB=y
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS=y
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_ECC=m
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU=m
CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU_HMAC_SHA224=y
CONFIG_CRYPTO_DEV_IXP4XX=m
CONFIG_CRYPTO_DEV_QAT=m
CONFIG_CRYPTO_DEV_QAT_DH895xCC=m
CONFIG_CRYPTO_DEV_QAT_C3XXX=m
CONFIG_CRYPTO_DEV_QAT_C62X=m
CONFIG_CRYPTO_DEV_QAT_4XXX=m
CONFIG_CRYPTO_DEV_QAT_420XX=m
CONFIG_CRYPTO_DEV_QAT_6XXX=m
CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=m
CONFIG_CRYPTO_DEV_QAT_C3XXXVF=m
CONFIG_CRYPTO_DEV_QAT_C62XVF=m
CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION=y
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y
CONFIG_CRYPTO_DEV_QCE_SHA=y
CONFIG_CRYPTO_DEV_QCE_AEAD=y
CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y
# CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER is not set
# CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set
# CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set
CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512
CONFIG_CRYPTO_DEV_QCOM_RNG=m
CONFIG_CRYPTO_DEV_IMGTEC_HASH=m
CONFIG_CRYPTO_DEV_TEGRA=m
CONFIG_CRYPTO_DEV_XILINX_TRNG=m
CONFIG_CRYPTO_DEV_ZYNQMP_AES=m
CONFIG_CRYPTO_DEV_ZYNQMP_SHA3=m
CONFIG_CRYPTO_DEV_CHELSIO=m
CONFIG_CRYPTO_DEV_VIRTIO=m
CONFIG_CRYPTO_DEV_SAFEXCEL=m
CONFIG_CRYPTO_DEV_CCREE=m
CONFIG_CRYPTO_DEV_HISI_SEC=m
CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m
CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG=y
CONFIG_CRYPTO_DEV_SA2UL=m
CONFIG_CRYPTO_DEV_ASPEED=m
CONFIG_CRYPTO_DEV_ASPEED_DEBUG=y
CONFIG_CRYPTO_DEV_ASPEED_HACE_HASH=y
CONFIG_CRYPTO_DEV_ASPEED_HACE_CRYPTO=y
CONFIG_CRYPTO_DEV_ASPEED_ACRY=y
CONFIG_CRYPTO_DEV_JH7110=m
CONFIG_CRYPTO_DEV_EIP93=m
CONFIG_CRYPTO_DEV_TI_DTHEV2=m
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
CONFIG_X509_CERTIFICATE_PARSER=y
CONFIG_PKCS8_PRIVATE_KEY_PARSER=m
CONFIG_PKCS7_MESSAGE_PARSER=y
CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA=y
CONFIG_PKCS7_TEST_KEY=m
CONFIG_SIGNED_PE_FILE_VERIFICATION=y
CONFIG_FIPS_SIGNATURE_SELFTEST=m
CONFIG_FIPS_SIGNATURE_SELFTEST_RSA=y
CONFIG_FIPS_SIGNATURE_SELFTEST_ECDSA=y
#
# Certificates for signature checking
#
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
CONFIG_MODULE_SIG_KEY_TYPE_RSA=y
# CONFIG_MODULE_SIG_KEY_TYPE_ECDSA is not set
# CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_44 is not set
# CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_65 is not set
# CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_87 is not set
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_SYSTEM_EXTRA_CERTIFICATE=y
CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096
CONFIG_SECONDARY_TRUSTED_KEYRING=y
CONFIG_SECONDARY_TRUSTED_KEYRING_SIGNED_BY_BUILTIN=y
CONFIG_SYSTEM_BLACKLIST_KEYRING=y
CONFIG_SYSTEM_BLACKLIST_HASH_LIST=""
CONFIG_SYSTEM_REVOCATION_LIST=y
CONFIG_SYSTEM_REVOCATION_KEYS=""
CONFIG_SYSTEM_BLACKLIST_AUTH_UPDATE=y
CONFIG_OPENSSL_SUPPORTS_ML_DSA=y
# end of Certificates for signature checking
CONFIG_CRYPTO_KRB5=m
CONFIG_CRYPTO_KRB5_SELFTESTS=y
CONFIG_BINARY_PRINTF=y
#
# Library routines
#
CONFIG_RAID6_PQ=m
CONFIG_RAID6_PQ_BENCHMARK=y
CONFIG_LINEAR_RANGES=y
CONFIG_PACKING=y
CONFIG_PACKING_KUNIT_TEST=m
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_CORDIC=m
CONFIG_PRIME_NUMBERS=m
CONFIG_RATIONAL=y
CONFIG_GENERIC_IOMAP=y
CONFIG_STMP_DEVICE=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
CONFIG_ARCH_HAS_FAST_MULTIPLIER=y
CONFIG_ARCH_USE_SYM_ANNOTATIONS=y
CONFIG_CRC4=m
CONFIG_CRC7=m
CONFIG_CRC8=y
CONFIG_CRC16=m
CONFIG_CRC_CCITT=m
CONFIG_CRC_ITU_T=m
CONFIG_CRC_T10DIF=y
CONFIG_CRC_T10DIF_ARCH=y
CONFIG_CRC32=y
CONFIG_CRC32_ARCH=y
CONFIG_CRC64=y
CONFIG_CRC_OPTIMIZATIONS=y
CONFIG_CRC_KUNIT_TEST=m
CONFIG_CRC_BENCHMARK=y
#
# Crypto library routines
#
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LIB_AES=y
CONFIG_CRYPTO_LIB_AES_ARCH=y
CONFIG_CRYPTO_LIB_AESCFB=y
CONFIG_CRYPTO_LIB_ARC4=m
CONFIG_CRYPTO_LIB_GF128MUL=m
CONFIG_CRYPTO_LIB_BLAKE2B=m
CONFIG_CRYPTO_LIB_CHACHA=y
CONFIG_CRYPTO_LIB_CURVE25519=m
CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=y
CONFIG_CRYPTO_LIB_DES=m
CONFIG_CRYPTO_LIB_MD5=y
CONFIG_CRYPTO_LIB_MLDSA=m
CONFIG_CRYPTO_LIB_NH=m
CONFIG_CRYPTO_LIB_POLY1305=y
CONFIG_CRYPTO_LIB_POLY1305_GENERIC=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
CONFIG_CRYPTO_LIB_POLYVAL=m
CONFIG_CRYPTO_LIB_CHACHA20POLY1305=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LIB_SHA512=y
CONFIG_CRYPTO_LIB_SHA3=y
CONFIG_CRYPTO_LIB_SM3=m
CONFIG_CRYPTO_LIB_BLAKE2B_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_CURVE25519_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_MD5_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_MLDSA_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_NH_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_POLY1305_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_POLYVAL_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_SHA1_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_SHA256_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_SHA512_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_SHA3_KUNIT_TEST=m
CONFIG_CRYPTO_LIB_BENCHMARK_VISIBLE=y
CONFIG_CRYPTO_LIB_BENCHMARK=y
# end of Crypto library routines
CONFIG_XXHASH=y
CONFIG_AUDIT_GENERIC=y
CONFIG_RANDOM32_SELFTEST=y
CONFIG_842_COMPRESS=m
CONFIG_842_DECOMPRESS=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_LZ4_COMPRESS=m
CONFIG_LZ4HC_COMPRESS=m
CONFIG_LZ4_DECOMPRESS=y
CONFIG_ZSTD_COMMON=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y
CONFIG_XZ_DEC=y
CONFIG_XZ_DEC_X86=y
CONFIG_XZ_DEC_POWERPC=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
CONFIG_XZ_DEC_ARM64=y
CONFIG_XZ_DEC_SPARC=y
CONFIG_XZ_DEC_RISCV=y
CONFIG_XZ_DEC_MICROLZMA=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_XZ_DEC_TEST=m
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_LZ4=y
CONFIG_DECOMPRESS_ZSTD=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_REED_SOLOMON=m
CONFIG_REED_SOLOMON_ENC8=y
CONFIG_REED_SOLOMON_DEC8=y
CONFIG_REED_SOLOMON_ENC16=y
CONFIG_REED_SOLOMON_DEC16=y
CONFIG_BCH=m
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
CONFIG_BTREE=y
CONFIG_INTERVAL_TREE=y
CONFIG_INTERVAL_TREE_SPAN_ITER=y
CONFIG_XARRAY_MULTI=y
CONFIG_ASSOCIATIVE_ARRAY=y
CONFIG_CLOSURES=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAS_DMA=y
CONFIG_DMA_OPS_HELPERS=y
CONFIG_NEED_SG_DMA_FLAGS=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_DMA_DECLARE_COHERENT=y
CONFIG_SWIOTLB=y
CONFIG_SWIOTLB_DYNAMIC=y
CONFIG_DMA_NEED_SYNC=y
CONFIG_DMA_RESTRICTED_POOL=y
CONFIG_DMA_CMA=y
#
# Default contiguous memory area size:
#
CONFIG_CMA_SIZE_MBYTES=0
CONFIG_CMA_SIZE_SEL_MBYTES=y
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
# CONFIG_CMA_SIZE_SEL_MIN is not set
# CONFIG_CMA_SIZE_SEL_MAX is not set
CONFIG_CMA_ALIGNMENT=8
CONFIG_DMA_API_DEBUG=y
CONFIG_DMA_MAP_BENCHMARK=y
CONFIG_SGL_ALLOC=y
CONFIG_CHECK_SIGNATURE=y
CONFIG_CPUMASK_OFFSTACK=y
CONFIG_CPU_RMAP=y
CONFIG_DQL=y
CONFIG_GLOB=y
CONFIG_NLATTR=y
CONFIG_LRU_CACHE=m
CONFIG_CLZ_TAB=y
CONFIG_IRQ_POLL=y
CONFIG_MPILIB=y
CONFIG_SIGNATURE=y
CONFIG_DIMLIB=y
CONFIG_LIBFDT=y
CONFIG_OID_REGISTRY=y
CONFIG_UCS2_STRING=y
CONFIG_HAVE_GENERIC_VDSO=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT=y
CONFIG_FONT_SUPPORT=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_FONT_6x11=y
CONFIG_FONT_7x14=y
CONFIG_FONT_PEARL_8x8=y
CONFIG_FONT_ACORN_8x8=y
CONFIG_FONT_MINI_4x6=y
CONFIG_FONT_6x10=y
CONFIG_FONT_10x18=y
CONFIG_FONT_SUN8x16=y
CONFIG_FONT_SUN12x22=y
CONFIG_FONT_TER10x18=y
CONFIG_FONT_TER16x32=y
CONFIG_FONT_6x8=y
CONFIG_SG_SPLIT=y
CONFIG_SG_POOL=y
CONFIG_MEMREGION=y
CONFIG_ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION=y
CONFIG_ARCH_STACKWALK=y
CONFIG_STACKDEPOT=y
CONFIG_STACKDEPOT_ALWAYS_INIT=y
CONFIG_STACKDEPOT_MAX_FRAMES=64
CONFIG_REF_TRACKER=y
CONFIG_SBITMAP=y
CONFIG_PARMAN=m
CONFIG_OBJAGG=m
CONFIG_LWQ_TEST=y
# end of Library routines
CONFIG_PLDMFW=y
CONFIG_ASN1_ENCODER=m
CONFIG_POLYNOMIAL=m
CONFIG_FIRMWARE_TABLE=y
CONFIG_UNION_FIND=y
#
# Kernel hacking
#
#
# printk and dmesg options
#
CONFIG_PRINTK_TIME=y
CONFIG_PRINTK_CALLER=y
CONFIG_PRINTK_EXECUTION_CTX=y
CONFIG_STACKTRACE_BUILD_ID=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
CONFIG_CONSOLE_LOGLEVEL_QUIET=4
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
CONFIG_BOOT_PRINTK_DELAY=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DYNAMIC_DEBUG_CORE=y
CONFIG_SYMBOLIC_ERRNAME=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_BUGVERBOSE_DETAILED=y
# end of printk and dmesg options
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MISC=y
#
# Compile-time checks and compiler options
#
CONFIG_AS_HAS_NON_CONST_ULEB128=y
CONFIG_DEBUG_INFO_NONE=y
# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
# CONFIG_DEBUG_INFO_DWARF4 is not set
# CONFIG_DEBUG_INFO_DWARF5 is not set
CONFIG_FRAME_WARN=2048
CONFIG_STRIP_ASM_SYMS=y
CONFIG_READABLE_ASM=y
CONFIG_HEADERS_INSTALL=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_FRAME_POINTER=y
CONFIG_VMLINUX_MAP=y
CONFIG_BUILTIN_MODULE_RANGES=y
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
# end of Compile-time checks and compiler options
#
# Generic Kernel Debugging Instruments
#
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
CONFIG_MAGIC_SYSRQ_SERIAL=y
CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_FS_ALLOW_ALL=y
# CONFIG_DEBUG_FS_ALLOW_NONE is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_HONOUR_BLOCKLIST=y
CONFIG_KGDB_SERIAL_CONSOLE=m
CONFIG_KGDB_TESTS=y
CONFIG_KGDB_TESTS_ON_BOOT=y
CONFIG_KGDB_TESTS_BOOT_STRING="V1F100"
CONFIG_KGDB_LOW_LEVEL_TRAP=y
CONFIG_KGDB_KDB=y
CONFIG_KDB_DEFAULT_ENABLE=0x1
CONFIG_KDB_KEYBOARD=y
CONFIG_KDB_CONTINUE_CATASTROPHIC=0
CONFIG_ARCH_HAS_EARLY_DEBUG=y
CONFIG_ARCH_HAS_UBSAN=y
CONFIG_UBSAN=y
CONFIG_CC_HAS_UBSAN_BOUNDS_STRICT=y
CONFIG_UBSAN_BOUNDS=y
CONFIG_UBSAN_BOUNDS_STRICT=y
CONFIG_UBSAN_SHIFT=y
CONFIG_UBSAN_DIV_ZERO=y
CONFIG_UBSAN_UNREACHABLE=y
CONFIG_UBSAN_BOOL=y
CONFIG_UBSAN_ENUM=y
CONFIG_TEST_UBSAN=m
CONFIG_HAVE_KCSAN_COMPILER=y
# end of Generic Kernel Debugging Instruments
#
# Networking Debugging
#
CONFIG_NET_DEV_REFCNT_TRACKER=y
CONFIG_NET_NS_REFCNT_TRACKER=y
CONFIG_DEBUG_NET=y
CONFIG_DEBUG_NET_SMALL_RTNL=y
# end of Networking Debugging
#
# Memory Debugging
#
CONFIG_PAGE_EXTENSION=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y
CONFIG_SLUB_DEBUG=y
CONFIG_SLUB_DEBUG_ON=y
CONFIG_PAGE_OWNER=y
CONFIG_PAGE_POISONING=y
CONFIG_DEBUG_PAGE_REF=y
CONFIG_DEBUG_RODATA_TEST=y
CONFIG_ARCH_HAS_DEBUG_WX=y
CONFIG_DEBUG_WX=y
CONFIG_ARCH_HAS_PTDUMP=y
CONFIG_PTDUMP=y
CONFIG_PTDUMP_DEBUGFS=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE=16000
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN=y
CONFIG_DEBUG_OBJECTS=y
CONFIG_DEBUG_OBJECTS_SELFTEST=y
CONFIG_DEBUG_OBJECTS_FREE=y
CONFIG_DEBUG_OBJECTS_TIMERS=y
CONFIG_DEBUG_OBJECTS_WORK=y
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
CONFIG_SHRINKER_DEBUG=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_DEBUG_VFS=y
CONFIG_DEBUG_VM_IRQSOFF=y
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_VM_MAPLE_TREE=y
CONFIG_DEBUG_VM_RB=y
CONFIG_DEBUG_VM_PGFLAGS=y
CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
CONFIG_DEBUG_VIRTUAL=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_PER_CPU_MAPS=y
CONFIG_DEBUG_KMAP_LOCAL=y
CONFIG_ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP=y
CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP=y
CONFIG_DEBUG_HIGHMEM=y
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CC_HAS_KASAN_SW_TAGS=y
CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y
CONFIG_HAVE_ARCH_KFENCE=y
CONFIG_KFENCE=y
CONFIG_KFENCE_SAMPLE_INTERVAL=100
CONFIG_KFENCE_NUM_OBJECTS=255
CONFIG_KFENCE_DEFERRABLE=y
CONFIG_KFENCE_STATIC_KEYS=y
CONFIG_KFENCE_STRESS_TEST_FAULTS=0
CONFIG_KFENCE_KUNIT_TEST=m
# end of Memory Debugging
CONFIG_DEBUG_SHIRQ=y
#
# Debug Oops, Lockups and Hangs
#
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_TIMEOUT=0
CONFIG_LOCKUP_DETECTOR=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_SOFTLOCKUP_DETECTOR_INTR_STORM=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=0
CONFIG_HAVE_HARDLOCKUP_DETECTOR_BUDDY=y
CONFIG_HARDLOCKUP_DETECTOR=y
CONFIG_HARDLOCKUP_DETECTOR_PREFER_BUDDY=y
# CONFIG_HARDLOCKUP_DETECTOR_PERF is not set
CONFIG_HARDLOCKUP_DETECTOR_BUDDY=y
# CONFIG_HARDLOCKUP_DETECTOR_ARCH is not set
CONFIG_HARDLOCKUP_DETECTOR_COUNTS_HRTIMER=y
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
CONFIG_BOOTPARAM_HUNG_TASK_PANIC=0
CONFIG_DETECT_HUNG_TASK_BLOCKER=y
CONFIG_WQ_WATCHDOG=y
CONFIG_BOOTPARAM_WQ_STALL_PANIC=0
CONFIG_WQ_CPU_INTENSIVE_REPORT=y
CONFIG_TEST_LOCKUP=m
# end of Debug Oops, Lockups and Hangs
#
# Scheduler Debugging
#
CONFIG_SCHED_INFO=y
CONFIG_SCHEDSTATS=y
# end of Scheduler Debugging
CONFIG_DEBUG_PREEMPT=y
CONFIG_DEBUG_ATOMIC=y
CONFIG_DEBUG_ATOMIC_LARGEST_ALIGN=y
#
# Lock Debugging (spinlocks, mutexes, etc...)
#
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_PROVE_LOCKING=y
CONFIG_PROVE_RAW_LOCK_NESTING=y
CONFIG_LOCK_STAT=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
CONFIG_DEBUG_RWSEMS=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_LOCKDEP=y
CONFIG_LOCKDEP_BITS=15
CONFIG_LOCKDEP_CHAINS_BITS=16
CONFIG_LOCKDEP_STACK_TRACE_BITS=19
CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14
CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12
CONFIG_DEBUG_LOCKDEP=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
CONFIG_LOCK_TORTURE_TEST=m
CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_SCF_TORTURE_TEST=m
# end of Lock Debugging (spinlocks, mutexes, etc...)
CONFIG_TRACE_IRQFLAGS=y
CONFIG_TRACE_IRQFLAGS_NMI=y
CONFIG_NMI_CHECK_CPU=y
CONFIG_DEBUG_IRQFLAGS=y
CONFIG_STACKTRACE=y
CONFIG_DEBUG_KOBJECT=y
CONFIG_DEBUG_KOBJECT_RELEASE=y
#
# Debug kernel data structures
#
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_PLIST=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_DEBUG_CLOSURES=y
CONFIG_DEBUG_MAPLE_TREE=y
# end of Debug kernel data structures
#
# RCU Debugging
#
CONFIG_PROVE_RCU=y
CONFIG_PROVE_RCU_LIST=y
CONFIG_TORTURE_TEST=m
CONFIG_RCU_SCALE_TEST=m
CONFIG_RCU_TORTURE_TEST=m
CONFIG_RCU_TORTURE_TEST_CHK_RDR_STATE=y
CONFIG_RCU_TORTURE_TEST_LOG_CPU=y
CONFIG_RCU_TORTURE_TEST_LOG_GP=y
CONFIG_RCU_REF_SCALE_TEST=m
CONFIG_RCU_CPU_STALL_TIMEOUT=21
CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0
CONFIG_RCU_CPU_STALL_CPUTIME=y
CONFIG_RCU_CPU_STALL_NOTIFIER=y
CONFIG_RCU_TRACE=y
CONFIG_RCU_EQS_DEBUG=y
# end of RCU Debugging
CONFIG_DEBUG_WQ_FORCE_RR_CPU=y
CONFIG_CPU_HOTPLUG_STATE_CONTROL=y
CONFIG_LATENCYTOP=y
CONFIG_DEBUG_CGROUP_REF=y
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_RETHOOK=y
CONFIG_RETHOOK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_FREGS=y
CONFIG_HAVE_FTRACE_GRAPH_FUNC=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_FENTRY=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y
CONFIG_BUILDTIME_MCOUNT_SORT=y
CONFIG_TRACER_MAX_TRACE=y
CONFIG_TRACE_CLOCK=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_PREEMPTIRQ_TRACEPOINTS=y
CONFIG_TRACING=y
CONFIG_GENERIC_TRACER=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
CONFIG_TRACEFS_AUTOMOUNT_DEPRECATED=y
CONFIG_BOOTTIME_TRACING=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_FUNCTION_GRAPH_RETVAL=y
CONFIG_FUNCTION_GRAPH_RETADDR=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
CONFIG_FUNCTION_SELF_TRACING=y
CONFIG_FUNCTION_PROFILER=y
CONFIG_STACK_TRACER=y
CONFIG_TRACE_PREEMPT_TOGGLE=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_PREEMPT_TRACER=y
CONFIG_SCHED_TRACER=y
CONFIG_HWLAT_TRACER=y
CONFIG_OSNOISE_TRACER=y
CONFIG_TIMERLAT_TRACER=y
CONFIG_MMIOTRACE=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_TRACE_SYSCALL_BUF_SIZE_DEFAULT=63
CONFIG_TRACER_SNAPSHOT=y
CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_KPROBE_EVENTS=y
CONFIG_KPROBE_EVENTS_ON_NOTRACE=y
CONFIG_UPROBE_EVENTS=y
CONFIG_EPROBE_EVENTS=y
CONFIG_BPF_EVENTS=y
CONFIG_DYNAMIC_EVENTS=y
CONFIG_PROBE_EVENTS=y
CONFIG_BPF_KPROBE_OVERRIDE=y
CONFIG_FTRACE_MCOUNT_USE_CC=y
CONFIG_TRACING_MAP=y
CONFIG_SYNTH_EVENTS=y
CONFIG_USER_EVENTS=y
CONFIG_HIST_TRIGGERS=y
CONFIG_TRACE_EVENT_INJECT=y
CONFIG_TRACEPOINT_BENCHMARK=y
CONFIG_RING_BUFFER_BENCHMARK=m
CONFIG_TRACE_EVAL_MAP_FILE=y
CONFIG_FTRACE_RECORD_RECURSION=y
CONFIG_FTRACE_RECORD_RECURSION_SIZE=128
CONFIG_FTRACE_VALIDATE_RCU_IS_WATCHING=y
CONFIG_RING_BUFFER_RECORD_RECURSION=y
CONFIG_GCOV_PROFILE_FTRACE=y
CONFIG_FTRACE_SELFTEST=y
CONFIG_FTRACE_STARTUP_TEST=y
CONFIG_EVENT_TRACE_STARTUP_TEST=y
CONFIG_EVENT_TRACE_TEST_SYSCALLS=y
CONFIG_FTRACE_SORT_STARTUP_TEST=y
CONFIG_RING_BUFFER_STARTUP_TEST=y
CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS=y
CONFIG_MMIOTRACE_TEST=m
CONFIG_PREEMPTIRQ_DELAY_TEST=m
CONFIG_SYNTH_EVENT_GEN_TEST=m
CONFIG_KPROBE_EVENT_GEN_TEST=m
CONFIG_HIST_TRIGGERS_DEBUG=y
CONFIG_RV_MON_EVENTS=y
CONFIG_RV_MON_MAINTENANCE_EVENTS=y
CONFIG_DA_MON_EVENTS_IMPLICIT=y
CONFIG_DA_MON_EVENTS_ID=y
CONFIG_LTL_MON_EVENTS_ID=y
CONFIG_RV_LTL_MONITOR=y
CONFIG_RV=y
CONFIG_RV_PER_TASK_MONITORS=2
CONFIG_RV_MON_WIP=y
CONFIG_RV_MON_WWNR=y
CONFIG_RV_MON_RTAPP=y
CONFIG_RV_MON_PAGEFAULT=y
CONFIG_RV_MON_SLEEP=y
CONFIG_RV_REACTORS=y
CONFIG_RV_REACT_PRINTK=y
CONFIG_RV_REACT_PANIC=y
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
CONFIG_SAMPLES=y
CONFIG_SAMPLE_AUXDISPLAY=y
CONFIG_SAMPLE_TRACE_EVENTS=m
CONFIG_SAMPLE_TRACE_CUSTOM_EVENTS=m
CONFIG_SAMPLE_TRACE_PRINTK=m
CONFIG_SAMPLE_FTRACE_OPS=m
CONFIG_SAMPLE_TRACE_ARRAY=m
CONFIG_SAMPLE_KOBJECT=m
CONFIG_SAMPLE_KPROBES=m
CONFIG_SAMPLE_KRETPROBES=m
CONFIG_SAMPLE_HW_BREAKPOINT=m
CONFIG_SAMPLE_KFIFO=m
CONFIG_SAMPLE_KDB=m
CONFIG_SAMPLE_RPMSG_CLIENT=m
CONFIG_SAMPLE_CONFIGFS=m
CONFIG_SAMPLE_CONNECTOR=m
CONFIG_SAMPLE_FANOTIFY_ERROR=y
CONFIG_SAMPLE_HIDRAW=y
CONFIG_SAMPLE_LANDLOCK=y
CONFIG_SAMPLE_PIDFD=y
CONFIG_SAMPLE_SECCOMP=y
CONFIG_SAMPLE_TIMER=y
CONFIG_SAMPLE_TSM_MR=m
CONFIG_SAMPLE_UHID=y
CONFIG_SAMPLE_VFIO_MDEV_MTTY=m
CONFIG_SAMPLE_VFIO_MDEV_MDPY=m
CONFIG_SAMPLE_VFIO_MDEV_MDPY_FB=m
CONFIG_SAMPLE_VFIO_MDEV_MBOCHS=m
CONFIG_SAMPLE_ANDROID_BINDERFS=y
CONFIG_SAMPLE_VFS=y
CONFIG_SAMPLE_INTEL_MEI=y
CONFIG_SAMPLE_TPS6594_PFSM=y
CONFIG_SAMPLE_WATCHDOG=y
CONFIG_SAMPLE_WATCH_QUEUE=y
CONFIG_SAMPLE_KMEMLEAK=m
CONFIG_SAMPLE_CGROUP=y
CONFIG_SAMPLE_CHECK_EXEC=y
CONFIG_SAMPLE_HUNG_TASK=m
#
# DAMON Samples
#
CONFIG_SAMPLE_DAMON_WSSE=y
CONFIG_SAMPLE_DAMON_PRCL=y
CONFIG_SAMPLE_DAMON_MTIER=y
# end of DAMON Samples
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
CONFIG_STRICT_DEVMEM=y
CONFIG_IO_STRICT_DEVMEM=y
#
# x86 Debugging
#
CONFIG_EARLY_PRINTK_USB=y
CONFIG_X86_VERBOSE_BOOTUP=y
CONFIG_EARLY_PRINTK=y
CONFIG_EARLY_PRINTK_DBGP=y
CONFIG_EARLY_PRINTK_USB_XDBC=y
CONFIG_EFI_PGT_DUMP=y
CONFIG_DEBUG_TLBFLUSH=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_0X80=y
# CONFIG_IO_DELAY_0XED is not set
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not set
CONFIG_DEBUG_BOOT_PARAMS=y
CONFIG_CPA_DEBUG=y
CONFIG_DEBUG_ENTRY=y
CONFIG_DEBUG_NMI_SELFTEST=y
CONFIG_DEBUG_IMR_SELFTEST=y
CONFIG_X86_DEBUG_FPU=y
CONFIG_PUNIT_ATOM_DEBUG=m
CONFIG_UNWINDER_FRAME_POINTER=y
# end of x86 Debugging
#
# Kernel Testing and Coverage
#
CONFIG_KUNIT=m
CONFIG_KUNIT_DEBUGFS=y
CONFIG_KUNIT_FAULT_TEST=y
CONFIG_KUNIT_TEST=m
CONFIG_KUNIT_EXAMPLE_TEST=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_KUNIT_DEFAULT_ENABLED=y
CONFIG_KUNIT_AUTORUN_ENABLED=y
CONFIG_KUNIT_DEFAULT_FILTER_GLOB=""
CONFIG_KUNIT_DEFAULT_FILTER=""
CONFIG_KUNIT_DEFAULT_FILTER_ACTION=""
CONFIG_KUNIT_DEFAULT_TIMEOUT=300
CONFIG_NOTIFIER_ERROR_INJECTION=m
CONFIG_PM_NOTIFIER_ERROR_INJECT=m
CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT=m
CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m
CONFIG_FUNCTION_ERROR_INJECTION=y
CONFIG_FAULT_INJECTION=y
CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAULT_INJECTION_USERCOPY=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAIL_FUTEX=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAIL_FUNCTION=y
CONFIG_FAIL_MMC_REQUEST=y
CONFIG_FAIL_SUNRPC=y
CONFIG_FAIL_SKB_REALLOC=y
CONFIG_FAULT_INJECTION_CONFIGFS=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
CONFIG_RUNTIME_TESTING_MENU=y
CONFIG_TEST_DHRY=m
CONFIG_LKDTM=m
CONFIG_CPUMASK_KUNIT_TEST=m
CONFIG_TEST_LIST_SORT=m
CONFIG_TEST_SORT=m
CONFIG_TEST_DIV64=m
CONFIG_TEST_MULDIV64=m
CONFIG_TEST_IOV_ITER=m
CONFIG_KPROBES_SANITY_TEST=m
CONFIG_BACKTRACE_SELF_TEST=m
CONFIG_TEST_REF_TRACKER=m
CONFIG_RBTREE_TEST=m
CONFIG_REED_SOLOMON_TEST=m
CONFIG_INTERVAL_TREE_TEST=m
CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_PRINTF_KUNIT_TEST=m
CONFIG_SCANF_KUNIT_TEST=m
CONFIG_SEQ_BUF_KUNIT_TEST=m
CONFIG_STRING_KUNIT_TEST=m
CONFIG_STRING_HELPERS_KUNIT_TEST=m
CONFIG_FFS_KUNIT_TEST=m
CONFIG_TEST_KSTRTOX=m
CONFIG_TEST_BITMAP=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_MAPLE_TREE=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_IDA=m
CONFIG_TEST_PARMAN=m
CONFIG_TEST_LKM=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
CONFIG_TEST_BPF=m
CONFIG_FIND_BIT_BENCHMARK=m
CONFIG_TEST_FIRMWARE=m
CONFIG_TEST_SYSCTL=m
CONFIG_BITOPS_KUNIT=m
CONFIG_BITFIELD_KUNIT=m
CONFIG_CHECKSUM_KUNIT=m
CONFIG_UTIL_MACROS_KUNIT=m
CONFIG_HASH_KUNIT_TEST=m
CONFIG_RESOURCE_KUNIT_TEST=m
CONFIG_SYSCTL_KUNIT_TEST=m
CONFIG_KFIFO_KUNIT_TEST=m
CONFIG_LIST_KUNIT_TEST=m
CONFIG_LIST_PRIVATE_KUNIT_TEST=m
CONFIG_HASHTABLE_KUNIT_TEST=m
CONFIG_LINEAR_RANGES_TEST=m
CONFIG_CONTEXT_ANALYSIS_TEST=y
CONFIG_CMDLINE_KUNIT_TEST=m
CONFIG_BASE64_KUNIT=m
CONFIG_BITS_TEST=m
CONFIG_SLUB_KUNIT_TEST=m
CONFIG_RATIONAL_KUNIT_TEST=m
CONFIG_MEMCPY_KUNIT_TEST=m
CONFIG_MIN_HEAP_KUNIT_TEST=m
CONFIG_IS_SIGNED_TYPE_KUNIT_TEST=m
CONFIG_OVERFLOW_KUNIT_TEST=m
CONFIG_RANDSTRUCT_KUNIT_TEST=m
CONFIG_STACKINIT_KUNIT_TEST=m
CONFIG_FORTIFY_KUNIT_TEST=m
CONFIG_SIPHASH_KUNIT_TEST=m
CONFIG_USERCOPY_KUNIT_TEST=m
CONFIG_BLACKHOLE_DEV_KUNIT_TEST=m
CONFIG_TEST_UDELAY=m
CONFIG_TEST_STATIC_KEYS=m
CONFIG_TEST_DYNAMIC_DEBUG=m
CONFIG_TEST_KMOD=m
CONFIG_TEST_RUNTIME=y
CONFIG_TEST_RUNTIME_MODULE=y
CONFIG_TEST_KALLSYMS=m
CONFIG_TEST_KALLSYMS_A=m
CONFIG_TEST_KALLSYMS_B=m
CONFIG_TEST_KALLSYMS_C=m
CONFIG_TEST_KALLSYMS_D=m
# CONFIG_TEST_KALLSYMS_FAST is not set
CONFIG_TEST_KALLSYMS_LARGE=y
# CONFIG_TEST_KALLSYMS_MAX is not set
CONFIG_TEST_KALLSYMS_NUMSYMS=100
CONFIG_TEST_KALLSYMS_SCALE_FACTOR=8
CONFIG_TEST_DEBUG_VIRTUAL=m
CONFIG_TEST_MEMCAT_P=m
CONFIG_TEST_OBJAGG=m
CONFIG_TEST_MEMINIT=m
CONFIG_TEST_FREE_PAGES=m
CONFIG_TEST_FPU=m
CONFIG_TEST_CLOCKSOURCE_WATCHDOG=m
CONFIG_TEST_OBJPOOL=m
CONFIG_RATELIMIT_KUNIT_TEST=m
CONFIG_UUID_KUNIT_TEST=m
CONFIG_INT_POW_KUNIT_TEST=m
CONFIG_INT_SQRT_KUNIT_TEST=m
CONFIG_INT_LOG_KUNIT_TEST=m
CONFIG_GCD_KUNIT_TEST=m
CONFIG_PRIME_NUMBERS_KUNIT_TEST=m
CONFIG_GLOB_KUNIT_TEST=m
CONFIG_ARCH_USE_MEMTEST=y
CONFIG_MEMTEST=y
CONFIG_HYPERV_TESTING=y
# end of Kernel Testing and Coverage
#
# Rust hacking
#
# end of Rust hacking
# end of Kernel hacking
#
# Documentation
#
CONFIG_WARN_MISSING_DOCUMENTS=y
CONFIG_WARN_ABI_ERRORS=y
# end of Documentation
CONFIG_IO_URING_ZCRX=y
CONFIG_IO_URING_BPF=y
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v5] media: pci: add AVMatrix HWS capture driver
2026-03-30 23:36 ` [PATCH v4] media: pci: add AVMatrix HWS capture driver hoff.benjamin.k
2026-04-02 6:25 ` kernel test robot
@ 2026-04-03 13:57 ` hoff.benjamin.k
1 sibling, 0 replies; 11+ messages in thread
From: hoff.benjamin.k @ 2026-04-03 13:57 UTC (permalink / raw)
To: linux-media; +Cc: linux-kernel, mchehab, hverkuil+cisco, kernel test robot
From: Ben Hoff <hoff.benjamin.k@gmail.com>
Add an in-tree AVMatrix HWS PCIe capture driver. The driver supports
up to four HDMI inputs and exposes the video capture path through
V4L2 with vb2-dma-contig streaming, DV timings, and per-input
controls. Audio support is intentionally omitted from this
submission.
This patch also adds the MAINTAINERS entry for the new driver.
This driver is derived from a GPL out-of-tree driver.
Changes since v4:
- replace plain 64-bit elapsed-time divisions in debug logging with
div_u64() so i386 module builds do not emit __udivdi3 references
Changes since v3:
- fold the MAINTAINERS update into this patch so per-patch CI sees the
new file pattern
- wrap the validation text for checkpatch
Changes since v2:
- keep scratch DMA allocation on a single probe-owned path
- avoid double-freeing V4L2 control handlers on register unwind
- drop the extra per-node resolution sysfs ABI
- turn live geometry changes into explicit SOURCE_CHANGE renegotiation
- report live DV timings and reject attempts to retime a live source
- stop advertising RESOLUTION source changes for fps-only updates
- keep live fps state across harmless S_FMT restarts
- stop exposing an unvalidated DV RX power-present signal
- clean the imported sources for checkpatch and W=1 builds
Validation:
- build-tested with W=1 against a local kernel build tree
- compiled the driver with ARCH=i386 allmodconfig and verified the
resulting hws_pci.o, hws_video.o, and hws.o do not reference
__udivdi3
- v4l2-compliance 1.32.0 on /dev/video1: 51 tests succeeded,
0 failed, 1 warning
DV_RX_POWER_PRESENT is intentionally left unsupported in this revision
because current hardware evidence does not expose a validated
receiver-side power-detect signal distinct from active video presence.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202604020522.z22eZuW8-lkp@intel.com/
Signed-off-by: Ben Hoff <hoff.benjamin.k@gmail.com>
---
MAINTAINERS | 6 +
drivers/media/pci/Kconfig | 1 +
drivers/media/pci/Makefile | 1 +
drivers/media/pci/hws/Kconfig | 12 +
drivers/media/pci/hws/Makefile | 4 +
drivers/media/pci/hws/hws.h | 174 +++
drivers/media/pci/hws/hws_irq.c | 271 +++++
drivers/media/pci/hws/hws_irq.h | 10 +
drivers/media/pci/hws/hws_pci.c | 865 ++++++++++++++
drivers/media/pci/hws/hws_reg.h | 136 +++
drivers/media/pci/hws/hws_v4l2_ioctl.c | 924 +++++++++++++++
drivers/media/pci/hws/hws_v4l2_ioctl.h | 36 +
drivers/media/pci/hws/hws_video.c | 1506 ++++++++++++++++++++++++
drivers/media/pci/hws/hws_video.h | 29 +
14 files changed, 3975 insertions(+)
create mode 100644 drivers/media/pci/hws/Kconfig
create mode 100644 drivers/media/pci/hws/Makefile
create mode 100644 drivers/media/pci/hws/hws.h
create mode 100644 drivers/media/pci/hws/hws_irq.c
create mode 100644 drivers/media/pci/hws/hws_irq.h
create mode 100644 drivers/media/pci/hws/hws_pci.c
create mode 100644 drivers/media/pci/hws/hws_reg.h
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.c
create mode 100644 drivers/media/pci/hws/hws_v4l2_ioctl.h
create mode 100644 drivers/media/pci/hws/hws_video.c
create mode 100644 drivers/media/pci/hws/hws_video.h
diff --git a/MAINTAINERS b/MAINTAINERS
index c3fe46d7c4bc..2c5511d740f2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7471,6 +7471,12 @@ S: Maintained
F: Documentation/admin-guide/media/mgb4.rst
F: drivers/media/pci/mgb4/
+AVMATRIX HWS DRIVER
+M: Ben Hoff <hoff.benjamin.k@gmail.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/pci/hws/
+
DIOLAN U2C-12 I2C DRIVER
M: Guenter Roeck <linux@roeck-us.net>
L: linux-i2c@vger.kernel.org
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index eebb16c58f3d..bfdb200f85a3 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -13,6 +13,7 @@ if MEDIA_PCI_SUPPORT
if MEDIA_CAMERA_SUPPORT
comment "Media capture support"
+source "drivers/media/pci/hws/Kconfig"
source "drivers/media/pci/mgb4/Kconfig"
source "drivers/media/pci/solo6x10/Kconfig"
source "drivers/media/pci/tw5864/Kconfig"
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index 02763ad88511..c4508b6723a9 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
obj-$(CONFIG_VIDEO_CX25821) += cx25821/
obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_DT3155) += dt3155/
+obj-$(CONFIG_VIDEO_HWS) += hws/
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
obj-$(CONFIG_VIDEO_MGB4) += mgb4/
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
diff --git a/drivers/media/pci/hws/Kconfig b/drivers/media/pci/hws/Kconfig
new file mode 100644
index 000000000000..b606d5ffadef
--- /dev/null
+++ b/drivers/media/pci/hws/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_HWS
+ tristate "AVMatrix HWS capture driver"
+ depends on VIDEO_DEV && PCI
+ select VIDEOBUF2_DMA_CONTIG
+ help
+ This is a Video4Linux2 driver for AVMatrix HWS PCIe capture cards.
+ It provides a PCIe capture interface with V4L2 streaming, DV timings,
+ and per-input controls for the supported HWS boards.
+
+ To compile this driver as a module, choose M here: the module will
+ be called hws.
diff --git a/drivers/media/pci/hws/Makefile b/drivers/media/pci/hws/Makefile
new file mode 100644
index 000000000000..a66aebd348e5
--- /dev/null
+++ b/drivers/media/pci/hws/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+hws-objs := hws_pci.o hws_irq.o hws_video.o hws_v4l2_ioctl.o
+
+obj-$(CONFIG_VIDEO_HWS) += hws.o
diff --git a/drivers/media/pci/hws/hws.h b/drivers/media/pci/hws/hws.h
new file mode 100644
index 000000000000..ebc8cc0daf36
--- /dev/null
+++ b/drivers/media/pci/hws/hws.h
@@ -0,0 +1,174 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_PCIE_H
+#define HWS_PCIE_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/sizes.h>
+#include <linux/atomic.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/videobuf2-dma-sg.h>
+
+#include "hws_reg.h"
+
+struct hwsmem_param {
+ u32 index;
+ u32 type;
+ u32 status;
+};
+
+struct hws_pix_state {
+ u32 width;
+ u32 height;
+ u32 fourcc; /* V4L2_PIX_FMT_* (YUYV only here) */
+ u32 bytesperline; /* stride */
+ u32 sizeimage; /* full frame */
+ enum v4l2_field field; /* V4L2_FIELD_NONE or INTERLACED */
+ enum v4l2_colorspace colorspace; /* e.g., REC709 */
+ enum v4l2_ycbcr_encoding ycbcr_enc; /* V4L2_YCBCR_ENC_DEFAULT */
+ enum v4l2_quantization quantization; /* V4L2_QUANTIZATION_LIM_RANGE */
+ enum v4l2_xfer_func xfer_func; /* V4L2_XFER_FUNC_DEFAULT */
+ bool interlaced; /* cached hardware state */
+ u32 half_size; /* optional: if your HW needs it */
+};
+
+#define UNSET (-1U)
+
+struct hws_pcie_dev;
+struct hws_adapter;
+struct hws_video;
+
+struct hwsvideo_buffer {
+ struct vb2_v4l2_buffer vb;
+ struct list_head list;
+ int slot; /* for two-buffer approach */
+};
+
+struct hws_video {
+ /* ───── linkage ───── */
+ struct hws_pcie_dev *parent; /* parent device */
+ struct video_device *video_device;
+
+ struct vb2_queue buffer_queue;
+ struct list_head capture_queue;
+ struct hwsvideo_buffer *active;
+ struct hwsvideo_buffer *next_prepared;
+
+ /* ───── locking ───── */
+ struct mutex state_lock; /* primary state */
+ spinlock_t irq_lock; /* ISR-side */
+
+ /* ───── indices ───── */
+ int channel_index;
+
+ /* ───── colour controls ───── */
+ int current_brightness;
+ int current_contrast;
+ int current_saturation;
+ int current_hue;
+
+ /* ───── V4L2 controls ───── */
+ struct v4l2_ctrl_handler control_handler;
+ struct v4l2_ctrl *ctrl_brightness;
+ struct v4l2_ctrl *ctrl_contrast;
+ struct v4l2_ctrl *ctrl_saturation;
+ struct v4l2_ctrl *ctrl_hue;
+ /* ───── capture queue status ───── */
+ struct hws_pix_state pix;
+ struct v4l2_dv_timings cur_dv_timings; /* last configured/notified DV timings */
+ u32 current_fps; /* Hz, updated by mode changes, not by read-only queries */
+ u32 alloc_sizeimage;
+
+ /* ───── per-channel capture state ───── */
+ bool cap_active;
+ bool stop_requested;
+ u8 last_buf_half_toggle;
+ bool half_seen;
+ atomic_t sequence_number;
+ u32 queued_count;
+
+ /* ───── timeout and error handling ───── */
+ u32 timeout_count;
+ u32 error_count;
+
+ bool window_valid;
+ u32 last_dma_hi;
+ u32 last_dma_page;
+ u32 last_pci_addr;
+ u32 last_half16;
+
+ /* ───── misc counters ───── */
+ int signal_loss_cnt;
+};
+
+static inline void hws_set_current_dv_timings(struct hws_video *vid,
+ u32 width, u32 height,
+ bool interlaced)
+{
+ if (!vid)
+ return;
+
+ vid->cur_dv_timings = (struct v4l2_dv_timings) {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = width,
+ .height = height,
+ .interlaced = interlaced,
+ },
+ };
+}
+
+struct hws_scratch_dma {
+ void *cpu;
+ dma_addr_t dma;
+ size_t size;
+};
+
+struct hws_pcie_dev {
+ /* ───── core objects ───── */
+ struct pci_dev *pdev;
+ struct hws_video video[MAX_VID_CHANNELS];
+
+ /* ───── BAR & workqueues ───── */
+ void __iomem *bar0_base;
+
+ /* ───── device identity / capabilities ───── */
+ u16 vendor_id;
+ u16 device_id;
+ u16 device_ver;
+ u16 hw_ver;
+ u32 sub_ver;
+ u32 port_id;
+ // TriState, used in `set_video_format_size`
+ u32 support_yv12;
+ u32 max_hw_video_buf_sz;
+ u8 max_channels;
+ u8 cur_max_video_ch;
+ bool start_run;
+
+ bool buf_allocated;
+
+ /* ───── V4L2 framework objects ───── */
+ struct v4l2_device v4l2_device;
+
+ /* ───── kernel thread ───── */
+ struct task_struct *main_task;
+ struct hws_scratch_dma scratch_vid[MAX_VID_CHANNELS];
+
+ bool suspended;
+ int irq;
+
+ /* ───── error flags ───── */
+ int pci_lost;
+
+};
+
+#endif
diff --git a/drivers/media/pci/hws/hws_irq.c b/drivers/media/pci/hws/hws_irq.c
new file mode 100644
index 000000000000..0747dfb7ab97
--- /dev/null
+++ b/drivers/media/pci/hws/hws_irq.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/compiler.h>
+#include <linux/moduleparam.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/minmax.h>
+#include <linux/string.h>
+
+#include <media/videobuf2-dma-contig.h>
+
+#include "hws_irq.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws.h"
+
+#define MAX_INT_LOOPS 100
+
+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 = &hws->video[ch];
+ unsigned long flags;
+ struct hwsvideo_buffer *buf;
+
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): stop=%d cap=%d queued=%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=%u): suspended\n", ch);
+ return -EBUSY;
+ }
+
+ if (READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active)) {
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): stop=%d cap=%d -> cancel\n", ch,
+ v->stop_requested, v->cap_active);
+ return -ECANCELED;
+ }
+
+ 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=%u): queue empty\n", ch);
+ return -EAGAIN;
+ }
+
+ buf = list_first_entry(&v->capture_queue, struct hwsvideo_buffer, list);
+ list_del_init(&buf->list); /* keep buffer safe for later cleanup */
+ if (v->queued_count)
+ v->queued_count--;
+ v->active = buf;
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ dev_dbg(&hws->pdev->dev, "arm_next(ch=%u): picked buffer %p\n", ch,
+ buf);
+
+ /* Publish descriptor(s) before doorbell/MMIO kicks. */
+ wmb();
+
+ /* Avoid MMIO during suspend */
+ if (READ_ONCE(hws->suspended)) {
+ unsigned long f;
+
+ dev_dbg(&hws->pdev->dev,
+ "arm_next(ch=%u): suspended after pick\n", ch);
+ spin_lock_irqsave(&v->irq_lock, f);
+ if (v->active) {
+ list_add(&buf->list, &v->capture_queue);
+ v->queued_count++;
+ v->active = NULL;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, f);
+ return -EBUSY;
+ }
+
+ /* Also program the DMA address register directly */
+ {
+ dma_addr_t dma_addr =
+ vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(hws, ch, dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base + HWS_REG_DMA_ADDR(ch));
+ }
+
+ dev_dbg(&hws->pdev->dev, "arm_next(ch=%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);
+ return 0;
+}
+
+static void hws_video_handle_vdone(struct hws_video *v)
+{
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned int ch = v->channel_index;
+ struct hwsvideo_buffer *done;
+ unsigned long flags;
+ bool promoted = false;
+
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): stop=%d cap=%d active=%p\n",
+ ch, READ_ONCE(v->stop_requested), READ_ONCE(v->cap_active),
+ v->active);
+
+ int ret;
+
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): entry stop=%d cap=%d\n", ch,
+ v->stop_requested, v->cap_active);
+ if (READ_ONCE(hws->suspended))
+ return;
+
+ if (READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active))
+ return;
+
+ spin_lock_irqsave(&v->irq_lock, flags);
+ done = v->active;
+ if (done && v->next_prepared) {
+ v->active = v->next_prepared;
+ v->next_prepared = NULL;
+ promoted = true;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* 1) Complete the buffer the HW just finished (if any) */
+ if (done) {
+ struct vb2_v4l2_buffer *vb2v = &done->vb;
+ size_t expected = v->pix.sizeimage;
+ size_t plane_size = vb2_plane_size(&vb2v->vb2_buf, 0);
+
+ if (expected > plane_size) {
+ dev_warn_ratelimited(&hws->pdev->dev,
+ "bh_video(ch=%u): sizeimage %zu > plane %zu, dropping seq=%u\n",
+ ch, expected, plane_size,
+ (u32)atomic_read(&v->sequence_number) + 1);
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_ERROR);
+ goto arm_next;
+ }
+ vb2_set_plane_payload(&vb2v->vb2_buf, 0, expected);
+
+ dma_rmb(); /* device writes visible before userspace sees it */
+
+ vb2v->sequence = (u32)atomic_inc_return(&v->sequence_number);
+ vb2v->vb2_buf.timestamp = ktime_get_ns();
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): DONE buf=%p seq=%u half_seen=%d toggle=%u\n",
+ ch, done, vb2v->sequence, v->half_seen,
+ v->last_buf_half_toggle);
+
+ if (!promoted)
+ v->active = NULL; /* channel no longer owns this buffer */
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+
+ if (READ_ONCE(hws->suspended))
+ return;
+
+ if (promoted) {
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): promoted pre-armed buffer active=%p\n",
+ ch, v->active);
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_prime_next_locked(v);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ return;
+ }
+
+arm_next:
+ /* 2) Immediately arm the next queued buffer (if present) */
+ ret = hws_arm_next(hws, ch);
+ if (ret == -EAGAIN) {
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): no queued buffer to arm\n", ch);
+ return;
+ }
+ dev_dbg(&hws->pdev->dev,
+ "bh_video(ch=%u): armed next buffer, active=%p\n", ch,
+ v->active);
+ /* On success the engine now points at v->active’s DMA address */
+}
+
+irqreturn_t hws_irq_handler(int irq, void *info)
+{
+ struct hws_pcie_dev *pdx = info;
+ u32 int_state;
+
+ dev_dbg(&pdx->pdev->dev, "irq: entry\n");
+ if (pdx->bar0_base) {
+ dev_dbg(&pdx->pdev->dev,
+ "irq: INT_EN=0x%08x INT_STATUS=0x%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 = 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;
+ }
+ // u32 sys_status = readl(pdx->bar0_base + HWS_REG_SYS_STATUS);
+
+ int_state = readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ if (!int_state || int_state == 0xFFFFFFFF) {
+ dev_dbg(&pdx->pdev->dev,
+ "irq: spurious or device-gone int_state=0x%08x\n",
+ int_state);
+ return IRQ_NONE;
+ }
+ dev_dbg(&pdx->pdev->dev, "irq: entry INT_STATUS=0x%08x\n", int_state);
+
+ /* Loop until all pending bits are serviced (max 100 iterations) */
+ for (u32 cnt = 0; int_state && cnt < MAX_INT_LOOPS; ++cnt) {
+ for (unsigned int ch = 0; ch < pdx->cur_max_video_ch; ++ch) {
+ u32 vbit = HWS_INT_VDONE_BIT(ch);
+
+ if (!(int_state & vbit))
+ continue;
+
+ if (READ_ONCE(pdx->video[ch].cap_active) &&
+ !READ_ONCE(pdx->video[ch].stop_requested)) {
+ if (hws_toggle_debug) {
+ u32 toggle =
+ 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=%u toggle=%u handling inline (cap=%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=%u ignored (cap=%d stop=%d)\n",
+ ch,
+ READ_ONCE(pdx->video[ch].cap_active),
+ READ_ONCE(pdx->video[ch].stop_requested));
+ }
+
+ writel(vbit, pdx->bar0_base + HWS_REG_INT_STATUS);
+ (void)readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ /* Re‐read in case new interrupt bits popped while processing */
+ int_state = readl_relaxed(pdx->bar0_base + HWS_REG_INT_STATUS);
+ dev_dbg(&pdx->pdev->dev,
+ "irq: loop cnt=%u new INT_STATUS=0x%08x\n", cnt,
+ int_state);
+ if (cnt + 1 == MAX_INT_LOOPS)
+ dev_warn_ratelimited(&pdx->pdev->dev,
+ "IRQ storm? status=0x%08x\n",
+ int_state);
+ }
+
+ return IRQ_HANDLED;
+}
diff --git a/drivers/media/pci/hws/hws_irq.h b/drivers/media/pci/hws/hws_irq.h
new file mode 100644
index 000000000000..a42867aa0c46
--- /dev/null
+++ b/drivers/media/pci/hws/hws_irq.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_INTERRUPT_H
+#define HWS_INTERRUPT_H
+
+#include <linux/pci.h>
+#include "hws.h"
+
+irqreturn_t hws_irq_handler(int irq, void *info);
+
+#endif /* HWS_INTERRUPT_H */
diff --git a/drivers/media/pci/hws/hws_pci.c b/drivers/media/pci/hws/hws_pci.c
new file mode 100644
index 000000000000..e4e8e682f8a5
--- /dev/null
+++ b/drivers/media/pci/hws/hws_pci.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/iopoll.h>
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/ktime.h>
+#include <linux/math64.h>
+#include <linux/pm.h>
+#include <linux/freezer.h>
+#include <linux/pci_regs.h>
+
+#include <media/v4l2-ctrls.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_irq.h"
+#include "hws_v4l2_ioctl.h"
+
+#define DRV_NAME "hws"
+#define HWS_BUSY_POLL_DELAY_US 10
+#define HWS_BUSY_POLL_TIMEOUT_US 1000000
+
+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(7, 0)
+#define DEVINFO_SUBVER GENMASK(15, 8)
+#define DEVINFO_YV12 GENMASK(31, 28)
+#define DEVINFO_HWKEY GENMASK(27, 24)
+#define DEVINFO_PORTID GENMASK(25, 24) /* low 2 bits of HW-key */
+
+#define MAKE_ENTRY(__vend, __chip, __subven, __subdev, __configptr) \
+ { .vendor = (__vend), \
+ .device = (__chip), \
+ .subvendor = (__subven), \
+ .subdevice = (__subdev), \
+ .driver_data = (unsigned long)(__configptr) }
+
+/*
+ * PCI IDs for HWS family cards.
+ *
+ * The subsystem IDs are fixed at 0x8888:0x0007 for this family. Some boards
+ * enumerate with vendor ID 0x8888 or 0x1f33. Exact SKU names are not fully
+ * pinned down yet; update these comments when vendor documentation or INF
+ * strings are available.
+ */
+static const struct pci_device_id hws_pci_table[] = {
+ /* HWS family, SKU unknown. */
+ MAKE_ENTRY(0x8888, 0x9534, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x8534, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x8554, 0x8888, 0x0007, NULL),
+
+ /* HWS 2x2 HDMI family. */
+ MAKE_ENTRY(0x8888, 0x8524, 0x8888, 0x0007, NULL),
+ /* HWS 2x2 SDI family. */
+ MAKE_ENTRY(0x1F33, 0x6524, 0x8888, 0x0007, NULL),
+
+ /* HWS X4 HDMI family. */
+ MAKE_ENTRY(0x8888, 0x8504, 0x8888, 0x0007, NULL),
+ /* HWS X4 SDI family. */
+ MAKE_ENTRY(0x8888, 0x6504, 0x8888, 0x0007, NULL),
+
+ /* HWS family, SKU unknown. */
+ MAKE_ENTRY(0x8888, 0x8532, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x8888, 0x8512, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x8888, 0x8501, 0x8888, 0x0007, NULL),
+ MAKE_ENTRY(0x1F33, 0x6502, 0x8888, 0x0007, NULL),
+
+ /* HWS X4 HDMI family (alternate vendor ID). */
+ MAKE_ENTRY(0x1F33, 0x8504, 0x8888, 0x0007, NULL),
+ /* HWS 2x2 HDMI family (alternate vendor ID). */
+ MAKE_ENTRY(0x1F33, 0x8524, 0x8888, 0x0007, NULL),
+
+ {}
+};
+
+static void enable_pcie_relaxed_ordering(struct pci_dev *dev)
+{
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
+}
+
+static void hws_configure_hardware_capabilities(struct hws_pcie_dev *hdev)
+{
+ u16 id = hdev->device_id;
+
+ /* select per-chip channel counts */
+ switch (id) {
+ case 0x9534:
+ case 0x6524:
+ case 0x8524:
+ case 0x8504:
+ case 0x6504:
+ hdev->cur_max_video_ch = 4;
+ break;
+ case 0x8532:
+ hdev->cur_max_video_ch = 2;
+ break;
+ case 0x8512:
+ case 0x6502:
+ hdev->cur_max_video_ch = 2;
+ break;
+ case 0x8501:
+ hdev->cur_max_video_ch = 1;
+ break;
+ default:
+ hdev->cur_max_video_ch = 4;
+ break;
+ }
+
+ /* universal buffer capacity */
+ hdev->max_hw_video_buf_sz = MAX_MM_VIDEO_SIZE;
+
+ /* decide hardware-version and program DMA max size if needed */
+ if (hdev->device_ver > 121) {
+ if (id == 0x8501 && hdev->device_ver == 122) {
+ hdev->hw_ver = 0;
+ } else {
+ hdev->hw_ver = 1;
+ u32 dma_max = (u32)(MAX_VIDEO_SCALER_SIZE / 16);
+
+ writel(dma_max, hdev->bar0_base + HWS_REG_DMA_MAX_SIZE);
+ /* readback to flush posted MMIO write */
+ (void)readl(hdev->bar0_base + HWS_REG_DMA_MAX_SIZE);
+ }
+ } else {
+ hdev->hw_ver = 0;
+ }
+}
+
+static void hws_stop_device(struct hws_pcie_dev *hws);
+
+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 = &hws->pdev->dev;
+ if (!hws->bar0_base) {
+ dev_dbg(dev,
+ "lifecycle:%s:%s bar0-unmapped suspended=%d start_run=%d pci_lost=%d irq=%d\n",
+ action, phase, READ_ONCE(hws->suspended), hws->start_run,
+ hws->pci_lost, hws->irq);
+ return;
+ }
+
+ int_en = readl(hws->bar0_base + INT_EN_REG_BASE);
+ int_status = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ vcap = readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ sys_status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+ dec_mode = readl(hws->bar0_base + HWS_REG_DEC_MODE);
+
+ dev_dbg(dev,
+ "lifecycle:%s:%s suspended=%d start_run=%d pci_lost=%d irq=%d INT_EN=0x%08x INT_STATUS=0x%08x VCAP=0x%08x SYS=0x%08x DEC=0x%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;
+ /* mirror PCI IDs for later switches */
+ hdev->device_id = hdev->pdev->device;
+ hdev->vendor_id = hdev->pdev->vendor;
+
+ reg = readl(hdev->bar0_base + HWS_REG_DEVICE_INFO);
+
+ hdev->device_ver = FIELD_GET(DEVINFO_VER, reg);
+ hdev->sub_ver = FIELD_GET(DEVINFO_SUBVER, reg);
+ hdev->support_yv12 = FIELD_GET(DEVINFO_YV12, reg);
+ hdev->port_id = FIELD_GET(DEVINFO_PORTID, reg);
+
+ hdev->max_hw_video_buf_sz = MAX_MM_VIDEO_SIZE;
+ hdev->max_channels = 4;
+ hdev->buf_allocated = false;
+ hdev->main_task = NULL;
+ hdev->start_run = false;
+ hdev->pci_lost = 0;
+
+ writel(0x00, hdev->bar0_base + HWS_REG_DEC_MODE);
+ writel(0x10, hdev->bar0_base + HWS_REG_DEC_MODE);
+
+ hws_configure_hardware_capabilities(hdev);
+
+ dev_info(&hdev->pdev->dev,
+ "chip detected: ver=%u subver=%u port=%u yv12=%u\n",
+ hdev->device_ver, hdev->sub_ver, hdev->port_id,
+ hdev->support_yv12);
+
+ return 0;
+}
+
+static int main_ks_thread_handle(void *data)
+{
+ struct hws_pcie_dev *pdx = data;
+
+ set_freezable();
+
+ while (!kthread_should_stop()) {
+ /* If we’re suspending, don’t touch hardware; just sleep/freeeze */
+ if (READ_ONCE(pdx->suspended)) {
+ try_to_freeze();
+ schedule_timeout_interruptible(msecs_to_jiffies(1000));
+ continue;
+ }
+
+ /* avoid MMIO when suspended (guarded above) */
+ check_video_format(pdx);
+
+ try_to_freeze(); /* cooperate with freezer each loop */
+
+ /* Sleep 1s or until signaled to wake/stop */
+ schedule_timeout_interruptible(msecs_to_jiffies(1000));
+ }
+
+ dev_dbg(&pdx->pdev->dev, "%s: exiting\n", __func__);
+ return 0;
+}
+
+static void hws_stop_kthread_action(void *data)
+{
+ struct hws_pcie_dev *hws = data;
+ struct task_struct *t;
+ u64 start_ns;
+
+ if (!hws)
+ return;
+
+ t = READ_ONCE(hws->main_task);
+ if (!IS_ERR_OR_NULL(t)) {
+ start_ns = ktime_get_mono_fast_ns();
+ dev_dbg(&hws->pdev->dev,
+ "lifecycle:kthread-stop:begin task=%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));
+ }
+}
+
+static int hws_alloc_seed_buffers(struct hws_pcie_dev *hws)
+{
+ int ch;
+ /* 64 KiB is plenty for a safe dummy; align to 64 for your HW */
+ const size_t need = ALIGN(64 * 1024, 64);
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+#if defined(CONFIG_HAS_DMA) /* normal on PCIe platforms */
+ void *cpu = dma_alloc_coherent(&hws->pdev->dev, need,
+ &hws->scratch_vid[ch].dma,
+ GFP_KERNEL);
+#else
+ void *cpu = NULL;
+#endif
+ if (!cpu) {
+ dev_warn(&hws->pdev->dev,
+ "scratch: dma_alloc_coherent failed ch=%d\n", ch);
+ /* not fatal: free earlier ones and continue without seeding */
+ while (--ch >= 0) {
+ if (hws->scratch_vid[ch].cpu)
+ dma_free_coherent(&hws->pdev->dev,
+ hws->scratch_vid[ch].size,
+ hws->scratch_vid[ch].cpu,
+ hws->scratch_vid[ch].dma);
+ hws->scratch_vid[ch].cpu = NULL;
+ hws->scratch_vid[ch].size = 0;
+ }
+ return -ENOMEM;
+ }
+ hws->scratch_vid[ch].cpu = cpu;
+ hws->scratch_vid[ch].size = need;
+ }
+ return 0;
+}
+
+static void hws_free_seed_buffers(struct hws_pcie_dev *hws)
+{
+ int ch;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+ if (hws->scratch_vid[ch].cpu) {
+ dma_free_coherent(&hws->pdev->dev,
+ hws->scratch_vid[ch].size,
+ hws->scratch_vid[ch].cpu,
+ hws->scratch_vid[ch].dma);
+ hws->scratch_vid[ch].cpu = NULL;
+ hws->scratch_vid[ch].size = 0;
+ }
+ }
+}
+
+static void hws_seed_channel(struct hws_pcie_dev *hws, int ch)
+{
+ dma_addr_t paddr = hws->scratch_vid[ch].dma;
+ u32 lo = lower_32_bits(paddr);
+ u32 hi = upper_32_bits(paddr);
+ u32 pci_addr = lo & PCI_E_BAR_ADD_LOWMASK;
+
+ lo &= PCI_E_BAR_ADD_MASK;
+
+ /* Program 64-bit BAR remap entry for this channel (table @ 0x208 + ch * 8) */
+ writel_relaxed(hi, hws->bar0_base +
+ PCI_ADDR_TABLE_BASE + 0x208 + ch * 8);
+ writel_relaxed(lo, hws->bar0_base +
+ PCI_ADDR_TABLE_BASE + 0x208 + ch * 8 +
+ PCIE_BARADDROFSIZE);
+
+ /* Program capture engine per-channel base/half */
+ writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
+ hws->bar0_base + CVBS_IN_BUF_BASE +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* half size: use either the current format’s half or half of scratch */
+ {
+ u32 half = hws->video[ch].pix.half_size ?
+ hws->video[ch].pix.half_size :
+ (u32)(hws->scratch_vid[ch].size / 2);
+
+ writel_relaxed(half / 16,
+ hws->bar0_base + CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+ }
+
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS); /* flush posted writes */
+}
+
+static void hws_seed_all_channels(struct hws_pcie_dev *hws)
+{
+ int ch;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++) {
+ if (hws->scratch_vid[ch].cpu)
+ hws_seed_channel(hws, ch);
+ }
+}
+
+static void hws_irq_mask_gate(struct hws_pcie_dev *hws)
+{
+ writel(0x00000000, hws->bar0_base + INT_EN_REG_BASE);
+ (void)readl(hws->bar0_base + INT_EN_REG_BASE);
+}
+
+static void hws_irq_unmask_gate(struct hws_pcie_dev *hws)
+{
+ writel(HWS_INT_EN_MASK, hws->bar0_base + INT_EN_REG_BASE);
+ (void)readl(hws->bar0_base + INT_EN_REG_BASE);
+}
+
+static void hws_irq_clear_pending(struct hws_pcie_dev *hws)
+{
+ u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+
+ if (st) {
+ writel(st, hws->bar0_base + HWS_REG_INT_STATUS); /* W1C */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+}
+
+static void hws_block_hotpaths(struct hws_pcie_dev *hws)
+{
+ WRITE_ONCE(hws->suspended, true);
+ if (hws->irq >= 0)
+ disable_irq(hws->irq);
+
+ if (!hws->bar0_base)
+ return;
+
+ hws_irq_mask_gate(hws);
+ hws_irq_clear_pending(hws);
+}
+
+static int hws_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+ struct hws_pcie_dev *hws;
+ int i, ret, irq;
+ unsigned long irqf = 0;
+ bool v4l2_registered = false;
+
+ /* devres-backed device object */
+ hws = devm_kzalloc(&pdev->dev, sizeof(*hws), GFP_KERNEL);
+ if (!hws)
+ return -ENOMEM;
+
+ hws->pdev = pdev;
+ hws->irq = -1;
+ hws->suspended = false;
+ pci_set_drvdata(pdev, hws);
+
+ /* 1) Enable device + bus mastering (managed) */
+ ret = pcim_enable_device(pdev);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "pcim_enable_device\n");
+ pci_set_master(pdev);
+
+ /* 2) Map BAR0 (managed) */
+ ret = pcim_iomap_regions(pdev, BIT(0), KBUILD_MODNAME);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "pcim_iomap_regions BAR0\n");
+ hws->bar0_base = pcim_iomap_table(pdev)[0];
+
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+ if (ret) {
+ dev_warn(&pdev->dev,
+ "64-bit DMA mask unavailable, falling back to 32-bit (%d)\n",
+ ret);
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ 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");
+ }
+
+ /* 3) Optional PCIe tuning (same as before) */
+ enable_pcie_relaxed_ordering(pdev);
+#ifdef CONFIG_ARCH_TI816X
+ pcie_set_readrq(pdev, 128);
+#endif
+
+ /* 4) Identify chip & capabilities */
+ read_chip_id(hws);
+ dev_info(&pdev->dev, "Device VID=0x%04x DID=0x%04x\n",
+ pdev->vendor, pdev->device);
+ hws_init_video_sys(hws, false);
+
+ /* 5) Init channels (video state, locks, vb2, ctrls) */
+ for (i = 0; i < hws->max_channels; i++) {
+ ret = hws_video_init_channel(hws, i);
+ if (ret) {
+ dev_err(&pdev->dev, "video channel init failed (ch=%d)\n", i);
+ goto err_unwind_channels;
+ }
+ }
+
+ /* 6) Allocate scratch DMA and seed BAR table + channel base/half (legacy SetDMAAddress) */
+ ret = hws_alloc_seed_buffers(hws);
+ if (!ret)
+ hws_seed_all_channels(hws);
+
+ /* 7) Start-run sequence (like InitVideoSys) */
+ hws_init_video_sys(hws, false);
+
+ /* A) Force legacy INTx; legacy used request_irq(pdev->irq, ..., IRQF_SHARED) */
+ pci_intx(pdev, 1);
+ irqf = IRQF_SHARED;
+ irq = pdev->irq;
+ hws->irq = irq;
+ dev_info(&pdev->dev, "IRQ mode: legacy INTx (shared), irq=%d\n", irq);
+
+ /* B) Mask the device's global/bridge gate (INT_EN_REG_BASE) */
+ hws_irq_mask_gate(hws);
+
+ /* C) Clear any sticky pending interrupt status (W1C) before we arm the line */
+ hws_irq_clear_pending(hws);
+
+ /* D) Request the legacy shared interrupt line (no vectors/MSI/MSI-X) */
+ ret = devm_request_irq(&pdev->dev, irq, hws_irq_handler, irqf,
+ dev_name(&pdev->dev), hws);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq(%d) failed: %d\n", irq, ret);
+ goto err_unwind_channels;
+ }
+
+ /* E) Set the global interrupt enable bit in main control register */
+ {
+ u32 ctl_reg = readl(hws->bar0_base + HWS_REG_CTL);
+
+ ctl_reg |= 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");
+ }
+
+ /* F) Open the global gate just like legacy did */
+ hws_irq_unmask_gate(hws);
+ dev_info(&pdev->dev, "INT_EN_GATE readback=0x%08x\n",
+ readl(hws->bar0_base + INT_EN_REG_BASE));
+
+ /* 11) Register V4L2 */
+ ret = hws_video_register(hws);
+ if (ret) {
+ dev_err(&pdev->dev, "video_register: %d\n", ret);
+ goto err_unwind_channels;
+ }
+ v4l2_registered = true;
+
+ /* 12) Background monitor thread (managed) */
+ hws->main_task = kthread_run(main_ks_thread_handle, hws, "hws-mon");
+ if (IS_ERR(hws->main_task)) {
+ ret = PTR_ERR(hws->main_task);
+ hws->main_task = NULL;
+ dev_err(&pdev->dev, "kthread_run: %d\n", ret);
+ goto err_unregister_va;
+ }
+ ret = devm_add_action_or_reset(&pdev->dev, hws_stop_kthread_action, hws);
+ if (ret) {
+ dev_err(&pdev->dev, "devm_add_action kthread_stop: %d\n", ret);
+ goto err_unregister_va; /* reset already stopped the thread */
+ }
+
+ /* 13) Final: show the line is armed */
+ dev_info(&pdev->dev, "irq handler installed on irq=%d\n", irq);
+ return 0;
+
+err_unregister_va:
+ hws_stop_device(hws);
+ hws_video_unregister(hws);
+ hws_free_seed_buffers(hws);
+ return ret;
+err_unwind_channels:
+ hws_free_seed_buffers(hws);
+ if (!v4l2_registered) {
+ while (--i >= 0)
+ hws_video_cleanup_channel(hws, i);
+ }
+ return ret;
+}
+
+static int hws_check_busy(struct hws_pcie_dev *pdx)
+{
+ void __iomem *reg = pdx->bar0_base + HWS_REG_SYS_STATUS;
+ u32 val;
+ int ret;
+
+ /* poll until !(val & BUSY_BIT), sleeping HWS_BUSY_POLL_DELAY_US between reads */
+ ret = readl_poll_timeout(reg, val, !(val & HWS_SYS_DMA_BUSY_BIT),
+ HWS_BUSY_POLL_DELAY_US,
+ HWS_BUSY_POLL_TIMEOUT_US);
+ if (ret) {
+ dev_err(&pdx->pdev->dev,
+ "SYS_STATUS busy bit never cleared (0x%08x)\n", val);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static void hws_stop_dsp(struct hws_pcie_dev *hws)
+{
+ u32 status;
+
+ /* Read the decoder mode/status register */
+ status = readl(hws->bar0_base + HWS_REG_DEC_MODE);
+ dev_dbg(&hws->pdev->dev, "%s: status=0x%08x\n", __func__, status);
+
+ /* If the device looks unplugged/stuck, bail out */
+ if (status == 0xFFFFFFFF)
+ return;
+
+ /* Tell the DSP to stop */
+ writel(0x10, hws->bar0_base + HWS_REG_DEC_MODE);
+
+ if (hws_check_busy(hws))
+ dev_warn(&hws->pdev->dev, "DSP busy timeout on stop\n");
+ /* Disable video capture engine in the DSP */
+ writel(0x0, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+}
+
+/* Publish stop so ISR/BH won’t touch video buffers anymore. */
+static void hws_publish_stop_flags(struct hws_pcie_dev *hws)
+{
+ unsigned int i;
+
+ for (i = 0; i < hws->cur_max_video_ch; ++i) {
+ struct hws_video *v = &hws->video[i];
+
+ WRITE_ONCE(v->cap_active, false);
+ WRITE_ONCE(v->stop_requested, true);
+ }
+
+ smp_wmb(); /* make flags visible before we touch MMIO/queues */
+}
+
+/* Drain engines + ISR/BH after flags are published. */
+static void hws_drain_after_stop(struct hws_pcie_dev *hws)
+{
+ u32 ackmask = 0;
+ unsigned int i;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ /* Mask device enables: no new DMA starts. */
+ writel(0x0, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS); /* flush */
+
+ /* Let any in-flight DMAs finish (best-effort). */
+ (void)hws_check_busy(hws);
+
+ /* Ack any latched VDONE. */
+ for (i = 0; i < hws->cur_max_video_ch; ++i)
+ ackmask |= HWS_INT_VDONE_BIT(i);
+ if (ackmask) {
+ writel(ackmask, hws->bar0_base + HWS_REG_INT_STATUS);
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ /* Ensure no hard IRQ is still running. */
+ if (hws->irq >= 0)
+ synchronize_irq(hws->irq);
+
+ dev_dbg(&hws->pdev->dev, "lifecycle:drain-after-stop:done (%lluus)\n",
+ hws_elapsed_us(start_ns));
+}
+
+static void hws_stop_device(struct hws_pcie_dev *hws)
+{
+ u32 status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+ u64 start_ns = ktime_get_mono_fast_ns();
+ bool live = status != 0xFFFFFFFF;
+
+ dev_dbg(&hws->pdev->dev, "%s: status=0x%08x\n", __func__, status);
+ if (!live) {
+ hws->pci_lost = true;
+ goto out;
+ }
+ hws_log_lifecycle_snapshot(hws, "stop-device", "begin");
+
+ /* Make ISR/BH a no-op, then drain engines/IRQ. */
+ hws_publish_stop_flags(hws);
+ hws_drain_after_stop(hws);
+
+ /* 1) Stop the on-board DSP */
+ hws_stop_dsp(hws);
+
+out:
+ hws->start_run = 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__);
+}
+
+static int hws_quiesce_for_transition(struct hws_pcie_dev *hws,
+ const char *action,
+ bool stop_thread)
+{
+ struct device *dev = &hws->pdev->dev;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+ int vret;
+
+ hws_log_lifecycle_snapshot(hws, action, "begin");
+
+ step_ns = 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");
+
+ if (stop_thread) {
+ step_ns = 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));
+ }
+
+ step_ns = ktime_get_mono_fast_ns();
+ vret = hws_video_quiesce(hws, action);
+ dev_dbg(dev, "lifecycle:%s:video-quiesce ret=%d (%lluus)\n", action,
+ vret, hws_elapsed_us(step_ns));
+ if (vret)
+ dev_warn(dev, "lifecycle:%s video quiesce returned %d\n",
+ action, vret);
+
+ step_ns = 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=%d (%lluus)\n", action,
+ vret, hws_elapsed_us(start_ns));
+
+ return vret;
+}
+
+static void hws_remove(struct pci_dev *pdev)
+{
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ u64 start_ns;
+
+ if (!hws)
+ return;
+
+ start_ns = 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);
+
+ /* Stop hardware / capture cleanly (your helper) */
+ hws_stop_device(hws);
+
+ /* Unregister subsystems you registered */
+ hws_video_unregister(hws);
+
+ /* Release seeded DMA buffers */
+ hws_free_seed_buffers(hws);
+ /* kthread is stopped by the devm action you added in probe */
+ hws_log_lifecycle_snapshot(hws, "remove", "end");
+ dev_info(&pdev->dev, "lifecycle:remove done (%lluus)\n",
+ hws_elapsed_us(start_ns));
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int hws_pm_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int vret;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ dev_info(dev, "lifecycle:pm_suspend begin\n");
+ vret = hws_quiesce_for_transition(hws, "pm_suspend", false);
+
+ step_ns = 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=%d (%lluus)\n", vret,
+ hws_elapsed_us(start_ns));
+
+ return 0;
+}
+
+static int hws_pm_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int ret;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ dev_info(dev, "lifecycle:pm_resume begin\n");
+
+ /* Back to D0 and re-enable the function */
+ step_ns = ktime_get_mono_fast_ns();
+ pci_set_power_state(pdev, PCI_D0);
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(dev, "pci_enable_device: %d\n", ret);
+ return ret;
+ }
+ pci_restore_state(pdev);
+ pci_set_master(pdev);
+ dev_dbg(dev, "lifecycle:pm_resume:pci-enable (%lluus)\n",
+ hws_elapsed_us(step_ns));
+
+ /* Reapply any PCIe tuning lost across D3 */
+ enable_pcie_relaxed_ordering(pdev);
+
+ /* Reinitialize chip-side capabilities / registers */
+ step_ns = 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));
+
+ /* IRQs can be re-enabled now that MMIO is sane */
+ step_ns = ktime_get_mono_fast_ns();
+ if (hws->irq >= 0)
+ enable_irq(hws->irq);
+
+ WRITE_ONCE(hws->suspended, false);
+ dev_dbg(dev, "lifecycle:pm_resume:irq-unsuspend (%lluus)\n",
+ hws_elapsed_us(step_ns));
+
+ /* vb2: nothing mandatory; userspace will STREAMON again when ready */
+ step_ns = 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));
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(hws_pm_ops, hws_pm_suspend, hws_pm_resume);
+# define HWS_PM_OPS (&hws_pm_ops)
+#else
+# define HWS_PM_OPS NULL
+#endif
+
+static void hws_shutdown(struct pci_dev *pdev)
+{
+ struct hws_pcie_dev *hws = pci_get_drvdata(pdev);
+ int vret = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+ u64 step_ns;
+
+ if (!hws)
+ return;
+
+ dev_info(&pdev->dev, "lifecycle:pci_shutdown begin\n");
+ vret = hws_quiesce_for_transition(hws, "pci_shutdown", true);
+
+ step_ns = 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=%d (%lluus)\n",
+ vret, hws_elapsed_us(start_ns));
+}
+
+static struct pci_driver hws_pci_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = hws_pci_table,
+ .probe = hws_probe,
+ .remove = hws_remove,
+ .shutdown = hws_shutdown,
+ .driver = {
+ .pm = HWS_PM_OPS,
+ },
+};
+
+MODULE_DEVICE_TABLE(pci, hws_pci_table);
+
+static int __init pcie_hws_init(void)
+{
+ return pci_register_driver(&hws_pci_driver);
+}
+
+static void __exit pcie_hws_exit(void)
+{
+ pci_unregister_driver(&hws_pci_driver);
+}
+
+module_init(pcie_hws_init);
+module_exit(pcie_hws_exit);
+
+MODULE_DESCRIPTION(DRV_NAME);
+MODULE_AUTHOR("Ben Hoff <hoff.benjamin.k@gmail.com>");
+MODULE_AUTHOR("Sales <sales@avmatrix.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("DMA_BUF");
diff --git a/drivers/media/pci/hws/hws_reg.h b/drivers/media/pci/hws/hws_reg.h
new file mode 100644
index 000000000000..e4fb4af44434
--- /dev/null
+++ b/drivers/media/pci/hws/hws_reg.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _HWS_PCIE_REG_H
+#define _HWS_PCIE_REG_H
+
+#include <linux/bits.h>
+#include <linux/sizes.h>
+
+#define XDMA_CHANNEL_NUM_MAX (1)
+#define MAX_NUM_ENGINES (XDMA_CHANNEL_NUM_MAX * 2)
+
+#define PCIE_BARADDROFSIZE 4u
+
+#define PCI_BUS_ACCESS_BASE 0x00000000U
+#define INT_EN_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0134U)
+#define PCIEBR_EN_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0148U)
+#define PCIE_INT_DEC_REG_BASE (PCI_BUS_ACCESS_BASE + 0x0138U)
+
+#define HWS_INT_EN_MASK 0x0003FFFFU
+
+#define PCIEBAR_AXI_BASE 0x20000000U
+
+#define CTL_REG_ACC_BASE 0x0
+#define PCI_ADDR_TABLE_BASE CTL_REG_ACC_BASE
+
+#define CVBS_IN_BASE 0x00004000U
+#define CVBS_IN_BUF_BASE (CVBS_IN_BASE + (16U * PCIE_BARADDROFSIZE))
+#define CVBS_IN_BUF_BASE2 (CVBS_IN_BASE + (50U * PCIE_BARADDROFSIZE))
+
+/* 2 Mib */
+#define MAX_L_VIDEO_SIZE 0x200000U
+
+#define PCI_E_BAR_PAGE_SIZE 0x20000000
+#define PCI_E_BAR_ADD_MASK 0xE0000000
+#define PCI_E_BAR_ADD_LOWMASK 0x1FFFFFFF
+
+#define MAX_VID_CHANNELS 4
+
+#define MAX_MM_VIDEO_SIZE SZ_4M
+
+#define MAX_VIDEO_HW_W 1920
+#define MAX_VIDEO_HW_H 1080
+#define MAX_VIDEO_SCALER_SIZE (1920U * 1080U * 2U)
+
+#define MIN_VAMP_BRIGHTNESS_UNITS 0
+#define MAX_VAMP_BRIGHTNESS_UNITS 0xff
+
+#define MIN_VAMP_CONTRAST_UNITS 0
+#define MAX_VAMP_CONTRAST_UNITS 0xff
+
+#define MIN_VAMP_SATURATION_UNITS 0
+#define MAX_VAMP_SATURATION_UNITS 0xff
+
+#define MIN_VAMP_HUE_UNITS 0
+#define MAX_VAMP_HUE_UNITS 0xff
+
+#define HWS_BRIGHTNESS_DEFAULT 0x80
+#define HWS_CONTRAST_DEFAULT 0x80
+#define HWS_SATURATION_DEFAULT 0x80
+#define HWS_HUE_DEFAULT 0x00
+
+/* Core/global status. */
+#define HWS_REG_SYS_STATUS (CVBS_IN_BASE + 0 * PCIE_BARADDROFSIZE)
+/* bit3: DMA busy, bit2: int, ... */
+
+#define HWS_SYS_DMA_BUSY_BIT BIT(3) /* 0x08 = DMA busy flag */
+
+#define HWS_REG_DEC_MODE (CVBS_IN_BASE + 0 * PCIE_BARADDROFSIZE)
+/* Main control register */
+#define HWS_REG_CTL (CVBS_IN_BASE + 4 * PCIE_BARADDROFSIZE)
+#define HWS_CTL_IRQ_ENABLE_BIT BIT(0) /* Global interrupt enable bit */
+/* Write 0x00 to fully reset decoder,
+ * set bit 31=1 to "start run",
+ * low byte=0x13 selects YUYV/BT.709/etc,
+ * in ReadChipId() we also write 0x00 and 0x10 here for chip-ID sequencing.
+ */
+
+/* Per-channel done flags. */
+#define HWS_REG_INT_STATUS (CVBS_IN_BASE + 1 * PCIE_BARADDROFSIZE)
+#define HWS_SYS_BUSY_BIT BIT(2) /* matches old 0x04 test */
+
+/* Capture enable switches. */
+/* bit0-3: CH0-CH3 video enable */
+#define HWS_REG_VCAP_ENABLE (CVBS_IN_BASE + 2 * PCIE_BARADDROFSIZE)
+/* bits0-3: signal present, bits8-11: interlace */
+#define HWS_REG_ACTIVE_STATUS (CVBS_IN_BASE + 5 * PCIE_BARADDROFSIZE)
+/* bits0-3: HDCP detected */
+#define HWS_REG_HDCP_STATUS (CVBS_IN_BASE + 8 * PCIE_BARADDROFSIZE)
+#define HWS_REG_DMA_MAX_SIZE (CVBS_IN_BASE + 9 * PCIE_BARADDROFSIZE)
+
+/* Buffer addresses (written once during init/reset). */
+/* Base of host-visible buffer. */
+#define HWS_REG_VBUF1_ADDR (CVBS_IN_BASE + 25 * PCIE_BARADDROFSIZE)
+/* Per-channel DMA address. */
+#define HWS_REG_DMA_ADDR(ch) (CVBS_IN_BASE + (26 + (ch)) * PCIE_BARADDROFSIZE)
+
+/* Per-channel live buffer toggles (read-only). */
+#define HWS_REG_VBUF_TOGGLE(ch) (CVBS_IN_BASE + (32 + (ch)) * PCIE_BARADDROFSIZE)
+/*
+ * Returns 0 or 1 = which half of the video ring the DMA engine is
+ * currently filling for channel *ch* (0-3).
+ */
+
+/* Per-interrupt bits (video 0-3). */
+#define HWS_INT_VDONE_BIT(ch) BIT(ch) /* 0x01,0x02,0x04,0x08 */
+
+#define HWS_REG_INT_ACK (CVBS_IN_BASE + 0x4000 + 1 * PCIE_BARADDROFSIZE)
+
+/* 16-bit W | 16-bit H. */
+#define HWS_REG_IN_RES(ch) (CVBS_IN_BASE + (90 + (ch) * 2) * PCIE_BARADDROFSIZE)
+/* B|C|H|S packed bytes. */
+#define HWS_REG_BCHS(ch) (CVBS_IN_BASE + (91 + (ch) * 2) * PCIE_BARADDROFSIZE)
+
+/* Input fps. */
+#define HWS_REG_FRAME_RATE(ch) (CVBS_IN_BASE + (110 + (ch)) * PCIE_BARADDROFSIZE)
+/* Programmed out W|H. */
+#define HWS_REG_OUT_RES(ch) (CVBS_IN_BASE + (120 + (ch)) * PCIE_BARADDROFSIZE)
+/* Programmed out fps. */
+#define HWS_REG_OUT_FRAME_RATE(ch) (CVBS_IN_BASE + (130 + (ch)) * PCIE_BARADDROFSIZE)
+
+/* Device version/port ID/subversion register. */
+#define HWS_REG_DEVICE_INFO (CVBS_IN_BASE + 88 * PCIE_BARADDROFSIZE)
+/*
+ * Reading this 32-bit word returns:
+ * bits 7:0 = "device version"
+ * bits 15:8 = "device sub-version"
+ * bits 23:24 = "HW key / port ID" etc.
+ * bits 31:28 = "support YV12" flags
+ */
+
+/* Convenience aliases for individual channels. */
+#define HWS_REG_VBUF_TOGGLE_CH0 HWS_REG_VBUF_TOGGLE(0)
+#define HWS_REG_VBUF_TOGGLE_CH1 HWS_REG_VBUF_TOGGLE(1)
+#define HWS_REG_VBUF_TOGGLE_CH2 HWS_REG_VBUF_TOGGLE(2)
+#define HWS_REG_VBUF_TOGGLE_CH3 HWS_REG_VBUF_TOGGLE(3)
+
+#endif /* _HWS_PCIE_REG_H */
diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.c b/drivers/media/pci/hws/hws_v4l2_ioctl.c
new file mode 100644
index 000000000000..9c0826c0f9f9
--- /dev/null
+++ b/drivers/media/pci/hws/hws_v4l2_ioctl.c
@@ -0,0 +1,924 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/math64.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_v4l2_ioctl.h"
+
+struct hws_dv_mode {
+ struct v4l2_dv_timings timings;
+ u32 refresh_hz;
+};
+
+static const struct hws_dv_mode *
+hws_find_dv_by_wh(u32 w, u32 h, bool interlaced);
+static const struct hws_dv_mode *
+hws_find_dv_by_wh_fps(u32 w, u32 h, bool interlaced, u32 fps);
+static u32 hws_get_live_fps(struct hws_video *vid);
+static u32 hws_input_status(struct hws_video *vid);
+static int hws_fill_dv_timings(u32 w, u32 h, bool interlace, u32 fps,
+ struct v4l2_dv_timings *timings);
+
+static const struct hws_dv_mode hws_dv_modes[] = {
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1920,
+ .height = 1080,
+ .hfrontporch = 88,
+ .hsync = 44,
+ .hbackporch = 148,
+ .vfrontporch = 4,
+ .vsync = 5,
+ .vbackporch = 36,
+ .pixelclock = 148500000,
+ .polarities = V4L2_DV_VSYNC_POS_POL |
+ V4L2_DV_HSYNC_POS_POL,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1920,
+ .height = 1080,
+ .hfrontporch = 88,
+ .hsync = 44,
+ .hbackporch = 148,
+ .vfrontporch = 4,
+ .vsync = 5,
+ .vbackporch = 36,
+ .pixelclock = 74250000,
+ .polarities = V4L2_DV_VSYNC_POS_POL |
+ V4L2_DV_HSYNC_POS_POL,
+ .interlaced = 0,
+ },
+ },
+ 30,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 720,
+ .hfrontporch = 110,
+ .hsync = 40,
+ .hbackporch = 220,
+ .vfrontporch = 5,
+ .vsync = 5,
+ .vbackporch = 20,
+ .pixelclock = 74250000,
+ .polarities = V4L2_DV_VSYNC_POS_POL |
+ V4L2_DV_HSYNC_POS_POL,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 720,
+ .height = 480,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 720,
+ .height = 576,
+ .interlaced = 0,
+ },
+ },
+ 50,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 800,
+ .height = 600,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 640,
+ .height = 480,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1024,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 800,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1280,
+ .height = 1024,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1360,
+ .height = 768,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1440,
+ .height = 900,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1680,
+ .height = 1050,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+ /* Portrait */
+ {
+ {
+ .type = V4L2_DV_BT_656_1120,
+ .bt = {
+ .width = 1080,
+ .height = 1920,
+ .interlaced = 0,
+ },
+ },
+ 60,
+ },
+};
+
+static const size_t hws_dv_modes_cnt = ARRAY_SIZE(hws_dv_modes);
+
+/* YUYV: 16 bpp; align to 64 as you did elsewhere */
+static inline u32 hws_calc_bpl_yuyv(u32 w) { return ALIGN(w * 2, 64); }
+static inline u32 hws_calc_size_yuyv(u32 w, u32 h) { return hws_calc_bpl_yuyv(w) * h; }
+static inline u32 hws_calc_half_size(u32 sizeimage)
+{
+ return sizeimage / 2;
+}
+
+static inline void hws_hw_write_bchs(struct hws_pcie_dev *hws, unsigned int ch,
+ u8 br, u8 co, u8 hu, u8 sa)
+{
+ u32 packed = (sa << 24) | (hu << 16) | (co << 8) | br;
+
+ if (!hws || !hws->bar0_base || ch >= hws->max_channels)
+ return;
+ writel_relaxed(packed, hws->bar0_base + HWS_REG_BCHS(ch));
+ (void)readl(hws->bar0_base + HWS_REG_BCHS(ch)); /* post write */
+}
+
+/* Helper: find a supported DV mode by W/H + interlace flag */
+static const struct hws_dv_mode *
+hws_match_supported_dv(const struct v4l2_dv_timings *req)
+{
+ const struct v4l2_bt_timings *bt;
+ u32 fps;
+
+ if (!req || req->type != V4L2_DV_BT_656_1120)
+ return NULL;
+
+ bt = &req->bt;
+ fps = 0;
+ if (bt->pixelclock) {
+ u32 total_w = bt->width + bt->hfrontporch + bt->hsync +
+ bt->hbackporch;
+ u32 total_h = bt->height + bt->vfrontporch + bt->vsync +
+ bt->vbackporch;
+
+ if (total_w && total_h)
+ fps = DIV_ROUND_CLOSEST_ULL((u64)bt->pixelclock,
+ (u64)total_w * total_h);
+ }
+ if (fps) {
+ const struct hws_dv_mode *exact =
+ hws_find_dv_by_wh_fps(bt->width, bt->height,
+ !!bt->interlaced, fps);
+ if (exact)
+ return exact;
+ }
+ return hws_find_dv_by_wh(bt->width, bt->height, !!bt->interlaced);
+}
+
+/* Helper: find a supported DV mode by W/H + interlace flag */
+static const struct hws_dv_mode *
+hws_find_dv_by_wh(u32 w, u32 h, bool interlaced)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct hws_dv_mode *t = &hws_dv_modes[i];
+ const struct v4l2_bt_timings *bt = &t->timings.bt;
+
+ if (t->timings.type != V4L2_DV_BT_656_1120)
+ continue;
+
+ if (bt->width == w && bt->height == h &&
+ !!bt->interlaced == interlaced)
+ return t;
+ }
+ return NULL;
+}
+
+static const struct hws_dv_mode *
+hws_find_dv_by_wh_fps(u32 w, u32 h, bool interlaced, u32 fps)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct hws_dv_mode *t = &hws_dv_modes[i];
+ const struct v4l2_bt_timings *bt = &t->timings.bt;
+
+ if (t->timings.type != V4L2_DV_BT_656_1120)
+ continue;
+
+ if (bt->width == w && bt->height == h &&
+ !!bt->interlaced == interlaced &&
+ t->refresh_hz == fps)
+ return t;
+ }
+ return NULL;
+}
+
+static bool hws_get_live_dv_geometry(struct hws_video *vid,
+ u32 *w, u32 *h, bool *interlaced)
+{
+ struct hws_pcie_dev *pdx;
+ u32 reg;
+
+ if (!vid)
+ return false;
+
+ pdx = vid->parent;
+ if (!pdx || !pdx->bar0_base)
+ return false;
+
+ reg = readl(pdx->bar0_base + HWS_REG_IN_RES(vid->channel_index));
+ if (!reg || reg == 0xFFFFFFFF)
+ return false;
+
+ if (w)
+ *w = reg & 0xFFFF;
+ if (h)
+ *h = (reg >> 16) & 0xFFFF;
+ if (interlaced) {
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ *interlaced = !!(reg & BIT(8 + vid->channel_index));
+ }
+ return true;
+}
+
+static u32 hws_get_live_fps(struct hws_video *vid)
+{
+ struct hws_pcie_dev *pdx;
+ u32 fps;
+
+ if (!vid)
+ return 0;
+
+ pdx = vid->parent;
+ if (!pdx || !pdx->bar0_base)
+ return 0;
+
+ fps = readl(pdx->bar0_base + HWS_REG_FRAME_RATE(vid->channel_index));
+ if (!fps || fps == 0xFFFFFFFF || fps > 240)
+ return 0;
+
+ return fps;
+}
+
+static u32 hws_pick_fps_from_mode(u32 w, u32 h, bool interlaced)
+{
+ const struct hws_dv_mode *m = hws_find_dv_by_wh(w, h, interlaced);
+
+ if (m && m->refresh_hz)
+ return m->refresh_hz;
+ /* Fallback to a sane default */
+ return 60;
+}
+
+static int hws_fill_dv_timings(u32 w, u32 h, bool interlace, u32 fps,
+ struct v4l2_dv_timings *timings)
+{
+ const struct hws_dv_mode *m;
+
+ m = fps ? hws_find_dv_by_wh_fps(w, h, interlace, fps) : NULL;
+ if (!m)
+ m = hws_find_dv_by_wh(w, h, interlace);
+ if (!m)
+ return -ENOLINK;
+
+ *timings = m->timings;
+ return 0;
+}
+
+static u32 hws_input_status(struct hws_video *vid)
+{
+ struct hws_pcie_dev *pdx;
+ u32 reg;
+
+ if (!vid)
+ return V4L2_IN_ST_NO_SIGNAL;
+
+ pdx = vid->parent;
+ if (!pdx || !pdx->bar0_base)
+ return V4L2_IN_ST_NO_SIGNAL;
+
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ if (reg == 0xffffffff)
+ return V4L2_IN_ST_NO_SIGNAL;
+
+ return (reg & BIT(vid->channel_index)) ? 0 : V4L2_IN_ST_NO_SIGNAL;
+}
+
+/* Query the *current detected* DV timings on the input.
+ * If you have a real hardware detector, call it here; otherwise we
+ * derive from the cached pix state and map to the closest supported DV mode.
+ */
+int hws_vidioc_query_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ u32 w, h;
+ u32 fps;
+ bool interlace;
+
+ if (!timings)
+ return -EINVAL;
+
+ w = vid->pix.width;
+ h = vid->pix.height;
+ interlace = vid->pix.interlaced;
+ (void)hws_get_live_dv_geometry(vid, &w, &h, &interlace);
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(w, h, interlace);
+
+ return hws_fill_dv_timings(w, h, interlace, fps, timings);
+}
+
+/* Enumerate the Nth supported DV timings from our static table. */
+int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
+ struct v4l2_enum_dv_timings *edv)
+{
+ struct hws_video *vid = video_drvdata(file);
+ const struct hws_dv_mode *m;
+ u32 w, h;
+ u32 fps;
+ bool interlace;
+
+ if (!edv)
+ return -EINVAL;
+
+ if (edv->pad)
+ return -EINVAL;
+
+ w = 0;
+ h = 0;
+ interlace = false;
+ if (hws_get_live_dv_geometry(vid, &w, &h, &interlace)) {
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(w, h, interlace);
+ m = fps ? hws_find_dv_by_wh_fps(w, h, interlace, fps) : NULL;
+ if (!m)
+ m = hws_find_dv_by_wh(w, h, interlace);
+ if (m) {
+ if (edv->index)
+ return -EINVAL;
+ edv->timings = m->timings;
+ return 0;
+ }
+ }
+
+ if (edv->index >= hws_dv_modes_cnt)
+ return -EINVAL;
+
+ edv->timings = hws_dv_modes[edv->index].timings;
+ return 0;
+}
+
+/* Get the *currently configured* DV timings. */
+int hws_vidioc_g_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ u32 w, h;
+ u32 fps;
+ bool interlace;
+
+ if (!timings)
+ return -EINVAL;
+
+ w = vid->pix.width;
+ h = vid->pix.height;
+ interlace = vid->pix.interlaced;
+ if (hws_get_live_dv_geometry(vid, &w, &h, &interlace)) {
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(w, h, interlace);
+ return hws_fill_dv_timings(w, h, interlace, fps, timings);
+ }
+
+ *timings = vid->cur_dv_timings;
+ return 0;
+}
+
+static inline void hws_set_colorimetry_state(struct hws_pix_state *p)
+{
+ bool sd = p->height <= 576;
+
+ p->colorspace = sd ? V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
+ p->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ p->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ p->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+}
+
+/* Set DV timings: must match one of our supported modes.
+ * If buffers are queued and this implies a size change, we reject with -EBUSY.
+ * Otherwise we update pix state and (optionally) reprogram the HW.
+ */
+int hws_vidioc_s_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct hws_video *vid = video_drvdata(file);
+ const struct hws_dv_mode *m;
+ const struct v4l2_bt_timings *bt;
+ u32 new_w, new_h;
+ bool interlaced;
+ int ret = 0;
+ unsigned long was_busy;
+ u32 live_w, live_h;
+ u32 live_fps;
+ bool live_interlaced;
+ bool live_present;
+
+ if (!timings)
+ return -EINVAL;
+
+ m = hws_match_supported_dv(timings);
+ if (!m)
+ return -EINVAL;
+
+ bt = &m->timings.bt;
+ if (bt->interlaced)
+ return -EINVAL; /* only progressive modes are advertised */
+ new_w = bt->width;
+ new_h = bt->height;
+ interlaced = false;
+
+ lockdep_assert_held(&vid->state_lock);
+ live_present = hws_get_live_dv_geometry(vid, &live_w, &live_h,
+ &live_interlaced);
+
+ /* If vb2 has active buffers and size would change, reject. */
+ was_busy = vb2_is_busy(&vid->buffer_queue);
+ if (was_busy &&
+ (new_w != vid->pix.width || new_h != vid->pix.height ||
+ interlaced != vid->pix.interlaced)) {
+ ret = -EBUSY;
+ return ret;
+ }
+
+ /* When a live input signal is present, the receiver owns the timing.
+ * Allow setting the already-active timings so v4l2-compliance can
+ * round-trip them, but reject attempts to retime the live source.
+ */
+ if (live_present) {
+ live_fps = hws_get_live_fps(vid);
+ if (!live_fps)
+ live_fps = vid->current_fps ? vid->current_fps :
+ hws_pick_fps_from_mode(live_w, live_h,
+ live_interlaced);
+ if (live_w == new_w && live_h == new_h &&
+ live_interlaced == interlaced &&
+ m->refresh_hz == live_fps)
+ return 0;
+ return -EBUSY;
+ }
+
+ /* Update software pixel state (and recalc sizes) */
+ vid->pix.width = new_w;
+ vid->pix.height = new_h;
+ vid->pix.field = interlaced ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_NONE;
+ vid->pix.interlaced = interlaced;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+
+ hws_set_colorimetry_state(&vid->pix);
+
+ /* Recompute stride/sizeimage/half_size using your helper */
+ vid->pix.bytesperline = hws_calc_bpl_yuyv(new_w);
+ vid->pix.sizeimage = hws_calc_size_yuyv(new_w, new_h);
+ vid->pix.half_size = hws_calc_half_size(vid->pix.sizeimage);
+ vid->cur_dv_timings = m->timings;
+ vid->current_fps = m->refresh_hz;
+ if (!was_busy)
+ vid->alloc_sizeimage = vid->pix.sizeimage;
+ return ret;
+}
+
+/* Report DV timings capability: advertise BT.656/1120 with
+ * the min/max WxH derived from our table and basic progressive support.
+ */
+int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
+ struct v4l2_dv_timings_cap *cap)
+{
+ u32 min_w = ~0U, min_h = ~0U;
+ u32 max_w = 0, max_h = 0;
+ size_t i, n = 0;
+
+ if (!cap)
+ return -EINVAL;
+
+ memset(cap, 0, sizeof(*cap));
+ cap->type = V4L2_DV_BT_656_1120;
+
+ for (i = 0; i < ARRAY_SIZE(hws_dv_modes); i++) {
+ const struct v4l2_bt_timings *bt = &hws_dv_modes[i].timings.bt;
+
+ if (hws_dv_modes[i].timings.type != V4L2_DV_BT_656_1120)
+ continue;
+ n++;
+
+ if (bt->width < min_w)
+ min_w = bt->width;
+ if (bt->height < min_h)
+ min_h = bt->height;
+ if (bt->width > max_w)
+ max_w = bt->width;
+ if (bt->height > max_h)
+ max_h = bt->height;
+ }
+
+ /* If the table was empty, fail gracefully. */
+ if (!n || min_w == U32_MAX)
+ return -ENODATA;
+
+ cap->bt.min_width = min_w;
+ cap->bt.max_width = max_w;
+ cap->bt.min_height = min_h;
+ cap->bt.max_height = max_h;
+
+ /* We support both CEA-861- and VESA-style modes in the list. */
+ cap->bt.standards =
+ V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT;
+
+ /* Progressive only, unless your table includes interlaced entries. */
+ cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE;
+
+ /* Leave pixelclock/porch limits unconstrained (0) for now. */
+ return 0;
+}
+
+static int hws_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct hws_video *vid =
+ container_of(ctrl->handler, struct hws_video, control_handler);
+ struct hws_pcie_dev *pdx = vid->parent;
+ bool program = false;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ vid->current_brightness = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_CONTRAST:
+ vid->current_contrast = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_SATURATION:
+ vid->current_saturation = ctrl->val;
+ program = true;
+ break;
+ case V4L2_CID_HUE:
+ vid->current_hue = ctrl->val;
+ program = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (program) {
+ hws_hw_write_bchs(pdx, vid->channel_index,
+ (u8)vid->current_brightness,
+ (u8)vid->current_contrast,
+ (u8)vid->current_hue,
+ (u8)vid->current_saturation);
+ }
+ return 0;
+}
+
+const struct v4l2_ctrl_ops hws_ctrl_ops = {
+ .s_ctrl = hws_s_ctrl,
+};
+
+int hws_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
+{
+ struct hws_video *vid = video_drvdata(file);
+ int vi_index = vid->channel_index + 1; /* keep it simple */
+
+ strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+ snprintf(cap->card, sizeof(cap->card),
+ "AVMatrix HWS Capture %d", vi_index);
+ return 0;
+}
+
+int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh, struct v4l2_fmtdesc *f)
+{
+ if (f->index != 0)
+ return -EINVAL; /* only one format */
+
+ f->pixelformat = V4L2_PIX_FMT_YUYV;
+ return 0;
+}
+
+int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct hws_video *vid = video_drvdata(file);
+
+ fmt->fmt.pix.width = vid->pix.width;
+ fmt->fmt.pix.height = vid->pix.height;
+ fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ fmt->fmt.pix.field = vid->pix.field;
+ fmt->fmt.pix.bytesperline = vid->pix.bytesperline;
+ fmt->fmt.pix.sizeimage = vid->pix.sizeimage;
+ fmt->fmt.pix.colorspace = vid->pix.colorspace;
+ fmt->fmt.pix.ycbcr_enc = vid->pix.ycbcr_enc;
+ fmt->fmt.pix.quantization = vid->pix.quantization;
+ fmt->fmt.pix.xfer_func = vid->pix.xfer_func;
+ return 0;
+}
+
+static inline void hws_set_colorimetry_fmt(struct v4l2_pix_format *p)
+{
+ bool sd = p->height <= 576;
+
+ p->colorspace = sd ? V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
+ p->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ p->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ p->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+}
+
+int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct hws_video *vid = file ? video_drvdata(file) : NULL;
+ struct hws_pcie_dev *pdev = vid ? vid->parent : NULL;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ u32 req_w = pix->width, req_h = pix->height;
+ u32 w, h, min_bpl, bpl;
+ size_t size; /* wider than u32 for overflow check */
+ size_t max_frame = pdev ? pdev->max_hw_video_buf_sz : MAX_MM_VIDEO_SIZE;
+
+ /* Only YUYV */
+ pix->pixelformat = V4L2_PIX_FMT_YUYV;
+
+ /* Defaults then clamp */
+ w = (req_w ? req_w : 640);
+ h = (req_h ? req_h : 480);
+ if (w > MAX_VIDEO_HW_W)
+ w = MAX_VIDEO_HW_W;
+ if (h > MAX_VIDEO_HW_H)
+ h = MAX_VIDEO_HW_H;
+ if (!w)
+ w = 640; /* hard fallback in case macros are odd */
+ if (!h)
+ h = 480;
+
+ /* Field policy */
+ pix->field = V4L2_FIELD_NONE;
+
+ /* Stride policy for packed 16bpp, 64B align */
+ min_bpl = ALIGN(w * 2, 64);
+
+ /* Bound requested bpl to something sane, then align */
+ bpl = pix->bytesperline;
+ if (bpl < min_bpl) {
+ bpl = min_bpl;
+ } else {
+ /* Cap at 16x width to avoid silly values that overflow sizeimage */
+ u32 max_bpl = ALIGN(w * 2 * 16, 64);
+
+ if (bpl > max_bpl)
+ bpl = max_bpl;
+ bpl = ALIGN(bpl, 64);
+ }
+ if (h && max_frame) {
+ size_t max_bpl_hw = max_frame / h;
+
+ if (max_bpl_hw < min_bpl)
+ return -ERANGE;
+ max_bpl_hw = rounddown(max_bpl_hw, 64);
+ 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 = (u32)max_bpl_hw;
+ }
+ }
+ size = (size_t)bpl * (size_t)h;
+ if (size > max_frame)
+ return -ERANGE;
+
+ pix->width = w;
+ pix->height = h;
+ pix->bytesperline = bpl;
+ pix->sizeimage = (u32)size; /* logical size, not page-aligned */
+
+ hws_set_colorimetry_fmt(pix);
+ if (pdev)
+ dev_dbg(&pdev->pdev->dev,
+ "try_fmt: w=%u h=%u bpl=%u size=%u field=%u\n",
+ pix->width, pix->height, pix->bytesperline,
+ pix->sizeimage, pix->field);
+ return 0;
+}
+
+int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
+{
+ struct hws_video *vid = video_drvdata(file);
+ int ret;
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ /* Normalize the request */
+ ret = hws_vidioc_try_fmt_vid_cap(file, priv, f);
+ if (ret)
+ return ret;
+
+ /* Don't allow buffer layout changes while buffers are queued. */
+ if (vb2_is_busy(&vid->buffer_queue)) {
+ if (f->fmt.pix.width != vid->pix.width ||
+ f->fmt.pix.height != vid->pix.height ||
+ f->fmt.pix.bytesperline != vid->pix.bytesperline)
+ return -EBUSY;
+ }
+
+ /* Apply to driver state */
+ vid->pix.width = f->fmt.pix.width;
+ vid->pix.height = f->fmt.pix.height;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+ vid->pix.field = f->fmt.pix.field;
+ vid->pix.colorspace = f->fmt.pix.colorspace;
+ vid->pix.ycbcr_enc = f->fmt.pix.ycbcr_enc;
+ vid->pix.quantization = f->fmt.pix.quantization;
+ vid->pix.xfer_func = f->fmt.pix.xfer_func;
+
+ /* Update sizes (use helper if you prefer strict alignment math) */
+ vid->pix.bytesperline = f->fmt.pix.bytesperline; /* aligned */
+ vid->pix.sizeimage = f->fmt.pix.sizeimage; /* logical */
+ vid->pix.half_size = hws_calc_half_size(vid->pix.sizeimage);
+ vid->pix.interlaced = false;
+ /* S_FMT negotiates buffer layout only. Keep detector-owned DV timing
+ * state unchanged so a harmless restart cannot clobber the live FPS.
+ */
+ /* Or:
+ * hws_calc_sizeimage(vid, vid->pix.width, vid->pix.height, false);
+ */
+
+ /* Refresh vb2 watermark when idle */
+ if (!vb2_is_busy(&vid->buffer_queue))
+ vid->alloc_sizeimage = PAGE_ALIGN(vid->pix.sizeimage);
+ dev_dbg(&vid->parent->pdev->dev,
+ "s_fmt: w=%u h=%u bpl=%u size=%u alloc=%u\n",
+ vid->pix.width, vid->pix.height, vid->pix.bytesperline,
+ vid->pix.sizeimage, vid->alloc_sizeimage);
+
+ return 0;
+}
+
+int hws_vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *param)
+{
+ struct hws_video *vid = video_drvdata(file);
+ u32 fps;
+
+ if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ fps = hws_get_live_fps(vid);
+ if (!fps)
+ fps = vid->current_fps ? vid->current_fps : 60;
+
+ /* HDMI receivers report the detected frame period, they don't set it. */
+ param->parm.capture.capability = 0;
+ param->parm.capture.capturemode = 0;
+ param->parm.capture.timeperframe.numerator = 1;
+ param->parm.capture.timeperframe.denominator = fps;
+ param->parm.capture.extendedmode = 0;
+ param->parm.capture.readbuffers = 0;
+
+ return 0;
+}
+
+int hws_vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *input)
+{
+ struct hws_video *vid = video_drvdata(file);
+
+ if (input->index)
+ return -EINVAL;
+ input->type = V4L2_INPUT_TYPE_CAMERA;
+ strscpy(input->name, KBUILD_MODNAME, sizeof(input->name));
+ input->capabilities = V4L2_IN_CAP_DV_TIMINGS;
+ input->status = hws_input_status(vid);
+
+ return 0;
+}
+
+int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *index)
+{
+ *index = 0;
+ return 0;
+}
+
+int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.h b/drivers/media/pci/hws/hws_v4l2_ioctl.h
new file mode 100644
index 000000000000..53044f78d6fa
--- /dev/null
+++ b/drivers/media/pci/hws/hws_v4l2_ioctl.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_V4L2_IOCTL_H
+#define HWS_V4L2_IOCTL_H
+
+#include <media/v4l2-ctrls.h>
+#include <linux/fs.h>
+
+extern const struct v4l2_ctrl_ops hws_ctrl_ops;
+
+int hws_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap);
+int hws_vidioc_enum_fmt_vid_cap(struct file *file, void *priv_fh, struct v4l2_fmtdesc *f);
+int hws_vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt);
+int hws_vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f);
+int hws_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms);
+int hws_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms);
+int hws_vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *setfps);
+int hws_vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i);
+int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *i);
+int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i);
+int hws_vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *a);
+int hws_vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a);
+int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
+ struct v4l2_dv_timings_cap *cap);
+int hws_vidioc_s_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+
+int hws_vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a);
+int hws_vidioc_g_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
+ struct v4l2_enum_dv_timings *edv);
+int hws_vidioc_query_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings);
+int hws_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
+
+#endif
diff --git a/drivers/media/pci/hws/hws_video.c b/drivers/media/pci/hws/hws_video.c
new file mode 100644
index 000000000000..9c81af6e7d7f
--- /dev/null
+++ b/drivers/media/pci/hws/hws_video.c
@@ -0,0 +1,1506 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/overflow.h>
+#include <linux/delay.h>
+#include <linux/bits.h>
+#include <linux/jiffies.h>
+#include <linux/ktime.h>
+#include <linux/math64.h>
+#include <linux/interrupt.h>
+#include <linux/moduleparam.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "hws.h"
+#include "hws_reg.h"
+#include "hws_video.h"
+#include "hws_irq.h"
+#include "hws_v4l2_ioctl.h"
+
+#define HWS_REMAP_SLOT_OFF(ch) (0x208 + (ch) * 8) /* one 64-bit slot per ch */
+#define HWS_BUF_BASE_OFF(ch) (CVBS_IN_BUF_BASE + (ch) * PCIE_BARADDROFSIZE)
+#define HWS_HALF_SZ_OFF(ch) (CVBS_IN_BUF_BASE2 + (ch) * PCIE_BARADDROFSIZE)
+
+static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool interlace);
+static bool hws_read_active_state(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool *interlace);
+static void handle_hwv2_path(struct hws_pcie_dev *hws, unsigned int ch);
+static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch);
+static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
+ bool interlaced);
+
+/* DMA helper functions */
+static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma);
+static struct hwsvideo_buffer *
+hws_take_queued_buffer_locked(struct hws_video *vid);
+
+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 == LIST_POISON1 || n->prev == LIST_POISON2;
+}
+
+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=0x%llx tag=%s\n", ch,
+ (u64)dma, tag ? tag : "");
+}
+
+static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma)
+{
+ const u32 addr_mask = PCI_E_BAR_ADD_MASK; // 0xE0000000
+ const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK; // 0x1FFFFFFF
+ struct hws_pcie_dev *hws = vid->parent;
+ unsigned int ch = vid->channel_index;
+ u32 table_off = HWS_REMAP_SLOT_OFF(ch);
+ u32 lo = lower_32_bits(dma);
+ u32 hi = upper_32_bits(dma);
+ u32 pci_addr = lo & addr_low_mask; // low 29 bits inside 512MB window
+ u32 page_lo = lo & addr_mask; // bits 31..29 only (page bits)
+
+ bool wrote = false;
+
+ /* Remap entry only when DMA crosses into a new 512 MB page */
+ if (!vid->window_valid || vid->last_dma_hi != hi ||
+ vid->last_dma_page != page_lo) {
+ writel(hi, hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
+ writel(page_lo,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
+ PCIE_BARADDROFSIZE);
+ vid->last_dma_hi = hi;
+ vid->last_dma_page = page_lo;
+ wrote = true;
+ }
+
+ /* Base pointer only needs low 29 bits */
+ if (!vid->window_valid || vid->last_pci_addr != pci_addr) {
+ writel((ch + 1) * PCIEBAR_AXI_BASE + pci_addr,
+ hws->bar0_base + HWS_BUF_BASE_OFF(ch));
+ vid->last_pci_addr = pci_addr;
+ wrote = true;
+ }
+
+ /* Half-size only changes when resolution changes */
+ if (!vid->window_valid || vid->last_half16 != vid->pix.half_size / 16) {
+ writel(vid->pix.half_size / 16,
+ hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+ vid->last_half16 = vid->pix.half_size / 16;
+ wrote = true;
+ }
+
+ vid->window_valid = true;
+
+ if (dma_window_verify && wrote) {
+ u32 r_hi =
+ readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off);
+ u32 r_lo =
+ readl(hws->bar0_base + PCI_ADDR_TABLE_BASE + table_off +
+ PCIE_BARADDROFSIZE);
+ u32 r_base = readl(hws->bar0_base + HWS_BUF_BASE_OFF(ch));
+ u32 r_half = readl(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+
+ dev_dbg(&hws->pdev->dev,
+ "ch%u remap verify: hi=0x%08x page_lo=0x%08x exp_page=0x%08x base=0x%08x exp_base=0x%08x half16B=0x%08x exp_half=0x%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) {
+ /* Flush posted writes before arming DMA */
+ readl_relaxed(hws->bar0_base + HWS_HALF_SZ_OFF(ch));
+ }
+}
+
+static struct hwsvideo_buffer *
+hws_take_queued_buffer_locked(struct hws_video *vid)
+{
+ struct hwsvideo_buffer *buf;
+
+ if (!vid || list_empty(&vid->capture_queue))
+ return NULL;
+
+ buf = list_first_entry(&vid->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&buf->list);
+ if (vid->queued_count)
+ vid->queued_count--;
+ return buf;
+}
+
+void hws_prime_next_locked(struct hws_video *vid)
+{
+ struct hws_pcie_dev *hws;
+ struct hwsvideo_buffer *next;
+ dma_addr_t dma;
+
+ if (!vid)
+ return;
+
+ hws = vid->parent;
+ if (!hws || !hws->bar0_base)
+ return;
+
+ if (!READ_ONCE(vid->cap_active) || !vid->active || vid->next_prepared)
+ return;
+
+ next = hws_take_queued_buffer_locked(vid);
+ if (!next)
+ return;
+
+ vid->next_prepared = next;
+ dma = vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
+ 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=0x%llx\n",
+ vid->channel_index, next, (u64)dma);
+}
+
+static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag)
+{
+ struct hws_pcie_dev *hws;
+ unsigned long flags;
+ struct hwsvideo_buffer *buf = NULL, *next = NULL;
+ bool have_next = false;
+ bool doorbell = false;
+
+ if (!v)
+ return false;
+ hws = v->parent;
+ if (!hws || READ_ONCE(v->stop_requested) || !READ_ONCE(v->cap_active))
+ return false;
+ spin_lock_irqsave(&v->irq_lock, flags);
+ if (v->active) {
+ buf = v->active;
+ v->active = NULL;
+ buf->slot = 0;
+ } else if (!list_empty(&v->capture_queue)) {
+ buf = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&buf->list);
+ if (v->queued_count)
+ v->queued_count--;
+ buf->slot = 0;
+ }
+ if (v->next_prepared) {
+ next = v->next_prepared;
+ v->next_prepared = NULL;
+ next->slot = 0;
+ v->active = next;
+ have_next = true;
+ } else if (!list_empty(&v->capture_queue)) {
+ next = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&next->list);
+ if (v->queued_count)
+ v->queued_count--;
+ next->slot = 0;
+ v->active = next;
+ have_next = true;
+ } else {
+ v->active = NULL;
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+ if (!buf)
+ return false;
+ /* Complete buffer with a neutral frame so dequeuers keep running. */
+ {
+ struct vb2_v4l2_buffer *vb2v = &buf->vb;
+ void *dst = vb2_plane_vaddr(&vb2v->vb2_buf, 0);
+
+ if (dst)
+ memset(dst, 0x10, v->pix.sizeimage);
+ vb2_set_plane_payload(&vb2v->vb2_buf, 0, v->pix.sizeimage);
+ vb2v->sequence = (u32)atomic_inc_return(&v->sequence_number);
+ vb2v->vb2_buf.timestamp = ktime_get_ns();
+ vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+ if (have_next && next) {
+ dma_addr_t dma =
+ vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(hws, v->channel_index, dma);
+ hws_set_dma_doorbell(hws, v->channel_index, dma,
+ tag ? tag : "nosignal_zero");
+ doorbell = true;
+ }
+ if (doorbell) {
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, v->channel_index, true);
+ }
+ return true;
+}
+
+static int hws_ctrls_init(struct hws_video *vid)
+{
+ struct v4l2_ctrl_handler *hdl = &vid->control_handler;
+
+ /* Create BCHS controls. */
+ v4l2_ctrl_handler_init(hdl, 4);
+
+ vid->ctrl_brightness = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
+ V4L2_CID_BRIGHTNESS,
+ MIN_VAMP_BRIGHTNESS_UNITS,
+ MAX_VAMP_BRIGHTNESS_UNITS, 1,
+ HWS_BRIGHTNESS_DEFAULT);
+
+ vid->ctrl_contrast =
+ v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_CONTRAST,
+ MIN_VAMP_CONTRAST_UNITS, MAX_VAMP_CONTRAST_UNITS,
+ 1, HWS_CONTRAST_DEFAULT);
+
+ vid->ctrl_saturation = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops,
+ V4L2_CID_SATURATION,
+ MIN_VAMP_SATURATION_UNITS,
+ MAX_VAMP_SATURATION_UNITS, 1,
+ HWS_SATURATION_DEFAULT);
+
+ vid->ctrl_hue = v4l2_ctrl_new_std(hdl, &hws_ctrl_ops, V4L2_CID_HUE,
+ MIN_VAMP_HUE_UNITS,
+ MAX_VAMP_HUE_UNITS, 1,
+ HWS_HUE_DEFAULT);
+ if (hdl->error) {
+ int err = hdl->error;
+
+ v4l2_ctrl_handler_free(hdl);
+ return err;
+ }
+ return 0;
+}
+
+int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch)
+{
+ struct hws_video *vid;
+
+ /* basic sanity */
+ if (!pdev || ch < 0 || ch >= pdev->max_channels)
+ return -EINVAL;
+
+ vid = &pdev->video[ch];
+
+ /* hard reset the per-channel struct (safe here since we init everything next) */
+ memset(vid, 0, sizeof(*vid));
+
+ /* identity */
+ vid->parent = pdev;
+ vid->channel_index = ch;
+
+ /* locks & lists */
+ mutex_init(&vid->state_lock);
+ spin_lock_init(&vid->irq_lock);
+ INIT_LIST_HEAD(&vid->capture_queue);
+ atomic_set(&vid->sequence_number, 0);
+ vid->active = NULL;
+
+ /* DMA watchdog removed; retain counters for diagnostics */
+ vid->timeout_count = 0;
+ vid->error_count = 0;
+
+ vid->queued_count = 0;
+ vid->window_valid = false;
+
+ /* default format (adjust to your HW) */
+ vid->pix.width = 1920;
+ vid->pix.height = 1080;
+ vid->pix.fourcc = V4L2_PIX_FMT_YUYV;
+ vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
+ vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
+ vid->pix.field = V4L2_FIELD_NONE;
+ vid->pix.colorspace = V4L2_COLORSPACE_REC709;
+ vid->pix.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ vid->pix.quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ vid->pix.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+ vid->pix.interlaced = false;
+ vid->pix.half_size = vid->pix.sizeimage / 2;
+ vid->alloc_sizeimage = vid->pix.sizeimage;
+ hws_set_current_dv_timings(vid, vid->pix.width,
+ vid->pix.height, vid->pix.interlaced);
+ vid->current_fps = 60;
+
+ /* color controls default (mid-scale) */
+ vid->current_brightness = 0x80;
+ vid->current_contrast = 0x80;
+ vid->current_saturation = 0x80;
+ vid->current_hue = 0x80;
+
+ /* capture state */
+ vid->cap_active = false;
+ vid->stop_requested = false;
+ vid->last_buf_half_toggle = 0;
+ vid->half_seen = false;
+ vid->signal_loss_cnt = 0;
+
+ /* Create BCHS + DV power-present as modern controls */
+ {
+ int err = hws_ctrls_init(vid);
+
+ if (err) {
+ dev_err(&pdev->pdev->dev,
+ "v4l2 ctrl init failed on ch%d: %d\n", ch, err);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static void hws_video_drain_queue_locked(struct hws_video *vid)
+{
+ /* Return in-flight first */
+ if (vid->active) {
+ vb2_buffer_done(&vid->active->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ vid->active = NULL;
+ }
+
+ /* Then everything queued */
+ while (!list_empty(&vid->capture_queue)) {
+ struct hwsvideo_buffer *b =
+ list_first_entry(&vid->capture_queue,
+ struct hwsvideo_buffer,
+ list);
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+}
+
+static void hws_video_release_registration(struct hws_video *vid)
+{
+ if (vid->buffer_queue.ops) {
+ vb2_queue_release(&vid->buffer_queue);
+ vid->buffer_queue.ops = NULL;
+ }
+
+ if (!vid->video_device)
+ return;
+
+ if (video_is_registered(vid->video_device))
+ vb2_video_unregister_device(vid->video_device);
+ else
+ video_device_release(vid->video_device);
+ vid->video_device = NULL;
+}
+
+static void hws_video_collect_done_locked(struct hws_video *vid,
+ struct list_head *done)
+{
+ struct hwsvideo_buffer *b;
+
+ if (vid->active) {
+ if (!list_node_unlinked(&vid->active->list)) {
+ list_move_tail(&vid->active->list, done);
+ } else {
+ INIT_LIST_HEAD(&vid->active->list);
+ list_add_tail(&vid->active->list, done);
+ }
+ vid->active = NULL;
+ }
+
+ if (vid->next_prepared) {
+ if (!list_node_unlinked(&vid->next_prepared->list)) {
+ list_move_tail(&vid->next_prepared->list, done);
+ } else {
+ INIT_LIST_HEAD(&vid->next_prepared->list);
+ list_add_tail(&vid->next_prepared->list, done);
+ }
+ vid->next_prepared = NULL;
+ }
+
+ while (!list_empty(&vid->capture_queue)) {
+ b = list_first_entry(&vid->capture_queue, struct hwsvideo_buffer,
+ list);
+ list_move_tail(&b->list, done);
+ }
+
+ vid->queued_count = 0;
+}
+
+void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch)
+{
+ struct hws_video *vid;
+ unsigned long flags;
+
+ if (!pdev || ch < 0 || ch >= pdev->max_channels)
+ return;
+
+ vid = &pdev->video[ch];
+
+ /* 1) Stop HW best-effort for this channel */
+ hws_enable_video_capture(vid->parent, vid->channel_index, false);
+
+ /* 2) Flip software state so IRQ/BH will be no-ops if they run */
+ WRITE_ONCE(vid->stop_requested, true);
+ WRITE_ONCE(vid->cap_active, false);
+
+ /* 3) Ensure the IRQ handler finished any in-flight completions */
+ if (vid->parent && vid->parent->irq >= 0)
+ synchronize_irq(vid->parent->irq);
+
+ /* 4) Drain SW capture queue & in-flight under lock */
+ spin_lock_irqsave(&vid->irq_lock, flags);
+ hws_video_drain_queue_locked(vid);
+ spin_unlock_irqrestore(&vid->irq_lock, flags);
+
+ /* 5) Release VB2 queue if initialized */
+ hws_video_release_registration(vid);
+
+ /* 6) Free V4L2 controls */
+ v4l2_ctrl_handler_free(&vid->control_handler);
+
+ /* 8) Reset simple state (don’t memset the whole struct here) */
+ mutex_destroy(&vid->state_lock);
+ INIT_LIST_HEAD(&vid->capture_queue);
+ vid->active = NULL;
+ vid->stop_requested = false;
+ vid->last_buf_half_toggle = 0;
+ vid->half_seen = false;
+ vid->signal_loss_cnt = 0;
+}
+
+/* Convenience cast */
+static inline struct hwsvideo_buffer *to_hwsbuf(struct vb2_buffer *vb)
+{
+ return container_of(to_vb2_v4l2_buffer(vb), struct hwsvideo_buffer, vb);
+}
+
+static int hws_buf_init(struct vb2_buffer *vb)
+{
+ struct hwsvideo_buffer *b = to_hwsbuf(vb);
+
+ INIT_LIST_HEAD(&b->list);
+ return 0;
+}
+
+static void hws_buf_finish(struct vb2_buffer *vb)
+{
+ /* vb2 core handles cache maintenance for dma-contig buffers */
+ (void)vb;
+}
+
+static void hws_buf_cleanup(struct vb2_buffer *vb)
+{
+ struct hwsvideo_buffer *b = to_hwsbuf(vb);
+
+ if (!list_empty(&b->list))
+ list_del_init(&b->list);
+}
+
+void hws_program_dma_for_addr(struct hws_pcie_dev *hws, unsigned int ch,
+ dma_addr_t dma)
+{
+ struct hws_video *vid = &hws->video[ch];
+
+ hws_program_dma_window(vid, dma);
+}
+
+void hws_enable_video_capture(struct hws_pcie_dev *hws, unsigned int chan,
+ bool on)
+{
+ u32 status;
+
+ if (!hws || hws->pci_lost || chan >= hws->max_channels)
+ return;
+
+ status = readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ status = on ? (status | BIT(chan)) : (status & ~BIT(chan));
+ writel(status, hws->bar0_base + HWS_REG_VCAP_ENABLE);
+ (void)readl(hws->bar0_base + HWS_REG_VCAP_ENABLE);
+
+ WRITE_ONCE(hws->video[chan].cap_active, on);
+
+ dev_dbg(&hws->pdev->dev, "vcap %s ch%u (reg=0x%08x)\n",
+ on ? "ON" : "OFF", chan, status);
+}
+
+static void hws_seed_dma_windows(struct hws_pcie_dev *hws)
+{
+ const u32 addr_mask = PCI_E_BAR_ADD_MASK;
+ const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK;
+ u32 table = 0x208; /* one 64-bit entry per channel */
+ unsigned int ch;
+
+ if (!hws || !hws->bar0_base)
+ return;
+
+ /* If cur_max_video_ch isn’t set yet, default to max_channels */
+ if (!hws->cur_max_video_ch || hws->cur_max_video_ch > hws->max_channels)
+ hws->cur_max_video_ch = hws->max_channels;
+
+ for (ch = 0; ch < hws->cur_max_video_ch; ch++, table += 8) {
+ if (!hws->scratch_vid[ch].cpu)
+ continue;
+
+ /* Program 64-bit BAR remap entry for this channel */
+ {
+ dma_addr_t p = hws->scratch_vid[ch].dma;
+ u32 lo = lower_32_bits(p) & addr_mask;
+ u32 hi = upper_32_bits(p);
+ u32 pci_addr_low = lower_32_bits(p) & addr_low_mask;
+
+ writel_relaxed(hi,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE +
+ table);
+ writel_relaxed(lo,
+ hws->bar0_base + PCI_ADDR_TABLE_BASE +
+ table + PCIE_BARADDROFSIZE);
+
+ /* Per-channel AXI base + PCI low */
+ writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE +
+ pci_addr_low,
+ hws->bar0_base + CVBS_IN_BUF_BASE +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* Half-frame length in /16 units.
+ * Prefer the current channel’s computed half_size if available.
+ * Fall back to half of the probe-owned scratch buffer.
+ */
+ {
+ u32 half_bytes = hws->video[ch].pix.half_size ?
+ hws->video[ch].pix.half_size :
+ (u32)(hws->scratch_vid[ch].size / 2);
+ writel_relaxed(half_bytes / 16,
+ hws->bar0_base +
+ CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+ }
+ }
+ }
+
+ /* Post writes so device sees them before we move on */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+}
+
+static void hws_ack_all_irqs(struct hws_pcie_dev *hws)
+{
+ u32 st = readl(hws->bar0_base + HWS_REG_INT_STATUS);
+
+ if (st) {
+ writel(st, hws->bar0_base + HWS_REG_INT_STATUS); /* W1C */
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+}
+
+static void hws_open_irq_fabric(struct hws_pcie_dev *hws)
+{
+ /* Route all sources to vector 0 (same value you’re already using) */
+ writel(0x00000000, hws->bar0_base + PCIE_INT_DEC_REG_BASE);
+ (void)readl(hws->bar0_base + PCIE_INT_DEC_REG_BASE);
+
+ /* Turn on the bridge if your IP needs it */
+ 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);
+}
+
+void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable)
+{
+ int i;
+
+ if (hws->start_run && !enable)
+ return;
+
+ /* 1) reset the decoder mode register to 0 */
+ writel(0x00000000, hws->bar0_base + HWS_REG_DEC_MODE);
+ hws_seed_dma_windows(hws);
+
+ /* 3) on a full reset, clear all per-channel status and indices */
+ if (!enable) {
+ for (i = 0; i < hws->max_channels; i++) {
+ /* helpers to arm/disable capture engines */
+ hws_enable_video_capture(hws, i, false);
+ }
+ }
+
+ /* 4) “Start run”: set bit31, wait a bit, then program low 24 bits */
+ writel(0x80000000, hws->bar0_base + HWS_REG_DEC_MODE);
+ // udelay(500);
+ 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);
+ /* 6) record that we're now running */
+ hws->start_run = true;
+}
+
+int hws_check_card_status(struct hws_pcie_dev *hws)
+{
+ u32 status;
+
+ if (!hws || !hws->bar0_base)
+ return -ENODEV;
+
+ status = readl(hws->bar0_base + HWS_REG_SYS_STATUS);
+
+ /* Common “device missing” pattern */
+ if (status == 0xFFFFFFFF) {
+ hws->pci_lost = true;
+ dev_err(&hws->pdev->dev, "PCIe device not responding\n");
+ return -ENODEV;
+ }
+
+ /* If RUN/READY bit (bit0) isn’t set, (re)initialize 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);
+ /* Optional: verify the core cleared its busy bit, if you have one */
+ /* int ret = hws_check_busy(hws); */
+ /* if (ret) return ret; */
+ }
+
+ return 0;
+}
+
+void check_video_format(struct hws_pcie_dev *pdx)
+{
+ int i;
+
+ for (i = 0; i < pdx->cur_max_video_ch; i++) {
+ bool interlace = false;
+
+ if (!hws_read_active_state(pdx, i, &interlace)) {
+ /* No active video; optionally feed neutral frames to keep streaming. */
+ if (pdx->video[i].signal_loss_cnt == 0)
+ pdx->video[i].signal_loss_cnt = 1;
+ if (READ_ONCE(pdx->video[i].cap_active))
+ hws_force_no_signal_frame(&pdx->video[i],
+ "monitor_nosignal");
+ } else {
+ if (pdx->hw_ver > 0)
+ handle_hwv2_path(pdx, i);
+ else
+ /* Legacy path stub; see handle_legacy_path() comment. */
+ handle_legacy_path(pdx, i);
+
+ update_live_resolution(pdx, i, interlace);
+ pdx->video[i].signal_loss_cnt = 0;
+ }
+ }
+}
+
+static inline void hws_write_if_diff(struct hws_pcie_dev *hws, u32 reg_off,
+ u32 new_val)
+{
+ void __iomem *addr;
+ u32 old;
+
+ if (!hws || !hws->bar0_base)
+ return;
+
+ addr = hws->bar0_base + reg_off;
+
+ old = readl(addr);
+ /* Treat all-ones as device gone; avoid writing garbage. */
+ if (old == 0xFFFFFFFF) {
+ hws->pci_lost = true;
+ return;
+ }
+
+ if (old != new_val) {
+ writel(new_val, addr);
+ /* Post the write on some bridges / enforce ordering. */
+ (void)readl(addr);
+ }
+}
+
+static bool hws_read_active_state(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool *interlace)
+{
+ u32 reg;
+ bool active;
+
+ if (ch >= pdx->cur_max_video_ch)
+ return false;
+
+ reg = readl(pdx->bar0_base + HWS_REG_ACTIVE_STATUS);
+ active = !!(reg & BIT(ch));
+ if (interlace)
+ *interlace = !!(reg & BIT(8 + ch));
+ return active;
+}
+
+/* Modern hardware path: keep HW registers in sync with current per-channel
+ * software state. Adjust the OUT_* bits below to match your HW contract.
+ */
+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;
+
+ if (!hws || !hws->bar0_base || ch >= hws->max_channels)
+ return;
+
+ vid = &hws->video[ch];
+
+ /* 1) Input frame rate (read-only; log or export via debugfs if wanted) */
+ in_fps = readl(hws->bar0_base + HWS_REG_FRAME_RATE(ch));
+ /* dev_dbg(&hws->pdev->dev, "ch%u input fps=%u\n", ch, in_fps); */
+ (void)in_fps;
+
+ /* 2) Output resolution programming
+ * If your HW expects a separate “scaled” size, add fields to track it.
+ * For now, mirror the current format (fmt_curr) to OUT_RES.
+ */
+ want_out_res = (vid->pix.height << 16) | vid->pix.width;
+ cur_out_res = readl(hws->bar0_base + HWS_REG_OUT_RES(ch));
+ if (cur_out_res != want_out_res)
+ hws_write_if_diff(hws, HWS_REG_OUT_RES(ch), want_out_res);
+
+ /* 3) Output FPS: only program if you actually track a target.
+ * Example heuristic (disabled by default):
+ *
+ * u32 out_fps = (vid->fmt_curr.height >= 1080) ? 60 : 30;
+ * hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), out_fps);
+ */
+
+ /* 4) BCHS controls: pack from per-channel current_* fields */
+ reg = readl(hws->bar0_base + HWS_REG_BCHS(ch));
+ {
+ u8 br = reg & 0xFF;
+ u8 co = (reg >> 8) & 0xFF;
+ u8 hu = (reg >> 16) & 0xFF;
+ u8 sa = (reg >> 24) & 0xFF;
+
+ if (br != vid->current_brightness ||
+ co != vid->current_contrast || hu != vid->current_hue ||
+ sa != vid->current_saturation) {
+ u32 packed = (vid->current_saturation << 24) |
+ (vid->current_hue << 16) |
+ (vid->current_contrast << 8) |
+ vid->current_brightness;
+ hws_write_if_diff(hws, HWS_REG_BCHS(ch), packed);
+ }
+ }
+
+ /* 5) HDCP detect: read only (no cache field in your structs today) */
+ reg = readl(hws->bar0_base + HWS_REG_HDCP_STATUS);
+ /* bool hdcp = !!(reg & BIT(ch)); // use if you later add a field/control */
+}
+
+static void handle_legacy_path(struct hws_pcie_dev *hws, unsigned int ch)
+{
+ /*
+ * Legacy (hw_ver == 0) expected behavior:
+ * - A per-channel SW FPS accumulator incremented on each VDONE.
+ * - A once-per-second poll mapped the count to discrete FPS:
+ * >55*2 => 60, >45*2 => 50, >25*2 => 30, >20*2 => 25, else 60,
+ * then reset the accumulator to 0.
+ * - The *2 factor assumed VDONE fired per-field; if legacy VDONE is
+ * per-frame, drop the factor.
+ *
+ * Current code keeps this path as a no-op; vid->current_fps stays at the
+ * default or mode-derived value. If accurate legacy FPS reporting is
+ * needed (V4L2 g_parm/timeperframe), reintroduce the accumulator in the
+ * IRQ path and perform the mapping/reset here.
+ *
+ * No-op by default. If you introduce a SW FPS accumulator, map it here.
+ *
+ * Example skeleton:
+ *
+ * u32 sw_rate = READ_ONCE(hws->sw_fps[ch]); // incremented elsewhere
+ * if (sw_rate > THRESHOLD) {
+ * u32 fps = pick_fps_from_rate(sw_rate);
+ * hws_write_if_diff(hws, HWS_REG_OUT_FRAME_RATE(ch), fps);
+ * WRITE_ONCE(hws->sw_fps[ch], 0);
+ * }
+ */
+ (void)hws;
+ (void)ch;
+}
+
+static void hws_video_apply_mode_change(struct hws_pcie_dev *pdx,
+ unsigned int ch, u16 w, u16 h,
+ bool interlaced, u32 fps)
+{
+ struct hws_video *v = &pdx->video[ch];
+ unsigned long flags;
+ u32 new_size;
+ bool queue_busy;
+ bool geometry_changed;
+ struct list_head done;
+ struct hwsvideo_buffer *b, *tmp;
+
+ if (!pdx || !pdx->bar0_base)
+ return;
+ if (ch >= pdx->max_channels)
+ return;
+ if (!w || !h || w > MAX_VIDEO_HW_W ||
+ (!interlaced && h > MAX_VIDEO_HW_H) ||
+ (interlaced && (h * 2) > MAX_VIDEO_HW_H))
+ return;
+ if (!fps || fps == 0xFFFFFFFF || fps > 240)
+ fps = (h == 576) ? 50 : 60;
+
+ geometry_changed = w != v->pix.width || h != v->pix.height ||
+ interlaced != v->pix.interlaced;
+ if (!geometry_changed && fps == v->current_fps)
+ return;
+
+ if (!geometry_changed) {
+ /* Refresh cached live timing state, but don't emit a resolution
+ * change event when only the frame rate changes.
+ */
+ mutex_lock(&v->state_lock);
+ v->pix.interlaced = interlaced;
+ v->pix.field = interlaced ? V4L2_FIELD_INTERLACED :
+ V4L2_FIELD_NONE;
+ hws_set_current_dv_timings(v, w, h, interlaced);
+ v->current_fps = fps;
+ mutex_unlock(&v->state_lock);
+ return;
+ }
+
+ if (!mutex_trylock(&v->state_lock))
+ return;
+
+ INIT_LIST_HEAD(&done);
+ queue_busy = vb2_is_busy(&v->buffer_queue);
+
+ WRITE_ONCE(v->stop_requested, true);
+ WRITE_ONCE(v->cap_active, false);
+ /* Publish software stop first so the IRQ completion path sees the stop
+ * before we touch MMIO or the lists. Pairs with READ_ONCE() checks in the
+ * VDONE handler and hws_arm_next() to prevent completions while modes
+ * change.
+ */
+ smp_wmb();
+
+ hws_enable_video_capture(pdx, ch, false);
+ readl(pdx->bar0_base + HWS_REG_INT_STATUS);
+
+ if (v->parent && v->parent->irq >= 0)
+ synchronize_irq(v->parent->irq);
+
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_video_collect_done_locked(v, &done);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* Update software pixel state */
+ v->pix.width = w;
+ v->pix.height = h;
+ v->pix.interlaced = interlaced;
+ hws_set_current_dv_timings(v, w, h, interlaced);
+ v->current_fps = fps;
+
+ new_size = hws_calc_sizeimage(v, w, h, interlaced);
+ v->window_valid = false;
+
+ /* Geometry changes require userspace renegotiation once buffers exist.
+ * Emit SOURCE_CHANGE, mark the queue in error, and let userspace
+ * STREAMOFF/REQBUFS/STREAMON rather than trying to restart capture
+ * with partially drained in-flight state.
+ */
+ if (queue_busy) {
+ struct v4l2_event ev = {
+ .type = V4L2_EVENT_SOURCE_CHANGE,
+ };
+
+ ev.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
+ v4l2_event_queue(v->video_device, &ev);
+ vb2_queue_error(&v->buffer_queue);
+ } else {
+ v->alloc_sizeimage = PAGE_ALIGN(new_size);
+ WRITE_ONCE(v->stop_requested, false);
+ }
+
+ /* Program HW with new resolution */
+ hws_write_if_diff(pdx, HWS_REG_OUT_RES(ch), (h << 16) | w);
+
+ /* Legacy half-buffer programming */
+ writel(v->pix.half_size / 16,
+ pdx->bar0_base + CVBS_IN_BUF_BASE2 + ch * PCIE_BARADDROFSIZE);
+ (void)readl(pdx->bar0_base + CVBS_IN_BUF_BASE2 +
+ ch * PCIE_BARADDROFSIZE);
+
+ /* Reset per-channel toggles/counters */
+ WRITE_ONCE(v->last_buf_half_toggle, 0);
+ atomic_set(&v->sequence_number, 0);
+
+ mutex_unlock(&v->state_lock);
+
+ list_for_each_entry_safe(b, tmp, &done, list) {
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+}
+
+static void update_live_resolution(struct hws_pcie_dev *pdx, unsigned int ch,
+ bool interlace)
+{
+ u32 reg = readl(pdx->bar0_base + HWS_REG_IN_RES(ch));
+ u32 fps = readl(pdx->bar0_base + HWS_REG_FRAME_RATE(ch));
+ u16 res_w = reg & 0xFFFF;
+ u16 res_h = (reg >> 16) & 0xFFFF;
+ struct hws_video *vid = &pdx->video[ch];
+ bool geometry_changed;
+ bool fps_changed;
+
+ bool within_hw = (res_w <= MAX_VIDEO_HW_W) &&
+ ((!interlace && res_h <= MAX_VIDEO_HW_H) ||
+ (interlace && (res_h * 2) <= MAX_VIDEO_HW_H));
+
+ if (!within_hw)
+ return;
+
+ geometry_changed = res_w != vid->pix.width ||
+ res_h != vid->pix.height ||
+ interlace != vid->pix.interlaced;
+ fps_changed = fps && fps != 0xFFFFFFFF && fps <= 240 &&
+ fps != vid->current_fps;
+
+ if (geometry_changed || fps_changed)
+ hws_video_apply_mode_change(pdx, ch, res_w, res_h, interlace,
+ fps);
+}
+
+static int hws_open(struct file *file)
+{
+ return v4l2_fh_open(file);
+}
+
+static const struct v4l2_file_operations hws_fops = {
+ .owner = THIS_MODULE,
+ .open = hws_open,
+ .release = vb2_fop_release,
+ .poll = vb2_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = vb2_fop_mmap,
+};
+
+static int hws_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_src_change_event_subscribe(fh, sub);
+ case V4L2_EVENT_CTRL:
+ return v4l2_ctrl_subscribe_event(fh, sub);
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_ioctl_ops hws_ioctl_fops = {
+ /* Core caps/info */
+ .vidioc_querycap = hws_vidioc_querycap,
+
+ /* Pixel format: still needed to report YUYV etc. */
+ .vidioc_enum_fmt_vid_cap = hws_vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = hws_vidioc_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = hws_vidioc_s_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = hws_vidioc_try_fmt_vid_cap,
+
+ /* Buffer queueing / streaming */
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+
+ /* Inputs */
+ .vidioc_enum_input = hws_vidioc_enum_input,
+ .vidioc_g_input = hws_vidioc_g_input,
+ .vidioc_s_input = hws_vidioc_s_input,
+
+ /* DV timings (HDMI/DVI/VESA modes) */
+ .vidioc_query_dv_timings = hws_vidioc_query_dv_timings,
+ .vidioc_enum_dv_timings = hws_vidioc_enum_dv_timings,
+ .vidioc_g_dv_timings = hws_vidioc_g_dv_timings,
+ .vidioc_s_dv_timings = hws_vidioc_s_dv_timings,
+ .vidioc_dv_timings_cap = hws_vidioc_dv_timings_cap,
+
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = hws_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_g_parm = hws_vidioc_g_parm,
+};
+
+static u32 hws_calc_sizeimage(struct hws_video *v, u16 w, u16 h,
+ bool interlaced)
+{
+ /* example for packed 16bpp (YUYV); replace with your real math/align */
+ u32 lines = h; /* full frame lines for sizeimage */
+ u32 bytesperline = ALIGN(w * 2, 64);
+ u32 sizeimage, half0;
+
+ /* publish into pix, since we now carry these in-state */
+ v->pix.bytesperline = bytesperline;
+ sizeimage = bytesperline * lines;
+
+ half0 = sizeimage / 2;
+
+ v->pix.sizeimage = sizeimage;
+ v->pix.half_size = half0; /* first half; second = sizeimage - half0 */
+ v->pix.field = interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
+
+ return v->pix.sizeimage;
+}
+
+static int hws_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
+ unsigned int *nplanes, unsigned int sizes[],
+ struct device *alloc_devs[])
+{
+ struct hws_video *vid = q->drv_priv;
+
+ (void)num_buffers;
+ (void)alloc_devs;
+
+ if (!vid->pix.sizeimage) {
+ vid->pix.bytesperline = ALIGN(vid->pix.width * 2, 64);
+ vid->pix.sizeimage = vid->pix.bytesperline * vid->pix.height;
+ }
+ if (*nplanes) {
+ if (sizes[0] < vid->pix.sizeimage)
+ return -EINVAL;
+ } else {
+ *nplanes = 1;
+ sizes[0] = PAGE_ALIGN(vid->pix.sizeimage);
+ }
+
+ vid->alloc_sizeimage = PAGE_ALIGN(vid->pix.sizeimage);
+ return 0;
+}
+
+static int hws_buffer_prepare(struct vb2_buffer *vb)
+{
+ struct hws_video *vid = vb->vb2_queue->drv_priv;
+ struct hws_pcie_dev *hws = vid->parent;
+ size_t need = vid->pix.sizeimage;
+ dma_addr_t dma_addr;
+
+ if (vb2_plane_size(vb, 0) < need)
+ return -EINVAL;
+
+ /* Validate DMA address alignment */
+ dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ if (dma_addr & 0x3F) { /* 64-byte alignment required */
+ dev_err(&hws->pdev->dev,
+ "Buffer DMA address 0x%llx not 64-byte aligned\n",
+ (unsigned long long)dma_addr);
+ return -EINVAL;
+ }
+
+ vb2_set_plane_payload(vb, 0, need);
+ return 0;
+}
+
+static void hws_buffer_queue(struct vb2_buffer *vb)
+{
+ struct hws_video *vid = vb->vb2_queue->drv_priv;
+ struct hwsvideo_buffer *buf = to_hwsbuf(vb);
+ struct hws_pcie_dev *hws = vid->parent;
+ unsigned long flags;
+
+ dev_dbg(&hws->pdev->dev,
+ "buffer_queue(ch=%u): vb=%p sizeimage=%u q_active=%d\n",
+ vid->channel_index, vb, vid->pix.sizeimage,
+ READ_ONCE(vid->cap_active));
+
+ /* Initialize buffer slot */
+ buf->slot = 0;
+
+ spin_lock_irqsave(&vid->irq_lock, flags);
+ list_add_tail(&buf->list, &vid->capture_queue);
+ vid->queued_count++;
+
+ /* If streaming and no in-flight buffer, prime HW immediately */
+ if (READ_ONCE(vid->cap_active) && !vid->active) {
+ dma_addr_t dma_addr;
+
+ dev_dbg(&hws->pdev->dev,
+ "buffer_queue(ch=%u): priming first vb=%p\n",
+ vid->channel_index, &buf->vb.vb2_buf);
+ list_del_init(&buf->list);
+ vid->queued_count--;
+ vid->active = buf;
+
+ dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+ hws_program_dma_for_addr(vid->parent, vid->channel_index,
+ dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base + HWS_REG_DMA_ADDR(vid->channel_index));
+
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, vid->channel_index, true);
+ hws_prime_next_locked(vid);
+ } else if (READ_ONCE(vid->cap_active) && vid->active) {
+ hws_prime_next_locked(vid);
+ }
+ spin_unlock_irqrestore(&vid->irq_lock, flags);
+}
+
+static int hws_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct hws_video *v = q->drv_priv;
+ struct hws_pcie_dev *hws = v->parent;
+ struct hwsvideo_buffer *to_program = NULL; /* local copy */
+ struct vb2_buffer *prog_vb2 = NULL;
+ unsigned long flags;
+ int ret;
+
+ dev_dbg(&hws->pdev->dev, "start_streaming: ch=%u count=%u\n",
+ v->channel_index, count);
+
+ ret = hws_check_card_status(hws);
+ if (ret) {
+ struct hwsvideo_buffer *b, *tmp;
+ unsigned long f;
+ LIST_HEAD(queued);
+
+ spin_lock_irqsave(&v->irq_lock, f);
+ if (v->active) {
+ list_add_tail(&v->active->list, &queued);
+ v->active = NULL;
+ }
+ if (v->next_prepared) {
+ list_add_tail(&v->next_prepared->list, &queued);
+ v->next_prepared = NULL;
+ }
+ while (!list_empty(&v->capture_queue)) {
+ b = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_move_tail(&b->list, &queued);
+ }
+ spin_unlock_irqrestore(&v->irq_lock, f);
+
+ list_for_each_entry_safe(b, tmp, &queued, list) {
+ list_del_init(&b->list);
+ vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+ }
+ return ret;
+ }
+ (void)hws_read_active_state(hws, v->channel_index,
+ &v->pix.interlaced);
+
+ lockdep_assert_held(&v->state_lock);
+ /* init per-stream state */
+ WRITE_ONCE(v->stop_requested, false);
+ WRITE_ONCE(v->cap_active, true);
+ WRITE_ONCE(v->half_seen, false);
+ WRITE_ONCE(v->last_buf_half_toggle, 0);
+
+ /* Try to prime a buffer, but it's OK if none are queued yet */
+ spin_lock_irqsave(&v->irq_lock, flags);
+ if (!v->active && !list_empty(&v->capture_queue)) {
+ to_program = list_first_entry(&v->capture_queue,
+ struct hwsvideo_buffer, list);
+ list_del_init(&to_program->list);
+ v->queued_count--;
+ v->active = to_program;
+ prog_vb2 = &to_program->vb.vb2_buf;
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u took buffer %p\n",
+ v->channel_index, to_program);
+ }
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* Only program/enable HW if we actually have a buffer */
+ if (to_program) {
+ if (!prog_vb2)
+ prog_vb2 = &to_program->vb.vb2_buf;
+ {
+ dma_addr_t dma_addr;
+
+ dma_addr = vb2_dma_contig_plane_dma_addr(prog_vb2, 0);
+ hws_program_dma_for_addr(hws, v->channel_index, dma_addr);
+ iowrite32(lower_32_bits(dma_addr),
+ hws->bar0_base +
+ HWS_REG_DMA_ADDR(v->channel_index));
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u programmed buffer %p dma=0x%08x\n",
+ v->channel_index, to_program,
+ lower_32_bits(dma_addr));
+ (void)readl(hws->bar0_base + HWS_REG_INT_STATUS);
+ }
+
+ wmb(); /* ensure descriptors visible before enabling capture */
+ hws_enable_video_capture(hws, v->channel_index, true);
+ {
+ unsigned long pf;
+
+ spin_lock_irqsave(&v->irq_lock, pf);
+ hws_prime_next_locked(v);
+ spin_unlock_irqrestore(&v->irq_lock, pf);
+ }
+ } else {
+ dev_dbg(&hws->pdev->dev,
+ "start_streaming: ch=%u no buffer yet (will arm on QBUF)\n",
+ v->channel_index);
+ }
+
+ return 0;
+}
+
+static void hws_log_video_state(struct hws_video *v, const char *action,
+ const char *phase)
+{
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned long flags;
+ unsigned int queued = 0;
+ unsigned int tracked = 0;
+ unsigned int seq = 0;
+ struct hwsvideo_buffer *b;
+ bool streaming = 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 = READ_ONCE(v->cap_active);
+ stop_requested = READ_ONCE(v->stop_requested);
+ active = v->active;
+ next_prepared = v->next_prepared;
+ tracked = v->queued_count;
+ seq = (u32)atomic_read(&v->sequence_number);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:%s ch=%u streaming=%d cap=%d stop=%d active=%p next=%p queued=%u tracked=%u seq=%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 = q->drv_priv;
+ struct hws_pcie_dev *hws = v->parent;
+ unsigned long flags;
+ struct hwsvideo_buffer *b, *tmp;
+ LIST_HEAD(done);
+ unsigned int done_cnt = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ hws_log_video_state(v, "streamoff", "begin");
+
+ /* 1) Quiesce SW/HW first */
+ lockdep_assert_held(&v->state_lock);
+ WRITE_ONCE(v->cap_active, false);
+ WRITE_ONCE(v->stop_requested, true);
+
+ hws_enable_video_capture(v->parent, v->channel_index, false);
+
+ /* 2) Collect in-flight + queued under the IRQ lock */
+ spin_lock_irqsave(&v->irq_lock, flags);
+ hws_video_collect_done_locked(v, &done);
+ spin_unlock_irqrestore(&v->irq_lock, flags);
+
+ /* 3) Complete outside the lock */
+ list_for_each_entry_safe(b, tmp, &done, list) {
+ /* 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=%u completed=%u (%lluus)\n",
+ v->channel_index, done_cnt, hws_elapsed_us(start_ns));
+ hws_log_video_state(v, "streamoff", "end");
+}
+
+static const struct vb2_ops hwspcie_video_qops = {
+ .queue_setup = hws_queue_setup,
+ .buf_prepare = hws_buffer_prepare,
+ .buf_init = hws_buf_init,
+ .buf_finish = hws_buf_finish,
+ .buf_cleanup = hws_buf_cleanup,
+ .buf_queue = hws_buffer_queue,
+ .start_streaming = hws_start_streaming,
+ .stop_streaming = hws_stop_streaming,
+};
+
+int hws_video_register(struct hws_pcie_dev *dev)
+{
+ int i, ret;
+
+ ret = v4l2_device_register(&dev->pdev->dev, &dev->v4l2_device);
+ if (ret) {
+ dev_err(&dev->pdev->dev, "v4l2_device_register failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ for (i = 0; i < dev->cur_max_video_ch; i++) {
+ struct hws_video *ch = &dev->video[i];
+ struct video_device *vdev;
+ struct vb2_queue *q;
+
+ /* hws_video_init_channel() should have set:
+ * - ch->parent, ch->channel_index
+ * - locks (state_lock, irq_lock)
+ * - capture_queue (INIT_LIST_HEAD)
+ * - control_handler + controls
+ * - fmt_curr (width/height)
+ * Don’t reinitialize any of those here.
+ */
+
+ vdev = video_device_alloc();
+ if (!vdev) {
+ dev_err(&dev->pdev->dev,
+ "video_device_alloc ch%u failed\n", i);
+ ret = -ENOMEM;
+ goto err_unwind;
+ }
+ ch->video_device = vdev;
+
+ /* Basic V4L2 node setup */
+ snprintf(vdev->name, sizeof(vdev->name), "%s-hdmi%u",
+ KBUILD_MODNAME, i);
+ vdev->v4l2_dev = &dev->v4l2_device;
+ vdev->fops = &hws_fops; /* your file_ops */
+ vdev->ioctl_ops = &hws_ioctl_fops; /* your ioctl_ops */
+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ vdev->lock = &ch->state_lock; /* serialize file ops */
+ vdev->ctrl_handler = &ch->control_handler;
+ vdev->vfl_dir = VFL_DIR_RX;
+ vdev->release = video_device_release;
+ if (ch->control_handler.error) {
+ ret = ch->control_handler.error;
+ goto err_unwind;
+ }
+ video_set_drvdata(vdev, ch);
+
+ /* vb2 queue init (dma-contig) */
+ q = &ch->buffer_queue;
+ memset(q, 0, sizeof(*q));
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_DMABUF;
+ q->drv_priv = ch;
+ q->buf_struct_size = sizeof(struct hwsvideo_buffer);
+ q->ops = &hwspcie_video_qops; /* your vb2_ops */
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &ch->state_lock;
+ q->min_queued_buffers = 1;
+ q->dev = &dev->pdev->dev;
+
+ ret = vb2_queue_init(q);
+ vdev->queue = q;
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "vb2_queue_init ch%u failed: %d\n", i, ret);
+ goto err_unwind;
+ }
+
+ /* Make controls live (no-op if none or already set up) */
+ if (ch->control_handler.error) {
+ ret = ch->control_handler.error;
+ dev_err(&dev->pdev->dev,
+ "ctrl handler ch%u error: %d\n", i, ret);
+ goto err_unwind;
+ }
+ v4l2_ctrl_handler_setup(&ch->control_handler);
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "video_register_device ch%u failed: %d\n", i,
+ ret);
+ goto err_unwind;
+ }
+ }
+
+ return 0;
+
+err_unwind:
+ for (; i >= 0; i--) {
+ struct hws_video *ch = &dev->video[i];
+
+ hws_video_release_registration(ch);
+ }
+ v4l2_device_unregister(&dev->v4l2_device);
+ return ret;
+}
+
+void hws_video_unregister(struct hws_pcie_dev *dev)
+{
+ int i;
+
+ if (!dev)
+ return;
+
+ for (i = 0; i < dev->cur_max_video_ch; i++) {
+ struct hws_video *ch = &dev->video[i];
+
+ hws_video_release_registration(ch);
+ v4l2_ctrl_handler_free(&ch->control_handler);
+ }
+ v4l2_device_unregister(&dev->v4l2_device);
+}
+
+int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason)
+{
+ int i, ret = 0;
+ u64 start_ns = ktime_get_mono_fast_ns();
+
+ dev_dbg(&hws->pdev->dev, "video:%s:begin channels=%u\n", reason,
+ hws->cur_max_video_ch);
+ for (i = 0; i < hws->cur_max_video_ch; i++) {
+ struct hws_video *vid = &hws->video[i];
+ struct vb2_queue *q = &vid->buffer_queue;
+ u64 ch_start_ns = ktime_get_mono_fast_ns();
+ bool streaming;
+
+ if (!q || !q->ops) {
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d skipped queue-unavailable\n",
+ reason, i);
+ continue;
+ }
+
+ streaming = vb2_is_streaming(q);
+ hws_log_video_state(vid, reason, "channel");
+ if (streaming) {
+ /* Stop via vb2 (runs your .stop_streaming) */
+ int r = vb2_streamoff(q, q->type);
+
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d streamoff ret=%d (%lluus)\n",
+ reason, i, r, hws_elapsed_us(ch_start_ns));
+ if (r && !ret)
+ ret = r;
+ } else {
+ dev_dbg(&hws->pdev->dev,
+ "video:%s:ch=%d idle (%lluus)\n",
+ reason, i, hws_elapsed_us(ch_start_ns));
+ }
+ }
+ dev_dbg(&hws->pdev->dev, "video:%s:done ret=%d (%lluus)\n", reason,
+ ret, hws_elapsed_us(start_ns));
+ return ret;
+}
+
+void hws_video_pm_resume(struct hws_pcie_dev *hws)
+{
+ /* Nothing mandatory to do here for vb2 — userspace will STREAMON again.
+ * If you track per-channel 'auto-restart' policy, re-arm it here.
+ */
+}
diff --git a/drivers/media/pci/hws/hws_video.h b/drivers/media/pci/hws/hws_video.h
new file mode 100644
index 000000000000..d02cfb2cdeb3
--- /dev/null
+++ b/drivers/media/pci/hws/hws_video.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef HWS_VIDEO_H
+#define HWS_VIDEO_H
+
+struct hws_video;
+
+int hws_video_register(struct hws_pcie_dev *dev);
+void hws_video_unregister(struct hws_pcie_dev *dev);
+void hws_enable_video_capture(struct hws_pcie_dev *hws,
+ unsigned int chan,
+ bool on);
+void hws_prime_next_locked(struct hws_video *vid);
+
+int hws_video_init_channel(struct hws_pcie_dev *pdev, int ch);
+void hws_video_cleanup_channel(struct hws_pcie_dev *pdev, int ch);
+void check_video_format(struct hws_pcie_dev *pdx);
+int hws_check_card_status(struct hws_pcie_dev *hws);
+void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable);
+
+void hws_program_dma_for_addr(struct hws_pcie_dev *hws,
+ unsigned int ch,
+ dma_addr_t dma);
+void hws_set_dma_doorbell(struct hws_pcie_dev *hws, unsigned int ch,
+ dma_addr_t dma, const char *tag);
+
+int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason);
+void hws_video_pm_resume(struct hws_pcie_dev *hws);
+
+#endif // HWS_VIDEO_H
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-04-03 13:57 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260112022420.390854-1-hoff.benjamin.k@gmail.com>
2026-03-18 0:10 ` [PATCH v2 0/2] media: pci: add AVMatrix HWS capture driver Ben Hoff
2026-03-18 0:10 ` [PATCH v2 1/2] " Ben Hoff
2026-03-24 9:17 ` Hans Verkuil
2026-03-18 0:10 ` [PATCH v2 2/2] MAINTAINERS: add entry for AVMatrix HWS driver Ben Hoff
2026-03-24 9:19 ` [PATCH v2 0/2] media: pci: add AVMatrix HWS capture driver Hans Verkuil
2026-03-30 19:56 ` [PATCH v3 " hoff.benjamin.k
2026-03-30 19:56 ` [PATCH v3 1/2] " hoff.benjamin.k
2026-03-30 19:56 ` [PATCH v3 2/2] MAINTAINERS: add entry for AVMatrix HWS driver hoff.benjamin.k
2026-03-30 23:36 ` [PATCH v4] media: pci: add AVMatrix HWS capture driver hoff.benjamin.k
2026-04-02 6:25 ` kernel test robot
2026-04-03 13:57 ` [PATCH v5] " hoff.benjamin.k
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox