devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 0/6]  of: overlay: kobject & sysfs'ation
@ 2016-05-09 13:09 Pantelis Antoniou
  2016-05-09 13:09 ` [PATCH v8 1/6] of: overlay: kobjectify overlay objects Pantelis Antoniou
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Pantelis Antoniou @ 2016-05-09 13:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Frank Rowand, Matt Porter, Koen Kooi, Guenter Roeck,
	Greg Kroah-Hartman, devicetree, linux-kernel, linux-api,
	Pantelis Antoniou, Pantelis Antoniou

The first patch puts the overlays as objects in the sysfs in
/sys/firmware/devicetree/overlays.

The #2 adds a master overlay enable switch (that once is set to
disabled can't be re-enabled), while the one after that
introduces a number of default per overlay attributes.
The patch following is the ABI docs for the sysfs entries of #2,
while the next one updates the doc entry for the kernel parameter
of_overlay_disable.

Patch #5 add per overlay sysfs attributes, and the next one is
documentation about it.

The patchset is against linus's tree as of today.

Changes since v7:
* ACKs from gregh
* Rebased against latest mainline

Changes since v6:
* Updated changelogs as per maintainer suggestion.
* Fixed documentation entries and split them up
* Added command line parameter docs.

Changes since v5:
* Does a single kobject_put that suffices
* A per-fragment sysfs directory and a single value target.
* Update in the ABI documention.

Changes since v4:
* Rebased against latest mainline.

Changes since v3:
* Used strtobool instead of kstrtoul
* ABI Documentation includes a pointer to the discussion that
requested the sysfs property.

Changes since v2:
* Removed the unittest patch.
* Split the sysfs attribute patch to a global and a per-overlay
  patch.
* Dropped binary attributes using textual kobj_attributes instead.

Changes since v1:
* Maintainer requested changes.
* Documented the sysfs entries
* Per overlay sysfs attributes.

Pantelis Antoniou (6):
  of: overlay: kobjectify overlay objects
  of: overlay: global sysfs enable attribute
  Documentation: ABI: overlays - global attributes
  Documentation: document of_overlay_disable parameter
  of: overlay: add per overlay sysfs attributes
  Documentation: ABI: overlays - per overlay docs

 .../ABI/testing/sysfs-firmware-devicetree-overlays |  52 ++++++
 Documentation/kernel-parameters.txt                |   3 +
 drivers/of/base.c                                  |   5 +
 drivers/of/of_private.h                            |   9 +
 drivers/of/overlay.c                               | 201 ++++++++++++++++++++-
 5 files changed, 264 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-devicetree-overlays

-- 
1.7.12

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v8 1/6] of: overlay: kobjectify overlay objects
  2016-05-09 13:09 [PATCH v8 0/6] of: overlay: kobject & sysfs'ation Pantelis Antoniou
@ 2016-05-09 13:09 ` Pantelis Antoniou
  2016-05-09 13:09 ` [PATCH v8 2/6] of: overlay: global sysfs enable attribute Pantelis Antoniou
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Pantelis Antoniou @ 2016-05-09 13:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Frank Rowand, Matt Porter, Koen Kooi, Guenter Roeck,
	Greg Kroah-Hartman, devicetree, linux-kernel, linux-api,
	Pantelis Antoniou, Pantelis Antoniou

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>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/of/base.c       |  5 +++++
 drivers/of/of_private.h |  9 +++++++++
 drivers/of/overlay.c    | 50 +++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index b299de2..9bbca56 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -192,6 +192,7 @@ int __of_attach_node_sysfs(struct device_node *np)
 void __init of_core_init(void)
 {
 	struct device_node *np;
+	int ret;
 
 	/* Create the kset, and register existing nodes */
 	mutex_lock(&of_mutex);
@@ -208,6 +209,10 @@ void __init of_core_init(void)
 	/* Symlink in /proc as required by userspace ABI */
 	if (of_root)
 		proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
+
+	ret = of_overlay_init();
+	if (ret != 0)
+		pr_warn("of_init: of_overlay_init failed!\n");
 }
 
 static struct property *__of_find_property(const struct device_node *np,
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 829469f..092cba7 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -92,4 +92,13 @@ extern void __of_detach_node_sysfs(struct device_node *np);
 #define for_each_transaction_entry_reverse(_oft, _te) \
 	list_for_each_entry_reverse(_te, &(_oft)->te_list, node)
 
+#if defined(CONFIG_OF_OVERLAY)
+extern int of_overlay_init(void);
+#else
+static inline int of_overlay_init(void)
+{
+	return 0;
+}
+#endif
+
 #endif /* _LINUX_OF_PRIVATE_H */
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 8225081..4e06c34 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/idr.h>
+#include <linux/sysfs.h>
 
 #include "of_private.h"
 
@@ -51,6 +52,7 @@ struct of_overlay {
 	int count;
 	struct of_overlay_info *ovinfo_tab;
 	struct of_changeset cset;
+	struct kobject kobj;
 };
 
 static int of_overlay_apply_one(struct of_overlay *ov,
@@ -326,6 +328,24 @@ static int of_free_overlay_info(struct of_overlay *ov)
 static LIST_HEAD(ov_list);
 static DEFINE_IDR(ov_idr);
 
+static inline struct of_overlay *kobj_to_overlay(struct kobject *kobj)
+{
+	return container_of(kobj, struct of_overlay, kobj);
+}
+
+void of_overlay_release(struct kobject *kobj)
+{
+	struct of_overlay *ov = kobj_to_overlay(kobj);
+
+	kfree(ov);
+}
+
+static struct kobj_type of_overlay_ktype = {
+	.release = of_overlay_release,
+};
+
+static struct kset *ov_kset;
+
 /**
  * of_overlay_create() - Create and apply an overlay
  * @tree:	Device node containing all the overlays
@@ -351,6 +371,9 @@ int of_overlay_create(struct device_node *tree)
 
 	of_changeset_init(&ov->cset);
 
+	/* initialize kobject */
+	kobject_init(&ov->kobj, &of_overlay_ktype);
+
 	mutex_lock(&of_mutex);
 
 	id = idr_alloc(&ov_idr, ov, 0, 0, GFP_KERNEL);
@@ -386,6 +409,14 @@ int of_overlay_create(struct device_node *tree)
 		goto err_revert_overlay;
 	}
 
+	ov->kobj.kset = ov_kset;
+	err = kobject_add(&ov->kobj, NULL, "%d", id);
+	if (err != 0) {
+		pr_err("%s: kobject_add() failed for tree@%s\n",
+				__func__, tree->full_name);
+		goto err_cancel_overlay;
+	}
+
 	/* add to the tail of the overlay list */
 	list_add_tail(&ov->node, &ov_list);
 
@@ -393,6 +424,8 @@ int of_overlay_create(struct device_node *tree)
 
 	return id;
 
+err_cancel_overlay:
+	of_changeset_revert(&ov->cset);
 err_revert_overlay:
 err_abort_trans:
 	of_free_overlay_info(ov);
@@ -515,7 +548,8 @@ int of_overlay_destroy(int id)
 	of_free_overlay_info(ov);
 	idr_remove(&ov_idr, id);
 	of_changeset_destroy(&ov->cset);
-	kfree(ov);
+
+	kobject_put(&ov->kobj);
 
 	err = 0;
 
@@ -545,7 +579,7 @@ int of_overlay_destroy_all(void)
 		__of_changeset_revert(&ov->cset);
 		of_free_overlay_info(ov);
 		idr_remove(&ov_idr, ov->id);
-		kfree(ov);
+		kobject_put(&ov->kobj);
 	}
 
 	mutex_unlock(&of_mutex);
@@ -553,3 +587,15 @@ int of_overlay_destroy_all(void)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(of_overlay_destroy_all);
+
+/* called from of_init() */
+int of_overlay_init(void)
+{
+	int rc;
+
+	ov_kset = kset_create_and_add("overlays", NULL, &of_kset->kobj);
+	if (!ov_kset)
+		return -ENOMEM;
+
+	return 0;
+}
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v8 2/6] of: overlay: global sysfs enable attribute
  2016-05-09 13:09 [PATCH v8 0/6] of: overlay: kobject & sysfs'ation Pantelis Antoniou
  2016-05-09 13:09 ` [PATCH v8 1/6] of: overlay: kobjectify overlay objects Pantelis Antoniou
@ 2016-05-09 13:09 ` Pantelis Antoniou
  2016-05-09 13:10 ` [PATCH v8 3/6] Documentation: ABI: overlays - global attributes Pantelis Antoniou
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Pantelis Antoniou @ 2016-05-09 13:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Frank Rowand, Matt Porter, Koen Kooi, Guenter Roeck,
	Greg Kroah-Hartman, devicetree, linux-kernel, linux-api,
	Pantelis Antoniou, Pantelis Antoniou

A throw once master enable switch to protect against any
further overlay applications if the administrator desires so.

A kernel command line option is provided as well.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/of/overlay.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 4e06c34..47e8d3a 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -21,6 +21,7 @@
 #include <linux/err.h>
 #include <linux/idr.h>
 #include <linux/sysfs.h>
+#include <linux/atomic.h>
 
 #include "of_private.h"
 
@@ -55,8 +56,19 @@ struct of_overlay {
 	struct kobject kobj;
 };
 
+/* master enable switch; once set to 0 can't be re-enabled */
+static atomic_t ov_enable = ATOMIC_INIT(1);
+
+static int __init of_overlay_disable_setup(char *str __always_unused)
+{
+	atomic_set(&ov_enable, 0);
+	return 1;
+}
+__setup("of_overlay_disable", of_overlay_disable_setup);
+
 static int of_overlay_apply_one(struct of_overlay *ov,
 		struct device_node *target, const struct device_node *overlay);
+static int overlay_removal_is_ok(struct of_overlay *ov);
 
 static int of_overlay_apply_single_property(struct of_overlay *ov,
 		struct device_node *target, struct property *prop)
@@ -340,6 +352,35 @@ void of_overlay_release(struct kobject *kobj)
 	kfree(ov);
 }
 
+static ssize_t enable_show(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&ov_enable));
+}
+
+static ssize_t enable_store(struct kobject *kobj,
+		struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	int ret;
+	bool new_enable;
+
+	ret = strtobool(buf, &new_enable);
+	if (ret != 0)
+		return ret;
+	/* if we've disabled it, no going back */
+	if (atomic_read(&ov_enable) == 0)
+		return -EPERM;
+	atomic_set(&ov_enable, (int)new_enable);
+	return count;
+}
+
+static struct kobj_attribute enable_attr = __ATTR_RW(enable);
+
+static const struct attribute *overlay_global_attrs[] = {
+	&enable_attr.attr,
+	NULL
+};
+
 static struct kobj_type of_overlay_ktype = {
 	.release = of_overlay_release,
 };
@@ -361,6 +402,10 @@ int of_overlay_create(struct device_node *tree)
 	struct of_overlay *ov;
 	int err, id;
 
+	/* administratively disabled */
+	if (!atomic_read(&ov_enable))
+		return -EPERM;
+
 	/* allocate the overlay structure */
 	ov = kzalloc(sizeof(*ov), GFP_KERNEL);
 	if (ov == NULL)
@@ -597,5 +642,8 @@ int of_overlay_init(void)
 	if (!ov_kset)
 		return -ENOMEM;
 
-	return 0;
+	rc = sysfs_create_files(&ov_kset->kobj, overlay_global_attrs);
+	WARN(rc, "%s: error adding global attributes\n", __func__);
+
+	return rc;
 }
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v8 3/6] Documentation: ABI: overlays - global attributes
  2016-05-09 13:09 [PATCH v8 0/6] of: overlay: kobject & sysfs'ation Pantelis Antoniou
  2016-05-09 13:09 ` [PATCH v8 1/6] of: overlay: kobjectify overlay objects Pantelis Antoniou
  2016-05-09 13:09 ` [PATCH v8 2/6] of: overlay: global sysfs enable attribute Pantelis Antoniou
@ 2016-05-09 13:10 ` Pantelis Antoniou
       [not found] ` <1462799403-10083-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Pantelis Antoniou @ 2016-05-09 13:10 UTC (permalink / raw)
  To: Rob Herring
  Cc: Frank Rowand, Matt Porter, Koen Kooi, Guenter Roeck,
	Greg Kroah-Hartman, devicetree, linux-kernel, linux-api,
	Pantelis Antoniou, Pantelis Antoniou

Documentation ABI entry for overlays sysfs entries.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 .../ABI/testing/sysfs-firmware-devicetree-overlays | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-devicetree-overlays

diff --git a/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
new file mode 100644
index 0000000..e938f44
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
@@ -0,0 +1,24 @@
+What:		/sys/firmware/devicetree/overlays/
+Date:		October 2015
+Contact:	Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+Description:
+		This directory contains the applied device tree overlays of
+		the running system, as directories of the overlay id.
+
+What:		/sys/firmware/devicetree/overlays/enable
+Date:		October 2015
+Contact:	Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+Description:
+		The master enable switch, by default is 1, and when
+		set to 0 it cannot be re-enabled for security reasons.
+
+		The discussion about this switch takes place in:
+		http://comments.gmane.org/gmane.linux.drivers.devicetree/101871
+
+		Kees Cook:
+		"Coming from the perspective of drawing a bright line between
+		kernel and the root user (which tends to start with disabling
+		kernel module loading), I would say that there at least needs
+		to be a high-level one-way "off" switch for the interface so
+		that systems that have this interface can choose to turn it off
+		during initial boot, etc."
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v8 4/6] Documentation: document of_overlay_disable parameter
       [not found] ` <1462799403-10083-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
@ 2016-05-09 13:10   ` Pantelis Antoniou
  0 siblings, 0 replies; 7+ messages in thread
From: Pantelis Antoniou @ 2016-05-09 13:10 UTC (permalink / raw)
  To: Rob Herring
  Cc: Frank Rowand, Matt Porter, Koen Kooi, Guenter Roeck,
	Greg Kroah-Hartman, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Pantelis Antoniou,
	Pantelis Antoniou

Document the of_overlay_disable parameter.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
Acked-by: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>
---
 Documentation/kernel-parameters.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 0b3de80..cc8d434 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -90,6 +90,7 @@ parameter is applicable:
 	NET	Appropriate network support is enabled.
 	NUMA	NUMA support is enabled.
 	NFS	Appropriate NFS support is enabled.
+	OF	Open Firmware support (device tree) is enabled.
 	OSS	OSS sound support is enabled.
 	PV_OPS	A paravirtualized kernel is enabled.
 	PARIDE	The ParIDE (parallel port IDE) subsystem is enabled.
@@ -2715,6 +2716,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			This can be set from sysctl after boot.
 			See Documentation/sysctl/vm.txt for details.
 
+	of_overlay_disable	[OF] Disable device tree overlays at boot time.
+
 	ohci1394_dma=early	[HW] enable debugging via the ohci1394 driver.
 			See Documentation/debugging-via-ohci1394.txt for more
 			info.
-- 
1.7.12

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v8 5/6] of: overlay: add per overlay sysfs attributes
  2016-05-09 13:09 [PATCH v8 0/6] of: overlay: kobject & sysfs'ation Pantelis Antoniou
                   ` (3 preceding siblings ...)
       [not found] ` <1462799403-10083-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
@ 2016-05-09 13:10 ` Pantelis Antoniou
  2016-05-09 13:10 ` [PATCH v8 6/6] Documentation: ABI: overlays - per overlay docs Pantelis Antoniou
  5 siblings, 0 replies; 7+ messages in thread
From: Pantelis Antoniou @ 2016-05-09 13:10 UTC (permalink / raw)
  To: Rob Herring
  Cc: Frank Rowand, Matt Porter, Koen Kooi, Guenter Roeck,
	Greg Kroah-Hartman, devicetree, linux-kernel, linux-api,
	Pantelis Antoniou, Pantelis Antoniou

* A per overlay can_remove sysfs attribute that reports whether
the overlay can be removed or not due to another overlapping overlay.

* A target sysfs attribute listing the target of each fragment,
in a group named after the name of the fragment.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/of/overlay.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 99 insertions(+), 4 deletions(-)

diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 47e8d3a..fdfc487 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -25,8 +25,23 @@
 
 #include "of_private.h"
 
+/* fwd. decl */
+struct of_overlay;
+struct of_overlay_info;
+
+/* an attribute for each fragment */
+struct fragment_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct kobject *kobj, struct fragment_attribute *fattr,
+			char *buf);
+	ssize_t (*store)(struct kobject *kobj, struct fragment_attribute *fattr,
+			 const char *buf, size_t count);
+	struct of_overlay_info *ovinfo;
+};
+
 /**
  * struct of_overlay_info - Holds a single overlay info
+ * @info:	info node that contains the target and overlay
  * @target:	target of the overlay operation
  * @overlay:	pointer to the overlay contents node
  *
@@ -34,8 +49,13 @@
  * records.
  */
 struct of_overlay_info {
+	struct of_overlay *ov;
+	struct device_node *info;
 	struct device_node *target;
 	struct device_node *overlay;
+	struct attribute_group attr_group;
+	struct attribute *attrs[2];
+	struct fragment_attribute target_attr;
 };
 
 /**
@@ -52,6 +72,7 @@ struct of_overlay {
 	struct list_head node;
 	int count;
 	struct of_overlay_info *ovinfo_tab;
+	const struct attribute_group **attr_groups;
 	struct of_changeset cset;
 	struct kobject kobj;
 };
@@ -253,6 +274,8 @@ static int of_fill_overlay_info(struct of_overlay *ov,
 	if (ovinfo->target == NULL)
 		goto err_fail;
 
+	ovinfo->info = of_node_get(info_node);
+
 	return 0;
 
 err_fail:
@@ -263,6 +286,17 @@ err_fail:
 	return -EINVAL;
 }
 
+static ssize_t target_show(struct kobject *kobj,
+		struct fragment_attribute *fattr, char *buf)
+{
+	struct of_overlay_info *ovinfo = fattr->ovinfo;
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			of_node_full_name(ovinfo->target));
+}
+
+static const struct fragment_attribute target_template_attr = __ATTR_RO(target);
+
 /**
  * of_build_overlay_info() - Build an overlay info array
  * @ov		Overlay to build
@@ -280,7 +314,7 @@ static int of_build_overlay_info(struct of_overlay *ov,
 {
 	struct device_node *node;
 	struct of_overlay_info *ovinfo;
-	int cnt, err;
+	int i, cnt, err;
 
 	/* worst case; every child is a node */
 	cnt = 0;
@@ -301,14 +335,45 @@ static int of_build_overlay_info(struct of_overlay *ov,
 
 	/* if nothing filled, return error */
 	if (cnt == 0) {
-		kfree(ovinfo);
-		return -ENODEV;
+		err = -ENODEV;
+		goto err_free_ovinfo;
 	}
 
 	ov->count = cnt;
 	ov->ovinfo_tab = ovinfo;
 
+	ov->attr_groups = kcalloc(cnt + 1,
+			sizeof(struct attribute_group *), GFP_KERNEL);
+	if (ov->attr_groups == NULL) {
+		err = -ENOMEM;
+		goto err_free_ovinfo;
+	}
+
+	for (i = 0; i < cnt; i++) {
+		ovinfo = &ov->ovinfo_tab[i];
+
+		ov->attr_groups[i] = &ovinfo->attr_group;
+
+		ovinfo->target_attr = target_template_attr;
+		/* make lockdep happy */
+		sysfs_attr_init(&ovinfo->target_attr.attr);
+		ovinfo->target_attr.ovinfo = ovinfo;
+
+		ovinfo->attrs[0] = &ovinfo->target_attr.attr;
+		ovinfo->attrs[1] = NULL;
+
+		/* NOTE: direct reference to the full_name */
+		ovinfo->attr_group.name = kbasename(ovinfo->info->full_name);
+		ovinfo->attr_group.attrs = ovinfo->attrs;
+
+	}
+	ov->attr_groups[i] = NULL;
+
 	return 0;
+
+err_free_ovinfo:
+	kfree(ovinfo);
+	return err;
 }
 
 /**
@@ -325,12 +390,16 @@ static int of_free_overlay_info(struct of_overlay *ov)
 	struct of_overlay_info *ovinfo;
 	int i;
 
+	/* free attribute groups space */
+	kfree(ov->attr_groups);
+
 	/* do it in reverse */
 	for (i = ov->count - 1; i >= 0; i--) {
 		ovinfo = &ov->ovinfo_tab[i];
 
 		of_node_put(ovinfo->target);
 		of_node_put(ovinfo->overlay);
+		of_node_put(ovinfo->info);
 	}
 	kfree(ov->ovinfo_tab);
 
@@ -381,8 +450,25 @@ static const struct attribute *overlay_global_attrs[] = {
 	NULL
 };
 
+static ssize_t can_remove_show(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
+{
+	struct of_overlay *ov = kobj_to_overlay(kobj);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", overlay_removal_is_ok(ov));
+}
+
+static struct kobj_attribute can_remove_attr = __ATTR_RO(can_remove);
+
+static struct attribute *overlay_attrs[] = {
+	&can_remove_attr.attr,
+	NULL
+};
+
 static struct kobj_type of_overlay_ktype = {
 	.release = of_overlay_release,
+	.sysfs_ops = &kobj_sysfs_ops,	/* default kobj sysfs ops */
+	.default_attrs = overlay_attrs,
 };
 
 static struct kset *ov_kset;
@@ -462,13 +548,21 @@ int of_overlay_create(struct device_node *tree)
 		goto err_cancel_overlay;
 	}
 
+	err = sysfs_create_groups(&ov->kobj, ov->attr_groups);
+	if (err != 0) {
+		pr_err("%s: sysfs_create_groups() failed for tree@%s\n",
+				__func__, tree->full_name);
+		goto err_remove_kobj;
+	}
+
 	/* add to the tail of the overlay list */
 	list_add_tail(&ov->node, &ov_list);
 
 	mutex_unlock(&of_mutex);
 
 	return id;
-
+err_remove_kobj:
+	kobject_put(&ov->kobj);
 err_cancel_overlay:
 	of_changeset_revert(&ov->cset);
 err_revert_overlay:
@@ -589,6 +683,7 @@ int of_overlay_destroy(int id)
 
 
 	list_del(&ov->node);
+	sysfs_remove_groups(&ov->kobj, ov->attr_groups);
 	__of_changeset_revert(&ov->cset);
 	of_free_overlay_info(ov);
 	idr_remove(&ov_idr, id);
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v8 6/6] Documentation: ABI: overlays - per overlay docs
  2016-05-09 13:09 [PATCH v8 0/6] of: overlay: kobject & sysfs'ation Pantelis Antoniou
                   ` (4 preceding siblings ...)
  2016-05-09 13:10 ` [PATCH v8 5/6] of: overlay: add per overlay sysfs attributes Pantelis Antoniou
@ 2016-05-09 13:10 ` Pantelis Antoniou
  5 siblings, 0 replies; 7+ messages in thread
From: Pantelis Antoniou @ 2016-05-09 13:10 UTC (permalink / raw)
  To: Rob Herring
  Cc: Frank Rowand, Matt Porter, Koen Kooi, Guenter Roeck,
	Greg Kroah-Hartman, devicetree, linux-kernel, linux-api,
	Pantelis Antoniou, Pantelis Antoniou

Documentation for the per-overlay attributes.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 .../ABI/testing/sysfs-firmware-devicetree-overlays | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
index e938f44..88d1549 100644
--- a/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
+++ b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
@@ -22,3 +22,31 @@ Description:
 		to be a high-level one-way "off" switch for the interface so
 		that systems that have this interface can choose to turn it off
 		during initial boot, etc."
+
+What:		/sys/firmware/devicetree/overlays/<id>
+Date:		October 2015
+Contact:	Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+Description:
+		Each directory represents an applied overlay, containing
+		the following attribute files.
+
+What:		/sys/firmware/devicetree/overlays/<id>/can_remove
+Date:		October 2015
+Contact:	Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+Description:
+		The attribute set to 1 means that the overlay can be removed,
+		while 0 means that the overlay is being overlapped therefore
+		removal is prohibited.
+
+What:		/sys/firmware/devicetree/overlays/<id>/<fragment-name>/
+Date:		October 2015
+Contact:	Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+Description:
+		Each of these directories contain information about of the
+		particular overlay fragment.
+
+What:		/sys/firmware/devicetree/overlays/<id>/<fragment-name>/target
+Date:		October 2015
+Contact:	Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+Description:
+		The full-path of the target of the fragment
-- 
1.7.12

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-05-09 13:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-09 13:09 [PATCH v8 0/6] of: overlay: kobject & sysfs'ation Pantelis Antoniou
2016-05-09 13:09 ` [PATCH v8 1/6] of: overlay: kobjectify overlay objects Pantelis Antoniou
2016-05-09 13:09 ` [PATCH v8 2/6] of: overlay: global sysfs enable attribute Pantelis Antoniou
2016-05-09 13:10 ` [PATCH v8 3/6] Documentation: ABI: overlays - global attributes Pantelis Antoniou
     [not found] ` <1462799403-10083-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
2016-05-09 13:10   ` [PATCH v8 4/6] Documentation: document of_overlay_disable parameter Pantelis Antoniou
2016-05-09 13:10 ` [PATCH v8 5/6] of: overlay: add per overlay sysfs attributes Pantelis Antoniou
2016-05-09 13:10 ` [PATCH v8 6/6] Documentation: ABI: overlays - per overlay docs Pantelis Antoniou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).