From ec722b002b7ab3db1b0538793abcb9daccd1f6b4 Mon Sep 17 00:00:00 2001 From: YuriNenakhov Date: Fri, 1 May 2015 15:26:51 -0600 Subject: [PATCH] DMA support initial --- src/drivers/elphel/Kconfig | 26 +++--- src/drivers/elphel/Makefile | 12 +-- src/drivers/elphel/elphel393-mem.c | 135 +++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 15 deletions(-) create mode 100644 src/drivers/elphel/elphel393-mem.c diff --git a/src/drivers/elphel/Kconfig b/src/drivers/elphel/Kconfig index efb8717..5a8da1f 100644 --- a/src/drivers/elphel/Kconfig +++ b/src/drivers/elphel/Kconfig @@ -1,12 +1,18 @@ -# -# Elphel devices -# - +# +# Elphel devices +# + menu "Elphel devices" config ELPHEL393 - tristate "Support Elphel 10393 board voltage regulator" -# add more -# depends on I2C && SYSFS - help - Say Y here if you have a Elphel board 10393. -endmenu + tristate "Support Elphel 10393 board voltage regulator, DMA memory allocator" +# add more +# depends on I2C && SYSFS + help + Say Y here if you have a Elphel board 10393. + +config ELPHELDRVONMICROZED + tristate "Provide only Elphel features which are compatible with Microzed" + help + Say Y here if you debug Elpel camera code on Microzed board. + +endmenu diff --git a/src/drivers/elphel/Makefile b/src/drivers/elphel/Makefile index 0189ae5..7609f17 100644 --- a/src/drivers/elphel/Makefile +++ b/src/drivers/elphel/Makefile @@ -1,5 +1,7 @@ -# -# Makefile for Elphel specific devices. -# - -obj-$(CONFIG_ELPHEL393) += elphel393-pwr.o +# +# Makefile for Elphel specific devices. +# + +obj-$(CONFIG_ELPHEL393) += elphel393-pwr.o +obj-$(CONFIG_ELPHEL393) += elphel393-mem.o +obj-$(CONFIG_ELPHELDRVONMICROZED) += elphel393-mem.o diff --git a/src/drivers/elphel/elphel393-mem.c b/src/drivers/elphel/elphel393-mem.c new file mode 100644 index 0000000..b4ec7b9 --- /dev/null +++ b/src/drivers/elphel/elphel393-mem.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SYSFS_PERMISSIONS 0644 /* default permissions for sysfs files */ +#define SYSFS_READONLY 0444 + + +static ssize_t get_paddr(struct device *dev, struct device_attribute *attr, char *buf); + +struct elphel_buf_t +{ + void *vaddr; + dma_addr_t paddr; + ssize_t size; +}; + +static struct elphel_buf_t elphel_buf = { + .vaddr = NULL, + .paddr = 0, + .size = 0 +}; + +static int __init elphelmem_init(void) +{ + struct device_node *node; + const __be32 *bufsize_be; + + printk("======== Allocating memory buffer ========\n"); + + node = of_find_node_by_name(NULL, "elphel393-mem"); + if (!node) + { + printk("ERROR: No node found\n"); + return -ENODEV; + } + + bufsize_be = (__be32 *)of_get_property(node, "memsize", NULL); + elphel_buf.size = be32_to_cpup(bufsize_be); + + elphel_buf.vaddr = dma_alloc_coherent(NULL,(elphel_buf.size*PAGE_SIZE),&(elphel_buf.paddr),GFP_KERNEL); + + if(elphel_buf.paddr) + { + printk("Allocated %u pages at address %x\n", (u32)elphel_buf.size, (u32)elphel_buf.paddr); + } + else printk("ERROR allocating memory buffer"); + + return 0; +} + +static void __exit elphelmem_exit(void) +{ + printk("Goodbye Cruel World!\n"); +} + + + +// SYSFS + +static ssize_t get_paddr(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf,"%x\n", (u32)elphel_buf.paddr); +} + +static ssize_t get_size(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf,"%u\n", elphel_buf.size); +} +static DEVICE_ATTR(buffer_address, SYSFS_PERMISSIONS & SYSFS_READONLY, get_paddr, NULL); +static DEVICE_ATTR(buffer_pages, SYSFS_PERMISSIONS & SYSFS_READONLY, get_size, NULL); + +static struct attribute *root_dev_attrs[] = { + &dev_attr_buffer_address.attr, + &dev_attr_buffer_pages.attr, + NULL +}; + +static const struct attribute_group dev_attr_root_group = { + .attrs = root_dev_attrs, + .name = NULL, +}; + +static int elphel393_mem_sysfs_register(struct platform_device *pdev) +{ + int retval=0; + struct device *dev = &pdev->dev; + if (&dev->kobj) { + if (((retval = sysfs_create_group(&dev->kobj, &dev_attr_root_group)))<0) return retval; + } + return retval; +} + +static int elphel393_mem_probe(struct platform_device *pdev) +{ + elphel393_mem_sysfs_register(pdev); + dev_info(&pdev->dev,"Probing elphel393-mem\n"); + return 0; +} + +static int elphel393_mem_remove(struct platform_device *pdev) +{ + dev_info(&pdev->dev,"Removing elphel393-mem"); + return 0; +} + +static struct of_device_id elphel393_mem_of_match[] = { + { .compatible = "elphel,elphel393-mem-1.00", }, + { /* end of table */} +}; +MODULE_DEVICE_TABLE(of, elphel393_pwr_of_match); + +static struct platform_driver elphel393_mem = { + .probe = elphel393_mem_probe, + .remove = elphel393_mem_remove, + .driver = { + .name = "elphel393-mem", + .owner = THIS_MODULE, + .of_match_table = elphel393_mem_of_match, + .pm = NULL, /* power management */ + }, +}; + +module_platform_driver(elphel393_mem); +module_init(elphelmem_init); +module_exit(elphelmem_exit); +MODULE_LICENSE("GPL"); + + -- 2.18.1