From patchwork Thu Jul 11 10:16:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felipe Balbi X-Patchwork-Id: 2826279 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 040259F968 for ; Thu, 11 Jul 2013 10:17:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B8D2320178 for ; Thu, 11 Jul 2013 10:17:29 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 60B9120164 for ; Thu, 11 Jul 2013 10:17:28 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UxDw7-00054p-Tj; Thu, 11 Jul 2013 10:17:20 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UxDw5-00042p-Im; Thu, 11 Jul 2013 10:17:17 +0000 Received: from devils.ext.ti.com ([198.47.26.153]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UxDw2-00042U-Im for linux-arm-kernel@lists.infradead.org; Thu, 11 Jul 2013 10:17:15 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id r6BAGlDx015743; Thu, 11 Jul 2013 05:16:47 -0500 Received: from DFLE73.ent.ti.com (dfle73.ent.ti.com [128.247.5.110]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id r6BAGk9r012099; Thu, 11 Jul 2013 05:16:46 -0500 Received: from dlelxv22.itg.ti.com (172.17.1.197) by DFLE73.ent.ti.com (128.247.5.110) with Microsoft SMTP Server id 14.2.342.3; Thu, 11 Jul 2013 05:16:46 -0500 Received: from localhost (h79-1.vpn.ti.com [172.24.79.1]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id r6BAGjdS006801; Thu, 11 Jul 2013 05:16:46 -0500 From: Felipe Balbi To: Tony Lindgren Subject: [PATCH] arm: omap2plus: unidle devices which are about to probe Date: Thu, 11 Jul 2013 13:16:28 +0300 Message-ID: <1373537788-30413-1-git-send-email-balbi@ti.com> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <20130711092612.GG23892@arwen.pp.htv.fi> References: <20130711092612.GG23892@arwen.pp.htv.fi> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130711_061714_728855_E82941B9 X-CRM114-Status: GOOD ( 13.48 ) X-Spam-Score: -7.2 (-------) Cc: paul@pwsan.com, Kevin Hilman , mpfj-list@newflow.co.uk, Rajendra Nayak , vaibhav.bedia@ti.com, Felipe Balbi , Sourav Poddar , Linux OMAP Mailing List , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 in order to make HWMOD and pm_runtime agree on the initial state of the device, we will unidle the device and call pm_runtime_set_active() to tell pm_runtime that the device is really active. By the time driver's probe() is reached, a call to pm_runtime_get_sync() will not cause driver's ->runtime_resume() method to be called at first, only after a successful ->runtime_suspend(). Note that we must prevent pm_runtime transitions while driver is probing otherwise drivers would be suspended as soon as they call pm_runtime_use_autosuspend(). By calling pm_runtime_forbid() before probe() and pm_runtime_allow() after probe() we 'fix' that detail. Note that this patch was inspired by PCI's pci_pm_init(). Signed-off-by: Felipe Balbi --- boot tested on top of today's Linus master 6d128e1e72bf082542e85f72e6b7ddd704193588 with OMAP4 panda. Reached console prompt and, after setting a proper autosuspend delay, consoles autosuspend just fine. It needs to be tested on other platforms. ps: note that we also call pm_runtime_set_suspended(dev) from our late_initcall() to disable devices so that pm_runtime and HWMOD continue to aggree on device's state. arch/arm/mach-omap2/omap_device.c | 44 +++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 5cc9287..cb1fc1d 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -178,6 +178,26 @@ odbfd_exit: return ret; } +static void omap_device_pm_init(struct platform_device *pdev) +{ + omap_device_enable(pdev); + pm_runtime_forbid(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + device_enable_async_suspend(&pdev->dev); +} + +static void omap_device_pm_allow(struct platform_device *pdev) +{ + pm_runtime_allow(&pdev->dev); +} + +static void omap_device_pm_exit(struct platform_device *pdev) +{ + device_disable_async_suspend(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + omap_device_idle(pdev); +} + static int _omap_device_notifier_call(struct notifier_block *nb, unsigned long event, void *dev) { @@ -189,16 +209,31 @@ static int _omap_device_notifier_call(struct notifier_block *nb, if (pdev->archdata.od) omap_device_delete(pdev->archdata.od); break; + case BUS_NOTIFY_BIND_DRIVER: + if (pdev->archdata.od) + omap_device_pm_init(pdev); + break; + case BUS_NOTIFY_BOUND_DRIVER: + if (pdev->archdata.od) + omap_device_pm_allow(pdev); + break; + case BUS_NOTIFY_UNBOUND_DRIVER: + if (pdev->archdata.od) + omap_device_pm_exit(pdev); + break; case BUS_NOTIFY_ADD_DEVICE: if (pdev->dev.of_node) omap_device_build_from_dt(pdev); - /* fall through */ + break; default: - od = to_omap_device(pdev); - if (od) - od->_driver_status = event; + /* nothing */ + break; } + od = to_omap_device(pdev); + if (od) + od->_driver_status = event; + return NOTIFY_DONE; } @@ -855,6 +890,7 @@ static int __init omap_device_late_idle(struct device *dev, void *data) dev_warn(dev, "%s: enabled but no driver. Idling\n", __func__); omap_device_idle(pdev); + pm_runtime_set_suspended(dev); } }