From patchwork Thu Mar 30 12:04:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Nikula X-Patchwork-Id: 9654003 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 D532C60113 for ; Thu, 30 Mar 2017 12:05:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C55B228581 for ; Thu, 30 Mar 2017 12:05:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B9B052858A; Thu, 30 Mar 2017 12:05:07 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 5388628581 for ; Thu, 30 Mar 2017 12:05:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933371AbdC3MFH (ORCPT ); Thu, 30 Mar 2017 08:05:07 -0400 Received: from mga01.intel.com ([192.55.52.88]:33165 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933077AbdC3MFF (ORCPT ); Thu, 30 Mar 2017 08:05:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=intel.com; i=@intel.com; q=dns/txt; s=intel; t=1490875504; x=1522411504; h=from:to:cc:subject:date:message-id; bh=spIDoLoh4nLsmoUhnca1Gyo4n26SBDxogJiNMzKP0to=; b=LspoGMQ86pDWVpSwIiYxM/rAGHrcY8M+bSsjWBPeT/DwAflvw24pUkIo saHRZH4UksKS9k/p1f+UEDa9d72ovA==; Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Mar 2017 05:05:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,246,1486454400"; d="scan'208";a="1148795090" Received: from mylly.fi.intel.com (HELO mylly.fi.intel.com.) ([10.237.72.50]) by fmsmga002.fm.intel.com with ESMTP; 30 Mar 2017 05:05:01 -0700 From: Jarkko Nikula To: linux-i2c@vger.kernel.org Cc: linux-pm@vger.kernel.org, Wolfram Sang , "Rafael J . Wysocki" , John Stultz , Andy Shevchenko , Mika Westerberg , Jarkko Nikula Subject: [PATCH] i2c: designware: Do nothing in system suspend/resume when RT suspended Date: Thu, 30 Mar 2017 15:04:44 +0300 Message-Id: <20170330120444.12499-1-jarkko.nikula@linux.intel.com> X-Mailer: git-send-email 2.11.0 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 There is possibility to enter dw_i2c_plat_suspend() callback twice during system suspend under certain cases which is causing here warnings from clk_core_disable() and clk_core_unprepare() as well as accessing the registers that can be power gated. Commit 8503ff166504 ("i2c: designware: Avoid unnecessary resuming during system suspend") implemented a prepare callback that checks for runtime suspended device which allow PM core to set direct_complete flag and skip system suspend and resume callbacks. However it can still happen if nothing resumes the device prior system syspend (e.g. acpi_subsys_suspend()) and there is a slave device which unsets the direct_complete flag of the parent in __device_suspend() thus causing PM code to not skip the system suspend/resume callbacks. Avoid this by checking runtime status in suspend and resume callbacks and return directly if device is runtime suspended. This affects only system suspend/resume since during runtime suspend/resume runtime status is suspending (not suspended) or resuming. Signed-off-by: Jarkko Nikula Tested-by: John Stultz --- I'm able to trigger system suspend callback while device is runtime suspended by removing the pm_runtime_resume() call from drivers/mfd/intel-lpss.c: resume_lpss_device() and having unbound I2C slave (ACPI enumerated but doesn't bind due an error in probe function). In that case __device_suspend() for that unbound device has NULL suspend callback, and thus doesn't cause any runtime resume chain but still unsets the parent's direct_complete flag. John Stult has reported he can trigger this on HiKey board too. I'm not sure is this the right thing to do. It feels something the PM core should do but I'm not sure that either. One alternative could be to resume runtime suspended parent in in __device_suspend() right after where parent's direct_complete flag is unset. --- drivers/i2c/busses/i2c-designware-platdrv.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index a597ba32de7e..42a9cd09aa64 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -377,6 +377,9 @@ static int dw_i2c_plat_suspend(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); + if (pm_runtime_suspended(dev)) + return 0; + i2c_dw_disable(i_dev); i2c_dw_plat_prepare_clk(i_dev, false); @@ -388,6 +391,9 @@ static int dw_i2c_plat_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); + if (pm_runtime_suspended(dev)) + return 0; + i2c_dw_plat_prepare_clk(i_dev, true); i2c_dw_init(i_dev);