From b64d1bd787597dd35dd5b5b3b95f9f817d4bd95f Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Fri, 7 Sep 2018 17:09:49 -0400 Subject: [PATCH] enable configfs support and overlays --- .../add-overlay-compilation-support.patch | 125 +++++++ .../add_configfs_overlay_for_v4.18.x.patch | 326 ++++++++++++++++++ 2 files changed, 451 insertions(+) create mode 100644 patch/kernel/sunxi-dev-h6/add-overlay-compilation-support.patch create mode 100644 patch/kernel/sunxi-dev-h6/add_configfs_overlay_for_v4.18.x.patch diff --git a/patch/kernel/sunxi-dev-h6/add-overlay-compilation-support.patch b/patch/kernel/sunxi-dev-h6/add-overlay-compilation-support.patch new file mode 100644 index 000000000..df39dc883 --- /dev/null +++ b/patch/kernel/sunxi-dev-h6/add-overlay-compilation-support.patch @@ -0,0 +1,125 @@ +diff --git a/arch/arm/Makefile b/arch/arm/Makefile +index 65f4e2a4..9eb2043c 100644 +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -339,6 +339,12 @@ $(INSTALL_TARGETS): + %.dtb: | scripts + $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ + ++%.dtbo: | scripts ++ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ ++ ++%.scr: | scripts ++ $(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@ ++ + PHONY += dtbs dtbs_install + + dtbs: prepare scripts +diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore +index 3c79f859..4e5c1d59 100644 +--- a/arch/arm/boot/.gitignore ++++ b/arch/arm/boot/.gitignore +@@ -3,3 +3,5 @@ zImage + xipImage + bootpImage + uImage ++*.dtb* ++*.scr +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index f839ecd9..9788f16d 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -121,6 +121,12 @@ zinstall install: + %.dtb: scripts + $(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@ + ++%.dtbo: | scripts ++ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ ++ ++%.scr: | scripts ++ $(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@ ++ + PHONY += dtbs dtbs_install + + dtbs: prepare scripts +diff --git a/arch/arm64/boot/dts/.gitignore b/arch/arm64/boot/dts/.gitignore +index b60ed208..4bec63b6 100644 +--- a/arch/arm64/boot/dts/.gitignore ++++ b/arch/arm64/boot/dts/.gitignore +@@ -0,0 +1,2 @@ ++*.dtb* ++*.scr +diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst +index 34614a48..8a8313d6 100644 +--- a/scripts/Makefile.dtbinst ++++ b/scripts/Makefile.dtbinst +@@ -20,6 +20,9 @@ include scripts/Kbuild.include + include $(src)/Makefile + + dtbinst-files := $(sort $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS), $(dtb-))) ++dtboinst-files := $(dtbo-y) ++script-files := $(scr-y) ++readme-files := $(dtbotxt-y) + dtbinst-dirs := $(subdir-y) $(subdir-m) + + # Helper targets for Installing DTBs into the boot directory +@@ -31,10 +34,19 @@ install-dir = $(patsubst $(dtbinst_root)%,$(INSTALL_DTBS_PATH)%,$(obj)) + $(dtbinst-files): %.dtb: $(obj)/%.dtb + $(call cmd,dtb_install,$(install-dir)) + ++$(dtboinst-files): %.dtbo: $(obj)/%.dtbo ++ $(call cmd,dtb_install,$(install-dir)) ++ ++$(script-files): %.scr: $(obj)/%.scr ++ $(call cmd,dtb_install,$(install-dir)) ++ ++$(readme-files): %: $(src)/% ++ $(call cmd,dtb_install,$(install-dir)) ++ + $(dtbinst-dirs): + $(Q)$(MAKE) $(dtbinst)=$(obj)/$@ + +-PHONY += $(dtbinst-files) $(dtbinst-dirs) +-__dtbs_install: $(dtbinst-files) $(dtbinst-dirs) ++PHONY += $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs) ++__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs) + + .PHONY: $(PHONY) +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index 58c05e5d..2b95dda9 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -278,6 +278,9 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \ + # --------------------------------------------------------------------------- + DTC ?= $(objtree)/scripts/dtc/dtc + ++# Overlay support ++DTC_FLAGS += -@ -Wno-unit_address_format -Wno-simple_bus_reg ++ + # Disable noisy checks by default + ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),) + DTC_FLAGS += -Wno-unit_address_vs_reg \ +@@ -324,6 +327,23 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ + $(obj)/%.dtb: $(src)/%.dts FORCE + $(call if_changed_dep,dtc) + ++quiet_cmd_dtco = DTCO $@ ++cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ; \ ++ $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ ++ $(DTC) -O dtb -o $@ -b 0 \ ++ -i $(dir $<) $(DTC_FLAGS) \ ++ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ ++ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) ++ ++$(obj)/%.dtbo: $(src)/%.dts FORCE ++ $(call if_changed_dep,dtco) ++ ++quiet_cmd_scr = MKIMAGE $@ ++cmd_scr = mkimage -C none -A $(ARCH) -T script -d $< $@ ++ ++$(obj)/%.scr: $(src)/%.scr-cmd FORCE ++ $(call if_changed,scr) ++ + dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) + + # Bzip2 diff --git a/patch/kernel/sunxi-dev-h6/add_configfs_overlay_for_v4.18.x.patch b/patch/kernel/sunxi-dev-h6/add_configfs_overlay_for_v4.18.x.patch new file mode 100644 index 000000000..5868c2741 --- /dev/null +++ b/patch/kernel/sunxi-dev-h6/add_configfs_overlay_for_v4.18.x.patch @@ -0,0 +1,326 @@ +diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig +index bc07ad3..e9da9cf 100644 +--- a/drivers/of/Kconfig ++++ b/drivers/of/Kconfig +@@ -113,6 +113,13 @@ config OF_OVERLAY + While this option is selected automatically when needed, you can + enable it manually to improve device tree unit test coverage. + ++config OF_CONFIGFS ++ bool "Device Tree Overlay ConfigFS interface" ++ select CONFIGFS_FS ++ depends on OF_OVERLAY ++ help ++ Enable a simple user-space driven DT overlay interface. ++ + config OF_NUMA + bool + +diff --git a/drivers/of/Makefile b/drivers/of/Makefile +index d7efd9d..a06cc35 100644 +--- a/drivers/of/Makefile ++++ b/drivers/of/Makefile +@@ -13,6 +13,7 @@ obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o + obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o + obj-$(CONFIG_OF_RESOLVE) += resolver.o + obj-$(CONFIG_OF_OVERLAY) += overlay.o ++obj-$(CONFIG_OF_CONFIGFS) += configfs.o + obj-$(CONFIG_OF_NUMA) += of_numa.o + + obj-$(CONFIG_OF_UNITTEST) += unittest-data/ +diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c +new file mode 100644 +index 0000000..68f889d +--- /dev/null ++++ b/drivers/of/configfs.c +@@ -0,0 +1,277 @@ ++/* ++ * Configfs entries for device-tree ++ * ++ * Copyright (C) 2013 - Pantelis Antoniou ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "of_private.h" ++ ++struct cfs_overlay_item { ++ struct config_item item; ++ ++ char path[PATH_MAX]; ++ ++ const struct firmware *fw; ++ struct device_node *overlay; ++ int ov_id; ++ ++ void *dtbo; ++ int dtbo_size; ++}; ++ ++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; ++} ++ ++static ssize_t cfs_overlay_item_path_show(struct config_item *item, ++ char *page) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ return sprintf(page, "%s\n", overlay->path); ++} ++ ++static ssize_t cfs_overlay_item_path_store(struct config_item *item, ++ const char *page, size_t count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ const char *p = page; ++ char *s; ++ int err; ++ ++ /* if it's set do not allow changes */ ++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 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; ++ ++ err = of_overlay_fdt_apply((void *)overlay->fw->data, ++ (u32)overlay->fw->size, &overlay->ov_id); ++ if (err != 0) ++ goto out_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 config_item *item, ++ char *page) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ return sprintf(page, "%s\n", ++ overlay->ov_id > 0 ? "applied" : "unapplied"); ++} ++ ++CONFIGFS_ATTR(cfs_overlay_item_, path); ++CONFIGFS_ATTR_RO(cfs_overlay_item_, status); ++ ++static struct configfs_attribute *cfs_overlay_attrs[] = { ++ &cfs_overlay_item_attr_path, ++ &cfs_overlay_item_attr_status, ++ NULL, ++}; ++ ++ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, ++ void *buf, size_t max_count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ pr_debug("%s: buf=%p max_count=%zu\n", __func__, ++ buf, max_count); ++ ++ if (overlay->dtbo == NULL) ++ return 0; ++ ++ /* copy if buffer provided */ ++ if (buf != NULL) { ++ /* the buffer must be large enough */ ++ if (overlay->dtbo_size > max_count) ++ return -ENOSPC; ++ ++ memcpy(buf, overlay->dtbo, overlay->dtbo_size); ++ } ++ ++ return overlay->dtbo_size; ++} ++ ++ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, ++ const void *buf, size_t count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ int err; ++ ++ /* if it's set do not allow changes */ ++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) ++ return -EPERM; ++ ++ /* copy the contents */ ++ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); ++ if (overlay->dtbo == NULL) ++ return -ENOMEM; ++ ++ overlay->dtbo_size = count; ++ ++ err = of_overlay_fdt_apply(overlay->dtbo, overlay->dtbo_size, ++ &overlay->ov_id); ++ if (err != 0) ++ goto out_err; ++ ++ return count; ++ ++out_err: ++ kfree(overlay->dtbo); ++ overlay->dtbo = NULL; ++ overlay->dtbo_size = 0; ++ overlay->ov_id = 0; ++ ++ return err; ++} ++ ++CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); ++ ++static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { ++ &cfs_overlay_item_attr_dtbo, ++ 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_remove(&overlay->ov_id); ++ if (overlay->fw) ++ release_firmware(overlay->fw); ++ /* kfree with NULL is safe */ ++ kfree(overlay->dtbo); ++ kfree(overlay); ++} ++ ++static struct configfs_item_operations cfs_overlay_item_ops = { ++ .release = cfs_overlay_release, ++}; ++ ++static struct config_item_type cfs_overlay_type = { ++ .ct_item_ops = &cfs_overlay_item_ops, ++ .ct_attrs = cfs_overlay_attrs, ++ .ct_bin_attrs = cfs_overlay_bin_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); ++ ++ 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, ++}; ++ ++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; ++ ++static struct configfs_subsystem of_cfs_subsys = { ++ .su_group = { ++ .cg_item = { ++ .ci_namebuf = "device-tree", ++ .ci_type = &of_cfs_type, ++ }, ++ }, ++ .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); ++ config_group_init_type_name(&of_cfs_overlay_group, "overlays", ++ &overlays_type); ++ configfs_add_default_group(&of_cfs_overlay_group, ++ &of_cfs_subsys.su_group); ++ ++ 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); +diff --git a/drivers/of/fdt_address.c b/drivers/of/fdt_address.c +index dca8f9b..ec7e167 100644 +--- a/drivers/of/fdt_address.c ++++ b/drivers/of/fdt_address.c +@@ -161,7 +161,7 @@ static int __init fdt_translate_one(const void *blob, int parent, + * that can be mapped to a cpu physical address). This is not really specified + * that way, but this is traditionally the way IBM at least do things + */ +-static u64 __init fdt_translate_address(const void *blob, int node_offset) ++u64 __init fdt_translate_address(const void *blob, int node_offset) + { + int parent, len; + const struct of_bus *bus, *pbus;