summaryrefslogtreecommitdiff
path: root/recipes-kernel/linux/linux-at91-4.9.87/v5-3-9-OF-DT-Overlay-configfs-interface.diff
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-at91-4.9.87/v5-3-9-OF-DT-Overlay-configfs-interface.diff')
-rw-r--r--recipes-kernel/linux/linux-at91-4.9.87/v5-3-9-OF-DT-Overlay-configfs-interface.diff287
1 files changed, 287 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-at91-4.9.87/v5-3-9-OF-DT-Overlay-configfs-interface.diff b/recipes-kernel/linux/linux-at91-4.9.87/v5-3-9-OF-DT-Overlay-configfs-interface.diff
new file mode 100644
index 0000000..619b888
--- /dev/null
+++ b/recipes-kernel/linux/linux-at91-4.9.87/v5-3-9-OF-DT-Overlay-configfs-interface.diff
@@ -0,0 +1,287 @@
+Patch from:
+https://lore.kernel.org/patchwork/patch/468129/
+
+This patch will not compile with the 4.9.87 kernel.
+
+ConfigFS overlay
+==================================================================================
+diff -aNru linux-4.9.87.orig/drivers/of/Kconfig linux-4.9.87/drivers/of/Kconfig
+--- linux-4.9.87.orig/drivers/of/Kconfig 2018-12-05 10:47:45.348494186 -0600
++++ linux-4.9.87/drivers/of/Kconfig 2018-12-05 11:05:10.272463251 -0600
+@@ -112,4 +112,11 @@
+ config OF_NUMA
+ bool
+
++config OF_CONFIGFS
++ bool "OpenFirmware Overlay ConfigFS interface"
++ select CONFIGFS_FS
++ select OF_OVERLAY
++ help
++ Enable a simple user-space driver DT overlay interface.
++
+ endif # OF
+diff -aNru linux-4.9.87.orig/drivers/of/Makefile linux-4.9.87/drivers/of/Makefile
+--- linux-4.9.87.orig/drivers/of/Makefile 2018-12-05 10:48:27.836492928 -0600
++++ linux-4.9.87/drivers/of/Makefile 2018-12-05 11:05:57.668461848 -0600
+@@ -14,5 +14,6 @@
+ obj-$(CONFIG_OF_RESOLVE) += resolver.o
+ obj-$(CONFIG_OF_OVERLAY) += overlay.o
+ obj-$(CONFIG_OF_NUMA) += of_numa.o
++obj-$(CONFIG_OF_CONFIGFS) += configfs.o
+
+ obj-$(CONFIG_OF_UNITTEST) += unittest-data/
+diff -aNru linux-4.9.87.orig/drivers/of/configfs.c linux-4.9.87/drivers/of/configfs.c
+--- linux-4.9.87.orig/drivers/of/configfs.c 1969-12-31 18:00:00.000000000 -0600
++++ linux-4.9.87/drivers/of/configfs.c 2018-12-05 10:58:59.056474241 -0600
+@@ -0,0 +1,251 @@
++/*
++ * Configfs entries for device-tree
++ *
++ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <linux/ctype.h>
++#include <linux/cpu.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_fdt.h>
++#include <linux/spinlock.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/configfs.h>
++#include <linux/types.h>
++#include <linux/stat.h>
++#include <linux/limits.h>
++#include <linux/file.h>
++#include <linux/vmalloc.h>
++#include <linux/firmware.h>
++
++#include "of_private.h"
++
++#ifdef CONFIG_OF_OVERLAY
++
++struct cfs_overlay_item {
++ struct config_item item;
++
++ char path[PATH_MAX];
++
++ const struct firmware *fw;
++ struct device_node *overlay;
++ int ov_id;
++};
++
++static inline struct cfs_overlay_item *to_cfs_overlay_item(
++ struct config_item *item)
++{
++ return item ? container_of(item, struct cfs_overlay_item, item) : NULL;
++}
++
++CONFIGFS_ATTR_STRUCT(cfs_overlay_item);
++#define CFS_OVERLAY_ITEM_ATTR(_name, _mode, _show, _store) \
++struct cfs_overlay_item_attribute cfs_overlay_item_attr_##_name = \
++ __CONFIGFS_ATTR(_name, _mode, _show, _store)
++#define CFS_OVERLAY_ITEM_ATTR_RO(_name, _show) \
++struct cfs_overlay_item_attribute cfs_overlay_item_attr_##_name = \
++ __CONFIGFS_ATTR_RO(_name, _show)
++
++static ssize_t cfs_overlay_item_path_show(struct cfs_overlay_item *overlay,
++ char *page)
++{
++ return sprintf(page, "%s\n", overlay->path);
++}
++
++static ssize_t cfs_overlay_item_path_store(struct cfs_overlay_item *overlay,
++ const char *page, size_t count)
++{
++ const char *p = page;
++ char *s;
++ int err;
++
++ /* if it's set do not allow changes */
++ if (overlay->path[0] != '\0')
++ return -EPERM;
++
++ /* copy to path buffer (and make sure it's always zero terminated */
++ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p);
++ overlay->path[sizeof(overlay->path) - 1] = '\0';
++
++ /* strip trailing newlines */
++ s = overlay->path + strlen(overlay->path);
++ while (s > overlay->path && *--s == '\n')
++ *s = '\0';
++
++ pr_debug("%s: path is '%s'\n", __func__, overlay->path);
++
++ err = request_firmware(&overlay->fw, overlay->path, NULL);
++ if (err != 0)
++ goto out_err;
++
++ /* unflatten the tree */
++ of_fdt_unflatten_tree((void *)overlay->fw->data, &overlay->overlay);
++ if (overlay->overlay == NULL) {
++ pr_err("%s: failed to unflatten tree\n", __func__);
++ err = -EINVAL;
++ goto out_err;
++ }
++ pr_debug("%s: unflattened OK\n", __func__);
++
++ /* mark it as detached */
++ of_node_set_flag(overlay->overlay, OF_DETACHED);
++
++ /* perform resolution */
++ err = of_resolve(overlay->overlay);
++ if (err != 0) {
++ pr_err("%s: Failed to resolve tree\n", __func__);
++ goto out_err;
++ }
++ pr_debug("%s: resolved OK\n", __func__);
++
++ err = of_overlay_create(overlay->overlay);
++ if (err < 0) {
++ pr_err("%s: Failed to create overlay (err=%d)\n",
++ __func__, err);
++ goto out_err;
++ }
++ overlay->ov_id = err;
++
++ return count;
++
++out_err:
++
++ release_firmware(overlay->fw);
++ overlay->fw = NULL;
++
++ overlay->path[0] = '\0';
++ return err;
++}
++
++static ssize_t cfs_overlay_item_status_show(struct cfs_overlay_item *overlay,
++ char *page)
++{
++ return sprintf(page, "%s\n",
++ overlay->ov_id >= 0 ? "applied" : "unapplied");
++}
++
++CFS_OVERLAY_ITEM_ATTR(path, S_IRUGO | S_IWUSR,
++ cfs_overlay_item_path_show, cfs_overlay_item_path_store);
++CFS_OVERLAY_ITEM_ATTR_RO(status, cfs_overlay_item_status_show);
++
++static struct configfs_attribute *cfs_overlay_attrs[] = {
++ &cfs_overlay_item_attr_path.attr,
++ &cfs_overlay_item_attr_status.attr,
++ NULL,
++};
++
++static void cfs_overlay_release(struct config_item *item)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++
++ if (overlay->ov_id >= 0)
++ of_overlay_destroy(overlay->ov_id);
++ if (overlay->fw)
++ release_firmware(overlay->fw);
++ kfree(overlay);
++}
++
++CONFIGFS_ATTR_OPS(cfs_overlay_item);
++static struct configfs_item_operations cfs_overlay_item_ops = {
++ .release = cfs_overlay_release,
++ .show_attribute = cfs_overlay_item_attr_show,
++ .store_attribute = cfs_overlay_item_attr_store,
++};
++
++static struct config_item_type cfs_overlay_type = {
++ .ct_item_ops = &cfs_overlay_item_ops,
++ .ct_attrs = cfs_overlay_attrs,
++ .ct_owner = THIS_MODULE,
++};
++
++static struct config_item *cfs_overlay_group_make_item(
++ struct config_group *group, const char *name)
++{
++ struct cfs_overlay_item *overlay;
++
++ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
++ if (!overlay)
++ return ERR_PTR(-ENOMEM);
++ overlay->ov_id = -1;
++
++ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type);
++ return &overlay->item;
++}
++
++static void cfs_overlay_group_drop_item(struct config_group *group,
++ struct config_item *item)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++
++ config_item_put(&overlay->item);
++}
++
++static struct configfs_group_operations overlays_ops = {
++ .make_item = cfs_overlay_group_make_item,
++ .drop_item = cfs_overlay_group_drop_item,
++};
++
++static struct config_item_type overlays_type = {
++ .ct_group_ops = &overlays_ops,
++ .ct_owner = THIS_MODULE,
++};
++
++#endif /* CONFIG_OF_OVERLAY */
++
++static struct configfs_group_operations of_cfs_ops = {
++ /* empty - we don't allow anything to be created */
++};
++
++static struct config_item_type of_cfs_type = {
++ .ct_group_ops = &of_cfs_ops,
++ .ct_owner = THIS_MODULE,
++};
++
++struct config_group of_cfs_overlay_group;
++
++struct config_group *of_cfs_def_groups[] = {
++#ifdef CONFIG_OF_OVERLAY
++ &of_cfs_overlay_group,
++#endif
++ NULL
++};
++
++static struct configfs_subsystem of_cfs_subsys = {
++ .su_group = {
++ .cg_item = {
++ .ci_namebuf = "device-tree",
++ .ci_type = &of_cfs_type,
++ },
++ .default_groups = of_cfs_def_groups,
++ },
++ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex),
++};
++
++static int __init of_cfs_init(void)
++{
++ int ret;
++
++ pr_info("%s\n", __func__);
++
++ config_group_init(&of_cfs_subsys.su_group);
++#ifdef CONFIG_OF_OVERLAY
++ config_group_init_type_name(&of_cfs_overlay_group, "overlays",
++ &overlays_type);
++#endif
++
++ ret = configfs_register_subsystem(&of_cfs_subsys);
++ if (ret != 0) {
++ pr_err("%s: failed to register subsys\n", __func__);
++ goto out;
++ }
++ pr_info("%s: OK\n", __func__);
++out:
++ return ret;
++}
++late_initcall(of_cfs_init);