From patchwork Mon Jun 15 09:57:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Shevchenko X-Patchwork-Id: 6607821 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D714DC0020 for ; Mon, 15 Jun 2015 10:01:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 09EB22035D for ; Mon, 15 Jun 2015 10:01:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0631520595 for ; Mon, 15 Jun 2015 10:01:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755332AbbFOKBG (ORCPT ); Mon, 15 Jun 2015 06:01:06 -0400 Received: from mga02.intel.com ([134.134.136.20]:1267 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754139AbbFOJ5q (ORCPT ); Mon, 15 Jun 2015 05:57:46 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 15 Jun 2015 02:57:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,618,1427785200"; d="scan'208";a="743563754" Received: from black.fi.intel.com ([10.237.72.86]) by fmsmga002.fm.intel.com with ESMTP; 15 Jun 2015 02:57:42 -0700 Received: by black.fi.intel.com (Postfix, from userid 1003) id 848BA45A; Mon, 15 Jun 2015 12:57:41 +0300 (EEST) From: Andy Shevchenko To: "Rafael J . Wysocki" , linux-acpi@vger.kernel.org, linux-pm@vger.kernel.org, Greg Kroah-Hartman , Vinod Koul , Lee Jones , Andrew Morton , Mika Westerberg , linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, Heikki Krogerus , Jarkko Nikula , "Wysocki, Rafael J" , Mike Turquette Cc: Andy Shevchenko Subject: [PATCH v4 3/8] Driver core: wakeup the parent device before trying probe Date: Mon, 15 Jun 2015 12:57:31 +0300 Message-Id: <1434362256-239992-4-git-send-email-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1434362256-239992-1-git-send-email-andriy.shevchenko@linux.intel.com> References: <1434362256-239992-1-git-send-email-andriy.shevchenko@linux.intel.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 From: "Rafael J. Wysocki" If the parent is still suspended when driver probe is attempted, the result may be failure. For example, if the parent is a PCI MFD device that has been suspended when we try to probe our device, any register reads will return 0xffffffff. To fix the problem, making sure the parent is always awake before attempting driver probe. Signed-off-by: Heikki Krogerus Signed-off-by: Rafael J. Wysocki Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/base/dd.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index e843fdb..c4c1eaf 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -399,6 +399,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe); * * This function must be called with @dev lock held. When called for a * USB interface, @dev->parent lock must be held as well. + * + * If the device has a parent, runtime-resume the parent before driver probing. */ int driver_probe_device(struct device_driver *drv, struct device *dev) { @@ -410,10 +412,16 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) pr_debug("bus: '%s': %s: matched device %s with driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name); + if (dev->parent) + pm_runtime_get_sync(dev->parent); + pm_runtime_barrier(dev); ret = really_probe(dev, drv); pm_request_idle(dev); + if (dev->parent) + pm_runtime_put(dev->parent); + return ret; } @@ -459,8 +467,14 @@ int device_attach(struct device *dev) ret = 0; } } else { + if (dev->parent) + pm_runtime_get_sync(dev->parent); + ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); pm_request_idle(dev); + + if (dev->parent) + pm_runtime_put(dev->parent); } out_unlock: device_unlock(dev);