From patchwork Thu Feb 11 14:36:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Nikula X-Patchwork-Id: 8281011 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 A6A2ABEEE5 for ; Thu, 11 Feb 2016 14:38:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BB0C0203B1 for ; Thu, 11 Feb 2016 14:38:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B4B15203AD for ; Thu, 11 Feb 2016 14:38:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750857AbcBKOi3 (ORCPT ); Thu, 11 Feb 2016 09:38:29 -0500 Received: from mga02.intel.com ([134.134.136.20]:47264 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751366AbcBKOiI (ORCPT ); Thu, 11 Feb 2016 09:38:08 -0500 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 11 Feb 2016 06:38:07 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,431,1449561600"; d="scan'208";a="910036970" Received: from mylly.fi.intel.com (HELO mylly.fi.intel.com.) ([10.237.72.60]) by orsmga002.jf.intel.com with ESMTP; 11 Feb 2016 06:38:06 -0800 From: Jarkko Nikula To: Wolfram Sang Cc: Andy Shevchenko , Mika Westerberg , linux-i2c@vger.kernel.org, linux-pm@vger.kernel.org, Jarkko Nikula Subject: [PATCH] i2c: designware: Prevent runtime suspend during adapter registration Date: Thu, 11 Feb 2016 16:36:03 +0200 Message-Id: <1455201363-3278-1-git-send-email-jarkko.nikula@linux.intel.com> X-Mailer: git-send-email 2.7.0 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.1 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 There can be unnecessary runtime suspend-resume cycle during i2c-designware-platdrv probe when it registers the I2C adapter device. This happens because i2c-designware-platdrv is set to initially active platform device in its probe function and is a parent of I2C adapter. In that case power.usage_count of i2c-designware device is zero and pm_runtime_get()/pm_runtime_put() cycle during probe could put it into runtime suspend. This happens when the i2c_register_adapter() calls the device_register(): i2c_register_adapter device_register device_add bus_probe_device device_initial_probe __device_attach if (dev->parent) pm_runtime_get_sync(dev->parent) ... if (dev->parent) pm_runtime_put(dev->parent) After that the i2c_register_adapter() continues registering I2C slave devices. In case slave device probe does I2C transfers the parent will resume again and thus get a needless runtime suspend/resume cycle during adapter registration. Prevent this while retaining the runtime PM status of i2c-designware by only incrementing/decrementing device power usage count during I2C adapter registration. That makes sure there won't be spurious runtime PM status changes and lets the driver core to idle the device after probe finishes. Signed-off-by: Jarkko Nikula Acked-by: Mika Westerberg --- I sent earlier an RFC doing the same in i2c-core because it looked a few other I2C bus drivers might benefit too. However, as Alan pointed, it's bad form to do PM on your parent: http://www.spinics.net/lists/linux-i2c/msg22587.html After hacking a bit with PM in i2c-designware-pcidrv.c I can say this is only for i2c-designware-platdrv case. Runtime PM settings are a little different between platform and PCI devices. For instance runtime PM is enabled by default for PCI devices but forbidded and there seems be no reason to move runtime PM calls in i2c_dw_pci_probe(). Anyway, I decided to put PM usage count increment/decrement calls to i2c-designware-core.c: i2c_dw_probe() because change lines are more clear there, are more future proof and don't harm PCI case. --- drivers/i2c/busses/i2c-designware-core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 10fbd6d841e0..dfe35087b40d 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -883,9 +883,17 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) return r; } + /* + * Increment PM usage count during adapter registration in order to + * avoid possible spurious runtime suspend when adapter device is + * registered to the device core and immediate resume in case bus has + * registered I2C slaves that do I2C transfers in their probe. + */ + pm_runtime_get_noresume(dev->dev); r = i2c_add_numbered_adapter(adap); if (r) dev_err(dev->dev, "failure adding adapter: %d\n", r); + pm_runtime_put_noidle(dev->dev); return r; }