From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753571AbdADH1i (ORCPT ); Wed, 4 Jan 2017 02:27:38 -0500 Received: from mail-dm3nam03on0080.outbound.protection.outlook.com ([104.47.41.80]:2750 "EHLO NAM03-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751858AbdADH1e (ORCPT ); Wed, 4 Jan 2017 02:27:34 -0500 Authentication-Results: spf=pass (sender IP is 149.199.60.100) smtp.mailfrom=xilinx.com; vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=bestguesspass action=none header.from=xilinx.com; From: Kedareswara rao Appana To: , , , , , , , , , , CC: , , , Subject: [PATCH v3 1/3] dmaengine: xilinx_dma: Check for channel idle state before submitting dma descriptor Date: Wed, 4 Jan 2017 12:24:05 +0530 Message-ID: <1483512847-25710-2-git-send-email-appanad@xilinx.com> X-Mailer: git-send-email 2.1.1 In-Reply-To: <1483512847-25710-1-git-send-email-appanad@xilinx.com> References: <1483512847-25710-1-git-send-email-appanad@xilinx.com> X-RCIS-Action: ALLOW X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.0.0.1202-22800.006 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)(7916002)(39860400002)(39450400003)(39840400002)(39410400002)(39850400002)(2980300002)(438002)(189002)(199003)(6666003)(2950100002)(45336002)(46386002)(8676002)(38730400001)(5003940100001)(4326007)(189998001)(2906002)(106466001)(50986999)(52956003)(76176999)(54906002)(36386004)(92566002)(42186005)(305945005)(103686003)(63266004)(7416002)(50226002)(48376002)(5660300001)(36756003)(356003)(81166006)(626004)(50466002)(90966002)(5001770100001)(47776003)(33646002)(2201001)(81156014)(8936002)(107986001)(921003)(2101003)(83996005)(1121003)(5001870100001);DIR:OUT;SFP:1101;SCL:1;SRVR:MWHPR02MB2782;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;CY1NAM02FT008;1:9rEdz9cEYQEO6X5YIlkZ3/TLnM0FAW5iBbP4OVhCZwSUnUSdlm04LtibGZiaMWYALYPPesg6BuziiqqkwpLdRHT8ZcGMv25cc4lEDlN9vouRQN1v4YcJYv4Nl5bv9lB5477ELKFC14cXMDa/2daiU0M5CV+YxstC+74zxFuRbh1R/AfLrWXQFhHyTkbygu6iGLLgXtP4IOGbFmTDd/VodXqWHzxPNoFzTEIslJv7RFF1N5vkb1dBuQ7yfA5mXH5aB59IzKRw/g+w7lg/caQzFXQTF694kxEVzVOie+7n/P7iSKPvwkux7BqlqnrhpGhSYo5J2h0R5abUq5b30RYyaz6JOUOLRnjzNCcC3h6SyJEbJDrmLwUkyul5Vce7X2/5CUNDTreueaM2VNOrdGi6D6Hma0foGFu5Cht/rr+kTd47t+NQA1WrRKpaUwkuENS2AxkMe+f5Y5BUwPJjlFoObTb34TSwWRj9n23NpjGUhAYKsf8Kuh0mVnUpSTaTF9IalBtghGNIc9xuknhWdmcOChKJn5afFWYePs1/g1K78aOPgZr1V+ks9+2KRhVZ6H+fd9oFks51PI2nIqyR+fLwoKMEC1M5ma7iPQVAvjn3KZDmIWIGCQX7D1syzhIykTDJJCzDEnlnR0DF60RsU5/HHg== MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 95a080d8-50fa-424a-af29-08d4346e81d4 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(8251501002);SRVR:MWHPR02MB2782; X-Microsoft-Exchange-Diagnostics: 1;MWHPR02MB2782;3:C1mXiBIDEpuONkm3Cmh1PAZUuLCYuW3qLJw/7z07kqVP0P7cy5N0p7tLdZjqXNbCJ95DVXFdmAra+UhSVIr21ED3lGEyZdDoEFQ9wETcaM1GQjAAShClW5llEsXWXoOV8mRzm55Q53Q5GgCU7eILa+YK9JFvnkiRbC5i5QNI6CRxZ+n+uQ8ffP3ujZqxLP4K4mN+HDIKidjTUD8BD8xBHW6+RPIDfWjjLYNscj9zhSJbMD+DV4nwfH3AmHDIc4gTpbCrlUinVQWjW28Bi7QnLjAc+mp5kVMZ7AFJKZZrhw3C7ESpBqhtezCzekOxsXF51jqtwkaHHjqtv5BwjlsLkDPsDLbQ9DyMFgjkUuieb/P8N6wVhg76qEZ3U/VtUa5wQxR/c8S4iqAqBmY3Hh12aQ== X-Microsoft-Exchange-Diagnostics: 1;MWHPR02MB2782;25:2sSKDBir1PX2DBqrcdpALsli5TcaWfb/0RhxpOTEAuW1x4eFkOYRd9qPMQHpviQ5kFfOmVEhA0cOQd4Tntow3ZkFa/9NhIv7u+motj6lFrRhdskwkZI5Q06eUrlH6/5sMswq5kevMKbAXOyq9vpDrAQ77jKkNJvuluXZJBayfMUd0vpYaV+De1fFfvt39LaTbr5gxLpYDuXJ0deqUEbcfud4oqYv3iW2jHhgll43YUHKifiKyR5+oAvw0EXT7uZmfvR2r9qEfwi3VY13vGuBBIKN2qNOITyY+EFAm2ebsmoBQsOsAzWhA/f7iCtCvJta/nBoYcmW90GTsm3jMHOgJXQaQG8dv1o9/s01KcS5UbbAtuGYfyhnUiosI9ZmIKm4tw4xxVxjn67W2tAJLb3SOMP/34nJVgSvnzctHHs46fcXxqLCiMdahXMqJ/kS7Yeoz2cAHwA0k+OQVBTOrAPi7EV22pE1Hp2hPDjTHH7Gzb96L1G850qJkO/cD5X140TbRbxsRl/W8z92+D8HlNpRreoZrvgsLDGCQPWM4eXyvIXTS4OOBQ8mc7fu2b5zjJ/yYlomU6Z0RLgPfOsZtADg1npTpsERNPpMHyYrT0IGvWRQcwObo0wBMqHwI47YHJAP4ozCkTy3bCYQUDSYLTe8rusSWG6NPuiJW3SObabXAT/b9ljbc5UqB2+DbYoh6M8mePBZUAod3HrgY/inL513DHaH0wKWi3wlaPQzFfzcMYwOs1N0swwxhTj6XgccPRY7ERVb36pbLwD4gK2jIdKGSe5U9SCwSSLmgK+ZkNHmR3HUehTOmmbbsrxjqbMVBme47X7iiKLyBbkeANXOKfGfnQ== X-Microsoft-Exchange-Diagnostics: 1;MWHPR02MB2782;31:JSJgth6qUf/im2nxbT4sGJTSPQTdJvb0lJ8PYAHk9tc/AQG7h3wsd2T4MJs1BRAQp1yHj1g2yKFm7y6E+ERfCcxkvu7sakFMdHa4mFX7mWHJpliZxE/8ZOmIebigui4cQSAbZKVPOlL088BwiG8kL0/RPp6ttgQ+rdN3jf5ZlilRsO1mE5avkqQc+TV8h2WqRjvTLXPKsgbskkanpWTqfGR6YMcTqybg85Fipfs/AuJVZgoywlCjqcstvPkWaTrTJueczw/MprKQ7a0swDwXtQ==;20:zdKjSb1Y/yPzh2/xU11wr0y54pWoQgL6Cc2cylDA1G7dZlPsJ/V6HJzPRgjS8WcduyhtxHohNjBdbEEMZ8Mv56QVCB9Nzj8Ljov/JXeqdHzsaD/E63TEY1bPVF9tIeIMTR1Hmt9L2xMehQ2R17QyUiwYRhJpzxL0BETYETnDKCHNuAiDPenzmv3JjUSKpRbOMNO/DVVOhGipkYdLBjFr4lioyKdYZyBMNHMPKazvCY0JmAF+Osx0X7chxq7WLzw+l5NOl845O9nyrK5KMNJilurZzh99QjO7rIEahTOJmNco18hVPBFApYh6JE9Wg3Iq2PwER/sxdrIuOAV4SaloESVcPhVmdtNAZlgcAUkf4fQNuu2oBxc8RPUjmfXtYtFe0Giyj3g/o8RPI8Qs8IlKCH8pBRo/Rlig1CzKgKw9HBQqTKfEAhiEl+Bh9N8r/ZJjmYWl0yAAYQhQwUC9plrglpkIkoVZHCFNUHkMxIgaBbOQrVC2/nFC8F3+Lkgap8IT X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(192813158149592); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(13023025)(13024025)(13015025)(13017025)(13018025)(8121501046)(5005006)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123560025)(20161123558021)(20161123564025)(20161123562025)(6072148);SRVR:MWHPR02MB2782;BCL:0;PCL:0;RULEID:;SRVR:MWHPR02MB2782; X-Microsoft-Exchange-Diagnostics: 1;MWHPR02MB2782;4:6bSqW50Ob0fuerD3ajOucxsBd5jePerDxS/hp/4vtJ/gEwn8Y6ztE1y/HpUL7hv75l0P27IxxtaJQTt3OnX2FUAN8BwxMl5cDLRuqi9G5Ct2VtJKrik1nOrjg5muVbAJAXgmrnWWKyrjxQQmkHn9C149m3Xqj5LRJNblU7WtzLJhh688bUjineeyzSYT1VYZi9o40w5aCVRTj0wu/tN9ho0Q8bzGKKN3m0IpOnWEmcnUSjl+spEwzbTmNu8ze1GMNjD3vLxk7N9RErDOh45GV7K2+fuwSLoi+OCFTdK+pssexl17QZAgh+IyLTTBEL2SnhXPsiRIWL+eXR6gxCiHxSWtLOWXXLNVy9w5bDtw5y7a/ceMRUJZ5fSGeHsDff8UCL3LH8i5xFsxafIz1ddjB5m70bB/7/pCUI0XeqwV22OxTD7jqZoaZOluKj2Y+laQh2gO0OZ2qP+Up6urwBW+whQF4MTY6fYjQdvmRN2eDwI7ggjIuriXqF4AsO8KZHkYqcZ9rl7Q7gwtnO8Z8eXfqDRb1O+GT1jEzBSjGRElj4cUU+QA+BNsxvepMLzuvoGkxKwh7oXVQyng93BqSRQFwDLlj5bUwnxNl3BnAUpSSRoqUQZEpWvboPU+wS8SuKBXL5FHAeKJdOdXRI/HJVUZPhWTOIlDkH3b9Hu/UYQAZDg4rwJ+sFwVAjb50So24MDLvjCNiW1MMKr/721yVo4gVCKhISRlIQ9/V258nEmjCxtOSyGaD89ms4GNwnK1+f/ETu+c1QcfbveTLF5OgpjlGw== X-Forefront-PRVS: 0177904E6B X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;MWHPR02MB2782;23:rYLHHoDhbGmjEMUbRSqRL7WvRWk34rAKG32njGumt?= =?us-ascii?Q?GcXFJGAOYC6PjDOmwOem1aAxaUrnYEYoo3XPGGAxJwLZkz/+TdGgnl9+t3lh?= =?us-ascii?Q?mxUCRbZOlPwidd92ouaEQGI5ikn09yqo/eoyMUWhLYghnn2zDX5ZL10y/kDv?= =?us-ascii?Q?0cQAoRMH0I16DseZhsMO6lE6/yoqww6dZPoss3VmZuWxmG7NUzf1A1s1c6tg?= =?us-ascii?Q?2scuNz96goQQdFDbZBHuGCAyjBulPQmgBIubCL37YSPmqg+aaRSsDLkuPgYx?= =?us-ascii?Q?q1InI9AfsGI8InWLqvQ+99D92HCzS8nF9mSWak6ngEndRUYZ0Ln0X8ml8Mmx?= =?us-ascii?Q?RUQ8dFwXZzqLA23Fm3azolmYw4kiDrepfSM4Q/mdPu8vIka2EE6sJP7jrjqc?= =?us-ascii?Q?+H0KArDNrwIGDlDAIQ+Rs/lr8AEYzPtQ/jSJkmN/L9vyl0JRN1AGjoMgbEyi?= =?us-ascii?Q?3U2DjgdQxyHgu1g3h/PgnYcGnl0NaZDufEv9j1wC32SIgHxVk61A3ZMIC89M?= =?us-ascii?Q?8iT7Xv/ITwuxCBD9g5SC+9cvkVcVkFyCLNTObq+IRSWW3FhN21LIVfwkM/13?= =?us-ascii?Q?LxyTSczPF6HmiCUfWA752J1n2aadN1ghGl+Fy63UYMIEi1UFIIrWM+1WmIJ8?= =?us-ascii?Q?lap18+z280PRMx07nfxjqKC3nuNW59amhvEnzW19Vqoil20XRSP5h0PPthCw?= =?us-ascii?Q?vNjutJWO7mT12htbsWVvNAW20RDFC2iEyp85/NLjYKVa7X5moxivJN707JaH?= =?us-ascii?Q?g7W/bekUDQE7A4++RHUjDhwYnI8zxYaaWS8qWigOcZlgYLSw9lcNFmI1LxuG?= =?us-ascii?Q?7TNJlZAyfzsHzbhOZe0KqruEDkh+LAneESj2ae/XE98e3NV4SySH1utx1xd8?= =?us-ascii?Q?4tmY8Ez9Oe2QEFhUikAfCQliyHVYAvkUAydZB/KjlL1OnIvRp3gvwCMAa3kh?= =?us-ascii?Q?1Pr0YlZp7FuXkhLPqGz2X75YM0VJv9M4T3CME8JSd8ztl9zHbFN5dvDOWbFh?= =?us-ascii?Q?H7geS1qpu94GrSyND67ZT+HNYXJW2fWb83iY2bXFIiP/2X5wHk6cgJm4DMCy?= =?us-ascii?Q?ba821NApOedEtaLlTCTJQUSHUNwduUam3Wv5pd2cgIrcxT/+n8Olqt5qBM1i?= =?us-ascii?Q?G2QtSVYWOc4r0c+NVs7x6gejIjeJZHvioKxHTGk8rCkgPxARN9t65bqEH26D?= =?us-ascii?Q?7EUdUo1znL2Bhc2PdaPJ7IecYoR90WXVu2aetjtOBZPOQN+4sC11xSSkjOJy?= =?us-ascii?Q?F8dsL4StmppioZorh5WlfM3RlnMcyL82CFjjOj9TGK5Pf3wMqSq2SZsvrFAi?= =?us-ascii?Q?vjw0WVBMlCA1ub/csJMAuA=3D?= X-Microsoft-Exchange-Diagnostics: 1;MWHPR02MB2782;6:8ePLbK93RCDL3Umvh2t4elY9ASkU0hdJ72WIvTOhEyQHPHfdmSo8DeYWe3b6fDzQwIC1JGz9rDQsFNXEPRa27dcdzcp8ElNpdYVWNUAicPse9pA1PlwqWuQJ8HqA5TdRZBymjVeStOjdwnau7gTfHpk+NeNqqr7bszV6MYTIDEDSaFdUl70iDE0X+hlKTnjAR3dbQ2d48y4dwtVanwbuF5+XZo1OGSM6an/NlpQLKovkPSmawV0Jy3+x5je5Gwu+zljjGUVsba4x4Ma1Rr3TdM+2aL1zhEfim/6VHMyjrch4l4Brj1Uinhg2DqJxxhN1cQCLxHi8zf9c/NXHwFbw3Zg8a8/eoh8DlDD9g84OF94gvMYLAJbzg5mTdNYb9FkmhNoiOWTtFZ57vHTawE4A7t7G1QwWRcJ2Dh3dM2SS8bzVGScthdIgZwS5U9ong6VvXckn8mWPJp4UOeIRE59azA==;5:tOP3lCSu6m4glMqWGTgtJ85vCGzaVIJDpMVPJB4SL3DnDFshadWftmtQvjIPf/T8mmxkY0rjeq4Ef2h+tQgEMZ61GYzIkOZ9o0QNctIr1vLfWkQPqdG+GP/rKdwYmxXlligXoq9kiE3Hzky9IREJzfeYIsxefxJwWrF2xCzJ5Dw=;24:7zGN38VVWrUhSVJBRUit56F4hNJutpc9KLp3dKprSTQs7n8qcF84E3sZfJ8QpQzdoavmvfMD8VwGjR9lc108Yg3lEUSRnLk6L4Q2+eoiWHo= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;MWHPR02MB2782;7:/OGAouSdjNS+lWh8T98GC9cTT0cZp1o0PH76ctsY8zallzpsY4ccAxkfM0z6JO81m1G4yTZwMBSpC0FeNg00q/meuP1N0NtSBM0MXD2js9mmJkHdB1D372eYsvFxGCYyCAKSvK2Zkg133jw+nugNTfFeOLuViEQExDjF0OWxx0zQzXEiTLnAX1NyfaB6rW2zT3k1iG8TSJec7xAd77ldSeF96RuQPgvDwo9XGcDre62ech+HNNHypcAKHVJVA5vZC98daHY7TCEHheIsGsmMEPG10xZxzoJw1oETHESOeXkWWvK02lG3IKpDcPzNByDw7r7qnRDSKXNj+bW+lT51yPfDgpdCeYBz3IShdZgUNK2zwo3ZTHZxejKYQ7i+iSID4VYjBQsh/0zy9O9yUyDdYme0KePMzKMEkQyPpLQlnV9sVVSa82bmkc0/xM0jBNgO1HQ5jOLnOwwlB48YzM95Uw== X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Jan 2017 06:54:18.7828 (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: MWHPR02MB2782 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add channel idle state to ensure that dma descriptor is not submitted when VDMA engine is in progress. Reviewed-by: Jose Abreu Signed-off-by: Kedareswara rao Appana --- Changes for v3: ---> None. Changes for v2: ---> Add idle check in the reset as suggested by Jose Abreu ---> Removed xilinx_dma_is_running/xilinx_dma_is_idle checks in the driver and used common idle checks across the driver as suggested by Laurent Pinchart. drivers/dma/xilinx/xilinx_dma.c | 56 +++++++++++++---------------------------- 1 file changed, 17 insertions(+), 39 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 8288fe4..be7eb41 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -321,6 +321,7 @@ struct xilinx_dma_tx_descriptor { * @cyclic: Check for cyclic transfers. * @genlock: Support genlock mode * @err: Channel has errors + * @idle: Check for channel idle * @tasklet: Cleanup work after irq * @config: Device configuration info * @flush_on_fsync: Flush on Frame sync @@ -351,6 +352,7 @@ struct xilinx_dma_chan { bool cyclic; bool genlock; bool err; + bool idle; struct tasklet_struct tasklet; struct xilinx_vdma_config config; bool flush_on_fsync; @@ -920,32 +922,6 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan, } /** - * xilinx_dma_is_running - Check if DMA channel is running - * @chan: Driver specific DMA channel - * - * Return: '1' if running, '0' if not. - */ -static bool xilinx_dma_is_running(struct xilinx_dma_chan *chan) -{ - return !(dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) & - XILINX_DMA_DMASR_HALTED) && - (dma_ctrl_read(chan, XILINX_DMA_REG_DMACR) & - XILINX_DMA_DMACR_RUNSTOP); -} - -/** - * xilinx_dma_is_idle - Check if DMA channel is idle - * @chan: Driver specific DMA channel - * - * Return: '1' if idle, '0' if not. - */ -static bool xilinx_dma_is_idle(struct xilinx_dma_chan *chan) -{ - return dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) & - XILINX_DMA_DMASR_IDLE; -} - -/** * xilinx_dma_halt - Halt DMA channel * @chan: Driver specific DMA channel */ @@ -966,6 +942,7 @@ static void xilinx_dma_halt(struct xilinx_dma_chan *chan) chan, dma_ctrl_read(chan, XILINX_DMA_REG_DMASR)); chan->err = true; } + chan->idle = true; } /** @@ -1007,6 +984,9 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) if (chan->err) return; + if (!chan->idle) + return; + if (list_empty(&chan->pending_list)) return; @@ -1018,13 +998,6 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) tail_segment = list_last_entry(&tail_desc->segments, struct xilinx_vdma_tx_segment, node); - /* If it is SG mode and hardware is busy, cannot submit */ - if (chan->has_sg && xilinx_dma_is_running(chan) && - !xilinx_dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy\n"); - return; - } - /* * If hardware is idle, then all descriptors on the running lists are * done, start new transfers @@ -1110,6 +1083,7 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) vdma_desc_write(chan, XILINX_DMA_REG_VSIZE, last->hw.vsize); } + chan->idle = false; if (!chan->has_sg) { list_del(&desc->node); list_add_tail(&desc->node, &chan->active_list); @@ -1136,6 +1110,9 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan) if (chan->err) return; + if (!chan->idle) + return; + if (list_empty(&chan->pending_list)) return; @@ -1181,6 +1158,7 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan) list_splice_tail_init(&chan->pending_list, &chan->active_list); chan->desc_pendingcount = 0; + chan->idle = false; } /** @@ -1196,15 +1174,11 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) if (chan->err) return; - if (list_empty(&chan->pending_list)) + if (!chan->idle) return; - /* If it is SG mode and hardware is busy, cannot submit */ - if (chan->has_sg && xilinx_dma_is_running(chan) && - !xilinx_dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy\n"); + if (list_empty(&chan->pending_list)) return; - } head_desc = list_first_entry(&chan->pending_list, struct xilinx_dma_tx_descriptor, node); @@ -1302,6 +1276,7 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) list_splice_tail_init(&chan->pending_list, &chan->active_list); chan->desc_pendingcount = 0; + chan->idle = false; } /** @@ -1366,6 +1341,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan) } chan->err = false; + chan->idle = true; return err; } @@ -1447,6 +1423,7 @@ static irqreturn_t xilinx_dma_irq_handler(int irq, void *data) if (status & XILINX_DMA_DMASR_FRM_CNT_IRQ) { spin_lock(&chan->lock); xilinx_dma_complete_descriptor(chan); + chan->idle = true; chan->start_transfer(chan); spin_unlock(&chan->lock); } @@ -2327,6 +2304,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, chan->has_sg = xdev->has_sg; chan->desc_pendingcount = 0x0; chan->ext_addr = xdev->ext_addr; + chan->idle = true; spin_lock_init(&chan->lock); INIT_LIST_HEAD(&chan->pending_list); -- 2.1.2 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kedareswara rao Appana Subject: [PATCH v3 1/3] dmaengine: xilinx_dma: Check for channel idle state before submitting dma descriptor Date: Wed, 4 Jan 2017 12:24:05 +0530 Message-ID: <1483512847-25710-2-git-send-email-appanad@xilinx.com> References: <1483512847-25710-1-git-send-email-appanad@xilinx.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1483512847-25710-1-git-send-email-appanad@xilinx.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: robh+dt@kernel.org, mark.rutland@arm.com, dan.j.williams@intel.com, vinod.koul@intel.com, michal.simek@xilinx.com, soren.brinkmann@xilinx.com, appanad@xilinx.com, moritz.fischer@ettus.com, laurent.pinchart@ideasonboard.com, luis@debethencourt.com, Jose.Abreu@synopsys.com Cc: dmaengine@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org List-Id: devicetree@vger.kernel.org Add channel idle state to ensure that dma descriptor is not submitted when VDMA engine is in progress. Reviewed-by: Jose Abreu Signed-off-by: Kedareswara rao Appana --- Changes for v3: ---> None. Changes for v2: ---> Add idle check in the reset as suggested by Jose Abreu ---> Removed xilinx_dma_is_running/xilinx_dma_is_idle checks in the driver and used common idle checks across the driver as suggested by Laurent Pinchart. drivers/dma/xilinx/xilinx_dma.c | 56 +++++++++++++---------------------------- 1 file changed, 17 insertions(+), 39 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 8288fe4..be7eb41 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -321,6 +321,7 @@ struct xilinx_dma_tx_descriptor { * @cyclic: Check for cyclic transfers. * @genlock: Support genlock mode * @err: Channel has errors + * @idle: Check for channel idle * @tasklet: Cleanup work after irq * @config: Device configuration info * @flush_on_fsync: Flush on Frame sync @@ -351,6 +352,7 @@ struct xilinx_dma_chan { bool cyclic; bool genlock; bool err; + bool idle; struct tasklet_struct tasklet; struct xilinx_vdma_config config; bool flush_on_fsync; @@ -920,32 +922,6 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan, } /** - * xilinx_dma_is_running - Check if DMA channel is running - * @chan: Driver specific DMA channel - * - * Return: '1' if running, '0' if not. - */ -static bool xilinx_dma_is_running(struct xilinx_dma_chan *chan) -{ - return !(dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) & - XILINX_DMA_DMASR_HALTED) && - (dma_ctrl_read(chan, XILINX_DMA_REG_DMACR) & - XILINX_DMA_DMACR_RUNSTOP); -} - -/** - * xilinx_dma_is_idle - Check if DMA channel is idle - * @chan: Driver specific DMA channel - * - * Return: '1' if idle, '0' if not. - */ -static bool xilinx_dma_is_idle(struct xilinx_dma_chan *chan) -{ - return dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) & - XILINX_DMA_DMASR_IDLE; -} - -/** * xilinx_dma_halt - Halt DMA channel * @chan: Driver specific DMA channel */ @@ -966,6 +942,7 @@ static void xilinx_dma_halt(struct xilinx_dma_chan *chan) chan, dma_ctrl_read(chan, XILINX_DMA_REG_DMASR)); chan->err = true; } + chan->idle = true; } /** @@ -1007,6 +984,9 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) if (chan->err) return; + if (!chan->idle) + return; + if (list_empty(&chan->pending_list)) return; @@ -1018,13 +998,6 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) tail_segment = list_last_entry(&tail_desc->segments, struct xilinx_vdma_tx_segment, node); - /* If it is SG mode and hardware is busy, cannot submit */ - if (chan->has_sg && xilinx_dma_is_running(chan) && - !xilinx_dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy\n"); - return; - } - /* * If hardware is idle, then all descriptors on the running lists are * done, start new transfers @@ -1110,6 +1083,7 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) vdma_desc_write(chan, XILINX_DMA_REG_VSIZE, last->hw.vsize); } + chan->idle = false; if (!chan->has_sg) { list_del(&desc->node); list_add_tail(&desc->node, &chan->active_list); @@ -1136,6 +1110,9 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan) if (chan->err) return; + if (!chan->idle) + return; + if (list_empty(&chan->pending_list)) return; @@ -1181,6 +1158,7 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan) list_splice_tail_init(&chan->pending_list, &chan->active_list); chan->desc_pendingcount = 0; + chan->idle = false; } /** @@ -1196,15 +1174,11 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) if (chan->err) return; - if (list_empty(&chan->pending_list)) + if (!chan->idle) return; - /* If it is SG mode and hardware is busy, cannot submit */ - if (chan->has_sg && xilinx_dma_is_running(chan) && - !xilinx_dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy\n"); + if (list_empty(&chan->pending_list)) return; - } head_desc = list_first_entry(&chan->pending_list, struct xilinx_dma_tx_descriptor, node); @@ -1302,6 +1276,7 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) list_splice_tail_init(&chan->pending_list, &chan->active_list); chan->desc_pendingcount = 0; + chan->idle = false; } /** @@ -1366,6 +1341,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan) } chan->err = false; + chan->idle = true; return err; } @@ -1447,6 +1423,7 @@ static irqreturn_t xilinx_dma_irq_handler(int irq, void *data) if (status & XILINX_DMA_DMASR_FRM_CNT_IRQ) { spin_lock(&chan->lock); xilinx_dma_complete_descriptor(chan); + chan->idle = true; chan->start_transfer(chan); spin_unlock(&chan->lock); } @@ -2327,6 +2304,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, chan->has_sg = xdev->has_sg; chan->desc_pendingcount = 0x0; chan->ext_addr = xdev->ext_addr; + chan->idle = true; spin_lock_init(&chan->lock); INIT_LIST_HEAD(&chan->pending_list); -- 2.1.2 From mboxrd@z Thu Jan 1 00:00:00 1970 From: appana.durga.rao@xilinx.com (Kedareswara rao Appana) Date: Wed, 4 Jan 2017 12:24:05 +0530 Subject: [PATCH v3 1/3] dmaengine: xilinx_dma: Check for channel idle state before submitting dma descriptor In-Reply-To: <1483512847-25710-1-git-send-email-appanad@xilinx.com> References: <1483512847-25710-1-git-send-email-appanad@xilinx.com> Message-ID: <1483512847-25710-2-git-send-email-appanad@xilinx.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Add channel idle state to ensure that dma descriptor is not submitted when VDMA engine is in progress. Reviewed-by: Jose Abreu Signed-off-by: Kedareswara rao Appana --- Changes for v3: ---> None. Changes for v2: ---> Add idle check in the reset as suggested by Jose Abreu ---> Removed xilinx_dma_is_running/xilinx_dma_is_idle checks in the driver and used common idle checks across the driver as suggested by Laurent Pinchart. drivers/dma/xilinx/xilinx_dma.c | 56 +++++++++++++---------------------------- 1 file changed, 17 insertions(+), 39 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 8288fe4..be7eb41 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -321,6 +321,7 @@ struct xilinx_dma_tx_descriptor { * @cyclic: Check for cyclic transfers. * @genlock: Support genlock mode * @err: Channel has errors + * @idle: Check for channel idle * @tasklet: Cleanup work after irq * @config: Device configuration info * @flush_on_fsync: Flush on Frame sync @@ -351,6 +352,7 @@ struct xilinx_dma_chan { bool cyclic; bool genlock; bool err; + bool idle; struct tasklet_struct tasklet; struct xilinx_vdma_config config; bool flush_on_fsync; @@ -920,32 +922,6 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan, } /** - * xilinx_dma_is_running - Check if DMA channel is running - * @chan: Driver specific DMA channel - * - * Return: '1' if running, '0' if not. - */ -static bool xilinx_dma_is_running(struct xilinx_dma_chan *chan) -{ - return !(dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) & - XILINX_DMA_DMASR_HALTED) && - (dma_ctrl_read(chan, XILINX_DMA_REG_DMACR) & - XILINX_DMA_DMACR_RUNSTOP); -} - -/** - * xilinx_dma_is_idle - Check if DMA channel is idle - * @chan: Driver specific DMA channel - * - * Return: '1' if idle, '0' if not. - */ -static bool xilinx_dma_is_idle(struct xilinx_dma_chan *chan) -{ - return dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) & - XILINX_DMA_DMASR_IDLE; -} - -/** * xilinx_dma_halt - Halt DMA channel * @chan: Driver specific DMA channel */ @@ -966,6 +942,7 @@ static void xilinx_dma_halt(struct xilinx_dma_chan *chan) chan, dma_ctrl_read(chan, XILINX_DMA_REG_DMASR)); chan->err = true; } + chan->idle = true; } /** @@ -1007,6 +984,9 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) if (chan->err) return; + if (!chan->idle) + return; + if (list_empty(&chan->pending_list)) return; @@ -1018,13 +998,6 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) tail_segment = list_last_entry(&tail_desc->segments, struct xilinx_vdma_tx_segment, node); - /* If it is SG mode and hardware is busy, cannot submit */ - if (chan->has_sg && xilinx_dma_is_running(chan) && - !xilinx_dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy\n"); - return; - } - /* * If hardware is idle, then all descriptors on the running lists are * done, start new transfers @@ -1110,6 +1083,7 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) vdma_desc_write(chan, XILINX_DMA_REG_VSIZE, last->hw.vsize); } + chan->idle = false; if (!chan->has_sg) { list_del(&desc->node); list_add_tail(&desc->node, &chan->active_list); @@ -1136,6 +1110,9 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan) if (chan->err) return; + if (!chan->idle) + return; + if (list_empty(&chan->pending_list)) return; @@ -1181,6 +1158,7 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan) list_splice_tail_init(&chan->pending_list, &chan->active_list); chan->desc_pendingcount = 0; + chan->idle = false; } /** @@ -1196,15 +1174,11 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) if (chan->err) return; - if (list_empty(&chan->pending_list)) + if (!chan->idle) return; - /* If it is SG mode and hardware is busy, cannot submit */ - if (chan->has_sg && xilinx_dma_is_running(chan) && - !xilinx_dma_is_idle(chan)) { - dev_dbg(chan->dev, "DMA controller still busy\n"); + if (list_empty(&chan->pending_list)) return; - } head_desc = list_first_entry(&chan->pending_list, struct xilinx_dma_tx_descriptor, node); @@ -1302,6 +1276,7 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) list_splice_tail_init(&chan->pending_list, &chan->active_list); chan->desc_pendingcount = 0; + chan->idle = false; } /** @@ -1366,6 +1341,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan) } chan->err = false; + chan->idle = true; return err; } @@ -1447,6 +1423,7 @@ static irqreturn_t xilinx_dma_irq_handler(int irq, void *data) if (status & XILINX_DMA_DMASR_FRM_CNT_IRQ) { spin_lock(&chan->lock); xilinx_dma_complete_descriptor(chan); + chan->idle = true; chan->start_transfer(chan); spin_unlock(&chan->lock); } @@ -2327,6 +2304,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, chan->has_sg = xdev->has_sg; chan->desc_pendingcount = 0x0; chan->ext_addr = xdev->ext_addr; + chan->idle = true; spin_lock_init(&chan->lock); INIT_LIST_HEAD(&chan->pending_list); -- 2.1.2