of/overlay: add of overlay notifications
PATCH 1/1 of/overlay: add of overlay notifications
This patch add of overlay notifications.
When DT overlays are being added, some drivers/subsystems need to see device tree overlays before the changes go into the live tree.
This is distinct from reconfig notifiers that are post-apply or post-remove and which issue very granular notifications without providing access to the context of a whole overlay.
The following 4 notificatons are issued:
OF_OVERLAY_PRE_APPLY
OF_OVERLAY_POST_APPLY
OF_OVERLAY_PRE_REMOVE
OF_OVERLAY_POST_REMOVE
In the case of pre-apply notification, if the notifier returns error, the overlay will be rejected.
This patch exports two functions for registering/unregistering notifications:
of_overlay_notifier_register(struct notifier_block *nb) of_overlay_notifier_unregister(struct notifier_block *nb)
The notification data includes pointers to the overlay target and the overlay:
struct of_overlay_notify_data {
struct device_node *overlay;
struct device_node *target;
};--- drivers/of/overlay.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- include/linux/of.h | 25 +++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-)
drivers/of/overlay.c +46 -1
@@ -56,6 +56,41 @@ struct of_overlay {static int of_overlay_apply_one (struct of_overlay *ov,struct device_node *target,const struct device_node *overlay); +static BLOCKING_NOTIFIER_HEAD (of_overlay_chain); + +int of_overlay_notifier_register (struct notifier_block *nb) +{ +return blocking_notifier_chain_register (&of_overlay_chain, nb); +} +EXPORT_SYMBOL_GPL (of_overlay_notifier_register); + +int of_overlay_notifier_unregister (struct notifier_block *nb) +{ +return blocking_notifier_chain_unregister (&of_overlay_chain, nb); +} +EXPORT_SYMBOL_GPL (of_overlay_notifier_unregister); + +static int of_overlay_notify (struct of_overlay *ov, +enum of_overlay_notify_action action) +{ +struct of_overlay_notify_data nd; +int i, ret; + +for (i =0 ; i < ov->count; i++) { +struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i]; + + nd.target = ovinfo->target; + nd.overlay = ovinfo->overlay; + + ret =blocking_notifier_call_chain (&of_overlay_chain, + action, &nd); +if (ret) +return notifier_to_errno (ret); + } + +return 0 ; +} +static int of_overlay_apply_single_property (struct of_overlay *ov,struct device_node *target,struct property *prop) {
@@ -370,6 +405,13 @@ int of_overlay_create(struct device_node *tree) goto err_free_idr; } + err =of_overlay_notify (ov,OF_OVERLAY_PRE_APPLY ); +if (err <0 ) { +pr_err ("%s: Pre-apply notifier failed (err=%d)\n" , + __func__, err); + goto err_free_idr; + } +/* apply the overlay */ err =of_overlay_apply (ov);if (err) {
@@ -389,6 +431,8 @@ int of_overlay_create(struct device_node *tree)/* add to the tail of the overlay list */ list_add_tail (&ov->node, &ov_list); +of_overlay_notify (ov,OF_OVERLAY_POST_APPLY ); +mutex_unlock (&of_mutex);return id;
@@ -509,9 +553,10 @@ int of_overlay_destroy(int id) goto out; } - +of_overlay_notify (ov,OF_OVERLAY_PRE_REMOVE );list_del (&ov->node);__of_changeset_revert (&ov->cset); +of_overlay_notify (ov,OF_OVERLAY_POST_REMOVE );of_free_overlay_info (ov);idr_remove (&ov_idr, id);of_changeset_destroy (&ov->cset);
include/linux/of.h +25 -0
@@ -1083,6 +1083,21 @@ int of_overlay_create(struct device_node *tree);int of_overlay_destroy (int id);int of_overlay_destroy_all (void ); +enum of_overlay_notify_action { +OF_OVERLAY_PRE_APPLY , +OF_OVERLAY_POST_APPLY , +OF_OVERLAY_PRE_REMOVE , +OF_OVERLAY_POST_REMOVE , +}; + +struct of_overlay_notify_data { +struct device_node *overlay; +struct device_node *target; +}; + +int of_overlay_notifier_register (struct notifier_block *nb); +int of_overlay_notifier_unregister (struct notifier_block *nb); +#else static inline int of_overlay_create (struct device_node *tree)
@@ -1100,6 +1115,16 @@ static inline int of_overlay_destroy_all(void)return -ENOTSUPP ; } +int of_overlay_notifier_register (struct notifier_block *nb) +{ +return 0 ; +} + +int of_overlay_notifier_unregister (struct notifier_block *nb) +{ +return 0 ; +} +#endif #endif /* _LINUX_OF_H */
Signature · 1 line
1.7.9.5
kbuild test robot
build botreproduce:
Hi Alan,
[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.5-rc5 next-20160225]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Alan-Tull/of-overlay-add-of-overlay-notifications/20160226-074214 base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux for-next config: i386-tinyconfig (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=i386
All errors (new ones prefixed by >>):
arch/x86/kernel/setup.o: In function `of_overlay_notifier_register':
>> setup.c:(.text+0x3): multiple definition of `of_overlay_notifier_register' arch/x86/kernel/irq.o:irq.c:(.text+0x1): first defined here arch/x86/kernel/setup.o: In function `of_overlay_notifier_unregister': >> setup.c:(.text+0x6): multiple definition of `of_overlay_notifier_unregister'
arch/x86/kernel/irq.o:irq.c:(.text+0x4): first defined here arch/x86/kernel/irqinit.o: In function `of_overlay_notifier_register':
irqinit.c:(.text+0x0): multiple definition of of_overlay_notifier_register' arch/x86/kernel/irq.o:irq.c:(.text+0x1): first defined here arch/x86/kernel/irqinit.o: In function of_overlay_notifier_unregister':
irqinit.c:(.text+0x3): multiple definition of of_overlay_notifier_unregister' arch/x86/kernel/irq.o:irq.c:(.text+0x4): first defined here arch/x86/kernel/rtc.o: In function of_overlay_notifier_register':
rtc.c:(.text+0x43): multiple definition of of_overlay_notifier_register' arch/x86/kernel/irq.o:irq.c:(.text+0x1): first defined here arch/x86/kernel/rtc.o: In function of_overlay_notifier_unregister':
rtc.c:(.text+0x46): multiple definition of of_overlay_notifier_unregister' arch/x86/kernel/irq.o:irq.c:(.text+0x4): first defined here arch/x86/kernel/sysfb.o: In function of_overlay_notifier_register':
sysfb.c:(.text+0x0): multiple definition of of_overlay_notifier_register' arch/x86/kernel/irq.o:irq.c:(.text+0x1): first defined here arch/x86/kernel/sysfb.o: In function of_overlay_notifier_unregister':
sysfb.c:(.text+0x3): multiple definition of `of_overlay_notifier_unregister' arch/x86/kernel/irq.o:irq.c:(.text+0x4): first defined here
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Quoted 147 lines · Alan Tull
This patch add of overlay notifications.
When DT overlays are being added, some
drivers/subsystemsneed to see device tree overlays before the changes go into the live tree.This is distinct from reconfig notifiers that are post-apply or post-remove and which issue very granular notifications without providing access to the context of a whole overlay.
The following 4 notificatons are issued:
OF_OVERLAY_PRE_APPLY
OF_OVERLAY_POST_APPLY
OF_OVERLAY_PRE_REMOVE
OF_OVERLAY_POST_REMOVEIn the case of pre-apply notification, if the notifier returns error, the overlay will be rejected.
This patch exports two functions for registering/unregistering notifications:
of_overlay_notifier_register(struct notifier_block *nb)of_overlay_notifier_unregister(struct notifier_block *nb)The notification data includes pointers to the overlay target and the overlay:
struct of_overlay_notify_data { struct device_node *overlay; struct device_node *target; };Signed-off-by Alan Tull <[email protected]>--- drivers/of/overlay.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- include/linux/of.h | 25 +++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-)drivers/of/overlay.c +46
-1@@ -56,6 +56,41 @@ struct of_overlay {static int of_overlay_apply_one (struct of_overlay *ov,struct device_node *target,const struct device_node *overlay); +static BLOCKING_NOTIFIER_HEAD (of_overlay_chain); + +int of_overlay_notifier_register (struct notifier_block *nb) +{ +return blocking_notifier_chain_register (&of_overlay_chain, nb); +} +EXPORT_SYMBOL_GPL (of_overlay_notifier_register); + +int of_overlay_notifier_unregister (struct notifier_block *nb) +{ +return blocking_notifier_chain_unregister (&of_overlay_chain, nb); +} +EXPORT_SYMBOL_GPL (of_overlay_notifier_unregister); + +static int of_overlay_notify (struct of_overlay *ov, +enum of_overlay_notify_action action) +{ +struct of_overlay_notify_data nd; +int i, ret; + +for (i =0 ; i < ov->count; i++) { +struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i]; + + nd.target = ovinfo->target; + nd.overlay = ovinfo->overlay; + + ret =blocking_notifier_call_chain (&of_overlay_chain, + action, &nd); +if (ret) +return notifier_to_errno (ret); + } + +return 0 ; +} +static int of_overlay_apply_single_property (struct of_overlay *ov,struct device_node *target,struct property *prop) {@@ -370,6 +405,13 @@ int of_overlay_create(struct device_node *tree) goto err_free_idr; } + err =of_overlay_notify (ov,OF_OVERLAY_PRE_APPLY ); +if (err <0 ) { +pr_err ("%s: Pre-apply notifier failed (err=%d)\n" , + __func__, err); + goto err_free_idr; + } +/* apply the overlay */ err =of_overlay_apply (ov);if (err) {@@ -389,6 +431,8 @@ int of_overlay_create(struct device_node *tree)/* add to the tail of the overlay list */ list_add_tail (&ov->node, &ov_list); +of_overlay_notify (ov,OF_OVERLAY_POST_APPLY ); +mutex_unlock (&of_mutex);return id;@@ -509,9 +553,10 @@ int of_overlay_destroy(int id) goto out; } - +of_overlay_notify (ov,OF_OVERLAY_PRE_REMOVE );list_del (&ov->node);__of_changeset_revert (&ov->cset); +of_overlay_notify (ov,OF_OVERLAY_POST_REMOVE );of_free_overlay_info (ov);idr_remove (&ov_idr, id);of_changeset_destroy (&ov->cset);include/linux/of.h +15
-0@@ -1083,6 +1083,21 @@ int of_overlay_create(struct device_node *tree);int of_overlay_destroy (int id);int of_overlay_destroy_all (void ); +enum of_overlay_notify_action { +OF_OVERLAY_PRE_APPLY , +OF_OVERLAY_POST_APPLY , +OF_OVERLAY_PRE_REMOVE , +OF_OVERLAY_POST_REMOVE , +}; + +struct of_overlay_notify_data { +struct device_node *overlay; +struct device_node *target; +}; + +int of_overlay_notifier_register (struct notifier_block *nb); +int of_overlay_notifier_unregister (struct notifier_block *nb); +#else static inline int of_overlay_create (struct device_node *tree)
include/linux/of.h static inline int of_overlay_destroy_all(void) · line 1118
Quoted 4 lines
include/linux/of.h +1
-0@@ -1100,6 +1115,16 @@ static inline int of_overlay_destroy_all(void)return -ENOTSUPP ; } +int of_overlay_notifier_register (struct notifier_block *nb)
Needs 'static inline'
include/linux/of.h static inline int of_overlay_destroy_all(void) · line 1123
Quoted 5 lines
include/linux/of.h +5
-0+{ +return 0 ; +} + +int of_overlay_notifier_unregister (struct notifier_block *nb)
Needs 'static inline'
Alan
Quoted 11 lines
include/linux/of.h +4
-0+{ +return 0 ; +} +#endif #endif /* _LINUX_OF_H */ Signature · 1 line
1.7.9.5