From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751798AbdJTGeH (ORCPT ); Fri, 20 Oct 2017 02:34:07 -0400 Received: from mail-bn3nam01on0069.outbound.protection.outlook.com ([104.47.33.69]:60724 "EHLO NAM01-BN3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751360AbdJTGeE (ORCPT ); Fri, 20 Oct 2017 02:34:04 -0400 Authentication-Results: spf=pass (sender IP is 149.199.60.100) smtp.mailfrom=xilinx.com; intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=bestguesspass action=none header.from=xilinx.com; Subject: Re: [PATCH] dmaengine: zynqmp_dma: Add runtime pm support To: Michal Simek , Kedareswara rao Appana , , , , , CC: , , , Kedareswara rao Appana References: <1508310126-10926-1-git-send-email-appanad@xilinx.com> From: Michal Simek Message-ID: Date: Fri, 20 Oct 2017 08:33:48 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 7bit X-RCIS-Action: ALLOW X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.1.0.1062-23404.005 X-TM-AS-User-Approved-Sender: Yes;Yes X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:149.199.60.100;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(39860400002)(376002)(346002)(2980300002)(438002)(3190300001)(24454002)(189002)(199003)(4326008)(107886003)(65806001)(65956001)(230700001)(53546010)(23676002)(33646002)(31696002)(31686004)(64126003)(229853002)(8936002)(47776003)(6246003)(8676002)(81156014)(356003)(6666003)(2201001)(478600001)(2950100002)(86362001)(305945005)(63266004)(81166006)(106466001)(50466002)(54906003)(110136005)(58126008)(9786002)(54356999)(189998001)(76176999)(65826007)(36756003)(2906002)(106002)(5660300001)(50986999)(77096006)(316002)(36386004)(83506002)(107986001)(5001870100001);DIR:OUT;SFP:1101;SCL:1;SRVR:MWHPR02MB3389;H:xsj-pvapsmtpgw02;FPR:;SPF:Pass;PTR:xapps1.xilinx.com,unknown-60-100.xilinx.com;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BL2NAM02FT048;1:UjBheeutCHor6+tshcmYwphqaojxDxJ7JDsVSLfM7GsJeEKF2X1WuWrpc6Cjxh0gh/iU1FPBy57h3G2CcujO83HEcHQKdHE3KxSvuEmNW2cbtXT1/X0IKf1qT0O3EK4n X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 87084a45-dcf0-4dbf-e19e-08d517848c4d X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(8251501002)(4534020)(4602075)(4627075)(201703031133081)(201702281549075)(2017052603199);SRVR:MWHPR02MB3389; X-Microsoft-Exchange-Diagnostics: 1;MWHPR02MB3389;3:XyRalo65QfnRmUmxRQgja9IV81tcpi6A0hRe/vLa7ByhF6oRpgrmPm2ByQqQzdtIE5XeEJRyTW/7QxjGL/RZTVnWoOdHaXMrf5HUPy5BgXuOwttG/4X/UweOLNSqwGiqB/MfqDZL0q87kCm7EHqSRZ9QBj1HA3Jvoufa+Jvl2HS/a/fifxrpvYYO3fkRA9D9RukbUQjafyHBpYGD5an33A4hOurupH7RxQDPSM4dHu0ZBYHy2VsJFg1/ufdN+aRMsIrRkDv6bmVn7D2BrJHcO9EsJB2F32FAbkiEX3TjfG+aMWtZdZxL0oFS7fQvmxGVLc2Dv6qsPULLvj2v/Kh/m9M6zgOB3uHLN3RV5ugSXaU=;25:uHkYzaIXXvVcLQwOg28ppKmW8eMRg1Ie46c3NOrXSOtx7l0a9Rcac34k2KTg6jBVsSTjlTLffaZjO7gMCf569Yz12XIMPcU1xnfTnOqgLEMQCz7JfMD4HE24QKHqnufs42xupF8O9dzg6xSVBl06hO22qk5kyTesvIpk+FXY/2qfpznsB2RUXGC04lp/kgmPmeSuCFkm/zvJLyKMnAsJFT7cEVNcaGUSs4Wj2oHmEtKJkAa9NNmC/rSz6g7EuInAZq90OMfdswYslVIA7/Lv2wqrrnj+OQ9Wg+gKT8hqOWjx5NNudvdYDykkRmvjHW+Qd0JuRvlNd5nyN/x3udKNnw== X-MS-TrafficTypeDiagnostic: MWHPR02MB3389: X-Microsoft-Exchange-Diagnostics: 1;MWHPR02MB3389;31:o/i0cN9bGui2TNM5H5jWvLXG5+NCof7ErS+jkrrNpD3CmDi97Rn2hvRO671hqTjmZAJXlS0l97rD1pJuYkcQcFzLIJWD9nvhSNBgeGVmpTL4lx1z4QQo8ppWok4JhoysLarGopWhqOsFIozaB5YFzqhUxhJsVeucM/dyX3eNy1GDvnnWfH2Fal+AqJjvR+83stNXOTO7mFwaQIRjqfVf9of+Er2EnuKAh/hB1QpVHhA=;20:C3qwvibLK6ZEJtDapl1AqG89eNqNuiVwIBo0uTbAjngc2RDCKDgtorZcZ/k8QLLo6ulahKfjsCDWidLCcXfki52M35AmR956V18GewBMXM/ME/QxB5WIrMEO5aS63XneHCExk/iCsmc7qOrquXxQKILxxoedMjzbuCdN+Gl7WMuxRSAGflCe+cdtOt07879DAL9sBqwhBsjMQSiBHg99M8pIUsD/Mqh/yfWY3fUM3frsHpPaYu2OOMuN85UvNoSYiMZ/fzhHjTh4pWuhU5lVQ7udc6NqKdFMBzIek6fV3in+OKATgDQGiEUt0jeUBx1UNLu8uINP9pMYPSgxW5n8TN9a74V8dUP3qD/RXGHoAz2E7yX1g5wX4BIphruO0Du/TGetRKv3hLLWjD/TQ6XaBkV1FAcfr+GEwWrtI1foKsACmq3SA0+y0EMs3FtTTv9CYA4lVWFEVoEwWy1MmcX36reqTgDIkqEEDHWQK0scbOe77OYsI5oLFAzgXdTh2ksD X-Exchange-Antispam-Report-Test: UriScan:(192813158149592); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(10201501046)(93006095)(93004095)(3231020)(100000703101)(100105400095)(3002001)(6055026)(6041248)(20161123564025)(20161123560025)(20161123558100)(20161123555025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:MWHPR02MB3389;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:MWHPR02MB3389; X-Microsoft-Exchange-Diagnostics: 1;MWHPR02MB3389;4:erju82QPQ0lO3vBeu0ZejY8lQ2HJei7ET4ZaLbaPlncqRH+9CmCNYfiCXyP+rvC8dLWuQC9MN/N+yfr9Zpy8TIrq6mc3ngSw6flWAcH93EH0WuKiZVkcxPi90E1h4JYUGL2wlUVqUl+c5d4eVaOuWErbBulN9pGvSZP0nR51tc1VuBvKjkrYLkvDLqMw+PFnMJqI8UyT2Ji8pb6GALFFntW0wywjSCIEtzwcTbZewT0uzKHxcH7zTjpTk8zODm7Wxc1ejWxslC/SqPJ90/b0qIsMevMfbUH974gPl03R6qM= X-Forefront-PRVS: 0466CA5A45 X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtNV0hQUjAyTUIzMzg5OzIzOlpHL3c5VFpYd2s3dE0wTVB2bmNXMU9jMm9D?= =?utf-8?B?SWxDZThaak10RXpUTXVadmlBVjBNT0pkV1lic0p1cHRZK0NsalBXNTlINlYr?= =?utf-8?B?R0VkbHlJRk9oNnIvcmx5ZzBRaXJPQ214SXNLcUUwRlBNT1FvWTVSci84aHJK?= =?utf-8?B?UG9jWllxcS9JRVJOcTlzOW00emRKd1lQRW9ZQ3R1Z3ZDWkRmYStmRUh0eGJ0?= =?utf-8?B?WWxEbzR3QWZRWWxPc3FUd014aWFST09SbXNVTktMUU1KZDRrS0p3RnJrM2ZO?= =?utf-8?B?em5tc0txTkhRNVNzMzRCR3hKWUQ0Y2s2UnVPZG9wQ2xldWZLZ09CbVFMUVVo?= =?utf-8?B?SmZkMDIvekw3eWJiMUg3NEVjMW1FakRzeFAxMlorMFB5MWdlR0FFcHA4elVu?= =?utf-8?B?M1c0RDhlMjBheUhrc0pCckNmSkJIREdiZEJnNktSTVVHa2pPLzY1cnZzSjBW?= =?utf-8?B?djNjeGYyVXFlcHBuNmlGSE5SRUVPS1NyTWZseTBEUDF4MHlVZTRLcWhTZFRo?= =?utf-8?B?US9tUlFYaW4zenBSTGhMMWc0bTNIbENDRXEwTzZlSVBUcmtzQ0pDNTBPNzls?= =?utf-8?B?Y3RiM3p6dXVVSDh5eEUyRUxjYXJGQ1AyR1pjU2F1NkhJNXB2cmtIYkJvTkZo?= =?utf-8?B?b2Z4cVpVYkxkMTF4cFdyK0krSzFvMjFFUTZ6cFRYLzJZTjM4ekUzSUc5VzVu?= =?utf-8?B?TTlXS1FoZE1XZzNrVnlBT2tPaUc0amxXb2RkbTdVay9XTmI1R0lxSXB0L2JN?= =?utf-8?B?c1J0SkVWRjFONnNISHIzVjFSVFdmVkh6YU02ZXI3VnNZNVhGYjB2UUorT0Iy?= =?utf-8?B?alpJUzBGREV1SDFrUjBzOWVkQlJoYXVKNGRtdDczUGk1d3BhMDFXdGo1SjZ1?= =?utf-8?B?TmxQN0VlT0V2NmFLdlIxSTI5OVF6TEJ3WGNhdFhsYTRKWE1QZTBtd3JkeHlM?= =?utf-8?B?UldCREI5UVVjVEJUYm94eUVKcHJ3RTc2MmpyQkQrbm5mSVpzdjl1MzEzbzI2?= =?utf-8?B?cjNZZzlxVFZpUFNMclA4TnVrcCtmRkp6b3RRR0ZSV1p6TkJuMm9DcHpOaWx1?= =?utf-8?B?empIOG1kR1JEYm1XWG41UFIzWFAvUFR5TGRSRzVrWjBkWldaZW0yZFZHV0Vs?= =?utf-8?B?ZHl5SlEyTkpVc3FzYjhpd1pCSkRKMWxaUmlFaWMwZUVGakE5VjNPcUNaSlh5?= =?utf-8?B?YmIreEd5aXFZbnJaRnVSclBtZUtjUkNyeXIrVXVnaEUvYjRXVEpXRHFvVFFQ?= =?utf-8?B?aWtLM2Q3Nm9MRUxtTmdMMjRWRVp3T1dmTldXdmNjRFI1YlhEYTJsQnpWSWs1?= =?utf-8?B?NWN4ZDJqczB2QXUvWktiL2hUQ1FWczYyZE9YWUFXYTRVZkRTN1hxQVlKTWJW?= =?utf-8?B?Q2l2L1oyT3ZObjNMYVFtVU84cmFnYWQwNFlFL0ppTG5uZUVPT2cvcnNTcVRP?= =?utf-8?B?U2s1dUdOd1BNVFNiT2pLYjl5eTQ3RmcvcDZFRjJzZmFtcWdWM01TcFhibDNs?= =?utf-8?B?aFhlR0VHWEFYQjJFSFpEbEtSRUVaTXNEdFN4TFN0V3pma01GZXo4ZTUyTmI2?= =?utf-8?B?ak1rOGFrSFZjUVYzSmRPTXd1dnc5bTJhTWFHbVUxTHNQVUF5NlRmN2RDNzFk?= =?utf-8?B?TFdWUUg2MEZCWi9pR2FFS1lmai9MN2NIeW8wZDgwS2wxbGFadGZaM1ZweHFT?= =?utf-8?B?cTNJeUJ3NDBCVy9USFU3T1p3My9BNTVET2UrYTlJekNzejMvMWN0djhQWk9j?= =?utf-8?B?NTlzNlJCaUFFUjlUM1lMaVYrRFdYdk1WdUVaVkRjUDJLRFJ4V1BpcmZhSnNp?= =?utf-8?Q?PLpHEib8pGFYw?= X-Microsoft-Exchange-Diagnostics: 1;MWHPR02MB3389;6:aFA0eGeE9O/02GcdX2rsIjpYrNpeBGWI27psFX6iaTLdzD15bsPTYLcPcTBqvfeOi2lxpHRGGErE1hQx77nozeZAUlVbo+fzZZ7HasbFlOlC3b+Ex43pQrebqBYIXlk5tKdMuHEZu6vAqed9touTHDg1hPFNsqdBHcRM8wX+tcnKU3YUB7vlin0O2VjXmEH9ro/cujxdV2N7iA6856aZUL+UqOrsKUEcFZhr1Zqtrrgm5/mms+/PxTN0D9aOJS8khIU7s2Wn5/YBTfB07BV9GgGpiZNb4Sos5M2xAqF79QAOSHKvkMJarhvpfv+DJ4weZN0kN9Oop912db86S25rvg==;5:iWa9JXD+kzrKoa6yKzwJE9oeqPkAWAG6wiuR6uGYXLbb/E8qv2R1hAJei9IShoy/9SZzSg4w/3FIfrW/b1cFBEobc+DYUTD9pBkHY/KDeiFunI3qZQfjaAnrlrNusPVkqZEpeaZxQnUxKPS2TMKKBw==;24:QIdrKA1t4DUyPFIuAh6vqNIXVHloZoDRn1Urlgp0cxbbmSioZgRWXmg0SMjT++mVmKbjjGteNngNyXFk/Ad3whz/y+kqf9PozpJfy0X5Wi8=;7:fb1u/yIf34MFgh9ZpbWkns09mF7sCONmXNO8lxyXGFWhGWNJl/aDJ4PytDFLet0oCoQFwzdH0h2d3W41fuu02Nv9M00vRM6tIgDZRd3SdeYFmEK2ZNJ9wi18yZV8B9XOShwEDjbpRN+1QkQTe4K8bN+oyLvFLaqC81td/bT34ixOP41akpVrPezyhtOG+Fa1Q7xR366+6eDggIo4HtouBHKjL4HJyHlEovLj5w6vcQA= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Oct 2017 06:33:59.7016 (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: MWHPR02MB3389 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 20.10.2017 08:31, Michal Simek wrote: > On 18.10.2017 09:02, Kedareswara rao Appana wrote: >> This patch adds runtime pm support in the driver. >> >> Signed-off-by: Kedareswara rao Appana >> --- >> drivers/dma/xilinx/zynqmp_dma.c | 167 ++++++++++++++++++++++++++++++++-------- >> 1 file changed, 135 insertions(+), 32 deletions(-) >> >> diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c >> index 1ee1241..dd73831 100644 >> --- a/drivers/dma/xilinx/zynqmp_dma.c >> +++ b/drivers/dma/xilinx/zynqmp_dma.c >> @@ -23,6 +23,7 @@ >> #include >> #include >> #include >> +#include >> >> #include "../dmaengine.h" >> >> @@ -138,6 +139,8 @@ >> #define ZYNQMP_DMA_BUS_WIDTH_64 64 >> #define ZYNQMP_DMA_BUS_WIDTH_128 128 >> >> +#define ZDMA_PM_TIMEOUT 100 >> + >> #define ZYNQMP_DMA_DESC_SIZE(chan) (chan->desc_size) >> >> #define to_chan(chan) container_of(chan, struct zynqmp_dma_chan, \ >> @@ -211,8 +214,6 @@ struct zynqmp_dma_desc_sw { >> * @bus_width: Bus width >> * @src_burst_len: Source burst length >> * @dst_burst_len: Dest burst length >> - * @clk_main: Pointer to main clock >> - * @clk_apb: Pointer to apb clock >> */ >> struct zynqmp_dma_chan { >> struct zynqmp_dma_device *zdev; >> @@ -237,8 +238,6 @@ struct zynqmp_dma_chan { >> u32 bus_width; >> u32 src_burst_len; >> u32 dst_burst_len; >> - struct clk *clk_main; >> - struct clk *clk_apb; >> }; >> >> /** >> @@ -246,11 +245,15 @@ struct zynqmp_dma_chan { >> * @dev: Device Structure >> * @common: DMA device structure >> * @chan: Driver specific DMA channel >> + * @clk_main: Pointer to main clock >> + * @clk_apb: Pointer to apb clock >> */ >> struct zynqmp_dma_device { >> struct device *dev; >> struct dma_device common; >> struct zynqmp_dma_chan *chan; >> + struct clk *clk_main; >> + struct clk *clk_apb; >> }; >> >> static inline void zynqmp_dma_writeq(struct zynqmp_dma_chan *chan, u32 reg, >> @@ -461,7 +464,11 @@ static int zynqmp_dma_alloc_chan_resources(struct dma_chan *dchan) >> { >> struct zynqmp_dma_chan *chan = to_chan(dchan); >> struct zynqmp_dma_desc_sw *desc; >> - int i; >> + int i, ret; >> + >> + ret = pm_runtime_get_sync(chan->dev); >> + if (ret < 0) >> + return ret; >> >> chan->sw_desc_pool = kzalloc(sizeof(*desc) * ZYNQMP_DMA_NUM_DESCS, >> GFP_KERNEL); >> @@ -664,6 +671,8 @@ static void zynqmp_dma_free_chan_resources(struct dma_chan *dchan) >> (2 * ZYNQMP_DMA_DESC_SIZE(chan) * ZYNQMP_DMA_NUM_DESCS), >> chan->desc_pool_v, chan->desc_pool_p); >> kfree(chan->sw_desc_pool); >> + pm_runtime_mark_last_busy(chan->dev); >> + pm_runtime_put_autosuspend(chan->dev); >> } >> >> /** >> @@ -841,8 +850,6 @@ static void zynqmp_dma_chan_remove(struct zynqmp_dma_chan *chan) >> devm_free_irq(chan->zdev->dev, chan->irq, chan); >> tasklet_kill(&chan->tasklet); >> list_del(&chan->common.device_node); >> - clk_disable_unprepare(chan->clk_apb); >> - clk_disable_unprepare(chan->clk_main); >> } >> >> /** >> @@ -907,30 +914,6 @@ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev, >> "zynqmp-dma", chan); >> if (err) >> return err; >> - chan->clk_main = devm_clk_get(&pdev->dev, "clk_main"); >> - if (IS_ERR(chan->clk_main)) { >> - dev_err(&pdev->dev, "main clock not found.\n"); >> - return PTR_ERR(chan->clk_main); >> - } >> - >> - chan->clk_apb = devm_clk_get(&pdev->dev, "clk_apb"); >> - if (IS_ERR(chan->clk_apb)) { >> - dev_err(&pdev->dev, "apb clock not found.\n"); >> - return PTR_ERR(chan->clk_apb); >> - } >> - >> - err = clk_prepare_enable(chan->clk_main); >> - if (err) { >> - dev_err(&pdev->dev, "Unable to enable main clock.\n"); >> - return err; >> - } >> - >> - err = clk_prepare_enable(chan->clk_apb); >> - if (err) { >> - clk_disable_unprepare(chan->clk_main); >> - dev_err(&pdev->dev, "Unable to enable apb clock.\n"); >> - return err; >> - } >> >> chan->desc_size = sizeof(struct zynqmp_dma_desc_ll); >> chan->idle = true; >> @@ -953,6 +936,87 @@ static struct dma_chan *of_zynqmp_dma_xlate(struct of_phandle_args *dma_spec, >> } >> >> /** >> + * zynqmp_dma_suspend - Suspend method for the driver >> + * @dev: Address of the device structure >> + * >> + * Put the driver into low power mode. >> + * Return: 0 on success and failure value on error >> + */ >> +static int __maybe_unused zynqmp_dma_suspend(struct device *dev) >> +{ >> + if (!device_may_wakeup(dev)) >> + return pm_runtime_force_suspend(dev); >> + >> + return 0; >> +} >> + >> +/** >> + * zynqmp_dma_resume - Resume from suspend >> + * @dev: Address of the device structure >> + * >> + * Resume operation after suspend. >> + * Return: 0 on success and failure value on error >> + */ >> +static int __maybe_unused zynqmp_dma_resume(struct device *dev) >> +{ >> + if (!device_may_wakeup(dev)) >> + return pm_runtime_force_resume(dev); >> + >> + return 0; >> +} >> + >> +/** >> + * zynqmp_dma_runtime_suspend - Runtime suspend method for the driver >> + * @dev: Address of the device structure >> + * >> + * Put the driver into low power mode. >> + * Return: 0 always >> + */ >> +static int __maybe_unused zynqmp_dma_runtime_suspend(struct device *dev) >> +{ >> + struct zynqmp_dma_device *zdev = dev_get_drvdata(dev); >> + >> + clk_disable_unprepare(zdev->clk_main); >> + clk_disable_unprepare(zdev->clk_apb); >> + >> + return 0; >> +} >> + >> +/** >> + * zynqmp_dma_runtime_resume - Runtime suspend method for the driver >> + * @dev: Address of the device structure >> + * >> + * Put the driver into low power mode. >> + * Return: 0 always >> + */ >> +static int __maybe_unused zynqmp_dma_runtime_resume(struct device *dev) >> +{ >> + struct zynqmp_dma_device *zdev = dev_get_drvdata(dev); >> + int err; >> + >> + err = clk_prepare_enable(zdev->clk_main); >> + if (err) { >> + dev_err(dev, "Unable to enable main clock.\n"); >> + return err; >> + } >> + >> + err = clk_prepare_enable(zdev->clk_apb); >> + if (err) { >> + dev_err(dev, "Unable to enable apb clock.\n"); >> + clk_disable_unprepare(zdev->clk_main); >> + return err; >> + } >> + >> + return 0; >> +} >> + >> +static const struct dev_pm_ops zynqmp_dma_dev_pm_ops = { >> + SET_SYSTEM_SLEEP_PM_OPS(zynqmp_dma_suspend, zynqmp_dma_resume) >> + SET_RUNTIME_PM_OPS(zynqmp_dma_runtime_suspend, >> + zynqmp_dma_runtime_resume, NULL) >> +}; >> + >> +/** >> * zynqmp_dma_probe - Driver probe function >> * @pdev: Pointer to the platform_device structure >> * >> @@ -984,12 +1048,39 @@ static int zynqmp_dma_probe(struct platform_device *pdev) >> p->device_config = zynqmp_dma_device_config; >> p->dev = &pdev->dev; >> >> + zdev->clk_main = devm_clk_get(&pdev->dev, "clk_main"); >> + if (IS_ERR(zdev->clk_main)) { >> + dev_err(&pdev->dev, "main clock not found.\n"); >> + return PTR_ERR(zdev->clk_main); >> + } >> + >> + zdev->clk_apb = devm_clk_get(&pdev->dev, "clk_apb"); >> + if (IS_ERR(zdev->clk_apb)) { >> + dev_err(&pdev->dev, "apb clock not found.\n"); >> + return PTR_ERR(zdev->clk_apb); >> + } >> + >> + ret = clk_prepare_enable(zdev->clk_main); >> + if (ret) { >> + dev_err(&pdev->dev, "Unable to enable main clock.\n"); >> + return ret; >> + } >> + >> + ret = clk_prepare_enable(zdev->clk_apb); >> + if (ret) { >> + dev_err(&pdev->dev, "Unable to enable apb clock.\n"); >> + goto err_disable_clk; >> + } >> + >> platform_set_drvdata(pdev, zdev); >> + pm_runtime_set_autosuspend_delay(zdev->dev, ZDMA_PM_TIMEOUT); >> + pm_runtime_use_autosuspend(zdev->dev); >> + pm_runtime_enable(zdev->dev); >> >> ret = zynqmp_dma_chan_probe(zdev, pdev); >> if (ret) { >> dev_err(&pdev->dev, "Probing channel failed\n"); >> - goto free_chan_resources; >> + goto err_disable_pm; >> } >> >> p->dst_addr_widths = BIT(zdev->chan->bus_width / 8); >> @@ -1005,10 +1096,18 @@ static int zynqmp_dma_probe(struct platform_device *pdev) >> goto free_chan_resources; >> } >> >> + pm_runtime_mark_last_busy(zdev->dev); >> + pm_runtime_put_sync_autosuspend(zdev->dev); >> + >> dev_info(&pdev->dev, "ZynqMP DMA driver Probe success\n"); >> >> return 0; >> >> +err_disable_clk: >> + clk_disable_unprepare(zdev->clk_main); >> +err_disable_pm: >> + clk_disable_unprepare(zdev->clk_apb); >> + pm_runtime_disable(zdev->dev); >> free_chan_resources: >> zynqmp_dma_chan_remove(zdev->chan); >> return ret; >> @@ -1028,6 +1127,9 @@ static int zynqmp_dma_remove(struct platform_device *pdev) >> dma_async_device_unregister(&zdev->common); >> >> zynqmp_dma_chan_remove(zdev->chan); >> + pm_runtime_disable(zdev->dev); >> + clk_disable_unprepare(zdev->clk_apb); >> + clk_disable_unprepare(zdev->clk_main); >> >> return 0; >> } >> @@ -1042,6 +1144,7 @@ static struct platform_driver zynqmp_dma_driver = { >> .driver = { >> .name = "xilinx-zynqmp-dma", >> .of_match_table = zynqmp_dma_of_match, >> + .pm = &zynqmp_dma_dev_pm_ops, >> }, >> .probe = zynqmp_dma_probe, >> .remove = zynqmp_dma_remove, >> > > CR number? Please ignore this one - I thought it is coming to our soc vendor tree. :-) Cheers, Michal