pinwheel: Fix intermittent webcam failure from IPU6 isys oops
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.
This commit is contained in:
2 files changed
+76
-1
No files matched your search
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
Reference in new issue
Block a user