From f067025bc676ba8d18fba5f959598339e39b86db Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Wed, 20 Jul 2016 13:13:50 -0700 Subject: dmaengine: add support to provide error result from a DMA transation Adding a new callback that will provide the error result for a transaction. The result is allocated on the stack and the callback should create a copy if it wishes to retain the information after exiting. The result parameter is now defined and takes over the dummy void pointer we placed in the helper functions previously. dmaengine drivers should start converting to the new "callback_result" callback in order to receive transaction results. Signed-off-by: Dave Jiang Reviewed-by: Lars-Peter Clausen Signed-off-by: Vinod Koul --- include/linux/dmaengine.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 30de0197263a..cc535a478bae 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -441,6 +441,21 @@ typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param); typedef void (*dma_async_tx_callback)(void *dma_async_param); +enum dmaengine_tx_result { + DMA_TRANS_NOERROR = 0, /* SUCCESS */ + DMA_TRANS_READ_FAILED, /* Source DMA read failed */ + DMA_TRANS_WRITE_FAILED, /* Destination DMA write failed */ + DMA_TRANS_ABORTED, /* Op never submitted / aborted */ +}; + +struct dmaengine_result { + enum dmaengine_tx_result result; + u32 residue; +}; + +typedef void (*dma_async_tx_callback_result)(void *dma_async_param, + const struct dmaengine_result *result); + struct dmaengine_unmap_data { u8 map_cnt; u8 to_cnt; @@ -478,6 +493,7 @@ struct dma_async_tx_descriptor { dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx); int (*desc_free)(struct dma_async_tx_descriptor *tx); dma_async_tx_callback callback; + dma_async_tx_callback_result callback_result; void *callback_param; struct dmaengine_unmap_data *unmap; #ifdef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH -- cgit v1.2.3 From 434cec62a6d73b8c8080cd992bc97a564fdd5a5a Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 15 Sep 2016 07:37:30 +0200 Subject: bus: mvebu-mbus: Provide stub function for mvebu_mbus_get_io_win_info() This patch provides a stub function for mvebu_mbus_get_io_win_info(), which will be used for all non-Orion (ARM32 MVEBU) platforms for compile test coverage. On such platforms this function will return an error so that drivers might detect a potential problem. Signed-off-by: Stefan Roese Acked-by: Gregory CLEMENT Cc: Thomas Petazzoni Cc: Marcin Wojtas Cc: Arnd Bergmann Cc: Andrew Lunn Cc: Vinod Koul Signed-off-by: Vinod Koul --- include/linux/mbus.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mbus.h b/include/linux/mbus.h index d610232762e3..2931aa43dab1 100644 --- a/include/linux/mbus.h +++ b/include/linux/mbus.h @@ -11,6 +11,8 @@ #ifndef __LINUX_MBUS_H #define __LINUX_MBUS_H +#include + struct resource; struct mbus_dram_target_info @@ -55,6 +57,8 @@ struct mbus_dram_target_info #ifdef CONFIG_PLAT_ORION extern const struct mbus_dram_target_info *mv_mbus_dram_info(void); extern const struct mbus_dram_target_info *mv_mbus_dram_info_nooverlap(void); +int mvebu_mbus_get_io_win_info(phys_addr_t phyaddr, u32 *size, u8 *target, + u8 *attr); #else static inline const struct mbus_dram_target_info *mv_mbus_dram_info(void) { @@ -64,14 +68,24 @@ static inline const struct mbus_dram_target_info *mv_mbus_dram_info_nooverlap(vo { return NULL; } +static inline int mvebu_mbus_get_io_win_info(phys_addr_t phyaddr, u32 *size, + u8 *target, u8 *attr) +{ + /* + * On all ARM32 MVEBU platforms with MBus support, this stub + * function will not get called. The real function from the + * MBus driver is called instead. ARM64 MVEBU platforms like + * the Armada 3700 could use the mv_xor device driver which calls + * into this function + */ + return -EINVAL; +} #endif int mvebu_mbus_save_cpu_target(u32 __iomem *store_addr); void mvebu_mbus_get_pcie_mem_aperture(struct resource *res); void mvebu_mbus_get_pcie_io_aperture(struct resource *res); int mvebu_mbus_get_dram_win_info(phys_addr_t phyaddr, u8 *target, u8 *attr); -int mvebu_mbus_get_io_win_info(phys_addr_t phyaddr, u32 *size, u8 *target, - u8 *attr); int mvebu_mbus_add_window_remap_by_id(unsigned int target, unsigned int attribute, phys_addr_t base, size_t size, -- cgit v1.2.3 From 71d0bc65ba089e8e769cddad66dae8cb4c49a0d4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 23 Aug 2016 16:09:40 +0300 Subject: dmaengine: hsu: refactor hsu_dma_do_irq() to return int Since we have nice macro IRQ_RETVAL() we would use it to convert a flag of handled interrupt from int to irqreturn_t. The rationale of doing this is: a) hence we implicitly mark hsu_dma_do_irq() as an auxiliary function that can't be used as interrupt handler directly, and b) to be in align with serial driver which is using serial8250_handle_irq() that returns plain int by design. Signed-off-by: Andy Shevchenko Acked-by: Greg Kroah-Hartman Signed-off-by: Vinod Koul --- include/linux/dma/hsu.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dma/hsu.h b/include/linux/dma/hsu.h index aaff68efba5d..197eec63e501 100644 --- a/include/linux/dma/hsu.h +++ b/include/linux/dma/hsu.h @@ -41,8 +41,7 @@ struct hsu_dma_chip { /* Export to the internal users */ int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr, u32 *status); -irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr, - u32 status); +int hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr, u32 status); /* Export to the platform drivers */ int hsu_dma_probe(struct hsu_dma_chip *chip); @@ -53,10 +52,10 @@ static inline int hsu_dma_get_status(struct hsu_dma_chip *chip, { return 0; } -static inline irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, - unsigned short nr, u32 status) +static inline int hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr, + u32 status) { - return IRQ_NONE; + return 0; } static inline int hsu_dma_probe(struct hsu_dma_chip *chip) { return -ENODEV; } static inline int hsu_dma_remove(struct hsu_dma_chip *chip) { return 0; } -- cgit v1.2.3 From ba409b31b3d37b52dda4eefcde04f5837c7ee4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Wed, 10 Aug 2016 13:22:14 +0200 Subject: dma-mapping: add {map,unmap}_resource to dma_map_ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add methods to handle mapping of device resources from a physical address. This is needed for example to be able to map MMIO FIFO registers to a IOMMU. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Acked-by: Arnd Bergmann Signed-off-by: Vinod Koul --- include/linux/dma-mapping.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 66533e18276c..673b7be85f7a 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -95,6 +95,12 @@ struct dma_map_ops { struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs); + dma_addr_t (*map_resource)(struct device *dev, phys_addr_t phys_addr, + size_t size, enum dma_data_direction dir, + unsigned long attrs); + void (*unmap_resource)(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir, + unsigned long attrs); void (*sync_single_for_cpu)(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir); -- cgit v1.2.3 From 0e74b34dfc3318bf4c7e51349d453d49fb8e9e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Wed, 10 Aug 2016 13:22:15 +0200 Subject: dma-debug: add support for resource mappings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A MMIO mapped resource can not be represented by a struct page so a new debug type is needed to handle this. This patch add such type and functionality to add/remove entries and how to translate them to a physical address. Signed-off-by: Niklas Söderlund Acked-by: Arnd Bergmann Signed-off-by: Vinod Koul --- include/linux/dma-debug.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h index fe8cb610deac..c7d844f09c3a 100644 --- a/include/linux/dma-debug.h +++ b/include/linux/dma-debug.h @@ -56,6 +56,13 @@ extern void debug_dma_alloc_coherent(struct device *dev, size_t size, extern void debug_dma_free_coherent(struct device *dev, size_t size, void *virt, dma_addr_t addr); +extern void debug_dma_map_resource(struct device *dev, phys_addr_t addr, + size_t size, int direction, + dma_addr_t dma_addr); + +extern void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, + size_t size, int direction); + extern void debug_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, int direction); @@ -141,6 +148,18 @@ static inline void debug_dma_free_coherent(struct device *dev, size_t size, { } +static inline void debug_dma_map_resource(struct device *dev, phys_addr_t addr, + size_t size, int direction, + dma_addr_t dma_addr) +{ +} + +static inline void debug_dma_unmap_resource(struct device *dev, + dma_addr_t dma_addr, size_t size, + int direction) +{ +} + static inline void debug_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, int direction) -- cgit v1.2.3 From 6f3d87968f9c8b529bc81eff5a1f45e92553493d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Wed, 10 Aug 2016 13:22:16 +0200 Subject: dma-mapping: add dma_{map,unmap}_resource MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Map/Unmap a device MMIO resource from a physical address. If no dma_map_ops method is available the operation is a no-op. Signed-off-by: Niklas Söderlund Acked-by: Arnd Bergmann Signed-off-by: Vinod Koul --- include/linux/dma-mapping.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 673b7be85f7a..6e00c7fdbbd3 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -264,6 +264,42 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, debug_dma_unmap_page(dev, addr, size, dir, false); } +static inline dma_addr_t dma_map_resource(struct device *dev, + phys_addr_t phys_addr, + size_t size, + enum dma_data_direction dir, + unsigned long attrs) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + unsigned long pfn = __phys_to_pfn(phys_addr); + dma_addr_t addr; + + BUG_ON(!valid_dma_direction(dir)); + + /* Don't allow RAM to be mapped */ + BUG_ON(pfn_valid(pfn)); + + addr = phys_addr; + if (ops->map_resource) + addr = ops->map_resource(dev, phys_addr, size, dir, attrs); + + debug_dma_map_resource(dev, phys_addr, size, dir, addr); + + return addr; +} + +static inline void dma_unmap_resource(struct device *dev, dma_addr_t addr, + size_t size, enum dma_data_direction dir, + unsigned long attrs) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + + BUG_ON(!valid_dma_direction(dir)); + if (ops->unmap_resource) + ops->unmap_resource(dev, addr, size, dir, attrs); + debug_dma_unmap_resource(dev, addr, size, dir); +} + static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) -- cgit v1.2.3 From 93d05f1ec644c97535159649de7f8e6731841336 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 2 Sep 2016 15:57:09 +0530 Subject: dmaengine: mmp_tdma: enable COMPILE_TEST To get more coverage, enable COMPILE_TEST for this driver. While at it, to fix build on other archs, select MMP_SRAM only for ARCH_MMP and also fix the platform header Suggested-by: Arnd Bergmann Acked-by: Zhangfei Gao Signed-off-by: Vinod Koul --- include/linux/platform_data/dma-mmp_tdma.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/platform_data/dma-mmp_tdma.h b/include/linux/platform_data/dma-mmp_tdma.h index 0c72886030ef..422d4504dbac 100644 --- a/include/linux/platform_data/dma-mmp_tdma.h +++ b/include/linux/platform_data/dma-mmp_tdma.h @@ -28,7 +28,7 @@ struct sram_platdata { int granularity; }; -#ifdef CONFIG_ARM +#ifdef CONFIG_MMP_SRAM extern struct gen_pool *sram_get_gpool(char *pool_name); #else static inline struct gen_pool *sram_get_gpool(char *pool_name) -- cgit v1.2.3 From 34681d84a0f7cc22ded1413dc79eef8a2f23d9c3 Mon Sep 17 00:00:00 2001 From: Sam Van Den Berge Date: Thu, 22 Sep 2016 20:51:15 +0200 Subject: dmaengine: s3c24xx: Add dma_slave_map for s3c2440 devices This patch updates the s3c24xx dma driver to be able to pass a dma_slave_map array via the platform data. This is needed to be able to use the new, simpler dmaengine API [1]. I used the virtual DMA channels as a parameter for the dma_filter function. By doing that, I could reuse the existing filter function in drivers/dma/s3c24xx-dma.c. I have tested this on my mini2440 board with the audio driver. According to my observations, dma_request_slave_channel in the function dmaengine_pcm_new in the file sound/soc/soc-generic-dmaengine-pcm.c now returns a valid DMA channel whereas before no DMA channel was returned at that point. Entries for DMACH_XD0, DMACH_XD1 and DMACH_TIMER are missing because I don't realy know which driver to use for these. [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-December/393635.html Signed-off-by: Sam Van Den Berge Reviewed-by: Sylwester Nawrocki Acked-by: Arnd Bergmann Acked-by: Krzysztof Kozlowski Signed-off-by: Vinod Koul --- include/linux/platform_data/dma-s3c24xx.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/platform_data/dma-s3c24xx.h b/include/linux/platform_data/dma-s3c24xx.h index 89ba1b0c90e4..4f9aba405e96 100644 --- a/include/linux/platform_data/dma-s3c24xx.h +++ b/include/linux/platform_data/dma-s3c24xx.h @@ -30,16 +30,22 @@ struct s3c24xx_dma_channel { u16 chansel; }; +struct dma_slave_map; + /** * struct s3c24xx_dma_platdata - platform specific settings * @num_phy_channels: number of physical channels * @channels: array of virtual channel descriptions * @num_channels: number of virtual channels + * @slave_map: dma slave map matching table + * @slavecnt: number of elements in slave_map */ struct s3c24xx_dma_platdata { int num_phy_channels; struct s3c24xx_dma_channel *channels; int num_channels; + const struct dma_slave_map *slave_map; + int slavecnt; }; struct dma_chan; -- cgit v1.2.3 From a8db115e476ee31fc3e892522038da50dd3a66cc Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 21 Sep 2016 15:41:30 +0300 Subject: dmaengine/ARM: omap-dma: Fix the DMAengine compile test on non OMAP configs The DMAengine driver for omap-dma use three function calls from the plat-omap legacy driver. When the DMAengine driver is built when ARCH_OMAP is not set, the compilation will fail due to missing symbols. Add empty inline functions to allow the DMAengine driver to be compiled with COMPILE_TEST. Signed-off-by: Peter Ujfalusi Signed-off-by: Vinod Koul --- include/linux/omap-dma.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h index 1d99b61adc65..290081620b3e 100644 --- a/include/linux/omap-dma.h +++ b/include/linux/omap-dma.h @@ -297,6 +297,7 @@ struct omap_system_dma_plat_info { #define dma_omap15xx() __dma_omap15xx(d) #define dma_omap16xx() __dma_omap16xx(d) +#if defined(CONFIG_ARCH_OMAP) extern struct omap_system_dma_plat_info *omap_get_plat_info(void); extern void omap_set_dma_priority(int lch, int dst_port, int priority); @@ -355,4 +356,22 @@ static inline int omap_lcd_dma_running(void) } #endif +#else /* CONFIG_ARCH_OMAP */ + +static inline struct omap_system_dma_plat_info *omap_get_plat_info(void) +{ + return NULL; +} + +static inline int omap_request_dma(int dev_id, const char *dev_name, + void (*callback)(int lch, u16 ch_status, void *data), + void *data, int *dma_ch) +{ + return -ENODEV; +} + +static inline void omap_free_dma(int ch) { } + +#endif /* CONFIG_ARCH_OMAP */ + #endif /* __LINUX_OMAP_DMA_H */ -- cgit v1.2.3 From 2895e1f8048d1be7b1b5be6439c740621c0e5361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Thu, 29 Sep 2016 12:02:39 +0200 Subject: dma-mapping: fix ia64 build, use PHYS_PFN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kbuild test robot reports: In file included from include/linux/skbuff.h:34:0, from include/linux/tcp.h:21, from drivers/net/ethernet/amd/xgbe/xgbe-drv.c:119: include/linux/dma-mapping.h: In function 'dma_map_resource': >> include/linux/dma-mapping.h:274:22: error: implicit declaration of function '__phys_to_pfn' [-Werror=implicit-function-declaration] unsigned long pfn = __phys_to_pfn(phys_addr); ^~~~~~~~~~~~~ ia64 does not provide __phys_to_pfn(), use the PHYS_PFN() alias. Signed-off-by: Niklas Söderlund Signed-off-by: Vinod Koul --- include/linux/dma-mapping.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 6e00c7fdbbd3..ff7c87fb0305 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -271,7 +271,7 @@ static inline dma_addr_t dma_map_resource(struct device *dev, unsigned long attrs) { struct dma_map_ops *ops = get_dma_ops(dev); - unsigned long pfn = __phys_to_pfn(phys_addr); + unsigned long pfn = PHYS_PFN(phys_addr); dma_addr_t addr; BUG_ON(!valid_dma_direction(dir)); -- cgit v1.2.3 From 3757dc48a66f829cf6ba82a612ba4587ab4b5f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Thu, 29 Sep 2016 12:02:40 +0200 Subject: dma-mapping: fix m32r build warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kbuild test robot reports: In file included from include/linux/skbuff.h:34:0, from include/linux/icmpv6.h:4, from include/linux/ipv6.h:75, from include/net/ipv6.h:16, from include/linux/sunrpc/clnt.h:27, from include/linux/nfs_fs.h:30, from fs/lockd/clntlock.c:13: include/linux/dma-mapping.h: In function 'dma_map_resource': >> include/linux/dma-mapping.h:274:16: warning: unused variable 'pfn' [-Wunused-variable] unsigned long pfn = __phys_to_pfn(phys_addr); ^~~ The pfn value is only used once in the call to pfn_valid(), remove the variable and calculate the pfn when it's needed. Note that the kbuild report is old and PHYS_PFN() is now used instead of __phys_to_pfn() to calculate the pfn. Signed-off-by: Niklas Söderlund Signed-off-by: Vinod Koul --- include/linux/dma-mapping.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index ff7c87fb0305..642cb4c7ad37 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -271,13 +271,12 @@ static inline dma_addr_t dma_map_resource(struct device *dev, unsigned long attrs) { struct dma_map_ops *ops = get_dma_ops(dev); - unsigned long pfn = PHYS_PFN(phys_addr); dma_addr_t addr; BUG_ON(!valid_dma_direction(dir)); /* Don't allow RAM to be mapped */ - BUG_ON(pfn_valid(pfn)); + BUG_ON(pfn_valid(PHYS_PFN(phys_addr))); addr = phys_addr; if (ops->map_resource) -- cgit v1.2.3