From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755484AbbJHJgT (ORCPT ); Thu, 8 Oct 2015 05:36:19 -0400 Received: from mail-by2on0113.outbound.protection.outlook.com ([207.46.100.113]:55200 "EHLO na01-by2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1755285AbbJHJgP (ORCPT ); Thu, 8 Oct 2015 05:36:15 -0400 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; mentor.com; dkim=none (message not signed) header.d=none;mentor.com; dmarc=none action=none header.from=freescale.com; Date: Thu, 8 Oct 2015 17:19:53 +0800 From: Robin Gong To: "Bondarenko, Anton" CC: "s.hauer@pengutronix.de" , "broonie@kernel.org" , "linux-kernel@vger.kernel.org" , "linux-spi@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "Wang, Jiada (ESD)" , "Zapolskiy, Vladimir" Subject: Re: [PATCH v2 1/8] spi: imx: Fix DMA transfer Message-ID: <20151008091951.GA6101@shlinux2> References: <20150930082341.GB2709@shlinux2> <04376A3D786BD947B28569C998A374A62E280DD6@NA-MBX-02.mgc.mentorg.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <04376A3D786BD947B28569C998A374A62E280DD6@NA-MBX-02.mgc.mentorg.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;BN1BFFO11FD019;1:OclROeQGHDG2fGnykCwbkdafIxAhYUtdN2shQ86UhcyzZIdU5zlXBtJ+wp7M7ViKEJOa/p7ErkWIxbe1yGGatqfuJLt9iRpNLc0alGNQweAPPwEBfwXNz1exGgtyO2kZS7OI+LY9Cyz2jNwaL0kqF/Zrpwc1MZhIrC7ioZtdXeR4uJDparo/r6DmC5ZCs9q0z5NX6jpHRILyOA38Ovl1506l8uGTzehpFfPzN4pz4unB71CC0F4uTqlNOy1/PdyQv72i/kLXh+nZWgCX9LakdSCZvHaDxcoYeQKvW6+eNT0q2f+x5GdFyZUVdTn8opXI2ju2XJ9pimXR83wcty1oRg== X-Forefront-Antispam-Report: CIP:192.88.158.2;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10019020)(6009001)(2980300002)(1109001)(1110001)(339900001)(24454002)(189002)(199003)(15975445007)(77096005)(64706001)(11100500001)(2950100001)(93886004)(47776003)(92566002)(33716001)(217423001)(189998001)(5001960100002)(110136002)(33656002)(19580395003)(105606002)(106466001)(85426001)(50466002)(87936001)(69596002)(23726002)(83506001)(50986999)(46406003)(54356999)(76176999)(5008740100001)(97756001)(6806005)(97736004)(4001350100001)(81156007)(46102003)(104016004)(5007970100001)(42262002);DIR:OUT;SFP:1102;SCL:1;SRVR:BY2PR03MB491;H:az84smr01.freescale.net;FPR:;SPF:Fail;PTR:InfoDomainNonexistent;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB491;2:mt/yGZlugi9RzlI0lMSzgKxeGhYm286s9vDSQa/s5S35JnHdL40zHymnGdklfWmKx9pIZqykmAiAcwze4sYUjMHdvjQZWObMVH2t4/nLgbEFkrMnlQ1Qkj696OwcqWoOmtCU75mPhFTiLGTk80nEEwrU2WyrvH+QJHKiapQxzkQ=;3:zKnkf6eIv+z1Ge/WfwFSVIoRj5z3Dr+Ox5lUM5kdoidwvGV/7WWmf83Klc8jVMGsKEf0v1BVj0CeUKGTJCZmiP4cj2fVpfe/6uhLVnUk0soiyoCrjJeAmc3s89F4WA061FRgFgNPUapplJq65oNhln4nqo8tOcMwowSfRk4MuZaZ3PL+pxKbPzKNtvtqznFjSxKAO3sL0eerIUbYXi4ZVQadFByVmnrQoMqeKp+IXcQ=;25:fN2bPk8Xal8gzd2EfSN4G31v505lKxmTI0NLnZb/ftRdP+/1z/di5xzaTPcwrpt+Kaxr/duRYOtO6IPz6kWPHM6asuRdauUzQXziVaODsvSnm9fXGekzI4lLjR4ZrH8vOoMU9KHEdjvJSRa/Z7Vu5gt0IC+GjlzoWwaVqemV3tuYogqbNtBfnkkjjXlPjUYBu/It6B2I9G2nnh9Y018IDS2FQMXs5XmWquRQogbjlnyoS75G+eybB+LQhRp/gghw8MitIakRJY9s7U5hRsIOcg== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY2PR03MB491; X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB491;20:fdaK1GrMg5yOhTwC66ZyddA4SRatWgBMG3J+I/3na5sjq+oMk2cK2nblUoiOJfJE9nJ0XVdXiSEwHmrFN6wOlcWR+9H/hSyySuo4f2RJ6QI77p8/NbXIDBTuEJzus5hyPfMsKNyBaecqZeyBpPcOJ+HzttxhegsqXo/DO/Df52R1EWpdjRuJN7XKAZKjxWY3/WIx6i543p7eGgUn6YN2bCAXPvQK/vDV5tdu4jAFG/4BUj4iw71vd/PV77s/yDhYJHfJZYlvcsRDZjbAXgUG6OSs6xMj3tthfIIjsjcYuG0XVtxNfn7/2mfumylHLW4O17SBo0n3UPUkqHXWn8qIgM2ftwdRHVMmMBl1JDmG8Xg=;4:Lj0RtychGogrKBc6UJpWT+VrqHMnrfFOHXwSqjF/rREOeo3GjOzn1UjwJZldrwuxnxZ33alhNNYFagE9231eDVGmd+1xwXKPRVOZpMvbeq+dLZOPHZxJx0bBe17BI4cA4bgAf3AwMJfuFTXjQXkNzgVxBl3qyU+dGe7pFTRQ84N5zgmQACyPO/KVijwjRNjr7NsrKGwtgJktSM8UlBDNA/PNI0MAPirRAGXyKHnZPlrsF2pQDWEjoE7ZAHYFnyE5EonpP06udOX1iwVsGkgfnU8oVncEo4eOY3bogHraqW6WYbXKmxBmd/aNOREmx26sv2d9xIYi22bMCPbkKD0qbk+HwTOLKOUY4K2XNRs//uA= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(520078)(8121501046)(3002001);SRVR:BY2PR03MB491;BCL:0;PCL:0;RULEID:;SRVR:BY2PR03MB491; X-Forefront-PRVS: 0723A02764 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BY2PR03MB491;23:AUZkvTLP1+av+DdT+D0dhIzATpsWOexwSIAsRm/m7z?= =?us-ascii?Q?8APwmbbe2Ru690nim65Pa3AaVDuNhoos50le+JP3v9F5k+VYbzihy5/3DRMY?= =?us-ascii?Q?0awBr3f7c/mkhSEp0/U5pxbO3jct9SGEPnC2CZUTLjLC0JIGz2vsPlL8osBo?= =?us-ascii?Q?Ly1ySfbj/3ezzU3SIJJUlSpJJG808fBk4FEB7+4UXemTtmVXseH33/gLbfA7?= =?us-ascii?Q?pnpR8e0+6nmsbgZwjSAEYgDTjBmI9rzal/Xz7FhzQBuqojIJMd1humS6EAo0?= =?us-ascii?Q?pb0BFip0tk8KSC+3nnEzuLecJV7qoLPd/yxOkzPZ2G12iZryPZEGDzNpANRx?= =?us-ascii?Q?v5s7/7V521GPHi7ITGAB/JP53WRqT4svIHrGtrWqiKSmihgGGltUf982lwjF?= =?us-ascii?Q?/D9um69gS5YIW4sLgJB22wty+LBA6DLaODaZjJ/yCAquxh2VUY+Rvkdjhtxv?= =?us-ascii?Q?LLjBm3lDTzCZk89fRiB0lEbhOGZPCkpjGVfiTEQaS4v30g7gLiyRyfNv0PqS?= =?us-ascii?Q?MvynhDcSg0MNG0/60pHsS24RiZwTrcB7JX9ud604rrsWrCEAkoB1Dl372B51?= =?us-ascii?Q?oQmU0JET4imRWsscjtZm0Au9sQAByyXtrVxbQc9vrbwZBhKGijLuTvxWtkBK?= =?us-ascii?Q?BImwJt2qzOUemULyDKvu4DXpe+1OqKPYjH8PnRihxTS3tFpHF0Awy9UNwpcu?= =?us-ascii?Q?AEJ7C1HZEtm0nNqV9VQDqd9ZCMmkXBmuNs9+iOMJphNgqthxfTJpRF+eP7BO?= =?us-ascii?Q?21/uPNBDMxf9Cir2ZN7dhyebiAjvo0Aa8uoaTuWvOrK4+3V4EuCyXHBZ7Jb4?= =?us-ascii?Q?rATAFqdoDMMYjciNXa4JDqbHDtdHc3+K1KexQ2E8eZp9jAdexitbdCtb56Nl?= =?us-ascii?Q?MwNdyUqq5WHhi0EKWANzwHicp1QCcC/lnSYwGCLexhrVgEtTRayCDUzfExZ+?= =?us-ascii?Q?aTMfO2Ylek5IacT9cZO68aATG+aThJPQu09IVnA4y1d4RCRz9wBCox5VI2w6?= =?us-ascii?Q?P3aeWCEVN6CWE/cAqoqXv5POBxIYyjAM5d/lQZEoDy4m42sxySnBbdLVlVVm?= =?us-ascii?Q?SudAf4Sq9c/vBSfy/qCBcPVu5U8LFtFK/703oKztmiuQqs4ViUjwsQcHa3A8?= =?us-ascii?Q?zPigjPUlJMIZnvK74Ejcc+pBi3+a4w6T3sAJ4toZwwRmgMtj7oLMoDIBARMh?= =?us-ascii?Q?BPXb/AFEWN4xQ=3D?= X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB491;5:T/FPVNfaXt+toxZOq2bq2weSk3PM67XIb13PrDzwJ+LJ5RsB5uyatOpSAcAiv9zhi59Hpket00GqN1/cbkTK/GxL0N7e1aqg+QI1RdLzRAZkiEjhR6KDJvrS3iVoWFnCUhYtDQ0PwAq4JIq3EZmFGg==;24:DsE6uORBh8jYsxuIV7VvkxTITgWVcWPkRNde6R8DOjcdeGRU9TPBwKrunBQL8lfRbggdTjhoL+7m3U2c9uCfKV+YF1MS86I+lQ/Yj5KBsgw=;20:j51QiM5zvK9RPYdIiXt9cWO8oTzygCpdgHnv822UB3Q09cPhx8VY+KwlDLVhS8gpxCYt5VPhX5Gj46APM7MiXA== SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Oct 2015 09:20:30.3798 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d;Ip=[192.88.158.2];Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR03MB491 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Oct 01, 2015 at 12:02:41AM +0000, Bondarenko, Anton wrote: > >> @@ -201,9 +202,8 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, > >> { > >> struct spi_imx_data *spi_imx = spi_master_get_devdata(master); > >> > >> - if (spi_imx->dma_is_inited > >> - && transfer->len > spi_imx->rx_wml * sizeof(u32) > >> - && transfer->len > spi_imx->tx_wml * sizeof(u32)) > >> + if (spi_imx->dma_is_inited && > >> + (transfer->len > spi_imx->wml * sizeof(u32))) > > Add Sascha in the loop. I don't think "* sizeof(u32)", since even 1 byte data > > will consume one position of 32bit FIFO Thus if here > > spi_imx->wml = spi_imx_get_fifosize(spi_imx) / 2 = 32, the threshold value > > which judge DMA mode used or not should be 32 not 32 * 4. > > Of course, it will not cause any function break since both DMA and PIO can work > > ,but I think we'd better correct it. > I agree, in case of 1 byte SPI word we do not need to multiply by 4. > But for 16 bit and 32 bit SPI words it's necessary. This part is > addressed in patch 3. > I could remove "* sizeof(u32)" for now. I still think don't need *sizeof(u32) even for 16bit and 32bit, whatever bits used as one spi word(<32bits), one spi word consume one position of SPI FIFO (32bit). > >> return true; > >> return false; > >> } > >> @@ -369,19 +374,10 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, > >> * and enable DMA request. > >> */ > >> if (spi_imx->dma_is_inited) { > >> - dma = readl(spi_imx->base + MX51_ECSPI_DMA); > >> - > >> - spi_imx->rxt_wml = spi_imx_get_fifosize(spi_imx) / 2; > >> - rx_wml_cfg = spi_imx->rx_wml << MX51_ECSPI_DMA_RX_WML_OFFSET; > >> - tx_wml_cfg = spi_imx->tx_wml << MX51_ECSPI_DMA_TX_WML_OFFSET; > >> - rxt_wml_cfg = spi_imx->rxt_wml << MX51_ECSPI_DMA_RXT_WML_OFFSET; > >> - dma = (dma & ~MX51_ECSPI_DMA_TX_WML_MASK > >> - & ~MX51_ECSPI_DMA_RX_WML_MASK > >> - & ~MX51_ECSPI_DMA_RXT_WML_MASK) > >> - | rx_wml_cfg | tx_wml_cfg | rxt_wml_cfg > >> - |(1 << MX51_ECSPI_DMA_TEDEN_OFFSET) > >> - |(1 << MX51_ECSPI_DMA_RXDEN_OFFSET) > >> - |(1 << MX51_ECSPI_DMA_RXTDEN_OFFSET); > >> + dma = (spi_imx->wml - 1) << MX51_ECSPI_DMA_RX_WML_OFFSET > >> + | (spi_imx->wml - 1) << MX51_ECSPI_DMA_TX_WML_OFFSET > >> + | (1 << MX51_ECSPI_DMA_TEDEN_OFFSET) > >> + | (1 << MX51_ECSPI_DMA_RXDEN_OFFSET); > > Please set tx threshold as 0 as your v1 patch if I remember right, as our > > internal tree done: > > http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/commit/drivers/spi/spi-imx.c?h=imx_3.14.28_7d_alpha&id=2e7615e2f399e39c58dd31f84a31f7c2592da7e7 > Will be fixed in V3 patchset > >> > >> writel(dma, spi_imx->base + MX51_ECSPI_DMA); > >> } > >> @@ -825,6 +821,8 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, > >> if (of_machine_is_compatible("fsl,imx6dl")) > >> return 0; > >> > >> + spi_imx->wml = spi_imx_get_fifosize(spi_imx) / 2; > >> + > >> /* Prepare for TX DMA: */ > >> master->dma_tx = dma_request_slave_channel(dev, "tx"); > >> if (!master->dma_tx) { > >> @@ -836,7 +834,8 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, > >> slave_config.direction = DMA_MEM_TO_DEV; > >> slave_config.dst_addr = res->start + MXC_CSPITXDATA; > >> slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; > >> - slave_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 2; > >> + slave_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) > >> + - spi_imx->wml; > > slave_config.dst_maxburst = spi_imx->wml;? > Will be fixed in V3 > >> ret = dmaengine_slave_config(master->dma_tx, &slave_config); > >> if (ret) { > >> dev_err(dev, "error in TX dma configuration.\n"); > >> @@ -854,7 +853,8 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, > >> slave_config.direction = DMA_DEV_TO_MEM; > >> slave_config.src_addr = res->start + MXC_CSPIRXDATA; > >> slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; > >> - slave_config.src_maxburst = spi_imx_get_fifosize(spi_imx) / 2; > >> + slave_config.src_maxburst = spi_imx_get_fifosize(spi_imx) > >> + - spi_imx->wml; > > slave_config.src_maxburst = spi_imx->wml;? > Will be fixed in V3 > >> ret = dmaengine_slave_config(master->dma_rx, &slave_config); > >> if (ret) { > >> dev_err(dev, "error in RX dma configuration.\n"); > >> @@ -867,8 +867,6 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, > >> master->max_dma_len = MAX_SDMA_BD_BYTES; > >> spi_imx->bitbang.master->flags = SPI_MASTER_MUST_RX | > >> SPI_MASTER_MUST_TX; > >> - spi_imx->tx_wml = spi_imx_get_fifosize(spi_imx) / 2; > >> - spi_imx->rx_wml = spi_imx_get_fifosize(spi_imx) / 2; > >> spi_imx->dma_is_inited = 1; > >> > >> return 0; > >> @@ -897,8 +895,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, > >> struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL; > >> int ret; > >> unsigned long timeout; > >> - u32 dma; > >> - int left; > >> + const int left = transfer->len % spi_imx->wml; > >> struct spi_master *master = spi_imx->bitbang.master; > >> struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg; > >> > >> @@ -915,9 +912,23 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, > >> } > >> > >> if (rx) { > >> + /* Cut RX data tail */ > >> + const unsigned int old_nents = rx->nents; > >> + > >> + WARN_ON(sg_dma_len(&rx->sgl[rx->nents - 1]) < left); > >> + sg_dma_len(&rx->sgl[rx->nents - 1]) -= left; > >> + if (sg_dma_len(&rx->sgl[rx->nents - 1]) == 0) > >> + --rx->nents; > >> + > >> desc_rx = dmaengine_prep_slave_sg(master->dma_rx, > >> rx->sgl, rx->nents, DMA_DEV_TO_MEM, > >> DMA_PREP_INTERRUPT | DMA_CTRL_ACK); > >> + > >> + /* Restore old SG table state */ > >> + if (old_nents > rx->nents) > >> + ++rx->nents; > >> + sg_dma_len(&rx->sgl[rx->nents - 1]) += left; > >> + > >> if (!desc_rx) > >> goto no_dma; > >> > >> @@ -932,17 +943,10 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, > >> /* Trigger the cspi module. */ > >> spi_imx->dma_finished = 0; > >> > >> - dma = readl(spi_imx->base + MX51_ECSPI_DMA); > >> - dma = dma & (~MX51_ECSPI_DMA_RXT_WML_MASK); > >> - /* Change RX_DMA_LENGTH trigger dma fetch tail data */ > >> - left = transfer->len % spi_imx->rxt_wml; > >> - if (left) > >> - writel(dma | (left << MX51_ECSPI_DMA_RXT_WML_OFFSET), > >> - spi_imx->base + MX51_ECSPI_DMA); > >> + dma_async_issue_pending(master->dma_rx); > >> + dma_async_issue_pending(master->dma_tx); > >> spi_imx->devtype_data->trigger(spi_imx); > >> > >> - dma_async_issue_pending(master->dma_tx); > >> - dma_async_issue_pending(master->dma_rx); > > why change the sequence of issue_pending and trigger? I don't think need to do so. > The reason for order change for TX/RX requests is avoiding buffer > overflow for RX. This will happen if our code will be interrupted after > SPI HW and TX DMA started. This mean we will sent TX data, but there is > no one to consume RX data. So RX DMA should start before TX DMA. > On other hand TX DMA should start work earlier to fill buffer before SPI > HW starts pushing data out. This will give us a small performance bonus. > Not a big one, but still something for free. > >> /* Wait SDMA to finish the data transfer.*/ > >> timeout = wait_for_completion_timeout(&spi_imx->dma_tx_completion, > >> IMX_DMA_TIMEOUT); > >> @@ -951,6 +955,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, > >> dev_driver_string(&master->dev), > >> dev_name(&master->dev)); > >> dmaengine_terminate_all(master->dma_tx); > >> + dmaengine_terminate_all(master->dma_rx); > >> } else { > >> timeout = wait_for_completion_timeout( > >> &spi_imx->dma_rx_completion, IMX_DMA_TIMEOUT); > >> @@ -960,10 +965,32 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, > >> dev_name(&master->dev)); > >> spi_imx->devtype_data->reset(spi_imx); > >> dmaengine_terminate_all(master->dma_rx); > >> + } else if (left) { > >> + void *pio_buffer = transfer->rx_buf > >> + + (transfer->len - left); > >> + > >> + dma_sync_sg_for_cpu(master->dma_rx->device->dev, > >> + rx->sgl, rx->nents, > >> + DMA_FROM_DEVICE); > > Only the last entry needed: > > dma_sync_sg_for_cpu(master->dma_rx->device->dev, > > rx->sgl[rx->nents - 1], 1, > > DMA_FROM_DEVICE); > Agree. Will be fixed in V3 > >> + > >> + spi_imx->rx_buf = pio_buffer; > >> + spi_imx->txfifo = left; > >> + reinit_completion(&spi_imx->xfer_done); > >> + > >> + spi_imx->devtype_data->intctrl(spi_imx, MXC_INT_TCEN); > >> + > >> + timeout = wait_for_completion_timeout( > >> + &spi_imx->xfer_done, IMX_DMA_TIMEOUT); > >> + if (!timeout) { > >> + pr_warn("%s %s: I/O Error in RX tail\n", > >> + dev_driver_string(&master->dev), > >> + dev_name(&master->dev)); > >> + } > >> + > >> + dmac_flush_range(pio_buffer, pio_buffer + left); > The line above causing build error in some configurations. Replacing it > with dma_sync_sg call similar to previous one, but with > >> + outer_flush_range(virt_to_phys(pio_buffer), > >> + virt_to_phys(pio_buffer) + left); > >> } > >> - writel(dma | > >> - spi_imx->rxt_wml << MX51_ECSPI_DMA_RXT_WML_OFFSET, > >> - spi_imx->base + MX51_ECSPI_DMA); > >> } > >> > >> spi_imx->dma_finished = 1; > >> -- > >> 2.5.2 > >> >