diff options
| -rw-r--r-- | Documentation/devicetree/overlay-notes.txt | 8 | ||||
| -rw-r--r-- | drivers/of/overlay.c | 30 |
2 files changed, 29 insertions, 9 deletions
diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt index a4feb6dde8cd..725fb8d255c1 100644 --- a/Documentation/devicetree/overlay-notes.txt +++ b/Documentation/devicetree/overlay-notes.txt | |||
| @@ -98,6 +98,14 @@ Finally, if you need to remove all overlays in one-go, just call | |||
| 98 | of_overlay_remove_all() which will remove every single one in the correct | 98 | of_overlay_remove_all() which will remove every single one in the correct |
| 99 | order. | 99 | order. |
| 100 | 100 | ||
| 101 | In addition, there is the option to register notifiers that get called on | ||
| 102 | overlay operations. See of_overlay_notifier_register/unregister and | ||
| 103 | enum of_overlay_notify_action for details. | ||
| 104 | |||
| 105 | Note that a notifier callback is not supposed to store pointers to a device | ||
| 106 | tree node or its content beyond OF_OVERLAY_POST_REMOVE corresponding to the | ||
| 107 | respective node it received. | ||
| 108 | |||
| 101 | Overlay DTS Format | 109 | Overlay DTS Format |
| 102 | ------------------ | 110 | ------------------ |
| 103 | 111 | ||
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index b35fe88f1851..7baa53e5b1d7 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c | |||
| @@ -102,12 +102,28 @@ static DEFINE_IDR(ovcs_idr); | |||
| 102 | 102 | ||
| 103 | static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain); | 103 | static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain); |
| 104 | 104 | ||
| 105 | /** | ||
| 106 | * of_overlay_notifier_register() - Register notifier for overlay operations | ||
| 107 | * @nb: Notifier block to register | ||
| 108 | * | ||
| 109 | * Register for notification on overlay operations on device tree nodes. The | ||
| 110 | * reported actions definied by @of_reconfig_change. The notifier callback | ||
| 111 | * furthermore receives a pointer to the affected device tree node. | ||
| 112 | * | ||
| 113 | * Note that a notifier callback is not supposed to store pointers to a device | ||
| 114 | * tree node or its content beyond @OF_OVERLAY_POST_REMOVE corresponding to the | ||
| 115 | * respective node it received. | ||
| 116 | */ | ||
| 105 | int of_overlay_notifier_register(struct notifier_block *nb) | 117 | int of_overlay_notifier_register(struct notifier_block *nb) |
| 106 | { | 118 | { |
| 107 | return blocking_notifier_chain_register(&overlay_notify_chain, nb); | 119 | return blocking_notifier_chain_register(&overlay_notify_chain, nb); |
| 108 | } | 120 | } |
| 109 | EXPORT_SYMBOL_GPL(of_overlay_notifier_register); | 121 | EXPORT_SYMBOL_GPL(of_overlay_notifier_register); |
| 110 | 122 | ||
| 123 | /** | ||
| 124 | * of_overlay_notifier_register() - Unregister notifier for overlay operations | ||
| 125 | * @nb: Notifier block to unregister | ||
| 126 | */ | ||
| 111 | int of_overlay_notifier_unregister(struct notifier_block *nb) | 127 | int of_overlay_notifier_unregister(struct notifier_block *nb) |
| 112 | { | 128 | { |
| 113 | return blocking_notifier_chain_unregister(&overlay_notify_chain, nb); | 129 | return blocking_notifier_chain_unregister(&overlay_notify_chain, nb); |
| @@ -671,17 +687,13 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) | |||
| 671 | of_node_put(ovcs->fragments[i].overlay); | 687 | of_node_put(ovcs->fragments[i].overlay); |
| 672 | } | 688 | } |
| 673 | kfree(ovcs->fragments); | 689 | kfree(ovcs->fragments); |
| 674 | |||
| 675 | /* | 690 | /* |
| 676 | * TODO | 691 | * There should be no live pointers into ovcs->overlay_tree and |
| 677 | * | 692 | * ovcs->fdt due to the policy that overlay notifiers are not allowed |
| 678 | * would like to: kfree(ovcs->overlay_tree); | 693 | * to retain pointers into the overlay devicetree. |
| 679 | * but can not since drivers may have pointers into this data | ||
| 680 | * | ||
| 681 | * would like to: kfree(ovcs->fdt); | ||
| 682 | * but can not since drivers may have pointers into this data | ||
| 683 | */ | 694 | */ |
| 684 | 695 | kfree(ovcs->overlay_tree); | |
| 696 | kfree(ovcs->fdt); | ||
| 685 | kfree(ovcs); | 697 | kfree(ovcs); |
| 686 | } | 698 | } |
| 687 | 699 | ||
