From patchwork Mon Dec 4 19:13:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Tull X-Patchwork-Id: 844379 Return-Path: X-Original-To: incoming-dt@patchwork.ozlabs.org Delivered-To: patchwork-incoming-dt@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=devicetree-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yrF1f210Fz9sNw for ; Tue, 5 Dec 2017 06:14:46 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752957AbdLDTOo (ORCPT ); Mon, 4 Dec 2017 14:14:44 -0500 Received: from mail.kernel.org ([198.145.29.99]:42828 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752587AbdLDTOC (ORCPT ); Mon, 4 Dec 2017 14:14:02 -0500 Received: from localhost.localdomain (unknown [192.55.54.60]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5A08D2199D; Mon, 4 Dec 2017 19:14:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5A08D2199D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=atull@kernel.org From: Alan Tull To: Moritz Fischer , Rob Herring , Frank Rowand , Pantelis Antoniou Cc: Alan Tull , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org Subject: [PATCH 1/2] of: overlay: add flag enabling overlays and enable fpga-region overlays Date: Mon, 4 Dec 2017 13:13:56 -0600 Message-Id: <20171204191357.3211-2-atull@kernel.org> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171204191357.3211-1-atull@kernel.org> References: <20171204191357.3211-1-atull@kernel.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add a flag to struct device_node marking the node as a valid target for device tree overlays. When an overlay is submitted, if any target in the overlay is not enabled for overlays, the overlay is rejected. Drivers that support dynamic configuration can enable/disable their device node with: void of_node_overlay_enable(struct device_node *np) void of_node_overlay_disable(struct device_node *np) During each FPGA region's probe, enable its node for overlays. Signed-off-by: Alan Tull --- v1: (changes from the rfc) Add a flag instead of implementing a list rename functions for what they do, not how they're implemented squash with patch that enables fpga-region nodes add a helpful error message --- drivers/fpga/of-fpga-region.c | 4 ++++ drivers/of/overlay.c | 26 ++++++++++++++++++++++++++ include/linux/of.h | 19 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c index 119ff75..8633eea 100644 --- a/drivers/fpga/of-fpga-region.c +++ b/drivers/fpga/of-fpga-region.c @@ -438,6 +438,7 @@ static int of_fpga_region_probe(struct platform_device *pdev) goto eprobe_mgr_put; of_platform_populate(np, fpga_region_of_match, NULL, ®ion->dev); + of_node_overlay_enable(np); dev_info(dev, "FPGA Region probed\n"); @@ -451,7 +452,10 @@ static int of_fpga_region_probe(struct platform_device *pdev) static int of_fpga_region_remove(struct platform_device *pdev) { struct fpga_region *region = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + of_node_overlay_disable(np); fpga_region_unregister(region); fpga_mgr_put(region->mgr); diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 53bc9e3..a9758d6 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "of_private.h" @@ -646,6 +647,27 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) kfree(ovcs); } +static int of_overlay_check_targets(struct overlay_changeset *ovcs) +{ + struct device_node *target; + int i; + + for (i = 0; i < ovcs->count; i++) { + target = ovcs->fragments[i].target; + + if (!of_node_cmp(target->name, "__symbols__")) + continue; + + if (!of_node_check_flag(target, OF_OVERLAY_ENABLED)) { + pr_err("Overlays not enabled for target %pOF\n", + target); + return -EPERM; + } + } + + return 0; +} + /** * of_overlay_apply() - Create and apply an overlay changeset * @tree: Expanded overlay device tree @@ -717,6 +739,10 @@ int of_overlay_apply(struct device_node *tree, int *ovcs_id) if (ret) goto err_free_overlay_changeset; + ret = of_overlay_check_targets(ovcs); + if (ret) + goto err_free_overlay_changeset; + ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY); if (ret) { pr_err("overlay changeset pre-apply notify error %d\n", ret); diff --git a/include/linux/of.h b/include/linux/of.h index d3dea1d..16a2cae 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -147,6 +147,7 @@ extern raw_spinlock_t devtree_lock; #define OF_DETACHED 2 /* node has been detached from the device tree */ #define OF_POPULATED 3 /* device already created for the node */ #define OF_POPULATED_BUS 4 /* of_platform_populate recursed to children of this node */ +#define OF_OVERLAY_ENABLED 5 /* allow DT overlay targeting this node */ #define OF_BAD_ADDR ((u64)-1) @@ -1364,6 +1365,16 @@ int of_overlay_remove_all(void); int of_overlay_notifier_register(struct notifier_block *nb); int of_overlay_notifier_unregister(struct notifier_block *nb); +static inline void of_node_overlay_enable(struct device_node *np) +{ + of_node_set_flag(np, OF_OVERLAY_ENABLED); +} + +static inline void of_node_overlay_disable(struct device_node *np) +{ + of_node_clear_flag(np, OF_OVERLAY_ENABLED); +} + #else static inline int of_overlay_apply(struct device_node *tree, int *ovcs_id) @@ -1391,6 +1402,14 @@ static inline int of_overlay_notifier_unregister(struct notifier_block *nb) return 0; } +static inline void of_node_overlay_enable(struct device_node *np) +{ +} + +static inline void of_node_overlay_disable(struct device_node *np) +{ +} + #endif #endif /* _LINUX_OF_H */ From patchwork Mon Dec 4 19:13:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Tull X-Patchwork-Id: 844378 Return-Path: X-Original-To: incoming-dt@patchwork.ozlabs.org Delivered-To: patchwork-incoming-dt@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=devicetree-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yrF0x40xDz9rxl for ; Tue, 5 Dec 2017 06:14:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752488AbdLDTOI (ORCPT ); Mon, 4 Dec 2017 14:14:08 -0500 Received: from mail.kernel.org ([198.145.29.99]:42854 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752806AbdLDTOD (ORCPT ); Mon, 4 Dec 2017 14:14:03 -0500 Received: from localhost.localdomain (unknown [192.55.54.60]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5654021933; Mon, 4 Dec 2017 19:14:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5654021933 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=atull@kernel.org From: Alan Tull To: Moritz Fischer , Rob Herring , Frank Rowand , Pantelis Antoniou Cc: Alan Tull , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org Subject: [PATCH 2/2] of: dynamic: add overlay-allowed DT property Date: Mon, 4 Dec 2017 13:13:57 -0600 Message-Id: <20171204191357.3211-3-atull@kernel.org> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171204191357.3211-1-atull@kernel.org> References: <20171204191357.3211-1-atull@kernel.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Allow DT nodes to be marked as valid targets for DT overlays by the added "overlay-allowed" property. Signed-off-by: Alan Tull --- drivers/of/base.c | 4 ++-- drivers/of/dynamic.c | 3 +++ drivers/of/fdt.c | 3 +++ drivers/of/of_private.h | 2 ++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 26618ba..ac6b326 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -116,8 +116,8 @@ void __init of_core_init(void) proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); } -static struct property *__of_find_property(const struct device_node *np, - const char *name, int *lenp) +struct property *__of_find_property(const struct device_node *np, + const char *name, int *lenp) { struct property *pp; diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index ab988d8..fae9b85 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -207,6 +207,9 @@ static void __of_attach_node(struct device_node *np) np->name = __of_get_property(np, "name", NULL) ? : ""; np->type = __of_get_property(np, "device_type", NULL) ? : ""; + if (__of_find_property(np, "overlay-allowed", NULL)) + of_node_set_flag(np, OF_OVERLAY_ENABLED); + phandle = __of_get_property(np, "phandle", &sz); if (!phandle) phandle = __of_get_property(np, "linux,phandle", &sz); diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 4675e5a..9237f30 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -323,6 +323,9 @@ static bool populate_node(const void *blob, np->name = ""; if (!np->type) np->type = ""; + + if (of_find_property(np, "overlay-allowed", NULL)) + of_node_set_flag(np, OF_OVERLAY_ENABLED); } *pnp = np; diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 92a9a36..75fcba3 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -115,6 +115,8 @@ struct device_node *__of_find_node_by_path(struct device_node *parent, struct device_node *__of_find_node_by_full_path(struct device_node *node, const char *path); +extern struct property *__of_find_property(const struct device_node *np, + const char *name, int *lenp); extern const void *__of_get_property(const struct device_node *np, const char *name, int *lenp); extern int __of_add_property(struct device_node *np, struct property *prop);