Re: [PATCH v2] staging: kpc2000: Add DMA driver

2019-04-25 Thread 'gre...@linuxfoundation.org'
On Mon, Apr 22, 2019 at 10:05:58PM +, Matt Sickler wrote:
> Add Daktronics DMA driver.  I've added the SPDX license identifiers, Kconfig
> entry, and cleaned up as many of the warnings as I could.
> 
> The AIO support code will be removed in a future patch.
> 
> Signed-off-by: Matt Sickler 

Looks good, now applied, thanks for doing this.

greg k-h
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2] staging: kpc2000: Add DMA driver

2019-04-23 Thread kbuild test robot
Hi Matt,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on staging/staging-testing]
[cannot apply to v5.1-rc6 next-20190418]
[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/Matt-Sickler/staging-kpc2000-Add-DMA-driver/20190423-120446
config: parisc-allmodconfig (attached as .config)
compiler: hppa-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=parisc 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot 


All warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:330:0,
from include/linux/kernel.h:15,
from include/linux/list.h:9,
from include/linux/module.h:9,
from drivers/staging/kpc2000/kpc_dma/fileops.c:2:
   drivers/staging/kpc2000/kpc_dma/fileops.c: In function 'kpc_dma_transfer':
   drivers/staging/kpc2000/kpc_dma/fileops.c:58:35: warning: format '%ld' 
expects argument of type 'long int', but argument 7 has type 'size_t {aka 
unsigned int}' [-Wformat=]
 dev_dbg(>ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = 
[%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, 
(void*)iov_base, iov_len, ldev);
  ^
   include/linux/dynamic_debug.h:118:15: note: in definition of macro 
'__dynamic_func_call'
  func(, ##__VA_ARGS__);  \
  ^~~
   include/linux/dynamic_debug.h:150:2: note: in expansion of macro 
'_dynamic_func_call'
 _dynamic_func_call(fmt,__dynamic_dev_dbg,   \
 ^~
   include/linux/device.h:1493:2: note: in expansion of macro 'dynamic_dev_dbg'
 dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
 ^~~
   include/linux/device.h:1493:23: note: in expansion of macro 'dev_fmt'
 dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
  ^~~
>> drivers/staging/kpc2000/kpc_dma/fileops.c:58:2: note: in expansion of macro 
>> 'dev_dbg'
 dev_dbg(>ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = 
[%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, 
(void*)iov_base, iov_len, ldev);
 ^~~

vim +/dev_dbg +58 drivers/staging/kpc2000/kpc_dma/fileops.c

34  
35  /**  Transfer Helpers  **/
36  static
37  int  kpc_dma_transfer(struct dev_private_data *priv, struct kiocb *kcb, 
unsigned long iov_base, size_t iov_len)
38  {
39  unsigned int i = 0;
40  long rv = 0;
41  struct kpc_dma_device *ldev;
42  struct aio_cb_data *acd;
43  DECLARE_COMPLETION_ONSTACK(done);
44  u32 desc_needed = 0;
45  struct scatterlist *sg;
46  u32 num_descrs_avail;
47  struct kpc_dma_descriptor *desc;
48  unsigned int pcnt;
49  unsigned int p;
50  u64 card_addr;
51  u64 dma_addr;
52  u64 user_ctl;
53  
54  BUG_ON(priv == NULL);
55  ldev = priv->ldev;
56  BUG_ON(ldev == NULL);
57  
  > 58  dev_dbg(>ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], 
kcb = [%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, 
(void*)iov_base, iov_len, ldev);
59  
60  acd = (struct aio_cb_data *) kzalloc(sizeof(struct 
aio_cb_data), GFP_KERNEL);
61  if (!acd){
62  dev_err(>ldev->pldev->dev, "Couldn't kmalloc 
space for for the aio data\n");
63  return -ENOMEM;
64  }
65  memset(acd, 0x66, sizeof(struct aio_cb_data));
66  
67  acd->priv = priv;
68  acd->ldev = priv->ldev;
69  acd->cpl = 
70  acd->flags = 0;
71  acd->kcb = kcb;
72  acd->len = iov_len;
73  acd->page_count = count_pages(iov_base, iov_len);
74  
75  // Allocate an array of page pointers
76  acd->user_pages = kzalloc(sizeof(struct page *) * 
acd->page_count, GFP_KERNEL);
77  if (!acd->user_pages){
78  dev_err(>ldev->pldev->dev, "Couldn't kmalloc 
space for for the page pointers\n");
79  rv = -ENOMEM;
80  goto err_alloc_userpages;
81  }
82  
83  // Lock the user buffer pages in memory, and hold on to the 
page pointers (for the sglist)
84  down_read(>mm->mmap_sem);  /*  get memory map 
semaphore */
85  rv = get_user_pages(iov_base, acd->page_count, FOLL_TOUCH | 
FOLL_WRITE | FOLL_GET, 

Re: [PATCH v2] staging: kpc2000: Add DMA driver

2019-04-22 Thread kbuild test robot
Hi Matt,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on staging/staging-testing]
[cannot apply to v5.1-rc6 next-20190418]
[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/Matt-Sickler/staging-kpc2000-Add-DMA-driver/20190423-120446
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-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=arm 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot 


All warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:330:0,
from include/linux/kernel.h:15,
from include/linux/list.h:9,
from include/linux/module.h:9,
from drivers/staging//kpc2000/kpc_dma/fileops.c:2:
   drivers/staging//kpc2000/kpc_dma/fileops.c: In function 'kpc_dma_transfer':
>> drivers/staging//kpc2000/kpc_dma/fileops.c:58:35: warning: format '%ld' 
>> expects argument of type 'long int', but argument 7 has type 'size_t {aka 
>> unsigned int}' [-Wformat=]
 dev_dbg(>ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = 
[%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, 
(void*)iov_base, iov_len, ldev);
  ^
   include/linux/dynamic_debug.h:118:15: note: in definition of macro 
'__dynamic_func_call'
  func(, ##__VA_ARGS__);  \
  ^~~
   include/linux/dynamic_debug.h:150:2: note: in expansion of macro 
'_dynamic_func_call'
 _dynamic_func_call(fmt,__dynamic_dev_dbg,   \
 ^~
   include/linux/device.h:1493:2: note: in expansion of macro 'dynamic_dev_dbg'
 dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
 ^~~
   include/linux/device.h:1493:23: note: in expansion of macro 'dev_fmt'
 dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
  ^~~
   drivers/staging//kpc2000/kpc_dma/fileops.c:58:2: note: in expansion of macro 
'dev_dbg'
 dev_dbg(>ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = 
[%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, 
(void*)iov_base, iov_len, ldev);
 ^~~

vim +58 drivers/staging//kpc2000/kpc_dma/fileops.c

   > 2  #include 
 3  #include 
 4  #include 
 5  #include/* printk() */
 6  #include  /* kmalloc() */
 7  #include/* everything... */
 8  #include /* error codes */
 9  #include /* size_t */
10  #include 
11  #include /* copy_*_user */
12  #include   /* aio stuff */
13  #include 
14  #include 
15  #include "kpc_dma_driver.h"
16  #include "uapi.h"
17  
18  /**  Helper Functions  **/
19  static inline
20  unsigned int  count_pages(unsigned long iov_base, size_t iov_len)
21  {
22  unsigned long first = (iov_base & PAGE_MASK) >> 
PAGE_SHIFT;
23  unsigned long last  = ((iov_base+iov_len-1) & PAGE_MASK) >> 
PAGE_SHIFT;
24  return last - first + 1;
25  }
26  
27  static inline
28  unsigned int  count_parts_for_sge(struct scatterlist *sg)
29  {
30  unsigned int sg_length = sg_dma_len(sg);
31  sg_length += (0x8-1);
32  return (sg_length / 0x8);
33  }
34  
35  /**  Transfer Helpers  **/
36  static
37  int  kpc_dma_transfer(struct dev_private_data *priv, struct kiocb *kcb, 
unsigned long iov_base, size_t iov_len)
38  {
39  unsigned int i = 0;
40  long rv = 0;
41  struct kpc_dma_device *ldev;
42  struct aio_cb_data *acd;
43  DECLARE_COMPLETION_ONSTACK(done);
44  u32 desc_needed = 0;
45  struct scatterlist *sg;
46  u32 num_descrs_avail;
47  struct kpc_dma_descriptor *desc;
48  unsigned int pcnt;
49  unsigned int p;
50  u64 card_addr;
51  u64 dma_addr;
52  u64 user_ctl;
53  
54  BUG_ON(priv == NULL);
55  ldev = priv->ldev;
56  BUG_ON(ldev == NULL);
57  
  > 58  dev_dbg(>ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], 
kcb = [%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, 
(void*)iov_base, iov_len, ldev);
59  
60  acd = (struct aio_cb_data *) kzalloc(sizeof(struct 
aio_cb_data), GFP_KERNEL);
61  if (!acd){
62  dev_err(>ldev->pldev->dev, "Couldn't kmalloc 
space for for the aio data\n");
63  return -ENOMEM;
  

[PATCH v2] staging: kpc2000: Add DMA driver

2019-04-22 Thread Matt Sickler
Add Daktronics DMA driver.  I've added the SPDX license identifiers, Kconfig
entry, and cleaned up as many of the warnings as I could.

The AIO support code will be removed in a future patch.

Signed-off-by: Matt Sickler 
---
 drivers/staging/kpc2000/Kconfig  |  11 +
 drivers/staging/kpc2000/Makefile |   1 +
 drivers/staging/kpc2000/kpc_dma/Makefile |   6 +
 drivers/staging/kpc2000/kpc_dma/dma.c| 264 ++
 drivers/staging/kpc2000/kpc_dma/fileops.c| 420 +++
 drivers/staging/kpc2000/kpc_dma/kpc_dma_driver.c | 248 +
 drivers/staging/kpc2000/kpc_dma/kpc_dma_driver.h | 220 
 drivers/staging/kpc2000/kpc_dma/uapi.h   |  11 +
 8 files changed, 1181 insertions(+)
 create mode 100644 drivers/staging/kpc2000/kpc_dma/Makefile
 create mode 100644 drivers/staging/kpc2000/kpc_dma/dma.c
 create mode 100644 drivers/staging/kpc2000/kpc_dma/fileops.c
 create mode 100644 drivers/staging/kpc2000/kpc_dma/kpc_dma_driver.c
 create mode 100644 drivers/staging/kpc2000/kpc_dma/kpc_dma_driver.h
 create mode 100644 drivers/staging/kpc2000/kpc_dma/uapi.h

diff --git a/drivers/staging/kpc2000/Kconfig b/drivers/staging/kpc2000/Kconfig
index 926e770d6e0e..fb5922928f47 100644
--- a/drivers/staging/kpc2000/Kconfig
+++ b/drivers/staging/kpc2000/Kconfig
@@ -44,3 +44,14 @@ config KPC2000_I2C
 
  If unsure, say N.
 
+config KPC2000_DMA
+   tristate "Daktronics KPC DMA controller"
+   depends on KPC2000
+   help
+ Say Y here if you wish to support the Daktronics DMA controller.
+
+ To compile this driver as a module, choose M here: the module
+ will be called kpc2000_dma
+
+ If unsure, say N.
+
diff --git a/drivers/staging/kpc2000/Makefile b/drivers/staging/kpc2000/Makefile
index 6fcb2ee7b27d..1e48e9df1329 100644
--- a/drivers/staging/kpc2000/Makefile
+++ b/drivers/staging/kpc2000/Makefile
@@ -3,3 +3,4 @@
 obj-$(CONFIG_KPC2000) += kpc2000/
 obj-$(CONFIG_KPC2000_I2C) += kpc_i2c/
 obj-$(CONFIG_KPC2000_SPI) += kpc_spi/
+obj-$(CONFIG_KPC2000_DMA) += kpc_dma/
diff --git a/drivers/staging/kpc2000/kpc_dma/Makefile 
b/drivers/staging/kpc2000/kpc_dma/Makefile
new file mode 100644
index ..fe5db532c8c8
--- /dev/null
+++ b/drivers/staging/kpc2000/kpc_dma/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-m := kpc_dma.o
+kpc_dma-objs += dma.o
+kpc_dma-objs += fileops.o
+kpc_dma-objs += kpc_dma_driver.o
diff --git a/drivers/staging/kpc2000/kpc_dma/dma.c 
b/drivers/staging/kpc2000/kpc_dma/dma.c
new file mode 100644
index ..6959bac11388
--- /dev/null
+++ b/drivers/staging/kpc2000/kpc_dma/dma.c
@@ -0,0 +1,264 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "kpc_dma_driver.h"
+
+/**  IRQ Handlers  **/
+static
+irqreturn_t  ndd_irq_handler(int irq, void *dev_id)
+{
+   struct kpc_dma_device *ldev = (struct kpc_dma_device*)dev_id;
+   
+   if ((GetEngineControl(ldev) & ENG_CTL_IRQ_ACTIVE) || 
(ldev->desc_completed->MyDMAAddr != GetEngineCompletePtr(ldev)))
+   schedule_work(>irq_work);
+   
+   return IRQ_HANDLED;
+}
+
+static
+void  ndd_irq_worker(struct work_struct *ws)
+{
+   struct kpc_dma_descriptor *cur;
+   struct kpc_dma_device *eng = container_of(ws, struct kpc_dma_device, 
irq_work);
+   lock_engine(eng);
+   
+   if (GetEngineCompletePtr(eng) == 0)
+   goto out;
+   
+   if (eng->desc_completed->MyDMAAddr == GetEngineCompletePtr(eng))
+   goto out;
+   
+   cur = eng->desc_completed;
+   do {
+   cur = cur->Next;
+   dev_dbg(>pldev->dev, "Handling completed descriptor %p 
(acd = %p)\n", cur, cur->acd);
+   BUG_ON(cur == eng->desc_next); // Ordering failure.
+   
+   if (cur->DescControlFlags & DMA_DESC_CTL_SOP){
+   eng->accumulated_bytes = 0;
+   eng->accumulated_flags = 0;
+   }
+   
+   eng->accumulated_bytes += cur->DescByteCount;
+   if (cur->DescStatusFlags & DMA_DESC_STS_ERROR)
+   eng->accumulated_flags |= ACD_FLAG_ENG_ACCUM_ERROR;
+   
+   if (cur->DescStatusFlags & DMA_DESC_STS_SHORT)
+   eng->accumulated_flags |= ACD_FLAG_ENG_ACCUM_SHORT;
+   
+   if (cur->DescControlFlags & DMA_DESC_CTL_EOP){
+   if (cur->acd)
+   transfer_complete_cb(cur->acd, 
eng->accumulated_bytes, eng->accumulated_flags | ACD_FLAG_DONE);
+   }
+   
+   eng->desc_completed = cur;
+   } while (cur->MyDMAAddr != GetEngineCompletePtr(eng));
+   
+ out:
+   SetClearEngineControl(eng, ENG_CTL_IRQ_ACTIVE, 0);
+   
+