From patchwork Wed Oct 28 06:04:39 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shubhrajyoti Datta X-Patchwork-Id: 537209 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 7FAF41402D6 for ; Wed, 28 Oct 2015 17:19:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754216AbbJ1GTY (ORCPT ); Wed, 28 Oct 2015 02:19:24 -0400 Received: from mail-bl2on0098.outbound.protection.outlook.com ([65.55.169.98]:25149 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751237AbbJ1GTW (ORCPT ); Wed, 28 Oct 2015 02:19:22 -0400 Received: from BL2FFO11FD021.protection.gbl (10.173.160.32) by BL2FFO11HUB021.protection.gbl (10.173.161.45) with Microsoft SMTP Server (TLS) id 15.1.306.13; Wed, 28 Oct 2015 06:04:55 +0000 Authentication-Results: spf=pass (sender IP is 149.199.60.100) smtp.mailfrom=xilinx.com; lists.infradead.org; dkim=none (message not signed) header.d=none;lists.infradead.org; dmarc=bestguesspass action=none header.from=xilinx.com; Received-SPF: Pass (protection.outlook.com: domain of xilinx.com designates 149.199.60.100 as permitted sender) receiver=protection.outlook.com; client-ip=149.199.60.100; helo=xsj-pvapsmtpgw02; Received: from xsj-pvapsmtpgw02 (149.199.60.100) by BL2FFO11FD021.mail.protection.outlook.com (10.173.161.100) with Microsoft SMTP Server (TLS) id 15.1.306.13 via Frontend Transport; Wed, 28 Oct 2015 06:04:55 +0000 Received: from unknown-38-66.xilinx.com ([149.199.38.66]:41203 helo=xsj-pvapsmtp01) by xsj-pvapsmtpgw02 with esmtp (Exim 4.63) (envelope-from ) id 1ZrJqw-0004WD-Rl; Tue, 27 Oct 2015 23:04:54 -0700 Received: from [127.0.0.1] (helo=localhost) by xsj-pvapsmtp01 with smtp (Exim 4.63) (envelope-from ) id 1ZrJqw-0000Rw-NI; Tue, 27 Oct 2015 23:04:54 -0700 Received: from [172.23.146.171] (helo=xhdl3763.xilinx.com) by xsj-pvapsmtp01 with esmtp (Exim 4.63) (envelope-from ) id 1ZrJqr-0000RL-J6; Tue, 27 Oct 2015 23:04:50 -0700 Received: by xhdl3763.xilinx.com (Postfix, from userid 9049) id B9BF12CE0424; Wed, 28 Oct 2015 11:34:48 +0530 (IST) From: Shubhrajyoti Datta To: CC: , , , , , Shubhrajyoti Datta Subject: [PATCHv2] i2c: cadence: Enable power management Date: Wed, 28 Oct 2015 11:34:39 +0530 Message-ID: <1446012279-2578-1-git-send-email-shubhraj@xilinx.com> X-Mailer: git-send-email 2.1.2 X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.0.0.1202-21904.005 X-TM-AS-User-Approved-Sender: Yes;Yes X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD021; 1:anmB3/FfWwRgLkVDwC1UWyTEPgzTelOYi3FZ/eN9i4gOKiobUZ7lT2jAMLNb6xlu0slXBr7JJm6hX9WZN1WeH4dLY3tr1nZtxmRVzrDdXgVjqdHOuHDu9EQe22+kkFerZBo0zyIiPswbifFbOyE6SMaEzz2UW4u1iPm5rD1TJEfxq7dIjZYHPeYj5xz84KtuUxojzwooPfqx6zfFfL5iILFrxIGGHvuPEJ/xX6C79btCgIyHHTrsI1cCvnBSJ0W7xVv4JDUClbTe31S51n7qr3RaoyllkJ7Gsy+UOOAd6lDGabGG6S9zPv2vFsfdXKvDURwhTouh5YuzpGsqZwhQApIE2KiOzR9GIBHPeJDfJBwTBed4PyV0wPsiv3zi2ma2LzMox8pPvIBZgqnRz/Aa7FRORcoEcxq2xKkAFoznOj0= X-Forefront-Antispam-Report: CIP:149.199.60.100; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(2980300002)(438002)(189002)(199003)(87936001)(5007970100001)(86362001)(6806005)(189998001)(229853001)(63266004)(52956003)(11100500001)(50226001)(90966002)(5001960100002)(2351001)(42186005)(5008740100001)(110136002)(5003940100001)(103686003)(106466001)(107886002)(48376002)(50466002)(36386004)(92566002)(5001920100001)(50986999)(45336002)(36756003)(33646002)(47776003)(19580405001)(4001430100002)(19580395003)(46386002)(81156007)(107986001)(5001870100001); DIR:OUT; SFP:1101; SCL:1; SRVR:BL2FFO11HUB021; H:xsj-pvapsmtpgw02; FPR:; SPF:Pass; PTR:unknown-60-100.xilinx.com,xapps1.xilinx.com; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11HUB021; 2:vi5Y/3hLnKwC/xYYfvVfSo6jRbkOxw7mmoObI3MoNKygYOO1Q1SnktxA3VmJmxR12YpDWQ+G6p9b/rhVK5ufu9IP2k2mGzGuClM0rIqkLb9uZg8ci591e/kw5T2BCDgFvxQhx8tL2ZKDgPHjboE+Q2yX9qAQC4LXBLk1VkXi+Ow=; 3:S7IkdNHPZzO/TVT8HA9jEVBGcgaQdvhywigDAflS1hYistvUcoUTAqemfIC8sFxAv9cyHx+Wa+jCtp1GdIyFMqMiZDzQzuQufqSGUhXm8mW1uUXgJPBEtYc6kYtXD4BZMT7E2N5x5WB5uaoxCYqi81ED/8rX/X0C2Wplsy24J7oPxPfuW1FPwfOdVIDeYok5EBXdtA1jtOMoK19V31IqdjoIE8x2F7ZgWq5ie1NhN0KvsmOLlRzVvUcaUg3fSCNxy5dhxw6Y9OvDR6q3TEHW8A==; 25:ZWxMwNGyjI2jRuTeuASTEybWUHk9tSVgIqZwkzUF/H/LJTxh20ArxXW2uBwuqq5c7bvOVxHsgKk5WNPhm87ev9hXi96Ujl7No5OBGHEg3Yog+wXVuDYRxYksyveLFktwsmm8ELKdB4gE4WpsfXbwNjV5cqwDmxRZSCZXOuFApfXw7QIce1yEFVU9z2msd0oEgF7yLWLIzydhoestPs1QfZ3bSujfvUZRCSraEX+kQJad2NKRVzFTVYFgHe1sQKp9kcPKrMykWfz5enM8Lc7t3Q== X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(8251501001); SRVR:BL2FFO11HUB021; X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11HUB021; 20:PCFkbBkiGqKFaXZuCQTEg9j2Rg37C4Be/LrDNjbUqikcSu4t6LmnKPbVl2iBdsl3Zmp2OLK5mXluDlJZOAYwa7OF4PjW9zoo1q9XXx/Lt0vtIZn5c7oGEKljpzsi1o9sAp8YYgD/EtYX32sArKMo2KkUK8Ty/L/kreF7lYireo+rfPLMkbWdUGeRCJ6MYTEpIhbffMrzwZO+LPP2fOtNt0W2piZgPGltxqcwCLCfcxorFVelPquNoU0FQYU3+ehLYHSaIMcTyM3KYjtXCM0tyja63h6dnY8HLjnw1k4nme2zqvncGIi8u5j4ft9Cu/QdoZPZwH4dWeym8hcFwAvQtGHd7qgeeQDSGN5zqLDvw57IpBRQEDqy1YceLAoVil0qpfkgkFy9tZH3s8mS6wdMBUmavX6L5Y2DXHcuMo7teDCRTGOyRkeZlHhuS2nRNAIA9K0E0GWE9EjqTO6QU2VFu3II0C33vNJNMSitNCHuYe18ct7T4a+kYef8Zxt66L6u; 4:C/5D6IKQHZsCSGf+t+nRf7LSMuyOZnPFq/u+64fyHtpEpLQS/HdkAxldMLvv3L74VEqL1IQo+xDmRONeVqbLaT/zyABOM3Jt8aG+nJOPnPzkVQSliGNa8TRpNh5eGL1KDWmZIPN7BZpfw9PLfitUyOYeh94zD2UJ5r+R4j/nHCk70XRIkd/e6vrmFZhVg6OxmtBlH4Ot3zruJ6KhWz5zTADK7qGMT7ElN9q6WIPxo1QaRQhtgV6+b1Lom5pxfMYjimWt+8P67m5rfEWH3ZJxAwNS/oBJqlhaPkv0kmaJkSAPw9+uRE//GqCxshGW8046sdSjd1zb9lMuzdRQzG+PhzoY3eZnGN5H2xsXLP4TNW31o6novAR3ZiAwjxVwZdFPWOBeFlCz2+Z7kw5LQkAJsQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(192813158149592); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(520078)(5005006)(8121501046)(3002001)(10201501044)(102215026); SRVR:BL2FFO11HUB021; BCL:0; PCL:0; RULEID:; SRVR:BL2FFO11HUB021; X-Forefront-PRVS: 0743E8D0A6 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BL2FFO11HUB021; 23:giOVPundujJZhpWItxQoDHB52GyDyAMYWwt/+s3i?= =?us-ascii?Q?nRRBMLp+5pesdeVzyZOQVOpOIxwNW1A1U0auYtnn1McQ8WxGs8Z/W6Q6M1m7?= =?us-ascii?Q?C0AQxVS95+NPfzszpYv8sy8yfznh++67opiyCUw7Fz36KJA4LKaC0OPURoMU?= =?us-ascii?Q?BZbULGVNhiyTFFjgoPjA9zdj4Tr/cxxCe+TBsv8AEF/CDgbSrKo+60EWbXuY?= =?us-ascii?Q?+hkb1D5EbYKzttL1e987iwnbYj4HJ/GaRbtTwckHGZIl+Fw6xv3l6zGytGxb?= =?us-ascii?Q?XgvwfILc40xYT08chEjq6tad0YZY6AiHDr/i4WIxP/04GUssjaQDRPp5kWS8?= =?us-ascii?Q?WVnohuvNg4osrI59poWZDPh+kEtVKrddBsyf2URVPpJwEeJ/3aso40awPkb4?= =?us-ascii?Q?Y5aTi3J1mcP5tmO/tAo0QuWRCRbHO8bOZI3K+DzTrryNKb8C6JrsN1ZsdxA5?= =?us-ascii?Q?uZBy0Dkm6YjozE8izabHSnfQ/rx3CmOtZTqfZEY37y9IcBpCzCfXuYNM3qVO?= =?us-ascii?Q?wFiMGjTlGs2Mv+4I/YRdhal1Js19yz2Mm2cBeeRMT+bKt+q5Bcqmwh9u9YRR?= =?us-ascii?Q?ca6mf45KYR/saKWF34pYrXxBA7b8cyntDe1Qk5q3pfqe6k02445wNCAcKf+1?= =?us-ascii?Q?Ulsg1E0ph1chqazsU9uPjqk9FkBA0MdR9w1dCmifIruMtdzHnvASF+8p1Y2g?= =?us-ascii?Q?RyDFR9aAso3cE+xSI4GhPU5sVY84BxnywdWlR65CR+HJRBOcxWywSIa2O+SG?= =?us-ascii?Q?48G0eoqk7Put77oj0X9etgROeycUgZM474lj/NnDDl6hH3T64rZdUms9LWv7?= =?us-ascii?Q?NFFl2wD1Q+1sMXcjV+EMhQ82FnHrjARNv8b+l4ouGmFQETroIYTbusfsGS/3?= =?us-ascii?Q?wubiRNd5oz22mUUJKrf4tdHrf4Mj7+u0O2amWnk50Yotz6UdRWjBrkhz2uDI?= =?us-ascii?Q?RavAmcP+jVO6Kmn2mlj87M1YOyRE8TfgDWiauLu5Ev7eX6pj7wx6A2oJwWDP?= =?us-ascii?Q?acZxgWdpTq8HoS07/Gq5vB8M7O3GvWq62pvr/my+nlu0pUIo1X7uTjUoPwSC?= =?us-ascii?Q?yPXKJvVP8ZcaLoT7ZpDXKfL+mYdlB+jHhucPK2LaXD9hwqXJdAz8L4V/qlB0?= =?us-ascii?Q?AOobYig26vzOZpIqn8n/B6eTE+cr9U4R?= X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11HUB021; 5:ZzIdjDHS6Vg63fmCMK8h8n34ijxxCOzwqYITf2SKdMmBT87uXbBunbfWpwmYdRR4Boo+U5ykozr2+mLefAuC2+pqq2+6j595vbWnOBtzoNl/NSJpBx7RmB5ofVCFmQqVnwrHfy7iLffg8Oy7A/H21A==; 24:F3cdqkvOLSEfHse4AiHeFeX1cQaL4B6egXSgOuUFmvyL6HN+QuGxvGVQeLB+zj3L1Uw9omZEQ3XkvbKFMRVvYPHq/wqwz9L7EYUNvjjczSE= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Oct 2015 06:04:55.5944 (UTC) X-MS-Exchange-CrossTenant-Id: 657af505-d5df-48d0-8300-c31994686c5c X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=657af505-d5df-48d0-8300-c31994686c5c; Ip=[149.199.60.100]; Helo=[xsj-pvapsmtpgw02] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL2FFO11HUB021 Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Currently the clocks are enabled at probe and disabled at remove. This patch enables the clocks at the start of transfer and disables after it. Also adapts to runtime pm. Remove xi2c->suspended and use pm runtime status instead. converts dev pm to const to silence a checkpatch warning. Signed-off-by: Shubhrajyoti Datta --- changes since v1: update the cc list. drivers/i2c/busses/i2c-cadence.c | 74 ++++++++++++++++++++++++-------------- 1 files changed, 47 insertions(+), 27 deletions(-) diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index f5227c5..ba3c67c 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -18,6 +18,7 @@ #include #include #include +#include /* Register offsets for the I2C device. */ #define CDNS_I2C_CR_OFFSET 0x00 /* Control Register, RW */ @@ -98,6 +99,8 @@ CDNS_I2C_IXR_COMP) #define CDNS_I2C_TIMEOUT msecs_to_jiffies(1000) +/* timeout for pm runtime autosuspend */ +#define CNDS_I2C_PM_TIMEOUT 1000 /* ms */ #define CDNS_I2C_FIFO_DEPTH 16 /* FIFO depth at which the DATA interrupt occurs */ @@ -130,7 +133,6 @@ * @xfer_done: Transfer complete status * @p_send_buf: Pointer to transmit buffer * @p_recv_buf: Pointer to receive buffer - * @suspended: Flag holding the device's PM status * @send_count: Number of bytes still expected to send * @recv_count: Number of bytes still expected to receive * @curr_recv_count: Number of bytes to be received in current transfer @@ -143,6 +145,7 @@ * @quirks: flag for broken hold bit usage in r1p10 */ struct cdns_i2c { + struct device *dev; void __iomem *membase; struct i2c_adapter adap; struct i2c_msg *p_msg; @@ -150,7 +153,6 @@ struct cdns_i2c { struct completion xfer_done; unsigned char *p_send_buf; unsigned char *p_recv_buf; - u8 suspended; unsigned int send_count; unsigned int recv_count; unsigned int curr_recv_count; @@ -623,10 +625,16 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, u32 reg; struct cdns_i2c *id = adap->algo_data; bool hold_quirk; + + ret = pm_runtime_get_sync(id->dev); + if (ret < 0) + return ret; /* Check if the bus is free */ if (msgs->len) - if (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_BA) - return -EAGAIN; + if (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_BA) { + ret = -EAGAIN; + goto out; + } hold_quirk = !!(id->quirks & CDNS_I2C_BROKEN_HOLD_BIT); /* @@ -645,7 +653,8 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, if (msgs[count].flags & I2C_M_RD) { dev_warn(adap->dev.parent, "Can't do repeated start after a receive message\n"); - return -EOPNOTSUPP; + ret = -EOPNOTSUPP; + goto out; } } id->bus_hold_flag = 1; @@ -663,20 +672,26 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ret = cdns_i2c_process_msg(id, msgs, adap); if (ret) - return ret; + goto out; /* Report the other error interrupts to application */ if (id->err_status) { cdns_i2c_master_reset(adap); - if (id->err_status & CDNS_I2C_IXR_NACK) - return -ENXIO; - - return -EIO; + if (id->err_status & CDNS_I2C_IXR_NACK) { + ret = -ENXIO; + goto out; + } + ret = -EIO; + goto out; } } - return num; + ret = num; +out: + pm_runtime_mark_last_busy(id->dev); + pm_runtime_put_autosuspend(id->dev); + return ret; } /** @@ -815,7 +830,7 @@ static int cdns_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long struct clk_notifier_data *ndata = data; struct cdns_i2c *id = to_cdns_i2c(nb); - if (id->suspended) + if (pm_runtime_suspended(id->dev)) return NOTIFY_OK; switch (event) { @@ -863,14 +878,12 @@ static int cdns_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long * * Return: 0 always */ -static int __maybe_unused cdns_i2c_suspend(struct device *_dev) +static int __maybe_unused cdns_i2c_runtime_suspend(struct device *dev) { - struct platform_device *pdev = container_of(_dev, - struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct cdns_i2c *xi2c = platform_get_drvdata(pdev); clk_disable(xi2c->clk); - xi2c->suspended = 1; return 0; } @@ -883,26 +896,25 @@ static int __maybe_unused cdns_i2c_suspend(struct device *_dev) * * Return: 0 on success and error value on error */ -static int __maybe_unused cdns_i2c_resume(struct device *_dev) +static int __maybe_unused cdns_i2c_runtime_resume(struct device *dev) { - struct platform_device *pdev = container_of(_dev, - struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct cdns_i2c *xi2c = platform_get_drvdata(pdev); int ret; ret = clk_enable(xi2c->clk); if (ret) { - dev_err(_dev, "Cannot enable clock.\n"); + dev_err(dev, "Cannot enable clock.\n"); return ret; } - xi2c->suspended = 0; - return 0; } -static SIMPLE_DEV_PM_OPS(cdns_i2c_dev_pm_ops, cdns_i2c_suspend, - cdns_i2c_resume); +static const struct dev_pm_ops cdns_i2c_dev_pm_ops = { + SET_RUNTIME_PM_OPS(cdns_i2c_runtime_suspend, + cdns_i2c_runtime_resume, NULL) +}; static const struct cdns_platform_data r1p10_i2c_def = { .quirks = CDNS_I2C_BROKEN_HOLD_BIT, }; @@ -935,6 +947,7 @@ static int cdns_i2c_probe(struct platform_device *pdev) if (!id) return -ENOMEM; + id->dev = &pdev->dev; platform_set_drvdata(pdev, id); match = of_match_node(cdns_i2c_of_match, pdev->dev.of_node); @@ -966,10 +979,14 @@ static int cdns_i2c_probe(struct platform_device *pdev) return PTR_ERR(id->clk); } ret = clk_prepare_enable(id->clk); - if (ret) { + if (ret) dev_err(&pdev->dev, "Unable to enable clock.\n"); - return ret; - } + + pm_runtime_enable(id->dev); + pm_runtime_set_autosuspend_delay(id->dev, CNDS_I2C_PM_TIMEOUT); + pm_runtime_use_autosuspend(id->dev); + pm_runtime_set_active(id->dev); + id->clk_rate_change_nb.notifier_call = cdns_i2c_clk_notifier_cb; if (clk_notifier_register(id->clk, &id->clk_rate_change_nb)) dev_warn(&pdev->dev, "Unable to register clock notifier.\n"); @@ -1019,6 +1036,8 @@ static int cdns_i2c_probe(struct platform_device *pdev) err_clk_dis: clk_disable_unprepare(id->clk); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_disable(&pdev->dev); return ret; } @@ -1037,6 +1056,7 @@ static int cdns_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&id->adap); clk_notifier_unregister(id->clk, &id->clk_rate_change_nb); clk_disable_unprepare(id->clk); + pm_runtime_disable(&pdev->dev); return 0; }