From patchwork Tue Jun 6 15:59:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johan Hovold X-Patchwork-Id: 9769233 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D8E1C60364 for ; Tue, 6 Jun 2017 16:03:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E24B828415 for ; Tue, 6 Jun 2017 16:03:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D6D902846D; Tue, 6 Jun 2017 16:03:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7FDCE28415 for ; Tue, 6 Jun 2017 16:03:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751542AbdFFQAw (ORCPT ); Tue, 6 Jun 2017 12:00:52 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:33162 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751527AbdFFQAt (ORCPT ); Tue, 6 Jun 2017 12:00:49 -0400 Received: by mail-lf0-f67.google.com with SMTP id u62so11922790lfg.0; Tue, 06 Jun 2017 09:00:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=g6Cpx8iCEAh6qCcWXbnk8ABVCzctzpsa2rLZKj4q67g=; b=m022NSPxvVhdkn+AKuU0Em4JZIrdBbbMIxqmR7OQl8aRFs0X3AgmYmn+BYPkxzjHza CiljcsScrh2BCnlKURdHsXW6aYwS2sE7rIMHLWUBWcGVFeuRIjTNlWSBBeak0LuCsBff lmdMafRvmlqgnG0A4ZvMO+2oeWFAq4qZ/Y+GmT33XGPRUXEqQtrDCtwNGJhJvK0ZMwPH 8emT2nHJShHRZQNTSUvv8c+m9nUFkqc84cIg+enEeqCqKiRl0hlQ+F41mviVUHQnnmZf L1x3ScQCn85nNM+hJ5p1aALhj3Iw7YastsP2hVloR+6wm3NJUiO8FiOoif+9ZQDoEEOy yKXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=g6Cpx8iCEAh6qCcWXbnk8ABVCzctzpsa2rLZKj4q67g=; b=BZRzNz8xsZCt2ByZtQcAXZIgVMB9jRRtMdc8WlPsBKWC5j1YM4fPX2sy1gwpB5/I9I meeXnZE6DpavrGWAild/OR6X6QhHyCZZuiZmxtsCIBxoJBryFyu4eUj805BZepC819EH dhxxrX12VF79p87iwvItVAUY6bi26OKzR2UcRaeafFgyv2sY/hNYDhCvKhVuCuc4c+8S ulVnshEg2yDTgEVmzH8llqs7YFFLYvE2ow0zS9xQgPdYXFIK/1r+1A6y62rTc1nW1VLc MlPZ1PsMSnwP8QpLnF7VUt28ha1b7zGLCCZopxwdW3PFXuPgRWC3t9vW1kOe7dnblZIP Pulg== X-Gm-Message-State: AODbwcAoiCPQu/QsabB9Pn2b3rbux4pIUi4t6hxR+mBSj5VE6Qx26mpR ftpvrbUCcvZWDHzLFc4= X-Received: by 10.46.83.1 with SMTP id h1mr7995635ljb.102.1496764847556; Tue, 06 Jun 2017 09:00:47 -0700 (PDT) Received: from xi.terra (c-42c8e255.07-184-6d6c6d4.cust.bredbandsbolaget.se. [85.226.200.66]) by smtp.gmail.com with ESMTPSA id l142sm2545684lfl.25.2017.06.06.09.00.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Jun 2017 09:00:45 -0700 (PDT) Received: from johan by xi.terra with local (Exim 4.89) (envelope-from ) id 1dIGuU-00071A-QV; Tue, 06 Jun 2017 18:00:46 +0200 From: Johan Hovold To: Greg Kroah-Hartman Cc: Linus Walleij , Peter Chen , Rob Herring , Arnd Bergmann , Sricharan R , Zhang Rui , Eduardo Valentin , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-usb@vger.kernel.org, Johan Hovold Subject: [PATCH v2 3/7] driver core: add helper to reuse a device-tree node Date: Tue, 6 Jun 2017 17:59:00 +0200 Message-Id: <20170606155904.26819-4-johan@kernel.org> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170606155904.26819-1-johan@kernel.org> References: <20170606155904.26819-1-johan@kernel.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a helper function to be used when reusing the device-tree node of another device. It is fairly common for drivers to reuse the device-tree node of a parent (or other ancestor) device when creating class or bus devices (e.g. gpio chips, i2c adapters, iio chips, spi masters, serdev, phys, usb root hubs). But reusing a device-tree node may cause problems if the new device is later probed as for example driver core would currently attempt to reinitialise an already active associated pinmux configuration. Other potential issues include the platform-bus code unconditionally dropping the device-tree node reference in its device destructor, reinitialisation of other bus-managed resources such as clocks, and the recently added DMA-setup in driver core. Note that for most examples above this is currently not an issue as the devices are never probed, but this is a problem for the USB bus which has recently gained device-tree support. This was discovered and worked-around in a rather ad-hoc fashion by commit dc5878abf49c ("usb: core: move root hub's device node assignment after it is added to bus") by not setting the of_node pointer until after the root-hub device has been registered. Instead we can allow devices to reuse a device-tree node by setting a flag in their struct device that can be used by core, bus and driver code to avoid resources from being over-allocated. Note that the helper also grabs an extra reference to the device node, which specifically balances the unconditional put in the platform-device destructor. Signed-off-by: Johan Hovold --- drivers/base/core.c | 16 ++++++++++++++++ include/linux/device.h | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index bbecaf9293be..c3064ff09af5 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2884,3 +2884,19 @@ void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode) else dev->fwnode = fwnode; } + +/** + * device_set_of_node_from_dev - reuse device-tree node of another device + * @dev: device whose device-tree node is being set + * @dev2: device whose device-tree node is being reused + * + * Takes another reference to the new device-tree node after first dropping + * any reference held to the old node. + */ +void device_set_of_node_from_dev(struct device *dev, const struct device *dev2) +{ + of_node_put(dev->of_node); + dev->of_node = of_node_get(dev2->of_node); + dev->of_node_reused = true; +} +EXPORT_SYMBOL_GPL(device_set_of_node_from_dev); diff --git a/include/linux/device.h b/include/linux/device.h index 9ef518af5515..60ab00b13095 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -879,6 +879,8 @@ struct dev_links_info { * * @offline_disabled: If set, the device is permanently online. * @offline: Set after successful invocation of bus type's .offline(). + * @of_node_reused: Set if the device-tree node is shared with an ancestor + * device. * * At the lowest level, every device in a Linux system is represented by an * instance of struct device. The device structure contains the information @@ -966,6 +968,7 @@ struct device { bool offline_disabled:1; bool offline:1; + bool of_node_reused:1; }; static inline struct device *kobj_to_dev(struct kobject *kobj) @@ -1144,6 +1147,7 @@ extern int device_offline(struct device *dev); extern int device_online(struct device *dev); extern void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); extern void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode); +void device_set_of_node_from_dev(struct device *dev, const struct device *dev2); static inline int dev_num_vf(struct device *dev) {