From patchwork Tue Sep 27 12:34:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 9351815 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 45F09600CB for ; Tue, 27 Sep 2016 12:33:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 368852891E for ; Tue, 27 Sep 2016 12:33:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 29AD3291E5; Tue, 27 Sep 2016 12:33:58 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham 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 728202891E for ; Tue, 27 Sep 2016 12:33:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755168AbcI0Md4 (ORCPT ); Tue, 27 Sep 2016 08:33:56 -0400 Received: from mailout2.hostsharing.net ([83.223.90.233]:34813 "EHLO mailout2.hostsharing.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755161AbcI0Mdz (ORCPT ); Tue, 27 Sep 2016 08:33:55 -0400 Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mailout2.hostsharing.net (Postfix) with ESMTPS id A1FF410189AC5; Tue, 27 Sep 2016 14:33:51 +0200 (CEST) Received: from localhost (3-38-90-81.adsl.cmo.de [81.90.38.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 195856091667; Tue, 27 Sep 2016 14:33:49 +0200 (CEST) Date: Tue, 27 Sep 2016 14:34:29 +0200 From: Lukas Wunner To: "Rafael J. Wysocki" Cc: Linux PM list , Greg Kroah-Hartman , Alan Stern , Linux Kernel Mailing List , Tomeu Vizoso , Mark Brown , Marek Szyprowski , Kevin Hilman , Ulf Hansson , "Luis R. Rodriguez" , Jonathan Corbet Subject: Re: [RFC/RFT][PATCH v3 0/5] Functional dependencies between devices Message-ID: <20160927123429.GA5828@wunner.de> References: <27296716.H9VWo8ShOm@vostro.rjw.lan> <5257325.y9rG1UM74b@vostro.rjw.lan> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <5257325.y9rG1UM74b@vostro.rjw.lan> User-Agent: Mutt/1.6.1 (2016-04-27) 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 [+cc corbet] To whom it may concern, I made some notes while reviewing the state machine in patch 2 of this series and thought, why not rework it into something that could eventually go into the Documentation/ tree? So here's an initial draft. There's some introductory text plus a description of the state machine. Just putting this out there now to ease reviewers' lives, despite the obvious WIP status. I'll try to amend it as the series converges. This is already rst-formatted but I haven't actually run it through sphinx yet. Lukas -- >8 -- Subject: [PATCH] Documentation: device links: Add initial documentation Signed-off-by: Lukas Wunner --- Documentation/driver-model/device_link.rst | 95 ++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 Documentation/driver-model/device_link.rst diff --git a/Documentation/driver-model/device_link.rst b/Documentation/driver-model/device_link.rst new file mode 100644 index 0000000..ba911b4 --- /dev/null +++ b/Documentation/driver-model/device_link.rst @@ -0,0 +1,95 @@ +============ +Device links +============ + +By default, the driver core only enforces dependencies between devices +that are borne out of a parent/child relationship within the device +hierarchy: When suspending, resuming or shutting down the system, devices +are ordered based on this relationship, i.e. children are always suspended +before their parent, and the parent is always resumed before its children. + +Sometimes there is a need to represent device dependencies beyond the +mere parent/child relationship, e.g. between siblings, and have the +driver core automatically take care of them. + +Secondly, the driver core by default does not enforce any driver presence +dependencies, i.e. that one device must be bound to a driver before +another one can probe or function correctly. + +Often these two dependency types come together, so a device depends on +another one both with regards to driver presence *and* with regards to +suspend/resume and shutdown ordering. + +Device links allow representation of such dependencies in the driver core. + +In its standard form, a device link combines *both* dependency types: +It guarantees correct suspend/resume and shutdown ordering between a +"supplier" device and its "consumer" devices, and it guarantees driver +presence on the supplier: The consumer devices are not probed before the +supplier is bound to a driver, and they're unbound before the supplier +is unbound. + +When driver presence on the supplier is irrelevant and only correct +suspend/resume and shutdown ordering is needed, the device link may +simply be set up with the DEVICE_LINK_STATELESS flag. + +A driver presence dependency between parent and child, i.e. within the +regular device hierarchy, could in principle also be represented in the +driver core using a device link. + +If a device link is set up with the DEVICE_LINK_AUTOREMOVE flag, it is +automatically purged when the consumer fails to probe or later unbinds. +This is handy when adding a device link from the consumer's ->probe hook, +as it obviates the need to delete the link in the ->remove hook or in +the error path of the ->probe hook. + + +State machine +============= + +""" + .=============================. + | | + v | +DORMANT <=> AVAILABLE <=> CONSUMER_PROBE => ACTIVE + ^ | + | | + '============ SUPPLIER_UNBIND <============' +""" + +* The initial state of a device link is passed in to device_link_add(). + If the link is created before any devices are probed, it must be set to + DEVICE_LINK_DORMANT. + +* When a supplier device is bound to a driver, links to its consumers + progress to DEVICE_LINK_AVAILABLE. + (Call to device_links_driver_bound() from driver_bound().) + +* Before a consumer device is probed, presence of supplier drivers is + verified by checking that links to suppliers are in DEVICE_LINK_AVAILABLE + state. The state of the links is updated to DEVICE_LINK_CONSUMER_PROBE. + (Call to device_links_check_suppliers() from driver_probe_device().) + This prevents the supplier from unbinding. + (Call to wait_for_device_probe() in device_links_unbind_consumers().) + +* If the probe fails, links to suppliers revert back to DEVICE_LINK_AVAILABLE. + (Call to device_links_no_driver() from really_probe().) + +* If the probe succeeds, links to suppliers progress to DEVICE_LINK_ACTIVE. + (Call of device_links_driver_bound() from driver_bound().) + +* When the consumer's driver is later on removed, links to suppliers revert + back to DEVICE_LINK_AVAILABLE. + (Call to device_links_no_driver() from __device_release_driver().) + +* Before a supplier's driver is removed, links to consumers that are not + bound to a driver are updated to DEVICE_LINK_SUPPLIER_UNBIND. + (Call to device_links_busy() from __device_release_driver().) + This prevents the consumers from binding. + (Call to device_links_check_suppliers() from driver_probe_device().) + Consumers that are bound are freed from their driver; consumers that are + probing are waited for until they are done. + (Call to device_links_unbind_consumers() from __device_release_driver().) + Once all links to consumers are in DEVICE_LINK_SUPPLIER_UNBIND state, + the supplier driver is released and the links revert to DEVICE_LINK_DORMANT. + (Call to device_links_driver_gone() from __device_release_driver().)