From patchwork Tue May 30 16:25:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johan Hovold X-Patchwork-Id: 9754865 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 4BBEF602BF for ; Tue, 30 May 2017 16:27:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3DC9E26538 for ; Tue, 30 May 2017 16:27:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 31BC627165; Tue, 30 May 2017 16:27:33 +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.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, 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 C66B826538 for ; Tue, 30 May 2017 16:27:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751266AbdE3Q1P (ORCPT ); Tue, 30 May 2017 12:27:15 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:33648 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751148AbdE3Q1L (ORCPT ); Tue, 30 May 2017 12:27:11 -0400 Received: by mail-lf0-f67.google.com with SMTP id m18so9326548lfj.0; Tue, 30 May 2017 09:26:59 -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=xp6Jq4ixPE2H8w3/7zuOZ80VSNJPLEavWpnXYlRK3EQ=; b=riTNj8IP9HX3oZFUcLdrsGdAGFM3bpD0J5UTwNFa3eZ0UmdW26uk02BwZD1FbBwh6s XJHBxUevNEhMXvFQRvZni5hmNtksuumbzrUyolfpgYCC5gaY1MGqKOhhkBJl7uMXx+pv lUgKBqFknfS9MAmRfmzXxzmtlO2k7txMJ8ay/W7M8KOTjYETBeX+djsteGmPZT+n8PrG zP+b2WkxU6tWxu7/mJv/yWdNyopHtKzhT/YgqlU7S3DcDNga1BCt5DH5KzDOZ6q84CNs KoXh+pWLaMkmizFr/TV352+ITfIrfj153Zr6v/b7LbU0ZSUjljRPokgPDKfMmzD0+Vnu uO1A== 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=xp6Jq4ixPE2H8w3/7zuOZ80VSNJPLEavWpnXYlRK3EQ=; b=ZAOvOHEBoExRHwGF1SwnA3uzVpzSI1MfBS6pzIC8Xq/gCE4/TxBNjcb4cZZPs6hLoN lABO07RGo8aFXYfZ4TOsF+tXzpy+zaQN0bWCC8TxYR2j3Ve98BFDGiYMcGBw8klB0CFr pzB3veMdT+anSPMmD75hVtTHTidpnaASD4uoH9Qo36mNkYqVw1+2DrWHH5L0LmuMmwE1 L1qWBjGp4i/O+1jVEUUY9SA27V4MHpBWsOETd407SitgP2sz3beLg5iw3+uEBmU0r2tA QUM49PnToAVo848QvWK+TdLpXyOfHZwho6buqUXuAKTMV2KgJn6upl6h2sSU7XOUGkAu S7vQ== X-Gm-Message-State: AODbwcCMVykefI5BD+uZ6aY8AyUrBDVoxl/BvUYM70fpiK0PB5Dk9kkm CpdUuybuzuM37Q== X-Received: by 10.46.83.65 with SMTP id t1mr6461217ljd.28.1496161608606; Tue, 30 May 2017 09:26:48 -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 h67sm2818531lfh.24.2017.05.30.09.26.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 May 2017 09:26:46 -0700 (PDT) Received: from johan by xi.terra with local (Exim 4.89) (envelope-from ) id 1dFjyr-0006oy-88; Tue, 30 May 2017 18:26:49 +0200 From: Johan Hovold To: Greg Kroah-Hartman Cc: Linus Walleij , Peter Chen , Rob Herring , Arnd Bergmann , Sricharan R , Zhang Rui , Eduardo Valentin , linux-pm@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold Subject: [PATCH 3/7] driver core: add helper to reuse a device-tree node Date: Tue, 30 May 2017 18:25:50 +0200 Message-Id: <20170530162554.26159-4-johan@kernel.org> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170530162554.26159-1-johan@kernel.org> References: <20170530162554.26159-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 | 2 ++ 2 files changed, 18 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..d7544bb558c3 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -966,6 +966,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 +1145,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) {