From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751245AbdANFgK (ORCPT ); Sat, 14 Jan 2017 00:36:10 -0500 Received: from mail-dm3nam03on0088.outbound.protection.outlook.com ([104.47.41.88]:22992 "EHLO NAM03-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750738AbdANFgH (ORCPT ); Sat, 14 Jan 2017 00:36:07 -0500 Authentication-Results: spf=pass (sender IP is 149.199.60.100) smtp.mailfrom=xilinx.com; arm.com; dkim=none (message not signed) header.d=none;arm.com; dmarc=bestguesspass action=none header.from=xilinx.com;arm.com; dkim=none (message not signed) header.d=none; From: Kedareswara rao Appana To: , , , , , , , , , , CC: , , , Subject: [PATCH v6 1/3] dmaengine: xilinx_dma: Check for channel idle state before submitting dma descriptor Date: Sat, 14 Jan 2017 11:05:53 +0530 Message-ID: <1484372155-19423-2-git-send-email-appanad@xilinx.com> X-Mailer: git-send-email 2.1.1 In-Reply-To: <1484372155-19423-1-git-send-email-appanad@xilinx.com> References: <1484372155-19423-1-git-send-email-appanad@xilinx.com> X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.0.0.1202-22820.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)(7916002)(39840400002)(39450400003)(39860400002)(39850400002)(39410400002)(2980300002)(438002)(3190300001)(199003)(189002)(8936002)(46386002)(45336002)(8676002)(50466002)(7416002)(81166006)(27001)(5660300001)(5003940100001)(626004)(356003)(36386004)(189998001)(90966002)(50986999)(76176999)(305945005)(81156014)(47776003)(2906002)(42186005)(38730400001)(54906002)(103686003)(5001770100001)(92566002)(106466001)(63266004)(33646002)(50226002)(4326007)(2201001)(2950100002)(48376002)(6666003)(36756003)(52956003)(921003)(107986001)(83996005)(2101003)(1121003)(5001870100001);DIR:OUT;SFP:1101;SCL:1;SRVR:CY1PR0201MB0761;H:xsj-pvapsmtpgw02;FPR:;SPF:Pass;PTR:unknown-60-100.xilinx.com,xapps1.xilinx.com;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BL2NAM02FT063;1:gHs5+t2kq+E+NivRK1gZSBnpu0MeYJuNjNJUzpSmniM+ntF6ttHEdihmrwb+0XVcs63YT3hT1WNy8hH03xK7aUYqwUsf6NYMjeVJXbFBVDEjhqzq3wg2k8JrdQEGA3d6WG7kFmIJ1MQgOgb1lbeVDxU7nRnhlvqPHCX0R6yd8LHskO9W0skv/q3rvBE+gIofm2cUIIFFFctn3ZI7REfj3lzh6Yn4VINAdtV7Tsd8D84THdApm1nu5nNSr8pVrwjjMRvDBhFRaSnkkuF3LChU0LVFv30sLkKqxiJRUVzhW1Tio/slejcemSeOaaHEFeMW4Dad9i6PgMizC6Ub0UZ6pXLD+s68hMvftvd4jFhRvtZZTfAOdmUdzsaSD5AhlUuhoTKuz9kBB7+invcWVPH5I+5V8LDQ43CQ/i6vOJtK2/9kQ9XqF/laN6iHdJriHKJZJNZHXEgWrY5UmiMKkTI/MjS4vO2e7pLAMUwQCJhIauzXGZBX6jhi8F79zSrBpYf27wfqo3d59AZS027UN1+bQWaBbA/wJZ3d2Fe+Mjjfers2WxtUJh+66xM4w4S3VGbSsxbCrI9VUyWCV13C5beO/rtcfBlsY9VdeXh80ZZ9rrzt82sbhwog4fULS6BKyZeMSDTgspKW6KmZrMQRXKDW9A== MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 16a87eee-b2e7-4da6-f69d-08d43c3f3a40 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(8251501002);SRVR:CY1PR0201MB0761; X-Microsoft-Exchange-Diagnostics: 1;CY1PR0201MB0761;3:JPU+hGsrYdvpeuJTfrGDQcHCjt1Ztf/anrFkZI9zFJDuqawlpQsN6daNTNor3kbX2S88RV87A3lZqlAMvBV1SqNx/yxB27juRE5bI3bJROPpi8LZiqvsxClDuQBEnFN4a+JMm4h0WKhYr/KJoXY0wg0o6lRzcCL11uXLqjhB94xHR5ikpaS/4eGAW7O/+FiKWnEJKgeetluVwg074cvN9FNXlz8xulZ6qNaE1HtfM7OxNrA+MOyf6JZYlxjyEGs4X/ax63X8/VwOZMWOzqalvG5O2eoTSpAiveZ6Q06gzGO9sLcyeIPEJxQ32gSljCj/n5KBYnS8kuKbBXu+TQnjS8ykOywfVMtc7WhUpSISM6RNSv9S0Nek3JPveWROOkAjF/ZCmcGv+liFdx9sKacupQ==;25:uQ9zHNjyrkyJ5fFwA2nygzyTBh3+xSGMlwAlap7B5n48iN3LDKXYaeXCNPfdhBkaAmJ+EkoW10P3FvzRNnLAT8plC6O+SHPDxxlvUmNrpF74MSmSJ5zcvuwLj6LgKKJim7Pm2yo634iZerLvtNlaNoKuoZ5dfEzm1CC84fJgrEkHHtgCiMWNuH82KNRZklFz8IZ4CqC7GsuCyrkIqds/tx/4c1rB7kU1Fd7jxx0A0AvfI5x8RWkMNVqqVCYTa8IPxSpj+gRsKvXRrE6ewcQ3PoYmBwhMUdzOg0M8TMz7SzXC/v+bREGJb1rqGAQi2NQgNUAGGYQVWS9vRQdRVx+E+ya5CLPMSuOb3tiMUrYzTjG3+ZWB1ufXZJWeZlHxu+Byd90wFbJ5/eYNP1v0GUfnEJutASizikdSvqtbHcRq+akiGYE3eoDR/R9azX81NLjg5a7nqAFo5Q0gTVqsIQHVhw== X-Microsoft-Exchange-Diagnostics: 1;CY1PR0201MB0761;31:tOQqYDbaBpKTtcCJGe56vPe1o3or572Y9uHEmc2AiJ096tDcvuxzoUh50rIZVxsSzXZAs3T+L3fcvGiD5PztNr1gbkaeuMi8dXCmfzCoIc7vH1jXivH1G4BbSvjwVT6pd8QvOiLF3Vgh1KA2rJtUlFdITrDqpD0oRv4x9c+rf/+tZIwi18QcB4OUmofQ+J1n05YyR8Vnygg6XyibWvMNI8ufzPtNXIIIndO5Hs3pAwM1rdKkKB7BDwVAmgbn47kbghK1tDtbfw6dqs7J3y4IlA==;20:Tl3i3j/Ndsoo+gSfNHJTGRRZEsmyJiqUCmRbiJL4CM0WF//RmcTnpf+Gx2bOO2s/QV/6TMYuXNjQetmElwlImzY1SMzlp0bWYb/8S3hqLopq0QcG2bBy+hMHmxYVfov9xGAJnoo15Fe2jl36ErN9+p68CehE8enuTUc33vWKQr00Y/tdwjiOrYiFa8Xde07FiWz5Sr9Ti3R5PGzVXhmruVlsuIcZ140Vze2CI/AyxXPDm1/DYX7fjObx9aD2QuGOzacaEytrn0q/Xr6Zy0jPI0e/oe6V43QicfEhCw+Hp6vV47G7wY855rXR3uDj5Cx1Pwpc9lZIBCawY22j+5Ojle57q8TeeY0XQPeZWh8NYF2aCERrEUkO8F4zFuqKkTylWNsMtqxHmIKIMlbAqRTteJVU3Xu8qirBQCe3kh4QYC+PgMKsO4f2/JLsfMiwrjj9Q/ipyjkRocWVBGal/jHE4et3CV66nG/qw6suQ0slvtILDwO7/Ssl67/8OzpKy4lo 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)(5005006)(8121501046)(13017025)(13023025)(13024025)(13015025)(13018025)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123560025)(20161123564025)(20161123562025)(6072148);SRVR:CY1PR0201MB0761;BCL:0;PCL:0;RULEID:;SRVR:CY1PR0201MB0761; X-Microsoft-Exchange-Diagnostics: 1;CY1PR0201MB0761;4:DJ9mgOGuzMqe2GUOkeamKRzn1UwThUjmvgQcO8vf0ceK6jRDU9SbX4PE5Jq3z+5WQ6yDhn7uZFJgRDgmfXz2alYJ+3QsvZuwc1aw5XeRmoYI0DD1DKGTzpTP3XgPfU+u/VFsqQqA+QSeglcTGw4aokqfAu/kNKVmsRroEY7Xue6CI7JFyQZcMUOPCOSDzA1fah66EYpE5lMB6AM9ksbVVqMPHHkYQczlkh4lZeH46PiVI7F71S0R3ayKF7IJGoBqEzN8Seb0FfqnVHRRd0HtubA+DCDzGNW8/jzc/GspQOIXGCPXsBaTpI+izj3c967x+/6YWGq8ON1PS41/cPnrA6FfqIyQfIQaUy2khbCmWiE1vUeuJoRbrkbBLqgL4ZPOmiWpzunx5or4YTYXnRPZUPhStgwgiAtRYHdQu5svT9XNhZfAkcLxjEhdC9wh2Pgiev45wpid6z4v9PHssfYWEGweb2zB7ZCD6r6fDhhC+2xWPlpXG6OBDdbCDBOQbLFX2rwqNJKJS5GEaGaCaexMyHMoG/OuSc2KItJlTpXmcUEPPHVEVDxv6moYAxF5Gj/rBitz9bDDVNUzhXSeWKiNF1+z50F4Od9roW/bpWAQPZWegFgtV+8Gp8l0Dpw8G8VSIIU5vE17V7YVFiIg0rPGdEn4TpqMleprj+Aj9ICAqoxe0ScKAxainmciNOHq9YROvQ7YuF96kKGQfhucR4BAZv5n93+mFpMdlpGObwPvmsA= X-Forefront-PRVS: 0187F3EA14 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;CY1PR0201MB0761;23:F4ObytSt+ZBKMf2dQsqt1THDe6RfsXB6lw3e7MD?= =?us-ascii?Q?Jr4z6GJuCi+GuAdMSwxVq51Ksah5eyBTGR7SUI7Lo11ETcIBSb5fPpXfA2jU?= =?us-ascii?Q?labmdOd4TlPJyDjt9rID8vXLSK5e/8Ae7bUWbOhRVRk0GAfcdD0jdy0SpBAR?= =?us-ascii?Q?qDJzfWhWGlkodJTQ0w81z8GEY2DBxvduG+IU08T7FAuJol9gqnSK1FMYhlBt?= =?us-ascii?Q?HDACu4uVz5jC9KUWBTlPGYRvmWqZb63ZOj0FYyYH8kJXtRAeY/WkJP4ilUXA?= =?us-ascii?Q?dCc9goOOJuH50vAmreEaqVvqZHsYWYXsrYFvrHvKv6BT4IuAC09yMhqVRuAZ?= =?us-ascii?Q?0tlRlqOp+ra020IPwq0ixCUYBDYg9evdf7OoYpHbrvYjs1BwcxUOO+/M3/Zy?= =?us-ascii?Q?VIIhv6+kj8LV3u9Qd2s1Lpzhbxa5yVCbLWZZSw+8ULFsnceghYFu3of3pVEj?= =?us-ascii?Q?yupeKfiPw3043pZVfSyU4CmdXlHhs7MwRk7URBbKMguLh76dSSNBUCi5E+uo?= =?us-ascii?Q?/RxJOYkUJ6GCuQArHmGeD9auTenzRuRCLCVw4+2RD9c4+B/cRrD8X6EkbEvr?= =?us-ascii?Q?BbTJ5Lj5k4h9gDYgUQJ304VyfwcaYW9VUl/hW6U5DoNFDzo5WcQYtrDDjcdZ?= =?us-ascii?Q?gYM9hWSppSKcCGMeUsKyPHwWx3S9IiEHyUv+OOY4M0Kr0GcMHbe1ZZ+cRY63?= =?us-ascii?Q?3jwpG5uQSZFJwjGdolcBHRuzYlahXo02ghSONC1Gsb81ZI7nB97rDsrU636Z?= =?us-ascii?Q?0NHyoEhrWNi7JNKxq4BfEDBAE5UldKG50Jbyw7V4+HChOPnL34Dx8i78pOpC?= =?us-ascii?Q?uAwfR+f89bcJ4KY4xeXoWDYH+ra6H7QCsrtZigTHgQWR0xZntmhnrk+Dr6DV?= =?us-ascii?Q?M/h2yJNi9ZmiYHn4c9dFr1IDHpV0ihG4eeCbWPg17EjDUlFoBjbEV44LJqtz?= =?us-ascii?Q?qqvVwdJtUYQe8xFotK9/Ivdqy27M6TwxCtAqVY7Mw4ycMbUadPHGbGY0BvtE?= =?us-ascii?Q?T1kRFCcqJUr3vL0hXx5i6j3E0kqAOrNb1+8ZzN774l/7czlRsewUb06ea3lb?= =?us-ascii?Q?jEy7wy6feum4Vp/To0cmXY7L96uoUlGtRft4Sok7Z4UdvT8bVqncdlqmFNOx?= =?us-ascii?Q?VKMmeD6YMgi3OP5kGKw1sEvMMBIWBKoSPuZgau0YhFfi0DAi+QVDl5B0aTI8?= =?us-ascii?Q?D7WCTRMySJanzFE7F3OwE/iSAaM9+CANMpYpGI0cob/y+VV+IWRmml5kt+d4?= =?us-ascii?Q?koVv+ydhs7AskxBauqQAUxLgZPFdJh+MSfrrx3BjFbuQEW/ZUDoySRnXaLFo?= =?us-ascii?Q?CuuJBSct5wJ/K2eiTSEwQ9YslCmYC0s50nBuislBIq7J1QKk/Yqizv/yICOK?= =?us-ascii?Q?Y9obURg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;CY1PR0201MB0761;6:5yyBCEFDtjagfcaT8eY1Qw5DCC/nVEEUkYtxQd8EnXhbZVLV7ODe0/gpmCEQzYhODtmiM2SfGJv6VBfUZPXTycpYVgNeBZOnGA21+qSz52fWTV731aMKZmV+s7QP2h6FezYqJkRNaWYNB4xzNUzisxsY2SIFY93Lz7hDJqXGrh6y32DAbXwmhAiBz5islLGV5tiEBU89H6ai9GGfOCN3cjyuLO7CCi/X14zkIjiAiBr3Tp2ujIPfJasKymiItIovlKjIdCVWhjXYib5wPAKH+VDo0WYXynlwOrzOb5ykutS8L7GcMWYtlrrjy1lA4oI+Aged41vTIfFLDBMxqY1OuMhB3jpUys8gZ6Spbkv/68NhGYOY/Ig2hSRaNvoPYTvK7FWsUUBoC5mAQ3u5PtJCvYrIg4BjTyIbrw0/hXPhk+v3DHKu1EwY90Cwgx/bIC4fmfy2JDQyhg724pii8QpeAQ==;5:Qgstg2XwI6/Tdff1Nk8aSSxGK6pEU4xHO7RHi8aSSb1sdvhOQz2xm4AkVpt2MX08yRp5oCQHuSFLS4l9AvGSoZSkeTn2SUFcLRGG9Ur3dQxT3Dy9WGCxNemaHGl7LXmfqRRmlp45SnWy404WAU+ulrIihmzEfm8iDSc6e0HfklA=;24:71AYOMWrQAQpl3xdn5y+rq6dSQhmHIvOcPq8cKO6Mq37IbzHcXORn1PjQ6W9W+0P9fiV3l2OndT05DRlSPTvdGk3GVSVNwxi8rFfO2Sw7Gs= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY1PR0201MB0761;7:cfshbKBPF/YSpSWUKR0g4DWwpcRt0TUFjJBb1DW0x6QjCC/0UjaGdtPv43SwUoMWtf9MVOXiTAijbuHNK60p7A2MuK2bv64glyc5At9oaklPQHcrLvlEqJVsf5MveuoWo8Nsv0XlmBWUtxSPiTp28TBtb0O02AulyFA5XZHjX+D61CglAQ8fG+xHPUFcFJSVwwvUhNA2Tz0SNLQmFyD6rR078N9qv6lvabfJ4nqbz3V/Fohk3W2zjTcrzPNcUlv/eQJNUOER9BZRySmtHc5yBuCs8r+Dx/00trBeGEeqIAi023YMmndjQkodqyxki16ICEPeJxixRw9XcordVv61oKmIojt2cBB1bWA+lGtcudmHRyrkdraKOWC+IFOsTD3fyQIgD/C/mZHAmZSP1UqufoX2pRQVSAw+1RfjcZB2DRukh52UIJhPRVLpOGdjILIcZf49V6qgFXzPd9tEGU9Rng== X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Jan 2017 05:36:02.1212 (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: CY1PR0201MB0761 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add variable for checking channel idle state to ensure that dma descriptor is not Submitted when DMA engine is in progress. This will avoids the pollling for a bit in the status register to know Dma state in the driver hot path. Reviewed-by: Jose Abreu Signed-off-by: Kedareswara rao Appana --- Changes for v6: ---> Updated commit message as suggested by Vinod. ---> Added Channel idle variable description in the driver as suggested by Vinod. Changes for v5: ---> None. Changes for v4: ---> None. 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 | 61 +++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 8288fe4..5eeea57 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,12 @@ 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; + /* This variable enusres that descripotrs are not + * Submited when dma engine is in progress. This variable is + * Added to avoid pollling for a bit in the status register to + * Know dma state in the driver hot path. + */ + 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 v6 1/3] dmaengine: xilinx_dma: Check for channel idle state before submitting dma descriptor Date: Sat, 14 Jan 2017 11:05:53 +0530 Message-ID: <1484372155-19423-2-git-send-email-appanad@xilinx.com> References: <1484372155-19423-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: <1484372155-19423-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 variable for checking channel idle state to ensure that dma descriptor is not Submitted when DMA engine is in progress. This will avoids the pollling for a bit in the status register to know Dma state in the driver hot path. Reviewed-by: Jose Abreu Signed-off-by: Kedareswara rao Appana --- Changes for v6: ---> Updated commit message as suggested by Vinod. ---> Added Channel idle variable description in the driver as suggested by Vinod. Changes for v5: ---> None. Changes for v4: ---> None. 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 | 61 +++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 8288fe4..5eeea57 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,12 @@ 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; + /* This variable enusres that descripotrs are not + * Submited when dma engine is in progress. This variable is + * Added to avoid pollling for a bit in the status register to + * Know dma state in the driver hot path. + */ + 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: Sat, 14 Jan 2017 11:05:53 +0530 Subject: [PATCH v6 1/3] dmaengine: xilinx_dma: Check for channel idle state before submitting dma descriptor In-Reply-To: <1484372155-19423-1-git-send-email-appanad@xilinx.com> References: <1484372155-19423-1-git-send-email-appanad@xilinx.com> Message-ID: <1484372155-19423-2-git-send-email-appanad@xilinx.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Add variable for checking channel idle state to ensure that dma descriptor is not Submitted when DMA engine is in progress. This will avoids the pollling for a bit in the status register to know Dma state in the driver hot path. Reviewed-by: Jose Abreu Signed-off-by: Kedareswara rao Appana --- Changes for v6: ---> Updated commit message as suggested by Vinod. ---> Added Channel idle variable description in the driver as suggested by Vinod. Changes for v5: ---> None. Changes for v4: ---> None. 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 | 61 +++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 8288fe4..5eeea57 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,12 @@ 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; + /* This variable enusres that descripotrs are not + * Submited when dma engine is in progress. This variable is + * Added to avoid pollling for a bit in the status register to + * Know dma state in the driver hot path. + */ + chan->idle = true; spin_lock_init(&chan->lock); INIT_LIST_HEAD(&chan->pending_list); -- 2.1.2