From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751398AbdJTGb4 (ORCPT ); Fri, 20 Oct 2017 02:31:56 -0400 Received: from mail-sn1nam01on0089.outbound.protection.outlook.com ([104.47.32.89]:9248 "EHLO NAM01-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750905AbdJTGbx (ORCPT ); Fri, 20 Oct 2017 02:31:53 -0400 Authentication-Results: spf=pass (sender IP is 149.199.60.83) 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: 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:31:38 +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: <1508310126-10926-1-git-send-email-appanad@xilinx.com> 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.83;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(376002)(39860400002)(346002)(2980300002)(438002)(3190300001)(199003)(24454002)(189002)(106466001)(53546010)(76176999)(77096006)(33646002)(9786002)(36386004)(229853002)(36756003)(8936002)(64126003)(58126008)(5660300001)(316002)(50986999)(54356999)(50466002)(31696002)(86362001)(54906003)(110136005)(2201001)(2906002)(65826007)(2950100002)(106002)(4326008)(23676002)(305945005)(478600001)(81166006)(107886003)(230700001)(81156014)(8676002)(63266004)(6246003)(65956001)(65806001)(47776003)(356003)(189998001)(83506002)(6666003)(31686004)(107986001);DIR:OUT;SFP:1101;SCL:1;SRVR:CY4PR02MB3383;H:xsj-pvapsmtpgw01;FPR:;SPF:Pass;PTR:unknown-60-83.xilinx.com;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;SN1NAM02FT036;1:Nb2AIgX2TvQeZ7c6BpiZlLek/OXFHTEcFHUnJ2lbwu/RYZDOEB7872PdSDCkgcRPfPgpvA/iQiBOrH/hAJ56wWL87jONbvMRTf8ndgiJu6qA7zfAaV/hSnFfH8E7v4Sg X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 912b1973-211e-4629-281e-08d517843e9c X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(8251501002)(4534020)(4602075)(4627075)(201703031133081)(201702281549075)(2017052603199);SRVR:CY4PR02MB3383; X-Microsoft-Exchange-Diagnostics: 1;CY4PR02MB3383;3:4R9BLNC29bprPq36xO7z9Nd/jxWoFcQ5//VQWWSd9QwqnAu6MaOpNVCllCh20+56vknHAfR1AN4v312meMNaBmW6kglofVtpKMSexLLovwj1P0YCK2UoOAmb6BlYfAcHWFYrC0pxe5ov9nX2bpvf29bjCN709CNwUDslaCkL4shiYjb0pyKlsNBkcgdBrPLGgJpzfy5OboaOPB+5y8XqgwLWxCqgrZj7akgU1N7EatwuWwXwpAekorRHZxM270rQUdpJ3XHKQLz8aentlr5ozTHyt2VkfJBfLiMzZfEkVTEwel1TGM0v4rYg4ZJi6E6IuqH8V9/K0Dm43TJn7Dx90jmdrqdeh7P6ZpVyYpB/Lx4=;25:q7lwXaMocaaKw4aeyN6Uxi5cZIXGfBvYXfaGYCr+QLrVhd3kiW9VxvqLlH6YIbc1KK2knxpYkxEbuf4EaJYjPz/2lD6hwshpX1ieSqNaJVMxfZTyoQSSbWT23OdFfts6HW46jKmmtLJqZXYhsdSEf/XnjCMSh88F4kupnyWDWRLZuOVhqS846zhaT9VdtJkTNKyLIO/SMGUdfUAeU8z008Wp3+2dpQFYIRD+nQ6zRGjC1zwNTU3V43daUzwNQCES87heJ/j4E4mBUFGljexHXkYzmJQY//ihkfmJPaj1Evj5kiHZzR1pa76d7xVA9eVwYbkPZEAbfL9m850LGvr8Mg== X-MS-TrafficTypeDiagnostic: CY4PR02MB3383: X-Microsoft-Exchange-Diagnostics: 1;CY4PR02MB3383;31:GfEvNAnQINkInSS59QJVo5TgNaiYyIURbfL3drJJAx46+I4VzzIi94pK/s087sKC6HtV+C8u9ZM9d2xG2x69gQToXksJ6YSUIHsw6ZQgKEOf+DLMrkz0GMMVyIoNr2U67RkQ2UzKAHQYncA8WHQVUVKz7fCR3FEQaGxd8Tvb9hmP6yekS4n6ctGe5CMdm9ML/UzZHkY5tex9PmTyLyaoMKGFFwgcPZGvEg1eV9xHWeQ=;20:dh9RR8eOmiaTI8YoODBe0CdyGmUh2sCYq+XFCNtnttweagio18ZilBrxHgOmeaUrKJ6B8wyTGgKu41kLcQuE0HKEAJhGG2xjK46wD5TTMfbpSQjafJE4sup+Z6glZcFsKs9jZ2c33edz4soOSge9bpwJdcjG1mcv7loRnbglyxyFZkz7CiiXIcpN+5hpC5i93e109JW/S3/FOODISn84WsDeBvbreOCiPmWw1Z34OmXLeK2h8n7XOhtnpdlrElyd6xhRgQNS+a5ilKfGTNNsi0Zuq0gItilda1E5V0IC01LRqTvYdo3RB8gqLxf1lvJsJ7I2RQLN1DdiiwGhbLplp5p8djyajVjqeoJzOBfpkvmZpxo8o7fC+XP9BaS9q+cIHW4KTGzQvgZulMeMWUBPXF4iyyEniOEmYqFbPReKmrgzw/MiV8I4FKC1WYVca1MXXHJYJt/zh4176ikl+MceWNFdGy+PZTwnMV+cuS3EbTKTVlhBiEQElkje3EEAWT0b 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)(3002001)(93006095)(93004095)(3231020)(100000703101)(100105400095)(6055026)(6041248)(20161123555025)(20161123564025)(20161123558100)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:CY4PR02MB3383;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:CY4PR02MB3383; X-Microsoft-Exchange-Diagnostics: 1;CY4PR02MB3383;4:eWIGOpDNuNTw1w+cWx63um/Ex0x9gtA3DJI/+Udvzt7a4muhSge5i7dxsLP3Pnr1eBR2a9xJFPafeF6Hgxv4830rJnSjIn4RbGrbSBL+WzR0FZadl4cZOX2kebCxt4xeNIrZDCLhyDjydWjp/UwVw2a5hiRDSmxELyFknVNine06gASTTIR2E4nymrlBSsK0xxJBJgNvbNpQVSUF5B5LUSJPoIdIWlzHjxNin+3dDH9idjuKdXB8SjbNHWp4bXMxdjYihNAn7Cj40lRGheuKlxy8i7graGNA1s7TX6ywWng= X-Forefront-PRVS: 0466CA5A45 X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtDWTRQUjAyTUIzMzgzOzIzOjRWcnJIWE84bDMyRVJUUHBzbjN6VThnT3pO?= =?utf-8?B?TTdNWWtyWFFZYXFjeUN6YkdJR3RLWWE5Q1hKUEVkQ3lNV0tocU9LbG8yYWhr?= =?utf-8?B?K3BodDUxWUJDcmlsaE5NWnFxa1JrMndnSEJibjNMM0pzeHZSSkZEZ3BSWDNq?= =?utf-8?B?QlJWMm9TTHZXNXJvT0RIZ1VuUzF5aFlLcHVhWnUrNGlSTklyc25oRUkzUTk0?= =?utf-8?B?WnRMcDdpTFZTOVMvN3d1WE90WGpYU2ZtcnhvQVpydW1DOVBUblBHaXlPdnNY?= =?utf-8?B?ekN0SEdIbGRDM2ZkWlpKRWphcmFaZ1h4T1ZMMi9RUjBrMWczZVB3UGFVVG9i?= =?utf-8?B?Nk5OSy9uUjBCdGZhYUFwZWtieFhrMUdrTm9XNWdrdWE4OFA3bWRORmcwMUYw?= =?utf-8?B?eUxNZXFSQ0QrVy9BYnMzSzNTa05Ld1NNd3Q1Yzk5T25GYWRrazlBd005b05R?= =?utf-8?B?MDBrcS94dTZDUUdta2JPRGVKT0NocjJkdXpzYi9SeFVEYWlBL0c2K0o1bEJr?= =?utf-8?B?OEYzMEk4ZUR3QTc0SGJnZlpsSWJLb2lnaUx0V1RtbmVJcTdmMGxGbUZOU3Vh?= =?utf-8?B?c0UvakMwU1FUV2NDYVlrbUVId2hRMHk5VXhsU3kzaFRMVmZWTy81R3pIL0wv?= =?utf-8?B?dmVMRmJGcU1QUGl3a0ptWUxlU0cvcE13djNZNFBjT2w0V1Z5Q3FMWE9kRkdZ?= =?utf-8?B?bS8wZnQxRFQ5c3ZvbWFtbUpOTENHS3c0WTAwcDdMcXJoNTZLUGMzZVI1cjIx?= =?utf-8?B?YlhtWjV3RGZqcGNDWWhYMTZBbFIwYWlaSjRLY0JnVlB1R2hFVXdyZE5Rd1p1?= =?utf-8?B?ZEh5QkM3RjJ2UkVaWnhVcTdPT1RCeUxoaTBBenZ0QTU5akYxUDJuVWk5ZjNQ?= =?utf-8?B?Vlg3bEhSRXhvQmY3SjJaMW91ZkJFZmU0TjVJMmxBOHBmak1KSHN3K25JOWl6?= =?utf-8?B?VktxOFkxbGpUQXVuUWZHTUxnRFo0S2FzSlgvMXBpV1I2UitGRkFZN0FBdTRk?= =?utf-8?B?UkZZSlFYTytGQ3hxam9jWW1sdnR4bUg1SWhSRWlzZDBRWUxQMHRtTVpMRVlS?= =?utf-8?B?VjQyMlMvWEx3b0pzSGd3VkRrMlBOenNLLzJqeXM1TmwrbTltOUcxSjdBM2Fm?= =?utf-8?B?T2FQSkljNHo2dXkzZmZkVnBzNkJzbVZPRDFUOGt6WkJEcFpmVTRVRDJCWVB3?= =?utf-8?B?Kzc0VTZpV25ZdmwydzNFc0RrNWRKSHF0dkg5dURQT0Q0eTdqR3ZOUGxNN2lq?= =?utf-8?B?ZDVEdUVxY2lTOVg1aUM4eFBSR2M1OWorK0xURkJQZjc1ODhmYm9mSXRUUTRa?= =?utf-8?B?Y1pvTWhqQ09IbThjTFkvVVAvYlBhVzlyemdZWEswVjhtdUU4T0VwdE05L2hG?= =?utf-8?B?akQ3TFZVMTVTeWQrZ0pubGkxdHd6TGo3RlFWMmRNY1NCTEUyT0VFbWNpREFk?= =?utf-8?B?UEFodXpHaDIrMU1aandpcjh5WEVDTFhNMFhHSk81U1gzVmExelcxekxVU1VI?= =?utf-8?B?djR5ajJxVlQwRS9MZ3M2K3lmRzl6b3dWYzRoeWVsWlFSN05TUm9SVVZqemtP?= =?utf-8?B?OWJEUzFvWk12R0IrVmhwZTNMcHJSbmNISEFXdHV2d2NxditaenVrT2JYbnZK?= =?utf-8?B?ZmdlR2N0dGtOZUlTRnFuUTA2dEtUOVBnTmN1eUoyYWVKM0psYXpiTGhuV3lH?= =?utf-8?B?V20vNVlOVWNVNVlrQnFyOHM4QkFBNFFSenh4UUE0RUhMREt4eG5SQnFnai8r?= =?utf-8?B?YVFsTjNUZnphbVdrRXBGQT09?= X-Microsoft-Exchange-Diagnostics: 1;CY4PR02MB3383;6:48ci8qffWfxQKPsed8tAwX3vBsLOEVEeo6cN0SqveF7oXarVSMiN4nspSIFSs9Z83k1/oKtJE7W4nk1CdT9wA0YGGmZrbIwNVQO9wYSUhy/VVsBVlODfuYhNrBsaQiEw/Yy78QWGe48rRf0j9I4hnLnUceBRl0fYq8Urdx5s1+168ElqJok81a7rImXh4k1oIaAWq03gt3Qgn8DVoytCHdWOAjmOMvACOdyffOnzCJa8bvn17U7OEbkRiGTae5yyrToIg8EpgTldPd2VU0zvkDbqdy4G8yEIV5OSI3w1QCEsOK7pC3+Y5tN0WH22mtAq3laJHiWUNkv+aQRldk1nOQ==;5:Xqntb/TEqNHlzLAXsC7e4FnWNqR0PSR09r3R6reIXW88mHNMWOm2W04M0XBkPUeMASCNaAbmz4skFs9Q/7F748MaMveBh1uDI9PnCUMg2Fvf2SvS/Ogix8j2MY3Vg2grvbfXfBrsONwfNm408bcAxw==;24:jDCNgZNZ47l7lPNV0gIS+lky/YkDu3GY12QHA1b89O+Zi82MLOHVsm/8KKBXekoF4nbEBwYwIqtavkFZwRPBMYJ0byWBDAdrB/eN2gCTn+M=;7:ABtrqo9y8IcY+lIQBBmThbM0A/DSVKTDOh30aTKMQ9k4Z9LNxP1R123aFR+WvVu8W5V9in+DBTBgNh9XJobG4T7+I4Tf8COZ+VBawkuaXqSDEc8+3zBJgCLbn++Jt0r3iPmI6AHI6pThiR/ZbQ8MqnTSvZHHo4zviiHV4JPz8ldeNhIdO0P/9szdzLZfkpiaT2BPqVPcO9ChKGG8cAqUoVA1koD4/mwRx8nXTX5Uynk= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Oct 2017 06:31:49.2430 (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.83];Helo=[xsj-pvapsmtpgw01] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR02MB3383 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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? M