On 7.3 the in-tree IPU6 isys driver can be runtime-suspended while isys_probe() is still running, before it has set drvdata. The suspend callback then dereferences a NULL isys, oopses, and psys never probes, so /dev/ipu-psys0 is missing and the camera HAL fails with "Failed to open PSYS". Patch the isys runtime PM callbacks to return early when drvdata is not set yet. The patched module is built on its own from the kernel source and installed under updates/, so it overrides the in-tree one without having to rebuild the whole kernel.
105 lines
2.9 KiB
Nix
105 lines
2.9 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
inherit (config.boot.kernelPackages) kernel kernelModuleMakeFlags;
|
|
|
|
ipu6-isys = pkgs.stdenv.mkDerivation {
|
|
pname = "ipu6-isys";
|
|
inherit (kernel) version;
|
|
|
|
__structuredAttrs = true;
|
|
|
|
patches = [ ./ipu6-isys-runtime-pm-null-check.patch ];
|
|
|
|
nativeBuildInputs = kernel.moduleBuildDependencies;
|
|
|
|
unpackPhase = ''
|
|
tar -xf ${kernel.src} --strip-components=1 --wildcards '*/drivers/media/pci/intel/ipu6/*'
|
|
'';
|
|
|
|
postPatch = ''
|
|
sed -i '/+= intel-ipu6\.o/d' drivers/media/pci/intel/ipu6/Makefile
|
|
'';
|
|
|
|
makeFlags = kernelModuleMakeFlags ++ [
|
|
"KERNELRELEASE=${kernel.modDirVersion}"
|
|
];
|
|
|
|
installFlags = [
|
|
"DEPMOD=true"
|
|
"INSTALL_MOD_PATH=${placeholder "out"}"
|
|
];
|
|
|
|
buildPhase = ''
|
|
runHook preBuild
|
|
make -C ${kernel.dev}/lib/modules/${kernel.modDirVersion}/build \
|
|
M=$(pwd)/drivers/media/pci/intel/ipu6 "''${makeFlags[@]}"
|
|
runHook postBuild
|
|
'';
|
|
|
|
installPhase = ''
|
|
runHook preInstall
|
|
make -C ${kernel.dev}/lib/modules/${kernel.modDirVersion}/build \
|
|
M=$(pwd)/drivers/media/pci/intel/ipu6 modules_install \
|
|
"''${makeFlags[@]}" "''${installFlags[@]}"
|
|
runHook postInstall
|
|
'';
|
|
};
|
|
in
|
|
{
|
|
nixpkgs.overlays = [
|
|
(final: prev: {
|
|
ipu6epmtl-camera-hal = prev.ipu6epmtl-camera-hal.overrideAttrs (old: {
|
|
postPatch = (old.postPatch or "") + ''
|
|
substituteInPlace src/v4l2/MediaControl.cpp \
|
|
--replace-fail 'static const string ivscName = "Intel IVSC CSI";' \
|
|
'static const string ivscName = "Intel CVS";'
|
|
'';
|
|
});
|
|
|
|
gst_all_1 = prev.gst_all_1 // {
|
|
icamerasrc-ipu6epmtl =
|
|
(prev.gst_all_1.icamerasrc-ipu6epmtl.override {
|
|
ipu6-camera-hal = final.ipu6epmtl-camera-hal;
|
|
}).overrideAttrs
|
|
(old: {
|
|
version = "20250923_ov02e";
|
|
src = final.fetchFromGitHub {
|
|
owner = "intel";
|
|
repo = "icamerasrc";
|
|
tag = "20250923_ov02e";
|
|
hash = "sha256-mKRK0Z3dnyvzvoL6BotpVFRtkb53GQw9wUOrHIUoEsA=";
|
|
};
|
|
});
|
|
};
|
|
})
|
|
];
|
|
|
|
boot.extraModulePackages = [ ipu6-isys ];
|
|
|
|
hardware.ipu6 = {
|
|
enable = true;
|
|
platform = "ipu6epmtl";
|
|
};
|
|
|
|
services.v4l2-relayd.instances.ipu6.input = {
|
|
pipeline = lib.mkForce "icamerasrc buffer-count=10";
|
|
width = 1920;
|
|
height = 1080;
|
|
};
|
|
|
|
systemd.services.v4l2-relayd-ipu6 = {
|
|
preStart = lib.mkOverride 40 ''
|
|
mkdir -p "$(dirname "$V4L2_DEVICE_FILE")"
|
|
${config.boot.kernelPackages.v4l2loopback.bin}/bin/v4l2loopback-ctl \
|
|
add --name "Intel MIPI Camera" --exclusive-caps=1 --buffers 8 \
|
|
${toString config.hardware.ipu6.videoDeviceNumber} || [ $? -eq 17 ]
|
|
echo /dev/video${toString config.hardware.ipu6.videoDeviceNumber} > "$V4L2_DEVICE_FILE"
|
|
'';
|
|
};
|
|
}
|