@@ -173,7 +173,24 @@ static int mfd_add_device(struct device *parent, int id,
goto fail_alias;
}
- if (cell->properties) {
+ /* If software node group exists, use it, otherwise try properties */
+ if (cell->node_group) {
+ struct fwnode_handle *fwnode;
+
+ ret = software_node_register_node_group(cell->node_group);
+ if (ret)
+ goto fail_alias;
+
+ /*
+ * The very first software node in the group is related to
+ * the device itself. The rest can be device-less children to
+ * fulfill the case of sub nodes (LEDs, GPIO keys, etc).
+ */
+ fwnode = software_node_fwnode(cell->node_group[0]);
+
+ /* Assign this firmware node as a secondary one of the device */
+ set_secondary_fwnode(&pdev->dev, fwnode);
+ } else if (cell->properties) {
ret = platform_device_add_properties(pdev, cell->properties);
if (ret)
goto fail_alias;
@@ -213,18 +230,18 @@ static int mfd_add_device(struct device *parent, int id,
if (has_acpi_companion(&pdev->dev)) {
ret = acpi_check_resource_conflict(&res[r]);
if (ret)
- goto fail_alias;
+ goto fail_resources;
}
}
}
ret = platform_device_add_resources(pdev, res, cell->num_resources);
if (ret)
- goto fail_alias;
+ goto fail_resources;
ret = platform_device_add(pdev);
if (ret)
- goto fail_alias;
+ goto fail_resources;
if (cell->pm_runtime_no_callbacks)
pm_runtime_no_callbacks(&pdev->dev);
@@ -233,6 +250,9 @@ static int mfd_add_device(struct device *parent, int id,
return 0;
+fail_resources:
+ set_secondary_fwnode(&pdev->dev, NULL);
+ software_node_unregister_node_group(cell->node_group);
fail_alias:
regulator_bulk_unregister_supply_alias(&pdev->dev,
cell->parent_supplies,
@@ -294,6 +314,9 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
pdev = to_platform_device(dev);
cell = mfd_get_cell(pdev);
+ set_secondary_fwnode(&pdev->dev, NULL);
+ software_node_unregister_node_group(cell->node_group);
+
regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
cell->num_parent_supplies);
@@ -72,6 +72,9 @@ struct mfd_cell {
/* device properties passed to the sub devices drivers */
struct property_entry *properties;
+ /* Software node group for the sub device */
+ const struct software_node **node_group;
+
/*
* Device Tree compatible string
* See: Documentation/devicetree/usage-model.txt Chapter 2.2 for details