diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp
index 0b596bce..7d28f9b8 100644
--- a/src/libcamera/device_enumerator.cpp
+++ b/src/libcamera/device_enumerator.cpp
@@ -9,10 +9,15 @@
 #include "device_enumerator_sysfs.h"
 #include "device_enumerator_udev.h"
 
+#include <algorithm>
+#include <dirent.h>
+#include <fstream>
 #include <string.h>
+#include <sys/types.h>
 
 #include "log.h"
 #include "media_device.h"
+#include "pipeline_handler.h"
 #include "utils.h"
 
 /**
@@ -306,4 +311,68 @@ std::shared_ptr<MediaDevice> DeviceEnumerator::search(const DeviceMatch &dm)
 	return nullptr;
 }
 
+int extractNumberFromFile(std::string &path)
+{
+	std::ifstream file;
+	std::string line;
+
+	file.open(path);
+	if (!file)
+		return -1;
+
+	file >> line;
+	int i = std::stoi(line, 0, 16);
+	file.close();
+
+	return i;
+}
+
+bool DeviceEnumerator::haveExpectedCameras(CameraManager *cm)
+{
+	std::vector<std::reference_wrapper<DeviceID>> &supportedDevices =
+		PipelineHandlerFactory::getDeviceIDs();
+	std::vector<DeviceID> availableDevices;
+	std::vector<DeviceID> intersection;
+	struct dirent *ent;
+	DIR *dir;
+	const char *pciDir = "/sys/bus/pci/devices";
+
+	dir = opendir(pciDir);
+	if (!dir) {
+		LOG(DeviceEnumerator, Error)
+			<< "Failed to open sysfs PCI directory";
+		/* We can't expect any cameras, so we vacuously have them all. */
+		return true;
+	}
+
+	while ((ent = readdir(dir)) != nullptr) {
+		std::string path = pciDir + std::string("/") + ent->d_name + "/vendor";
+		int vendor = extractNumberFromFile(path);
+		if (vendor < 0)
+			continue;
+
+		path = pciDir + std::string("/") + ent->d_name + "/device";
+		int device = extractNumberFromFile(path);
+		if (device < 0)
+			continue;
+
+		availableDevices.push_back(PCIDeviceID(vendor, device));
+	}
+
+	closedir(dir);
+
+	std::set_intersection(supportedDevices.begin(), supportedDevices.end(),
+			      availableDevices.begin(), availableDevices.end(),
+			      back_inserter(intersection),
+			      compareDevices<PCIDeviceID>);
+
+	if (cm->cameras().size() < intersection.size()) {
+		LOG(DeviceEnumerator, Warning) << "Not enough cameras!";
+		return false;
+	}
+
+	LOG(DeviceEnumerator, Debug) << "All cameras correctly initialized";
+	return true;
+}
+
 } /* namespace libcamera */
diff --git a/src/libcamera/include/device_enumerator.h b/src/libcamera/include/device_enumerator.h
index 770f4277..11c4cdfb 100644
--- a/src/libcamera/include/device_enumerator.h
+++ b/src/libcamera/include/device_enumerator.h
@@ -13,6 +13,8 @@
 
 #include <linux/media.h>
 
+#include <libcamera/camera_manager.h>
+
 namespace libcamera {
 
 class MediaDevice;
@@ -43,6 +45,8 @@ public:
 
 	std::shared_ptr<MediaDevice> search(const DeviceMatch &dm);
 
+	static bool haveExpectedCameras(CameraManager *cm);
+
 protected:
 	std::shared_ptr<MediaDevice> createDevice(const std::string &deviceNode);
 	void addDevice(const std::shared_ptr<MediaDevice> &media);
