There are also devm_* versions of these functions which release the
 descriptors once the device is released.
+
+MFD devices
+~~~~~~~~~~~
+The MFD devices register their children as platform devices. For the child
+devices there needs to be an ACPI handle that they can use to reference
+parts of the ACPI namespace that relate to them. In the Linux MFD subsystem
+we provide two ways:
+
+       o The children share the parent ACPI handle.
+       o The MFD cell can specify the ACPI id of the device.
+
+For the first case, the MFD drivers do not need to do anything. The
+resulting child platform device will have its ACPI_COMPANION() set to point
+to the parent device.
+
+If the ACPI namespace has a device that we can match using an ACPI id,
+the id should be set like:
+
+       static struct mfd_cell my_subdevice_cell = {
+               .name = "my_subdevice",
+               /* set the resources relative to the parent */
+               .acpi_pnpid = "XYZ0001",
+       };
+
+The ACPI id "XYZ0001" is then used to lookup an ACPI device directly under
+the MFD device and if found, that ACPI companion device is bound to the
+resulting child platform device.
 
        return 0;
 }
 
+#if IS_ENABLED(CONFIG_ACPI)
+static void mfd_acpi_add_device(const struct mfd_cell *cell,
+                               struct platform_device *pdev)
+{
+       struct acpi_device *parent_adev;
+       struct acpi_device *adev;
+
+       parent_adev = ACPI_COMPANION(pdev->dev.parent);
+       if (!parent_adev)
+               return;
+
+       /*
+        * MFD child device gets its ACPI handle either from the ACPI
+        * device directly under the parent that matches the acpi_pnpid or
+        * it will use the parent handle if is no acpi_pnpid is given.
+        */
+       adev = parent_adev;
+       if (cell->acpi_pnpid) {
+               struct acpi_device_id ids[2] = {};
+               struct acpi_device *child_adev;
+
+               strlcpy(ids[0].id, cell->acpi_pnpid, sizeof(ids[0].id));
+               list_for_each_entry(child_adev, &parent_adev->children, node)
+                       if (acpi_match_device_ids(child_adev, ids)) {
+                               adev = child_adev;
+                               break;
+                       }
+       }
+
+       ACPI_COMPANION_SET(&pdev->dev, adev);
+}
+#else
+static inline void mfd_acpi_add_device(const struct mfd_cell *cell,
+                                      struct platform_device *pdev)
+{
+}
+#endif
+
 static int mfd_add_device(struct device *parent, int id,
                          const struct mfd_cell *cell, atomic_t *usage_count,
                          struct resource *mem_base,
                }
        }
 
+       mfd_acpi_add_device(cell, pdev);
+
        if (cell->pdata_size) {
                ret = platform_device_add_data(pdev,
                                        cell->platform_data, cell->pdata_size);
 
         */
        const char              *of_compatible;
 
+       /* Matches ACPI PNP id, either _HID or _CID */
+       const char              *acpi_pnpid;
+
        /*
         * These resources can be specified relative to the parent device.
         * For accessing hardware you should use resources from the platform dev