All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Gross <agross@codeaurora.org>
To: Archit Taneja <architt@codeaurora.org>
Cc: Vinod Koul <vinod.koul@intel.com>,
	dmaengine@vger.kernel.org, Kumar Gala <galak@codeaurora.org>,
	linux-arm-kernel@lists.infradead.org,
	linux-arm-msm@vger.kernel.org,
	Bjorn Andersson <bjorn.andersson@sonymobile.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [Patch v2 1/2] dmaengine: Add ADM driver
Date: Fri, 9 Jan 2015 11:08:49 -0600	[thread overview]
Message-ID: <20150109170849.GA16970@qualcomm.com> (raw)
In-Reply-To: <54AF5B3C.7070305@codeaurora.org>

On Fri, Jan 09, 2015 at 10:08:20AM +0530, Archit Taneja wrote:
> Hi,
> 
> On 01/08/2015 08:56 AM, Andy Gross wrote:
> >Signed-off-by: Andy Gross <agross@codeaurora.org>
> <snip>
> 
> >+static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
> >+	struct scatterlist *sgl, unsigned int sg_len,
> >+	enum dma_transfer_direction direction, unsigned long flags,
> >+	void *context)
> >+{
> >+	struct adm_chan *achan = to_adm_chan(chan);
> >+	struct adm_device *adev = achan->adev;
> >+	struct adm_async_desc *async_desc;
> >+	struct scatterlist *sg;
> >+	u32 i;
> >+	u32 single_count = 0, box_count = 0, desc_offset = 0, crci = 0;
> >+	struct adm_desc_hw_box *box_desc;
> >+	struct adm_desc_hw_single *single_desc;
> >+	void *desc;
> >+	u32 *cple, *last_cmd;
> >+	u32 burst;
> >+	int blk_size = -EINVAL;
> 
> blk_size should be set to 0 here. Otherwise async_desc->blk_size
> takes -EINVAL when no flow control.

We only use the blk_size value in the start_dma function, and only if
device_fc=1.  So for no flow control, any value is acceptable.  You can't prep a
descriptor with a bad blk_size and flow control on.  So we're covered both ways.

> 
> >+
> >+
> >+	if (!is_slave_direction(direction)) {
> >+		dev_err(adev->dev, "invalid dma direction\n");
> >+		return NULL;
> >+	}
> >+
> >+	/*
> >+	 * get burst value from slave configuration
> >+	 * If zero, default to maximum burst size
> >+	 * If larger than the max transfer size, set to ADM_MAX_XFER
> >+	 */
> >+	burst = (direction == DMA_MEM_TO_DEV) ?
> >+		achan->slave.dst_maxburst :
> >+		achan->slave.src_maxburst;
> >+
> >+	if (!burst || burst > ADM_MAX_XFER)
> >+		burst = ADM_MAX_XFER;
> >+
> >+	/* if using flow control, validate burst and crci values */
> >+	if (achan->slave.device_fc) {
> >+
> >+		blk_size = adm_get_blksize(burst);
> >+		if (blk_size < 0) {
> >+			dev_err(adev->dev, "invalid burst value w/ crci: %d\n",
> >+				burst);
> >+			return ERR_PTR(-EINVAL);
> >+		}
> >+
> >+		crci = achan->slave.slave_id;
> >+		if (!(crci & 0xf)) {
> 
> This check isn't sufficient for the crci to lie between 1 and 15.
> slave_id passed as, say, 0xf5, will be valid.

True.  The real range would be 0x10->0x1F, as bit 8 denotes the mux setting.
I'll put in a check here.

> 
> <snip>
> 
> 
> >+/**
> >+ * adm_dma_irq - irq handler for ADM controller
> >+ * @irq: IRQ of interrupt
> >+ * @data: callback data
> >+ *
> >+ * IRQ handler for the bam controller
> >+ */
> >+static irqreturn_t adm_dma_irq(int irq, void *data)
> >+{
> >+	struct adm_device *adev = data;
> >+	u32 srcs, i;
> >+	struct adm_async_desc *async_desc;
> >+	unsigned long flags;
> >+
> >+	srcs = readl_relaxed(adev->regs +
> >+			HI_SEC_DOMAIN_IRQ_STATUS(adev->ee));
> >+
> >+	for (i = 0; i < 16; i++) {
> 
> we could use adev->num_channels here instead of 16.

Right.  will fix.


> <snip>
> 
> >+
> >+static int adm_dma_probe(struct platform_device *pdev)
> >+{
> >+	struct adm_device *adev;
> >+	struct resource *iores;
> >+	int ret;
> >+	u32 i;
> >+
> >+	adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL);
> >+	if (!adev)
> >+		return -ENOMEM;
> >+
> >+	adev->dev = &pdev->dev;
> >+
> >+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >+	adev->regs = devm_ioremap_resource(&pdev->dev, iores);
> >+	if (IS_ERR(adev->regs))
> >+		return PTR_ERR(adev->regs);
> >+
> >+	adev->irq = platform_get_irq(pdev, 0);
> >+	if (adev->irq < 0)
> >+		return adev->irq;
> >+
> >+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &adev->ee);
> >+	if (ret) {
> >+		dev_err(adev->dev, "Execution environment unspecified\n");
> >+		return ret;
> >+	}
> >+
> >+	adev->core_clk = devm_clk_get(adev->dev, "core");
> >+	if (IS_ERR(adev->core_clk))
> >+		return PTR_ERR(adev->core_clk);
> >+
> >+	ret = clk_prepare_enable(adev->core_clk);
> >+	if (ret) {
> >+		dev_err(adev->dev, "failed to prepare/enable core clock\n");
> >+		return ret;
> >+	}
> >+
> >+	adev->iface_clk = devm_clk_get(adev->dev, "iface");
> >+	if (IS_ERR(adev->iface_clk))
> >+		return PTR_ERR(adev->iface_clk);
> >+
> 
> An error here or below would leave core_clk on.

Will fix, thanks.

> >+		dev_err(adev->dev, "failed to get ADM0 C2 reset\n");
> >+		return PTR_ERR(adev->c2_reset);
> >+	}
> 
> All the devm_reset_control_get() failures should disable the clocks too.

Thanks, I'll fix that up.


-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

WARNING: multiple messages have this Message-ID (diff)
From: agross@codeaurora.org (Andy Gross)
To: linux-arm-kernel@lists.infradead.org
Subject: [Patch v2 1/2] dmaengine: Add ADM driver
Date: Fri, 9 Jan 2015 11:08:49 -0600	[thread overview]
Message-ID: <20150109170849.GA16970@qualcomm.com> (raw)
In-Reply-To: <54AF5B3C.7070305@codeaurora.org>

On Fri, Jan 09, 2015 at 10:08:20AM +0530, Archit Taneja wrote:
> Hi,
> 
> On 01/08/2015 08:56 AM, Andy Gross wrote:
> >Signed-off-by: Andy Gross <agross@codeaurora.org>
> <snip>
> 
> >+static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
> >+	struct scatterlist *sgl, unsigned int sg_len,
> >+	enum dma_transfer_direction direction, unsigned long flags,
> >+	void *context)
> >+{
> >+	struct adm_chan *achan = to_adm_chan(chan);
> >+	struct adm_device *adev = achan->adev;
> >+	struct adm_async_desc *async_desc;
> >+	struct scatterlist *sg;
> >+	u32 i;
> >+	u32 single_count = 0, box_count = 0, desc_offset = 0, crci = 0;
> >+	struct adm_desc_hw_box *box_desc;
> >+	struct adm_desc_hw_single *single_desc;
> >+	void *desc;
> >+	u32 *cple, *last_cmd;
> >+	u32 burst;
> >+	int blk_size = -EINVAL;
> 
> blk_size should be set to 0 here. Otherwise async_desc->blk_size
> takes -EINVAL when no flow control.

We only use the blk_size value in the start_dma function, and only if
device_fc=1.  So for no flow control, any value is acceptable.  You can't prep a
descriptor with a bad blk_size and flow control on.  So we're covered both ways.

> 
> >+
> >+
> >+	if (!is_slave_direction(direction)) {
> >+		dev_err(adev->dev, "invalid dma direction\n");
> >+		return NULL;
> >+	}
> >+
> >+	/*
> >+	 * get burst value from slave configuration
> >+	 * If zero, default to maximum burst size
> >+	 * If larger than the max transfer size, set to ADM_MAX_XFER
> >+	 */
> >+	burst = (direction == DMA_MEM_TO_DEV) ?
> >+		achan->slave.dst_maxburst :
> >+		achan->slave.src_maxburst;
> >+
> >+	if (!burst || burst > ADM_MAX_XFER)
> >+		burst = ADM_MAX_XFER;
> >+
> >+	/* if using flow control, validate burst and crci values */
> >+	if (achan->slave.device_fc) {
> >+
> >+		blk_size = adm_get_blksize(burst);
> >+		if (blk_size < 0) {
> >+			dev_err(adev->dev, "invalid burst value w/ crci: %d\n",
> >+				burst);
> >+			return ERR_PTR(-EINVAL);
> >+		}
> >+
> >+		crci = achan->slave.slave_id;
> >+		if (!(crci & 0xf)) {
> 
> This check isn't sufficient for the crci to lie between 1 and 15.
> slave_id passed as, say, 0xf5, will be valid.

True.  The real range would be 0x10->0x1F, as bit 8 denotes the mux setting.
I'll put in a check here.

> 
> <snip>
> 
> 
> >+/**
> >+ * adm_dma_irq - irq handler for ADM controller
> >+ * @irq: IRQ of interrupt
> >+ * @data: callback data
> >+ *
> >+ * IRQ handler for the bam controller
> >+ */
> >+static irqreturn_t adm_dma_irq(int irq, void *data)
> >+{
> >+	struct adm_device *adev = data;
> >+	u32 srcs, i;
> >+	struct adm_async_desc *async_desc;
> >+	unsigned long flags;
> >+
> >+	srcs = readl_relaxed(adev->regs +
> >+			HI_SEC_DOMAIN_IRQ_STATUS(adev->ee));
> >+
> >+	for (i = 0; i < 16; i++) {
> 
> we could use adev->num_channels here instead of 16.

Right.  will fix.


> <snip>
> 
> >+
> >+static int adm_dma_probe(struct platform_device *pdev)
> >+{
> >+	struct adm_device *adev;
> >+	struct resource *iores;
> >+	int ret;
> >+	u32 i;
> >+
> >+	adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL);
> >+	if (!adev)
> >+		return -ENOMEM;
> >+
> >+	adev->dev = &pdev->dev;
> >+
> >+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >+	adev->regs = devm_ioremap_resource(&pdev->dev, iores);
> >+	if (IS_ERR(adev->regs))
> >+		return PTR_ERR(adev->regs);
> >+
> >+	adev->irq = platform_get_irq(pdev, 0);
> >+	if (adev->irq < 0)
> >+		return adev->irq;
> >+
> >+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &adev->ee);
> >+	if (ret) {
> >+		dev_err(adev->dev, "Execution environment unspecified\n");
> >+		return ret;
> >+	}
> >+
> >+	adev->core_clk = devm_clk_get(adev->dev, "core");
> >+	if (IS_ERR(adev->core_clk))
> >+		return PTR_ERR(adev->core_clk);
> >+
> >+	ret = clk_prepare_enable(adev->core_clk);
> >+	if (ret) {
> >+		dev_err(adev->dev, "failed to prepare/enable core clock\n");
> >+		return ret;
> >+	}
> >+
> >+	adev->iface_clk = devm_clk_get(adev->dev, "iface");
> >+	if (IS_ERR(adev->iface_clk))
> >+		return PTR_ERR(adev->iface_clk);
> >+
> 
> An error here or below would leave core_clk on.

Will fix, thanks.

> >+		dev_err(adev->dev, "failed to get ADM0 C2 reset\n");
> >+		return PTR_ERR(adev->c2_reset);
> >+	}
> 
> All the devm_reset_control_get() failures should disable the clocks too.

Thanks, I'll fix that up.


-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

  reply	other threads:[~2015-01-09 17:08 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-08  3:26 [Patch v2 0/2] Add Qualcomm ADM dmaengine driver Andy Gross
2015-01-08  3:26 ` Andy Gross
2015-01-08  3:26 ` [Patch v2 1/2] dmaengine: Add ADM driver Andy Gross
2015-01-08  3:26   ` Andy Gross
2015-01-08  3:36   ` Andy Gross
2015-01-08  3:36     ` Andy Gross
2015-01-09  4:38   ` Archit Taneja
2015-01-09  4:38     ` Archit Taneja
2015-01-09 17:08     ` Andy Gross [this message]
2015-01-09 17:08       ` Andy Gross
2015-01-30 11:47   ` Pramod Gurav
2015-01-30 11:47     ` Pramod Gurav
2015-02-11  5:20     ` Andy Gross
2015-02-11  5:20       ` Andy Gross
2015-01-08  3:26 ` [Patch v2 2/2] dt/bindings: qcom_adm: Fix channel specificers Andy Gross
2015-01-08  3:26   ` Andy Gross
2015-01-08 16:26   ` Christopher Covington
2015-01-08 16:26     ` Christopher Covington
2015-01-08 17:19     ` Andy Gross
2015-01-08 17:19       ` Andy Gross

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150109170849.GA16970@qualcomm.com \
    --to=agross@codeaurora.org \
    --cc=architt@codeaurora.org \
    --cc=bjorn.andersson@sonymobile.com \
    --cc=dmaengine@vger.kernel.org \
    --cc=galak@codeaurora.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=vinod.koul@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.