Skip to content

Commit 54e7770

Browse files
pantoniouDa Xue
authored andcommitted
of: overlay: Kobjectify overlay objects
We are going to need the overlays to appear on sysfs with runtime global properties (like master enable) so turn them into kobjects. They have to be in sysfs so that people can have information about the overlays applied in the system, i.e. where their targets are and whether removal is possible. In a future more attributes can be added in a backwards compatible manner. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> [geert: Rebase to v4.15-rc1] [Fengguang Wu: Make overlay_changeset_release() static] [geert: Rebase on top of commit 39a751a ("of: change overlay apply input data from unflattened to FDT") in v4.17-rc1] [geert: Rebase on top of commit 421f4d1 ("of: overlay: do not free changeset when of_overlay_apply returns error") in v5.19-rc1] [geert: Rebase on top of commit 73aca58 ("of: Move of_platform_register_reconfig_notifier() into DT core") in v6.6-rc1] [geert: Add kerneldoc for fragment.kobj] Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
1 parent 670154d commit 54e7770

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

drivers/of/base.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ void __of_phandle_cache_inv_entry(phandle handle)
166166
void __init of_core_init(void)
167167
{
168168
struct device_node *np;
169+
int ret;
169170

170171
of_platform_register_reconfig_notifier();
171172

@@ -187,6 +188,10 @@ void __init of_core_init(void)
187188
/* Symlink in /proc as required by userspace ABI */
188189
if (of_root)
189190
proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
191+
192+
ret = of_overlay_init();
193+
if (ret != 0)
194+
pr_warn("of_init: of_overlay_init failed!\n");
190195
}
191196

192197
static struct property *__of_find_property(const struct device_node *np,

drivers/of/of_private.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,13 @@ void fdt_init_reserved_mem(void);
182182
void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
183183
phys_addr_t base, phys_addr_t size);
184184

185+
#if defined(CONFIG_OF_OVERLAY)
186+
extern int of_overlay_init(void);
187+
#else
188+
static inline int of_overlay_init(void)
189+
{
190+
return 0;
191+
}
192+
#endif
193+
185194
#endif /* _LINUX_OF_PRIVATE_H */

drivers/of/overlay.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/libfdt.h>
2121
#include <linux/err.h>
2222
#include <linux/idr.h>
23+
#include <linux/sysfs.h>
2324

2425
#include "of_private.h"
2526

@@ -65,6 +66,7 @@ struct fragment {
6566
* @fragments: fragment nodes in the overlay expanded device tree
6667
* @symbols_fragment: last element of @fragments[] is the __symbols__ node
6768
* @cset: changeset to apply fragments to live device tree
69+
* @kobj: kernel object handle
6870
*/
6971
struct overlay_changeset {
7072
int id;
@@ -77,6 +79,7 @@ struct overlay_changeset {
7779
struct fragment *fragments;
7880
bool symbols_fragment;
7981
struct of_changeset cset;
82+
struct kobject kobj;
8083
};
8184

8285
/* flags are sticky - once set, do not reset */
@@ -868,6 +871,17 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs)
868871
of_node_put(ovcs->fragments[i].overlay);
869872
}
870873
kfree(ovcs->fragments);
874+
kobject_put(&ovcs->kobj);
875+
}
876+
877+
static inline struct overlay_changeset *kobj_to_ovcs(struct kobject *kobj)
878+
{
879+
return container_of(kobj, struct overlay_changeset, kobj);
880+
}
881+
882+
static void overlay_changeset_release(struct kobject *kobj)
883+
{
884+
struct overlay_changeset *ovcs = kobj_to_ovcs(kobj);
871885

872886
/*
873887
* There should be no live pointers into ovcs->overlay_mem and
@@ -887,6 +901,12 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs)
887901
kfree(ovcs);
888902
}
889903

904+
static struct kobj_type overlay_changeset_ktype = {
905+
.release = overlay_changeset_release,
906+
};
907+
908+
static struct kset *ov_kset;
909+
890910
/*
891911
* internal documentation
892912
*
@@ -1015,6 +1035,8 @@ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
10151035
if (!ovcs)
10161036
return -ENOMEM;
10171037

1038+
kobject_init(&ovcs->kobj, &overlay_changeset_ktype);
1039+
10181040
of_overlay_mutex_lock();
10191041
mutex_lock(&of_mutex);
10201042

@@ -1064,6 +1086,16 @@ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
10641086
* can call of_overlay_remove();
10651087
*/
10661088
*ret_ovcs_id = ovcs->id;
1089+
1090+
if (ret)
1091+
goto out_unlock;
1092+
1093+
ovcs->kobj.kset = ov_kset;
1094+
ret = kobject_add(&ovcs->kobj, NULL, "%d", ovcs->id);
1095+
if (ret) {
1096+
pr_err("%s: kobject_add() failed for tree@%s\n", __func__,
1097+
ovcs->overlay_root->full_name);
1098+
}
10671099
goto out_unlock;
10681100

10691101
err_free_ovcs:
@@ -1284,3 +1316,13 @@ int of_overlay_remove_all(void)
12841316
return 0;
12851317
}
12861318
EXPORT_SYMBOL_GPL(of_overlay_remove_all);
1319+
1320+
/* called from of_init() */
1321+
int of_overlay_init(void)
1322+
{
1323+
ov_kset = kset_create_and_add("overlays", NULL, &of_kset->kobj);
1324+
if (!ov_kset)
1325+
return -ENOMEM;
1326+
1327+
return 0;
1328+
}

0 commit comments

Comments
 (0)