On 02/23/2012 11:03 AM, Cousson, Benoit : > Salut Nico, Coucou Benoit ;-) > On 2/22/2012 11:59 AM, Nicolas Ferre wrote: >> On 01/27/2012 06:29 PM, Cousson, Benoit : >>> Add some basic helpers to retrieve a DMA controller device_node >>> and the DMA request line number. >>> >>> For legacy reason another API will export the DMA request number >>> into a Linux resource of type IORESOURCE_DMA. >>> This API is usable only on system with an unique DMA controller. >> >> Hi, >> >> I followed that discussion and I like very much the biding that Benoit >> is proposing. It will help me a lot with my current work on Atmel DMA >> controller. >> >> If I understand correctly, some rework is needed before it can be >> integrated in a stable git tree (I mean before we can base our work on >> top of it). So, in the meantime, what should I do to help and make >> things go forward? to be quite frank, I would be interested to have a >> working DMA enabled device soon ;-) > > Me too, but unfortunately, I was busy trying to add irq_domain and > fixing issues with SPARSE_IRQ on OMAP :-( Been there, loved that ;-) >> Do you think that 3.4 is out of reach? > > Maybe not, from the comments, it looks like we should add a .xlate > callback to allow any custom parsing of the DMA nodes attributes. > > I'll be more than happy, if you can finalize that patch :-) I will try to figure out what I can understand from the irq mechanism of .xlate and try to see if I can implement it on top of your patch. I will keep you informed... Bye, >> Best regards, >> >>> Signed-off-by: Benoit Cousson<b-cousson@xxxxxx> >>> Cc: Grant Likely<grant.likely@xxxxxxxxxxxx> >>> Cc: Rob Herring<rob.herring@xxxxxxxxxxx> >>> --- >>> Documentation/devicetree/bindings/dma/dma.txt | 44 +++++++++ >>> drivers/of/Kconfig | 5 + >>> drivers/of/Makefile | 1 + >>> drivers/of/dma.c | 130 >>> +++++++++++++++++++++++++ >>> include/linux/of_dma.h | 49 +++++++++ >>> 5 files changed, 229 insertions(+), 0 deletions(-) >>> create mode 100644 Documentation/devicetree/bindings/dma/dma.txt >>> create mode 100644 drivers/of/dma.c >>> create mode 100644 include/linux/of_dma.h >>> >>> diff --git a/Documentation/devicetree/bindings/dma/dma.txt >>> b/Documentation/devicetree/bindings/dma/dma.txt >>> new file mode 100644 >>> index 0000000..7f2a301 >>> --- /dev/null >>> +++ b/Documentation/devicetree/bindings/dma/dma.txt >>> @@ -0,0 +1,44 @@ >>> +* Generic DMA Controller and DMA request bindings >>> + >>> +Generic binding to provide a way for a driver to retrieve the >>> +DMA request line that goes from an IP to a DMA controller. >>> + >>> + >>> +* DMA controller >>> + >>> +Required properties: >>> + - dma-controller: Mark the device as a DMA controller >>> + - #dma-cells: Number of cell for each DMA line, must be one. >>> + >>> + >>> +Example: >>> + >>> + sdma: dma-controller@48000000 { >>> + compatible = "ti,sdma-omap4" >>> + reg =<0x48000000 0x1000>; >>> + interrupts =<12>; >>> + dma-controller; >>> + #dma-cells =<1>; >>> + }; >>> + >>> + >>> + >>> +* DMA client >>> + >>> +Client drivers should specify the DMA request numbers using a >>> phandle to >>> +the controller + the DMA request number on that controller. >>> + >>> +Required properties: >>> + - dma-request: List of pair phandle + dma-request per line >>> + - dma-request-names: list of strings in the same order as the >>> dma-request >>> + in the dma-request property. >>> + >>> + >>> +Example: >>> + >>> + i2c1: i2c@1 { >>> + ... >>> + dma-request =<&sdma 2&sdma 3>; >>> + dma-request-names = "tx", "rx"; >>> + ... >>> + }; >>> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig >>> index 268163d..7d1f06b 100644 >>> --- a/drivers/of/Kconfig >>> +++ b/drivers/of/Kconfig >>> @@ -90,4 +90,9 @@ config OF_PCI_IRQ >>> help >>> OpenFirmware PCI IRQ routing helpers >>> >>> +config OF_DMA >>> + def_bool y >>> + help >>> + Device Tree DMA routing helpers >>> + >>> endmenu # OF >>> diff --git a/drivers/of/Makefile b/drivers/of/Makefile >>> index a73f5a5..d08443b 100644 >>> --- a/drivers/of/Makefile >>> +++ b/drivers/of/Makefile >>> @@ -12,3 +12,4 @@ obj-$(CONFIG_OF_SELFTEST) += selftest.o >>> obj-$(CONFIG_OF_MDIO) += of_mdio.o >>> obj-$(CONFIG_OF_PCI) += of_pci.o >>> obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o >>> +obj-$(CONFIG_OF_DMA) += dma.o >>> diff --git a/drivers/of/dma.c b/drivers/of/dma.c >>> new file mode 100644 >>> index 0000000..d4927e2 >>> --- /dev/null >>> +++ b/drivers/of/dma.c >>> @@ -0,0 +1,130 @@ >>> +/* >>> + * Device tree helpers for DMA request / controller >>> + * >>> + * Based on of_gpio.c >>> + * >>> + * Copyright (C) 2012 Texas Instruments Incorporated - >>> http://www.ti.com/ >>> + * >>> + * This program is free software; you can redistribute it and/or modify >>> + * it under the terms of the GNU General Public License version 2 as >>> + * published by the Free Software Foundation. >>> + */ >>> + >>> +#include<linux/device.h> >>> +#include<linux/err.h> >>> +#include<linux/module.h> >>> +#include<linux/of.h> >>> +#include<linux/of_dma.h> >>> + >>> +/** >>> + * of_get_dma_request() - Get a DMA request number and >>> dma-controller node >>> + * @np: device node to get DMA request from >>> + * @propname: property name containing DMA specifier(s) >>> + * @index: index of the DMA request >>> + * @ctrl_np: a device_node pointer to fill in >>> + * >>> + * Returns DMA number along to the dma controller node, or one of >>> the errno >>> + * value on the error condition. If @ctrl_np is not NULL the >>> function also >>> + * fills in the DMA controller device_node pointer. >>> + */ >>> +int of_get_dma_request(struct device_node *np, int index, >>> + struct device_node **ctrl_np) >>> +{ >>> + int ret = -EINVAL; >>> + struct of_phandle_args dma_spec; >>> + >>> + ret = of_parse_phandle_with_args(np, "dma-request", "#dma-cells", >>> + index,&dma_spec); >>> + if (ret) { >>> + pr_debug("%s: can't parse dma property\n", __func__); >>> + goto err0; >>> + } >>> + >>> + if (dma_spec.args_count> 0) >>> + ret = dma_spec.args[0]; >>> + >>> + if (ctrl_np) >>> + *ctrl_np = dma_spec.np; >>> + else >>> + of_node_put(dma_spec.np); >>> + >>> +err0: >>> + pr_debug("%s exited with status %d\n", __func__, ret); >>> + return ret; >>> +} >>> +EXPORT_SYMBOL(of_get_dma_request); >>> + >>> +/** >>> + * of_dma_count - Count DMA requests for a device >>> + * @np: device node to count DMAs for >>> + * >>> + * The function returns the count of DMA requests specified for a node. >>> + * >>> + * Note that the empty DMA specifiers counts too. For example, >>> + * >>> + * dma-request =<0 >>> + *&sdma 1 >>> + * 0 >>> + *&sdma 3>; >>> + * >>> + * defines four DMAs (so this function will return 4), two of which >>> + * are not specified. >>> + */ >>> +unsigned int of_dma_count(struct device_node *np) >>> +{ >>> + unsigned int cnt = 0; >>> + >>> + do { >>> + int ret; >>> + >>> + ret = of_parse_phandle_with_args(np, "dma-request", >>> + "#dma-cells", cnt, NULL); >>> + /* A hole in the dma-request =<> counts anyway. */ >>> + if (ret< 0&& ret != -EEXIST) >>> + break; >>> + } while (++cnt); >>> + >>> + return cnt; >>> +} >>> +EXPORT_SYMBOL(of_dma_count); >>> + >>> +/** >>> + * of_dma_to_resource - Decode a node's DMA and return it as a resource >>> + * @dev: pointer to device tree node >>> + * @index: zero-based index of the DMA request >>> + * @r: pointer to resource structure to return result into. >>> + * >>> + * Using a resource to export a DMA request number to a driver should >>> + * be used only for legacy purpose and on system when only one DMA >>> controller >>> + * is present. >>> + * The proper and only scalable way is to use the native >>> of_get_dma_request API >>> + * in order retrieve both the DMA controller device node and the DMA >>> request >>> + * line for that controller. >>> + */ >>> +int of_dma_to_resource(struct device_node *dev, int index, struct >>> resource *r) >>> +{ >>> + const char *name = NULL; >>> + int dma; >>> + >>> + if (!r) >>> + return -EINVAL; >>> + >>> + dma = of_get_dma_request(dev, index, NULL); >>> + if (dma< 0) >>> + return dma; >>> + >>> + /* >>> + * Get optional "dma-request-names" property to add a name >>> + * to the resource. >>> + */ >>> + of_property_read_string_index(dev, "dma-request-names", index, >>> + &name); >>> + >>> + r->start = dma; >>> + r->end = dma; >>> + r->flags = IORESOURCE_DMA; >>> + r->name = name ? name : dev->full_name; >>> + >>> + return dma; >>> +} >>> +EXPORT_SYMBOL_GPL(of_dma_to_resource); >>> diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h >>> new file mode 100644 >>> index 0000000..575163d >>> --- /dev/null >>> +++ b/include/linux/of_dma.h >>> @@ -0,0 +1,49 @@ >>> +/* >>> + * OF helpers for DMA request / controller >>> + * >>> + * Based on of_gpio.h >>> + * >>> + * Copyright (C) 2012 Texas Instruments Incorporated - >>> http://www.ti.com/ >>> + * >>> + * This program is free software; you can redistribute it and/or modify >>> + * it under the terms of the GNU General Public License version 2 as >>> + * published by the Free Software Foundation. >>> + */ >>> + >>> +#ifndef __LINUX_OF_DMA_H >>> +#define __LINUX_OF_DMA_H >>> + >>> +#include<linux/of.h> >>> + >>> +struct device_node; >>> + >>> +#ifdef CONFIG_OF_GPIO >>> + >>> +extern int of_get_dma_request(struct device_node *np, int index, >>> + struct device_node **ctrl_np); >>> +extern unsigned int of_dma_count(struct device_node *np); >>> +extern int of_dma_to_resource(struct device_node *dev, int index, >>> + struct resource *r); >>> + >>> +#else /* CONFIG_OF_DMA */ >>> + >>> +static int of_get_dma_request(struct device_node *np, int index, >>> + struct device_node **ctrl_np); >>> +{ >>> + return -ENOSYS; >>> +} >>> + >>> +static inline unsigned int of_dma_count(struct device_node *np) >>> +{ >>> + return 0; >>> +} >>> + >>> +static int of_dma_to_resource(struct device_node *dev, int index, >>> + struct resource *r); >>> +{ >>> + return -ENOSYS; >>> +} >>> + >>> +#endif /* CONFIG_OF_DMA */ >>> + >>> +#endif /* __LINUX_OF_DMA_H */ >> >> > > -- Nicolas Ferre -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html