From patchwork Fri Feb 7 16:53:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Francois Moine X-Patchwork-Id: 3606981 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 8C1369F2D6 for ; Fri, 7 Feb 2014 17:20:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AFAF420181 for ; Fri, 7 Feb 2014 17:20:33 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 174DF20120 for ; Fri, 7 Feb 2014 17:20:32 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4B7AEFBC2E; Fri, 7 Feb 2014 09:20:30 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp5-g21.free.fr (smtp5-g21.free.fr [212.27.42.5]) by gabe.freedesktop.org (Postfix) with ESMTP id BBF8FFBC2E for ; Fri, 7 Feb 2014 09:20:26 -0800 (PST) Received: from localhost (unknown [IPv6:2a01:e35:2f5c:9de0:212:bfff:fe1e:9ce4]) by smtp5-g21.free.fr (Postfix) with ESMTP id F2467D48162; Fri, 7 Feb 2014 18:20:09 +0100 (CET) X-Mailbox-Line: From 9f8bbe28b00160cab2cedffa3f8fb42121035964 Mon Sep 17 00:00:00 2001 Message-Id: <9f8bbe28b00160cab2cedffa3f8fb42121035964.1391793068.git.moinejf@free.fr> In-Reply-To: References: From: Jean-Francois Moine Date: Fri, 7 Feb 2014 17:53:27 +0100 Subject: [PATCH RFC 2/2] drivers/base: declare phandle DT nodes as components To: Russell King , devel@driverdev.osuosl.org Cc: alsa-devel@alsa-project.org, Takashi Iwai , Greg Kroah-Hartman , dri-devel@lists.freedesktop.org, Sascha Hauer , linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP At system startup time, some devices depends on the availability of some other devices before starting. The infrastructure for componentised subsystems permits to handle this dependence, each driver defining its own role. This patch does an automatic creation of the lowest components in case of DT. This permits simple devices to be part of complex componentised subsystems without any specific code. When created from DT, the device dependence is generally indicated by phandle: a device which is pointed to by a phandle must be started before the pointing device(s). So, at device register time, the devices which are pointed to by a phandle are declared as components, except when they declared themselves as such in their probe function. Signed-off-by: Jean-Francois Moine --- drivers/base/component.c | 12 ++++++++++++ drivers/base/core.c | 18 ++++++++++++++++++ include/linux/of.h | 2 ++ 3 files changed, 32 insertions(+) diff --git a/drivers/base/component.c b/drivers/base/component.c index 0a39d7a..3cab26b 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -17,6 +17,7 @@ #include #include #include +#include struct master { struct list_head node; @@ -336,6 +337,7 @@ EXPORT_SYMBOL_GPL(component_bind_all); int component_add(struct device *dev, const struct component_ops *ops) { struct component *component; + struct device_node *np; int ret; component = kzalloc(sizeof(*component), GFP_KERNEL); @@ -356,6 +358,11 @@ int component_add(struct device *dev, const struct component_ops *ops) kfree(component); } + + np = dev->of_node; + if (np) + np->_flags |= OF_DEV_COMPONENT; + mutex_unlock(&component_mutex); return ret < 0 ? ret : 0; @@ -365,6 +372,7 @@ EXPORT_SYMBOL_GPL(component_add); void component_del(struct device *dev, const struct component_ops *ops) { struct component *c, *component = NULL; + struct device_node *np; mutex_lock(&component_mutex); list_for_each_entry(c, &component_list, node) @@ -377,6 +385,10 @@ void component_del(struct device *dev, const struct component_ops *ops) if (component && component->master) take_down_master(component->master); + np = dev->of_node; + if (np) + np->_flags &= ~OF_DEV_COMPONENT; + mutex_unlock(&component_mutex); WARN_ON(!component); diff --git a/drivers/base/core.c b/drivers/base/core.c index 2b56717..0517b91 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "base.h" #include "power/power.h" @@ -980,6 +981,7 @@ int device_add(struct device *dev) struct device *parent = NULL; struct kobject *kobj; struct class_interface *class_intf; + struct device_node *np; int error = -EINVAL; dev = get_device(dev); @@ -1088,6 +1090,15 @@ int device_add(struct device *dev) class_intf->add_dev(dev, class_intf); mutex_unlock(&dev->class->p->mutex); } + + /* if DT-created device referenced by phandle, create a component */ + np = dev->of_node; + if (np && np->phandle && + !(np->_flags & OF_DEV_COMPONENT)) { + component_add(dev, NULL); + np->_flags |= OF_DEV_IMPLICIT_COMPONENT; + } + done: put_device(dev); return error; @@ -1189,10 +1200,17 @@ void device_del(struct device *dev) { struct device *parent = dev->parent; struct class_interface *class_intf; + struct device_node *np; /* Notify clients of device removal. This call must come * before dpm_sysfs_remove(). */ + np = dev->of_node; + if (np && (np->_flags & OF_DEV_COMPONENT)) { + component_del(dev, NULL); + np->_flags &= ~OF_DEV_IMPLICIT_COMPONENT; + } + if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DEL_DEVICE, dev); diff --git a/include/linux/of.h b/include/linux/of.h index 70c64ba..40f1c34 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -59,6 +59,8 @@ struct device_node { struct proc_dir_entry *pde; /* this node's proc directory */ struct kref kref; unsigned long _flags; +#define OF_DEV_COMPONENT 1 +#define OF_DEV_IMPLICIT_COMPONENT 2 void *data; #if defined(CONFIG_SPARC) const char *path_component_name;