Re: [PATCH v13] ARM: edma: Add DT and runtime PM support to the private EDMA API
On 6/21/2013 3:23 PM, Sekhar Nori wrote: From: Matt Porter mpor...@ti.com Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Enables build on OMAP. Changes by Joel: * Setup default one-to-one mapping for queue_priority and queue_tc mapping as discussed in [1]. * Split out xbar stuff to separate patch. [1] * Dropped unused DT helper to convert to array [1] https://patchwork.kernel.org/patch/2226761/ Signed-off-by: Matt Porter mpor...@ti.com [nsek...@ti.com: fix checkpatch errors, build breakages. Introduce edma_setup_info_from_dt() as part of that effort] Signed-off-by: Joel A Fernandes joelag...@ti.com Acked-by: Arnd Bergmann a...@arndb.de Signed-off-by: Sekhar Nori nsek...@ti.com So here is an updated version of this patch after merging your fix sent over the weekend . I tested the on AM335x, DA850 and DM644x boards using MMC/SD as the DMA client. With that I think this has gotten enough testing now and I plan to send a pull request for this later today and hope we make it in time. Thanks, Sekhar ---8--- From 6cba4355066bda19f14d4da66b8abbca0ffdfd59 Mon Sep 17 00:00:00 2001 From: Matt Porter mpor...@ti.com Date: Thu, 20 Jun 2013 16:06:38 -0500 Subject: [PATCH 3/4] ARM: edma: Add DT and runtime PM support to the private EDMA API Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Enables build on OMAP. Changes by Joel: * Setup default one-to-one mapping for queue_priority and queue_tc mapping as discussed in [1]. * Split out xbar stuff to separate patch. [1] * Dropped unused DT helper to convert to array * Fixed dangling pointer issue with Sekhar's changes [1] https://patchwork.kernel.org/patch/2226761/ Signed-off-by: Matt Porter mpor...@ti.com [nsek...@ti.com: fix checkpatch errors, build breakages. Introduce edma_setup_info_from_dt() as part of that effort] Signed-off-by: Joel A Fernandes joelag...@ti.com Acked-by: Arnd Bergmann a...@arndb.de Signed-off-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c| 186 +++-- arch/arm/mach-davinci/devices-da8xx.c |8 +- arch/arm/mach-davinci/devices-tnetv107x.c |4 +- arch/arm/mach-davinci/dm355.c |4 +- arch/arm/mach-davinci/dm365.c |4 +- arch/arm/mach-davinci/dm644x.c|4 +- arch/arm/mach-davinci/dm646x.c|4 +- include/linux/platform_data/edma.h|4 +- 8 files changed, 189 insertions(+), 29 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 7658874..5183a31 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -25,6 +25,13 @@ #include linux/platform_device.h #include linux/io.h #include linux/slab.h +#include linux/edma.h +#include linux/err.h +#include linux/of_address.h +#include linux/of_device.h +#include linux/of_dma.h +#include linux/of_irq.h +#include linux/pm_runtime.h #include linux/platform_data/edma.h @@ -1369,13 +1376,110 @@ void edma_clear_event(unsigned channel) } EXPORT_SYMBOL(edma_clear_event); -/*---*/ +#if IS_ENABLED(CONFIG_OF) IS_ENABLED(CONFIG_DMADEVICES) + +static int edma_of_parse_dt(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata) +{ + int ret = 0, i; + u32 value; + struct edma_rsv_info *rsv_info; + s8 (*queue_tc_map)[2], (*queue_priority_map)[2]; + + memset(pdata, 0, sizeof(struct edma_soc_info)); + + ret = of_property_read_u32(node, dma-channels, value); + if (ret 0) + return ret; + pdata-n_channel = value; + + ret = of_property_read_u32(node, ti,edma-regions, value); + if (ret 0) + return ret; + pdata-n_region = value; + + ret = of_property_read_u32(node, ti,edma-slots, value); + if (ret 0) + return ret; + pdata-n_slot = value; + + pdata-n_cc = 1; + + rsv_info = devm_kzalloc(dev, sizeof(struct edma_rsv_info), GFP_KERNEL); + if (!rsv_info) + return -ENOMEM; + pdata-rsv = rsv_info; + + queue_tc_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL); + if (!queue_tc_map) + return -ENOMEM; + + for (i = 0; i 3; i++) { + queue_tc_map[i][0] = i; + queue_tc_map[i][1] = i; + } + queue_tc_map[i][0] = -1; + queue_tc_map[i][1] = -1; + + pdata-queue_tc_mapping = queue_tc_map; + + queue_priority_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL); + if (!queue_priority_map) + return -ENOMEM; + + for (i = 0; i 3; i++) { + queue_priority_map[i][0] = i; + queue_priority_map[i][1] = i;
[PATCH v13] ARM: edma: Add DT and runtime PM support to the private EDMA API
From: Matt Porter mpor...@ti.com Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Enables build on OMAP. Changes by Joel: * Setup default one-to-one mapping for queue_priority and queue_tc mapping as discussed in [1]. * Split out xbar stuff to separate patch. [1] * Dropped unused DT helper to convert to array [1] https://patchwork.kernel.org/patch/2226761/ Signed-off-by: Matt Porter mpor...@ti.com [nsek...@ti.com: fix checkpatch errors, build breakages. Introduce edma_setup_info_from_dt() as part of that effort] Signed-off-by: Joel A Fernandes joelag...@ti.com Acked-by: Arnd Bergmann a...@arndb.de Signed-off-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c| 186 +++-- arch/arm/mach-davinci/devices-da8xx.c |8 +- arch/arm/mach-davinci/devices-tnetv107x.c |4 +- arch/arm/mach-davinci/dm355.c |4 +- arch/arm/mach-davinci/dm365.c |4 +- arch/arm/mach-davinci/dm644x.c|4 +- arch/arm/mach-davinci/dm646x.c|4 +- include/linux/platform_data/edma.h|4 +- 8 files changed, 189 insertions(+), 29 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 7658874..b3770ab 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -25,6 +25,13 @@ #include linux/platform_device.h #include linux/io.h #include linux/slab.h +#include linux/edma.h +#include linux/err.h +#include linux/of_address.h +#include linux/of_device.h +#include linux/of_dma.h +#include linux/of_irq.h +#include linux/pm_runtime.h #include linux/platform_data/edma.h @@ -1369,13 +1376,118 @@ void edma_clear_event(unsigned channel) } EXPORT_SYMBOL(edma_clear_event); -/*---*/ +#if IS_ENABLED(CONFIG_OF) IS_ENABLED(CONFIG_DMADEVICES) -static int __init edma_probe(struct platform_device *pdev) +static int edma_of_parse_dt(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata) +{ + int ret = 0, i; + u32 value; + struct edma_rsv_info *rsv_info; + s8 (*queue_tc_map)[2], (*queue_priority_map)[2]; + + memset(pdata, 0, sizeof(struct edma_soc_info)); + + ret = of_property_read_u32(node, dma-channels, value); + if (ret 0) + return ret; + pdata-n_channel = value; + + ret = of_property_read_u32(node, ti,edma-regions, value); + if (ret 0) + return ret; + pdata-n_region = value; + + ret = of_property_read_u32(node, ti,edma-slots, value); + if (ret 0) + return ret; + pdata-n_slot = value; + + pdata-n_cc = 1; + + rsv_info = devm_kzalloc(dev, sizeof(struct edma_rsv_info), GFP_KERNEL); + if (!rsv_info) + return -ENOMEM; + pdata-rsv = rsv_info; + + queue_tc_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL); + if (!queue_tc_map) + return -ENOMEM; + + for (i = 0; i 3; i++) { + queue_tc_map[i][0] = i; + queue_tc_map[i][1] = i; + } + queue_tc_map[i][0] = -1; + queue_tc_map[i][1] = -1; + + pdata-queue_tc_mapping = queue_tc_map; + + queue_priority_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL); + if (!queue_priority_map) + return -ENOMEM; + + for (i = 0; i 3; i++) { + queue_priority_map[i][0] = i; + queue_priority_map[i][1] = i; + } + queue_priority_map[i][0] = -1; + queue_priority_map[i][1] = -1; + + pdata-queue_priority_mapping = queue_priority_map; + + pdata-default_queue = 0; + + return ret; +} + +static struct of_dma_filter_info edma_filter_info = { + .filter_fn = edma_filter_fn, +}; + +static struct edma_soc_info **edma_setup_info_from_dt(struct device *dev, + struct device_node *node) +{ + static struct edma_soc_info **info; + struct edma_soc_info *ninfo; + int ret; + + /* Check if this is a second instance registered */ + if (arch_num_cc) { + dev_err(dev, only one EDMA instance is supported via DT\n); + return ERR_PTR(-ENODEV); + } + + ninfo = devm_kzalloc(dev, sizeof(struct edma_soc_info), GFP_KERNEL); + if (!ninfo) + return ERR_PTR(-ENOMEM); + + ret = edma_of_parse_dt(dev, node, ninfo); + if (ret) + return ERR_PTR(ret); + + dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap); + of_dma_controller_register(dev-of_node, of_dma_simple_xlate, + edma_filter_info); + + info = ninfo; + + return info; +} +#else +static struct edma_soc_info **edma_setup_info_from_dt(struct device