[RFC PATCH 2/9] media: request: add generic queue

2017-12-14 Thread Alexandre Courbot
Add a generic request queue that supports most use-case and should be
usable as-is by drivers without special hardware features.

The generic queue stores the requests into a FIFO list and executes them
sequentially.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/Makefile  |   2 +-
 drivers/media/media-request-queue-generic.c | 150 
 include/media/media-request.h   |   8 ++
 3 files changed, 159 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/media-request-queue-generic.c

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 985d35ec6b29..90117fff1339 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -4,7 +4,7 @@
 #
 
 media-objs := media-device.o media-devnode.o media-entity.o \
-  media-request.o
+  media-request.o media-request-queue-generic.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-request-queue-generic.c 
b/drivers/media/media-request-queue-generic.c
new file mode 100644
index ..780414b6d46a
--- /dev/null
+++ b/drivers/media/media-request-queue-generic.c
@@ -0,0 +1,150 @@
+/*
+ * Generic request queue implementation.
+ *
+ * Copyright (C) 2017, The Chromium OS Authors.  All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+
+#include 
+#include 
+
+/**
+ * struct media_request_generic - request enabled for the generic queue
+ *
+ * @base:  base request member
+ * @queue: entry in media_request_queue_generic::queued_requests
+ */
+struct media_request_generic {
+   struct media_request base;
+   struct list_head queue;
+};
+#define to_generic_request(r) \
+   container_of(r, struct media_request_generic, base)
+
+/**
+ * struct media_request_queue_generic - generic request queue implementation
+ *
+ * Implements a simple request queue, where the next queued request is executed
+ * as soon as the previous one completes.
+ *
+ * @base:  base request queue member
+ * @mutex: protects the queue
+ * @queued_requests:   list of requests to be sequentially executed
+ */
+struct media_request_queue_generic {
+   struct media_request_queue base;
+
+   struct list_head queued_requests;
+};
+#define to_generic_queue(q) \
+   container_of(q, struct media_request_queue_generic, base)
+
+static struct media_request *
+media_request_generic_alloc(struct media_request_queue *queue)
+{
+   struct media_request_generic *req;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return ERR_PTR(-ENOMEM);
+
+   return >base;
+}
+
+static void media_request_generic_free(struct media_request_queue *queue,
+  struct media_request *_req)
+{
+   struct media_request_generic *req = to_generic_request(_req);
+
+   kfree(req);
+}
+
+static void schedule_next_req(struct media_request_queue_generic *queue)
+{
+   struct media_request_generic *req;
+   struct media_request_entity_data *data;
+
+   req = list_first_entry_or_null(>queued_requests, typeof(*req),
+  queue);
+   if (!req)
+   return;
+
+   list_del(>queue);
+   queue->base.active_request = >base;
+
+   list_for_each_entry(data, >base.data, list) {
+   int ret;
+
+   ret = data->entity->req_ops->apply_data(data);
+   }
+
+   list_for_each_entry(data, >base.data, list) {
+   data->entity->ops->process_request(>base, data);
+   }
+}
+
+static void media_request_generic_complete(struct media_request_queue *_queue)
+{
+   struct media_request_queue_generic *queue = to_generic_queue(_queue);
+
+   queue->base.active_request = NULL;
+   schedule_next_req(queue);
+}
+
+static int media_request_generic_queue(struct media_request_queue *_queue,
+  struct media_request *_req)
+{
+   struct media_request_queue_generic *queue = to_generic_queue(_queue);
+   struct media_request_generic *req = to_generic_request(_req);
+
+   list_add_tail(>queue, >queued_requests);
+
+   if (!queue->base.active_request)
+   schedule_next_req(queue);
+
+   return 0;
+}
+
+static void
+media_request_generic_queue_release(struct media_request_queue *_queue)
+{
+   struct media_request_queue_generic *queue = to_generic_queue(_queue);
+
+   media_request_queue_release(>base);
+   kfree(queue);

[RFC PATCH 2/9] media: request: add generic queue

2017-12-14 Thread Alexandre Courbot
Add a generic request queue that supports most use-case and should be
usable as-is by drivers without special hardware features.

The generic queue stores the requests into a FIFO list and executes them
sequentially.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/Makefile  |   2 +-
 drivers/media/media-request-queue-generic.c | 150 
 include/media/media-request.h   |   8 ++
 3 files changed, 159 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/media-request-queue-generic.c

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 985d35ec6b29..90117fff1339 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -4,7 +4,7 @@
 #
 
 media-objs := media-device.o media-devnode.o media-entity.o \
-  media-request.o
+  media-request.o media-request-queue-generic.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-request-queue-generic.c 
b/drivers/media/media-request-queue-generic.c
new file mode 100644
index ..780414b6d46a
--- /dev/null
+++ b/drivers/media/media-request-queue-generic.c
@@ -0,0 +1,150 @@
+/*
+ * Generic request queue implementation.
+ *
+ * Copyright (C) 2017, The Chromium OS Authors.  All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+
+#include 
+#include 
+
+/**
+ * struct media_request_generic - request enabled for the generic queue
+ *
+ * @base:  base request member
+ * @queue: entry in media_request_queue_generic::queued_requests
+ */
+struct media_request_generic {
+   struct media_request base;
+   struct list_head queue;
+};
+#define to_generic_request(r) \
+   container_of(r, struct media_request_generic, base)
+
+/**
+ * struct media_request_queue_generic - generic request queue implementation
+ *
+ * Implements a simple request queue, where the next queued request is executed
+ * as soon as the previous one completes.
+ *
+ * @base:  base request queue member
+ * @mutex: protects the queue
+ * @queued_requests:   list of requests to be sequentially executed
+ */
+struct media_request_queue_generic {
+   struct media_request_queue base;
+
+   struct list_head queued_requests;
+};
+#define to_generic_queue(q) \
+   container_of(q, struct media_request_queue_generic, base)
+
+static struct media_request *
+media_request_generic_alloc(struct media_request_queue *queue)
+{
+   struct media_request_generic *req;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return ERR_PTR(-ENOMEM);
+
+   return >base;
+}
+
+static void media_request_generic_free(struct media_request_queue *queue,
+  struct media_request *_req)
+{
+   struct media_request_generic *req = to_generic_request(_req);
+
+   kfree(req);
+}
+
+static void schedule_next_req(struct media_request_queue_generic *queue)
+{
+   struct media_request_generic *req;
+   struct media_request_entity_data *data;
+
+   req = list_first_entry_or_null(>queued_requests, typeof(*req),
+  queue);
+   if (!req)
+   return;
+
+   list_del(>queue);
+   queue->base.active_request = >base;
+
+   list_for_each_entry(data, >base.data, list) {
+   int ret;
+
+   ret = data->entity->req_ops->apply_data(data);
+   }
+
+   list_for_each_entry(data, >base.data, list) {
+   data->entity->ops->process_request(>base, data);
+   }
+}
+
+static void media_request_generic_complete(struct media_request_queue *_queue)
+{
+   struct media_request_queue_generic *queue = to_generic_queue(_queue);
+
+   queue->base.active_request = NULL;
+   schedule_next_req(queue);
+}
+
+static int media_request_generic_queue(struct media_request_queue *_queue,
+  struct media_request *_req)
+{
+   struct media_request_queue_generic *queue = to_generic_queue(_queue);
+   struct media_request_generic *req = to_generic_request(_req);
+
+   list_add_tail(>queue, >queued_requests);
+
+   if (!queue->base.active_request)
+   schedule_next_req(queue);
+
+   return 0;
+}
+
+static void
+media_request_generic_queue_release(struct media_request_queue *_queue)
+{
+   struct media_request_queue_generic *queue = to_generic_queue(_queue);
+
+   media_request_queue_release(>base);
+   kfree(queue);
+}
+
+static const 

[RFC PATCH 4/9] videodev2.h: Add request field to v4l2_buffer

2017-12-14 Thread Alexandre Courbot
From: Hans Verkuil 

When queuing buffers allow for passing the request ID that
should be associated with this buffer.

Signed-off-by: Hans Verkuil 
[acour...@chromium.org: make request ID 32-bit]
Signed-off-by: Alexandre Courbot 
---
 drivers/media/usb/cpia2/cpia2_v4l.c   | 2 +-
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 7 ---
 drivers/media/v4l2-core/v4l2-ioctl.c  | 4 ++--
 drivers/media/v4l2-core/videobuf2-v4l2.c  | 3 ++-
 include/media/videobuf2-v4l2.h| 2 ++
 include/uapi/linux/videodev2.h| 3 ++-
 6 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c 
b/drivers/media/usb/cpia2/cpia2_v4l.c
index 3dedd83f0b19..7217dde95a8a 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -948,7 +948,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct 
v4l2_buffer *buf)
buf->sequence = cam->buffers[buf->index].seq;
buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
buf->length = cam->frame_size;
-   buf->reserved2 = 0;
+   buf->request = 0;
buf->reserved = 0;
memset(>timecode, 0, sizeof(buf->timecode));
 
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 821f2aa299ae..94f07c3b0b53 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -370,7 +370,7 @@ struct v4l2_buffer32 {
__s32   fd;
} m;
__u32   length;
-   __u32   reserved2;
+   __u32   request;
__u32   reserved;
 };
 
@@ -438,7 +438,8 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct 
v4l2_buffer32 __user
get_user(kp->type, >type) ||
get_user(kp->flags, >flags) ||
get_user(kp->memory, >memory) ||
-   get_user(kp->length, >length))
+   get_user(kp->length, >length) ||
+   get_user(kp->request, >request))
return -EFAULT;
 
if (V4L2_TYPE_IS_OUTPUT(kp->type))
@@ -533,7 +534,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct 
v4l2_buffer32 __user
put_user(kp->timestamp.tv_usec, >timestamp.tv_usec) ||
copy_to_user(>timecode, >timecode, sizeof(struct 
v4l2_timecode)) ||
put_user(kp->sequence, >sequence) ||
-   put_user(kp->reserved2, >reserved2) ||
+   put_user(kp->request, >request) ||
put_user(kp->reserved, >reserved) ||
put_user(kp->length, >length))
return -EFAULT;
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index ec4ecd5aa8bf..8d041247e97f 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -437,13 +437,13 @@ static void v4l_print_buffer(const void *arg, bool 
write_only)
const struct v4l2_plane *plane;
int i;
 
-   pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, flags=0x%08x, 
field=%s, sequence=%d, memory=%s",
+   pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, request=%u, 
flags=0x%08x, field=%s, sequence=%d, memory=%s",
p->timestamp.tv_sec / 3600,
(int)(p->timestamp.tv_sec / 60) % 60,
(int)(p->timestamp.tv_sec % 60),
(long)p->timestamp.tv_usec,
p->index,
-   prt_names(p->type, v4l2_type_names),
+   prt_names(p->type, v4l2_type_names), p->request,
p->flags, prt_names(p->field, v4l2_field_names),
p->sequence, prt_names(p->memory, v4l2_memory_names));
 
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c 
b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 0c0669976bdc..bde7b8a3a303 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -203,7 +203,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void 
*pb)
b->timestamp = ns_to_timeval(vb->timestamp);
b->timecode = vbuf->timecode;
b->sequence = vbuf->sequence;
-   b->reserved2 = 0;
+   b->request = vbuf->request;
b->reserved = 0;
 
if (q->is_multiplanar) {
@@ -320,6 +320,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb,
}
vb->timestamp = 0;
vbuf->sequence = 0;
+   vbuf->request = b->request;
 
if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
if (b->memory == VB2_MEMORY_USERPTR) {
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index 036127c54bbf..ef2be0ccff14 100644
--- a/include/media/videobuf2-v4l2.h
+++ 

[RFC PATCH 4/9] videodev2.h: Add request field to v4l2_buffer

2017-12-14 Thread Alexandre Courbot
From: Hans Verkuil 

When queuing buffers allow for passing the request ID that
should be associated with this buffer.

Signed-off-by: Hans Verkuil 
[acour...@chromium.org: make request ID 32-bit]
Signed-off-by: Alexandre Courbot 
---
 drivers/media/usb/cpia2/cpia2_v4l.c   | 2 +-
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 7 ---
 drivers/media/v4l2-core/v4l2-ioctl.c  | 4 ++--
 drivers/media/v4l2-core/videobuf2-v4l2.c  | 3 ++-
 include/media/videobuf2-v4l2.h| 2 ++
 include/uapi/linux/videodev2.h| 3 ++-
 6 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c 
b/drivers/media/usb/cpia2/cpia2_v4l.c
index 3dedd83f0b19..7217dde95a8a 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -948,7 +948,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct 
v4l2_buffer *buf)
buf->sequence = cam->buffers[buf->index].seq;
buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
buf->length = cam->frame_size;
-   buf->reserved2 = 0;
+   buf->request = 0;
buf->reserved = 0;
memset(>timecode, 0, sizeof(buf->timecode));
 
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 821f2aa299ae..94f07c3b0b53 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -370,7 +370,7 @@ struct v4l2_buffer32 {
__s32   fd;
} m;
__u32   length;
-   __u32   reserved2;
+   __u32   request;
__u32   reserved;
 };
 
@@ -438,7 +438,8 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct 
v4l2_buffer32 __user
get_user(kp->type, >type) ||
get_user(kp->flags, >flags) ||
get_user(kp->memory, >memory) ||
-   get_user(kp->length, >length))
+   get_user(kp->length, >length) ||
+   get_user(kp->request, >request))
return -EFAULT;
 
if (V4L2_TYPE_IS_OUTPUT(kp->type))
@@ -533,7 +534,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct 
v4l2_buffer32 __user
put_user(kp->timestamp.tv_usec, >timestamp.tv_usec) ||
copy_to_user(>timecode, >timecode, sizeof(struct 
v4l2_timecode)) ||
put_user(kp->sequence, >sequence) ||
-   put_user(kp->reserved2, >reserved2) ||
+   put_user(kp->request, >request) ||
put_user(kp->reserved, >reserved) ||
put_user(kp->length, >length))
return -EFAULT;
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index ec4ecd5aa8bf..8d041247e97f 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -437,13 +437,13 @@ static void v4l_print_buffer(const void *arg, bool 
write_only)
const struct v4l2_plane *plane;
int i;
 
-   pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, flags=0x%08x, 
field=%s, sequence=%d, memory=%s",
+   pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, request=%u, 
flags=0x%08x, field=%s, sequence=%d, memory=%s",
p->timestamp.tv_sec / 3600,
(int)(p->timestamp.tv_sec / 60) % 60,
(int)(p->timestamp.tv_sec % 60),
(long)p->timestamp.tv_usec,
p->index,
-   prt_names(p->type, v4l2_type_names),
+   prt_names(p->type, v4l2_type_names), p->request,
p->flags, prt_names(p->field, v4l2_field_names),
p->sequence, prt_names(p->memory, v4l2_memory_names));
 
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c 
b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 0c0669976bdc..bde7b8a3a303 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -203,7 +203,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void 
*pb)
b->timestamp = ns_to_timeval(vb->timestamp);
b->timecode = vbuf->timecode;
b->sequence = vbuf->sequence;
-   b->reserved2 = 0;
+   b->request = vbuf->request;
b->reserved = 0;
 
if (q->is_multiplanar) {
@@ -320,6 +320,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb,
}
vb->timestamp = 0;
vbuf->sequence = 0;
+   vbuf->request = b->request;
 
if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
if (b->memory == VB2_MEMORY_USERPTR) {
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index 036127c54bbf..ef2be0ccff14 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h
@@ -31,6 +31,7 @@
  * @field: enum 

[RFC PATCH 8/9] media: vim2m: add media device

2017-12-14 Thread Alexandre Courbot
Request API requires a media node. Add one to the vim2m driver so we can
use requests with it.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/platform/vim2m.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index b01fba020d5f..a32e8a7950eb 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -140,6 +140,9 @@ static struct vim2m_fmt *find_format(struct v4l2_format *f)
 struct vim2m_dev {
struct v4l2_device  v4l2_dev;
struct video_device vfd;
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct media_device mdev;
+#endif
 
atomic_tnum_inst;
struct mutexdev_mutex;
@@ -1001,6 +1004,13 @@ static int vim2m_probe(struct platform_device *pdev)
 
spin_lock_init(>irqlock);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   dev->mdev.dev = >dev;
+   strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
+   media_device_init(>mdev);
+   dev->v4l2_dev.mdev = >mdev;
+#endif
+
ret = v4l2_device_register(>dev, >v4l2_dev);
if (ret)
return ret;
@@ -1034,6 +1044,13 @@ static int vim2m_probe(struct platform_device *pdev)
goto err_m2m;
}
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   /* Register the media device node */
+   ret = media_device_register(>mdev);
+   if (ret)
+   goto err_m2m;
+#endif
+
return 0;
 
 err_m2m:
@@ -1050,6 +1067,13 @@ static int vim2m_remove(struct platform_device *pdev)
struct vim2m_dev *dev = platform_get_drvdata(pdev);
 
v4l2_info(>v4l2_dev, "Removing " MEM2MEM_NAME);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+   if (media_devnode_is_registered(dev->mdev.devnode))
+   media_device_unregister(>mdev);
+   media_device_cleanup(>mdev);
+#endif
+
v4l2_m2m_release(dev->m2m_dev);
del_timer_sync(>timer);
video_unregister_device(>vfd);
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 6/9] media: vb2: add support for requests in QBUF ioctl

2017-12-14 Thread Alexandre Courbot
Support the request argument of the QBUF ioctl.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-ioctl.c | 93 +++-
 1 file changed, 92 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 8d041247e97f..28f9c368563e 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -965,6 +966,81 @@ static int check_fmt(struct file *file, enum v4l2_buf_type 
type)
return -EINVAL;
 }
 
+/*
+ * Validate that a given request can be used during an ioctl.
+ *
+ * When using the request API, request file descriptors must be matched against
+ * the actual request object. User-space can pass any file descriptor, so we
+ * need to make sure the call is valid before going further.
+ *
+ * This function looks up the request and associated data and performs the
+ * following sanity checks:
+ *
+ * * Make sure that the entity supports requests,
+ * * Make sure that the entity belongs to the media_device managing the passed
+ *   request,
+ * * Make sure that the entity data (if any) is associated to the current file
+ *   handler.
+ *
+ * This function returns a pointer to the valid request, or and error code in
+ * case of failure. When successful, a reference to the request is acquired and
+ * must be properly released.
+ */
+#ifdef CONFIG_MEDIA_CONTROLLER
+static struct media_request *
+check_request(int request, struct file *file, void *fh)
+{
+   struct media_request *req = NULL;
+   struct video_device *vfd = video_devdata(file);
+   struct v4l2_fh *vfh =
+   test_bit(V4L2_FL_USES_V4L2_FH, >flags) ? fh : NULL;
+   struct media_entity *entity = >entity;
+   const struct media_entity *ent;
+   struct media_request_entity_data *data;
+   bool found = false;
+
+   if (!entity)
+   return ERR_PTR(-EINVAL);
+
+   /* Check that the entity supports requests */
+   if (!entity->req_ops)
+   return ERR_PTR(-ENOTSUPP);
+
+   req = media_request_get_from_fd(request);
+   if (!req)
+   return ERR_PTR(-EINVAL);
+
+   /* Validate that the entity belongs to the media_device managing
+* the request queue */
+   media_device_for_each_entity(ent, req->queue->mdev) {
+   if (entity == ent) {
+   found = true;
+   break;
+   }
+   }
+   if (!found) {
+   media_request_put(req);
+   return ERR_PTR(-EINVAL);
+   }
+
+   /* Validate that the entity's data belongs to the correct fh */
+   data = media_request_get_entity_data(req, entity, vfh);
+   if (IS_ERR(data)) {
+   media_request_put(req);
+   return ERR_PTR(PTR_ERR(data));
+   }
+
+   return req;
+}
+#else /* CONFIG_MEDIA_CONTROLLER */
+static struct media_request *
+check_request(int request, struct file *file, void *fh)
+{
+   return ERR_PTR(-ENOTSUPP);
+}
+
+#endif /* CONFIG_MEDIA_CONTROLLER */
+
 static void v4l_sanitize_format(struct v4l2_format *fmt)
 {
unsigned int offset;
@@ -1902,10 +1978,25 @@ static int v4l_querybuf(const struct v4l2_ioctl_ops 
*ops,
 static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
 {
+   struct media_request *req = NULL;
struct v4l2_buffer *p = arg;
int ret = check_fmt(file, p->type);
 
-   return ret ? ret : ops->vidioc_qbuf(file, fh, p);
+   if (ret)
+   return ret;
+
+   if (p->request > 0) {
+   req = check_request(p->request, file, fh);
+   if (IS_ERR(req))
+   return PTR_ERR(req);
+   }
+
+   ret = ops->vidioc_qbuf(file, fh, p);
+
+   if (req)
+   media_request_put(req);
+
+   return ret;
 }
 
 static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 8/9] media: vim2m: add media device

2017-12-14 Thread Alexandre Courbot
Request API requires a media node. Add one to the vim2m driver so we can
use requests with it.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/platform/vim2m.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index b01fba020d5f..a32e8a7950eb 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -140,6 +140,9 @@ static struct vim2m_fmt *find_format(struct v4l2_format *f)
 struct vim2m_dev {
struct v4l2_device  v4l2_dev;
struct video_device vfd;
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct media_device mdev;
+#endif
 
atomic_tnum_inst;
struct mutexdev_mutex;
@@ -1001,6 +1004,13 @@ static int vim2m_probe(struct platform_device *pdev)
 
spin_lock_init(>irqlock);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   dev->mdev.dev = >dev;
+   strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
+   media_device_init(>mdev);
+   dev->v4l2_dev.mdev = >mdev;
+#endif
+
ret = v4l2_device_register(>dev, >v4l2_dev);
if (ret)
return ret;
@@ -1034,6 +1044,13 @@ static int vim2m_probe(struct platform_device *pdev)
goto err_m2m;
}
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   /* Register the media device node */
+   ret = media_device_register(>mdev);
+   if (ret)
+   goto err_m2m;
+#endif
+
return 0;
 
 err_m2m:
@@ -1050,6 +1067,13 @@ static int vim2m_remove(struct platform_device *pdev)
struct vim2m_dev *dev = platform_get_drvdata(pdev);
 
v4l2_info(>v4l2_dev, "Removing " MEM2MEM_NAME);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+   if (media_devnode_is_registered(dev->mdev.devnode))
+   media_device_unregister(>mdev);
+   media_device_cleanup(>mdev);
+#endif
+
v4l2_m2m_release(dev->m2m_dev);
del_timer_sync(>timer);
video_unregister_device(>vfd);
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 6/9] media: vb2: add support for requests in QBUF ioctl

2017-12-14 Thread Alexandre Courbot
Support the request argument of the QBUF ioctl.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-ioctl.c | 93 +++-
 1 file changed, 92 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 8d041247e97f..28f9c368563e 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -965,6 +966,81 @@ static int check_fmt(struct file *file, enum v4l2_buf_type 
type)
return -EINVAL;
 }
 
+/*
+ * Validate that a given request can be used during an ioctl.
+ *
+ * When using the request API, request file descriptors must be matched against
+ * the actual request object. User-space can pass any file descriptor, so we
+ * need to make sure the call is valid before going further.
+ *
+ * This function looks up the request and associated data and performs the
+ * following sanity checks:
+ *
+ * * Make sure that the entity supports requests,
+ * * Make sure that the entity belongs to the media_device managing the passed
+ *   request,
+ * * Make sure that the entity data (if any) is associated to the current file
+ *   handler.
+ *
+ * This function returns a pointer to the valid request, or and error code in
+ * case of failure. When successful, a reference to the request is acquired and
+ * must be properly released.
+ */
+#ifdef CONFIG_MEDIA_CONTROLLER
+static struct media_request *
+check_request(int request, struct file *file, void *fh)
+{
+   struct media_request *req = NULL;
+   struct video_device *vfd = video_devdata(file);
+   struct v4l2_fh *vfh =
+   test_bit(V4L2_FL_USES_V4L2_FH, >flags) ? fh : NULL;
+   struct media_entity *entity = >entity;
+   const struct media_entity *ent;
+   struct media_request_entity_data *data;
+   bool found = false;
+
+   if (!entity)
+   return ERR_PTR(-EINVAL);
+
+   /* Check that the entity supports requests */
+   if (!entity->req_ops)
+   return ERR_PTR(-ENOTSUPP);
+
+   req = media_request_get_from_fd(request);
+   if (!req)
+   return ERR_PTR(-EINVAL);
+
+   /* Validate that the entity belongs to the media_device managing
+* the request queue */
+   media_device_for_each_entity(ent, req->queue->mdev) {
+   if (entity == ent) {
+   found = true;
+   break;
+   }
+   }
+   if (!found) {
+   media_request_put(req);
+   return ERR_PTR(-EINVAL);
+   }
+
+   /* Validate that the entity's data belongs to the correct fh */
+   data = media_request_get_entity_data(req, entity, vfh);
+   if (IS_ERR(data)) {
+   media_request_put(req);
+   return ERR_PTR(PTR_ERR(data));
+   }
+
+   return req;
+}
+#else /* CONFIG_MEDIA_CONTROLLER */
+static struct media_request *
+check_request(int request, struct file *file, void *fh)
+{
+   return ERR_PTR(-ENOTSUPP);
+}
+
+#endif /* CONFIG_MEDIA_CONTROLLER */
+
 static void v4l_sanitize_format(struct v4l2_format *fmt)
 {
unsigned int offset;
@@ -1902,10 +1978,25 @@ static int v4l_querybuf(const struct v4l2_ioctl_ops 
*ops,
 static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
 {
+   struct media_request *req = NULL;
struct v4l2_buffer *p = arg;
int ret = check_fmt(file, p->type);
 
-   return ret ? ret : ops->vidioc_qbuf(file, fh, p);
+   if (ret)
+   return ret;
+
+   if (p->request > 0) {
+   req = check_request(p->request, file, fh);
+   if (IS_ERR(req))
+   return PTR_ERR(req);
+   }
+
+   ret = ops->vidioc_qbuf(file, fh, p);
+
+   if (req)
+   media_request_put(req);
+
+   return ret;
 }
 
 static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 5/9] media: vb2: add support for requests

2017-12-14 Thread Alexandre Courbot
Add throttling support for buffers when requests are in use on a given
queue. Buffers associated to a request are kept into the vb2 queue until
the request becomes active, at which point all the buffers are passed to
the driver. The queue can also signal that is has processed all of a
request's buffers.

Also add support for the request parameter when handling the QBUF ioctl.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/videobuf2-core.c | 59 
 drivers/media/v4l2-core/videobuf2-v4l2.c | 29 +++-
 include/media/videobuf2-core.h   | 25 +-
 3 files changed, 104 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index cb115ba6a1d2..c01038b7962a 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -898,6 +898,8 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
state != VB2_BUF_STATE_REQUEUEING))
state = VB2_BUF_STATE_ERROR;
 
+   WARN_ON(vb->request != q->cur_req);
+
 #ifdef CONFIG_VIDEO_ADV_DEBUG
/*
 * Although this is not a callback, it still does have to balance
@@ -920,6 +922,13 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
/* Add the buffer to the done buffers list */
list_add_tail(>done_entry, >done_list);
vb->state = state;
+
+   if (q->cur_req) {
+   WARN_ON(q->req_buf_cnt < 1);
+
+   if (--q->req_buf_cnt == 0)
+   q->cur_req = NULL;
+   }
}
atomic_dec(>owned_by_drv_count);
spin_unlock_irqrestore(>done_lock, flags);
@@ -1298,6 +1307,16 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned 
int index, void *pb)
 }
 EXPORT_SYMBOL_GPL(vb2_core_prepare_buf);
 
+static void vb2_queue_enqueue_current_buffers(struct vb2_queue *q)
+{
+   struct vb2_buffer *vb;
+
+   list_for_each_entry(vb, >queued_list, queued_entry) {
+   if (vb->request == q->cur_req)
+   __enqueue_in_driver(vb);
+   }
+}
+
 /**
  * vb2_start_streaming() - Attempt to start streaming.
  * @q: videobuf2 queue
@@ -1318,8 +1337,7 @@ static int vb2_start_streaming(struct vb2_queue *q)
 * If any buffers were queued before streamon,
 * we can now pass them to driver for processing.
 */
-   list_for_each_entry(vb, >queued_list, queued_entry)
-   __enqueue_in_driver(vb);
+   vb2_queue_enqueue_current_buffers(q);
 
/* Tell the driver to start streaming */
q->start_streaming_called = 1;
@@ -1361,7 +1379,8 @@ static int vb2_start_streaming(struct vb2_queue *q)
return ret;
 }
 
-int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
+int vb2_core_qbuf(struct vb2_queue *q, unsigned int index,
+ struct media_request *req, void *pb)
 {
struct vb2_buffer *vb;
int ret;
@@ -1392,6 +1411,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int 
index, void *pb)
q->queued_count++;
q->waiting_for_buffers = false;
vb->state = VB2_BUF_STATE_QUEUED;
+   vb->request = req;
 
if (pb)
call_void_bufop(q, copy_timestamp, vb, pb);
@@ -1401,8 +1421,11 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int 
index, void *pb)
/*
 * If already streaming, give the buffer to driver for processing.
 * If not, the buffer will be given to driver on next streamon.
+*
+* If using the request API, the buffer will be given to the driver
+* when the request becomes active.
 */
-   if (q->start_streaming_called)
+   if (q->start_streaming_called && !req)
__enqueue_in_driver(vb);
 
/* Fill buffer information for the userspace */
@@ -1427,6 +1450,28 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int 
index, void *pb)
 }
 EXPORT_SYMBOL_GPL(vb2_core_qbuf);
 
+void vb2_queue_start_request(struct vb2_queue *q, struct media_request *req)
+{
+   struct vb2_buffer *vb;
+
+   q->req_buf_cnt = 0;
+   list_for_each_entry(vb, >queued_list, queued_entry) {
+   if (vb->request == req)
+   ++q->req_buf_cnt;
+   }
+
+   /* only consider the request if we actually have buffers for it */
+   if (q->req_buf_cnt == 0)
+   return;
+
+   q->cur_req = req;
+
+   /* If not streaming yet, we will enqueue the buffers later */
+   if (q->start_streaming_called)
+   vb2_queue_enqueue_current_buffers(q);
+}
+EXPORT_SYMBOL_GPL(vb2_queue_start_request);
+
 /**
  * __vb2_wait_for_done_vb() - wait for a buffer to become available
  * for dequeuing
@@ -2242,7 +2287,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int 

[RFC PATCH 3/9] media: request: add generic entity ops

2017-12-14 Thread Alexandre Courbot
Add skeleton ops for generic entities. The intent is to provide a
generic mechanism to apply request parameters to entities using regular
media/v4l2 functions.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/Makefile   |  3 +-
 drivers/media/media-request-entity-generic.c | 56 
 include/media/media-request.h|  5 +++
 3 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/media-request-entity-generic.c

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 90117fff1339..dea482f6ab72 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -4,7 +4,8 @@
 #
 
 media-objs := media-device.o media-devnode.o media-entity.o \
-  media-request.o media-request-queue-generic.o
+  media-request.o media-request-queue-generic.o \
+  media-request-entity-generic.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-request-entity-generic.c 
b/drivers/media/media-request-entity-generic.c
new file mode 100644
index ..18e53f9ce525
--- /dev/null
+++ b/drivers/media/media-request-entity-generic.c
@@ -0,0 +1,56 @@
+/*
+ * Media generic entity ops
+ *
+ * Copyright (C) 2017, The Chromium OS Authors.  All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+
+#include 
+#include 
+
+struct media_request_entity_data_generic {
+   struct media_request_entity_data base;
+};
+
+static struct media_request_entity_data *
+alloc_req_data(struct media_request *req, struct media_entity *entity)
+{
+   struct media_request_entity_data_generic *ret;
+
+   ret = kzalloc(sizeof(*ret), GFP_KERNEL);
+   if (!ret)
+   return ERR_PTR(-ENOMEM);
+
+   return >base;
+}
+
+static void release_req_data(struct media_request_entity_data *_data)
+{
+   struct media_request_entity_data_generic *data;
+
+   data = container_of(_data, typeof(*data), base);
+   kfree(data);
+}
+
+static int apply_req_data(struct media_request_entity_data *_data)
+{
+   return 0;
+}
+
+const struct media_request_entity_ops
+media_entity_request_generic_ops = {
+   .alloc_data = alloc_req_data,
+   .release_data = release_req_data,
+   .apply_data = apply_req_data,
+};
+EXPORT_SYMBOL_GPL(media_entity_request_generic_ops);
diff --git a/include/media/media-request.h b/include/media/media-request.h
index 583a1116f735..de3d6d824ffd 100644
--- a/include/media/media-request.h
+++ b/include/media/media-request.h
@@ -240,6 +240,11 @@ struct media_request_entity_ops {
int (*apply_data)(struct media_request_entity_data *data);
 };
 
+/*
+ * Generic entity request support, built on top of standard V4L2 functions
+ */
+extern const struct media_request_entity_ops media_entity_request_generic_ops;
+
 /**
  * media_device_request_cmd() - perform the REQUEST_CMD ioctl
  *
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 5/9] media: vb2: add support for requests

2017-12-14 Thread Alexandre Courbot
Add throttling support for buffers when requests are in use on a given
queue. Buffers associated to a request are kept into the vb2 queue until
the request becomes active, at which point all the buffers are passed to
the driver. The queue can also signal that is has processed all of a
request's buffers.

Also add support for the request parameter when handling the QBUF ioctl.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/videobuf2-core.c | 59 
 drivers/media/v4l2-core/videobuf2-v4l2.c | 29 +++-
 include/media/videobuf2-core.h   | 25 +-
 3 files changed, 104 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index cb115ba6a1d2..c01038b7962a 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -898,6 +898,8 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
state != VB2_BUF_STATE_REQUEUEING))
state = VB2_BUF_STATE_ERROR;
 
+   WARN_ON(vb->request != q->cur_req);
+
 #ifdef CONFIG_VIDEO_ADV_DEBUG
/*
 * Although this is not a callback, it still does have to balance
@@ -920,6 +922,13 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
/* Add the buffer to the done buffers list */
list_add_tail(>done_entry, >done_list);
vb->state = state;
+
+   if (q->cur_req) {
+   WARN_ON(q->req_buf_cnt < 1);
+
+   if (--q->req_buf_cnt == 0)
+   q->cur_req = NULL;
+   }
}
atomic_dec(>owned_by_drv_count);
spin_unlock_irqrestore(>done_lock, flags);
@@ -1298,6 +1307,16 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned 
int index, void *pb)
 }
 EXPORT_SYMBOL_GPL(vb2_core_prepare_buf);
 
+static void vb2_queue_enqueue_current_buffers(struct vb2_queue *q)
+{
+   struct vb2_buffer *vb;
+
+   list_for_each_entry(vb, >queued_list, queued_entry) {
+   if (vb->request == q->cur_req)
+   __enqueue_in_driver(vb);
+   }
+}
+
 /**
  * vb2_start_streaming() - Attempt to start streaming.
  * @q: videobuf2 queue
@@ -1318,8 +1337,7 @@ static int vb2_start_streaming(struct vb2_queue *q)
 * If any buffers were queued before streamon,
 * we can now pass them to driver for processing.
 */
-   list_for_each_entry(vb, >queued_list, queued_entry)
-   __enqueue_in_driver(vb);
+   vb2_queue_enqueue_current_buffers(q);
 
/* Tell the driver to start streaming */
q->start_streaming_called = 1;
@@ -1361,7 +1379,8 @@ static int vb2_start_streaming(struct vb2_queue *q)
return ret;
 }
 
-int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
+int vb2_core_qbuf(struct vb2_queue *q, unsigned int index,
+ struct media_request *req, void *pb)
 {
struct vb2_buffer *vb;
int ret;
@@ -1392,6 +1411,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int 
index, void *pb)
q->queued_count++;
q->waiting_for_buffers = false;
vb->state = VB2_BUF_STATE_QUEUED;
+   vb->request = req;
 
if (pb)
call_void_bufop(q, copy_timestamp, vb, pb);
@@ -1401,8 +1421,11 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int 
index, void *pb)
/*
 * If already streaming, give the buffer to driver for processing.
 * If not, the buffer will be given to driver on next streamon.
+*
+* If using the request API, the buffer will be given to the driver
+* when the request becomes active.
 */
-   if (q->start_streaming_called)
+   if (q->start_streaming_called && !req)
__enqueue_in_driver(vb);
 
/* Fill buffer information for the userspace */
@@ -1427,6 +1450,28 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int 
index, void *pb)
 }
 EXPORT_SYMBOL_GPL(vb2_core_qbuf);
 
+void vb2_queue_start_request(struct vb2_queue *q, struct media_request *req)
+{
+   struct vb2_buffer *vb;
+
+   q->req_buf_cnt = 0;
+   list_for_each_entry(vb, >queued_list, queued_entry) {
+   if (vb->request == req)
+   ++q->req_buf_cnt;
+   }
+
+   /* only consider the request if we actually have buffers for it */
+   if (q->req_buf_cnt == 0)
+   return;
+
+   q->cur_req = req;
+
+   /* If not streaming yet, we will enqueue the buffers later */
+   if (q->start_streaming_called)
+   vb2_queue_enqueue_current_buffers(q);
+}
+EXPORT_SYMBOL_GPL(vb2_queue_start_request);
+
 /**
  * __vb2_wait_for_done_vb() - wait for a buffer to become available
  * for dequeuing
@@ -2242,7 +2287,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int 
read)

[RFC PATCH 3/9] media: request: add generic entity ops

2017-12-14 Thread Alexandre Courbot
Add skeleton ops for generic entities. The intent is to provide a
generic mechanism to apply request parameters to entities using regular
media/v4l2 functions.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/Makefile   |  3 +-
 drivers/media/media-request-entity-generic.c | 56 
 include/media/media-request.h|  5 +++
 3 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/media-request-entity-generic.c

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 90117fff1339..dea482f6ab72 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -4,7 +4,8 @@
 #
 
 media-objs := media-device.o media-devnode.o media-entity.o \
-  media-request.o media-request-queue-generic.o
+  media-request.o media-request-queue-generic.o \
+  media-request-entity-generic.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-request-entity-generic.c 
b/drivers/media/media-request-entity-generic.c
new file mode 100644
index ..18e53f9ce525
--- /dev/null
+++ b/drivers/media/media-request-entity-generic.c
@@ -0,0 +1,56 @@
+/*
+ * Media generic entity ops
+ *
+ * Copyright (C) 2017, The Chromium OS Authors.  All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+
+#include 
+#include 
+
+struct media_request_entity_data_generic {
+   struct media_request_entity_data base;
+};
+
+static struct media_request_entity_data *
+alloc_req_data(struct media_request *req, struct media_entity *entity)
+{
+   struct media_request_entity_data_generic *ret;
+
+   ret = kzalloc(sizeof(*ret), GFP_KERNEL);
+   if (!ret)
+   return ERR_PTR(-ENOMEM);
+
+   return >base;
+}
+
+static void release_req_data(struct media_request_entity_data *_data)
+{
+   struct media_request_entity_data_generic *data;
+
+   data = container_of(_data, typeof(*data), base);
+   kfree(data);
+}
+
+static int apply_req_data(struct media_request_entity_data *_data)
+{
+   return 0;
+}
+
+const struct media_request_entity_ops
+media_entity_request_generic_ops = {
+   .alloc_data = alloc_req_data,
+   .release_data = release_req_data,
+   .apply_data = apply_req_data,
+};
+EXPORT_SYMBOL_GPL(media_entity_request_generic_ops);
diff --git a/include/media/media-request.h b/include/media/media-request.h
index 583a1116f735..de3d6d824ffd 100644
--- a/include/media/media-request.h
+++ b/include/media/media-request.h
@@ -240,6 +240,11 @@ struct media_request_entity_ops {
int (*apply_data)(struct media_request_entity_data *data);
 };
 
+/*
+ * Generic entity request support, built on top of standard V4L2 functions
+ */
+extern const struct media_request_entity_ops media_entity_request_generic_ops;
+
 /**
  * media_device_request_cmd() - perform the REQUEST_CMD ioctl
  *
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 9/9] media: vim2m: add request support

2017-12-14 Thread Alexandre Courbot
Set the necessary ops for supporting requests in vim2m.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/platform/vim2m.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index a32e8a7950eb..ffe94ef9214d 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
 MODULE_AUTHOR("Pawel Osciak, ");
@@ -142,6 +143,7 @@ struct vim2m_dev {
struct video_device vfd;
 #ifdef CONFIG_MEDIA_CONTROLLER
struct media_device mdev;
+   struct media_request_queue *req_queue;
 #endif
 
atomic_tnum_inst;
@@ -937,6 +939,11 @@ static int vim2m_open(struct file *file)
goto open_unlock;
}
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   v4l2_mem_ctx_request_init(ctx->fh.m2m_ctx, dev->req_queue,
+ >vfd.entity);
+#endif
+
v4l2_fh_add(>fh);
atomic_inc(>num_inst);
 
@@ -992,6 +999,12 @@ static const struct v4l2_m2m_ops m2m_ops = {
.job_abort  = job_abort,
 };
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+static const struct media_entity_operations vim2m_entity_ops = {
+   .process_request = v4l2_m2m_process_request,
+};
+#endif
+
 static int vim2m_probe(struct platform_device *pdev)
 {
struct vim2m_dev *dev;
@@ -1006,6 +1019,10 @@ static int vim2m_probe(struct platform_device *pdev)
 
 #ifdef CONFIG_MEDIA_CONTROLLER
dev->mdev.dev = >dev;
+   dev->req_queue = media_request_queue_generic_alloc(>mdev);
+   if (IS_ERR(dev->req_queue))
+   return PTR_ERR(dev->req_queue);
+   dev->mdev.req_queue = dev->req_queue;
strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
media_device_init(>mdev);
dev->v4l2_dev.mdev = >mdev;
@@ -1023,6 +1040,11 @@ static int vim2m_probe(struct platform_device *pdev)
vfd->lock = >dev_mutex;
vfd->v4l2_dev = >v4l2_dev;
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   vfd->entity.ops = _entity_ops;
+   vfd->entity.req_ops = _entity_request_generic_ops;
+#endif
+
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
if (ret) {
v4l2_err(>v4l2_dev, "Failed to register video device\n");
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 9/9] media: vim2m: add request support

2017-12-14 Thread Alexandre Courbot
Set the necessary ops for supporting requests in vim2m.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/platform/vim2m.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index a32e8a7950eb..ffe94ef9214d 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
 MODULE_AUTHOR("Pawel Osciak, ");
@@ -142,6 +143,7 @@ struct vim2m_dev {
struct video_device vfd;
 #ifdef CONFIG_MEDIA_CONTROLLER
struct media_device mdev;
+   struct media_request_queue *req_queue;
 #endif
 
atomic_tnum_inst;
@@ -937,6 +939,11 @@ static int vim2m_open(struct file *file)
goto open_unlock;
}
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   v4l2_mem_ctx_request_init(ctx->fh.m2m_ctx, dev->req_queue,
+ >vfd.entity);
+#endif
+
v4l2_fh_add(>fh);
atomic_inc(>num_inst);
 
@@ -992,6 +999,12 @@ static const struct v4l2_m2m_ops m2m_ops = {
.job_abort  = job_abort,
 };
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+static const struct media_entity_operations vim2m_entity_ops = {
+   .process_request = v4l2_m2m_process_request,
+};
+#endif
+
 static int vim2m_probe(struct platform_device *pdev)
 {
struct vim2m_dev *dev;
@@ -1006,6 +1019,10 @@ static int vim2m_probe(struct platform_device *pdev)
 
 #ifdef CONFIG_MEDIA_CONTROLLER
dev->mdev.dev = >dev;
+   dev->req_queue = media_request_queue_generic_alloc(>mdev);
+   if (IS_ERR(dev->req_queue))
+   return PTR_ERR(dev->req_queue);
+   dev->mdev.req_queue = dev->req_queue;
strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
media_device_init(>mdev);
dev->v4l2_dev.mdev = >mdev;
@@ -1023,6 +1040,11 @@ static int vim2m_probe(struct platform_device *pdev)
vfd->lock = >dev_mutex;
vfd->v4l2_dev = >v4l2_dev;
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   vfd->entity.ops = _entity_ops;
+   vfd->entity.req_ops = _entity_request_generic_ops;
+#endif
+
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
if (ret) {
v4l2_err(>v4l2_dev, "Failed to register video device\n");
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 7/9] media: v4l2-mem2mem: add request support

2017-12-14 Thread Alexandre Courbot
Support request API in the mem2mem framework. Drivers that specify ops
for the queue and entities can support requests seamlessly.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 34 ++
 include/media/v4l2-mem2mem.h   | 19 +++
 2 files changed, 53 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index f62e68aa04c4..eb52bee8e06a 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("Mem to mem device framework for videobuf");
 MODULE_AUTHOR("Pawel Osciak, ");
@@ -219,6 +220,15 @@ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
m2m_dev = m2m_ctx->m2m_dev;
dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   /* request is completed if all queues are done with it */
+   if (m2m_ctx->req_queue && m2m_ctx->req_queue->active_request &&
+   m2m_ctx->cap_q_ctx.q.cur_req == NULL &&
+   m2m_ctx->out_q_ctx.q.cur_req == NULL)
+   media_request_entity_complete(m2m_ctx->req_queue,
+ m2m_ctx->entity);
+#endif
+
if (!m2m_ctx->out_q_ctx.q.streaming
|| !m2m_ctx->cap_q_ctx.q.streaming) {
dprintk("Streaming needs to be on for both queues\n");
@@ -665,6 +675,15 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev 
*m2m_dev,
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init);
 
+void v4l2_mem_ctx_request_init(struct v4l2_m2m_ctx *ctx,
+  struct media_request_queue *req_queue,
+  struct media_entity *entity)
+{
+   ctx->entity = entity;
+   ctx->req_queue = req_queue;
+}
+EXPORT_SYMBOL_GPL(v4l2_mem_ctx_request_init);
+
 void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
 {
/* wait until the current context is dequeued from job_queue */
@@ -810,3 +829,18 @@ unsigned int v4l2_m2m_fop_poll(struct file *file, 
poll_table *wait)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_fop_poll);
 
+int v4l2_m2m_process_request(struct media_request *req,
+struct media_request_entity_data *data)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct v4l2_fh *fh = data->fh;
+   struct v4l2_m2m_ctx *ctx = fh->m2m_ctx;
+
+   vb2_queue_start_request(>cap_q_ctx.q, req);
+   vb2_queue_start_request(>out_q_ctx.q, req);
+
+   v4l2_m2m_try_schedule(ctx);
+#endif
+   return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_process_request);
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index e157d5c9b224..1c9925c3d4ce 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -19,6 +19,10 @@
 
 #include 
 
+struct media_entity;
+struct media_request;
+struct media_request_entity_data;
+
 /**
  * struct v4l2_m2m_ops - mem-to-mem device driver callbacks
  * @device_run:required. Begin the actual job (transaction) inside this
@@ -83,6 +87,7 @@ struct v4l2_m2m_queue_ctx {
  *
  * @q_lock: struct  lock
  * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ * @state: Pointer to state handler for channel support
  * @cap_q_ctx: Capture (output to memory) queue context
  * @out_q_ctx: Output (input from memory) queue context
  * @queue: List of memory to memory contexts
@@ -100,6 +105,8 @@ struct v4l2_m2m_ctx {
 
/* internal use only */
struct v4l2_m2m_dev *m2m_dev;
+   struct media_request_queue  *req_queue;
+   struct media_entity *entity;
 
struct v4l2_m2m_queue_ctx   cap_q_ctx;
 
@@ -351,6 +358,16 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev 
*m2m_dev,
void *drv_priv,
int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct 
vb2_queue *dst_vq));
 
+/**
+ * v4l2_mem_ctx_request_init() - enable a context to be used with requests
+ *
+ * @ctx: context to potentially use within a channel
+ * @req_queue: request queue that will be used with this context
+ */
+void v4l2_mem_ctx_request_init(struct v4l2_m2m_ctx *ctx,
+  struct media_request_queue *req_queue,
+  struct media_entity *entity);
+
 static inline void v4l2_m2m_set_src_buffered(struct v4l2_m2m_ctx *m2m_ctx,
 bool buffered)
 {
@@ -602,6 +619,8 @@ int v4l2_m2m_ioctl_streamoff(struct file *file, void *fh,
enum v4l2_buf_type type);
 int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma);
 unsigned int v4l2_m2m_fop_poll(struct file *file, poll_table *wait);
+int v4l2_m2m_process_request(struct media_request *req,
+struct media_request_entity_data *data);
 
 #endif /* 

[RFC PATCH 7/9] media: v4l2-mem2mem: add request support

2017-12-14 Thread Alexandre Courbot
Support request API in the mem2mem framework. Drivers that specify ops
for the queue and entities can support requests seamlessly.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 34 ++
 include/media/v4l2-mem2mem.h   | 19 +++
 2 files changed, 53 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index f62e68aa04c4..eb52bee8e06a 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("Mem to mem device framework for videobuf");
 MODULE_AUTHOR("Pawel Osciak, ");
@@ -219,6 +220,15 @@ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
m2m_dev = m2m_ctx->m2m_dev;
dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   /* request is completed if all queues are done with it */
+   if (m2m_ctx->req_queue && m2m_ctx->req_queue->active_request &&
+   m2m_ctx->cap_q_ctx.q.cur_req == NULL &&
+   m2m_ctx->out_q_ctx.q.cur_req == NULL)
+   media_request_entity_complete(m2m_ctx->req_queue,
+ m2m_ctx->entity);
+#endif
+
if (!m2m_ctx->out_q_ctx.q.streaming
|| !m2m_ctx->cap_q_ctx.q.streaming) {
dprintk("Streaming needs to be on for both queues\n");
@@ -665,6 +675,15 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev 
*m2m_dev,
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init);
 
+void v4l2_mem_ctx_request_init(struct v4l2_m2m_ctx *ctx,
+  struct media_request_queue *req_queue,
+  struct media_entity *entity)
+{
+   ctx->entity = entity;
+   ctx->req_queue = req_queue;
+}
+EXPORT_SYMBOL_GPL(v4l2_mem_ctx_request_init);
+
 void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
 {
/* wait until the current context is dequeued from job_queue */
@@ -810,3 +829,18 @@ unsigned int v4l2_m2m_fop_poll(struct file *file, 
poll_table *wait)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_fop_poll);
 
+int v4l2_m2m_process_request(struct media_request *req,
+struct media_request_entity_data *data)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct v4l2_fh *fh = data->fh;
+   struct v4l2_m2m_ctx *ctx = fh->m2m_ctx;
+
+   vb2_queue_start_request(>cap_q_ctx.q, req);
+   vb2_queue_start_request(>out_q_ctx.q, req);
+
+   v4l2_m2m_try_schedule(ctx);
+#endif
+   return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_process_request);
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index e157d5c9b224..1c9925c3d4ce 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -19,6 +19,10 @@
 
 #include 
 
+struct media_entity;
+struct media_request;
+struct media_request_entity_data;
+
 /**
  * struct v4l2_m2m_ops - mem-to-mem device driver callbacks
  * @device_run:required. Begin the actual job (transaction) inside this
@@ -83,6 +87,7 @@ struct v4l2_m2m_queue_ctx {
  *
  * @q_lock: struct  lock
  * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ * @state: Pointer to state handler for channel support
  * @cap_q_ctx: Capture (output to memory) queue context
  * @out_q_ctx: Output (input from memory) queue context
  * @queue: List of memory to memory contexts
@@ -100,6 +105,8 @@ struct v4l2_m2m_ctx {
 
/* internal use only */
struct v4l2_m2m_dev *m2m_dev;
+   struct media_request_queue  *req_queue;
+   struct media_entity *entity;
 
struct v4l2_m2m_queue_ctx   cap_q_ctx;
 
@@ -351,6 +358,16 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev 
*m2m_dev,
void *drv_priv,
int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct 
vb2_queue *dst_vq));
 
+/**
+ * v4l2_mem_ctx_request_init() - enable a context to be used with requests
+ *
+ * @ctx: context to potentially use within a channel
+ * @req_queue: request queue that will be used with this context
+ */
+void v4l2_mem_ctx_request_init(struct v4l2_m2m_ctx *ctx,
+  struct media_request_queue *req_queue,
+  struct media_entity *entity);
+
 static inline void v4l2_m2m_set_src_buffered(struct v4l2_m2m_ctx *m2m_ctx,
 bool buffered)
 {
@@ -602,6 +619,8 @@ int v4l2_m2m_ioctl_streamoff(struct file *file, void *fh,
enum v4l2_buf_type type);
 int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma);
 unsigned int v4l2_m2m_fop_poll(struct file *file, poll_table *wait);
+int v4l2_m2m_process_request(struct media_request *req,
+struct media_request_entity_data *data);
 
 #endif /* _MEDIA_V4L2_MEM2MEM_H */
 
-- 

[RFC PATCH 1/9] media: add request API core and UAPI

2017-12-14 Thread Alexandre Courbot
The request API provides a way to group buffers and device parameters
into units of work to be queued and executed. This patch introduces the
UAPI and core framework.

This patch is based on the previous work by Laurent Pinchart. The core
has changed considerably, but the UAPI is mostly untouched.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/Makefile   |   3 +-
 drivers/media/media-device.c |   6 +
 drivers/media/media-request.c| 390 +++
 drivers/media/v4l2-core/v4l2-ioctl.c |   2 +-
 include/media/media-device.h |   3 +
 include/media/media-entity.h |   6 +
 include/media/media-request.h| 269 
 include/uapi/linux/media.h   |  11 +
 8 files changed, 688 insertions(+), 2 deletions(-)
 create mode 100644 drivers/media/media-request.c
 create mode 100644 include/media/media-request.h

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 594b462ddf0e..985d35ec6b29 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -3,7 +3,8 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-media-objs := media-device.o media-devnode.o media-entity.o
+media-objs := media-device.o media-devnode.o media-entity.o \
+  media-request.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index e79f72b8b858..045cec7d2de9 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_MEDIA_CONTROLLER
 
@@ -407,6 +408,7 @@ static const struct media_ioctl_info ioctl_info[] = {
MEDIA_IOC(ENUM_LINKS, media_device_enum_links, 
MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(SETUP_LINK, media_device_setup_link, 
MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, 
MEDIA_IOC_FL_GRAPH_MUTEX),
+   MEDIA_IOC(REQUEST_CMD, media_device_request_cmd, 0),
 };
 
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
@@ -688,6 +690,10 @@ EXPORT_SYMBOL_GPL(media_device_init);
 
 void media_device_cleanup(struct media_device *mdev)
 {
+   if (mdev->req_queue) {
+   mdev->req_queue->ops->release(mdev->req_queue);
+   mdev->req_queue = NULL;
+   }
ida_destroy(>entity_internal_idx);
mdev->entity_internal_idx_max = 0;
media_graph_walk_cleanup(>pm_count_walk);
diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
new file mode 100644
index ..15dc65ddfe41
--- /dev/null
+++ b/drivers/media/media-request.c
@@ -0,0 +1,390 @@
+/*
+ * Request and request queue base management
+ *
+ * Copyright (C) 2017, The Chromium OS Authors.  All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+const struct file_operations request_fops;
+
+void media_request_get(struct media_request *req)
+{
+   kref_get(>kref);
+}
+EXPORT_SYMBOL_GPL(media_request_get);
+
+struct media_request *
+media_request_get_from_fd(int fd)
+{
+   struct file *f;
+   struct media_request *req;
+
+   f = fget(fd);
+   if (!f)
+   return NULL;
+
+   /* Not a request FD? */
+   if (f->f_op != _fops) {
+   fput(f);
+   return NULL;
+   }
+
+   req = f->private_data;
+   media_request_get(req);
+   fput(f);
+
+   return req;
+}
+EXPORT_SYMBOL_GPL(media_request_get_from_fd);
+
+static void media_request_release(struct kref *kref)
+{
+   struct media_request_entity_data *data, *next;
+   struct media_request *req =
+   container_of(kref, typeof(*req), kref);
+   struct media_device *mdev = req->queue->mdev;
+
+   dev_dbg(mdev->dev, "%s: releasing request %u\n", __func__, req->id);
+
+   list_del(>list);
+   list_for_each_entry_safe(data, next, >data, list) {
+   list_del(>list);
+   data->entity->req_ops->release_data(data);
+   }
+
+   req->queue->ops->req_free(req->queue, req);
+}
+
+void media_request_put(struct media_request *req)
+{
+   kref_put(>kref, media_request_release);
+}
+EXPORT_SYMBOL_GPL(media_request_put);
+
+struct media_request_entity_data *
+media_request_get_entity_data(struct media_request *req,
+ struct media_entity *entity, void *fh)
+{
+   struct 

[RFC PATCH 1/9] media: add request API core and UAPI

2017-12-14 Thread Alexandre Courbot
The request API provides a way to group buffers and device parameters
into units of work to be queued and executed. This patch introduces the
UAPI and core framework.

This patch is based on the previous work by Laurent Pinchart. The core
has changed considerably, but the UAPI is mostly untouched.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/Makefile   |   3 +-
 drivers/media/media-device.c |   6 +
 drivers/media/media-request.c| 390 +++
 drivers/media/v4l2-core/v4l2-ioctl.c |   2 +-
 include/media/media-device.h |   3 +
 include/media/media-entity.h |   6 +
 include/media/media-request.h| 269 
 include/uapi/linux/media.h   |  11 +
 8 files changed, 688 insertions(+), 2 deletions(-)
 create mode 100644 drivers/media/media-request.c
 create mode 100644 include/media/media-request.h

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 594b462ddf0e..985d35ec6b29 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -3,7 +3,8 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-media-objs := media-device.o media-devnode.o media-entity.o
+media-objs := media-device.o media-devnode.o media-entity.o \
+  media-request.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index e79f72b8b858..045cec7d2de9 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_MEDIA_CONTROLLER
 
@@ -407,6 +408,7 @@ static const struct media_ioctl_info ioctl_info[] = {
MEDIA_IOC(ENUM_LINKS, media_device_enum_links, 
MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(SETUP_LINK, media_device_setup_link, 
MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, 
MEDIA_IOC_FL_GRAPH_MUTEX),
+   MEDIA_IOC(REQUEST_CMD, media_device_request_cmd, 0),
 };
 
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
@@ -688,6 +690,10 @@ EXPORT_SYMBOL_GPL(media_device_init);
 
 void media_device_cleanup(struct media_device *mdev)
 {
+   if (mdev->req_queue) {
+   mdev->req_queue->ops->release(mdev->req_queue);
+   mdev->req_queue = NULL;
+   }
ida_destroy(>entity_internal_idx);
mdev->entity_internal_idx_max = 0;
media_graph_walk_cleanup(>pm_count_walk);
diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
new file mode 100644
index ..15dc65ddfe41
--- /dev/null
+++ b/drivers/media/media-request.c
@@ -0,0 +1,390 @@
+/*
+ * Request and request queue base management
+ *
+ * Copyright (C) 2017, The Chromium OS Authors.  All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+const struct file_operations request_fops;
+
+void media_request_get(struct media_request *req)
+{
+   kref_get(>kref);
+}
+EXPORT_SYMBOL_GPL(media_request_get);
+
+struct media_request *
+media_request_get_from_fd(int fd)
+{
+   struct file *f;
+   struct media_request *req;
+
+   f = fget(fd);
+   if (!f)
+   return NULL;
+
+   /* Not a request FD? */
+   if (f->f_op != _fops) {
+   fput(f);
+   return NULL;
+   }
+
+   req = f->private_data;
+   media_request_get(req);
+   fput(f);
+
+   return req;
+}
+EXPORT_SYMBOL_GPL(media_request_get_from_fd);
+
+static void media_request_release(struct kref *kref)
+{
+   struct media_request_entity_data *data, *next;
+   struct media_request *req =
+   container_of(kref, typeof(*req), kref);
+   struct media_device *mdev = req->queue->mdev;
+
+   dev_dbg(mdev->dev, "%s: releasing request %u\n", __func__, req->id);
+
+   list_del(>list);
+   list_for_each_entry_safe(data, next, >data, list) {
+   list_del(>list);
+   data->entity->req_ops->release_data(data);
+   }
+
+   req->queue->ops->req_free(req->queue, req);
+}
+
+void media_request_put(struct media_request *req)
+{
+   kref_put(>kref, media_request_release);
+}
+EXPORT_SYMBOL_GPL(media_request_put);
+
+struct media_request_entity_data *
+media_request_get_entity_data(struct media_request *req,
+ struct media_entity *entity, void *fh)
+{
+   struct media_request_queue *queue = 

[RFC PATCH 0/9] media: base request API support

2017-12-14 Thread Alexandre Courbot
Here is a new attempt at the request API, following the UAPI we agreed on in
Prague. Hopefully this can be used as the basis to move forward.

This series only introduces the very basics of how requests work: allocate a
request, queue buffers to it, queue the request itself, wait for it to complete,
reuse it. It does *not* yet use Hans' work with controls setting. I have
preferred to submit it this way for now as it allows us to concentrate on the
basic request/buffer flow, which was harder to get properly than I initially
thought. I still have a gut feeling that it can be improved, with less back-and-
forth into drivers.

Plugging in controls support should not be too hard a task (basically just apply
the saved controls when the request starts), and I am looking at it now.

The resulting vim2m driver can be successfully used with requests, and my tests
so far have been successful.

There are still some rougher edges:

* locking is currently quite coarse-grained
* too many #ifdef CONFIG_MEDIA_CONTROLLER in the code, as the request API
  depends on it - I plan to craft the headers so that it becomes unnecessary.
  As it is, some of the code will probably not even compile if
  CONFIG_MEDIA_CONTROLLER is not set

But all in all I think the request flow should be clear and easy to review, and
the possibility of custom queue and entity support implementations should give
us the flexibility we need to support more specific use-cases (I expect the
generic implementations to be sufficient most of the time though).

A very simple test program exercising this API is available here (don't forget
to adapt the /dev/media0 hardcoding):
https://gist.github.com/Gnurou/dbc3776ed97ea7d4ce6041ea15eb0438

Looking forward to your feedback and comments!

Alexandre Courbot (8):
  media: add request API core and UAPI
  media: request: add generic queue
  media: request: add generic entity ops
  media: vb2: add support for requests
  media: vb2: add support for requests in QBUF ioctl
  media: v4l2-mem2mem: add request support
  media: vim2m: add media device
  media: vim2m: add request support

Hans Verkuil (1):
  videodev2.h: Add request field to v4l2_buffer

 drivers/media/Makefile|   4 +-
 drivers/media/media-device.c  |   6 +
 drivers/media/media-request-entity-generic.c  |  56 
 drivers/media/media-request-queue-generic.c   | 150 ++
 drivers/media/media-request.c | 390 ++
 drivers/media/platform/vim2m.c|  46 +++
 drivers/media/usb/cpia2/cpia2_v4l.c   |   2 +-
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |   7 +-
 drivers/media/v4l2-core/v4l2-ioctl.c  |  99 ++-
 drivers/media/v4l2-core/v4l2-mem2mem.c|  34 +++
 drivers/media/v4l2-core/videobuf2-core.c  |  59 +++-
 drivers/media/v4l2-core/videobuf2-v4l2.c  |  32 ++-
 include/media/media-device.h  |   3 +
 include/media/media-entity.h  |   6 +
 include/media/media-request.h | 282 +++
 include/media/v4l2-mem2mem.h  |  19 ++
 include/media/videobuf2-core.h|  25 +-
 include/media/videobuf2-v4l2.h|   2 +
 include/uapi/linux/media.h|  11 +
 include/uapi/linux/videodev2.h|   3 +-
 20 files changed, 1216 insertions(+), 20 deletions(-)
 create mode 100644 drivers/media/media-request-entity-generic.c
 create mode 100644 drivers/media/media-request-queue-generic.c
 create mode 100644 drivers/media/media-request.c
 create mode 100644 include/media/media-request.h

-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 0/9] media: base request API support

2017-12-14 Thread Alexandre Courbot
Here is a new attempt at the request API, following the UAPI we agreed on in
Prague. Hopefully this can be used as the basis to move forward.

This series only introduces the very basics of how requests work: allocate a
request, queue buffers to it, queue the request itself, wait for it to complete,
reuse it. It does *not* yet use Hans' work with controls setting. I have
preferred to submit it this way for now as it allows us to concentrate on the
basic request/buffer flow, which was harder to get properly than I initially
thought. I still have a gut feeling that it can be improved, with less back-and-
forth into drivers.

Plugging in controls support should not be too hard a task (basically just apply
the saved controls when the request starts), and I am looking at it now.

The resulting vim2m driver can be successfully used with requests, and my tests
so far have been successful.

There are still some rougher edges:

* locking is currently quite coarse-grained
* too many #ifdef CONFIG_MEDIA_CONTROLLER in the code, as the request API
  depends on it - I plan to craft the headers so that it becomes unnecessary.
  As it is, some of the code will probably not even compile if
  CONFIG_MEDIA_CONTROLLER is not set

But all in all I think the request flow should be clear and easy to review, and
the possibility of custom queue and entity support implementations should give
us the flexibility we need to support more specific use-cases (I expect the
generic implementations to be sufficient most of the time though).

A very simple test program exercising this API is available here (don't forget
to adapt the /dev/media0 hardcoding):
https://gist.github.com/Gnurou/dbc3776ed97ea7d4ce6041ea15eb0438

Looking forward to your feedback and comments!

Alexandre Courbot (8):
  media: add request API core and UAPI
  media: request: add generic queue
  media: request: add generic entity ops
  media: vb2: add support for requests
  media: vb2: add support for requests in QBUF ioctl
  media: v4l2-mem2mem: add request support
  media: vim2m: add media device
  media: vim2m: add request support

Hans Verkuil (1):
  videodev2.h: Add request field to v4l2_buffer

 drivers/media/Makefile|   4 +-
 drivers/media/media-device.c  |   6 +
 drivers/media/media-request-entity-generic.c  |  56 
 drivers/media/media-request-queue-generic.c   | 150 ++
 drivers/media/media-request.c | 390 ++
 drivers/media/platform/vim2m.c|  46 +++
 drivers/media/usb/cpia2/cpia2_v4l.c   |   2 +-
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |   7 +-
 drivers/media/v4l2-core/v4l2-ioctl.c  |  99 ++-
 drivers/media/v4l2-core/v4l2-mem2mem.c|  34 +++
 drivers/media/v4l2-core/videobuf2-core.c  |  59 +++-
 drivers/media/v4l2-core/videobuf2-v4l2.c  |  32 ++-
 include/media/media-device.h  |   3 +
 include/media/media-entity.h  |   6 +
 include/media/media-request.h | 282 +++
 include/media/v4l2-mem2mem.h  |  19 ++
 include/media/videobuf2-core.h|  25 +-
 include/media/videobuf2-v4l2.h|   2 +
 include/uapi/linux/media.h|  11 +
 include/uapi/linux/videodev2.h|   3 +-
 20 files changed, 1216 insertions(+), 20 deletions(-)
 create mode 100644 drivers/media/media-request-entity-generic.c
 create mode 100644 drivers/media/media-request-queue-generic.c
 create mode 100644 drivers/media/media-request.c
 create mode 100644 include/media/media-request.h

-- 
2.15.1.504.g5279b80103-goog



Re: [PATCH v2 01/17] mm/gup: Fixup p*_access_permitted()

2017-12-14 Thread Peter Zijlstra
On Thu, Dec 14, 2017 at 10:09:24PM -0800, Linus Torvalds wrote:
> On Dec 14, 2017 21:04, "Dave Hansen"  wrote:
> Can we please just undo that broken crap instead of trying to "fix" it?
> 
> It was wrong. We absolutely do not want to complicate the gup path.
> 
> Let's fet rid of those broken p??_access_permited() things.

So we actually need the pte_access_permitted() stuff if we want to
ensure we're not stepping on !PAGE_USER things.




Re: [PATCH v2 01/17] mm/gup: Fixup p*_access_permitted()

2017-12-14 Thread Peter Zijlstra
On Thu, Dec 14, 2017 at 10:09:24PM -0800, Linus Torvalds wrote:
> On Dec 14, 2017 21:04, "Dave Hansen"  wrote:
> Can we please just undo that broken crap instead of trying to "fix" it?
> 
> It was wrong. We absolutely do not want to complicate the gup path.
> 
> Let's fet rid of those broken p??_access_permited() things.

So we actually need the pte_access_permitted() stuff if we want to
ensure we're not stepping on !PAGE_USER things.




[PATCH 04/27] clocksource/arm_arch_timer: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update arch_timer_kvm_info
timecounter init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Mark Rutland 
Cc: Marc Zyngier 
Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/clocksource/arm_arch_timer.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c 
b/drivers/clocksource/arm_arch_timer.c
index 31543e5..d96393f 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -910,10 +910,7 @@ static u64 arch_counter_get_cntvct_mem(void)
return ((u64) vct_hi << 32) | vct_lo;
 }
 
-static struct arch_timer_kvm_info arch_timer_kvm_info = {
-   .timecounter.cc.read = arch_counter_read_cc,
-   .timecounter.cc.mask = CLOCKSOURCE_MASK(56),
-};
+static struct arch_timer_kvm_info arch_timer_kvm_info;
 
 struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 {
@@ -923,7 +920,6 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 static void __init arch_counter_register(unsigned type)
 {
u64 start_count;
-   struct cyclecounter *cc = _timer_kvm_info.timecounter.cc;
 
/* Register the CP15 based counter if we have one */
if (type & ARCH_TIMER_TYPE_CP15) {
@@ -943,9 +939,12 @@ static void __init arch_counter_register(unsigned type)
start_count = arch_timer_read_counter();
clocksource_register_hz(_counter, arch_timer_rate);
 
-   cc->mult = clocksource_counter.mult;
-   cc->shift = clocksource_counter.shift;
-   timecounter_init(_timer_kvm_info.timecounter, start_count);
+   timecounter_initialize(_timer_kvm_info.timecounter,
+  arch_counter_read_cc,
+  CLOCKSOURCE_MASK(56),
+  clocksource_counter.mult,
+  clocksource_counter.shift,
+  start_count);
 
/* 56 bits minimum, so we assume worst case rollover */
sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
-- 
1.9.1



[PATCH 04/27] clocksource/arm_arch_timer: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update arch_timer_kvm_info
timecounter init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Mark Rutland 
Cc: Marc Zyngier 
Cc: Daniel Lezcano 
Cc: Thomas Gleixner 
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/clocksource/arm_arch_timer.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c 
b/drivers/clocksource/arm_arch_timer.c
index 31543e5..d96393f 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -910,10 +910,7 @@ static u64 arch_counter_get_cntvct_mem(void)
return ((u64) vct_hi << 32) | vct_lo;
 }
 
-static struct arch_timer_kvm_info arch_timer_kvm_info = {
-   .timecounter.cc.read = arch_counter_read_cc,
-   .timecounter.cc.mask = CLOCKSOURCE_MASK(56),
-};
+static struct arch_timer_kvm_info arch_timer_kvm_info;
 
 struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 {
@@ -923,7 +920,6 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 static void __init arch_counter_register(unsigned type)
 {
u64 start_count;
-   struct cyclecounter *cc = _timer_kvm_info.timecounter.cc;
 
/* Register the CP15 based counter if we have one */
if (type & ARCH_TIMER_TYPE_CP15) {
@@ -943,9 +939,12 @@ static void __init arch_counter_register(unsigned type)
start_count = arch_timer_read_counter();
clocksource_register_hz(_counter, arch_timer_rate);
 
-   cc->mult = clocksource_counter.mult;
-   cc->shift = clocksource_counter.shift;
-   timecounter_init(_timer_kvm_info.timecounter, start_count);
+   timecounter_initialize(_timer_kvm_info.timecounter,
+  arch_counter_read_cc,
+  CLOCKSOURCE_MASK(56),
+  clocksource_counter.mult,
+  clocksource_counter.shift,
+  start_count);
 
/* 56 bits minimum, so we assume worst case rollover */
sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
-- 
1.9.1



[PATCH 05/27] amd-xgbe: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update xgbe tstamp_tc
timecounter init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Tom Lendacky 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
index 5ea4edf..486437b 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
@@ -228,7 +228,6 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
 {
struct ptp_clock_info *info = >ptp_clock_info;
struct ptp_clock *clock;
-   struct cyclecounter *cc = >tstamp_tc.cc;
u64 dividend;
 
snprintf(info->name, sizeof(info->name), "%s",
@@ -258,12 +257,12 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate);
 
/* Setup the timecounter */
-   cc->read = xgbe_cc_read;
-   cc->mask = CLOCKSOURCE_MASK(64);
-   cc->mult = 1;
-   cc->shift = 0;
-
-   timecounter_init(>tstamp_tc, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>tstamp_tc,
+  xgbe_cc_read,
+  CLOCKSOURCE_MASK(64),
+  1,
+  0,
+  ktime_to_ns(ktime_get_real()));
 
/* Disable all timestamping to start */
XGMAC_IOWRITE(pdata, MAC_TSCR, 0);
-- 
1.9.1



[PATCH 05/27] amd-xgbe: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update xgbe tstamp_tc
timecounter init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Tom Lendacky 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
index 5ea4edf..486437b 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
@@ -228,7 +228,6 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
 {
struct ptp_clock_info *info = >ptp_clock_info;
struct ptp_clock *clock;
-   struct cyclecounter *cc = >tstamp_tc.cc;
u64 dividend;
 
snprintf(info->name, sizeof(info->name), "%s",
@@ -258,12 +257,12 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate);
 
/* Setup the timecounter */
-   cc->read = xgbe_cc_read;
-   cc->mask = CLOCKSOURCE_MASK(64);
-   cc->mult = 1;
-   cc->shift = 0;
-
-   timecounter_init(>tstamp_tc, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>tstamp_tc,
+  xgbe_cc_read,
+  CLOCKSOURCE_MASK(64),
+  1,
+  0,
+  ktime_to_ns(ktime_get_real()));
 
/* Disable all timestamping to start */
XGMAC_IOWRITE(pdata, MAC_TSCR, 0);
-- 
1.9.1



[PATCH 07/27] fec: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update fec ethernet
timecounter init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Fugang Duan 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/freescale/fec_ptp.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_ptp.c 
b/drivers/net/ethernet/freescale/fec_ptp.c
index b1261d1..1ba7216 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -278,14 +278,13 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
writel(FEC_T_CTRL_ENABLE | FEC_T_CTRL_PERIOD_RST,
fep->hwp + FEC_ATIME_CTRL);
 
-   memset(>tc.cc, 0, sizeof(fep->tc.cc));
-   fep->tc.cc.read = fec_ptp_read;
-   fep->tc.cc.mask = CLOCKSOURCE_MASK(31);
-   fep->tc.cc.shift = 31;
-   fep->tc.cc.mult = FEC_CC_MULT;
-
-   /* reset the ns time counter */
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   /* Initialize the ns time counter */
+   timecounter_initialize(>tc,
+  fec_ptp_read,
+  CLOCKSOURCE_MASK(31),
+  FEC_CC_MULT,
+  31,
+  ktime_to_ns(ktime_get_real()));
 
spin_unlock_irqrestore(>tmreg_lock, flags);
 }
-- 
1.9.1



Re: [PATCH] exit: move exit_task_namespaces() after exit_task_work()

2017-12-14 Thread Dmitry Vyukov
On Fri, Dec 15, 2017 at 7:56 AM, Eric W. Biederman
 wrote:
> Cong Wang  writes:
>
>> syzbot reported we have a use-after-free when mqueue_evict_inode()
>> is called on __cleanup_mnt() path, where the ipc ns is already
>> freed by the previous exit_task_namespaces(). We can just move
>> it after after exit_task_work() to avoid this use-after-free.
>
> How does that possibly work. (I haven't seen this syzbot report).
>
> Looking at the code we have get_ns_from_inode.  Which takes the mq_lock,
> sees if the pointer is NULL and takes a reference if it is non-NULL.
>
> Meanwhile put_ipc_ns calls mq_clear_sbinfo(ns) with the mq_lock held
> when the count drops to zero.
>
> Where is the race in that?
>
> The rest of mqueue_evict_inode uses the returned pointer and
> tests that the pointer is non-NULL before user it.
>
> So either szbot is giving you a bad report or there is a subtle race
> there I am not seeing.  The change below is not at all the proper way to
> fix a subtle race.
>
> Eric

Cong, what was that report? Searching by
"exit_task_work|exit_task_namespaces" there are too many of them:
https://groups.google.com/forum/#!searchin/syzkaller-bugs/%22exit_task_work$7Cexit_task_namespaces%22%7Csort:date

I can only say that syzbot does not make up reports. That's something
that actually happened and was provoked by userspace.



>> Reported-by: syzbot 
>> Cc: Ingo Molnar 
>> Cc: Al Viro 
>> Cc: Andrew Morton 
>> Cc: Linus Torvalds 
>> Cc: sta...@vger.kernel.org
>> Signed-off-by: Cong Wang 
>> ---
>>  kernel/exit.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/kernel/exit.c b/kernel/exit.c
>> index 6b4298a41167..909e43c45158 100644
>> --- a/kernel/exit.c
>> +++ b/kernel/exit.c
>> @@ -861,8 +861,8 @@ void __noreturn do_exit(long code)
>>   exit_fs(tsk);
>>   if (group_dead)
>>   disassociate_ctty(1);
>> - exit_task_namespaces(tsk);
>>   exit_task_work(tsk);
>> + exit_task_namespaces(tsk);
>>   exit_thread(tsk);
>>
>>   /*


[PATCH 07/27] fec: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update fec ethernet
timecounter init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Fugang Duan 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/freescale/fec_ptp.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_ptp.c 
b/drivers/net/ethernet/freescale/fec_ptp.c
index b1261d1..1ba7216 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -278,14 +278,13 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
writel(FEC_T_CTRL_ENABLE | FEC_T_CTRL_PERIOD_RST,
fep->hwp + FEC_ATIME_CTRL);
 
-   memset(>tc.cc, 0, sizeof(fep->tc.cc));
-   fep->tc.cc.read = fec_ptp_read;
-   fep->tc.cc.mask = CLOCKSOURCE_MASK(31);
-   fep->tc.cc.shift = 31;
-   fep->tc.cc.mult = FEC_CC_MULT;
-
-   /* reset the ns time counter */
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   /* Initialize the ns time counter */
+   timecounter_initialize(>tc,
+  fec_ptp_read,
+  CLOCKSOURCE_MASK(31),
+  FEC_CC_MULT,
+  31,
+  ktime_to_ns(ktime_get_real()));
 
spin_unlock_irqrestore(>tmreg_lock, flags);
 }
-- 
1.9.1



Re: [PATCH] exit: move exit_task_namespaces() after exit_task_work()

2017-12-14 Thread Dmitry Vyukov
On Fri, Dec 15, 2017 at 7:56 AM, Eric W. Biederman
 wrote:
> Cong Wang  writes:
>
>> syzbot reported we have a use-after-free when mqueue_evict_inode()
>> is called on __cleanup_mnt() path, where the ipc ns is already
>> freed by the previous exit_task_namespaces(). We can just move
>> it after after exit_task_work() to avoid this use-after-free.
>
> How does that possibly work. (I haven't seen this syzbot report).
>
> Looking at the code we have get_ns_from_inode.  Which takes the mq_lock,
> sees if the pointer is NULL and takes a reference if it is non-NULL.
>
> Meanwhile put_ipc_ns calls mq_clear_sbinfo(ns) with the mq_lock held
> when the count drops to zero.
>
> Where is the race in that?
>
> The rest of mqueue_evict_inode uses the returned pointer and
> tests that the pointer is non-NULL before user it.
>
> So either szbot is giving you a bad report or there is a subtle race
> there I am not seeing.  The change below is not at all the proper way to
> fix a subtle race.
>
> Eric

Cong, what was that report? Searching by
"exit_task_work|exit_task_namespaces" there are too many of them:
https://groups.google.com/forum/#!searchin/syzkaller-bugs/%22exit_task_work$7Cexit_task_namespaces%22%7Csort:date

I can only say that syzbot does not make up reports. That's something
that actually happened and was provoked by userspace.



>> Reported-by: syzbot 
>> Cc: Ingo Molnar 
>> Cc: Al Viro 
>> Cc: Andrew Morton 
>> Cc: Linus Torvalds 
>> Cc: sta...@vger.kernel.org
>> Signed-off-by: Cong Wang 
>> ---
>>  kernel/exit.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/kernel/exit.c b/kernel/exit.c
>> index 6b4298a41167..909e43c45158 100644
>> --- a/kernel/exit.c
>> +++ b/kernel/exit.c
>> @@ -861,8 +861,8 @@ void __noreturn do_exit(long code)
>>   exit_fs(tsk);
>>   if (group_dead)
>>   disassociate_ctty(1);
>> - exit_task_namespaces(tsk);
>>   exit_task_work(tsk);
>> + exit_task_namespaces(tsk);
>>   exit_thread(tsk);
>>
>>   /*


[PATCH 08/27] e1000e: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update e1000e timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/e1000e/e1000.h  |  4 
 drivers/net/ethernet/intel/e1000e/netdev.c | 31 +-
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h 
b/drivers/net/ethernet/intel/e1000e/e1000.h
index b59f82a..d6b0e59 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -341,6 +341,10 @@ struct e1000_adapter {
struct work_struct tx_hwtstamp_work;
spinlock_t systim_lock; /* protects SYSTIML/H regsters */
struct timecounter tc;
+   u64 (*cc_read)(const struct cyclecounter *cc);
+   u64 cc_mask;
+   u32 cc_mult;
+   u32 cc_shift;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_clock_info;
struct pm_qos_request pm_qos_req;
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c 
b/drivers/net/ethernet/intel/e1000e/netdev.c
index c9f7ba3..6be1327 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -3536,7 +3536,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter 
*adapter, u32 *timinca)
incperiod = INCPERIOD_96MHZ;
incvalue = INCVALUE_96MHZ;
shift = INCVALUE_SHIFT_96MHZ;
-   adapter->tc.cc.shift = shift + INCPERIOD_SHIFT_96MHZ;
+   adapter->cc_shift = shift + INCPERIOD_SHIFT_96MHZ;
break;
case e1000_pch_lpt:
if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) {
@@ -3544,13 +3544,13 @@ s32 e1000e_get_base_timinca(struct e1000_adapter 
*adapter, u32 *timinca)
incperiod = INCPERIOD_96MHZ;
incvalue = INCVALUE_96MHZ;
shift = INCVALUE_SHIFT_96MHZ;
-   adapter->tc.cc.shift = shift + INCPERIOD_SHIFT_96MHZ;
+   adapter->cc_shift = shift + INCPERIOD_SHIFT_96MHZ;
} else {
/* Stable 25MHz frequency */
incperiod = INCPERIOD_25MHZ;
incvalue = INCVALUE_25MHZ;
shift = INCVALUE_SHIFT_25MHZ;
-   adapter->tc.cc.shift = shift;
+   adapter->cc_shift = shift;
}
break;
case e1000_pch_spt:
@@ -3559,7 +3559,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter 
*adapter, u32 *timinca)
incperiod = INCPERIOD_24MHZ;
incvalue = INCVALUE_24MHZ;
shift = INCVALUE_SHIFT_24MHZ;
-   adapter->tc.cc.shift = shift;
+   adapter->cc_shift = shift;
break;
}
return -EINVAL;
@@ -3569,13 +3569,13 @@ s32 e1000e_get_base_timinca(struct e1000_adapter 
*adapter, u32 *timinca)
incperiod = INCPERIOD_24MHZ;
incvalue = INCVALUE_24MHZ;
shift = INCVALUE_SHIFT_24MHZ;
-   adapter->tc.cc.shift = shift;
+   adapter->cc_shift = shift;
} else {
/* Stable 38400KHz frequency */
incperiod = INCPERIOD_38400KHZ;
incvalue = INCVALUE_38400KHZ;
shift = INCVALUE_SHIFT_38400KHZ;
-   adapter->tc.cc.shift = shift;
+   adapter->cc_shift = shift;
}
break;
case e1000_82574:
@@ -3584,7 +3584,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter 
*adapter, u32 *timinca)
incperiod = INCPERIOD_25MHZ;
incvalue = INCVALUE_25MHZ;
shift = INCVALUE_SHIFT_25MHZ;
-   adapter->tc.cc.shift = shift;
+   adapter->cc_shift = shift;
break;
default:
return -EINVAL;
@@ -3953,9 +3953,14 @@ static void e1000e_systim_reset(struct e1000_adapter 
*adapter)
return;
}
 
-   /* reset the systim ns time counter */
+   /* reinitialize the systim ns time counter */
spin_lock_irqsave(>systim_lock, flags);
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>tc,
+  adapter->cc_read,
+  adapter->cc_mask,
+  adapter->cc_mult,
+  adapter->cc_shift,
+   

[PATCH 08/27] e1000e: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update e1000e timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/e1000e/e1000.h  |  4 
 drivers/net/ethernet/intel/e1000e/netdev.c | 31 +-
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h 
b/drivers/net/ethernet/intel/e1000e/e1000.h
index b59f82a..d6b0e59 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -341,6 +341,10 @@ struct e1000_adapter {
struct work_struct tx_hwtstamp_work;
spinlock_t systim_lock; /* protects SYSTIML/H regsters */
struct timecounter tc;
+   u64 (*cc_read)(const struct cyclecounter *cc);
+   u64 cc_mask;
+   u32 cc_mult;
+   u32 cc_shift;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_clock_info;
struct pm_qos_request pm_qos_req;
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c 
b/drivers/net/ethernet/intel/e1000e/netdev.c
index c9f7ba3..6be1327 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -3536,7 +3536,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter 
*adapter, u32 *timinca)
incperiod = INCPERIOD_96MHZ;
incvalue = INCVALUE_96MHZ;
shift = INCVALUE_SHIFT_96MHZ;
-   adapter->tc.cc.shift = shift + INCPERIOD_SHIFT_96MHZ;
+   adapter->cc_shift = shift + INCPERIOD_SHIFT_96MHZ;
break;
case e1000_pch_lpt:
if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) {
@@ -3544,13 +3544,13 @@ s32 e1000e_get_base_timinca(struct e1000_adapter 
*adapter, u32 *timinca)
incperiod = INCPERIOD_96MHZ;
incvalue = INCVALUE_96MHZ;
shift = INCVALUE_SHIFT_96MHZ;
-   adapter->tc.cc.shift = shift + INCPERIOD_SHIFT_96MHZ;
+   adapter->cc_shift = shift + INCPERIOD_SHIFT_96MHZ;
} else {
/* Stable 25MHz frequency */
incperiod = INCPERIOD_25MHZ;
incvalue = INCVALUE_25MHZ;
shift = INCVALUE_SHIFT_25MHZ;
-   adapter->tc.cc.shift = shift;
+   adapter->cc_shift = shift;
}
break;
case e1000_pch_spt:
@@ -3559,7 +3559,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter 
*adapter, u32 *timinca)
incperiod = INCPERIOD_24MHZ;
incvalue = INCVALUE_24MHZ;
shift = INCVALUE_SHIFT_24MHZ;
-   adapter->tc.cc.shift = shift;
+   adapter->cc_shift = shift;
break;
}
return -EINVAL;
@@ -3569,13 +3569,13 @@ s32 e1000e_get_base_timinca(struct e1000_adapter 
*adapter, u32 *timinca)
incperiod = INCPERIOD_24MHZ;
incvalue = INCVALUE_24MHZ;
shift = INCVALUE_SHIFT_24MHZ;
-   adapter->tc.cc.shift = shift;
+   adapter->cc_shift = shift;
} else {
/* Stable 38400KHz frequency */
incperiod = INCPERIOD_38400KHZ;
incvalue = INCVALUE_38400KHZ;
shift = INCVALUE_SHIFT_38400KHZ;
-   adapter->tc.cc.shift = shift;
+   adapter->cc_shift = shift;
}
break;
case e1000_82574:
@@ -3584,7 +3584,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter 
*adapter, u32 *timinca)
incperiod = INCPERIOD_25MHZ;
incvalue = INCVALUE_25MHZ;
shift = INCVALUE_SHIFT_25MHZ;
-   adapter->tc.cc.shift = shift;
+   adapter->cc_shift = shift;
break;
default:
return -EINVAL;
@@ -3953,9 +3953,14 @@ static void e1000e_systim_reset(struct e1000_adapter 
*adapter)
return;
}
 
-   /* reset the systim ns time counter */
+   /* reinitialize the systim ns time counter */
spin_lock_irqsave(>systim_lock, flags);
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>tc,
+  adapter->cc_read,
+  adapter->cc_mask,
+  adapter->cc_mult,
+  adapter->cc_shift,
+  ktime_to_ns(ktime_get_real()));

[PATCH 03/27] microblaze: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update xilinx_tc init with
this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Michal Simek 
Cc: Daniel Lezcano 
Cc: Neil Armstrong 
Cc: Nicolai Stange 
Cc: Arnd Bergmann 
Cc: Rob Herring 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
---
 arch/microblaze/kernel/timer.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index b7f89e9..b32a896 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -204,20 +204,21 @@ static u64 xilinx_cc_read(const struct cyclecounter *cc)
return xilinx_read(NULL);
 }
 
-static struct timecounter xilinx_tc = {
-   .cc.read = xilinx_cc_read,
-   .cc.mask = CLOCKSOURCE_MASK(32),
-   .cc.mult = 0,
-   .cc.shift = 8,
-};
+static struct timecounter xilinx_tc;
 
 static int __init init_xilinx_timecounter(void)
 {
-   struct cyclecounter *cc = _tc.cc;
+   u32 mult = 0;
+   u32 shift = 8;
 
-   cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift);
+   mult = div_sc(timer_clock_freq, NSEC_PER_SEC, shift);
 
-   timecounter_init(_tc, sched_clock());
+   timecounter_initialize(_tc,
+  xilinx_cc_read,
+  CLOCKSOURCE_MASK(32),
+  mult,
+  shift,
+  sched_clock());
 
return 0;
 }
-- 
1.9.1



[PATCH 03/27] microblaze: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update xilinx_tc init with
this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Michal Simek 
Cc: Daniel Lezcano 
Cc: Neil Armstrong 
Cc: Nicolai Stange 
Cc: Arnd Bergmann 
Cc: Rob Herring 
Cc: Thomas Gleixner 
Cc: linux-kernel@vger.kernel.org
---
 arch/microblaze/kernel/timer.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index b7f89e9..b32a896 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -204,20 +204,21 @@ static u64 xilinx_cc_read(const struct cyclecounter *cc)
return xilinx_read(NULL);
 }
 
-static struct timecounter xilinx_tc = {
-   .cc.read = xilinx_cc_read,
-   .cc.mask = CLOCKSOURCE_MASK(32),
-   .cc.mult = 0,
-   .cc.shift = 8,
-};
+static struct timecounter xilinx_tc;
 
 static int __init init_xilinx_timecounter(void)
 {
-   struct cyclecounter *cc = _tc.cc;
+   u32 mult = 0;
+   u32 shift = 8;
 
-   cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift);
+   mult = div_sc(timer_clock_freq, NSEC_PER_SEC, shift);
 
-   timecounter_init(_tc, sched_clock());
+   timecounter_initialize(_tc,
+  xilinx_cc_read,
+  CLOCKSOURCE_MASK(32),
+  mult,
+  shift,
+  sched_clock());
 
return 0;
 }
-- 
1.9.1



[PATCH 11/27] net/mlx4: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update mlx4 timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Tariq Toukan 
Cc: net...@vger.kernel.org
Cc: linux-r...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/mellanox/mlx4/en_clock.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c 
b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
index 35987b5..dd736cc 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
@@ -264,6 +264,7 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
 {
struct mlx4_dev *dev = mdev->dev;
unsigned long flags;
+   u32 mult, shift;
 
/* mlx4_en_init_timestamp is called for each netdev.
 * mdev->ptp_clock is common for all ports, skip initialization if
@@ -274,17 +275,17 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
 
seqlock_init(>clock_lock);
 
-   memset(>clock.cc, 0, sizeof(mdev->clock.cc));
-   mdev->clock.cc.read = mlx4_en_read_clock;
-   mdev->clock.cc.mask = CLOCKSOURCE_MASK(48);
-   mdev->clock.cc.shift = freq_to_shift(dev->caps.hca_core_clock);
-   mdev->clock.cc.mult =
-   clocksource_khz2mult(1000 * dev->caps.hca_core_clock,
-mdev->clock.cc.shift);
+   shift = freq_to_shift(dev->caps.hca_core_clock);
+   mult = clocksource_khz2mult(1000 * dev->caps.hca_core_clock, shift);
mdev->nominal_c_mult = mdev->clock.cc.mult;
 
write_seqlock_irqsave(>clock_lock, flags);
-   timecounter_init(>clock, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>clock,
+  mlx4_en_read_clock,
+  CLOCKSOURCE_MASK(48),
+  mult,
+  shift,
+  ktime_to_ns(ktime_get_real()));
write_sequnlock_irqrestore(>clock_lock, flags);
 
/* Configure the PHC */
-- 
1.9.1



[PATCH 11/27] net/mlx4: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update mlx4 timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Tariq Toukan 
Cc: net...@vger.kernel.org
Cc: linux-r...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/mellanox/mlx4/en_clock.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c 
b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
index 35987b5..dd736cc 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
@@ -264,6 +264,7 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
 {
struct mlx4_dev *dev = mdev->dev;
unsigned long flags;
+   u32 mult, shift;
 
/* mlx4_en_init_timestamp is called for each netdev.
 * mdev->ptp_clock is common for all ports, skip initialization if
@@ -274,17 +275,17 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
 
seqlock_init(>clock_lock);
 
-   memset(>clock.cc, 0, sizeof(mdev->clock.cc));
-   mdev->clock.cc.read = mlx4_en_read_clock;
-   mdev->clock.cc.mask = CLOCKSOURCE_MASK(48);
-   mdev->clock.cc.shift = freq_to_shift(dev->caps.hca_core_clock);
-   mdev->clock.cc.mult =
-   clocksource_khz2mult(1000 * dev->caps.hca_core_clock,
-mdev->clock.cc.shift);
+   shift = freq_to_shift(dev->caps.hca_core_clock);
+   mult = clocksource_khz2mult(1000 * dev->caps.hca_core_clock, shift);
mdev->nominal_c_mult = mdev->clock.cc.mult;
 
write_seqlock_irqsave(>clock_lock, flags);
-   timecounter_init(>clock, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>clock,
+  mlx4_en_read_clock,
+  CLOCKSOURCE_MASK(48),
+  mult,
+  shift,
+  ktime_to_ns(ktime_get_real()));
write_sequnlock_irqrestore(>clock_lock, flags);
 
/* Configure the PHC */
-- 
1.9.1



[PATCH 06/27] bnx2x: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update bnx2x timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Ariel Elior 
Cc: everest-linux...@cavium.com
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 83624ad..1e10a81 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -15269,15 +15269,6 @@ static u64 bnx2x_cyclecounter_read(const struct 
cyclecounter *cc)
return phc_cycles;
 }
 
-static void bnx2x_init_cyclecounter(struct cyclecounter *cc)
-{
-   memset(cc, 0, sizeof(*cc));
-   cc->read = bnx2x_cyclecounter_read;
-   cc->mask = CYCLECOUNTER_MASK(64);
-   cc->shift = 0;
-   cc->mult = 1;
-}
-
 static int bnx2x_send_reset_timesync_ramrod(struct bnx2x *bp)
 {
struct bnx2x_func_state_params func_params = {NULL};
@@ -15511,9 +15502,12 @@ void bnx2x_init_ptp(struct bnx2x *bp)
 * unload / load (e.g. MTU change) while it is running.
 */
if (!bp->timecounter_init_done) {
-   bnx2x_init_cyclecounter(>timecounter.cc);
-   timecounter_init(>timecounter,
-ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>timecounter,
+  bnx2x_cyclecounter_read,
+  CYCLECOUNTER_MASK(64),
+  1,
+  0,
+  ktime_to_ns(ktime_get_real()));
bp->timecounter_init_done = 1;
}
 
-- 
1.9.1



[PATCH 06/27] bnx2x: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update bnx2x timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Ariel Elior 
Cc: everest-linux...@cavium.com
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 83624ad..1e10a81 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -15269,15 +15269,6 @@ static u64 bnx2x_cyclecounter_read(const struct 
cyclecounter *cc)
return phc_cycles;
 }
 
-static void bnx2x_init_cyclecounter(struct cyclecounter *cc)
-{
-   memset(cc, 0, sizeof(*cc));
-   cc->read = bnx2x_cyclecounter_read;
-   cc->mask = CYCLECOUNTER_MASK(64);
-   cc->shift = 0;
-   cc->mult = 1;
-}
-
 static int bnx2x_send_reset_timesync_ramrod(struct bnx2x *bp)
 {
struct bnx2x_func_state_params func_params = {NULL};
@@ -15511,9 +15502,12 @@ void bnx2x_init_ptp(struct bnx2x *bp)
 * unload / load (e.g. MTU change) while it is running.
 */
if (!bp->timecounter_init_done) {
-   bnx2x_init_cyclecounter(>timecounter.cc);
-   timecounter_init(>timecounter,
-ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>timecounter,
+  bnx2x_cyclecounter_read,
+  CYCLECOUNTER_MASK(64),
+  1,
+  0,
+  ktime_to_ns(ktime_get_real()));
bp->timecounter_init_done = 1;
}
 
-- 
1.9.1



Re: [PATCH v6] mfd: Add support for RTS5250S power saving

2017-12-14 Thread Hans de Goede

Hi,

On 14-12-17 23:25, Bjorn Helgaas wrote:

[+cc Hans, Dave, linux-pci]


I appreciate the Cc but I'm not really involved in this, other
then fixing the original commit up so that the T440s can reach
idle-state PC7 again, instead of only going to PC3.

With that said, for any fixes to this please Cc me so that I can
test that the T440s does not regress again.

Regards,

Hans




On Thu, Sep 07, 2017 at 04:26:39PM +0800, rui_f...@realsil.com.cn wrote:

From: Rui Feng 


I wish this had been posted to linux-pci before being merged.

I'm concerned because some of this appears to overlap and
conflict with PCI core management of ASPM.

I assume these devices advertise ASPM support in their Link
Capabilites registers, right?  If so, why isn't the existing
PCI core ASPM support sufficient?


Enable power saving for RTS5250S as following steps:
1.Set 0xFE58 to enable clock power management.


Is this clock power management something specific to RTS5250S, or is
it standard PCIe architected stuff?


2.Check cfg space whether support L1SS or not.


This sounds like standard PCIe ASPM L1 Substates, right?


3.If support L1SS, set 0xFF03 to free clkreq.
4.When entering idle status, enable aspm
   and set parameters for L1SS and LTR.
5.Wnen entering run status, disable aspm
   and set parameters for L1SS and LTR.


In general, drivers should not configure ASPM, L1SS, and LTR
themselves; the PCI core should do that.

If a driver needs to tweak ASPM at run-time, it should use interfaces
exported by the PCI core to do so.


If entering L1SS mode successfully,
electric current will be below 2mA.



Signed-off-by: Rui Feng 
...



+static void rts5249_init_from_cfg(struct rtsx_pcr *pcr)
+{
+   struct rtsx_cr_option *option = &(pcr->option);
+   u32 lval;
+
+   if (CHK_PCI_PID(pcr, PID_524A))
+   rtsx_pci_read_config_dword(pcr,
+   PCR_ASPM_SETTING_REG1, );
+   else
+   rtsx_pci_read_config_dword(pcr,
+   PCR_ASPM_SETTING_REG2, );


This looks like you're reading the ASPM L1 Substates capability, i.e.,
PCI_L1SS_CAP, using hard-coded offsets based on the Device ID.  You
should be using pci_find_ext_capability() to locate it.


+   if (lval & ASPM_L1_1_EN_MASK)
+   rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
+
+   if (lval & ASPM_L1_2_EN_MASK)
+   rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
+
+   if (lval & PM_L1_1_EN_MASK)
+   rtsx_set_dev_flag(pcr, PM_L1_1_EN);
+
+   if (lval & PM_L1_2_EN_MASK)
+   rtsx_set_dev_flag(pcr, PM_L1_2_EN);


You're adding these:

   #define ASPM_L1_1_EN_MASK  BIT(3)
   #define ASPM_L1_2_EN_MASK  BIT(2)
   #define PM_L1_1_EN_MASKBIT(1)
   #define PM_L1_2_EN_MASKBIT(0)

The PCI core already defines these and you should use them instead:

   #define  PCI_L1SS_CAP_PCIPM_L1_20x0001  /* PCI-PM L1.2 Supported 
*/
   #define  PCI_L1SS_CAP_PCIPM_L1_10x0002  /* PCI-PM L1.1 Supported 
*/
   #define  PCI_L1SS_CAP_ASPM_L1_2 0x0004  /* ASPM L1.2 Supported */
   #define  PCI_L1SS_CAP_ASPM_L1_1 0x0008  /* ASPM L1.1 Supported */


+   if (option->ltr_en) {
+   u16 val;
+
+   pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, );
+   if (val & PCI_EXP_DEVCTL2_LTR_EN) {
+   option->ltr_enabled = true;
+   option->ltr_active = true;


ltr_active is never actually used.


+   rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
+   } else {
+   option->ltr_enabled = false;
+   }
+   }
+}
...



+static void rts5249_set_aspm(struct rtsx_pcr *pcr, bool enable)
+{
+   struct rtsx_cr_option *option = >option;
+   u8 val = 0;
+
+   if (pcr->aspm_enabled == enable)
+   return;
+
+   if (option->dev_aspm_mode == DEV_ASPM_DYNAMIC) {
+   if (enable)
+   val = pcr->aspm_en;
+   rtsx_pci_update_cfg_byte(pcr,
+   pcr->pcie_cap + PCI_EXP_LNKCTL,
+   ASPM_MASK_NEG, val);


This stomps on whatever ASPM configuration the PCI core did.


+   } else if (option->dev_aspm_mode == DEV_ASPM_BACKDOOR) {


DEV_ASPM_BACKDOOR is never set, so this looks like dead code.


+   u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0;
+   if (!enable)
+   val = FORCE_ASPM_CTL0;
+   rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val);
+   }
+
+   pcr->aspm_enabled = enable;
+}


[PATCH 12/27] net/mlx5: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update mlx5 timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Saeed Mahameed 
Cc: Matan Barak 
Cc: Leon Romanovsky 
Cc: Eugenia Emantayev 
Cc: Eitan Rabin 
Cc: Feras Daoud 
Cc: Sagar Arun Kamble 
Cc: Miroslav Lichvar 
Cc: net...@vger.kernel.org
Cc: linux-r...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c 
b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
index 8cb6838..071f78a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -458,6 +458,7 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
u64 ns;
u64 frac = 0;
u32 dev_freq;
+   u32 mult, shift;
 
dev_freq = MLX5_CAP_GEN(mdev, device_frequency_khz);
if (!dev_freq) {
@@ -465,13 +466,16 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
return;
}
rwlock_init(>lock);
-   cc->read = read_internal_timer;
-   cc->shift = MLX5_CYCLES_SHIFT;
-   cc->mult = clocksource_khz2mult(dev_freq, cc->shift);
-   clock->nominal_c_mult = cc->mult;
-   cc->mask = CLOCKSOURCE_MASK(41);
-
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   shift = MLX5_CYCLES_SHIFT;
+   mult = clocksource_khz2mult(dev_freq, shift);
+   clock->nominal_c_mult = mult;
+
+   timecounter_initialize(>tc,
+  read_internal_timer,
+  CLOCKSOURCE_MASK(41),
+  mult,
+  shift,
+  ktime_to_ns(ktime_get_real()));
 
/* Calculate period in seconds to call the overflow watchdog - to make
 * sure counter is checked at least once every wrap around.
-- 
1.9.1



Re: [PATCH v6] mfd: Add support for RTS5250S power saving

2017-12-14 Thread Hans de Goede

Hi,

On 14-12-17 23:25, Bjorn Helgaas wrote:

[+cc Hans, Dave, linux-pci]


I appreciate the Cc but I'm not really involved in this, other
then fixing the original commit up so that the T440s can reach
idle-state PC7 again, instead of only going to PC3.

With that said, for any fixes to this please Cc me so that I can
test that the T440s does not regress again.

Regards,

Hans




On Thu, Sep 07, 2017 at 04:26:39PM +0800, rui_f...@realsil.com.cn wrote:

From: Rui Feng 


I wish this had been posted to linux-pci before being merged.

I'm concerned because some of this appears to overlap and
conflict with PCI core management of ASPM.

I assume these devices advertise ASPM support in their Link
Capabilites registers, right?  If so, why isn't the existing
PCI core ASPM support sufficient?


Enable power saving for RTS5250S as following steps:
1.Set 0xFE58 to enable clock power management.


Is this clock power management something specific to RTS5250S, or is
it standard PCIe architected stuff?


2.Check cfg space whether support L1SS or not.


This sounds like standard PCIe ASPM L1 Substates, right?


3.If support L1SS, set 0xFF03 to free clkreq.
4.When entering idle status, enable aspm
   and set parameters for L1SS and LTR.
5.Wnen entering run status, disable aspm
   and set parameters for L1SS and LTR.


In general, drivers should not configure ASPM, L1SS, and LTR
themselves; the PCI core should do that.

If a driver needs to tweak ASPM at run-time, it should use interfaces
exported by the PCI core to do so.


If entering L1SS mode successfully,
electric current will be below 2mA.



Signed-off-by: Rui Feng 
...



+static void rts5249_init_from_cfg(struct rtsx_pcr *pcr)
+{
+   struct rtsx_cr_option *option = &(pcr->option);
+   u32 lval;
+
+   if (CHK_PCI_PID(pcr, PID_524A))
+   rtsx_pci_read_config_dword(pcr,
+   PCR_ASPM_SETTING_REG1, );
+   else
+   rtsx_pci_read_config_dword(pcr,
+   PCR_ASPM_SETTING_REG2, );


This looks like you're reading the ASPM L1 Substates capability, i.e.,
PCI_L1SS_CAP, using hard-coded offsets based on the Device ID.  You
should be using pci_find_ext_capability() to locate it.


+   if (lval & ASPM_L1_1_EN_MASK)
+   rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
+
+   if (lval & ASPM_L1_2_EN_MASK)
+   rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
+
+   if (lval & PM_L1_1_EN_MASK)
+   rtsx_set_dev_flag(pcr, PM_L1_1_EN);
+
+   if (lval & PM_L1_2_EN_MASK)
+   rtsx_set_dev_flag(pcr, PM_L1_2_EN);


You're adding these:

   #define ASPM_L1_1_EN_MASK  BIT(3)
   #define ASPM_L1_2_EN_MASK  BIT(2)
   #define PM_L1_1_EN_MASKBIT(1)
   #define PM_L1_2_EN_MASKBIT(0)

The PCI core already defines these and you should use them instead:

   #define  PCI_L1SS_CAP_PCIPM_L1_20x0001  /* PCI-PM L1.2 Supported 
*/
   #define  PCI_L1SS_CAP_PCIPM_L1_10x0002  /* PCI-PM L1.1 Supported 
*/
   #define  PCI_L1SS_CAP_ASPM_L1_2 0x0004  /* ASPM L1.2 Supported */
   #define  PCI_L1SS_CAP_ASPM_L1_1 0x0008  /* ASPM L1.1 Supported */


+   if (option->ltr_en) {
+   u16 val;
+
+   pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, );
+   if (val & PCI_EXP_DEVCTL2_LTR_EN) {
+   option->ltr_enabled = true;
+   option->ltr_active = true;


ltr_active is never actually used.


+   rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
+   } else {
+   option->ltr_enabled = false;
+   }
+   }
+}
...



+static void rts5249_set_aspm(struct rtsx_pcr *pcr, bool enable)
+{
+   struct rtsx_cr_option *option = >option;
+   u8 val = 0;
+
+   if (pcr->aspm_enabled == enable)
+   return;
+
+   if (option->dev_aspm_mode == DEV_ASPM_DYNAMIC) {
+   if (enable)
+   val = pcr->aspm_en;
+   rtsx_pci_update_cfg_byte(pcr,
+   pcr->pcie_cap + PCI_EXP_LNKCTL,
+   ASPM_MASK_NEG, val);


This stomps on whatever ASPM configuration the PCI core did.


+   } else if (option->dev_aspm_mode == DEV_ASPM_BACKDOOR) {


DEV_ASPM_BACKDOOR is never set, so this looks like dead code.


+   u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0;
+   if (!enable)
+   val = FORCE_ASPM_CTL0;
+   rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val);
+   }
+
+   pcr->aspm_enabled = enable;
+}


[PATCH 12/27] net/mlx5: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update mlx5 timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Saeed Mahameed 
Cc: Matan Barak 
Cc: Leon Romanovsky 
Cc: Eugenia Emantayev 
Cc: Eitan Rabin 
Cc: Feras Daoud 
Cc: Sagar Arun Kamble 
Cc: Miroslav Lichvar 
Cc: net...@vger.kernel.org
Cc: linux-r...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c 
b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
index 8cb6838..071f78a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -458,6 +458,7 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
u64 ns;
u64 frac = 0;
u32 dev_freq;
+   u32 mult, shift;
 
dev_freq = MLX5_CAP_GEN(mdev, device_frequency_khz);
if (!dev_freq) {
@@ -465,13 +466,16 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
return;
}
rwlock_init(>lock);
-   cc->read = read_internal_timer;
-   cc->shift = MLX5_CYCLES_SHIFT;
-   cc->mult = clocksource_khz2mult(dev_freq, cc->shift);
-   clock->nominal_c_mult = cc->mult;
-   cc->mask = CLOCKSOURCE_MASK(41);
-
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   shift = MLX5_CYCLES_SHIFT;
+   mult = clocksource_khz2mult(dev_freq, shift);
+   clock->nominal_c_mult = mult;
+
+   timecounter_initialize(>tc,
+  read_internal_timer,
+  CLOCKSOURCE_MASK(41),
+  mult,
+  shift,
+  ktime_to_ns(ktime_get_real()));
 
/* Calculate period in seconds to call the overflow watchdog - to make
 * sure counter is checked at least once every wrap around.
-- 
1.9.1



[PATCH 15/27] ALSA: hda - Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update azx timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jaroslav Kysela 
Cc: Takashi Iwai 
Cc: Thomas Gleixner 
Cc: Vinod Koul 
Cc: alsa-de...@alsa-project.org
Cc: linux-kernel@vger.kernel.org
---
 sound/hda/hdac_stream.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 9426c1a..ad91dde 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -477,12 +477,8 @@ static void azx_timecounter_init(struct hdac_stream 
*azx_dev,
 bool force, u64 last)
 {
struct timecounter *tc = _dev->tc;
-   struct cyclecounter *cc = _dev->tc.cc;
u64 nsec;
 
-   cc->read = azx_cc_read;
-   cc->mask = CLOCKSOURCE_MASK(32);
-
/*
 * Converting from 24 MHz to ns means applying a 125/3 factor.
 * To avoid any saturation issues in intermediate operations,
@@ -493,11 +489,13 @@ static void azx_timecounter_init(struct hdac_stream 
*azx_dev,
 * overflows occur after about 4 hours or less, not a option.
 */
 
-   cc->mult = 125; /* saturation after 195 years */
-   cc->shift = 0;
-
nsec = 0; /* audio time is elapsed time since trigger */
-   timecounter_init(tc, nsec);
+   timecounter_initialize(tc,
+  azx_cc_read,
+  CLOCKSOURCE_MASK(32),
+  125, /* saturation after 195 years */
+  0,
+  nsec);
if (force) {
/*
 * force timecounter to use predefined value,
-- 
1.9.1



[PATCH 15/27] ALSA: hda - Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update azx timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jaroslav Kysela 
Cc: Takashi Iwai 
Cc: Thomas Gleixner 
Cc: Vinod Koul 
Cc: alsa-de...@alsa-project.org
Cc: linux-kernel@vger.kernel.org
---
 sound/hda/hdac_stream.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 9426c1a..ad91dde 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -477,12 +477,8 @@ static void azx_timecounter_init(struct hdac_stream 
*azx_dev,
 bool force, u64 last)
 {
struct timecounter *tc = _dev->tc;
-   struct cyclecounter *cc = _dev->tc.cc;
u64 nsec;
 
-   cc->read = azx_cc_read;
-   cc->mask = CLOCKSOURCE_MASK(32);
-
/*
 * Converting from 24 MHz to ns means applying a 125/3 factor.
 * To avoid any saturation issues in intermediate operations,
@@ -493,11 +489,13 @@ static void azx_timecounter_init(struct hdac_stream 
*azx_dev,
 * overflows occur after about 4 hours or less, not a option.
 */
 
-   cc->mult = 125; /* saturation after 195 years */
-   cc->shift = 0;
-
nsec = 0; /* audio time is elapsed time since trigger */
-   timecounter_init(tc, nsec);
+   timecounter_initialize(tc,
+  azx_cc_read,
+  CLOCKSOURCE_MASK(32),
+  125, /* saturation after 195 years */
+  0,
+  nsec);
if (force) {
/*
 * force timecounter to use predefined value,
-- 
1.9.1



[PATCH 14/27] net: cpts: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update cpts timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: "David S. Miller" 
Cc: Grygorii Strashko 
Cc: Richard Cochran 
Cc: Bhumika Goyal 
Cc: Thomas Gleixner 
Cc: Ivan Khoronzhuk 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/ti/cpts.c | 29 +
 drivers/net/ethernet/ti/cpts.h |  3 +++
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index b8fe843..e6afc94 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -447,7 +447,12 @@ int cpts_register(struct cpts *cpts)
cpts_write32(cpts, CPTS_EN, control);
cpts_write32(cpts, TS_PEND_EN, int_enable);
 
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>tc,
+  cpts_systim_read,
+  cpts->mask,
+  cpts->mult,
+  cpts->shift,
+  ktime_to_ns(ktime_get_real()));
 
cpts->clock = ptp_clock_register(>info, cpts->dev);
if (IS_ERR(cpts->clock)) {
@@ -484,7 +489,8 @@ void cpts_unregister(struct cpts *cpts)
 }
 EXPORT_SYMBOL_GPL(cpts_unregister);
 
-static void cpts_calc_mult_shift(struct cpts *cpts)
+static void cpts_calc_mult_shift(struct cpts *cpts, u64 mask,
+u32 *mult, u32 *shift)
 {
struct cyclecounter *cc = >tc.cc;
u64 frac, maxsec, ns;
@@ -495,7 +501,7 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
/* Calc the maximum number of seconds which we can run before
 * wrapping around.
 */
-   maxsec = cc->mask;
+   maxsec = mask;
do_div(maxsec, freq);
/* limit conversation rate to 10 sec as higher values will produce
 * too small mult factors and so reduce the conversion accuracy
@@ -508,18 +514,18 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
dev_info(cpts->dev, "cpts: overflow check period %lu (jiffies)\n",
 cpts->ov_check_period);
 
-   if (cc->mult || cc->shift)
+   if (*mult || *shift)
return;
 
-   clocks_calc_mult_shift(>mult, >shift,
+   clocks_calc_mult_shift(mult, shift,
   freq, NSEC_PER_SEC, maxsec);
 
frac = 0;
-   ns = cyclecounter_cyc2ns(cc, freq, cc->mask, );
+   ns = cyclecounter_cyc2ns(cc, freq, mask, );
 
dev_info(cpts->dev,
 "CPTS: ref_clk_freq:%u calc_mult:%u calc_shift:%u error:%lld 
nsec/sec\n",
-freq, cc->mult, cc->shift,
+freq, *mult, *shift,
 (ns - NSEC_PER_SEC));
 }
 
@@ -571,15 +577,14 @@ struct cpts *cpts_create(struct device *dev, void __iomem 
*regs,
 
clk_prepare(cpts->refclk);
 
-   cpts->tc.cc.read = cpts_systim_read;
-   cpts->tc.cc.mask = CLOCKSOURCE_MASK(32);
+   cpts->mask = CLOCKSOURCE_MASK(32);
cpts->info = cpts_info;
 
-   cpts_calc_mult_shift(cpts);
-   /* save tc.cc.mult original value as it can be modified
+   cpts_calc_mult_shift(cpts, cpts->mask, >mult, >shift);
+   /* save mult original value as it can be modified
 * by cpts_ptp_adjfreq().
 */
-   cpts->cc_mult = cpts->tc.cc.mult;
+   cpts->cc_mult = cpts->mult;
 
return cpts;
 }
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index a7174eb..da50d34 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -118,6 +118,9 @@ struct cpts {
spinlock_t lock; /* protects time registers */
u32 cc_mult; /* for the nominal frequency */
struct timecounter tc;
+   u64 mask;
+   u32 mult;
+   u32 shift;
int phc_index;
struct clk *refclk;
struct list_head events;
-- 
1.9.1



[PATCH 14/27] net: cpts: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update cpts timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: "David S. Miller" 
Cc: Grygorii Strashko 
Cc: Richard Cochran 
Cc: Bhumika Goyal 
Cc: Thomas Gleixner 
Cc: Ivan Khoronzhuk 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/ti/cpts.c | 29 +
 drivers/net/ethernet/ti/cpts.h |  3 +++
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index b8fe843..e6afc94 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -447,7 +447,12 @@ int cpts_register(struct cpts *cpts)
cpts_write32(cpts, CPTS_EN, control);
cpts_write32(cpts, TS_PEND_EN, int_enable);
 
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>tc,
+  cpts_systim_read,
+  cpts->mask,
+  cpts->mult,
+  cpts->shift,
+  ktime_to_ns(ktime_get_real()));
 
cpts->clock = ptp_clock_register(>info, cpts->dev);
if (IS_ERR(cpts->clock)) {
@@ -484,7 +489,8 @@ void cpts_unregister(struct cpts *cpts)
 }
 EXPORT_SYMBOL_GPL(cpts_unregister);
 
-static void cpts_calc_mult_shift(struct cpts *cpts)
+static void cpts_calc_mult_shift(struct cpts *cpts, u64 mask,
+u32 *mult, u32 *shift)
 {
struct cyclecounter *cc = >tc.cc;
u64 frac, maxsec, ns;
@@ -495,7 +501,7 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
/* Calc the maximum number of seconds which we can run before
 * wrapping around.
 */
-   maxsec = cc->mask;
+   maxsec = mask;
do_div(maxsec, freq);
/* limit conversation rate to 10 sec as higher values will produce
 * too small mult factors and so reduce the conversion accuracy
@@ -508,18 +514,18 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
dev_info(cpts->dev, "cpts: overflow check period %lu (jiffies)\n",
 cpts->ov_check_period);
 
-   if (cc->mult || cc->shift)
+   if (*mult || *shift)
return;
 
-   clocks_calc_mult_shift(>mult, >shift,
+   clocks_calc_mult_shift(mult, shift,
   freq, NSEC_PER_SEC, maxsec);
 
frac = 0;
-   ns = cyclecounter_cyc2ns(cc, freq, cc->mask, );
+   ns = cyclecounter_cyc2ns(cc, freq, mask, );
 
dev_info(cpts->dev,
 "CPTS: ref_clk_freq:%u calc_mult:%u calc_shift:%u error:%lld 
nsec/sec\n",
-freq, cc->mult, cc->shift,
+freq, *mult, *shift,
 (ns - NSEC_PER_SEC));
 }
 
@@ -571,15 +577,14 @@ struct cpts *cpts_create(struct device *dev, void __iomem 
*regs,
 
clk_prepare(cpts->refclk);
 
-   cpts->tc.cc.read = cpts_systim_read;
-   cpts->tc.cc.mask = CLOCKSOURCE_MASK(32);
+   cpts->mask = CLOCKSOURCE_MASK(32);
cpts->info = cpts_info;
 
-   cpts_calc_mult_shift(cpts);
-   /* save tc.cc.mult original value as it can be modified
+   cpts_calc_mult_shift(cpts, cpts->mask, >mult, >shift);
+   /* save mult original value as it can be modified
 * by cpts_ptp_adjfreq().
 */
-   cpts->cc_mult = cpts->tc.cc.mult;
+   cpts->cc_mult = cpts->mult;
 
return cpts;
 }
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index a7174eb..da50d34 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -118,6 +118,9 @@ struct cpts {
spinlock_t lock; /* protects time registers */
u32 cc_mult; /* for the nominal frequency */
struct timecounter tc;
+   u64 mask;
+   u32 mult;
+   u32 shift;
int phc_index;
struct clk *refclk;
struct list_head events;
-- 
1.9.1



[PATCH 18/27] bnx2x: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update bnx2x_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Ariel Elior 
Cc: everest-linux...@cavium.com
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 1e10a81..e30e736 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -13849,8 +13849,8 @@ static int bnx2x_ptp_settime(struct ptp_clock_info *ptp,
 
DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns);
 
-   /* Re-init the timecounter */
-   timecounter_init(>timecounter, ns);
+   /* Reset the timecounter */
+   timecounter_reset(>timecounter, ns);
 
return 0;
 }
-- 
1.9.1



[PATCH 16/27] timecounter: Introduce timecounter_reset

2017-12-14 Thread Sagar Arun Kamble
timecounter_init initializes the cyclecounter and sets the start time.
Sometimes drivers using timecounter just want to update start time.
This patch creates new function timecounter_reset that just resets the
timecounter start time and associated state.

Suggested-by: Richard Cochran 
Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Chris Wilson 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Stephen Boyd 
Cc: linux-kernel@vger.kernel.org
---
 include/linux/timecounter.h | 17 +++--
 kernel/time/timecounter.c   |  9 +
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h
index 59d3fd7..e0fd741 100644
--- a/include/linux/timecounter.h
+++ b/include/linux/timecounter.h
@@ -98,7 +98,7 @@ static inline void timecounter_adjtime(struct timecounter 
*tc, s64 delta)
 
 /**
  * timecounter_init - initialize a time counter
- * @tc:Pointer to time counter which is to be 
initialized/reset
+ * @tc:Pointer to time counter which is to be 
initialized
  * @start_tstamp:  Arbitrary initial time stamp.
  *
  * After this call the current cycle register (roughly) corresponds to
@@ -131,8 +131,21 @@ extern void timecounter_initialize(struct timecounter *tc,
   u64 start_tstamp);
 
 /**
+ * timecounter_reset - reset a time counter
+ * @tc:Pointer to time counter which is to be reset
+ * @start_tstamp:  Arbitrary initial time stamp.
+ *
+ * After this call the current cycle register (roughly) corresponds to
+ * the supplied time stamp. Every call to timecounter_read() increments
+ * the time stamp counter by the number of elapsed nanoseconds.
+ */
+extern void timecounter_reset(struct timecounter *tc,
+ u64 start_tstamp);
+
+/**
  * timecounter_read - return nanoseconds elapsed since timecounter_init() or
- *timecounter_initialize() plus the initial time stamp
+ *timecounter_initialize() or timecounter_reset() plus
+ *   the initial time stamp
  * @tc:  Pointer to time counter.
  *
  * In other words, keeps track of time since the same epoch as
diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c
index 6d915752..3f62fe0 100644
--- a/kernel/time/timecounter.c
+++ b/kernel/time/timecounter.c
@@ -47,6 +47,15 @@ void timecounter_initialize(struct timecounter *tc,
 }
 EXPORT_SYMBOL_GPL(timecounter_initialize);
 
+void timecounter_reset(struct timecounter *tc,
+  u64 start_tstamp)
+{
+   tc->cycle_last = tc->cc.read(>cc);
+   tc->nsec = start_tstamp;
+   tc->frac = 0;
+}
+EXPORT_SYMBOL_GPL(timecounter_reset);
+
 /**
  * timecounter_read_delta - get nanoseconds since last call of this function
  * @tc: Pointer to time counter
-- 
1.9.1



[PATCH 18/27] bnx2x: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update bnx2x_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Ariel Elior 
Cc: everest-linux...@cavium.com
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 1e10a81..e30e736 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -13849,8 +13849,8 @@ static int bnx2x_ptp_settime(struct ptp_clock_info *ptp,
 
DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns);
 
-   /* Re-init the timecounter */
-   timecounter_init(>timecounter, ns);
+   /* Reset the timecounter */
+   timecounter_reset(>timecounter, ns);
 
return 0;
 }
-- 
1.9.1



[PATCH 16/27] timecounter: Introduce timecounter_reset

2017-12-14 Thread Sagar Arun Kamble
timecounter_init initializes the cyclecounter and sets the start time.
Sometimes drivers using timecounter just want to update start time.
This patch creates new function timecounter_reset that just resets the
timecounter start time and associated state.

Suggested-by: Richard Cochran 
Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Chris Wilson 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Stephen Boyd 
Cc: linux-kernel@vger.kernel.org
---
 include/linux/timecounter.h | 17 +++--
 kernel/time/timecounter.c   |  9 +
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h
index 59d3fd7..e0fd741 100644
--- a/include/linux/timecounter.h
+++ b/include/linux/timecounter.h
@@ -98,7 +98,7 @@ static inline void timecounter_adjtime(struct timecounter 
*tc, s64 delta)
 
 /**
  * timecounter_init - initialize a time counter
- * @tc:Pointer to time counter which is to be 
initialized/reset
+ * @tc:Pointer to time counter which is to be 
initialized
  * @start_tstamp:  Arbitrary initial time stamp.
  *
  * After this call the current cycle register (roughly) corresponds to
@@ -131,8 +131,21 @@ extern void timecounter_initialize(struct timecounter *tc,
   u64 start_tstamp);
 
 /**
+ * timecounter_reset - reset a time counter
+ * @tc:Pointer to time counter which is to be reset
+ * @start_tstamp:  Arbitrary initial time stamp.
+ *
+ * After this call the current cycle register (roughly) corresponds to
+ * the supplied time stamp. Every call to timecounter_read() increments
+ * the time stamp counter by the number of elapsed nanoseconds.
+ */
+extern void timecounter_reset(struct timecounter *tc,
+ u64 start_tstamp);
+
+/**
  * timecounter_read - return nanoseconds elapsed since timecounter_init() or
- *timecounter_initialize() plus the initial time stamp
+ *timecounter_initialize() or timecounter_reset() plus
+ *   the initial time stamp
  * @tc:  Pointer to time counter.
  *
  * In other words, keeps track of time since the same epoch as
diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c
index 6d915752..3f62fe0 100644
--- a/kernel/time/timecounter.c
+++ b/kernel/time/timecounter.c
@@ -47,6 +47,15 @@ void timecounter_initialize(struct timecounter *tc,
 }
 EXPORT_SYMBOL_GPL(timecounter_initialize);
 
+void timecounter_reset(struct timecounter *tc,
+  u64 start_tstamp)
+{
+   tc->cycle_last = tc->cc.read(>cc);
+   tc->nsec = start_tstamp;
+   tc->frac = 0;
+}
+EXPORT_SYMBOL_GPL(timecounter_reset);
+
 /**
  * timecounter_read_delta - get nanoseconds since last call of this function
  * @tc: Pointer to time counter
-- 
1.9.1



Re: [PATCH tip 0/3] Improvements of scheduler related Tracepoints

2017-12-14 Thread Peter Zijlstra
On Thu, Dec 14, 2017 at 07:16:00PM -0800, Alexei Starovoitov wrote:
> On 12/14/17 12:49 PM, Peter Zijlstra wrote:
> > On Thu, Dec 14, 2017 at 12:20:41PM -0800, Teng Qin wrote:
> > > This set of commits attempts to improve three scheduler related
> > > Tracepoints: sched_switch, sched_process_fork, sched_process_exit.
> > > 
> > > Firstly, these commit add additional flag values, namely preempt,
> > > clone_flags and group_dead to these Tracepoints, to make information
> > > exposed via the Tracepoints more useful and complete.
> > > 
> > > Secondly, these commits exposes task_struct pointers in these
> > > Tracepoints. The task_struct pointers are arguments of the Tracepoints
> > > and currently only used to compute struct field values. But for BPF
> > > programs attached to these Tracepoints, we may want to read additional
> > > task information via the task_struct pointers. This is currently either
> > > impossible, or we have to make assumption of whether the Tracepoint is
> > > running from previous / parent or next / child, and use current pointer
> > > instead. Exposing the task_struct pointers explicitly makes such use
> > > case easier and more reliable.
> > > 
> > 
> > NAK
> 
> not sure what is the concern here.
> Is it first or second part of the above ?

Definitely the second, but also the first. You know I would have ripped
out all scheduler tracepoints if I could have. They're a pain in the
arse.

A lot of people want to add to the tracepoints, with the end result that
they'll end up a big bloated pile of useless crap. The first part is
just the pieces you want added.

As to the second, that's complete crap; that just makes everything
slower for bodies benefit. If you register a traceprobe you already get
access to these things.

I think your problem is that you use perf to get access to the
tracepoints, which them means you have to do disgusting things like
this.


Re: [PATCH tip 0/3] Improvements of scheduler related Tracepoints

2017-12-14 Thread Peter Zijlstra
On Thu, Dec 14, 2017 at 07:16:00PM -0800, Alexei Starovoitov wrote:
> On 12/14/17 12:49 PM, Peter Zijlstra wrote:
> > On Thu, Dec 14, 2017 at 12:20:41PM -0800, Teng Qin wrote:
> > > This set of commits attempts to improve three scheduler related
> > > Tracepoints: sched_switch, sched_process_fork, sched_process_exit.
> > > 
> > > Firstly, these commit add additional flag values, namely preempt,
> > > clone_flags and group_dead to these Tracepoints, to make information
> > > exposed via the Tracepoints more useful and complete.
> > > 
> > > Secondly, these commits exposes task_struct pointers in these
> > > Tracepoints. The task_struct pointers are arguments of the Tracepoints
> > > and currently only used to compute struct field values. But for BPF
> > > programs attached to these Tracepoints, we may want to read additional
> > > task information via the task_struct pointers. This is currently either
> > > impossible, or we have to make assumption of whether the Tracepoint is
> > > running from previous / parent or next / child, and use current pointer
> > > instead. Exposing the task_struct pointers explicitly makes such use
> > > case easier and more reliable.
> > > 
> > 
> > NAK
> 
> not sure what is the concern here.
> Is it first or second part of the above ?

Definitely the second, but also the first. You know I would have ripped
out all scheduler tracepoints if I could have. They're a pain in the
arse.

A lot of people want to add to the tracepoints, with the end result that
they'll end up a big bloated pile of useless crap. The first part is
just the pieces you want added.

As to the second, that's complete crap; that just makes everything
slower for bodies benefit. If you register a traceprobe you already get
access to these things.

I think your problem is that you use perf to get access to the
tracepoints, which them means you have to do disgusting things like
this.


Re: [PATCH] locking/lockdep: Remove the cross-release locking checks

2017-12-14 Thread Byungchul Park
On Fri, Dec 15, 2017 at 3:24 PM, Theodore Ts'o  wrote:
> On Fri, Dec 15, 2017 at 01:05:43PM +0900, Byungchul Park wrote:
>> For example, in the case of fs issues, for now we can
>> invalidate wait_for_completion() in submit_bio_wait()
>
> And this will spawn a checkpatch.pl ERROR:
>
> ERROR("LOCKDEP",
> "lockdep_no_validate class is reserved for 
> device->mutex.\n" . $herecurr);
>
> This mention in checkpatch.pl is the only documentation I've been able
> to find about lockdep_set_novalidate_class(), by the way.
>
>> ... and re-validate it later, of course, I really want to find more
>> fundamental solution though.
>
> Oh, and I was finally able to find the quote that the *only* people
> who are likely to be able to deal with lock annotations are the

Right. Using the word, "only", is one that I should not have done
and I apologize for.

They are just "only" people who solve and classify locks quickly,
assuming all of kernel guys are familiar with lockdep annotations.
Thus, even this statement is bad as well, since no good
document for that exists, as you pointed out. I agree.

> subsystem maintainers.  But if the ways of dealing with lock
> annotations are not documented, such that subsystem maintainers are
> going to have a very hard time figuring out *how* to deal with it, it

Right. I've agreed with this, since you pointed out it's problem not
to be documented well.

> seems that lock classification as a solution to cross-release false
> positives seems unlikely:
>
>From: Byungchul Park 
>Date: Fri, 8 Dec 2017 18:27:45 +0900
>Subject: Re: [PATCH v4 72/73] xfs: Convert mru cache to XArray
>
>1) Firstly, it's hard to assign lock classes *properly*. By
>default, it relies on the caller site of lockdep_init_map(),
>but we need to assign another class manually, where ordering
>rules are complicated so cannot rely on the caller site. That
>*only* can be done by experts of the subsystem.
>
> - Ted



-- 
Thanks,
Byungchul


Re: [PATCH] locking/lockdep: Remove the cross-release locking checks

2017-12-14 Thread Byungchul Park
On Fri, Dec 15, 2017 at 3:24 PM, Theodore Ts'o  wrote:
> On Fri, Dec 15, 2017 at 01:05:43PM +0900, Byungchul Park wrote:
>> For example, in the case of fs issues, for now we can
>> invalidate wait_for_completion() in submit_bio_wait()
>
> And this will spawn a checkpatch.pl ERROR:
>
> ERROR("LOCKDEP",
> "lockdep_no_validate class is reserved for 
> device->mutex.\n" . $herecurr);
>
> This mention in checkpatch.pl is the only documentation I've been able
> to find about lockdep_set_novalidate_class(), by the way.
>
>> ... and re-validate it later, of course, I really want to find more
>> fundamental solution though.
>
> Oh, and I was finally able to find the quote that the *only* people
> who are likely to be able to deal with lock annotations are the

Right. Using the word, "only", is one that I should not have done
and I apologize for.

They are just "only" people who solve and classify locks quickly,
assuming all of kernel guys are familiar with lockdep annotations.
Thus, even this statement is bad as well, since no good
document for that exists, as you pointed out. I agree.

> subsystem maintainers.  But if the ways of dealing with lock
> annotations are not documented, such that subsystem maintainers are
> going to have a very hard time figuring out *how* to deal with it, it

Right. I've agreed with this, since you pointed out it's problem not
to be documented well.

> seems that lock classification as a solution to cross-release false
> positives seems unlikely:
>
>From: Byungchul Park 
>Date: Fri, 8 Dec 2017 18:27:45 +0900
>Subject: Re: [PATCH v4 72/73] xfs: Convert mru cache to XArray
>
>1) Firstly, it's hard to assign lock classes *properly*. By
>default, it relies on the caller site of lockdep_init_map(),
>but we need to assign another class manually, where ordering
>rules are complicated so cannot rely on the caller site. That
>*only* can be done by experts of the subsystem.
>
> - Ted



-- 
Thanks,
Byungchul


[PATCH 22/27] ixgbe: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update ixgbe_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 073c1ef..35f85ef 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -508,7 +508,7 @@ static int ixgbe_ptp_settime(struct ptp_clock_info *ptp,
 
/* reset the timecounter */
spin_lock_irqsave(>tmreg_lock, flags);
-   timecounter_init(>hw_tc, ns);
+   timecounter_reset(>hw_tc, ns);
spin_unlock_irqrestore(>tmreg_lock, flags);
 
if (adapter->ptp_setup_sdp)
-- 
1.9.1



[PATCH 22/27] ixgbe: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update ixgbe_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 073c1ef..35f85ef 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -508,7 +508,7 @@ static int ixgbe_ptp_settime(struct ptp_clock_info *ptp,
 
/* reset the timecounter */
spin_lock_irqsave(>tmreg_lock, flags);
-   timecounter_init(>hw_tc, ns);
+   timecounter_reset(>hw_tc, ns);
spin_unlock_irqrestore(>tmreg_lock, flags);
 
if (adapter->ptp_setup_sdp)
-- 
1.9.1



[PATCH 23/27] net/mlx4: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update mlx4_en_phc_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Tariq Toukan 
Cc: net...@vger.kernel.org
Cc: linux-r...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/mellanox/mlx4/en_clock.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c 
b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
index dd736cc..bfed4ac 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
@@ -207,7 +207,7 @@ static int mlx4_en_phc_settime(struct ptp_clock_info *ptp,
 
/* reset the timecounter */
write_seqlock_irqsave(>clock_lock, flags);
-   timecounter_init(>clock, ns);
+   timecounter_reset(>clock, ns);
write_sequnlock_irqrestore(>clock_lock, flags);
 
return 0;
-- 
1.9.1



[PATCH 21/27] igb: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update igb_ptp_settime_82576 with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/igb/igb_ptp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c 
b/drivers/net/ethernet/intel/igb/igb_ptp.c
index f6c1a8d..90344b2 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -330,7 +330,7 @@ static int igb_ptp_settime_82576(struct ptp_clock_info *ptp,
 
spin_lock_irqsave(>tmreg_lock, flags);
 
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
 
spin_unlock_irqrestore(>tmreg_lock, flags);
 
-- 
1.9.1



[PATCH 21/27] igb: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update igb_ptp_settime_82576 with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/igb/igb_ptp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c 
b/drivers/net/ethernet/intel/igb/igb_ptp.c
index f6c1a8d..90344b2 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -330,7 +330,7 @@ static int igb_ptp_settime_82576(struct ptp_clock_info *ptp,
 
spin_lock_irqsave(>tmreg_lock, flags);
 
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
 
spin_unlock_irqrestore(>tmreg_lock, flags);
 
-- 
1.9.1



[PATCH 23/27] net/mlx4: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update mlx4_en_phc_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Tariq Toukan 
Cc: net...@vger.kernel.org
Cc: linux-r...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/mellanox/mlx4/en_clock.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c 
b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
index dd736cc..bfed4ac 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
@@ -207,7 +207,7 @@ static int mlx4_en_phc_settime(struct ptp_clock_info *ptp,
 
/* reset the timecounter */
write_seqlock_irqsave(>clock_lock, flags);
-   timecounter_init(>clock, ns);
+   timecounter_reset(>clock, ns);
write_sequnlock_irqrestore(>clock_lock, flags);
 
return 0;
-- 
1.9.1



[PATCH 24/27] net/mlx5: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update mlx5_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Saeed Mahameed 
Cc: Matan Barak 
Cc: Leon Romanovsky 
Cc: Eugenia Emantayev 
Cc: Eitan Rabin 
Cc: Feras Daoud 
Cc: Tariq Toukan 
Cc: Thomas Gleixner 
Cc: net...@vger.kernel.org
Cc: linux-r...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c 
b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
index 071f78a..e490522 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -122,7 +122,7 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp,
unsigned long flags;
 
write_lock_irqsave(>lock, flags);
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
write_unlock_irqrestore(>lock, flags);
 
return 0;
-- 
1.9.1



[PATCH 24/27] net/mlx5: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update mlx5_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Saeed Mahameed 
Cc: Matan Barak 
Cc: Leon Romanovsky 
Cc: Eugenia Emantayev 
Cc: Eitan Rabin 
Cc: Feras Daoud 
Cc: Tariq Toukan 
Cc: Thomas Gleixner 
Cc: net...@vger.kernel.org
Cc: linux-r...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c 
b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
index 071f78a..e490522 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -122,7 +122,7 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp,
unsigned long flags;
 
write_lock_irqsave(>lock, flags);
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
write_unlock_irqrestore(>lock, flags);
 
return 0;
-- 
1.9.1



[PATCH 25/27] qede: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update qede_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Ariel Elior 
Cc: everest-linux...@cavium.com
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/qlogic/qede/qede_ptp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c 
b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
index 0d054dc..c2de311 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
@@ -129,9 +129,9 @@ static int qede_ptp_settime(struct ptp_clock_info *info,
 
DP_VERBOSE(edev, QED_MSG_DEBUG, "PTP settime called, ns = %llu\n", ns);
 
-   /* Re-init the timecounter */
+   /* Reset the timecounter */
spin_lock_bh(>lock);
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
spin_unlock_bh(>lock);
 
return 0;
-- 
1.9.1



[PATCH 26/27] net: cpts: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update cpts_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: "David S. Miller" 
Cc: Grygorii Strashko 
Cc: Bhumika Goyal 
Cc: Richard Cochran 
Cc: Thomas Gleixner 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/ti/cpts.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index e6afc94..41bac4d 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -268,7 +268,7 @@ static int cpts_ptp_settime(struct ptp_clock_info *ptp,
ns = timespec64_to_ns(ts);
 
spin_lock_irqsave(>lock, flags);
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
spin_unlock_irqrestore(>lock, flags);
 
return 0;
-- 
1.9.1



[PATCH 25/27] qede: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update qede_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Ariel Elior 
Cc: everest-linux...@cavium.com
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/qlogic/qede/qede_ptp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c 
b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
index 0d054dc..c2de311 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
@@ -129,9 +129,9 @@ static int qede_ptp_settime(struct ptp_clock_info *info,
 
DP_VERBOSE(edev, QED_MSG_DEBUG, "PTP settime called, ns = %llu\n", ns);
 
-   /* Re-init the timecounter */
+   /* Reset the timecounter */
spin_lock_bh(>lock);
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
spin_unlock_bh(>lock);
 
return 0;
-- 
1.9.1



[PATCH 26/27] net: cpts: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update cpts_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: "David S. Miller" 
Cc: Grygorii Strashko 
Cc: Bhumika Goyal 
Cc: Richard Cochran 
Cc: Thomas Gleixner 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/ti/cpts.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index e6afc94..41bac4d 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -268,7 +268,7 @@ static int cpts_ptp_settime(struct ptp_clock_info *ptp,
ns = timespec64_to_ns(ts);
 
spin_lock_irqsave(>lock, flags);
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
spin_unlock_irqrestore(>lock, flags);
 
return 0;
-- 
1.9.1



[PATCH 20/27] e1000e: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update e1000e_phc_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/e1000e/ptp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c 
b/drivers/net/ethernet/intel/e1000e/ptp.c
index 03d5f2a..5b368aa 100644
--- a/drivers/net/ethernet/intel/e1000e/ptp.c
+++ b/drivers/net/ethernet/intel/e1000e/ptp.c
@@ -222,7 +222,7 @@ static int e1000e_phc_settime(struct ptp_clock_info *ptp,
 
/* reset the timecounter */
spin_lock_irqsave(>systim_lock, flags);
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
spin_unlock_irqrestore(>systim_lock, flags);
 
return 0;
-- 
1.9.1



[PATCH 20/27] e1000e: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update e1000e_phc_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/e1000e/ptp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c 
b/drivers/net/ethernet/intel/e1000e/ptp.c
index 03d5f2a..5b368aa 100644
--- a/drivers/net/ethernet/intel/e1000e/ptp.c
+++ b/drivers/net/ethernet/intel/e1000e/ptp.c
@@ -222,7 +222,7 @@ static int e1000e_phc_settime(struct ptp_clock_info *ptp,
 
/* reset the timecounter */
spin_lock_irqsave(>systim_lock, flags);
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
spin_unlock_irqrestore(>systim_lock, flags);
 
return 0;
-- 
1.9.1



[PATCH 17/27] amd-xgbe: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update xgbe_config_tstamp and xgbe_settime with this new
function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Tom Lendacky 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 4 ++--
 drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 5005c87..aee99de 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1621,8 +1621,8 @@ static int xgbe_config_tstamp(struct xgbe_prv_data *pdata,
xgbe_update_tstamp_addend(pdata, pdata->tstamp_addend);
xgbe_set_tstamp_time(pdata, 0, 0);
 
-   /* Initialize the timecounter */
-   timecounter_init(>tstamp_tc, ktime_to_ns(ktime_get_real()));
+   /* Reset the timecounter */
+   timecounter_reset(>tstamp_tc, ktime_to_ns(ktime_get_real()));
 
return 0;
 }
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
index 486437b..5fcde50 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
@@ -211,7 +211,7 @@ static int xgbe_settime(struct ptp_clock_info *info,
 
spin_lock_irqsave(>tstamp_lock, flags);
 
-   timecounter_init(>tstamp_tc, nsec);
+   timecounter_reset(>tstamp_tc, nsec);
 
spin_unlock_irqrestore(>tstamp_lock, flags);
 
-- 
1.9.1



[PATCH 27/27] timecounter: Remove timecounter_init

2017-12-14 Thread Sagar Arun Kamble
With all timecounter users now initializing timecounter using
timecounter_initialize remove timecounter_init function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Stephen Boyd 
Cc: linux-kernel@vger.kernel.org
---
 include/linux/timecounter.h | 20 +++-
 kernel/time/timecounter.c   | 16 
 2 files changed, 7 insertions(+), 29 deletions(-)

diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h
index e0fd741..e3e1d1e 100644
--- a/include/linux/timecounter.h
+++ b/include/linux/timecounter.h
@@ -46,8 +46,7 @@ struct cyclecounter {
 /**
  * struct timecounter - layer above a %struct cyclecounter which counts 
nanoseconds
  * Contains the state needed by timecounter_read() to detect
- * cycle counter wrap around. Initialize with timecounter_init() when
- * underlying cyclecounter is initialized, with timecounter_initialize() to
+ * cycle counter wrap around. Initialize with timecounter_initialize() to
  * initialize cyclecounter and timecounter fields. Also used to convert
  * cycle counts into the corresponding nanosecond counts with
  * timecounter_cyc2time(). Users of this code are responsible for
@@ -97,18 +96,6 @@ static inline void timecounter_adjtime(struct timecounter 
*tc, s64 delta)
 }
 
 /**
- * timecounter_init - initialize a time counter
- * @tc:Pointer to time counter which is to be 
initialized
- * @start_tstamp:  Arbitrary initial time stamp.
- *
- * After this call the current cycle register (roughly) corresponds to
- * the initial time stamp. Every call to timecounter_read() increments
- * the time stamp counter by the number of elapsed nanoseconds.
- */
-extern void timecounter_init(struct timecounter *tc,
-u64 start_tstamp);
-
-/**
  * timecounter_initialize - initialize a time counter and underlying
cyclecounter
  * @tc:Pointer to time counter which is to be 
initialized
@@ -143,9 +130,8 @@ extern void timecounter_reset(struct timecounter *tc,
  u64 start_tstamp);
 
 /**
- * timecounter_read - return nanoseconds elapsed since timecounter_init() or
- *timecounter_initialize() or timecounter_reset() plus
- *   the initial time stamp
+ * timecounter_read - return nanoseconds elapsed since timecounter_initialize()
+ *   or timecounter_reset() plus the initial time stamp
  * @tc:  Pointer to time counter.
  *
  * In other words, keeps track of time since the same epoch as
diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c
index 3f62fe0..0a02ef0 100644
--- a/kernel/time/timecounter.c
+++ b/kernel/time/timecounter.c
@@ -18,17 +18,6 @@
 #include 
 #include 
 
-void timecounter_init(struct timecounter *tc, u64 start_tstamp)
-{
-   struct cyclecounter *cc = >cc;
-
-   tc->cycle_last = cc->read(cc);
-   tc->nsec = start_tstamp;
-   tc->mask = (1ULL << cc->shift) - 1;
-   tc->frac = 0;
-}
-EXPORT_SYMBOL_GPL(timecounter_init);
-
 void timecounter_initialize(struct timecounter *tc,
u64 (*read)(const struct cyclecounter *cc),
u64 mask,
@@ -43,7 +32,10 @@ void timecounter_initialize(struct timecounter *tc,
cc->mult = mult;
cc->shift = shift;
 
-   timecounter_init(tc, start_tstamp);
+   tc->cycle_last = cc->read(cc);
+   tc->nsec = start_tstamp;
+   tc->mask = (1ULL << cc->shift) - 1;
+   tc->frac = 0;
 }
 EXPORT_SYMBOL_GPL(timecounter_initialize);
 
-- 
1.9.1



[PATCH 17/27] amd-xgbe: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update xgbe_config_tstamp and xgbe_settime with this new
function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Tom Lendacky 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 4 ++--
 drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 5005c87..aee99de 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1621,8 +1621,8 @@ static int xgbe_config_tstamp(struct xgbe_prv_data *pdata,
xgbe_update_tstamp_addend(pdata, pdata->tstamp_addend);
xgbe_set_tstamp_time(pdata, 0, 0);
 
-   /* Initialize the timecounter */
-   timecounter_init(>tstamp_tc, ktime_to_ns(ktime_get_real()));
+   /* Reset the timecounter */
+   timecounter_reset(>tstamp_tc, ktime_to_ns(ktime_get_real()));
 
return 0;
 }
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
index 486437b..5fcde50 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
@@ -211,7 +211,7 @@ static int xgbe_settime(struct ptp_clock_info *info,
 
spin_lock_irqsave(>tstamp_lock, flags);
 
-   timecounter_init(>tstamp_tc, nsec);
+   timecounter_reset(>tstamp_tc, nsec);
 
spin_unlock_irqrestore(>tstamp_lock, flags);
 
-- 
1.9.1



[PATCH 27/27] timecounter: Remove timecounter_init

2017-12-14 Thread Sagar Arun Kamble
With all timecounter users now initializing timecounter using
timecounter_initialize remove timecounter_init function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Stephen Boyd 
Cc: linux-kernel@vger.kernel.org
---
 include/linux/timecounter.h | 20 +++-
 kernel/time/timecounter.c   | 16 
 2 files changed, 7 insertions(+), 29 deletions(-)

diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h
index e0fd741..e3e1d1e 100644
--- a/include/linux/timecounter.h
+++ b/include/linux/timecounter.h
@@ -46,8 +46,7 @@ struct cyclecounter {
 /**
  * struct timecounter - layer above a %struct cyclecounter which counts 
nanoseconds
  * Contains the state needed by timecounter_read() to detect
- * cycle counter wrap around. Initialize with timecounter_init() when
- * underlying cyclecounter is initialized, with timecounter_initialize() to
+ * cycle counter wrap around. Initialize with timecounter_initialize() to
  * initialize cyclecounter and timecounter fields. Also used to convert
  * cycle counts into the corresponding nanosecond counts with
  * timecounter_cyc2time(). Users of this code are responsible for
@@ -97,18 +96,6 @@ static inline void timecounter_adjtime(struct timecounter 
*tc, s64 delta)
 }
 
 /**
- * timecounter_init - initialize a time counter
- * @tc:Pointer to time counter which is to be 
initialized
- * @start_tstamp:  Arbitrary initial time stamp.
- *
- * After this call the current cycle register (roughly) corresponds to
- * the initial time stamp. Every call to timecounter_read() increments
- * the time stamp counter by the number of elapsed nanoseconds.
- */
-extern void timecounter_init(struct timecounter *tc,
-u64 start_tstamp);
-
-/**
  * timecounter_initialize - initialize a time counter and underlying
cyclecounter
  * @tc:Pointer to time counter which is to be 
initialized
@@ -143,9 +130,8 @@ extern void timecounter_reset(struct timecounter *tc,
  u64 start_tstamp);
 
 /**
- * timecounter_read - return nanoseconds elapsed since timecounter_init() or
- *timecounter_initialize() or timecounter_reset() plus
- *   the initial time stamp
+ * timecounter_read - return nanoseconds elapsed since timecounter_initialize()
+ *   or timecounter_reset() plus the initial time stamp
  * @tc:  Pointer to time counter.
  *
  * In other words, keeps track of time since the same epoch as
diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c
index 3f62fe0..0a02ef0 100644
--- a/kernel/time/timecounter.c
+++ b/kernel/time/timecounter.c
@@ -18,17 +18,6 @@
 #include 
 #include 
 
-void timecounter_init(struct timecounter *tc, u64 start_tstamp)
-{
-   struct cyclecounter *cc = >cc;
-
-   tc->cycle_last = cc->read(cc);
-   tc->nsec = start_tstamp;
-   tc->mask = (1ULL << cc->shift) - 1;
-   tc->frac = 0;
-}
-EXPORT_SYMBOL_GPL(timecounter_init);
-
 void timecounter_initialize(struct timecounter *tc,
u64 (*read)(const struct cyclecounter *cc),
u64 mask,
@@ -43,7 +32,10 @@ void timecounter_initialize(struct timecounter *tc,
cc->mult = mult;
cc->shift = shift;
 
-   timecounter_init(tc, start_tstamp);
+   tc->cycle_last = cc->read(cc);
+   tc->nsec = start_tstamp;
+   tc->mask = (1ULL << cc->shift) - 1;
+   tc->frac = 0;
 }
 EXPORT_SYMBOL_GPL(timecounter_initialize);
 
-- 
1.9.1



[PATCH 19/27] net: fec: ptp: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update fec_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Fugang Duan 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/freescale/fec_ptp.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_ptp.c 
b/drivers/net/ethernet/freescale/fec_ptp.c
index 1ba7216..d03ea0e 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -419,7 +419,6 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
 {
struct fec_enet_private *fep =
container_of(ptp, struct fec_enet_private, ptp_caps);
-
u64 ns;
unsigned long flags;
u32 counter;
@@ -439,7 +438,7 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
 
spin_lock_irqsave(>tmreg_lock, flags);
writel(counter, fep->hwp + FEC_ATIME);
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
spin_unlock_irqrestore(>tmreg_lock, flags);
mutex_unlock(>ptp_clk_mutex);
return 0;
-- 
1.9.1



[PATCH 19/27] net: fec: ptp: Use timecounter_reset interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_reset we can update the start time for
timecounter. Update fec_ptp_settime with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Fugang Duan 
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/freescale/fec_ptp.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_ptp.c 
b/drivers/net/ethernet/freescale/fec_ptp.c
index 1ba7216..d03ea0e 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -419,7 +419,6 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
 {
struct fec_enet_private *fep =
container_of(ptp, struct fec_enet_private, ptp_caps);
-
u64 ns;
unsigned long flags;
u32 counter;
@@ -439,7 +438,7 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
 
spin_lock_irqsave(>tmreg_lock, flags);
writel(counter, fep->hwp + FEC_ATIME);
-   timecounter_init(>tc, ns);
+   timecounter_reset(>tc, ns);
spin_unlock_irqrestore(>tmreg_lock, flags);
mutex_unlock(>ptp_clk_mutex);
return 0;
-- 
1.9.1



[PATCH 13/27] qede: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update qede timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Ariel Elior 
Cc: everest-linux...@cavium.com
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/qlogic/qede/qede_ptp.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c 
b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
index 95bb8a8..0d054dc 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
@@ -427,13 +427,12 @@ static int qede_ptp_init(struct qede_dev *edev, bool 
init_tc)
 * unload / load (e.g. MTU change) while it is running.
 */
if (init_tc) {
-   memset(>tc.cc, 0, sizeof(ptp->tc.cc));
-   ptp->tc.cc.read = qede_ptp_read_cc;
-   ptp->tc.cc.mask = CYCLECOUNTER_MASK(64);
-   ptp->tc.cc.shift = 0;
-   ptp->tc.cc.mult = 1;
-
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>tc,
+  qede_ptp_read_cc,
+  CYCLECOUNTER_MASK(64),
+  1,
+  0,
+  ktime_to_ns(ktime_get_real()));
}
 
return rc;
-- 
1.9.1



[PATCH 13/27] qede: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update qede timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Ariel Elior 
Cc: everest-linux...@cavium.com
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/qlogic/qede/qede_ptp.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c 
b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
index 95bb8a8..0d054dc 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
@@ -427,13 +427,12 @@ static int qede_ptp_init(struct qede_dev *edev, bool 
init_tc)
 * unload / load (e.g. MTU change) while it is running.
 */
if (init_tc) {
-   memset(>tc.cc, 0, sizeof(ptp->tc.cc));
-   ptp->tc.cc.read = qede_ptp_read_cc;
-   ptp->tc.cc.mask = CYCLECOUNTER_MASK(64);
-   ptp->tc.cc.shift = 0;
-   ptp->tc.cc.mult = 1;
-
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>tc,
+  qede_ptp_read_cc,
+  CYCLECOUNTER_MASK(64),
+  1,
+  0,
+  ktime_to_ns(ktime_get_real()));
}
 
return rc;
-- 
1.9.1



[PATCH 10/27] ixgbe: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update ixgbe ptp timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h  |  6 +++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  4 +--
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c  | 45 +++
 3 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h 
b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 5c391a0..67e8b5c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -739,6 +739,10 @@ struct ixgbe_adapter {
unsigned long last_rx_timestamp;
spinlock_t tmreg_lock;
struct timecounter hw_tc;
+   u64 (*cc_read)(const struct cyclecounter *cc);
+   u64 cc_mask;
+   u32 cc_mult;
+   u32 cc_shift;
u32 base_incval;
u32 tx_hwtstamp_timeouts;
u32 tx_hwtstamp_skipped;
@@ -994,7 +998,7 @@ static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring 
*rx_ring,
 
 int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
 int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
-void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
+void ixgbe_ptp_start_timecounter(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_reset(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter);
 #ifdef CONFIG_PCI_IOV
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 62a1891..86a337b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7332,7 +7332,7 @@ static void ixgbe_watchdog_link_is_up(struct 
ixgbe_adapter *adapter)
adapter->last_rx_ptp_check = jiffies;
 
if (test_bit(__IXGBE_PTP_RUNNING, >state))
-   ixgbe_ptp_start_cyclecounter(adapter);
+   ixgbe_ptp_start_timecounter(adapter);
 
switch (link_speed) {
case IXGBE_LINK_SPEED_10GB_FULL:
@@ -7400,7 +7400,7 @@ static void ixgbe_watchdog_link_is_down(struct 
ixgbe_adapter *adapter)
adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
 
if (test_bit(__IXGBE_PTP_RUNNING, >state))
-   ixgbe_ptp_start_cyclecounter(adapter);
+   ixgbe_ptp_start_timecounter(adapter);
 
e_info(drv, "NIC Link is Down\n");
netif_carrier_off(netdev);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 6e9f2c0..073c1ef 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -1075,7 +1075,8 @@ static void ixgbe_ptp_link_speed_adjust(struct 
ixgbe_adapter *adapter,
 }
 
 /**
- * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw
+ * ixgbe_ptp_start_timecounter - create the cycle counter from hw and
+ *  initialize corresponding timecounter.
  * @adapter: pointer to the adapter structure
  *
  * This function should be called to set the proper values for the TIMINCA
@@ -1084,10 +1085,9 @@ static void ixgbe_ptp_link_speed_adjust(struct 
ixgbe_adapter *adapter,
  * structure. It should be called whenever a new TIMINCA value is necessary,
  * such as during initialization or when the link speed changes.
  */
-void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
+void ixgbe_ptp_start_timecounter(struct ixgbe_adapter *adapter)
 {
struct ixgbe_hw *hw = >hw;
-   struct cyclecounter cc;
unsigned long flags;
u32 incval = 0;
u32 tsauxc = 0;
@@ -1104,9 +1104,9 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter 
*adapter)
 * proper fix to this problem would require modification of the
 * timecounter delta calculations.
 */
-   cc.mask = CLOCKSOURCE_MASK(64);
-   cc.mult = 1;
-   cc.shift = 0;
+   adapter->cc_mask = CLOCKSOURCE_MASK(64);
+   adapter->cc_mult = 1;
+   adapter->cc_shift = 0;
 
switch (hw->mac.type) {
case ixgbe_mac_X550EM_x:
@@ -1118,13 +1118,13 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter 
*adapter)
 */
fuse0 = IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0));
if (!(fuse0 & IXGBE_FUSES0_300MHZ)) {
-   cc.mult = 3;
-   cc.shift = 2;
+   adapter->cc_mult = 3;
+   adapter->cc_shift = 2;
}
/* fallthrough */
case ixgbe_mac_x550em_a:
case ixgbe_mac_X550:
- 

[PATCH 02/27] timecounter: Introduce timecounter_initialize to update timecounter and cyclecounter

2017-12-14 Thread Sagar Arun Kamble
With cyclecounter coupled with timecounter, we should move to use
interface that initializes entire timecounter structure. This patch
creates function timecounter_initialize that takes cyclecounter
parameters and start time and initializes the timecounter and underlying
cyclecounter.
Function timecounter_init which requires initialized cyclecounter can be
removed once all drivers are migrated to this new interface.

Suggested-by: Richard Cochran 
Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Chris Wilson 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Stephen Boyd 
Cc: linux-kernel@vger.kernel.org
---
 include/linux/timecounter.h | 41 -
 kernel/time/timecounter.c   | 18 ++
 2 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h
index 6daca06..59d3fd7 100644
--- a/include/linux/timecounter.h
+++ b/include/linux/timecounter.h
@@ -46,13 +46,14 @@ struct cyclecounter {
 /**
  * struct timecounter - layer above a %struct cyclecounter which counts 
nanoseconds
  * Contains the state needed by timecounter_read() to detect
- * cycle counter wrap around. Initialize with
- * timecounter_init(). Also used to convert cycle counts into the
- * corresponding nanosecond counts with timecounter_cyc2time(). Users
- * of this code are responsible for initializing the underlying
- * cycle counter hardware, locking issues and reading the time
- * more often than the cycle counter wraps around. The nanosecond
- * counter will only wrap around after ~585 years.
+ * cycle counter wrap around. Initialize with timecounter_init() when
+ * underlying cyclecounter is initialized, with timecounter_initialize() to
+ * initialize cyclecounter and timecounter fields. Also used to convert
+ * cycle counts into the corresponding nanosecond counts with
+ * timecounter_cyc2time(). Users of this code are responsible for
+ * locking issues and reading the time more often than the cycle counter
+ * wraps around. The nanosecond counter will only wrap around after ~585
+ * years.
  *
  * @cc:the cycle counter used by this instance
  * @cycle_last:most recent cycle counter value seen by
@@ -108,8 +109,30 @@ extern void timecounter_init(struct timecounter *tc,
 u64 start_tstamp);
 
 /**
- * timecounter_read - return nanoseconds elapsed since timecounter_init()
- *plus the initial time stamp
+ * timecounter_initialize - initialize a time counter and underlying
+   cyclecounter
+ * @tc:Pointer to time counter which is to be 
initialized
+ * @read:  Pointer to function that returns the current cycle value
+ * @mask:  bitmask for two's complement
+ * subtraction of non 64 bit counters,
+ * @mult:  cycle to nanosecond multiplier
+ * @shift: cycle to nanosecond divisor (power of two)
+ * @start_tstamp:  Arbitrary initial time stamp.
+ *
+ * After this call the current cycle register (roughly) corresponds to
+ * the initial time stamp. Every call to timecounter_read() increments
+ * the time stamp counter by the number of elapsed nanoseconds.
+ */
+extern void timecounter_initialize(struct timecounter *tc,
+  u64 (*read)(const struct cyclecounter *cc),
+  u64 mask,
+  u32 mult,
+  u32 shift,
+  u64 start_tstamp);
+
+/**
+ * timecounter_read - return nanoseconds elapsed since timecounter_init() or
+ *timecounter_initialize() plus the initial time stamp
  * @tc:  Pointer to time counter.
  *
  * In other words, keeps track of time since the same epoch as
diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c
index 7919acb..6d915752 100644
--- a/kernel/time/timecounter.c
+++ b/kernel/time/timecounter.c
@@ -29,6 +29,24 @@ void timecounter_init(struct timecounter *tc, u64 
start_tstamp)
 }
 EXPORT_SYMBOL_GPL(timecounter_init);
 
+void timecounter_initialize(struct timecounter *tc,
+   u64 (*read)(const struct cyclecounter *cc),
+   u64 mask,
+   u32 mult,
+   u32 shift,
+   u64 start_tstamp)
+{
+   struct cyclecounter *cc = >cc;
+
+   cc->read = read;
+   cc->mask = mask;
+   cc->mult = mult;
+   cc->shift = shift;
+
+   timecounter_init(tc, start_tstamp);
+}
+EXPORT_SYMBOL_GPL(timecounter_initialize);
+
 /**
  * timecounter_read_delta - get nanoseconds since 

[PATCH 10/27] ixgbe: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update ixgbe ptp timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h  |  6 +++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  4 +--
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c  | 45 +++
 3 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h 
b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 5c391a0..67e8b5c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -739,6 +739,10 @@ struct ixgbe_adapter {
unsigned long last_rx_timestamp;
spinlock_t tmreg_lock;
struct timecounter hw_tc;
+   u64 (*cc_read)(const struct cyclecounter *cc);
+   u64 cc_mask;
+   u32 cc_mult;
+   u32 cc_shift;
u32 base_incval;
u32 tx_hwtstamp_timeouts;
u32 tx_hwtstamp_skipped;
@@ -994,7 +998,7 @@ static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring 
*rx_ring,
 
 int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
 int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
-void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
+void ixgbe_ptp_start_timecounter(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_reset(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter);
 #ifdef CONFIG_PCI_IOV
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 62a1891..86a337b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7332,7 +7332,7 @@ static void ixgbe_watchdog_link_is_up(struct 
ixgbe_adapter *adapter)
adapter->last_rx_ptp_check = jiffies;
 
if (test_bit(__IXGBE_PTP_RUNNING, >state))
-   ixgbe_ptp_start_cyclecounter(adapter);
+   ixgbe_ptp_start_timecounter(adapter);
 
switch (link_speed) {
case IXGBE_LINK_SPEED_10GB_FULL:
@@ -7400,7 +7400,7 @@ static void ixgbe_watchdog_link_is_down(struct 
ixgbe_adapter *adapter)
adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
 
if (test_bit(__IXGBE_PTP_RUNNING, >state))
-   ixgbe_ptp_start_cyclecounter(adapter);
+   ixgbe_ptp_start_timecounter(adapter);
 
e_info(drv, "NIC Link is Down\n");
netif_carrier_off(netdev);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 6e9f2c0..073c1ef 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -1075,7 +1075,8 @@ static void ixgbe_ptp_link_speed_adjust(struct 
ixgbe_adapter *adapter,
 }
 
 /**
- * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw
+ * ixgbe_ptp_start_timecounter - create the cycle counter from hw and
+ *  initialize corresponding timecounter.
  * @adapter: pointer to the adapter structure
  *
  * This function should be called to set the proper values for the TIMINCA
@@ -1084,10 +1085,9 @@ static void ixgbe_ptp_link_speed_adjust(struct 
ixgbe_adapter *adapter,
  * structure. It should be called whenever a new TIMINCA value is necessary,
  * such as during initialization or when the link speed changes.
  */
-void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
+void ixgbe_ptp_start_timecounter(struct ixgbe_adapter *adapter)
 {
struct ixgbe_hw *hw = >hw;
-   struct cyclecounter cc;
unsigned long flags;
u32 incval = 0;
u32 tsauxc = 0;
@@ -1104,9 +1104,9 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter 
*adapter)
 * proper fix to this problem would require modification of the
 * timecounter delta calculations.
 */
-   cc.mask = CLOCKSOURCE_MASK(64);
-   cc.mult = 1;
-   cc.shift = 0;
+   adapter->cc_mask = CLOCKSOURCE_MASK(64);
+   adapter->cc_mult = 1;
+   adapter->cc_shift = 0;
 
switch (hw->mac.type) {
case ixgbe_mac_X550EM_x:
@@ -1118,13 +1118,13 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter 
*adapter)
 */
fuse0 = IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0));
if (!(fuse0 & IXGBE_FUSES0_300MHZ)) {
-   cc.mult = 3;
-   cc.shift = 2;
+   adapter->cc_mult = 3;
+   adapter->cc_shift = 2;
}
/* fallthrough */
case ixgbe_mac_x550em_a:
case ixgbe_mac_X550:
-   cc.read = ixgbe_ptp_read_X550;
+   adapter->cc_read = 

[PATCH 02/27] timecounter: Introduce timecounter_initialize to update timecounter and cyclecounter

2017-12-14 Thread Sagar Arun Kamble
With cyclecounter coupled with timecounter, we should move to use
interface that initializes entire timecounter structure. This patch
creates function timecounter_initialize that takes cyclecounter
parameters and start time and initializes the timecounter and underlying
cyclecounter.
Function timecounter_init which requires initialized cyclecounter can be
removed once all drivers are migrated to this new interface.

Suggested-by: Richard Cochran 
Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Chris Wilson 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Stephen Boyd 
Cc: linux-kernel@vger.kernel.org
---
 include/linux/timecounter.h | 41 -
 kernel/time/timecounter.c   | 18 ++
 2 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h
index 6daca06..59d3fd7 100644
--- a/include/linux/timecounter.h
+++ b/include/linux/timecounter.h
@@ -46,13 +46,14 @@ struct cyclecounter {
 /**
  * struct timecounter - layer above a %struct cyclecounter which counts 
nanoseconds
  * Contains the state needed by timecounter_read() to detect
- * cycle counter wrap around. Initialize with
- * timecounter_init(). Also used to convert cycle counts into the
- * corresponding nanosecond counts with timecounter_cyc2time(). Users
- * of this code are responsible for initializing the underlying
- * cycle counter hardware, locking issues and reading the time
- * more often than the cycle counter wraps around. The nanosecond
- * counter will only wrap around after ~585 years.
+ * cycle counter wrap around. Initialize with timecounter_init() when
+ * underlying cyclecounter is initialized, with timecounter_initialize() to
+ * initialize cyclecounter and timecounter fields. Also used to convert
+ * cycle counts into the corresponding nanosecond counts with
+ * timecounter_cyc2time(). Users of this code are responsible for
+ * locking issues and reading the time more often than the cycle counter
+ * wraps around. The nanosecond counter will only wrap around after ~585
+ * years.
  *
  * @cc:the cycle counter used by this instance
  * @cycle_last:most recent cycle counter value seen by
@@ -108,8 +109,30 @@ extern void timecounter_init(struct timecounter *tc,
 u64 start_tstamp);
 
 /**
- * timecounter_read - return nanoseconds elapsed since timecounter_init()
- *plus the initial time stamp
+ * timecounter_initialize - initialize a time counter and underlying
+   cyclecounter
+ * @tc:Pointer to time counter which is to be 
initialized
+ * @read:  Pointer to function that returns the current cycle value
+ * @mask:  bitmask for two's complement
+ * subtraction of non 64 bit counters,
+ * @mult:  cycle to nanosecond multiplier
+ * @shift: cycle to nanosecond divisor (power of two)
+ * @start_tstamp:  Arbitrary initial time stamp.
+ *
+ * After this call the current cycle register (roughly) corresponds to
+ * the initial time stamp. Every call to timecounter_read() increments
+ * the time stamp counter by the number of elapsed nanoseconds.
+ */
+extern void timecounter_initialize(struct timecounter *tc,
+  u64 (*read)(const struct cyclecounter *cc),
+  u64 mask,
+  u32 mult,
+  u32 shift,
+  u64 start_tstamp);
+
+/**
+ * timecounter_read - return nanoseconds elapsed since timecounter_init() or
+ *timecounter_initialize() plus the initial time stamp
  * @tc:  Pointer to time counter.
  *
  * In other words, keeps track of time since the same epoch as
diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c
index 7919acb..6d915752 100644
--- a/kernel/time/timecounter.c
+++ b/kernel/time/timecounter.c
@@ -29,6 +29,24 @@ void timecounter_init(struct timecounter *tc, u64 
start_tstamp)
 }
 EXPORT_SYMBOL_GPL(timecounter_init);
 
+void timecounter_initialize(struct timecounter *tc,
+   u64 (*read)(const struct cyclecounter *cc),
+   u64 mask,
+   u32 mult,
+   u32 shift,
+   u64 start_tstamp)
+{
+   struct cyclecounter *cc = >cc;
+
+   cc->read = read;
+   cc->mask = mask;
+   cc->mult = mult;
+   cc->shift = shift;
+
+   timecounter_init(tc, start_tstamp);
+}
+EXPORT_SYMBOL_GPL(timecounter_initialize);
+
 /**
  * timecounter_read_delta - get nanoseconds since last call of this function
  * @tc: Pointer to time counter
-- 
1.9.1



[PATCH 09/27] igb: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update igb ptp timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/igb/igb.h |  4 
 drivers/net/ethernet/intel/igb/igb_ptp.c | 23 ++-
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb.h 
b/drivers/net/ethernet/intel/igb/igb.h
index 4eac4f2..4ef5632 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -566,6 +566,10 @@ struct igb_adapter {
unsigned int ptp_flags;
spinlock_t tmreg_lock;
struct timecounter tc;
+   u64 (*cc_read)(const struct cyclecounter *cc);
+   u64 cc_mask;
+   u32 cc_mult;
+   u32 cc_shift;
u32 tx_hwtstamp_timeouts;
u32 tx_hwtstamp_skipped;
u32 rx_hwtstamp_cleared;
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c 
b/drivers/net/ethernet/intel/igb/igb_ptp.c
index 0745eff..f6c1a8d 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -1126,10 +1126,10 @@ void igb_ptp_init(struct igb_adapter *adapter)
adapter->ptp_caps.gettime64 = igb_ptp_gettime_82576;
adapter->ptp_caps.settime64 = igb_ptp_settime_82576;
adapter->ptp_caps.enable = igb_ptp_feature_enable;
-   adapter->tc.cc.read = igb_ptp_read_82576;
-   adapter->tc.cc.mask = CYCLECOUNTER_MASK(64);
-   adapter->tc.cc.mult = 1;
-   adapter->tc.cc.shift = IGB_82576_TSYNC_SHIFT;
+   adapter->cc_read = igb_ptp_read_82576;
+   adapter->cc_mask = CYCLECOUNTER_MASK(64);
+   adapter->cc_mult = 1;
+   adapter->cc_shift = IGB_82576_TSYNC_SHIFT;
adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK;
break;
case e1000_82580:
@@ -1145,10 +1145,10 @@ void igb_ptp_init(struct igb_adapter *adapter)
adapter->ptp_caps.gettime64 = igb_ptp_gettime_82576;
adapter->ptp_caps.settime64 = igb_ptp_settime_82576;
adapter->ptp_caps.enable = igb_ptp_feature_enable;
-   adapter->tc.cc.read = igb_ptp_read_82580;
-   adapter->tc.cc.mask = CYCLECOUNTER_MASK(IGB_NBITS_82580);
-   adapter->tc.cc.mult = 1;
-   adapter->tc.cc.shift = 0;
+   adapter->cc_read = igb_ptp_read_82580;
+   adapter->cc_mask = CYCLECOUNTER_MASK(IGB_NBITS_82580);
+   adapter->cc_mult = 1;
+   adapter->cc_shift = 0;
adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK;
break;
case e1000_i210:
@@ -1289,7 +1289,12 @@ void igb_ptp_reset(struct igb_adapter *adapter)
 
igb_ptp_write_i210(adapter, );
} else {
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>tc,
+  adapter->cc_read,
+  adapter->cc_mask,
+  adapter->cc_mult,
+  adapter->cc_shift,
+  ktime_to_ns(ktime_get_real()));
}
 out:
spin_unlock_irqrestore(>tmreg_lock, flags);
-- 
1.9.1



[PATCH 01/27] timecounter: Make cyclecounter struct part of timecounter struct

2017-12-14 Thread Sagar Arun Kamble
There is no real need for the users of timecounters to define cyclecounter
and timecounter variables separately. Since timecounter will always be
based on cyclecounter, have cyclecounter struct as member of timecounter
struct.

v2: Rebase.

Suggested-by: Chris Wilson 
Signed-off-by: Sagar Arun Kamble 
Cc: Chris Wilson 
Cc: Richard Cochran 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Stephen Boyd 
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: net...@vger.kernel.org
Cc: intel-wired-...@lists.osuosl.org
Cc: linux-r...@vger.kernel.org
Cc: alsa-de...@alsa-project.org
Cc: kvm...@lists.cs.columbia.edu
Acked-by: Jeff Kirsher  (Intel drivers)
---
 arch/microblaze/kernel/timer.c | 20 ++--
 drivers/clocksource/arm_arch_timer.c   | 19 ++--
 drivers/net/ethernet/amd/xgbe/xgbe-dev.c   |  3 +-
 drivers/net/ethernet/amd/xgbe/xgbe-ptp.c   |  9 +++---
 drivers/net/ethernet/amd/xgbe/xgbe.h   |  1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h|  1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   | 20 ++--
 drivers/net/ethernet/freescale/fec.h   |  1 -
 drivers/net/ethernet/freescale/fec_ptp.c   | 30 +-
 drivers/net/ethernet/intel/e1000e/e1000.h  |  1 -
 drivers/net/ethernet/intel/e1000e/netdev.c | 27 
 drivers/net/ethernet/intel/e1000e/ptp.c|  2 +-
 drivers/net/ethernet/intel/igb/igb.h   |  1 -
 drivers/net/ethernet/intel/igb/igb_ptp.c   | 25 ---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h   |  1 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c   | 17 +-
 drivers/net/ethernet/mellanox/mlx4/en_clock.c  | 28 -
 drivers/net/ethernet/mellanox/mlx4/mlx4_en.h   |  1 -
 .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 34 ++--
 drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++--
 drivers/net/ethernet/ti/cpts.c | 36 --
 drivers/net/ethernet/ti/cpts.h |  1 -
 include/linux/mlx5/driver.h|  1 -
 include/linux/timecounter.h|  4 +--
 include/sound/hdaudio.h|  1 -
 kernel/time/timecounter.c  | 28 -
 sound/hda/hdac_stream.c|  7 +++--
 virt/kvm/arm/arch_timer.c  |  6 ++--
 28 files changed, 163 insertions(+), 182 deletions(-)

diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index 7de941c..b7f89e9 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs)
return (u64)xilinx_clock_read();
 }
 
-static struct timecounter xilinx_tc = {
-   .cc = NULL,
-};
-
 static u64 xilinx_cc_read(const struct cyclecounter *cc)
 {
return xilinx_read(NULL);
 }
 
-static struct cyclecounter xilinx_cc = {
-   .read = xilinx_cc_read,
-   .mask = CLOCKSOURCE_MASK(32),
-   .shift = 8,
+static struct timecounter xilinx_tc = {
+   .cc.read = xilinx_cc_read,
+   .cc.mask = CLOCKSOURCE_MASK(32),
+   .cc.mult = 0,
+   .cc.shift = 8,
 };
 
 static int __init init_xilinx_timecounter(void)
 {
-   xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
-   xilinx_cc.shift);
+   struct cyclecounter *cc = _tc.cc;
+
+   cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift);
 
-   timecounter_init(_tc, _cc, sched_clock());
+   timecounter_init(_tc, sched_clock());
 
return 0;
 }
diff --git a/drivers/clocksource/arm_arch_timer.c 
b/drivers/clocksource/arm_arch_timer.c
index 57cb2f0..31543e5 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -179,11 +179,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter 
*cc)
.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static struct cyclecounter cyclecounter __ro_after_init = {
-   .read   = arch_counter_read_cc,
-   .mask   = CLOCKSOURCE_MASK(56),
-};
-
 struct ate_acpi_oem_info {
char oem_id[ACPI_OEM_ID_SIZE + 1];
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
@@ -915,7 +910,10 @@ static u64 arch_counter_get_cntvct_mem(void)
return ((u64) vct_hi << 32) | vct_lo;
 }
 
-static struct arch_timer_kvm_info arch_timer_kvm_info;
+static struct arch_timer_kvm_info arch_timer_kvm_info = {
+   .timecounter.cc.read = arch_counter_read_cc,
+   .timecounter.cc.mask = CLOCKSOURCE_MASK(56),
+};
 
 struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 {
@@ -925,6 +923,7 @@ struct 

[PATCH 01/27] timecounter: Make cyclecounter struct part of timecounter struct

2017-12-14 Thread Sagar Arun Kamble
There is no real need for the users of timecounters to define cyclecounter
and timecounter variables separately. Since timecounter will always be
based on cyclecounter, have cyclecounter struct as member of timecounter
struct.

v2: Rebase.

Suggested-by: Chris Wilson 
Signed-off-by: Sagar Arun Kamble 
Cc: Chris Wilson 
Cc: Richard Cochran 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Stephen Boyd 
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: net...@vger.kernel.org
Cc: intel-wired-...@lists.osuosl.org
Cc: linux-r...@vger.kernel.org
Cc: alsa-de...@alsa-project.org
Cc: kvm...@lists.cs.columbia.edu
Acked-by: Jeff Kirsher  (Intel drivers)
---
 arch/microblaze/kernel/timer.c | 20 ++--
 drivers/clocksource/arm_arch_timer.c   | 19 ++--
 drivers/net/ethernet/amd/xgbe/xgbe-dev.c   |  3 +-
 drivers/net/ethernet/amd/xgbe/xgbe-ptp.c   |  9 +++---
 drivers/net/ethernet/amd/xgbe/xgbe.h   |  1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h|  1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   | 20 ++--
 drivers/net/ethernet/freescale/fec.h   |  1 -
 drivers/net/ethernet/freescale/fec_ptp.c   | 30 +-
 drivers/net/ethernet/intel/e1000e/e1000.h  |  1 -
 drivers/net/ethernet/intel/e1000e/netdev.c | 27 
 drivers/net/ethernet/intel/e1000e/ptp.c|  2 +-
 drivers/net/ethernet/intel/igb/igb.h   |  1 -
 drivers/net/ethernet/intel/igb/igb_ptp.c   | 25 ---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h   |  1 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c   | 17 +-
 drivers/net/ethernet/mellanox/mlx4/en_clock.c  | 28 -
 drivers/net/ethernet/mellanox/mlx4/mlx4_en.h   |  1 -
 .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 34 ++--
 drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++--
 drivers/net/ethernet/ti/cpts.c | 36 --
 drivers/net/ethernet/ti/cpts.h |  1 -
 include/linux/mlx5/driver.h|  1 -
 include/linux/timecounter.h|  4 +--
 include/sound/hdaudio.h|  1 -
 kernel/time/timecounter.c  | 28 -
 sound/hda/hdac_stream.c|  7 +++--
 virt/kvm/arm/arch_timer.c  |  6 ++--
 28 files changed, 163 insertions(+), 182 deletions(-)

diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index 7de941c..b7f89e9 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs)
return (u64)xilinx_clock_read();
 }
 
-static struct timecounter xilinx_tc = {
-   .cc = NULL,
-};
-
 static u64 xilinx_cc_read(const struct cyclecounter *cc)
 {
return xilinx_read(NULL);
 }
 
-static struct cyclecounter xilinx_cc = {
-   .read = xilinx_cc_read,
-   .mask = CLOCKSOURCE_MASK(32),
-   .shift = 8,
+static struct timecounter xilinx_tc = {
+   .cc.read = xilinx_cc_read,
+   .cc.mask = CLOCKSOURCE_MASK(32),
+   .cc.mult = 0,
+   .cc.shift = 8,
 };
 
 static int __init init_xilinx_timecounter(void)
 {
-   xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
-   xilinx_cc.shift);
+   struct cyclecounter *cc = _tc.cc;
+
+   cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift);
 
-   timecounter_init(_tc, _cc, sched_clock());
+   timecounter_init(_tc, sched_clock());
 
return 0;
 }
diff --git a/drivers/clocksource/arm_arch_timer.c 
b/drivers/clocksource/arm_arch_timer.c
index 57cb2f0..31543e5 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -179,11 +179,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter 
*cc)
.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static struct cyclecounter cyclecounter __ro_after_init = {
-   .read   = arch_counter_read_cc,
-   .mask   = CLOCKSOURCE_MASK(56),
-};
-
 struct ate_acpi_oem_info {
char oem_id[ACPI_OEM_ID_SIZE + 1];
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
@@ -915,7 +910,10 @@ static u64 arch_counter_get_cntvct_mem(void)
return ((u64) vct_hi << 32) | vct_lo;
 }
 
-static struct arch_timer_kvm_info arch_timer_kvm_info;
+static struct arch_timer_kvm_info arch_timer_kvm_info = {
+   .timecounter.cc.read = arch_counter_read_cc,
+   .timecounter.cc.mask = CLOCKSOURCE_MASK(56),
+};
 
 struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 {
@@ -925,6 +923,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 static void __init arch_counter_register(unsigned type)
 {
u64 start_count;
+   struct cyclecounter *cc = _timer_kvm_info.timecounter.cc;
 

[PATCH 09/27] igb: Use timecounter_initialize interface

2017-12-14 Thread Sagar Arun Kamble
With new interface timecounter_initialize we can initialize timecounter
fields and underlying cyclecounter together. Update igb ptp timecounter
init with this new function.

Signed-off-by: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: Jeff Kirsher 
Cc: intel-wired-...@lists.osuosl.org
Cc: net...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/intel/igb/igb.h |  4 
 drivers/net/ethernet/intel/igb/igb_ptp.c | 23 ++-
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb.h 
b/drivers/net/ethernet/intel/igb/igb.h
index 4eac4f2..4ef5632 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -566,6 +566,10 @@ struct igb_adapter {
unsigned int ptp_flags;
spinlock_t tmreg_lock;
struct timecounter tc;
+   u64 (*cc_read)(const struct cyclecounter *cc);
+   u64 cc_mask;
+   u32 cc_mult;
+   u32 cc_shift;
u32 tx_hwtstamp_timeouts;
u32 tx_hwtstamp_skipped;
u32 rx_hwtstamp_cleared;
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c 
b/drivers/net/ethernet/intel/igb/igb_ptp.c
index 0745eff..f6c1a8d 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -1126,10 +1126,10 @@ void igb_ptp_init(struct igb_adapter *adapter)
adapter->ptp_caps.gettime64 = igb_ptp_gettime_82576;
adapter->ptp_caps.settime64 = igb_ptp_settime_82576;
adapter->ptp_caps.enable = igb_ptp_feature_enable;
-   adapter->tc.cc.read = igb_ptp_read_82576;
-   adapter->tc.cc.mask = CYCLECOUNTER_MASK(64);
-   adapter->tc.cc.mult = 1;
-   adapter->tc.cc.shift = IGB_82576_TSYNC_SHIFT;
+   adapter->cc_read = igb_ptp_read_82576;
+   adapter->cc_mask = CYCLECOUNTER_MASK(64);
+   adapter->cc_mult = 1;
+   adapter->cc_shift = IGB_82576_TSYNC_SHIFT;
adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK;
break;
case e1000_82580:
@@ -1145,10 +1145,10 @@ void igb_ptp_init(struct igb_adapter *adapter)
adapter->ptp_caps.gettime64 = igb_ptp_gettime_82576;
adapter->ptp_caps.settime64 = igb_ptp_settime_82576;
adapter->ptp_caps.enable = igb_ptp_feature_enable;
-   adapter->tc.cc.read = igb_ptp_read_82580;
-   adapter->tc.cc.mask = CYCLECOUNTER_MASK(IGB_NBITS_82580);
-   adapter->tc.cc.mult = 1;
-   adapter->tc.cc.shift = 0;
+   adapter->cc_read = igb_ptp_read_82580;
+   adapter->cc_mask = CYCLECOUNTER_MASK(IGB_NBITS_82580);
+   adapter->cc_mult = 1;
+   adapter->cc_shift = 0;
adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK;
break;
case e1000_i210:
@@ -1289,7 +1289,12 @@ void igb_ptp_reset(struct igb_adapter *adapter)
 
igb_ptp_write_i210(adapter, );
} else {
-   timecounter_init(>tc, ktime_to_ns(ktime_get_real()));
+   timecounter_initialize(>tc,
+  adapter->cc_read,
+  adapter->cc_mask,
+  adapter->cc_mult,
+  adapter->cc_shift,
+  ktime_to_ns(ktime_get_real()));
}
 out:
spin_unlock_irqrestore(>tmreg_lock, flags);
-- 
1.9.1



[PATCH 00/27] timecounter/cyclecounter struct/interface update

2017-12-14 Thread Sagar Arun Kamble
This series makes cyclecounter part of timecounter and introduces two
new interface functions timecounter_initialize() for initializing both
timecounter and cyclecounter fields and timecounter_reset() for setting
start time of timecounter. Updates all drivers with new functions and
removes function timecounter_init().

Cc: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Stephen Boyd 
Cc: linux-kernel@vger.kernel.org

Sagar Arun Kamble (27):
  timecounter: Make cyclecounter struct part of timecounter struct
  timecounter: Introduce timecounter_initialize to update timecounter
and cyclecounter
  microblaze: Use timecounter_initialize interface
  clocksource/arm_arch_timer: Use timecounter_initialize interface
  amd-xgbe: Use timecounter_initialize interface
  bnx2x: Use timecounter_initialize interface
  fec: Use timecounter_initialize interface
  e1000e: Use timecounter_initialize interface
  igb: Use timecounter_initialize interface
  ixgbe: Use timecounter_initialize interface
  net/mlx4: Use timecounter_initialize interface
  net/mlx5: Use timecounter_initialize interface
  qede: Use timecounter_initialize interface
  net: cpts: Use timecounter_initialize interface
  ALSA: hda - Use timecounter_initialize interface
  timecounter: Introduce timecounter_reset
  amd-xgbe: Use timecounter_reset interface
  bnx2x: Use timecounter_reset interface
  net: fec: ptp: Use timecounter_reset interface
  e1000e: Use timecounter_reset interface
  igb: Use timecounter_reset interface
  ixgbe: Use timecounter_reset interface
  net/mlx4: Use timecounter_reset interface
  net/mlx5: Use timecounter_reset interface
  qede: Use timecounter_reset interface
  net: cpts: Use timecounter_reset interface
  timecounter: Remove timecounter_init

 arch/microblaze/kernel/timer.c | 23 -
 drivers/clocksource/arm_arch_timer.c   | 16 +++---
 drivers/net/ethernet/amd/xgbe/xgbe-dev.c   |  5 +-
 drivers/net/ethernet/amd/xgbe/xgbe-ptp.c   | 18 +++
 drivers/net/ethernet/amd/xgbe/xgbe.h   |  1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h|  1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   | 24 -
 drivers/net/ethernet/freescale/fec.h   |  1 -
 drivers/net/ethernet/freescale/fec_ptp.c   | 34 ++---
 drivers/net/ethernet/intel/e1000e/e1000.h  |  5 +-
 drivers/net/ethernet/intel/e1000e/netdev.c | 34 +++--
 drivers/net/ethernet/intel/e1000e/ptp.c|  2 +-
 drivers/net/ethernet/intel/igb/igb.h   |  5 +-
 drivers/net/ethernet/intel/igb/igb_ptp.c   | 30 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe.h   |  7 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c   | 58 --
 drivers/net/ethernet/mellanox/mlx4/en_clock.c  | 29 +--
 drivers/net/ethernet/mellanox/mlx4/mlx4_en.h   |  1 -
 .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 38 +++---
 drivers/net/ethernet/qlogic/qede/qede_ptp.c| 21 
 drivers/net/ethernet/ti/cpts.c | 45 ++---
 drivers/net/ethernet/ti/cpts.h |  4 +-
 include/linux/mlx5/driver.h|  1 -
 include/linux/timecounter.h| 52 +--
 include/sound/hdaudio.h|  1 -
 kernel/time/timecounter.c  | 49 --
 sound/hda/hdac_stream.c| 17 +++
 virt/kvm/arm/arch_timer.c  |  6 +--
 29 files changed, 291 insertions(+), 241 deletions(-)

-- 
1.9.1



[PATCH 00/27] timecounter/cyclecounter struct/interface update

2017-12-14 Thread Sagar Arun Kamble
This series makes cyclecounter part of timecounter and introduces two
new interface functions timecounter_initialize() for initializing both
timecounter and cyclecounter fields and timecounter_reset() for setting
start time of timecounter. Updates all drivers with new functions and
removes function timecounter_init().

Cc: Sagar Arun Kamble 
Cc: Richard Cochran 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Stephen Boyd 
Cc: linux-kernel@vger.kernel.org

Sagar Arun Kamble (27):
  timecounter: Make cyclecounter struct part of timecounter struct
  timecounter: Introduce timecounter_initialize to update timecounter
and cyclecounter
  microblaze: Use timecounter_initialize interface
  clocksource/arm_arch_timer: Use timecounter_initialize interface
  amd-xgbe: Use timecounter_initialize interface
  bnx2x: Use timecounter_initialize interface
  fec: Use timecounter_initialize interface
  e1000e: Use timecounter_initialize interface
  igb: Use timecounter_initialize interface
  ixgbe: Use timecounter_initialize interface
  net/mlx4: Use timecounter_initialize interface
  net/mlx5: Use timecounter_initialize interface
  qede: Use timecounter_initialize interface
  net: cpts: Use timecounter_initialize interface
  ALSA: hda - Use timecounter_initialize interface
  timecounter: Introduce timecounter_reset
  amd-xgbe: Use timecounter_reset interface
  bnx2x: Use timecounter_reset interface
  net: fec: ptp: Use timecounter_reset interface
  e1000e: Use timecounter_reset interface
  igb: Use timecounter_reset interface
  ixgbe: Use timecounter_reset interface
  net/mlx4: Use timecounter_reset interface
  net/mlx5: Use timecounter_reset interface
  qede: Use timecounter_reset interface
  net: cpts: Use timecounter_reset interface
  timecounter: Remove timecounter_init

 arch/microblaze/kernel/timer.c | 23 -
 drivers/clocksource/arm_arch_timer.c   | 16 +++---
 drivers/net/ethernet/amd/xgbe/xgbe-dev.c   |  5 +-
 drivers/net/ethernet/amd/xgbe/xgbe-ptp.c   | 18 +++
 drivers/net/ethernet/amd/xgbe/xgbe.h   |  1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h|  1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   | 24 -
 drivers/net/ethernet/freescale/fec.h   |  1 -
 drivers/net/ethernet/freescale/fec_ptp.c   | 34 ++---
 drivers/net/ethernet/intel/e1000e/e1000.h  |  5 +-
 drivers/net/ethernet/intel/e1000e/netdev.c | 34 +++--
 drivers/net/ethernet/intel/e1000e/ptp.c|  2 +-
 drivers/net/ethernet/intel/igb/igb.h   |  5 +-
 drivers/net/ethernet/intel/igb/igb_ptp.c   | 30 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe.h   |  7 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c   | 58 --
 drivers/net/ethernet/mellanox/mlx4/en_clock.c  | 29 +--
 drivers/net/ethernet/mellanox/mlx4/mlx4_en.h   |  1 -
 .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 38 +++---
 drivers/net/ethernet/qlogic/qede/qede_ptp.c| 21 
 drivers/net/ethernet/ti/cpts.c | 45 ++---
 drivers/net/ethernet/ti/cpts.h |  4 +-
 include/linux/mlx5/driver.h|  1 -
 include/linux/timecounter.h| 52 +--
 include/sound/hdaudio.h|  1 -
 kernel/time/timecounter.c  | 49 --
 sound/hda/hdac_stream.c| 17 +++
 virt/kvm/arm/arch_timer.c  |  6 +--
 29 files changed, 291 insertions(+), 241 deletions(-)

-- 
1.9.1



Re: [PATCH 2/6] blk-mq: replace timeout synchronization with a RCU and generation based scheme

2017-12-14 Thread Peter Zijlstra
On Fri, Dec 15, 2017 at 10:12:50AM +0800, jianchao.wang wrote:
> > That only makes it a little better:
> > 
> > Task-A  Worker
> > 
> > write_seqcount_begin()
> > blk_mq_rw_update_state(rq, IN_FLIGHT)
> > blk_add_timer(rq)
> > 
> > schedule_work()
> > 
> > 
> > read_seqcount_begin()
> > while(seq & 1)
> > cpu_relax();
> > 
> Hi Peter
> 
> The current seqcount read side is as below:
>   do {
>   start = read_seqcount_begin(>gstate_seq);


static inline unsigned read_seqcount_begin(const seqcount_t *s)
{
seqcount_lockdep_reader_access(s);
return raw_read_seqcount_begin(s);
}

static inline unsigned raw_read_seqcount_begin(const seqcount_t *s)
{
unsigned ret = __read_seqcount_begin(s);
smp_rmb();
return ret;
}

static inline unsigned __read_seqcount_begin(const seqcount_t *s)
{
unsigned ret;

repeat:
ret = READ_ONCE(s->sequence);
if (unlikely(ret & 1)) {
cpu_relax();
goto repeat;
}
return ret;
}


Re: [PATCH 2/6] blk-mq: replace timeout synchronization with a RCU and generation based scheme

2017-12-14 Thread Peter Zijlstra
On Fri, Dec 15, 2017 at 10:12:50AM +0800, jianchao.wang wrote:
> > That only makes it a little better:
> > 
> > Task-A  Worker
> > 
> > write_seqcount_begin()
> > blk_mq_rw_update_state(rq, IN_FLIGHT)
> > blk_add_timer(rq)
> > 
> > schedule_work()
> > 
> > 
> > read_seqcount_begin()
> > while(seq & 1)
> > cpu_relax();
> > 
> Hi Peter
> 
> The current seqcount read side is as below:
>   do {
>   start = read_seqcount_begin(>gstate_seq);


static inline unsigned read_seqcount_begin(const seqcount_t *s)
{
seqcount_lockdep_reader_access(s);
return raw_read_seqcount_begin(s);
}

static inline unsigned raw_read_seqcount_begin(const seqcount_t *s)
{
unsigned ret = __read_seqcount_begin(s);
smp_rmb();
return ret;
}

static inline unsigned __read_seqcount_begin(const seqcount_t *s)
{
unsigned ret;

repeat:
ret = READ_ONCE(s->sequence);
if (unlikely(ret & 1)) {
cpu_relax();
goto repeat;
}
return ret;
}


Re: [PATCH] ASoC: nau8825: fix issue that pop noise when start capture

2017-12-14 Thread John Hsu

On 12/12/2017 3:10 AM, abhijeet.ku...@intel.com wrote:

From: Abhijeet Kumar 

In skylake platform, we hear a loud pop noise(0 dB) at start of
audio capture power up sequence. This patch removes the pop noise
from the recording by adding a delay before enabling ADC.

Signed-off-by: Abhijeet Kumar 
---
 sound/soc/codecs/nau8825.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index 714ce17da717..e853a6dfd33b 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -905,6 +905,7 @@ static int nau8825_adc_event(struct snd_soc_dapm_widget *w,

  switch (event) {
  case SND_SOC_DAPM_POST_PMU:
+ msleep(125);
  regmap_update_bits(nau8825->regmap, NAU8825_REG_ENA_CTRL,
  NAU8825_ENABLE_ADC, NAU8825_ENABLE_ADC);
  break;


The solution is fine for me. It's verified in my device and indeed
helps to reduce the capture pop noise. I think the little delay
is acceptable.



===
The privileged confidential information contained in this email is intended for 
use only by the addressees as indicated by the original sender of this email. 
If you are not the addressee indicated in this email or are not responsible for 
delivery of the email to such a person, please kindly reply to the sender 
indicating this fact and delete all copies of it from your computer and network 
server immediately. Your cooperation is highly appreciated. It is advised that 
any unauthorized use of confidential information of Nuvoton is strictly 
prohibited; and any information in this email irrelevant to the official 
business of Nuvoton shall be deemed as neither given nor endorsed by Nuvoton.


Re: [PATCH] ASoC: nau8825: fix issue that pop noise when start capture

2017-12-14 Thread John Hsu

On 12/12/2017 3:10 AM, abhijeet.ku...@intel.com wrote:

From: Abhijeet Kumar 

In skylake platform, we hear a loud pop noise(0 dB) at start of
audio capture power up sequence. This patch removes the pop noise
from the recording by adding a delay before enabling ADC.

Signed-off-by: Abhijeet Kumar 
---
 sound/soc/codecs/nau8825.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index 714ce17da717..e853a6dfd33b 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -905,6 +905,7 @@ static int nau8825_adc_event(struct snd_soc_dapm_widget *w,

  switch (event) {
  case SND_SOC_DAPM_POST_PMU:
+ msleep(125);
  regmap_update_bits(nau8825->regmap, NAU8825_REG_ENA_CTRL,
  NAU8825_ENABLE_ADC, NAU8825_ENABLE_ADC);
  break;


The solution is fine for me. It's verified in my device and indeed
helps to reduce the capture pop noise. I think the little delay
is acceptable.



===
The privileged confidential information contained in this email is intended for 
use only by the addressees as indicated by the original sender of this email. 
If you are not the addressee indicated in this email or are not responsible for 
delivery of the email to such a person, please kindly reply to the sender 
indicating this fact and delete all copies of it from your computer and network 
server immediately. Your cooperation is highly appreciated. It is advised that 
any unauthorized use of confidential information of Nuvoton is strictly 
prohibited; and any information in this email irrelevant to the official 
business of Nuvoton shall be deemed as neither given nor endorsed by Nuvoton.


Re: [PATCH] iommu/vt-d: Fix shift overflow in qi_flush_dev_iotlb

2017-12-14 Thread Peter Xu
On Wed, Dec 13, 2017 at 11:31:02AM -0600, Hook, Gary wrote:
> On 12/13/2017 11:15 AM, Alex Williamson wrote:
> > On Wed, 13 Dec 2017 10:41:47 -0600
> > "Hook, Gary"  wrote:
> > 
> > > On 12/13/2017 9:58 AM, Alex Williamson wrote:
> > > > On Wed, 13 Dec 2017 15:13:55 +0800
> > > > Peter Xu  wrote:
> > > > > On Tue, Dec 12, 2017 at 03:43:08PM -0700, Alex Williamson wrote:
> > > > > 
> > > > > [...]
> > > > > > diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
> > > > > > index 9a7ffd13c7f0..87888b102057 100644
> > > > > > --- a/drivers/iommu/dmar.c
> > > > > > +++ b/drivers/iommu/dmar.c
> > > > > > @@ -1345,7 +1345,9 @@ void qi_flush_dev_iotlb(struct intel_iommu 
> > > > > > *iommu, u16 sid, u16 qdep,
> > > > > > struct qi_desc desc;
> > > > > > if (mask) {
> > > > > > -   BUG_ON(addr & ((1 << (VTD_PAGE_SHIFT + mask)) - 1));
> > > > > > +   BUG_ON((mask > MAX_AGAW_PFN_WIDTH) ||
> > > > > > +  ((mask == MAX_AGAW_PFN_WIDTH) && addr) ||
> > > > > > +  (addr & ((1 << (VTD_PAGE_SHIFT + mask)) - 1)));
> > > > > 
> > > > > Could it work if we just use 1ULL instead of 1 here?  Thanks,
> > > > 
> > > > In either case we're talking about shifting off the end of the
> > > > variable, which I understand to be undefined.  Right?  Thanks,
> > > 
> > > How so? Bits fall off the left (MSB) end, zeroes fill in the right (LSB)
> > > end. I believe that behavior is pretty set.
> > 
> > Maybe I'm relying too much on stackoverflow, but:
> > 
> > https://stackoverflow.com/questions/11270492/what-does-the-c-standard-say-about-bitshifting-more-bits-than-the-width-of-type
> 
> No, probably not. I don't have my copy of c99 handy, so can't check it. But
> it is beyond me why any compiler implementation would choose to use a rotate
> instead of a shift... probably a performance issue.
> 
> So, yeah, when you have silly parameters, you get what you get.
> 
> I'll stick to my suggestion. Which seems unambiguous... but I could be
> wrong.

Hi, Alex, Hook,

I did a quick test:

xz-mi:tmp $ cat a.c
#include 

void main(void)
{
unsigned long long val = 0x8001ULL;
int shift; 

printf("origin: 0x%llx\n", val);
shift = 1; printf("shl 1: 0x%llx\n", val << shift);
shift = 62; printf("shl 62: 0x%llx\n", val << shift);
shift = 63; printf("shl 63: 0x%llx\n", val << shift);
shift = 64; printf("shl 64: 0x%llx\n", val << shift);
shift = 65; printf("shl 65: 0x%llx\n", val << shift);
}
xz-mi:tmp $ gcc -std=c99 a.c
xz-mi:tmp $ ./a.out 
origin: 0x8001
shl 1: 0x2
shl 62: 0x4000
shl 63: 0x8000
shl 64: 0x8001
shl 65: 0x2
xz-mi:tmp $ objdump -d a.out | grep -A20 ""
004004d7 :
  4004d7:   55  push   %rbp
  4004d8:   48 89 e5mov%rsp,%rbp
  4004db:   48 83 ec 10 sub$0x10,%rsp
  4004df:   48 b8 01 00 00 00 00movabs $0x8001,%rax
  4004e6:   00 00 80 
  4004e9:   48 89 45 f8 mov%rax,-0x8(%rbp)
  4004ed:   48 8b 45 f8 mov-0x8(%rbp),%rax
  4004f1:   48 89 c6mov%rax,%rsi
  4004f4:   bf 60 06 40 00  mov$0x400660,%edi
  4004f9:   b8 00 00 00 00  mov$0x0,%eax
  4004fe:   e8 ed fe ff ff  callq  4003f0 
  400503:   c7 45 f4 01 00 00 00movl   $0x1,-0xc(%rbp)
  40050a:   8b 45 f4mov-0xc(%rbp),%eax
  40050d:   48 8b 55 f8 mov-0x8(%rbp),%rdx
  400511:   89 c1   mov%eax,%ecx
  400513:   48 d3 e2shl%cl,%rdx
  400516:   48 89 d0mov%rdx,%rax
  400519:   48 89 c6mov%rax,%rsi
  40051c:   bf 70 06 40 00  mov$0x400670,%edi
  400521:   b8 00 00 00 00  mov$0x0,%eax

So it seems not really a rotation operation, but it looks more like
convering a "shifting N" into "shifting N%64" when N>=64.  So now I
agree with Alex's change.  Thanks all.

-- 
Peter Xu


Re: [PATCH] iommu/vt-d: Fix shift overflow in qi_flush_dev_iotlb

2017-12-14 Thread Peter Xu
On Wed, Dec 13, 2017 at 11:31:02AM -0600, Hook, Gary wrote:
> On 12/13/2017 11:15 AM, Alex Williamson wrote:
> > On Wed, 13 Dec 2017 10:41:47 -0600
> > "Hook, Gary"  wrote:
> > 
> > > On 12/13/2017 9:58 AM, Alex Williamson wrote:
> > > > On Wed, 13 Dec 2017 15:13:55 +0800
> > > > Peter Xu  wrote:
> > > > > On Tue, Dec 12, 2017 at 03:43:08PM -0700, Alex Williamson wrote:
> > > > > 
> > > > > [...]
> > > > > > diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
> > > > > > index 9a7ffd13c7f0..87888b102057 100644
> > > > > > --- a/drivers/iommu/dmar.c
> > > > > > +++ b/drivers/iommu/dmar.c
> > > > > > @@ -1345,7 +1345,9 @@ void qi_flush_dev_iotlb(struct intel_iommu 
> > > > > > *iommu, u16 sid, u16 qdep,
> > > > > > struct qi_desc desc;
> > > > > > if (mask) {
> > > > > > -   BUG_ON(addr & ((1 << (VTD_PAGE_SHIFT + mask)) - 1));
> > > > > > +   BUG_ON((mask > MAX_AGAW_PFN_WIDTH) ||
> > > > > > +  ((mask == MAX_AGAW_PFN_WIDTH) && addr) ||
> > > > > > +  (addr & ((1 << (VTD_PAGE_SHIFT + mask)) - 1)));
> > > > > 
> > > > > Could it work if we just use 1ULL instead of 1 here?  Thanks,
> > > > 
> > > > In either case we're talking about shifting off the end of the
> > > > variable, which I understand to be undefined.  Right?  Thanks,
> > > 
> > > How so? Bits fall off the left (MSB) end, zeroes fill in the right (LSB)
> > > end. I believe that behavior is pretty set.
> > 
> > Maybe I'm relying too much on stackoverflow, but:
> > 
> > https://stackoverflow.com/questions/11270492/what-does-the-c-standard-say-about-bitshifting-more-bits-than-the-width-of-type
> 
> No, probably not. I don't have my copy of c99 handy, so can't check it. But
> it is beyond me why any compiler implementation would choose to use a rotate
> instead of a shift... probably a performance issue.
> 
> So, yeah, when you have silly parameters, you get what you get.
> 
> I'll stick to my suggestion. Which seems unambiguous... but I could be
> wrong.

Hi, Alex, Hook,

I did a quick test:

xz-mi:tmp $ cat a.c
#include 

void main(void)
{
unsigned long long val = 0x8001ULL;
int shift; 

printf("origin: 0x%llx\n", val);
shift = 1; printf("shl 1: 0x%llx\n", val << shift);
shift = 62; printf("shl 62: 0x%llx\n", val << shift);
shift = 63; printf("shl 63: 0x%llx\n", val << shift);
shift = 64; printf("shl 64: 0x%llx\n", val << shift);
shift = 65; printf("shl 65: 0x%llx\n", val << shift);
}
xz-mi:tmp $ gcc -std=c99 a.c
xz-mi:tmp $ ./a.out 
origin: 0x8001
shl 1: 0x2
shl 62: 0x4000
shl 63: 0x8000
shl 64: 0x8001
shl 65: 0x2
xz-mi:tmp $ objdump -d a.out | grep -A20 ""
004004d7 :
  4004d7:   55  push   %rbp
  4004d8:   48 89 e5mov%rsp,%rbp
  4004db:   48 83 ec 10 sub$0x10,%rsp
  4004df:   48 b8 01 00 00 00 00movabs $0x8001,%rax
  4004e6:   00 00 80 
  4004e9:   48 89 45 f8 mov%rax,-0x8(%rbp)
  4004ed:   48 8b 45 f8 mov-0x8(%rbp),%rax
  4004f1:   48 89 c6mov%rax,%rsi
  4004f4:   bf 60 06 40 00  mov$0x400660,%edi
  4004f9:   b8 00 00 00 00  mov$0x0,%eax
  4004fe:   e8 ed fe ff ff  callq  4003f0 
  400503:   c7 45 f4 01 00 00 00movl   $0x1,-0xc(%rbp)
  40050a:   8b 45 f4mov-0xc(%rbp),%eax
  40050d:   48 8b 55 f8 mov-0x8(%rbp),%rdx
  400511:   89 c1   mov%eax,%ecx
  400513:   48 d3 e2shl%cl,%rdx
  400516:   48 89 d0mov%rdx,%rax
  400519:   48 89 c6mov%rax,%rsi
  40051c:   bf 70 06 40 00  mov$0x400670,%edi
  400521:   b8 00 00 00 00  mov$0x0,%eax

So it seems not really a rotation operation, but it looks more like
convering a "shifting N" into "shifting N%64" when N>=64.  So now I
agree with Alex's change.  Thanks all.

-- 
Peter Xu


[PATCH v4 2/2] misc: xlnx_vcu: Add Xilinx ZYNQMP VCU logicoreIP init driver

2017-12-14 Thread Dhaval Shah
Xilinx ZYNQMP logicoreIP Init driver is based on the new
LogiCoreIP design created. This driver provides the processing system
and programmable logic isolation. Set the frequency based on the clock
information get from the logicoreIP register set.

It is put in drivers/misc as there is no subsystem for this logicoreIP.

Signed-off-by: Dhaval Shah 
---
Changes since v4:
 * Indent the help text (below) by 2 additional spaces, as documented in 
coding-style.rst
 * Spell check are resolved as per the review comment.
 * inline the read() and write() functions..
 * multi-line comment style
 * Updated subject line prefix
Changes since v3:
 No Changes.
Changes since v2:
 * Removed the "default n" from the Kconfig
 * More help text added to explain more about the logicoreIP driver
 * SPDX id is relocated at top of the file with // style comment
 * Removed the export API and header file and make it a single driver
   which provides logocoreIP init.
 * Provide the information in commit message as well for the why driver
   in drivers/misc.

 drivers/misc/Kconfig|  15 ++
 drivers/misc/Makefile   |   1 +
 drivers/misc/xlnx_vcu.c | 631 
 3 files changed, 647 insertions(+)
 create mode 100644 drivers/misc/xlnx_vcu.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index f1a5c23..e679936 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -496,6 +496,21 @@ config PCI_ENDPOINT_TEST
Enable this configuration option to enable the host side test driver
for PCI Endpoint.
 
+config XILINX_VCU
+   tristate "Xilinx VCU logicoreIP Init"
+   help
+ Provides the driver to enable and disable the isolation between the
+ processing system and programmable logic part by using the logicoreIP
+ register set. This driver also configures the frequency based on the
+ clock information from the logicoreIP register set.
+
+ If you say yes here you get support for the logicoreIP.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called xlnx_vcu.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 5ca5f64..a6bd0b1 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_CXL_BASE)+= cxl/
 obj-$(CONFIG_ASPEED_LPC_CTRL)  += aspeed-lpc-ctrl.o
 obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
 obj-$(CONFIG_PCI_ENDPOINT_TEST)+= pci_endpoint_test.o
+obj-$(CONFIG_XILINX_VCU)   += xlnx_vcu.o
 
 lkdtm-$(CONFIG_LKDTM)  += lkdtm_core.o
 lkdtm-$(CONFIG_LKDTM)  += lkdtm_bugs.o
diff --git a/drivers/misc/xlnx_vcu.c b/drivers/misc/xlnx_vcu.c
new file mode 100644
index 000..f489d34
--- /dev/null
+++ b/drivers/misc/xlnx_vcu.c
@@ -0,0 +1,631 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx VCU Init
+ *
+ * Copyright (C) 2016 - 2017 Xilinx, Inc.
+ *
+ * Contacts   Dhaval Shah 
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Address map for different registers implemented in the VCU LogiCORE IP. */
+#define VCU_ECODER_ENABLE  0x00
+#define VCU_DECODER_ENABLE 0x04
+#define VCU_MEMORY_DEPTH   0x08
+#define VCU_ENC_COLOR_DEPTH0x0c
+#define VCU_ENC_VERTICAL_RANGE 0x10
+#define VCU_ENC_FRAME_SIZE_X   0x14
+#define VCU_ENC_FRAME_SIZE_Y   0x18
+#define VCU_ENC_COLOR_FORMAT   0x1c
+#define VCU_ENC_FPS0x20
+#define VCU_MCU_CLK0x24
+#define VCU_CORE_CLK   0x28
+#define VCU_PLL_BYPASS 0x2c
+#define VCU_ENC_CLK0x30
+#define VCU_PLL_CLK0x34
+#define VCU_ENC_VIDEO_STANDARD 0x38
+#define VCU_STATUS 0x3c
+#define VCU_AXI_ENC_CLK0x40
+#define VCU_AXI_DEC_CLK0x44
+#define VCU_AXI_MCU_CLK0x48
+#define VCU_DEC_VIDEO_STANDARD 0x4c
+#define VCU_DEC_FRAME_SIZE_X   0x50
+#define VCU_DEC_FRAME_SIZE_Y   0x54
+#define VCU_DEC_FPS0x58
+#define VCU_BUFFER_B_FRAME 0x5c
+#define VCU_WPP_EN 0x60
+#define VCU_PLL_CLK_DEC0x64
+#define VCU_GASKET_INIT0x74
+#define VCU_GASKET_VALUE   0x03
+
+/* vcu slcr registers, bitmask and shift */
+#define VCU_PLL_CTRL   0x24
+#define VCU_PLL_CTRL_RESET_MASK0x01
+#define VCU_PLL_CTRL_RESET_SHIFT   0
+#define VCU_PLL_CTRL_BYPASS_MASK   0x01
+#define VCU_PLL_CTRL_BYPASS_SHIFT  3
+#define VCU_PLL_CTRL_FBDIV_MASK0x7f
+#define VCU_PLL_CTRL_FBDIV_SHIFT   8
+#define 

[PATCH v4 2/2] misc: xlnx_vcu: Add Xilinx ZYNQMP VCU logicoreIP init driver

2017-12-14 Thread Dhaval Shah
Xilinx ZYNQMP logicoreIP Init driver is based on the new
LogiCoreIP design created. This driver provides the processing system
and programmable logic isolation. Set the frequency based on the clock
information get from the logicoreIP register set.

It is put in drivers/misc as there is no subsystem for this logicoreIP.

Signed-off-by: Dhaval Shah 
---
Changes since v4:
 * Indent the help text (below) by 2 additional spaces, as documented in 
coding-style.rst
 * Spell check are resolved as per the review comment.
 * inline the read() and write() functions..
 * multi-line comment style
 * Updated subject line prefix
Changes since v3:
 No Changes.
Changes since v2:
 * Removed the "default n" from the Kconfig
 * More help text added to explain more about the logicoreIP driver
 * SPDX id is relocated at top of the file with // style comment
 * Removed the export API and header file and make it a single driver
   which provides logocoreIP init.
 * Provide the information in commit message as well for the why driver
   in drivers/misc.

 drivers/misc/Kconfig|  15 ++
 drivers/misc/Makefile   |   1 +
 drivers/misc/xlnx_vcu.c | 631 
 3 files changed, 647 insertions(+)
 create mode 100644 drivers/misc/xlnx_vcu.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index f1a5c23..e679936 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -496,6 +496,21 @@ config PCI_ENDPOINT_TEST
Enable this configuration option to enable the host side test driver
for PCI Endpoint.
 
+config XILINX_VCU
+   tristate "Xilinx VCU logicoreIP Init"
+   help
+ Provides the driver to enable and disable the isolation between the
+ processing system and programmable logic part by using the logicoreIP
+ register set. This driver also configures the frequency based on the
+ clock information from the logicoreIP register set.
+
+ If you say yes here you get support for the logicoreIP.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called xlnx_vcu.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 5ca5f64..a6bd0b1 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_CXL_BASE)+= cxl/
 obj-$(CONFIG_ASPEED_LPC_CTRL)  += aspeed-lpc-ctrl.o
 obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
 obj-$(CONFIG_PCI_ENDPOINT_TEST)+= pci_endpoint_test.o
+obj-$(CONFIG_XILINX_VCU)   += xlnx_vcu.o
 
 lkdtm-$(CONFIG_LKDTM)  += lkdtm_core.o
 lkdtm-$(CONFIG_LKDTM)  += lkdtm_bugs.o
diff --git a/drivers/misc/xlnx_vcu.c b/drivers/misc/xlnx_vcu.c
new file mode 100644
index 000..f489d34
--- /dev/null
+++ b/drivers/misc/xlnx_vcu.c
@@ -0,0 +1,631 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx VCU Init
+ *
+ * Copyright (C) 2016 - 2017 Xilinx, Inc.
+ *
+ * Contacts   Dhaval Shah 
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Address map for different registers implemented in the VCU LogiCORE IP. */
+#define VCU_ECODER_ENABLE  0x00
+#define VCU_DECODER_ENABLE 0x04
+#define VCU_MEMORY_DEPTH   0x08
+#define VCU_ENC_COLOR_DEPTH0x0c
+#define VCU_ENC_VERTICAL_RANGE 0x10
+#define VCU_ENC_FRAME_SIZE_X   0x14
+#define VCU_ENC_FRAME_SIZE_Y   0x18
+#define VCU_ENC_COLOR_FORMAT   0x1c
+#define VCU_ENC_FPS0x20
+#define VCU_MCU_CLK0x24
+#define VCU_CORE_CLK   0x28
+#define VCU_PLL_BYPASS 0x2c
+#define VCU_ENC_CLK0x30
+#define VCU_PLL_CLK0x34
+#define VCU_ENC_VIDEO_STANDARD 0x38
+#define VCU_STATUS 0x3c
+#define VCU_AXI_ENC_CLK0x40
+#define VCU_AXI_DEC_CLK0x44
+#define VCU_AXI_MCU_CLK0x48
+#define VCU_DEC_VIDEO_STANDARD 0x4c
+#define VCU_DEC_FRAME_SIZE_X   0x50
+#define VCU_DEC_FRAME_SIZE_Y   0x54
+#define VCU_DEC_FPS0x58
+#define VCU_BUFFER_B_FRAME 0x5c
+#define VCU_WPP_EN 0x60
+#define VCU_PLL_CLK_DEC0x64
+#define VCU_GASKET_INIT0x74
+#define VCU_GASKET_VALUE   0x03
+
+/* vcu slcr registers, bitmask and shift */
+#define VCU_PLL_CTRL   0x24
+#define VCU_PLL_CTRL_RESET_MASK0x01
+#define VCU_PLL_CTRL_RESET_SHIFT   0
+#define VCU_PLL_CTRL_BYPASS_MASK   0x01
+#define VCU_PLL_CTRL_BYPASS_SHIFT  3
+#define VCU_PLL_CTRL_FBDIV_MASK0x7f
+#define VCU_PLL_CTRL_FBDIV_SHIFT   8
+#define VCU_PLL_CTRL_POR_IN_MASK   0x01
+#define 

[PATCH v4 1/2] dt-bindings: misc: Add DT bindings to xlnx_vcu driver

2017-12-14 Thread Dhaval Shah
From: Dhaval Shah 

Add Device Tree binding document for logicoreIP. This logicoreIP
provides the isolation between the processing system and
programmable logic. Also provides the clock related information.

Signed-off-by: Dhaval Shah 
---
Chnages since v3:
 No Changes.
Chnages since v3:
 * Use "dt-bindings: misc: ..." for the subject.
Changes since v2:
 * Describe the h/w
 * compatible string is updated to make it more specific
   based on the logicoreIP version.
 * Removed that encoder and decoder child nodes and relatd properties as that
   will be a separate driver and dts nodes. other team is working on that.
 * Updated to use as a single driver.

 .../devicetree/bindings/misc/xlnx,vcu.txt  | 31 ++
 1 file changed, 31 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/xlnx,vcu.txt

diff --git a/Documentation/devicetree/bindings/misc/xlnx,vcu.txt 
b/Documentation/devicetree/bindings/misc/xlnx,vcu.txt
new file mode 100644
index 000..6786d67
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/xlnx,vcu.txt
@@ -0,0 +1,31 @@
+LogicoreIP designed compatible with Xilinx ZYNQ family.
+---
+
+General concept
+---
+
+LogicoreIP design to provide the isolation between processing system
+and programmable logic. Also provides the list of register set to configure
+the frequency.
+
+Required properties:
+- compatible: shall be one of:
+   "xlnx,vcu"
+   "xlnx,vcu-logicoreip-1.0"
+- reg, reg-names: There are two sets of registers need to provide.
+   1. vcu slcr
+   2. Logicore
+   reg-names should contain name for the each register sequence.
+- clocks: phandle for aclk and pll_ref clocksource
+- clock-names: The identification string, "aclk", is always required for
+   the axi clock. "pll_ref" is required for pll.
+Example:
+
+   xlnx_vcu: vcu@a004 {
+   compatible = "xlnx,vcu-logicoreip-1.0";
+   reg = <0x0 0xa004 0x0 0x1000>,
+<0x0 0xa0041000 0x0 0x1000>;
+   reg-names = "vcu_slcr", "logicore";
+   clocks = <_1>, < 71>;
+   clock-names = "pll_ref", "aclk";
+   };
-- 
2.7.4



[PATCH v4 0/2] Documentation and driver of logicoreIP

2017-12-14 Thread Dhaval Shah
1st patch provide Device Tree binding document for logicoreIP
2nd patch provide the xlnx_vcu logicoreIP driver, Kconfig changes
and Makefile changes for the driver.

Dhaval Shah (2):
  Documentation: devicetree: Add DT bindings to xlnx_vcu driver
  misc: xlnx_vcu: Add Xilinx ZYNQMP VCU logicoreIP init driver

 .../devicetree/bindings/misc/xlnx,vcu.txt  |  31 +
 drivers/misc/Kconfig   |  15 +
 drivers/misc/Makefile  |   1 +
 drivers/misc/xlnx_vcu.c| 631 +
 4 files changed, 678 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/xlnx,vcu.txt
 create mode 100644 drivers/misc/xlnx_vcu.c

-- 
2.7.4



[PATCH v4 1/2] dt-bindings: misc: Add DT bindings to xlnx_vcu driver

2017-12-14 Thread Dhaval Shah
From: Dhaval Shah 

Add Device Tree binding document for logicoreIP. This logicoreIP
provides the isolation between the processing system and
programmable logic. Also provides the clock related information.

Signed-off-by: Dhaval Shah 
---
Chnages since v3:
 No Changes.
Chnages since v3:
 * Use "dt-bindings: misc: ..." for the subject.
Changes since v2:
 * Describe the h/w
 * compatible string is updated to make it more specific
   based on the logicoreIP version.
 * Removed that encoder and decoder child nodes and relatd properties as that
   will be a separate driver and dts nodes. other team is working on that.
 * Updated to use as a single driver.

 .../devicetree/bindings/misc/xlnx,vcu.txt  | 31 ++
 1 file changed, 31 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/xlnx,vcu.txt

diff --git a/Documentation/devicetree/bindings/misc/xlnx,vcu.txt 
b/Documentation/devicetree/bindings/misc/xlnx,vcu.txt
new file mode 100644
index 000..6786d67
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/xlnx,vcu.txt
@@ -0,0 +1,31 @@
+LogicoreIP designed compatible with Xilinx ZYNQ family.
+---
+
+General concept
+---
+
+LogicoreIP design to provide the isolation between processing system
+and programmable logic. Also provides the list of register set to configure
+the frequency.
+
+Required properties:
+- compatible: shall be one of:
+   "xlnx,vcu"
+   "xlnx,vcu-logicoreip-1.0"
+- reg, reg-names: There are two sets of registers need to provide.
+   1. vcu slcr
+   2. Logicore
+   reg-names should contain name for the each register sequence.
+- clocks: phandle for aclk and pll_ref clocksource
+- clock-names: The identification string, "aclk", is always required for
+   the axi clock. "pll_ref" is required for pll.
+Example:
+
+   xlnx_vcu: vcu@a004 {
+   compatible = "xlnx,vcu-logicoreip-1.0";
+   reg = <0x0 0xa004 0x0 0x1000>,
+<0x0 0xa0041000 0x0 0x1000>;
+   reg-names = "vcu_slcr", "logicore";
+   clocks = <_1>, < 71>;
+   clock-names = "pll_ref", "aclk";
+   };
-- 
2.7.4



[PATCH v4 0/2] Documentation and driver of logicoreIP

2017-12-14 Thread Dhaval Shah
1st patch provide Device Tree binding document for logicoreIP
2nd patch provide the xlnx_vcu logicoreIP driver, Kconfig changes
and Makefile changes for the driver.

Dhaval Shah (2):
  Documentation: devicetree: Add DT bindings to xlnx_vcu driver
  misc: xlnx_vcu: Add Xilinx ZYNQMP VCU logicoreIP init driver

 .../devicetree/bindings/misc/xlnx,vcu.txt  |  31 +
 drivers/misc/Kconfig   |  15 +
 drivers/misc/Makefile  |   1 +
 drivers/misc/xlnx_vcu.c| 631 +
 4 files changed, 678 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/xlnx,vcu.txt
 create mode 100644 drivers/misc/xlnx_vcu.c

-- 
2.7.4



Re: [PATCH] APEI / ERST: Fix missing error handling in erst_reader()

2017-12-14 Thread Takashi Iwai
On Fri, 15 Dec 2017 02:01:20 +0100,
Rafael J. Wysocki wrote:
> 
> On Thu, Dec 14, 2017 at 1:31 PM, Takashi Iwai  wrote:
> > The commit f6f828513290 ("pstore: pass allocated memory region back to
> > caller") changed the check of the return value from erst_read() in
> > erst_reader() in the following way:
> >
> > if (len == -ENOENT)
> > goto skip;
> > -   else if (len < 0) {
> > -   rc = -1;
> > +   else if (len < sizeof(*rcd)) {
> > +   rc = -EIO;
> > goto out;
> >
> > This introduced another bug: since the comparison with sizeof() is
> > cast to unsigned, a negative len value doesn't hit any longer.
> > As a result, when an error is returned from erst_read(), the code
> > falls through, and it may eventually lead to some weird thing like
> > memory corruption.
> >
> > This patch adds the negative error value check more explicitly for
> > addressing the issue.
> >
> > Fixes: f6f828513290 ("pstore: pass allocated memory region back to caller")
> 
> That's ancient. :-)
> 
> > Cc: 
> > Tested-by: Jerry Tang 
> > Signed-off-by: Takashi Iwai 
> > ---
> >  drivers/acpi/apei/erst.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
> > index 6742f6c68034..9bff853e85f3 100644
> > --- a/drivers/acpi/apei/erst.c
> > +++ b/drivers/acpi/apei/erst.c
> > @@ -1007,7 +1007,7 @@ static ssize_t erst_reader(struct pstore_record 
> > *record)
> > /* The record may be cleared by others, try read next record */
> > if (len == -ENOENT)
> > goto skip;
> > -   else if (len < sizeof(*rcd)) {
> > +   else if (len < 0 || len < sizeof(*rcd)) {
> > rc = -EIO;
> > goto out;
> > }
> > --
> 
> OK, I'm going to queue this up unless I see objections from Boris or Tony.

I missed Boris in Cc list, sorry.  Now added.


Takashi


Re: [PATCH] APEI / ERST: Fix missing error handling in erst_reader()

2017-12-14 Thread Takashi Iwai
On Fri, 15 Dec 2017 02:01:20 +0100,
Rafael J. Wysocki wrote:
> 
> On Thu, Dec 14, 2017 at 1:31 PM, Takashi Iwai  wrote:
> > The commit f6f828513290 ("pstore: pass allocated memory region back to
> > caller") changed the check of the return value from erst_read() in
> > erst_reader() in the following way:
> >
> > if (len == -ENOENT)
> > goto skip;
> > -   else if (len < 0) {
> > -   rc = -1;
> > +   else if (len < sizeof(*rcd)) {
> > +   rc = -EIO;
> > goto out;
> >
> > This introduced another bug: since the comparison with sizeof() is
> > cast to unsigned, a negative len value doesn't hit any longer.
> > As a result, when an error is returned from erst_read(), the code
> > falls through, and it may eventually lead to some weird thing like
> > memory corruption.
> >
> > This patch adds the negative error value check more explicitly for
> > addressing the issue.
> >
> > Fixes: f6f828513290 ("pstore: pass allocated memory region back to caller")
> 
> That's ancient. :-)
> 
> > Cc: 
> > Tested-by: Jerry Tang 
> > Signed-off-by: Takashi Iwai 
> > ---
> >  drivers/acpi/apei/erst.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
> > index 6742f6c68034..9bff853e85f3 100644
> > --- a/drivers/acpi/apei/erst.c
> > +++ b/drivers/acpi/apei/erst.c
> > @@ -1007,7 +1007,7 @@ static ssize_t erst_reader(struct pstore_record 
> > *record)
> > /* The record may be cleared by others, try read next record */
> > if (len == -ENOENT)
> > goto skip;
> > -   else if (len < sizeof(*rcd)) {
> > +   else if (len < 0 || len < sizeof(*rcd)) {
> > rc = -EIO;
> > goto out;
> > }
> > --
> 
> OK, I'm going to queue this up unless I see objections from Boris or Tony.

I missed Boris in Cc list, sorry.  Now added.


Takashi


  1   2   3   4   5   6   7   8   9   10   >