From patchwork Fri May 15 12:31:39 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jisheng Zhang X-Patchwork-Id: 6413901 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A4B8F9F1CC for ; Fri, 15 May 2015 12:37:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C1E8E20412 for ; Fri, 15 May 2015 12:37:34 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D965520456 for ; Fri, 15 May 2015 12:37:33 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YtEpf-0006Bd-JN; Fri, 15 May 2015 12:35:15 +0000 Received: from mx0a-0016f401.pphosted.com ([67.231.148.174]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YtEpc-00052T-0i for linux-arm-kernel@lists.infradead.org; Fri, 15 May 2015 12:35:12 +0000 Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.14.5/8.14.5) with SMTP id t4FCYiI0022648; Fri, 15 May 2015 05:34:50 -0700 Received: from sc-owa04.marvell.com ([199.233.58.150]) by mx0a-0016f401.pphosted.com with ESMTP id 1ucq1bbw7f-1 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Fri, 15 May 2015 05:34:49 -0700 Received: from maili.marvell.com (10.93.76.83) by SC-OWA04.marvell.com (10.93.76.33) with Microsoft SMTP Server id 8.3.327.1; Fri, 15 May 2015 05:34:47 -0700 Received: from xhacker.marvell.com (unknown [10.37.135.93]) by maili.marvell.com (Postfix) with ESMTP id C26EA3F703F; Fri, 15 May 2015 05:34:46 -0700 (PDT) From: Jisheng Zhang To: , Subject: [PATCH] i2c: designware: separate ops for system_sleep_pm and runtime_pm Date: Fri, 15 May 2015 20:31:39 +0800 Message-ID: <1431693099-2292-1-git-send-email-jszhang@marvell.com> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.14.151, 1.0.33, 0.0.0000 definitions=2015-05-15_02:2015-05-15, 2015-05-15, 1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=7.0.1-1402240000 definitions=main-1505150166 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150515_053512_082442_1DF55A20 X-CRM114-Status: GOOD ( 12.91 ) X-Spam-Score: -0.7 (/) Cc: Jisheng Zhang , linux-i2c@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 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.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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 Commit 1fc2fe204cb9 ("i2c: designware: Add runtime PM hooks") adds runtime pm support using the same ops for system sleep and runtime pm. When suspend to ram, the i2c host may have been runtime suspended, thus i2c_dw_disable() hangs. This patch fixes this issue by separating ops for system sleep pm and runtime pm, and in the system suspend/resume path, runtime pm apis are used to ensure the device is at correct state. Signed-off-by: Jisheng Zhang --- drivers/i2c/busses/i2c-designware-platdrv.c | 48 ++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 0a80e4a..d306397 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -298,14 +298,16 @@ static const struct of_device_id dw_i2c_of_match[] = { MODULE_DEVICE_TABLE(of, dw_i2c_of_match); #endif -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int dw_i2c_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); + pm_runtime_get_sync(dev); i2c_dw_disable(i_dev); - clk_disable_unprepare(i_dev->clk); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); return 0; } @@ -315,6 +317,32 @@ static int dw_i2c_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); + pm_runtime_get_sync(dev); + i2c_dw_init(i_dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return 0; +} +#endif + +#ifdef CONFIG_PM +static int dw_i2c_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); + + i2c_dw_disable(i_dev); + clk_disable_unprepare(i_dev->clk); + + return 0; +} + +static int dw_i2c_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); + clk_prepare_enable(i_dev->clk); if (!i_dev->pm_runtime_disabled) @@ -324,8 +352,18 @@ static int dw_i2c_resume(struct device *dev) } #endif -static UNIVERSAL_DEV_PM_OPS(dw_i2c_dev_pm_ops, dw_i2c_suspend, - dw_i2c_resume, NULL); +#ifdef CONFIG_PM +static const struct dev_pm_ops dw_i2c_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_suspend, dw_i2c_resume) + SET_RUNTIME_PM_OPS(dw_i2c_runtime_suspend, + dw_i2c_runtime_resume, NULL) +}; + +#define DW_I2C_DEV_PM_OPS (&dw_i2c_dev_pm_ops) + +#else +#define DW_I2C_DEV_PM_OPS NULL +#endif /* work with hotplug and coldplug */ MODULE_ALIAS("platform:i2c_designware"); @@ -337,7 +375,7 @@ static struct platform_driver dw_i2c_driver = { .name = "i2c_designware", .of_match_table = of_match_ptr(dw_i2c_of_match), .acpi_match_table = ACPI_PTR(dw_i2c_acpi_match), - .pm = &dw_i2c_dev_pm_ops, + .pm = DW_I2C_DEV_PM_OPS, }, };