Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932497AbbG0Xet (ORCPT ); Mon, 27 Jul 2015 19:34:49 -0400 Received: from mga01.intel.com ([192.55.52.88]:6215 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755025AbbG0Xd5 (ORCPT ); Mon, 27 Jul 2015 19:33:57 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,558,1432623600"; d="scan'208";a="772414174" From: Ashutosh Dixit To: Greg Kroah-Hartman , Dan Williams , Vinod Koul , linux-kernel@vger.kernel.org Cc: Ashutosh Dixit , Sudeep Dutt , Nikhil Rao , Siva Yerramreddy Subject: [PATCH char-misc-next 11/19] dma: Add support to program MIC x100 status descriptiors Date: Mon, 27 Jul 2015 16:58:17 -0700 Message-Id: <0c2dec1519fdd81dfe6335efc2a1edb0b142639b.1438040669.git.ashutosh.dixit@intel.com> X-Mailer: git-send-email 2.0.0.rc3.2.g998f840 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3549 Lines: 101 From: Siva Yerramreddy The MIC X100 DMA engine has a special status descriptor which writes an 8 byte value to a destination location. This is used to signal completion of all DMA descriptors prior to the status descriptor. This patch uses the src field as a value since the DMA engine API does not allow passing a value as an argument, if the length is 8 bytes. This special case works since the MIC x100 DMA engine requires cache line (64 byte) aligned src/dst/len so we can use the 8 byte length as a special case to enable programming status descriptors without requiring a change to the DMA engine API. Reviewed-by: Nikhil Rao Reviewed-by: Ashutosh Dixit Reviewed-by: Sudeep Dutt Signed-off-by: Siva Yerramreddy --- drivers/dma/mic_x100_dma.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/dma/mic_x100_dma.c b/drivers/dma/mic_x100_dma.c index 74d9db0..8d8acfc 100644 --- a/drivers/dma/mic_x100_dma.c +++ b/drivers/dma/mic_x100_dma.c @@ -193,8 +193,16 @@ static void mic_dma_prog_intr(struct mic_dma_chan *ch) static int mic_dma_do_dma(struct mic_dma_chan *ch, int flags, dma_addr_t src, dma_addr_t dst, size_t len) { - if (-ENOMEM == mic_dma_prog_memcpy_desc(ch, src, dst, len)) + if (len && -ENOMEM == mic_dma_prog_memcpy_desc(ch, src, dst, len)) { return -ENOMEM; + } else { + /* 3 is the maximum number of status descriptors */ + int ret = mic_dma_avail_desc_ring_space(ch, 3); + + if (ret < 0) + return ret; + } + /* Above mic_dma_prog_memcpy_desc() makes sure we have enough space */ if (flags & DMA_PREP_FENCE) { mic_dma_prep_status_desc(&ch->desc_ring[ch->head], 0, @@ -208,6 +216,21 @@ static int mic_dma_do_dma(struct mic_dma_chan *ch, int flags, dma_addr_t src, return 0; } +/* Program a status descriptor with phys as address and value to be written */ +static int mic_dma_do_status_update(struct mic_dma_chan *ch, dma_addr_t phys, + u64 value) +{ + int ret = mic_dma_avail_desc_ring_space(ch, 4); + + if (ret < 0) + return ret; + ret = 0; + mic_dma_prep_status_desc(&ch->desc_ring[ch->head], + value, phys, false); + mic_dma_hw_ring_inc_head(ch); + return ret; +} + static inline void mic_dma_issue_pending(struct dma_chan *ch) { struct mic_dma_chan *mic_ch = to_mic_dma_chan(ch); @@ -287,9 +310,28 @@ mic_dma_prep_memcpy_lock(struct dma_chan *ch, dma_addr_t dma_dest, return NULL; spin_lock(&mic_ch->prep_lock); + if (len == 8) { + /* + * This is a hack to program status descriptor since + * DMA engine API doesn't have support for this. + */ + result = mic_dma_do_status_update(mic_ch, dma_dest, dma_src); + if (result) + goto error; + + result = mic_dma_do_dma(mic_ch, DMA_PREP_FENCE, 0, 0, 0); + if (result < 0) + goto error; + result = mic_dma_do_dma(mic_ch, flags, 0, 0, 0); + if (result < 0) + goto error; + return allocate_tx(mic_ch); + } + result = mic_dma_do_dma(mic_ch, flags, dma_src, dma_dest, len); if (result >= 0) return allocate_tx(mic_ch); +error: dev_err(dev, "Error enqueueing dma, error=%d\n", result); spin_unlock(&mic_ch->prep_lock); return NULL; -- 2.0.0.rc3.2.g998f840 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/