From patchwork Tue Nov 17 14:35:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 56794 Delivered-To: patches@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp1975848lbb; Tue, 17 Nov 2015 06:35:51 -0800 (PST) X-Received: by 10.112.150.225 with SMTP id ul1mr19597555lbb.47.1447770950250; Tue, 17 Nov 2015 06:35:50 -0800 (PST) Return-Path: Received: from mail-lf0-x230.google.com (mail-lf0-x230.google.com. [2a00:1450:4010:c07::230]) by mx.google.com with ESMTPS id q18si26014303lfe.144.2015.11.17.06.35.50 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 Nov 2015 06:35:50 -0800 (PST) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:4010:c07::230 as permitted sender) client-ip=2a00:1450:4010:c07::230; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:4010:c07::230 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dkim=pass header.i=@linaro_org.20150623.gappssmtp.com Received: by lfs39 with SMTP id 39so6614730lfs.3 for ; Tue, 17 Nov 2015 06:35:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=tWadaJWXgdQP9Z1klAUlE/NV2mRp50xrdodEttxWs7k=; b=PnTsvcqHp/L9SLhki+G2wmQFe5D0Qx2eIo2nRvLYt08IiG/z+5esE+Zka/F68klMh0 y0i0ACis1Ca49R/nS3uXLi2dYj8McivGx1PY0I62Xxd1POsJKA0LpgYhVAcfTC6Pn9rL BdIwo+PAFR4dq4VnR30TO/OgagBvHcGru/W9mKMEBD1z/3X/oK3hBYe+O5hIDnUxEfzt ksXOG/1zh0rv1O2C8rgzjggq1Ky9BsI4Q/88BhCfCPFxaQHtn1GzdSWMtmqZFxeJWhvJ aANjriWZH41+SG74IXk1HWT9W4367fO7VpPdsppnch0BZPLXya2nzSMti/GINsxhpbDr +HWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=tWadaJWXgdQP9Z1klAUlE/NV2mRp50xrdodEttxWs7k=; b=RiXOMHD/rpwr+89mDqjjePYWWwAvzHmqoGQvplmY2wX8rdZMg6dc35+6BCpZmfDyal 5hiX3DIW4LVDIU0JJ/7wC+GJfgLsuFPYCwiZkvzyxBKyulJShmO6TtCcOsB/iMiOPWqq Rtbfos3Rs+PDmQBsrd8q3W8V9sWTAGpCJ90XO2I2zF7YcweyEV9tPR+fLFzQQkCfig3t ThVJOK7ce3Kez7UlcDoD0P0OWTnkPxD+htLlxgyg9FjUKqq8uwmTUcwPpgvG6JT4VNX4 vePFcg6vEnpNRRD82EHNq+a7NAPAIvA/XFt2zjkBUi7RiFbHOiAQg/qKhSulJsPEf5wt azRw== X-Gm-Message-State: ALoCoQmwPG7EYAY+fLGHpBB/fE80vYU7QEwBJWi8fC4thAZC6mkR1cXZZhw4fb45ApIyqdj6cpu7 X-Received: by 10.25.22.68 with SMTP id m65mr20365238lfi.10.1447770950057; Tue, 17 Nov 2015 06:35:50 -0800 (PST) Return-Path: Received: from localhost.localdomain (c-83-233-167-104.cust.bredband2.com. [83.233.167.104]) by smtp.gmail.com with ESMTPSA id i7sm6384436lbo.39.2015.11.17.06.35.49 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 17 Nov 2015 06:35:49 -0800 (PST) From: Ulf Hansson To: "Rafael J. Wysocki" , Greg Kroah-Hartman , linux-pm@vger.kernel.org Cc: Alan Stern , Kevin Hilman , Len Brown , Pavel Machek , Geert Uytterhoeven , Kuninori Morimoto , Eduardo Valentin , Ulf Hansson Subject: [PATCH 2/2] Driver core: Set initial runtime PM states at probe err and driver unbind Date: Tue, 17 Nov 2015 15:35:29 +0100 Message-Id: <1447770929-16652-3-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1447770929-16652-1-git-send-email-ulf.hansson@linaro.org> References: <1447770929-16652-1-git-send-email-ulf.hansson@linaro.org> There are two common expectations among several subsystems/drivers that deploys runtime PM support, but which isn't met by the driver core. Expectation 1) At ->probe() the subsystem/driver expects the runtime PM status of the device to be RPM_SUSPENDED, which is the initial status being assigned at device registration. This expectation is especially common among some of those subsystems/ drivers that manages devices with an attached PM domain, as those requires the ->runtime_resume() callback at the PM domain level to be invoked during ->probe(). Moreover these subsystems/drivers entirely relies on runtime PM resources being managed at the PM domain level, thus don't implement their own set of runtime PM callbacks. These are two scenarios that suffers from this unmet expectation. i) A failed ->probe() sequence requests probe deferral: ->probe() ... pm_runtime_enable() pm_runtime_get_sync() ... err: pm_runtime_put() pm_runtime_disable() ... As there are no guarantees that such sequence turns the runtime PM status of the device into RPM_SUSPENDED, the re-trying ->probe() may start with the status in RPM_ACTIVE. In such case the runtime PM core won't invoke the ->runtime_resume() callback because of a pm_runtime_get_sync(), as it considers the device to be already runtime resumed. ii) A driver re-bind sequence: At driver unbind, the subsystem/driver's >remove() callback invokes a sequence of runtime PM APIs, to undo actions during ->probe() and to put the device into low power state. ->remove() ... pm_runtime_put() pm_runtime_disable() ... Similar as in the failing ->probe() case, this sequence don't guarantee the runtime PM status of the device to turn into RPM_SUSPENDED. Trying to re-bind the driver thus causes the same issue as when re-trying ->probe(), in the probe deferral scenario. Expectation 2) Drivers that invokes the pm_runtime_irq_safe() API during ->probe(), triggers the runtime PM core to increase the usage count for the device's parent and permanently make it runtime resumed. The usage count is only dropped at device removal, which also allows it to be runtime suspended again. A re-trying ->probe() repeats the call to pm_runtime_irq_safe() and thus once more triggers the usage count of the device's parent to be increased. This leads to not only an imbalance issue of the usage count of the device's parent, but also to keep it runtime resumed permanently even if ->probe() fails. To address these issues, let's change the policy of the driver core to meet these expectations. More precisely, at ->probe() failures and driver unbind, restore the initial states of runtime PM. Although to still allow subsystem's to control PM for devices that doesn't ->probe() successfully, don't restore the initial states unless runtime PM is disabled. Signed-off-by: Ulf Hansson --- drivers/base/dd.c | 2 ++ 1 file changed, 2 insertions(+) -- 1.9.1 diff --git a/drivers/base/dd.c b/drivers/base/dd.c index a641cf3..8402e45 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -340,6 +340,7 @@ probe_failed: dev_set_drvdata(dev, NULL); if (dev->pm_domain && dev->pm_domain->dismiss) dev->pm_domain->dismiss(dev); + pm_runtime_remove(dev, false); switch (ret) { case -EPROBE_DEFER: @@ -695,6 +696,7 @@ static void __device_release_driver(struct device *dev) dev_set_drvdata(dev, NULL); if (dev->pm_domain && dev->pm_domain->dismiss) dev->pm_domain->dismiss(dev); + pm_runtime_remove(dev, false); klist_remove(&dev->p->knode_driver); if (dev->bus)