* [3/4] dmaengine: imx-sdma: implement channel termination via worker
From: Lucas Stach @ 2018-09-12 9:22 UTC (permalink / raw)
To: Robin Gong, Vinod Koul
Cc: dmaengine@vger.kernel.org, dl-linux-imx, kernel@pengutronix.de,
patchwork-lst@pengutronix.de
Hi Robin,
Am Dienstag, den 11.09.2018, 08:18 +0000 schrieb Robin Gong:
> Hi Lucas,
> I have quick test for UART, seems this patch set broke uart function on i.mx7d,
> I believe it should be same on other i.mx6 family. Could you double check it?
Can you describe your testcase and the issue you've seen in more
detail? I'm running this patch series on a system that does a lot of
communication with an UART attached Co-processor and I'm not seeing any
issues.
Regards,
Lucas
> > -----Original Message-----
> > From: Lucas Stach <l.stach@pengutronix.de>
> > Sent: 2018年9月10日 17:59
> > To: Robin Gong <yibin.gong@nxp.com>; Vinod Koul <vkoul@kernel.org>
> > Cc: dmaengine@vger.kernel.org; dl-linux-imx <linux-imx@nxp.com>;
> > kernel@pengutronix.de; patchwork-lst@pengutronix.de
> > Subject: Re: [PATCH 3/4] dmaengine: imx-sdma: implement channel
> > termination via worker
> >
> > Am Dienstag, den 04.09.2018, 02:36 +0000 schrieb Robin Gong:
> > > > -----Original Message-----
> > > > From: Lucas Stach <l.stach@pengutronix.de>
> > > > Sent: 2018年9月3日 21:12
> > > > To: Robin Gong <yibin.gong@nxp.com>; Vinod Koul <vkoul@kernel.o
> > > > rg>
> > > > Cc: dmaengine@vger.kernel.org; dl-linux-imx <linux-imx@nxp.com>
> > > > ;
> > > > kernel@pengutronix.de; patchwork-lst@pengutronix.de
> > > > Subject: Re: [PATCH 3/4] dmaengine: imx-sdma: implement channel
> > > > termination via worker
> > > >
> > > > Am Montag, den 03.09.2018, 08:59 +0000 schrieb Robin Gong:
> > > > > > -----Original Message-----
> > > > > > From: Lucas Stach <l.stach@pengutronix.de>
> > > > > > Sent: 2018年9月3日 16:41
> > > > > > To: Robin Gong <yibin.gong@nxp.com>; Vinod Koul <vkoul@kern
> > > > > > el.o
> > > > > > rg>
> > > > > > Cc: dmaengine@vger.kernel.org; dl-linux-imx <linux-imx@nxp.
> > > > > > com>
> > > > > > ; kernel@pengutronix.de; patchwork-lst@pengutronix.de
> > > > > > Subject: Re: [PATCH 3/4] dmaengine: imx-sdma: implement
> > > > > > channel
> > > > > > termination via worker
> > > > > >
> > > > > > Hi Robin,
> > > > > >
> > > > > > Am Freitag, den 31.08.2018, 09:49 +0000 schrieb Robin Gong:
> > > > > > > Hi Lucas,
> > > > > > > Seems I miss your previous mail. Thanks for your patch,
> > > > > > > but
> > > > > > > if move most jobs of sdma_disable_channel_with_delay()
> > > > > > > into
> > > > > > > worker, that will bring another race condition that upper
> > > > > > > driver such as Audio terminate channel and free resource
> > > > > > > of
> > > > > > > dma channel without really channel stop, if dma transfer
> > > > > > > done
> > > > > > > interrupt come after that, oops or kernel cash may be
> > > > > > > caught.
> > > > > > > Leave 'sdmac->desc = NULL' in the
> > > > > >
> > > > > > sdma_disable_channel_with_delay() may fix such potential
> > > > > > issue.
> > > > > >
> > > > > > No, there is no such issue. The audio channel terminate
> > > > > > will
> > > > > > call dmaengine_terminate_sync(), which internally calls
> > > > > > dmaengine_terminate_async() and then does a
> > > > > > dmaengine_synchronize().
> > > > > > As this patchset implements the device_synchronize function
> > > > > > in
> > > > > > the sdma driver, this will wait for the worker to finish
> > > > > > its
> > > > > > execution, so there is no race condition to worry about
> > > > > > here.
> > > > > >
> > > > > > Regards,
> > > > > > Lucas
> > > > >
> > > > > Yes, but how about other drivers which not call
> > > > > dmaengine_terminate_sync()?
> > > >
> > > > Please read the dmaengine documentation. device_terminate_all
> > > > has no
> > > > requirement that the transfer is actually canceled when the
> > > > call
> > > > returns. If the caller needs a guarantee that the channel is
> > > > stopped
> > > > it _must_ call device_synchronize.
> > >
> > > I know that, but the fact is some driver still use
> > > dmaengine_terminate_all() such as
> > > Spi/uart driver. My concern is how to avoid to break their
> > > function.
> >
> > They should simply be fixed to not use a deprecated function. Both
> > of those are
> > only using device_terminate_all in error or shutdown paths, so the
> > risk of races
> > is pretty minimal even with the current code. And I think the SPI
> > driver is trivial
> > to fix, as we can just use the terminate_sync variant there. The
> > UART driver
> > is a bit more tricky.
> >
> > Regards,
> > Lucas
^ permalink raw reply
* [v2,2/2] dmaengine: uniphier-mdmac: add UniPhier MIO DMAC driver
From: Masahiro Yamada @ 2018-09-12 7:31 UTC (permalink / raw)
To: Vinod
Cc: open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, DTML, Rob Herring,
Linux Kernel Mailing List, Masami Hiramatsu, Jassi Brar,
Dan Williams, linux-arm-kernel
2018-09-12 16:26 GMT+09:00 Vinod <vkoul@kernel.org>:
> On 12-09-18, 14:25, Masahiro Yamada wrote:
>> 2018-09-12 13:35 GMT+09:00 Vinod <vkoul@kernel.org>:
>> > On 12-09-18, 12:01, Masahiro Yamada wrote:
>> >> Hi Vinod,
>> >>
>> >>
>> >> 2018-09-11 16:00 GMT+09:00 Vinod <vkoul@kernel.org>:
>> >> > On 24-08-18, 10:41, Masahiro Yamada wrote:
>> >> >
>> >> >> +/* mc->vc.lock must be held by caller */
>> >> >> +static u32 __uniphier_mdmac_get_residue(struct uniphier_mdmac_desc *md)
>> >> >> +{
>> >> >> + u32 residue = 0;
>> >> >> + int i;
>> >> >> +
>> >> >> + for (i = md->sg_cur; i < md->sg_len; i++)
>> >> >> + residue += sg_dma_len(&md->sgl[i]);
>> >> >
>> >> > so if the descriptor is submitted to hardware, we return the descriptor
>> >> > length, which is not correct.
>> >> >
>> >> > Two cases are required to be handled:
>> >> > 1. Descriptor is in queue (IMO above logic is fine for that, but it can
>> >> > be calculated at descriptor submit and looked up here)
>> >>
>> >> Where do you want it to be calculated?
>> >
>> > where is it calculated now?
>>
>>
>> Please see __uniphier_mdmac_handle().
>>
>>
>> It gets the address and size by sg_dma_address(), sg_dma_len()
>> just before setting them to the hardware registers.
>>
>>
>> sg = &md->sgl[md->sg_cur];
>>
>> if (md->dir == DMA_MEM_TO_DEV) {
>> src_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_INC;
>> src_addr = sg_dma_address(sg);
>> dest_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_FIXED;
>> dest_addr = 0;
>> } else {
>> src_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_FIXED;
>> src_addr = 0;
>> dest_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_INC;
>> dest_addr = sg_dma_address(sg);
>> }
>>
>>
>>
>>
>>
>>
>>
>> >> This hardware provides only simple registers (address and size)
>> >> for one-shot transfer instead of descriptors.
>> >>
>> >> So, I used sgl as-is because I did not see a good reason
>> >> to transform sgl to another data structure.
>> >
>> >
>> >> > this seems missing stuff. Where do you do register calculation for the
>> >> > descriptor and where is slave_config here, how do you know where to
>> >> > send/receive data form/to (peripheral)
>> >>
>> >>
>> >> This dmac is really simple, and un-flexible.
>> >>
>> >> The peripheral address to send/receive data from/to is hard-weird.
>> >> cfg->{src_addr,dst_addr} is not configurable.
>> >>
>> >> Look at __uniphier_mdmac_handle().
>> >> 'dest_addr' and 'src_addr' must be set to 0 for the peripheral.
>> >
>> > Fair enough, what about other values like addr_width and maxburst?
>>
>>
>> None of them is configurable.
>
> what is configurable here :-)
The physical address of the memory, transfer size, direction
are configurable, of course.
But, they are out of scope of device_config hook.
> Who are the users of this DMA?
SD/eMMC controllers.
^ permalink raw reply
* [v2,2/2] dmaengine: uniphier-mdmac: add UniPhier MIO DMAC driver
From: Vinod Koul @ 2018-09-12 7:26 UTC (permalink / raw)
To: Masahiro Yamada
Cc: open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, DTML, Rob Herring,
Linux Kernel Mailing List, Masami Hiramatsu, Jassi Brar,
Dan Williams, linux-arm-kernel
On 12-09-18, 14:25, Masahiro Yamada wrote:
> 2018-09-12 13:35 GMT+09:00 Vinod <vkoul@kernel.org>:
> > On 12-09-18, 12:01, Masahiro Yamada wrote:
> >> Hi Vinod,
> >>
> >>
> >> 2018-09-11 16:00 GMT+09:00 Vinod <vkoul@kernel.org>:
> >> > On 24-08-18, 10:41, Masahiro Yamada wrote:
> >> >
> >> >> +/* mc->vc.lock must be held by caller */
> >> >> +static u32 __uniphier_mdmac_get_residue(struct uniphier_mdmac_desc *md)
> >> >> +{
> >> >> + u32 residue = 0;
> >> >> + int i;
> >> >> +
> >> >> + for (i = md->sg_cur; i < md->sg_len; i++)
> >> >> + residue += sg_dma_len(&md->sgl[i]);
> >> >
> >> > so if the descriptor is submitted to hardware, we return the descriptor
> >> > length, which is not correct.
> >> >
> >> > Two cases are required to be handled:
> >> > 1. Descriptor is in queue (IMO above logic is fine for that, but it can
> >> > be calculated at descriptor submit and looked up here)
> >>
> >> Where do you want it to be calculated?
> >
> > where is it calculated now?
>
>
> Please see __uniphier_mdmac_handle().
>
>
> It gets the address and size by sg_dma_address(), sg_dma_len()
> just before setting them to the hardware registers.
>
>
> sg = &md->sgl[md->sg_cur];
>
> if (md->dir == DMA_MEM_TO_DEV) {
> src_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_INC;
> src_addr = sg_dma_address(sg);
> dest_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_FIXED;
> dest_addr = 0;
> } else {
> src_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_FIXED;
> src_addr = 0;
> dest_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_INC;
> dest_addr = sg_dma_address(sg);
> }
>
>
>
>
>
>
>
> >> This hardware provides only simple registers (address and size)
> >> for one-shot transfer instead of descriptors.
> >>
> >> So, I used sgl as-is because I did not see a good reason
> >> to transform sgl to another data structure.
> >
> >
> >> > this seems missing stuff. Where do you do register calculation for the
> >> > descriptor and where is slave_config here, how do you know where to
> >> > send/receive data form/to (peripheral)
> >>
> >>
> >> This dmac is really simple, and un-flexible.
> >>
> >> The peripheral address to send/receive data from/to is hard-weird.
> >> cfg->{src_addr,dst_addr} is not configurable.
> >>
> >> Look at __uniphier_mdmac_handle().
> >> 'dest_addr' and 'src_addr' must be set to 0 for the peripheral.
> >
> > Fair enough, what about other values like addr_width and maxburst?
>
>
> None of them is configurable.
what is configurable here :-)
Who are the users of this DMA?
^ permalink raw reply
* [v3,2/2] dmaengine: Add metadata_ops for dma_async_tx_descriptor
From: Peter Ujfalusi @ 2018-09-12 6:45 UTC (permalink / raw)
To: dan.j.williams, vkoul; +Cc: dmaengine, linux-kernel, lars, radheys
The metadata is best described as side band data or parameters traveling
alongside the data DMAd by the DMA engine. It is data
which is understood by the peripheral and the peripheral driver only, the
DMA engine see it only as data block and it is not interpreting it in any
way.
The metadata can be different per descriptor as it is a parameter for the
data being transferred.
If the DMA supports per descriptor metadata it can implement the attach,
get_ptr/set_len callbacks.
Client drivers must only use either attach or get_ptr/set_len to avoid
misconfiguration.
Client driver can check if a given metadata mode is supported by the
channel during probe time with
dmaengine_is_metadata_mode_supported(chan, DESC_METADATA_CLIENT);
dmaengine_is_metadata_mode_supported(chan, DESC_METADATA_ENGINE);
and based on this information can use either mode.
Wrappers are also added for the metadata_ops.
To be used in DESC_METADATA_CLIENT mode:
dmaengine_desc_attach_metadata()
To be used in DESC_METADATA_ENGINE mode:
dmaengine_desc_get_metadata_ptr()
dmaengine_desc_set_metadata_len()
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
drivers/dma/dmaengine.c | 73 ++++++++++++++++++++++++++
include/linux/dmaengine.h | 108 ++++++++++++++++++++++++++++++++++++++
2 files changed, 181 insertions(+)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index f1a441ab395d..27b6d7c2d8a0 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -1306,6 +1306,79 @@ void dma_async_tx_descriptor_init(struct dma_async_tx_descriptor *tx,
}
EXPORT_SYMBOL(dma_async_tx_descriptor_init);
+static inline int desc_check_and_set_metadata_mode(
+ struct dma_async_tx_descriptor *desc, enum dma_desc_metadata_mode mode)
+{
+ /* Make sure that the metadata mode is not mixed */
+ if (!desc->desc_metadata_mode) {
+ if (dmaengine_is_metadata_mode_supported(desc->chan, mode))
+ desc->desc_metadata_mode = mode;
+ else
+ return -ENOTSUPP;
+ } else if (desc->desc_metadata_mode != mode) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int dmaengine_desc_attach_metadata(struct dma_async_tx_descriptor *desc,
+ void *data, size_t len)
+{
+ int ret;
+
+ if (!desc)
+ return -EINVAL;
+
+ ret = desc_check_and_set_metadata_mode(desc, DESC_METADATA_CLIENT);
+ if (ret)
+ return ret;
+
+ if (!desc->metadata_ops || !desc->metadata_ops->attach)
+ return -ENOTSUPP;
+
+ return desc->metadata_ops->attach(desc, data, len);
+}
+EXPORT_SYMBOL_GPL(dmaengine_desc_attach_metadata);
+
+void *dmaengine_desc_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
+ size_t *payload_len, size_t *max_len)
+{
+ int ret;
+
+ if (!desc)
+ return ERR_PTR(-EINVAL);
+
+ ret = desc_check_and_set_metadata_mode(desc, DESC_METADATA_ENGINE);
+ if (ret)
+ return ERR_PTR(ret);
+
+ if (!desc->metadata_ops || !desc->metadata_ops->get_ptr)
+ return ERR_PTR(-ENOTSUPP);
+
+ return desc->metadata_ops->get_ptr(desc, payload_len, max_len);
+}
+EXPORT_SYMBOL_GPL(dmaengine_desc_get_metadata_ptr);
+
+int dmaengine_desc_set_metadata_len(struct dma_async_tx_descriptor *desc,
+ size_t payload_len)
+{
+ int ret;
+
+ if (!desc)
+ return -EINVAL;
+
+ ret = desc_check_and_set_metadata_mode(desc, DESC_METADATA_ENGINE);
+ if (ret)
+ return ret;
+
+ if (!desc->metadata_ops || !desc->metadata_ops->set_len)
+ return -ENOTSUPP;
+
+ return desc->metadata_ops->set_len(desc, payload_len);
+}
+EXPORT_SYMBOL_GPL(dmaengine_desc_set_metadata_len);
+
/* dma_wait_for_async_tx - spin wait for a transaction to complete
* @tx: in-flight transaction to wait on
*/
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 3db833a8c542..10ff71b13eef 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -231,6 +231,58 @@ typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t;
* @bytes_transferred: byte counter
*/
+/**
+ * enum dma_desc_metadata_mode - per descriptor metadata mode types supported
+ * @DESC_METADATA_CLIENT - the metadata buffer is allocated/provided by the
+ * client driver and it is attached (via the dmaengine_desc_attach_metadata()
+ * helper) to the descriptor.
+ *
+ * Client drivers interested to use this mode can follow:
+ * - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
+ * 1. prepare the descriptor (dmaengine_prep_*)
+ * construct the metadata in the client's buffer
+ * 2. use dmaengine_desc_attach_metadata() to attach the buffer to the
+ * descriptor
+ * 3. submit the transfer
+ * - DMA_DEV_TO_MEM:
+ * 1. prepare the descriptor (dmaengine_prep_*)
+ * 2. use dmaengine_desc_attach_metadata() to attach the buffer to the
+ * descriptor
+ * 3. submit the transfer
+ * 4. when the transfer is completed, the metadata should be available in the
+ * attached buffer
+ *
+ * @DESC_METADATA_ENGINE - the metadata buffer is allocated/managed by the DMA
+ * driver. The client driver can ask for the pointer, maximum size and the
+ * currently used size of the metadata and can directly update or read it.
+ * dmaengine_desc_get_metadata_ptr() and dmaengine_desc_set_metadata_len() is
+ * provided as helper functions.
+ *
+ * Client drivers interested to use this mode can follow:
+ * - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
+ * 1. prepare the descriptor (dmaengine_prep_*)
+ * 2. use dmaengine_desc_get_metadata_ptr() to get the pointer to the engine's
+ * metadata area
+ * 3. update the metadata at the pointer
+ * 4. use dmaengine_desc_set_metadata_len() to tell the DMA engine the amount
+ * of data the client has placed into the metadata buffer
+ * 5. submit the transfer
+ * - DMA_DEV_TO_MEM:
+ * 1. prepare the descriptor (dmaengine_prep_*)
+ * 2. submit the transfer
+ * 3. on transfer completion, use dmaengine_desc_get_metadata_ptr() to get the
+ * pointer to the engine's metadata are
+ * 4. Read out the metadate from the pointer
+ *
+ * Note: the two mode is not compatible and clients must use one mode for a
+ * descriptor.
+ */
+enum dma_desc_metadata_mode {
+ DESC_METADATA_NONE = 0,
+ DESC_METADATA_CLIENT = BIT(0),
+ DESC_METADATA_ENGINE = BIT(1),
+};
+
struct dma_chan_percpu {
/* stats */
unsigned long memcpy_count;
@@ -494,6 +546,18 @@ struct dmaengine_unmap_data {
dma_addr_t addr[0];
};
+struct dma_async_tx_descriptor;
+
+struct dma_descriptor_metadata_ops {
+ int (*attach)(struct dma_async_tx_descriptor *desc, void *data,
+ size_t len);
+
+ void *(*get_ptr)(struct dma_async_tx_descriptor *desc,
+ size_t *payload_len, size_t *max_len);
+ int (*set_len)(struct dma_async_tx_descriptor *desc,
+ size_t payload_len);
+};
+
/**
* struct dma_async_tx_descriptor - async transaction descriptor
* ---dma generic offload fields---
@@ -507,6 +571,11 @@ struct dmaengine_unmap_data {
* descriptor pending. To be pushed on .issue_pending() call
* @callback: routine to call after this operation is complete
* @callback_param: general parameter to pass to the callback routine
+ * @desc_metadata_mode: core managed metadata mode to protect mixed use of
+ * DESC_METADATA_CLIENT or DESC_METADATA_ENGINE. Otherwise
+ * DESC_METADATA_NONE
+ * @metadata_ops: DMA driver provided metadata mode ops, need to be set by the
+ * DMA driver if metadata mode is supported with the descriptor
* ---async_tx api specific fields---
* @next: at completion submit this descriptor
* @parent: pointer to the next level up in the dependency chain
@@ -523,6 +592,8 @@ struct dma_async_tx_descriptor {
dma_async_tx_callback_result callback_result;
void *callback_param;
struct dmaengine_unmap_data *unmap;
+ enum dma_desc_metadata_mode desc_metadata_mode;
+ struct dma_descriptor_metadata_ops *metadata_ops;
#ifdef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH
struct dma_async_tx_descriptor *next;
struct dma_async_tx_descriptor *parent;
@@ -685,6 +756,7 @@ struct dma_filter {
* @global_node: list_head for global dma_device_list
* @filter: information for device/slave to filter function/param mapping
* @cap_mask: one or more dma_capability flags
+ * @desc_metadata_modes: supported metadata modes by the DMA device
* @max_xor: maximum number of xor sources, 0 if no capability
* @max_pq: maximum number of PQ sources and PQ-continue capability
* @copy_align: alignment shift for memcpy operations
@@ -749,6 +821,7 @@ struct dma_device {
struct list_head global_node;
struct dma_filter filter;
dma_cap_mask_t cap_mask;
+ enum dma_desc_metadata_mode desc_metadata_modes;
unsigned short max_xor;
unsigned short max_pq;
enum dmaengine_alignment copy_align;
@@ -935,6 +1008,41 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_memcpy(
len, flags);
}
+static inline bool dmaengine_is_metadata_mode_supported(struct dma_chan *chan,
+ enum dma_desc_metadata_mode mode)
+{
+ if (!chan)
+ return false;
+
+ return !!(chan->device->desc_metadata_modes & mode);
+}
+
+#ifdef CONFIG_DMA_ENGINE
+int dmaengine_desc_attach_metadata(struct dma_async_tx_descriptor *desc,
+ void *data, size_t len);
+void *dmaengine_desc_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
+ size_t *payload_len, size_t *max_len);
+int dmaengine_desc_set_metadata_len(struct dma_async_tx_descriptor *desc,
+ size_t payload_len);
+#else /* CONFIG_DMA_ENGINE */
+static inline int dmaengine_desc_attach_metadata(
+ struct dma_async_tx_descriptor *desc, void *data, size_t len)
+{
+ return -EINVAL;
+}
+static inline void *dmaengine_desc_get_metadata_ptr(
+ struct dma_async_tx_descriptor *desc, size_t *payload_len,
+ size_t *max_len)
+{
+ return NULL;
+}
+static inline int dmaengine_desc_set_metadata_len(
+ struct dma_async_tx_descriptor *desc, size_t payload_len)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_DMA_ENGINE */
+
/**
* dmaengine_terminate_all() - Terminate all active DMA transfers
* @chan: The channel for which to terminate the transfers
^ permalink raw reply related
* [v3,1/2] dmaengine: doc: Add sections for per descriptor metadata support
From: Peter Ujfalusi @ 2018-09-12 6:45 UTC (permalink / raw)
To: dan.j.williams, vkoul; +Cc: dmaengine, linux-kernel, lars, radheys
Update the provider and client documentation with details about the
metadata support.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
Documentation/driver-api/dmaengine/client.rst | 75 +++++++++++++++++++
.../driver-api/dmaengine/provider.rst | 46 ++++++++++++
2 files changed, 121 insertions(+)
diff --git a/Documentation/driver-api/dmaengine/client.rst b/Documentation/driver-api/dmaengine/client.rst
index fbbb2831f29f..0276ddae7ea2 100644
--- a/Documentation/driver-api/dmaengine/client.rst
+++ b/Documentation/driver-api/dmaengine/client.rst
@@ -151,6 +151,81 @@ The details of these operations are:
Note that callbacks will always be invoked from the DMA
engines tasklet, never from interrupt context.
+ Optional: per descriptor metadata
+ ---------------------------------
+ DMAengine provides two ways for metadata support.
+
+ DESC_METADATA_CLIENT
+
+ The metadata buffer is allocated/provided by the client driver and it is
+ attached to the descriptor.
+
+ .. code-block:: c
+
+ int dmaengine_desc_attach_metadata(struct dma_async_tx_descriptor *desc,
+ void *data, size_t len);
+
+ DESC_METADATA_ENGINE
+
+ The metadata buffer is allocated/managed by the DMA driver. The client
+ driver can ask for the pointer, maximum size and the currently used size of
+ the metadata and can directly update or read it.
+
+ .. code-block:: c
+
+ void *dmaengine_desc_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
+ size_t *payload_len, size_t *max_len);
+
+ int dmaengine_desc_set_metadata_len(struct dma_async_tx_descriptor *desc,
+ size_t payload_len);
+
+ Client drivers can query if a given mode is supported with:
+
+ .. code-block:: c
+
+ bool dmaengine_is_metadata_mode_supported(struct dma_chan *chan,
+ enum dma_desc_metadata_mode mode);
+
+ Depending on the used mode client drivers must follow different flow.
+
+ DESC_METADATA_CLIENT
+
+ - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
+ 1. prepare the descriptor (dmaengine_prep_*)
+ construct the metadata in the client's buffer
+ 2. use dmaengine_desc_attach_metadata() to attach the buffer to the
+ descriptor
+ 3. submit the transfer
+ - DMA_DEV_TO_MEM:
+ 1. prepare the descriptor (dmaengine_prep_*)
+ 2. use dmaengine_desc_attach_metadata() to attach the buffer to the
+ descriptor
+ 3. submit the transfer
+ 4. when the transfer is completed, the metadata should be available in the
+ attached buffer
+
+ DESC_METADATA_ENGINE
+
+ - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
+ 1. prepare the descriptor (dmaengine_prep_*)
+ 2. use dmaengine_desc_get_metadata_ptr() to get the pointer to the
+ engine's metadata area
+ 3. update the metadata at the pointer
+ 4. use dmaengine_desc_set_metadata_len() to tell the DMA engine the
+ amount of data the client has placed into the metadata buffer
+ 5. submit the transfer
+ - DMA_DEV_TO_MEM:
+ 1. prepare the descriptor (dmaengine_prep_*)
+ 2. submit the transfer
+ 3. on transfer completion, use dmaengine_desc_get_metadata_ptr() to get the
+ pointer to the engine's metadata are
+ 4. Read out the metadate from the pointer
+
+ .. note::
+
+ Mixed use of DESC_METADATA_CLIENT / DESC_METADATA_ENGINE is not allowed,
+ client drivers must use either of the modes per descriptor.
+
4. Submit the transaction
Once the descriptor has been prepared and the callback information
diff --git a/Documentation/driver-api/dmaengine/provider.rst b/Documentation/driver-api/dmaengine/provider.rst
index dfc4486b5743..9e6d87b3c477 100644
--- a/Documentation/driver-api/dmaengine/provider.rst
+++ b/Documentation/driver-api/dmaengine/provider.rst
@@ -247,6 +247,52 @@ after each transfer. In case of a ring buffer, they may loop
(DMA_CYCLIC). Addresses pointing to a device's register (e.g. a FIFO)
are typically fixed.
+Per descriptor metadata support
+-------------------------------
+Some data movement architecure (DMA controller and peripherals) uses metadata
+associated with a transaction. The DMA controller role is to transfer the
+payload and the metadata alongside.
+The metadata itself is not used by the DMA engine itself, but it contains
+parameters, keys, vectors, etc for peripheral or from the peripheral.
+
+The DMAengine framework provides a generic ways to facilitate the metadata for
+descriptors. Depending on the architecture the DMA driver can implement either
+or both of the methods and it is up to the client driver to choose which one
+to use.
+
+- DESC_METADATA_CLIENT
+
+ The metadata buffer is allocated/provided by the client driver and it is
+ attached (via the dmaengine_desc_attach_metadata() helper to the descriptor.
+
+ From the DMA driver the following is expected for this mode:
+ - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM
+ The data from the provided metadata buffer should be prepared for the DMA
+ controller to be sent alongside of the payload data. Either by copying to a
+ hardware descriptor, or highly coupled packet.
+ - DMA_DEV_TO_MEM
+ On transfer completion the DMA driver must copy the metadata to the client
+ provided metadata buffer.
+
+- DESC_METADATA_ENGINE
+
+ The metadata buffer is allocated/managed by the DMA driver. The client driver
+ can ask for the pointer, maximum size and the currently used size of the
+ metadata and can directly update or read it. dmaengine_desc_get_metadata_ptr()
+ and dmaengine_desc_set_metadata_len() is provided as helper functions.
+
+ From the DMA driver the following is expected for this mode:
+ - get_metadata_ptr
+ Should return a pointer for the metadata buffer, the maximum size of the
+ metadata buffer and the currently used / valid (if any) bytes in the buffer.
+ - set_metadata_len
+ It is called by the clients after it have placed the metadata to the buffer
+ to let the DMA driver know the number of valid bytes provided.
+
+ Note: since the client will ask for the metadata pointer in the completion
+ callback (in DMA_DEV_TO_MEM case) the DMA driver must ensure that the
+ descriptor is not freed up prior the callback is called.
+
Device operations
-----------------
^ permalink raw reply related
* [v2,2/2] dmaengine: uniphier-mdmac: add UniPhier MIO DMAC driver
From: Masahiro Yamada @ 2018-09-12 5:25 UTC (permalink / raw)
To: Vinod
Cc: open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, DTML, Rob Herring,
Linux Kernel Mailing List, Masami Hiramatsu, Jassi Brar,
Dan Williams, linux-arm-kernel
2018-09-12 13:35 GMT+09:00 Vinod <vkoul@kernel.org>:
> On 12-09-18, 12:01, Masahiro Yamada wrote:
>> Hi Vinod,
>>
>>
>> 2018-09-11 16:00 GMT+09:00 Vinod <vkoul@kernel.org>:
>> > On 24-08-18, 10:41, Masahiro Yamada wrote:
>> >
>> >> +/* mc->vc.lock must be held by caller */
>> >> +static u32 __uniphier_mdmac_get_residue(struct uniphier_mdmac_desc *md)
>> >> +{
>> >> + u32 residue = 0;
>> >> + int i;
>> >> +
>> >> + for (i = md->sg_cur; i < md->sg_len; i++)
>> >> + residue += sg_dma_len(&md->sgl[i]);
>> >
>> > so if the descriptor is submitted to hardware, we return the descriptor
>> > length, which is not correct.
>> >
>> > Two cases are required to be handled:
>> > 1. Descriptor is in queue (IMO above logic is fine for that, but it can
>> > be calculated at descriptor submit and looked up here)
>>
>> Where do you want it to be calculated?
>
> where is it calculated now?
Please see __uniphier_mdmac_handle().
It gets the address and size by sg_dma_address(), sg_dma_len()
just before setting them to the hardware registers.
sg = &md->sgl[md->sg_cur];
if (md->dir == DMA_MEM_TO_DEV) {
src_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_INC;
src_addr = sg_dma_address(sg);
dest_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_FIXED;
dest_addr = 0;
} else {
src_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_FIXED;
src_addr = 0;
dest_mode = UNIPHIER_MDMAC_CH_MODE__ADDR_INC;
dest_addr = sg_dma_address(sg);
}
>> This hardware provides only simple registers (address and size)
>> for one-shot transfer instead of descriptors.
>>
>> So, I used sgl as-is because I did not see a good reason
>> to transform sgl to another data structure.
>
>
>> > this seems missing stuff. Where do you do register calculation for the
>> > descriptor and where is slave_config here, how do you know where to
>> > send/receive data form/to (peripheral)
>>
>>
>> This dmac is really simple, and un-flexible.
>>
>> The peripheral address to send/receive data from/to is hard-weird.
>> cfg->{src_addr,dst_addr} is not configurable.
>>
>> Look at __uniphier_mdmac_handle().
>> 'dest_addr' and 'src_addr' must be set to 0 for the peripheral.
>
> Fair enough, what about other values like addr_width and maxburst?
None of them is configurable.
^ permalink raw reply
* [v2,2/2] dmaengine: uniphier-mdmac: add UniPhier MIO DMAC driver
From: Vinod Koul @ 2018-09-12 4:35 UTC (permalink / raw)
To: Masahiro Yamada
Cc: open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, DTML, Rob Herring,
Linux Kernel Mailing List, Masami Hiramatsu, Jassi Brar,
Dan Williams, linux-arm-kernel
On 12-09-18, 12:01, Masahiro Yamada wrote:
> Hi Vinod,
>
>
> 2018-09-11 16:00 GMT+09:00 Vinod <vkoul@kernel.org>:
> > On 24-08-18, 10:41, Masahiro Yamada wrote:
> >
> >> +/* mc->vc.lock must be held by caller */
> >> +static u32 __uniphier_mdmac_get_residue(struct uniphier_mdmac_desc *md)
> >> +{
> >> + u32 residue = 0;
> >> + int i;
> >> +
> >> + for (i = md->sg_cur; i < md->sg_len; i++)
> >> + residue += sg_dma_len(&md->sgl[i]);
> >
> > so if the descriptor is submitted to hardware, we return the descriptor
> > length, which is not correct.
> >
> > Two cases are required to be handled:
> > 1. Descriptor is in queue (IMO above logic is fine for that, but it can
> > be calculated at descriptor submit and looked up here)
>
> Where do you want it to be calculated?
where is it calculated now?
> This hardware provides only simple registers (address and size)
> for one-shot transfer instead of descriptors.
>
> So, I used sgl as-is because I did not see a good reason
> to transform sgl to another data structure.
> > this seems missing stuff. Where do you do register calculation for the
> > descriptor and where is slave_config here, how do you know where to
> > send/receive data form/to (peripheral)
>
>
> This dmac is really simple, and un-flexible.
>
> The peripheral address to send/receive data from/to is hard-weird.
> cfg->{src_addr,dst_addr} is not configurable.
>
> Look at __uniphier_mdmac_handle().
> 'dest_addr' and 'src_addr' must be set to 0 for the peripheral.
Fair enough, what about other values like addr_width and maxburst?
^ permalink raw reply
* [v2,2/2] dmaengine: uniphier-mdmac: add UniPhier MIO DMAC driver
From: Masahiro Yamada @ 2018-09-12 3:01 UTC (permalink / raw)
To: Vinod
Cc: open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, DTML, Rob Herring,
Linux Kernel Mailing List, Masami Hiramatsu, Jassi Brar,
Dan Williams, linux-arm-kernel
Hi Vinod,
2018-09-11 16:00 GMT+09:00 Vinod <vkoul@kernel.org>:
> On 24-08-18, 10:41, Masahiro Yamada wrote:
>
>> +/* mc->vc.lock must be held by caller */
>> +static u32 __uniphier_mdmac_get_residue(struct uniphier_mdmac_desc *md)
>> +{
>> + u32 residue = 0;
>> + int i;
>> +
>> + for (i = md->sg_cur; i < md->sg_len; i++)
>> + residue += sg_dma_len(&md->sgl[i]);
>
> so if the descriptor is submitted to hardware, we return the descriptor
> length, which is not correct.
>
> Two cases are required to be handled:
> 1. Descriptor is in queue (IMO above logic is fine for that, but it can
> be calculated at descriptor submit and looked up here)
Where do you want it to be calculated?
This hardware provides only simple registers (address and size)
for one-shot transfer instead of descriptors.
So, I used sgl as-is because I did not see a good reason
to transform sgl to another data structure.
> 2. Descriptor is running (interesting case), you need to read current
> register and offset that from descriptor length and return
OK, I will read out the register value
to retrieve the residue from the on-flight transfer.
>> +static struct dma_async_tx_descriptor *uniphier_mdmac_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 virt_dma_chan *vc = to_virt_chan(chan);
>> + struct uniphier_mdmac_desc *md;
>> +
>> + if (!is_slave_direction(direction))
>> + return NULL;
>> +
>> + md = kzalloc(sizeof(*md), GFP_KERNEL);
>
> _prep calls can be invoked from atomic context, so this should be
> GFP_NOWAIT, see Documentation/driver-api/dmaengine/provider.rst
Will fix.
>> + if (!md)
>> + return NULL;
>> +
>> + md->sgl = sgl;
>> + md->sg_len = sg_len;
>> + md->dir = direction;
>> +
>> + return vchan_tx_prep(vc, &md->vd, flags);
>
> this seems missing stuff. Where do you do register calculation for the
> descriptor and where is slave_config here, how do you know where to
> send/receive data form/to (peripheral)
This dmac is really simple, and un-flexible.
The peripheral address to send/receive data from/to is hard-weird.
cfg->{src_addr,dst_addr} is not configurable.
Look at __uniphier_mdmac_handle().
'dest_addr' and 'src_addr' must be set to 0 for the peripheral.
>> +static enum dma_status uniphier_mdmac_tx_status(struct dma_chan *chan,
>> + dma_cookie_t cookie,
>> + struct dma_tx_state *txstate)
>> +{
>> + struct virt_dma_chan *vc;
>> + struct virt_dma_desc *vd;
>> + struct uniphier_mdmac_chan *mc;
>> + struct uniphier_mdmac_desc *md = NULL;
>> + enum dma_status stat;
>> + unsigned long flags;
>> +
>> + stat = dma_cookie_status(chan, cookie, txstate);
>> + if (stat == DMA_COMPLETE)
>> + return stat;
>> +
>> + vc = to_virt_chan(chan);
>> +
>> + spin_lock_irqsave(&vc->lock, flags);
>> +
>> + mc = to_uniphier_mdmac_chan(vc);
>> +
>> + if (mc->md && mc->md->vd.tx.cookie == cookie)
>> + md = mc->md;
>> +
>> + if (!md) {
>> + vd = vchan_find_desc(vc, cookie);
>> + if (vd)
>> + md = to_uniphier_mdmac_desc(vd);
>> + }
>> +
>> + if (md)
>> + txstate->residue = __uniphier_mdmac_get_residue(md);
>
> txstate can be NULL and should be checked...
Will fix.
>> +static int uniphier_mdmac_probe(struct platform_device *pdev)
>> +{
>> + struct device *dev = &pdev->dev;
>> + struct uniphier_mdmac_device *mdev;
>> + struct dma_device *ddev;
>> + struct resource *res;
>> + int nr_chans, ret, i;
>> +
>> + nr_chans = platform_irq_count(pdev);
>> + if (nr_chans < 0)
>> + return nr_chans;
>> +
>> + ret = dma_set_mask(dev, DMA_BIT_MASK(32));
>> + if (ret)
>> + return ret;
>> +
>> + mdev = devm_kzalloc(dev, struct_size(mdev, channels, nr_chans),
>> + GFP_KERNEL);
>
> kcalloc variant?
No.
I allocate here
sizeof(*mdev) + nr_chans * sizeof(struct uniphier_mdmac_chan)
kcalloc does not cater to it.
You should check struct_size() helper macro.
>> + if (!mdev)
>> + return -ENOMEM;
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + mdev->reg_base = devm_ioremap_resource(dev, res);
>> + if (IS_ERR(mdev->reg_base))
>> + return PTR_ERR(mdev->reg_base);
>> +
>> + mdev->clk = devm_clk_get(dev, NULL);
>> + if (IS_ERR(mdev->clk)) {
>> + dev_err(dev, "failed to get clock\n");
>> + return PTR_ERR(mdev->clk);
>> + }
>> +
>> + ret = clk_prepare_enable(mdev->clk);
>> + if (ret)
>> + return ret;
>> +
>> + ddev = &mdev->ddev;
>> + ddev->dev = dev;
>> + dma_cap_set(DMA_PRIVATE, ddev->cap_mask);
>> + ddev->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED);
>> + ddev->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED);
>> + ddev->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
>> + ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
>> + ddev->device_prep_slave_sg = uniphier_mdmac_prep_slave_sg;
>> + ddev->device_terminate_all = uniphier_mdmac_terminate_all;
>> + ddev->device_synchronize = uniphier_mdmac_synchronize;
>> + ddev->device_tx_status = uniphier_mdmac_tx_status;
>> + ddev->device_issue_pending = uniphier_mdmac_issue_pending;
>
> No device_config?
As I mentioned above, this hardware has no room for configuration.
Nothing in struct dma_slave_config except 'direction' is configurable
for this hardware.
The 'direction' is deprecated.
If an empty device_config hook is OK,
I will add it.
^ permalink raw reply
* dmaengine: xilinx_dma: Fix __aligned attribute on zynqmp_dma_desc_ll
From: Nathan Chancellor @ 2018-09-11 23:48 UTC (permalink / raw)
To: Nick Desaulniers; +Cc: dan.j.williams, vkoul, appana.durga.rao, dmaengine, LKML
On Tue, Sep 11, 2018 at 04:37:48PM -0700, Nick Desaulniers wrote:
> On Tue, Sep 11, 2018 at 4:06 PM Nathan Chancellor
> <natechancellor@gmail.com> wrote:
> >
> > Clang warns:
> >
> > drivers/dma/xilinx/zynqmp_dma.c:166:4: warning: attribute 'aligned' is
> > ignored, place it after "struct" to apply attribute to type declaration
> > [-Wignored-attributes]
> > }; __aligned(64)
> > ^
> > ./include/linux/compiler_types.h:200:38: note: expanded from macro
> > '__aligned'
> > #define __aligned(x) __attribute__((aligned(x)))
> > ^
> > 1 warning generated.
> >
> > Place __aligned before the semicolon.
> >
> > Fixes: b0cc417c1637 ("dmaengine: Add Xilinx zynqmp dma engine driver support")
> > Reported-by: Nick Desaulniers <ndesaulniers@google.com>
> > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> > ---
> > drivers/dma/xilinx/zynqmp_dma.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
> > index c74a88b65039..dc19d67cb8c1 100644
> > --- a/drivers/dma/xilinx/zynqmp_dma.c
> > +++ b/drivers/dma/xilinx/zynqmp_dma.c
> > @@ -163,7 +163,7 @@ struct zynqmp_dma_desc_ll {
> > u32 ctrl;
> > u64 nxtdscraddr;
> > u64 rsvd;
> > -}; __aligned(64)
> > +} __aligned(64);
>
> Thanks for this patch Nathan. Thinking more about this...the integer
> passed to __attribute__((aligned(x))) should be in terms of bytes. 64
> bytes seems kind of high. Maybe they meant 64 *bits* thus 8 *bytes*
> which already the default alignment of the struct:
> https://godbolt.org/z/7vW6E3
>
> In which case, the correct fix is to remove the `__aligned(64);`
> outright. Since that doesn't change anything (thanks to clang's
> helpful -Wignored-attributes), such a patch would be "No Functional
> Change" (does not change the status quo). Still, it might be good for
> the maintainer to remark if 64 *byte* alignment was intentional (I
> would think not, but I don't have the datasheet for this piece of
> hardware in front of me; never say never) before sending such a patch.
>
> If the 64 *byte* (512 bit) alignment was intentional (again, which I
> doubt), then this patch is good to go, but that would then be a
> functional change and should be tested by someone with hardware.
>
Thanks for the review Nick. If that is indeed the case, I will spin up a v2.
>
> >
> > /**
> > * struct zynqmp_dma_desc_sw - Per Transaction structure
> > --
> > 2.18.0
> >
>
>
> --
> Thanks,
> ~Nick Desaulniers
^ permalink raw reply
* dmaengine: timb_dma: Use proper enum in td_prep_slave_sg
From: Nick Desaulniers @ 2018-09-11 23:44 UTC (permalink / raw)
To: Nathan Chancellor; +Cc: dan.j.williams, vkoul, dmaengine, LKML
On Tue, Sep 11, 2018 at 4:20 PM Nathan Chancellor
<natechancellor@gmail.com> wrote:
>
> Clang warns when implicitly converting from one enumerated type to
> another. Avoid this by using the equivalent value from the expected
> type.
>
> drivers/dma/timb_dma.c:548:27: warning: implicit conversion from
> enumeration type 'enum dma_transfer_direction' to different enumeration
> type 'enum dma_data_direction' [-Wenum-conversion]
> td_desc->desc_list_len, DMA_MEM_TO_DEV);
> ^~~~~~~~~~~~~~
> 1 warning generated.
>
> Reported-by: Nick Desaulniers <ndesaulniers@google.com>
> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> ---
> drivers/dma/timb_dma.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
> index 395c698edb4d..fc0f9c8766a8 100644
> --- a/drivers/dma/timb_dma.c
> +++ b/drivers/dma/timb_dma.c
> @@ -545,7 +545,7 @@ static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan,
> }
>
> dma_sync_single_for_device(chan2dmadev(chan), td_desc->txd.phys,
> - td_desc->desc_list_len, DMA_MEM_TO_DEV);
> + td_desc->desc_list_len, DMA_TO_DEVICE);
Looks like DMA_MEM_TO_DEV and DMA_TO_DEVICE happen to have the same
value (today) so no functional change.
And dma_sync_single_for_device is defined to take the `enum
dma_data_direction` which `DMA_TO_DEVICE` is an enumeration of.
Thanks for the patch Nathan.
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
>
> return &td_desc->txd;
> }
> --
> 2.18.0
>
^ permalink raw reply
* dmaengine: ep93xx: Return proper enum in ep93xx_dma_chan_direction
From: Nathan Chancellor @ 2018-09-11 23:40 UTC (permalink / raw)
To: Dan Williams, Vinod Koul
Cc: dmaengine, linux-kernel, Nick Desaulniers, Nathan Chancellor
Clang warns when implicitly converting from one enumerated type to
another. Avoid this by using the equivalent value from the expected
type.
In file included from drivers/dma/ep93xx_dma.c:30:
./include/linux/platform_data/dma-ep93xx.h:88:10: warning: implicit
conversion from enumeration type 'enum dma_data_direction' to different
enumeration type 'enum dma_transfer_direction' [-Wenum-conversion]
return DMA_NONE;
~~~~~~ ^~~~~~~~
1 warning generated.
Reported-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
---
include/linux/platform_data/dma-ep93xx.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/platform_data/dma-ep93xx.h b/include/linux/platform_data/dma-ep93xx.h
index f8f1f6b952a6..eb9805bb3fe8 100644
--- a/include/linux/platform_data/dma-ep93xx.h
+++ b/include/linux/platform_data/dma-ep93xx.h
@@ -85,7 +85,7 @@ static inline enum dma_transfer_direction
ep93xx_dma_chan_direction(struct dma_chan *chan)
{
if (!ep93xx_dma_chan_is_m2p(chan))
- return DMA_NONE;
+ return DMA_TRANS_NONE;
/* even channels are for TX, odd for RX */
return (chan->chan_id % 2 == 0) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
^ permalink raw reply related
* dmaengine: xilinx_dma: Fix __aligned attribute on zynqmp_dma_desc_ll
From: Nick Desaulniers @ 2018-09-11 23:37 UTC (permalink / raw)
To: Nathan Chancellor
Cc: dan.j.williams, vkoul, appana.durga.rao, dmaengine, LKML
On Tue, Sep 11, 2018 at 4:06 PM Nathan Chancellor
<natechancellor@gmail.com> wrote:
>
> Clang warns:
>
> drivers/dma/xilinx/zynqmp_dma.c:166:4: warning: attribute 'aligned' is
> ignored, place it after "struct" to apply attribute to type declaration
> [-Wignored-attributes]
> }; __aligned(64)
> ^
> ./include/linux/compiler_types.h:200:38: note: expanded from macro
> '__aligned'
> #define __aligned(x) __attribute__((aligned(x)))
> ^
> 1 warning generated.
>
> Place __aligned before the semicolon.
>
> Fixes: b0cc417c1637 ("dmaengine: Add Xilinx zynqmp dma engine driver support")
> Reported-by: Nick Desaulniers <ndesaulniers@google.com>
> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> ---
> drivers/dma/xilinx/zynqmp_dma.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
> index c74a88b65039..dc19d67cb8c1 100644
> --- a/drivers/dma/xilinx/zynqmp_dma.c
> +++ b/drivers/dma/xilinx/zynqmp_dma.c
> @@ -163,7 +163,7 @@ struct zynqmp_dma_desc_ll {
> u32 ctrl;
> u64 nxtdscraddr;
> u64 rsvd;
> -}; __aligned(64)
> +} __aligned(64);
Thanks for this patch Nathan. Thinking more about this...the integer
passed to __attribute__((aligned(x))) should be in terms of bytes. 64
bytes seems kind of high. Maybe they meant 64 *bits* thus 8 *bytes*
which already the default alignment of the struct:
https://godbolt.org/z/7vW6E3
In which case, the correct fix is to remove the `__aligned(64);`
outright. Since that doesn't change anything (thanks to clang's
helpful -Wignored-attributes), such a patch would be "No Functional
Change" (does not change the status quo). Still, it might be good for
the maintainer to remark if 64 *byte* alignment was intentional (I
would think not, but I don't have the datasheet for this piece of
hardware in front of me; never say never) before sending such a patch.
If the 64 *byte* (512 bit) alignment was intentional (again, which I
doubt), then this patch is good to go, but that would then be a
functional change and should be tested by someone with hardware.
>
> /**
> * struct zynqmp_dma_desc_sw - Per Transaction structure
> --
> 2.18.0
>
^ permalink raw reply
* dmaengine: timb_dma: Use proper enum in td_prep_slave_sg
From: Nathan Chancellor @ 2018-09-11 23:20 UTC (permalink / raw)
To: Dan Williams, Vinod Koul
Cc: dmaengine, linux-kernel, Nick Desaulniers, Nathan Chancellor
Clang warns when implicitly converting from one enumerated type to
another. Avoid this by using the equivalent value from the expected
type.
drivers/dma/timb_dma.c:548:27: warning: implicit conversion from
enumeration type 'enum dma_transfer_direction' to different enumeration
type 'enum dma_data_direction' [-Wenum-conversion]
td_desc->desc_list_len, DMA_MEM_TO_DEV);
^~~~~~~~~~~~~~
1 warning generated.
Reported-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
---
drivers/dma/timb_dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index 395c698edb4d..fc0f9c8766a8 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -545,7 +545,7 @@ static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan,
}
dma_sync_single_for_device(chan2dmadev(chan), td_desc->txd.phys,
- td_desc->desc_list_len, DMA_MEM_TO_DEV);
+ td_desc->desc_list_len, DMA_TO_DEVICE);
return &td_desc->txd;
}
^ permalink raw reply related
* dmaengine: xilinx_dma: Fix __aligned attribute on zynqmp_dma_desc_ll
From: Nathan Chancellor @ 2018-09-11 23:05 UTC (permalink / raw)
To: Dan Williams, Vinod Koul
Cc: Kedareswara rao Appana, dmaengine, linux-kernel, Nick Desaulniers,
Nathan Chancellor
Clang warns:
drivers/dma/xilinx/zynqmp_dma.c:166:4: warning: attribute 'aligned' is
ignored, place it after "struct" to apply attribute to type declaration
[-Wignored-attributes]
}; __aligned(64)
^
./include/linux/compiler_types.h:200:38: note: expanded from macro
'__aligned'
#define __aligned(x) __attribute__((aligned(x)))
^
1 warning generated.
Place __aligned before the semicolon.
Fixes: b0cc417c1637 ("dmaengine: Add Xilinx zynqmp dma engine driver support")
Reported-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
---
drivers/dma/xilinx/zynqmp_dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
index c74a88b65039..dc19d67cb8c1 100644
--- a/drivers/dma/xilinx/zynqmp_dma.c
+++ b/drivers/dma/xilinx/zynqmp_dma.c
@@ -163,7 +163,7 @@ struct zynqmp_dma_desc_ll {
u32 ctrl;
u64 nxtdscraddr;
u64 rsvd;
-}; __aligned(64)
+} __aligned(64);
/**
* struct zynqmp_dma_desc_sw - Per Transaction structure
^ permalink raw reply related
* [02/12] dmaengine: bcm2835: remove dma_slave_config direction usage
From: Scott Branden @ 2018-09-11 21:11 UTC (permalink / raw)
To: Vinod Koul, dmaengine; +Cc: Ray Jui, Scott Branden
On 18-09-11 01:35 AM, Vinod Koul wrote:
> dma_slave_config direction was marked as deprecated quite some
> time back, remove the usage from this driver so that the field
> can be removed
>
> Signed-off-by: Vinod Koul <vkoul@kernel.org>
Acked-by: Scott Branden <scott.branden@broadcom.com>
> ---
> CC: Ray Jui <rjui@broadcom.com>
> CC: Scott Branden <sbranden@broadcom.com>
>
> drivers/dma/bcm2835-dma.c | 8 --------
> 1 file changed, 8 deletions(-)
>
> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> index 847f84a41a69..cad55ab80d41 100644
> --- a/drivers/dma/bcm2835-dma.c
> +++ b/drivers/dma/bcm2835-dma.c
> @@ -778,14 +778,6 @@ static int bcm2835_dma_slave_config(struct dma_chan *chan,
> {
> struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
>
> - if ((cfg->direction == DMA_DEV_TO_MEM &&
> - cfg->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
> - (cfg->direction == DMA_MEM_TO_DEV &&
> - cfg->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
> - !is_slave_direction(cfg->direction)) {
> - return -EINVAL;
> - }
> -
> c->cfg = *cfg;
>
> return 0;
^ permalink raw reply
* dmaengine: zx-dma: replace spin_lock_irqsave with spin_lock in ISR
From: Lucas Stach @ 2018-09-11 15:17 UTC (permalink / raw)
To: jun qian, Dan Williams, Vinod Koul, Jun Nie, Baoyou Xie,
Shawn Guo
Cc: dmaengine, Barry song, linux-kernel, linux-arm-kernel
Am Dienstag, den 11.09.2018, 07:31 -0700 schrieb jun qian:
> As you are already in ISR, it is unnecessary to call
> spin_lock_irqsave.
As the IRQ in this driver isn't marked with IRQF_NO_THREAD, this is
going to blow up if the kernel is booted with the "threadirqs" command
line argument.
Regards,
Lucas
> Signed-off-by: jun qian <hangdianqj@163.com>
> Cc: Barry song <21cnbao@gmail.com>
> ---
> drivers/dma/zx_dma.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/dma/zx_dma.c b/drivers/dma/zx_dma.c
> index 2571bc7693df..111ab2db83b1 100644
> --- a/drivers/dma/zx_dma.c
> +++ b/drivers/dma/zx_dma.c
> @@ -288,9 +288,8 @@ static irqreturn_t zx_dma_int_handler(int irq,
> void *dev_id)
> p = &d->phy[i];
> c = p->vchan;
> if (c) {
> - unsigned long flags;
>
> - spin_lock_irqsave(&c->vc.lock, flags);
> + spin_lock(&c->vc.lock);
> if (c->cyclic) {
> vchan_cyclic_callback(&p->ds_run-
> >vd);
> } else {
> @@ -298,7 +297,7 @@ static irqreturn_t zx_dma_int_handler(int irq,
> void *dev_id)
> p->ds_done = p->ds_run;
> task = 1;
> }
> - spin_unlock_irqrestore(&c->vc.lock, flags);
> + spin_unlock(&c->vc.lock);
> irq_chan |= BIT(i);
> }
> }
^ permalink raw reply
* dmaengine: idma64: replace spin_lock_irqsave with spin_lock in ISR
From: jun qian @ 2018-09-11 14:37 UTC (permalink / raw)
To: Dan Williams, Vinod Koul; +Cc: dmaengine, linux-kernel, jun qian, Barry song
As you are already in ISR, it is unnecessary to call spin_lock_irqsave.
Signed-off-by: jun qian <hangdianqj@163.com>
Cc: Barry song <21cnbao@gmail.com>
---
drivers/dma/idma64.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
index 1fbf9cb9b742..5b9c1566ad73 100644
--- a/drivers/dma/idma64.c
+++ b/drivers/dma/idma64.c
@@ -142,9 +142,8 @@ static void idma64_chan_irq(struct idma64 *idma64, unsigned short c,
{
struct idma64_chan *idma64c = &idma64->chan[c];
struct idma64_desc *desc;
- unsigned long flags;
- spin_lock_irqsave(&idma64c->vchan.lock, flags);
+ spin_lock(&idma64c->vchan.lock);
desc = idma64c->desc;
if (desc) {
if (status_err & (1 << c)) {
@@ -161,7 +160,7 @@ static void idma64_chan_irq(struct idma64 *idma64, unsigned short c,
if (idma64c->desc == NULL || desc->status == DMA_ERROR)
idma64_stop_transfer(idma64c);
}
- spin_unlock_irqrestore(&idma64c->vchan.lock, flags);
+ spin_unlock(&idma64c->vchan.lock);
}
static irqreturn_t idma64_irq(int irq, void *dev)
^ permalink raw reply related
* dmaengine: zx-dma: replace spin_lock_irqsave with spin_lock in ISR
From: jun qian @ 2018-09-11 14:31 UTC (permalink / raw)
To: Dan Williams, Vinod Koul, Jun Nie, Baoyou Xie, Shawn Guo
Cc: linux-arm-kernel, dmaengine, linux-kernel, jun qian, Barry song
As you are already in ISR, it is unnecessary to call spin_lock_irqsave.
Signed-off-by: jun qian <hangdianqj@163.com>
Cc: Barry song <21cnbao@gmail.com>
---
drivers/dma/zx_dma.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/zx_dma.c b/drivers/dma/zx_dma.c
index 2571bc7693df..111ab2db83b1 100644
--- a/drivers/dma/zx_dma.c
+++ b/drivers/dma/zx_dma.c
@@ -288,9 +288,8 @@ static irqreturn_t zx_dma_int_handler(int irq, void *dev_id)
p = &d->phy[i];
c = p->vchan;
if (c) {
- unsigned long flags;
- spin_lock_irqsave(&c->vc.lock, flags);
+ spin_lock(&c->vc.lock);
if (c->cyclic) {
vchan_cyclic_callback(&p->ds_run->vd);
} else {
@@ -298,7 +297,7 @@ static irqreturn_t zx_dma_int_handler(int irq, void *dev_id)
p->ds_done = p->ds_run;
task = 1;
}
- spin_unlock_irqrestore(&c->vc.lock, flags);
+ spin_unlock(&c->vc.lock);
irq_chan |= BIT(i);
}
}
^ permalink raw reply related
* dmaengine: k3dma: replace spin_lock_irqsave with spin_lock in ISR
From: jun qian @ 2018-09-11 14:25 UTC (permalink / raw)
To: Dan Williams, Vinod Koul; +Cc: dmaengine, linux-kernel, jun qian, Barry song
As you are already in ISR, it is unnecessary to call spin_lock_irqsave.
Signed-off-by: jun qian <hangdianqj@163.com>
Cc: Barry song <21cnbao@gmail.com>
---
drivers/dma/k3dma.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c
index 6bfa217ed6d0..30052258ffd5 100644
--- a/drivers/dma/k3dma.c
+++ b/drivers/dma/k3dma.c
@@ -216,22 +216,21 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id)
i = __ffs(stat);
stat &= ~BIT(i);
if (likely(tc1 & BIT(i)) || (tc2 & BIT(i))) {
- unsigned long flags;
p = &d->phy[i];
c = p->vchan;
if (c && (tc1 & BIT(i))) {
- spin_lock_irqsave(&c->vc.lock, flags);
+ spin_lock(&c->vc.lock);
vchan_cookie_complete(&p->ds_run->vd);
p->ds_done = p->ds_run;
p->ds_run = NULL;
- spin_unlock_irqrestore(&c->vc.lock, flags);
+ spin_unlock(&c->vc.lock);
}
if (c && (tc2 & BIT(i))) {
- spin_lock_irqsave(&c->vc.lock, flags);
+ spin_lock(&c->vc.lock);
if (p->ds_run != NULL)
vchan_cyclic_callback(&p->ds_run->vd);
- spin_unlock_irqrestore(&c->vc.lock, flags);
+ spin_unlock(&c->vc.lock);
}
irq_chan |= BIT(i);
}
^ permalink raw reply related
* dmaengine: moxart-dma: replace spin_lock_irqsave with spin_lock in ISR
From: jun qian @ 2018-09-11 14:17 UTC (permalink / raw)
To: Dan Williams, Vinod Koul; +Cc: dmaengine, linux-kernel, jun qian, Barry song
As you are already in ISR, it is unnecessary to call spin_lock_irqsave.
Signed-off-by: jun qian <hangdianqj@163.com>
Cc: Barry song <21cnbao@gmail.com>
---
drivers/dma/moxart-dma.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c
index e04499c1f27f..77958f123226 100644
--- a/drivers/dma/moxart-dma.c
+++ b/drivers/dma/moxart-dma.c
@@ -524,7 +524,6 @@ static irqreturn_t moxart_dma_interrupt(int irq, void *devid)
struct moxart_dmadev *mc = devid;
struct moxart_chan *ch = &mc->slave_chans[0];
unsigned int i;
- unsigned long flags;
u32 ctrl;
dev_dbg(chan2dev(&ch->vc.chan), "%s\n", __func__);
@@ -541,14 +540,14 @@ static irqreturn_t moxart_dma_interrupt(int irq, void *devid)
if (ctrl & APB_DMA_FIN_INT_STS) {
ctrl &= ~APB_DMA_FIN_INT_STS;
if (ch->desc) {
- spin_lock_irqsave(&ch->vc.lock, flags);
+ spin_lock(&ch->vc.lock);
if (++ch->sgidx < ch->desc->sglen) {
moxart_dma_start_sg(ch, ch->sgidx);
} else {
vchan_cookie_complete(&ch->desc->vd);
moxart_dma_start_desc(&ch->vc.chan);
}
- spin_unlock_irqrestore(&ch->vc.lock, flags);
+ spin_unlock(&ch->vc.lock);
}
}
^ permalink raw reply related
* [v2,1/2] dmaengine: Add metadata_ops for dma_async_tx_descriptor
From: Peter Ujfalusi @ 2018-09-11 12:33 UTC (permalink / raw)
To: Vinod; +Cc: dan.j.williams, dmaengine, linux-kernel, lars, radheys
Vinod,
On 2018-09-11 10:33, Vinod wrote:
>> +int dmaengine_desc_attach_metadata(struct dma_async_tx_descriptor *desc,
>> + void *data, size_t len)
>> +{
>> + int ret;
>> +
>> + if (!desc)
>> + return -EINVAL;
>> +
>> + ret = desc_check_and_set_metadata_mode(desc, DESC_METADATA_CLIENT);
>> + if (ret)
>> + return ret;
>> +
>> + if (!desc->metadata_ops || !desc->metadata_ops->attach)
>> + return -ENOTSUPP;
>> +
>> + return desc->metadata_ops->attach(desc, data, len);
>> +}
>> +EXPORT_SYMBOL(dmaengine_desc_attach_metadata);
>
> EXPORT_SYMBOL_GPL ?
Sure, I think I have looked at
dma_async_tx_descriptor_init/dmaengine_get_unmap_data/dma_issue_pending_all/etc
they have EXPORT_SYMBOL()
- Péter
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
^ permalink raw reply
* [1/3] arm64: dts: actions: s900: Enable Tx DMA for UART5
From: kbuild test robot @ 2018-09-11 12:03 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: kbuild-all, vkoul, dan.j.williams, afaerber, robh+dt, gregkh,
jslaby, linux-serial, dmaengine, liuwei, 96boards, devicetree,
daniel.thompson, amit.kucheria, linux-arm-kernel, linux-kernel,
hzhang, bdong, manivannanece23, thomas.liau, jeff.chen, pn,
edgar.righi
Hi Manivannan,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on tty/tty-testing]
[also build test ERROR on v4.19-rc3 next-20180910]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Manivannan-Sadhasivam/Add-slave-DMA-support-for-Actios-Semi-S900-SoC/20180903-163744
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
config: arm64-allmodconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.2.0 make.cross ARCH=arm64
All errors (new ones prefixed by >>):
>> ERROR: Input tree has errors, aborting (use -f to force output)
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply
* [3/3] dmaengine: xilinx_dma: Fix 64-bit simple CDMA transfer
From: Radhey Shyam Pandey @ 2018-09-11 9:31 UTC (permalink / raw)
To: Vinod
Cc: dan.j.williams@intel.com, Michal Simek,
Appana Durga Kedareswara Rao, lars@metafoo.de,
dmaengine@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
> > > > Yeah that part was clear but the implementation can be better..
> > I thought over it and it seems having a new interface dma_ctrl_write_64
> > taking lsb and msb bits input looks better and scalable. It will be similar
> > to existing vdma_desc_write_64 impl. I will send v2 if it looks ok.
>
> Yes that is much better, btw why not reuse same routine as common xilinx
> lib functions :)
Thanks. vdma_desc_write_64 uses a different offset i.e desc_offset.
For reusing it we need to have an additional check to derive offset
(ctrl_offset/desc_offset) based on channel config type. Considering
it, i think a separate helper interface _64 for desc/control offset
simplifies the flow. Please let me know your thoughts on it.
-Radhey
>
> --
> ~Vinod
^ permalink raw reply
* [12/12] dmaengine: mmp_tdma: remove dma_slave_config direction usage
From: Vinod Koul @ 2018-09-11 8:35 UTC (permalink / raw)
To: dmaengine; +Cc: Vinod Koul
dma_slave_config direction was marked as deprecated quite some
time back, remove the usage from this driver so that the field
can be removed
Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
drivers/dma/mmp_tdma.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c
index 13c68b6434ce..c14f8820a567 100644
--- a/drivers/dma/mmp_tdma.c
+++ b/drivers/dma/mmp_tdma.c
@@ -116,6 +116,7 @@ struct mmp_tdma_chan {
u32 burst_sz;
enum dma_slave_buswidth buswidth;
enum dma_status status;
+ struct dma_slave_config slave_config;
int idx;
enum mmp_tdma_type type;
@@ -139,6 +140,10 @@ struct mmp_tdma_device {
#define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan)
+static int mmp_tdma_config_write(struct dma_chan *chan,
+ enum dma_transfer_direction dir,
+ struct dma_slave_config *dmaengine_cfg);
+
static void mmp_tdma_chan_set_desc(struct mmp_tdma_chan *tdmac, dma_addr_t phys)
{
writel(phys, tdmac->reg_base + TDNDPR);
@@ -442,6 +447,8 @@ static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic(
if (!desc)
goto err_out;
+ mmp_tdma_config_write(chan, direction, &tdmac->slave_config);
+
while (buf < buf_len) {
desc = &tdmac->desc_arr[i];
@@ -495,7 +502,18 @@ static int mmp_tdma_config(struct dma_chan *chan,
{
struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
- if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
+ memcpy(&tdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg));
+
+ return 0;
+}
+
+static int mmp_tdma_config_write(struct dma_chan *chan,
+ enum dma_transfer_direction dir,
+ struct dma_slave_config *dmaengine_cfg)
+{
+ struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
+
+ if (dir == DMA_DEV_TO_MEM) {
tdmac->dev_addr = dmaengine_cfg->src_addr;
tdmac->burst_sz = dmaengine_cfg->src_maxburst;
tdmac->buswidth = dmaengine_cfg->src_addr_width;
@@ -504,7 +522,7 @@ static int mmp_tdma_config(struct dma_chan *chan,
tdmac->burst_sz = dmaengine_cfg->dst_maxburst;
tdmac->buswidth = dmaengine_cfg->dst_addr_width;
}
- tdmac->dir = dmaengine_cfg->direction;
+ tdmac->dir = dir;
return mmp_tdma_config_chan(chan);
}
^ permalink raw reply related
* [11/12] dmaengine: ep93xx_dma: remove dma_slave_config direction usage
From: Vinod Koul @ 2018-09-11 8:35 UTC (permalink / raw)
To: dmaengine; +Cc: Vinod Koul
dma_slave_config direction was marked as deprecated quite some
time back, remove the usage from this driver so that the field
can be removed
Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
drivers/dma/ep93xx_dma.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index a15592383d4e..f674eb5fbbef 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -109,6 +109,9 @@
#define DMA_MAX_CHAN_DESCRIPTORS 32
struct ep93xx_dma_engine;
+static int ep93xx_dma_slave_config_write(struct dma_chan *chan,
+ enum dma_transfer_direction dir,
+ struct dma_slave_config *config);
/**
* struct ep93xx_dma_desc - EP93xx specific transaction descriptor
@@ -180,6 +183,7 @@ struct ep93xx_dma_chan {
struct list_head free_list;
u32 runtime_addr;
u32 runtime_ctrl;
+ struct dma_slave_config slave_config;
};
/**
@@ -1051,6 +1055,8 @@ ep93xx_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
return NULL;
}
+ ep93xx_dma_slave_config_write(chan, dir, &edmac->slave_config);
+
first = NULL;
for_each_sg(sgl, sg, sg_len, i) {
size_t len = sg_dma_len(sg);
@@ -1136,6 +1142,8 @@ ep93xx_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr,
return NULL;
}
+ ep93xx_dma_slave_config_write(chan, dir, &edmac->slave_config);
+
/* Split the buffer into period size chunks */
first = NULL;
for (offset = 0; offset < buf_len; offset += period_len) {
@@ -1227,6 +1235,17 @@ static int ep93xx_dma_slave_config(struct dma_chan *chan,
struct dma_slave_config *config)
{
struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
+
+ memcpy(&edmac->slave_config, config, sizeof(*config));
+
+ return 0;
+}
+
+static int ep93xx_dma_slave_config_write(struct dma_chan *chan,
+ enum dma_transfer_direction dir,
+ struct dma_slave_config *config)
+{
+ struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
enum dma_slave_buswidth width;
unsigned long flags;
u32 addr, ctrl;
@@ -1234,7 +1253,7 @@ static int ep93xx_dma_slave_config(struct dma_chan *chan,
if (!edmac->edma->m2m)
return -EINVAL;
- switch (config->direction) {
+ switch (dir) {
case DMA_DEV_TO_MEM:
width = config->src_addr_width;
addr = config->src_addr;
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox