From patchwork Wed Feb 28 18:45:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feng Kan X-Patchwork-Id: 10249335 X-Patchwork-Delegate: bhelgaas@google.com 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 91D0860384 for ; Wed, 28 Feb 2018 18:46:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 85FAB28E52 for ; Wed, 28 Feb 2018 18:46:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7A6F928E5A; Wed, 28 Feb 2018 18:46:15 +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=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, 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 DC6E728E34 for ; Wed, 28 Feb 2018 18:46:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752819AbeB1SqN (ORCPT ); Wed, 28 Feb 2018 13:46:13 -0500 Received: from mail-pl0-f68.google.com ([209.85.160.68]:38576 "EHLO mail-pl0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752412AbeB1SqM (ORCPT ); Wed, 28 Feb 2018 13:46:12 -0500 Received: by mail-pl0-f68.google.com with SMTP id d4-v6so2049026pll.5 for ; Wed, 28 Feb 2018 10:46:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=apm.com; s=apm; h=from:to:cc:subject:date:message-id; bh=KJ1PLUv7XKSZTn423lWgv7nwMV3GYF0QgL+EOVznF5s=; b=nEY7X/LbYFwWvJipWUaLg1dlyYWWiVQgdENii4M+bdTUf50hB0ojNXJD/W49EK6W7q FFAULcVrDE2LlwtjAW7/3B6lcaIDl4de8ofAwqJcFU9+/o0IRfZPWAbFuV9X83Gyk/2s Xg8kjPXUfP29hwdXlrKQ/cy2v68HvqHH7VPIs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=KJ1PLUv7XKSZTn423lWgv7nwMV3GYF0QgL+EOVznF5s=; b=ejTOttU4J0KuEMqtWp2FO2Alzv6+xmJ6wLLuI9ubNdoLQ36ds5N4rnrtl5KjUANMf4 coP5+1GpmTqKNwenLetL0tsw53SPkZiXt+v5WQ1LWIc8j/0Hd98GBuMXQWfzeBNWzIV6 FOOYI+HcpuE0w1QJuhWhJVQRHIvrJi7UTXQdh5MO5BdE0jmmtWSw7OE2l2oancLhKzSX jvdTUO2YKdIJYji8i4WfK2bs/4RI6CdYwixDfDx9FurEGFzT1klekz8bQU8ulcPp7+aS sRPXhy9giadrLwjWxy10y6njmmMoZZhvZhO61gqLglmyk/xHXz9HHBIRyVQvbhxJagSC Eecg== X-Gm-Message-State: APf1xPBX+5L1er2dLhdEGRqjzDWycVZokDWK5paU8pZjYiTjUIoN6kpX ivr+qAmzLyGF7qhEYruQYNmQww== X-Google-Smtp-Source: AG47ELvIJlN1A+iUF5QPZ8CwS3Bu6kftGZ9NMGJR3+kSyRSo/5VNSOvlmLADfp4iWwsAsW7gLCFang== X-Received: by 2002:a17:902:2cc1:: with SMTP id n59-v6mr6185346plb.215.1519843572074; Wed, 28 Feb 2018 10:46:12 -0800 (PST) Received: from goldengate.amcc.com ([206.80.4.98]) by smtp.gmail.com with ESMTPSA id 14sm5491096pfi.132.2018.02.28.10.46.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 28 Feb 2018 10:46:10 -0800 (PST) From: Feng Kan To: rjw@rjwysocki.net, linux-pm@vger.kernel.org, lorenzo.pieralisi@arm.com, linux-arm-kernel@lists.infradead.org, linux-pci@vger.kernel.org, bhelgaas@google.com Cc: Feng Kan , Toan Le Subject: [PATCH] PM / core: move device and its children to end of dpm list Date: Wed, 28 Feb 2018 10:45:55 -0800 Message-Id: <1519843555-982-1-git-send-email-fkan@apm.com> X-Mailer: git-send-email 2.7.4 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When bridge and its endpoint is enumated the devices are added to the dpm list. Afterward, the bridge defers probe when IOMMU is not ready. This causes the bridge to be moved to the end of the dpm list when deferred probe kicks in. The order of the dpm list for bridge and endpoint is reversed. Add reordering code to re-position the bridge and its children so the order for suspend and resume is not altered. Signed-off-by: Feng Kan Signed-off-by: Toan Le --- drivers/base/core.c | 20 ++++++++++++++++++++ drivers/base/dd.c | 8 ++++---- include/linux/device.h | 3 +++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 110230d..0b4ad99 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -148,6 +148,26 @@ static int device_reorder_to_tail(struct device *dev, void *not_used) } /** + * device_pm_reorder - reorder device and its children to end of dpm list + * @dev: current device pointer + * + * This is a lock held version of reordering the device to dpm list tail. + * This will move the device to the end of the dpm list if it not registered. + * Afterward, it will iterate through its children and do the same for them. + */ +void device_pm_reorder(struct device *dev) +{ + int idx; + + idx = device_links_read_lock(); + device_pm_lock(); + device_reorder_to_tail(dev, NULL); + device_pm_unlock(); + device_links_read_unlock(idx); +} +EXPORT_SYMBOL_GPL(device_pm_reorder); + +/** * device_link_add - Create a link between two devices. * @consumer: Consumer end of the link. * @supplier: Supplier end of the link. diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 2c964f5..3223a30 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -121,11 +121,11 @@ static void deferred_probe_work_func(struct work_struct *work) * Force the device to the end of the dpm_list since * the PM code assumes that the order we add things to * the list is a good order for suspend but deferred - * probe makes that very unsafe. + * probe makes that very unsafe. Also move any children + * belong to the device to the end of the list as well. + * This way the suspend resume order won't be corrupted. */ - device_pm_lock(); - device_pm_move_last(dev); - device_pm_unlock(); + device_pm_reorder(dev); dev_dbg(dev, "Retrying from deferred list\n"); if (initcall_debug && !initcalls_done) diff --git a/include/linux/device.h b/include/linux/device.h index 9d32000..1ec12d5 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1272,6 +1272,9 @@ extern void devm_device_remove_group(struct device *dev, /* debugging and troubleshooting/diagnostic helpers. */ extern const char *dev_driver_string(const struct device *dev); +/* reorder device and its children to end of dpm list */ +void device_pm_reorder(struct device *dev); + /* Device links interface. */ struct device_link *device_link_add(struct device *consumer, struct device *supplier, u32 flags);