diff --git a/hosts/pinwheel/modules/webcam/default.nix b/hosts/pinwheel/modules/webcam/default.nix index 69ceeef..96ec3ec 100644 --- a/hosts/pinwheel/modules/webcam/default.nix +++ b/hosts/pinwheel/modules/webcam/default.nix @@ -1,4 +1,55 @@ -{ config, lib, ... }: +{ + 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: { @@ -28,6 +79,8 @@ }) ]; + boot.extraModulePackages = [ ipu6-isys ]; + hardware.ipu6 = { enable = true; platform = "ipu6epmtl"; diff --git a/hosts/pinwheel/modules/webcam/ipu6-isys-runtime-pm-null-check.patch b/hosts/pinwheel/modules/webcam/ipu6-isys-runtime-pm-null-check.patch new file mode 100644 index 0000000..8d3dcc0 --- /dev/null +++ b/hosts/pinwheel/modules/webcam/ipu6-isys-runtime-pm-null-check.patch @@ -0,0 +1,22 @@ +--- a/drivers/media/pci/intel/ipu6/ipu6-isys.c ++++ b/drivers/media/pci/intel/ipu6/ipu6-isys.c +@@ -858,6 +858,9 @@ + unsigned long flags; + int ret; + ++ if (!isys) ++ return 0; ++ + ret = ipu6_mmu_hw_init(adev->mmu); + if (ret) + return ret; +@@ -885,6 +888,9 @@ + struct ipu6_isys *isys = dev_get_drvdata(dev); + unsigned long flags; + ++ if (!isys) ++ return 0; ++ + spin_lock_irqsave(&isys->power_lock, flags); + isys->power = 0; + spin_unlock_irqrestore(&isys->power_lock, flags);