media: ipu3-cio2: Defer probing until the PMIC is fully setup
authorHans de Goede <hdegoede@redhat.com>
Fri, 3 Dec 2021 10:28:55 +0000 (11:28 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Thu, 16 Dec 2021 19:57:21 +0000 (20:57 +0100)
On devices where things are not fully describe in devicetree (1)
and where the code thus falls back to calling cio2_bridge_init(),
the i2c-clients for any VCMs also need to be instantiated manually.

The VCM can be probed by its driver as soon as the code instantiates
the i2c-client and this probing must not happen before the PMIC is
fully setup.

Make cio2_bridge_init() return -EPROBE_DEFER when the PMIC is not
fully-setup, deferring the probe of the ipu3-cio2 driver.

This is a preparation patch for adding VCM enumeration support to
the ipu3-cio2-bridge code.

1) Through embedding of devicetree info in the ACPI tables

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/pci/intel/ipu3/cio2-bridge.c

index 1cbbcbf..c805916 100644 (file)
@@ -308,6 +308,40 @@ err_unregister_sensors:
        return ret;
 }
 
+/*
+ * The VCM cannot be probed until the PMIC is completely setup. We cannot rely
+ * on -EPROBE_DEFER for this, since the consumer<->supplier relations between
+ * the VCM and regulators/clks are not described in ACPI, instead they are
+ * passed as board-data to the PMIC drivers. Since -PROBE_DEFER does not work
+ * for the clks/regulators the VCM i2c-clients must not be instantiated until
+ * the PMIC is fully setup.
+ *
+ * The sensor/VCM ACPI device has an ACPI _DEP on the PMIC, check this using the
+ * acpi_dev_ready_for_enumeration() helper, like the i2c-core-acpi code does
+ * for the sensors.
+ */
+static int cio2_bridge_sensors_are_ready(void)
+{
+       struct acpi_device *adev;
+       bool ready = true;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(cio2_supported_sensors); i++) {
+               const struct cio2_sensor_config *cfg =
+                       &cio2_supported_sensors[i];
+
+               for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
+                       if (!adev->status.enabled)
+                               continue;
+
+                       if (!acpi_dev_ready_for_enumeration(adev))
+                               ready = false;
+               }
+       }
+
+       return ready;
+}
+
 int cio2_bridge_init(struct pci_dev *cio2)
 {
        struct device *dev = &cio2->dev;
@@ -316,6 +350,9 @@ int cio2_bridge_init(struct pci_dev *cio2)
        unsigned int i;
        int ret;
 
+       if (!cio2_bridge_sensors_are_ready())
+               return -EPROBE_DEFER;
+
        bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
        if (!bridge)
                return -ENOMEM;