[RFC PATCH 2/9] media: request: add generic queue
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 &req->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(&queue->queued_requests, typeof(*req), + queue); + if (!req) + return; + + list_del(&req->queue); + queue->base.active_request = &req->base; + + list_for_each_entry(data, &req->base.data, list) { + int ret; + + ret = data->entity->req_ops->apply_data(data); + } + + list_for_each_entry(data, &req->base.data, list) { + data->entity->ops->process_request(&req->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(&req->queue, &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(&queu
[RFC PATCH 4/9] videodev2.h: Add request field to v4l2_buffer
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(&buf->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, &up->type) || get_user(kp->flags, &up->flags) || get_user(kp->memory, &up->memory) || - get_user(kp->length, &up->length)) + get_user(kp->length, &up->length) || + get_user(kp->request, &up->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, &up->timestamp.tv_usec) || copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) || put_user(kp->sequence, &up->sequence) || - put_user(kp->reserved2, &up->reserved2) || + put_user(kp->request, &up->request) || put_user(kp->reserved, &up->reserved) || put_user(kp->length, &up->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/video
[RFC PATCH 8/9] media: vim2m: add media device
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(&dev->irqlock); +#ifdef CONFIG_MEDIA_CONTROLLER + dev->mdev.dev = &pdev->dev; + strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model)); + media_device_init(&dev->mdev); + dev->v4l2_dev.mdev = &dev->mdev; +#endif + ret = v4l2_device_register(&pdev->dev, &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(&dev->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(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); + +#ifdef CONFIG_MEDIA_CONTROLLER + if (media_devnode_is_registered(dev->mdev.devnode)) + media_device_unregister(&dev->mdev); + media_device_cleanup(&dev->mdev); +#endif + v4l2_m2m_release(dev->m2m_dev); del_timer_sync(&dev->timer); video_unregister_device(&dev->vfd); -- 2.15.1.504.g5279b80103-goog
[RFC PATCH 6/9] media: vb2: add support for requests in QBUF ioctl
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, &vfd->flags) ? fh : NULL; + struct media_entity *entity = &vfd->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
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(&vb->done_entry, &q->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(&q->owned_by_drv_count); spin_unlock_irqrestore(&q->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, &q->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, &q->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, &q->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
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 &ret->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
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, + &dev->vfd.entity); +#endif + v4l2_fh_add(&ctx->fh); atomic_inc(&dev->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 = &pdev->dev; + dev->req_queue = media_request_queue_generic_alloc(&dev->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(&dev->mdev); dev->v4l2_dev.mdev = &dev->mdev; @@ -1023,6 +1040,11 @@ static int vim2m_probe(struct platform_device *pdev) vfd->lock = &dev->dev_mutex; vfd->v4l2_dev = &dev->v4l2_dev; +#ifdef CONFIG_MEDIA_CONTROLLER + vfd->entity.ops = &vim2m_entity_ops; + vfd->entity.req_ops = &media_entity_request_generic_ops; +#endif + ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); if (ret) { v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); -- 2.15.1.504.g5279b80103-goog
[RFC PATCH 7/9] media: v4l2-mem2mem: add request support
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(&ctx->cap_q_ctx.q, req); + vb2_queue_start_request(&ctx->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 &mutex 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
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(&mdev->entity_internal_idx); mdev->entity_internal_idx_max = 0; media_graph_walk_cleanup(&mdev->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(&req->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 != &request_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(&req->list); + list_for_each_entry_safe(data, next, &req->data, list) { + list_del(&data->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(&req->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) +{ +
[RFC PATCH 0/9] media: base request API support
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()
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
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 = &arch_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(&clocksource_counter, arch_timer_rate); - cc->mult = clocksource_counter.mult; - cc->shift = clocksource_counter.shift; - timecounter_init(&arch_timer_kvm_info.timecounter, start_count); + timecounter_initialize(&arch_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
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 = &pdata->ptp_clock_info; struct ptp_clock *clock; - struct cyclecounter *cc = &pdata->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(&pdata->tstamp_tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(&pdata->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
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(&fep->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(&fep->tc, ktime_to_ns(ktime_get_real())); + /* Initialize the ns time counter */ + timecounter_initialize(&fep->tc, + fec_ptp_read, + CLOCKSOURCE_MASK(31), + FEC_CC_MULT, + 31, + ktime_to_ns(ktime_get_real())); spin_unlock_irqrestore(&fep->tmreg_lock, flags); } -- 1.9.1
Re: [PATCH] exit: move exit_task_namespaces() after exit_task_work()
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
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(&adapter->systim_lock, flags); - timecounter_init(&adapter->tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(&adapter->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
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 = &xilinx_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(&xilinx_tc, sched_clock()); + timecounter_initialize(&xilinx_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
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(&mdev->clock_lock); - memset(&mdev->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(&mdev->clock_lock, flags); - timecounter_init(&mdev->clock, ktime_to_ns(ktime_get_real())); + timecounter_initialize(&mdev->clock, + mlx4_en_read_clock, + CLOCKSOURCE_MASK(48), + mult, + shift, + ktime_to_ns(ktime_get_real())); write_sequnlock_irqrestore(&mdev->clock_lock, flags); /* Configure the PHC */ -- 1.9.1
[PATCH 06/27] bnx2x: Use timecounter_initialize interface
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(&bp->timecounter.cc); - timecounter_init(&bp->timecounter, -ktime_to_ns(ktime_get_real())); + timecounter_initialize(&bp->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
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, &lval); + else + rtsx_pci_read_config_dword(pcr, + PCR_ASPM_SETTING_REG2, &lval); 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, &val); + 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 = &pcr->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
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(&clock->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(&clock->tc, ktime_to_ns(ktime_get_real())); + shift = MLX5_CYCLES_SHIFT; + mult = clocksource_khz2mult(dev_freq, shift); + clock->nominal_c_mult = mult; + + timecounter_initialize(&clock->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
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 = &azx_dev->tc; - struct cyclecounter *cc = &azx_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
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(&cpts->tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(&cpts->tc, + cpts_systim_read, + cpts->mask, + cpts->mult, + cpts->shift, + ktime_to_ns(ktime_get_real())); cpts->clock = ptp_clock_register(&cpts->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 = &cpts->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(&cc->mult, &cc->shift, + clocks_calc_mult_shift(mult, shift, freq, NSEC_PER_SEC, maxsec); frac = 0; - ns = cyclecounter_cyc2ns(cc, freq, cc->mask, &frac); + ns = cyclecounter_cyc2ns(cc, freq, mask, &frac); 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, &cpts->mult, &cpts->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
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(&bp->timecounter, ns); + /* Reset the timecounter */ + timecounter_reset(&bp->timecounter, ns); return 0; } -- 1.9.1
[PATCH 16/27] timecounter: Introduce timecounter_reset
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(&tc->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
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
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
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(&adapter->tmreg_lock, flags); - timecounter_init(&adapter->hw_tc, ns); + timecounter_reset(&adapter->hw_tc, ns); spin_unlock_irqrestore(&adapter->tmreg_lock, flags); if (adapter->ptp_setup_sdp) -- 1.9.1
[PATCH 21/27] igb: Use timecounter_reset interface
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(&igb->tmreg_lock, flags); - timecounter_init(&igb->tc, ns); + timecounter_reset(&igb->tc, ns); spin_unlock_irqrestore(&igb->tmreg_lock, flags); -- 1.9.1
[PATCH 23/27] net/mlx4: Use timecounter_reset interface
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(&mdev->clock_lock, flags); - timecounter_init(&mdev->clock, ns); + timecounter_reset(&mdev->clock, ns); write_sequnlock_irqrestore(&mdev->clock_lock, flags); return 0; -- 1.9.1
[PATCH 24/27] net/mlx5: Use timecounter_reset interface
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(&clock->lock, flags); - timecounter_init(&clock->tc, ns); + timecounter_reset(&clock->tc, ns); write_unlock_irqrestore(&clock->lock, flags); return 0; -- 1.9.1
[PATCH 25/27] qede: Use timecounter_reset interface
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(&ptp->lock); - timecounter_init(&ptp->tc, ns); + timecounter_reset(&ptp->tc, ns); spin_unlock_bh(&ptp->lock); return 0; -- 1.9.1
[PATCH 26/27] net: cpts: Use timecounter_reset interface
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(&cpts->lock, flags); - timecounter_init(&cpts->tc, ns); + timecounter_reset(&cpts->tc, ns); spin_unlock_irqrestore(&cpts->lock, flags); return 0; -- 1.9.1
[PATCH 20/27] e1000e: Use timecounter_reset interface
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(&adapter->systim_lock, flags); - timecounter_init(&adapter->tc, ns); + timecounter_reset(&adapter->tc, ns); spin_unlock_irqrestore(&adapter->systim_lock, flags); return 0; -- 1.9.1
[PATCH 17/27] amd-xgbe: Use timecounter_reset interface
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(&pdata->tstamp_tc, ktime_to_ns(ktime_get_real())); + /* Reset the timecounter */ + timecounter_reset(&pdata->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(&pdata->tstamp_lock, flags); - timecounter_init(&pdata->tstamp_tc, nsec); + timecounter_reset(&pdata->tstamp_tc, nsec); spin_unlock_irqrestore(&pdata->tstamp_lock, flags); -- 1.9.1
[PATCH 27/27] timecounter: Remove timecounter_init
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 = &tc->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
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(&fep->tmreg_lock, flags); writel(counter, fep->hwp + FEC_ATIME); - timecounter_init(&fep->tc, ns); + timecounter_reset(&fep->tc, ns); spin_unlock_irqrestore(&fep->tmreg_lock, flags); mutex_unlock(&fep->ptp_clk_mutex); return 0; -- 1.9.1
[PATCH 13/27] qede: Use timecounter_initialize interface
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(&ptp->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(&ptp->tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(&ptp->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
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, &adapter->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, &adapter->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 = &adapter->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; + a
[PATCH 02/27] timecounter: Introduce timecounter_initialize to update timecounter and cyclecounter
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 = &tc->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 01/27] timecounter: Make cyclecounter struct part of timecounter struct
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 = &xilinx_tc.cc; + + cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); - timecounter_init(&xilinx_tc, &xilinx_cc, sched_clock()); + timecounter_init(&xilinx_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 = &arch_timer_kvm_
[PATCH 09/27] igb: Use timecounter_initialize interface
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, &ts); } else { - timecounter_init(&adapter->tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(&adapter->tc, + adapter->cc_read, + adapter->cc_mask, + adapter->cc_mult, + adapter->cc_shift, + ktime_to_ns(ktime_get_real())); } out: spin_unlock_irqrestore(&adapter->tmreg_lock, flags); -- 1.9.1
[PATCH 00/27] timecounter/cyclecounter struct/interface update
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
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(&rq->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
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
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
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 VCU_PLL_
[PATCH v4 1/2] dt-bindings: misc: Add DT bindings to xlnx_vcu driver
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 = <&si570_1>, <&clkc 71>; + clock-names = "pll_ref", "aclk"; + }; -- 2.7.4
[PATCH v4 0/2] Documentation and driver of logicoreIP
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()
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 4/9] build: update AC_PACKAGE_WANT_GDBM() and src/dbtest.c to build
On Thu, Dec 14, 2017 at 06:55:03PM +0100, Luis R. Rodriguez wrote: > On Thu, Dec 14, 2017 at 01:51:02PM +0800, Eryu Guan wrote: > > On Tue, Dec 12, 2017 at 04:45:14PM -0800, Luis R. Rodriguez wrote: > > > Modern gdbm-devel packages bundle together gdbm.h and ndbm.h. > > > The old m4 macro had detection support for some old gdbm libraries > > > but not for new ones. > > > > > > We fix compilation of src/dbtest.c by making the autoconf helper > > > check for this new arrangement: > > > > > > If both gdbm.h and gdbm.h are found define set both gdbm_ndbm_=true, > > ^^ ndbm.h? > > > and have_db=true, and define HAVE_GDBM_H. The src/dbtest.c already > > > had a HAVE_GDBM_H but there was never a respective autoconf settter for > > > it. We can just re-use this and fix it for new arrangement. > > > > > > Signed-off-by: Luis R. Rodriguez > > > > This looks fine to me. > > > > The only system I have by hand that have both and but > > not any is openSUSE Tumbleweed. > > Indeed, openSUSE and SLE releases. > > > Without this patch, > > dbtest was not built on openSUSE, and was built successfully with this > > patch applied. > > Yeap. > > > And dbtest is still built on RHEL6/7 and Fedora. > > Feel free to modify the commit log accordingly then. Curious, what packages > does Fedora/ RHEL6/7 use for the requirement here? > > We just have one: > > $ rpm -ql gdbm-devel-1.12-1.282.x86_64 > /usr/bin/gdbm_dump > /usr/bin/gdbm_load > /usr/bin/gdbmtool > /usr/include/dbm.h > /usr/include/gdbm.h > /usr/include/ndbm.h > /usr/lib64/libgdbm.a > /usr/lib64/libgdbm.so > /usr/lib64/libgdbm_compat.a > /usr/lib64/libgdbm_compat.so > /usr/lib64/libndbm.a > /usr/lib64/libndbm.so > /usr/share/info/gdbm.info.gz > /usr/share/man/man1/gdbm_dump.1.gz > /usr/share/man/man1/gdbm_load.1.gz > /usr/share/man/man1/gdbmtool.1.gz > /usr/share/man/man3/gdbm.3.gz gdbm-devel too, but it has gdbm/[gn]dbm.h pointing to ../[gn]dbm.h, so there's no such problem and dbtest is building normally. # rpm -ql gdbm-devel /usr/include/dbm.h /usr/include/gdbm /usr/include/gdbm.h /usr/include/gdbm/dbm.h /usr/include/gdbm/gdbm.h /usr/include/gdbm/ndbm.h /usr/include/ndbm.h /usr/lib64/libgdbm.so /usr/lib64/libgdbm_compat.so /usr/share/info/gdbm.info.gz /usr/share/man/man3/gdbm.3.gz > > > BTW, I'll queue patch 3 and this patch for next fstests release, while > > other patches seem not necessary, > > I think patch 2 is fine too. > > > I agreed with Dave that groups are not > > for excluding tests, the required tools and environments should be > > detected by tests and _notrun if not met. > > Yeah makes sense now. I think we should also document when adding > a group makes sense as well. > > > (The README change looks fine, > > but it doesn't apply due to the "fsgqa-381" change, so I drop it too for > > now.) > > Feel free to modify it, its not a big deal. OK, I'll modify on commit, thanks! Thanks, Eryu
Re: [PATCH v2 1/3] mmc: dt-bindings: add mmc support to MT7623 SoC
On 14 December 2017 at 12:16, Matthias Brugger wrote: > Hi Ulf, > > On 12/07/2017 07:43 AM, sean.w...@mediatek.com wrote: >> From: Sean Wang >> >> Add the devicetree binding for MT7623 SoC using MT2701 as the fallback. >> >> Cc: devicet...@vger.kernel.org >> Signed-off-by: Sean Wang >> Acked-by: Rob Herring >> --- >> Documentation/devicetree/bindings/mmc/mtk-sd.txt | 2 ++ >> 1 file changed, 2 insertions(+) >> >> diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt >> b/Documentation/devicetree/bindings/mmc/mtk-sd.txt >> index 72d2a73..9b80176 100644 >> --- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt >> +++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt >> @@ -12,6 +12,8 @@ Required properties: >> "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173 >> "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701 >> "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712 >> + "mediatek,mt7623-mmc", "mediatek,mt2701-mmc": for MT7623 SoC >> + >> - reg: physical base address of the controller and length >> - interrupts: Should contain MSDC interrupt number >> - clocks: Should contain phandle for the clock feeding the MMC controller >> > > Are you fine to take this patch through your branch, or shall I take it > through > mine? I have pick it up, thanks! > > @Sean it seems you forgot to send this patch to Ulf as well. In the future > please take care to send the patch to all relevant people and mailinglist. Yeah, thanks for looping me in this time! Kind regards Uffe
[PATCH] fs/namespace: __mnt_is_readonly can be boolean
This patch makes __mnt_is_readonly return bool due to this particular function only using either one or zero as its return value. No functional change. Signed-off-by: rongyin --- fs/namespace.c| 8 include/linux/mount.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index e158ec6..8a0e90a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -271,13 +271,13 @@ static struct mount *alloc_vfsmnt(const char *name) * mnt_want/drop_write() will _keep_ the filesystem * r/w. */ -int __mnt_is_readonly(struct vfsmount *mnt) +bool __mnt_is_readonly(struct vfsmount *mnt) { if (mnt->mnt_flags & MNT_READONLY) - return 1; + return true; if (sb_rdonly(mnt->mnt_sb)) - return 1; - return 0; + return true; + return false; } EXPORT_SYMBOL_GPL(__mnt_is_readonly); diff --git a/include/linux/mount.h b/include/linux/mount.h index 45b1f56..037eed5 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -81,7 +81,7 @@ struct vfsmount { extern void mntput(struct vfsmount *mnt); extern struct vfsmount *mntget(struct vfsmount *mnt); extern struct vfsmount *mnt_clone_internal(const struct path *path); -extern int __mnt_is_readonly(struct vfsmount *mnt); +extern bool __mnt_is_readonly(struct vfsmount *mnt); extern bool mnt_may_suid(struct vfsmount *mnt); struct path; -- 1.8.3.1
[PATCH] percpu: percpu_counter_initialized can be boolean
This patch makes percpu_counter_initialized return bool due to this particular function only using either one or zero as its return value. No functional change. Signed-off-by: guoyayun --- include/linux/percpu_counter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 73a7bf3..4f05249 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -86,7 +86,7 @@ static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc) return 0; } -static inline int percpu_counter_initialized(struct percpu_counter *fbc) +static inline bool percpu_counter_initialized(struct percpu_counter *fbc) { return (fbc->counters != NULL); } @@ -167,9 +167,9 @@ static inline s64 percpu_counter_sum(struct percpu_counter *fbc) return percpu_counter_read(fbc); } -static inline int percpu_counter_initialized(struct percpu_counter *fbc) +static inline bool percpu_counter_initialized(struct percpu_counter *fbc) { - return 1; + return true; } #endif /* CONFIG_SMP */ -- 1.8.3.1
Re: [PATCH] exit: move exit_task_namespaces() after exit_task_work()
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 > > 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); > > /*
[net-next] phylib: Add device reset GPIO support causes DSA MT7530 acquires reset-gpios fails
Hi Sergei, Recently I found the patch commit bafbdd527d56 (phylib: Add device reset GPIO support) would have the impact on MT7530 driver. Which causes the DSA MT7530 device (it's the child node under mdio bus) gets the reset-gpios fails because the same GPIO seems already be held in the earlier mdiobus_register_device call patched through the commit. do you have any idea how the commits also considers DSA case ? I guessed the DSA lan9303, mv88e8 switch should have the same issue since they have the same GPIO name as mdiobus_register_device required. drivers/net/dsa/lan9303-core.c:1303:chip->reset_gpio = devm_gpiod_get_optional(chip->dev, "reset", drivers/net/dsa/mv88e6xxx/chip.c:3936: chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); drivers/net/dsa/mt7530.c:1476: priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", Below is the stack dump I added in of_get_named_gpiod_flags call. Which apparently shows mdiobus_register_device would get gpio at first and then DSA driver does. [2.570607] [] (show_stack) from [] (dump_stack +0x98/0xac) [2.59] [] (dump_stack) from [] (of_get_named_gpiod_flags+0xe8/0x128) [2.586239] [] (of_get_named_gpiod_flags) from [] (fwnode_get_named_gpiod+0x5c/0xd0) [2.595648] [] (fwnode_get_named_gpiod) from [] (mdiobus_register_device+0x64/0xa8) [2.604969] [] (mdiobus_register_device) from [] (mdio_device_register+0x34/0x8c) [2.614119] [] (mdio_device_register) from [] (of_mdiobus_register+0x150/0x2c8) [2.623097] [] (of_mdiobus_register) from [] (mtk_probe+0x6a4/0x820) [2.631128] [] (mtk_probe) from [] (platform_drv_probe+0x5c/0xc0) [2.638898] [] (platform_drv_probe) from [] (driver_probe_device+0x2f4/0x4d8) [2.647702] [] (driver_probe_device) from [] (__driver_attach+0x10c/0x128) [2.656248] [] (__driver_attach) from [] (bus_for_each_dev+0x78/0xac) [2.664364] [] (bus_for_each_dev) from [] (driver_attach+0x2c/0x30) [2.672307] [] (driver_attach) from [] (bus_add_driver+0x1e0/0x278) [2.680250] [] (bus_add_driver) from [] (driver_register+0x88/0x108)would [2.688277] [] (driver_register) from [] (__platform_driver_register+0x50/0x58) [2.697256] [] (__platform_driver_register) from [] (mtk_driver_init+0x24/0x28) [2.706234] [] (mtk_driver_init) from [] (do_one_initcall+0x50/0x17c) [2.714351] [] (do_one_initcall) from [] (kernel_init_freeable+0x154/0x1f4) [2.722984] [] (kernel_init_freeable) from [] (kernel_init+0x18/0x124) [2.731185] [] (kernel_init) from [] (ret_from_fork+0x14/0x2c) [2.738719] of_get_named_gpiod_flags: parsed 'reset-gpios' property of node '/ethernet@1b10/mdio-bus/switch@0[0]' - status (0) [2.750631] mt7530 mdio-bus:00: GPIO lookup for consumer reset [2.756443] mt7530 mdio-bus:00: using device tree for GPIO lookup [2.762494] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.15.0-rc2-00819-g4d89425-dirty #6 [2.770514] Hardware name: Mediatek Cortex-A7 (Device Tree) [2.776049] [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [2.783733] [] (show_stack) from [] (dump_stack +0x98/0xac) [2.790901] [] (dump_stack) from [] (of_get_named_gpiod_flags+0xe8/0x128) [2.799359] [] (of_get_named_gpiod_flags) from [] (of_find_gpio+0x70/0xfc) [2.807903] [] (of_find_gpio) from [] (gpiod_get_index+0xac/0x2a0) [2.815759] [] (gpiod_get_index) from [] (devm_gpiod_get_index+0x5c/0x98) [2.824220] [] (devm_gpiod_get_index) from [] (devm_gpiod_get_optional+0x20/0wouldx34) [2.833370] [] (devm_gpiod_get_optional) from [] (mt7530_probe+0x170/0x1a0) [2.842003] [] (mt7530_probe) from [] (mdio_probe +0x40/0x64) [2.849342] [] (mdio_probe) from [] (driver_probe_device+0x2f4/0x4d8) [2.857455] [] (driver_probe_device) from [] (__device_attach_driver+0xc8/0x144) [2.866518] [] (__device_attach_driver) from [] (bus_for_each_drv+0x70/0xa4)geert+rene...@glider.be [2.875235] [] (bus_for_each_drv) from [] (__device_attach+0xc0/0x150) [2.883434] [] (__device_attach) from [] (device_initial_probe+0x1c/0x20) [2.891893] [] (device_initial_probe) from [] (bus_probe_device+0x94/0x9c) [2.900440] [] (bus_probe_device) from [] (device_add+0x374/0x5c0) [2.908297] [] (device_add) from [] (mdio_device_register+0x44/0x8c) [2.916326] [] (mdio_device_register) from [] (of_mdiobus_register+0x150/0x2c8) [2.925302] [] (of_mdiobus_register) from [] (mtk_probe+0x6a4/0x820) and the related dts I used is as below would mdio: mdio-bus { #address-cells = <1>; #size-cells = <0>; switch@0 { compatible = "mediatek,mt7530"; #address-cells = <1>; #size-cells = <0>; reg = <0>; reset-gpios = <&pio 33 0>; core-supply = <&mt6323_vpa_reg>; io-supply = <&mt6323_vemc3v3_reg>; port
Re: linux-next: Tree for Dec 15
Hello, On (12/15/17 15:13), Stephen Rothwell wrote: > Hi all, > > Changes since 20171214: > > New tree: init_task > > The staging.current tree still had its build failure for which I reverted > a commit. hm, still no next-20171215 at https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/refs/ -ss
Re: [RFC][PATCHv6 00/12] printk: introduce printing kernel thread
On (12/15/17 14:06), Sergey Senozhatsky wrote: [..] > > Where do we do the above? And has this been proven to be an issue? > > um... hundreds of cases. > > deep-stack spin_lock_irqsave() lockup reports from multiple CPUs (3 cpus) > happening at the same moment + NMI backtraces from all the CPUs (more > than 3 cpus) that follows the lockups, over not-so-fast serial console. > exactly the bug report I received two days ago. so which one of the CPUs > here is a good candidate to successfully emit all of the pending logbuf > entries? none. all of them either have local IRQs disabled, or dump_stack() > from either backtrace IPI or backtrace NMI (depending on the configuration). and, Steven, one more thing. wondering what's your opinion. suppose we have consoe_owner hand off enabled, 1 non-atomic CPU doing printk-s and several atomic CPUs doing printk-s. Is proposed hand off scheme really useful in this case? CPUs will now a) print their lines (a potentially slow call_console_drivers()) and b) spin in vprintk_emit on console_owner with local IRQs disabled waiting for either non-atomic printk CPU or another atomic CPU to finish printing its line (call_console_drivers()) and to hand off printing. so current CPU, after busy-waiting for foreign CPU's call_console_drivers(), will go and do his own call_console_drivers(). which, time-wise, simply doubles (roughly) the amount of time that CPU spends in printk()->console_unlock(). agreed? if we previously could have a case when non-atomic printk CPU would grab the console_sem and print all atomic printk CPUs messages first, and then its own messages, thus atomic printk CPUs would have just log_store(), now we will have CPUs to call_console_driver() and to spin on console_sem owner waiting for call_console_driver() on a foreign CPU [not all of them: it's one CPU doing the print out and one CPU spinning console_owner. but overall I think all CPUs will experience that spin on console_sem waiting for call_console_driver() and then do its own call_console_driver()]. even two CPUs case is not so simple anymore. see below. - first, assume one CPU is atomic and one is non-atomic. - second, assume that both CPUs are atomic CPUs, and go thought it again. CPU0CPU1 printk()printk() log_store() log_store() console_unlock() set console_owner sees console_owner sets console_waiter spin call_console_drivers() sees console_waiter break printk() log_store() console_unlock() set console_owner sees console_owner sets console_waiter spin call_console_drivers() sees console_waiter break printk() log_store() console_unlock() set console_owner sees console_owner sets console_waiter spin call_console_drivers() sees console_waiter break printk() log_store() console_unlock() set console_owner sees console_owner sets console_waiter spin that "wait for call_console_drivers() on another CPU and then do its own call_console_drivers()" pattern does look dangerous. the benefit of hand-off is really fragile sometimes, isn't it? -ss
[PATCH] kernel/kprobes: kprobes_built_in can be boolean
This patch makes kprobes_built_in return bool due to this particular function only using either one or zero as its return value. No functional change. Signed-off-by: guzhifeng --- include/linux/kprobes.h | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 9440a2f..8d0d910 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -219,9 +219,9 @@ struct kprobe_blacklist_entry { /* * For #ifdef avoidance: */ -static inline int kprobes_built_in(void) +static inline bool kprobes_built_in(void) { - return 1; + return true; } #ifdef CONFIG_KRETPROBES @@ -409,9 +409,9 @@ static inline struct kprobe_ctlblk *get_kprobe_ctlblk(void) #else /* !CONFIG_KPROBES: */ -static inline int kprobes_built_in(void) +static inline bool kprobes_built_in(void) { - return 0; + return false; } static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) { -- 1.8.3.1
Re: [PATCH v2 1/5] extcon: usbc-cros-ec: add support to notify USB type cables.
Hi Enric, Looks good to me. After reviewing the Lee Jones, I'll take it on next branch. Regards, Chanwoo Choi On 2017년 12월 13일 19:32, Enric Balletbo i Serra wrote: > From: Benson Leung > > Extend the driver to notify host and device type cables and the presence > of power. > > Signed-off-by: Benson Leung > Signed-off-by: Enric Balletbo i Serra > Reviewed-by: Chanwoo Choi > --- > Changes since v1: > - Use the BIT macro. Requested by Lee Jones. > - Add the Reviewed-by: Chanwoo Choi. > > drivers/extcon/extcon-usbc-cros-ec.c | 142 > ++- > include/linux/mfd/cros_ec_commands.h | 17 + > 2 files changed, 155 insertions(+), 4 deletions(-) > > diff --git a/drivers/extcon/extcon-usbc-cros-ec.c > b/drivers/extcon/extcon-usbc-cros-ec.c > index 6187f73..6721ab0 100644 > --- a/drivers/extcon/extcon-usbc-cros-ec.c > +++ b/drivers/extcon/extcon-usbc-cros-ec.c > @@ -34,16 +34,26 @@ struct cros_ec_extcon_info { > > struct notifier_block notifier; > > + unsigned int dr; /* data role */ > + bool pr; /* power role (true if VBUS enabled) */ > bool dp; /* DisplayPort enabled */ > bool mux; /* SuperSpeed (usb3) enabled */ > unsigned int power_type; > }; > > static const unsigned int usb_type_c_cable[] = { > + EXTCON_USB, > + EXTCON_USB_HOST, > EXTCON_DISP_DP, > EXTCON_NONE, > }; > > +enum usb_data_roles { > + DR_NONE, > + DR_HOST, > + DR_DEVICE, > +}; > + > /** > * cros_ec_pd_command() - Send a command to the EC. > * @info: pointer to struct cros_ec_extcon_info > @@ -150,6 +160,7 @@ static int cros_ec_usb_get_role(struct > cros_ec_extcon_info *info, > pd_control.port = info->port_id; > pd_control.role = USB_PD_CTRL_ROLE_NO_CHANGE; > pd_control.mux = USB_PD_CTRL_MUX_NO_CHANGE; > + pd_control.swap = USB_PD_CTRL_SWAP_NONE; > ret = cros_ec_pd_command(info, EC_CMD_USB_PD_CONTROL, 1, >&pd_control, sizeof(pd_control), >&resp, sizeof(resp)); > @@ -183,11 +194,72 @@ static int cros_ec_pd_get_num_ports(struct > cros_ec_extcon_info *info) > return resp.num_ports; > } > > +static const char *cros_ec_usb_role_string(unsigned int role) > +{ > + return role == DR_NONE ? "DISCONNECTED" : > + (role == DR_HOST ? "DFP" : "UFP"); > +} > + > +static const char *cros_ec_usb_power_type_string(unsigned int type) > +{ > + switch (type) { > + case USB_CHG_TYPE_NONE: > + return "USB_CHG_TYPE_NONE"; > + case USB_CHG_TYPE_PD: > + return "USB_CHG_TYPE_PD"; > + case USB_CHG_TYPE_PROPRIETARY: > + return "USB_CHG_TYPE_PROPRIETARY"; > + case USB_CHG_TYPE_C: > + return "USB_CHG_TYPE_C"; > + case USB_CHG_TYPE_BC12_DCP: > + return "USB_CHG_TYPE_BC12_DCP"; > + case USB_CHG_TYPE_BC12_CDP: > + return "USB_CHG_TYPE_BC12_CDP"; > + case USB_CHG_TYPE_BC12_SDP: > + return "USB_CHG_TYPE_BC12_SDP"; > + case USB_CHG_TYPE_OTHER: > + return "USB_CHG_TYPE_OTHER"; > + case USB_CHG_TYPE_VBUS: > + return "USB_CHG_TYPE_VBUS"; > + case USB_CHG_TYPE_UNKNOWN: > + return "USB_CHG_TYPE_UNKNOWN"; > + default: > + return "USB_CHG_TYPE_UNKNOWN"; > + } > +} > + > +static bool cros_ec_usb_power_type_is_wall_wart(unsigned int type, > + unsigned int role) > +{ > + switch (type) { > + /* FIXME : Guppy, Donnettes, and other chargers will be miscategorized > + * because they identify with USB_CHG_TYPE_C, but we can't return true > + * here from that code because that breaks Suzy-Q and other kinds of > + * USB Type-C cables and peripherals. > + */ > + case USB_CHG_TYPE_PROPRIETARY: > + case USB_CHG_TYPE_BC12_DCP: > + return true; > + case USB_CHG_TYPE_PD: > + case USB_CHG_TYPE_C: > + case USB_CHG_TYPE_BC12_CDP: > + case USB_CHG_TYPE_BC12_SDP: > + case USB_CHG_TYPE_OTHER: > + case USB_CHG_TYPE_VBUS: > + case USB_CHG_TYPE_UNKNOWN: > + case USB_CHG_TYPE_NONE: > + default: > + return false; > + } > +} > + > static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info, > bool force) > { > struct device *dev = info->dev; > int role, power_type; > + unsigned int dr = DR_NONE; > + bool pr = false; > bool polarity = false; > bool dp = false; > bool mux = false; > @@ -206,9 +278,12 @@ static int extcon_cros_ec_detect_cable(struct > cros_ec_extcon_info *info, > dev_err(dev, "failed getting role err = %d\n", role); > return role; > } > + dev_dbg(dev, "disconnected\n"); > } else { > int pd_mux_state; > > + dr = (role & PD_CTRL_RESP_ROLE_DATA) ? DR_HOST
[PATCH] kernel/groups: groups_search can be boolean
This patch makes groups_search return bool due to this particular function only using either one or zero as its return value. No functional change. Signed-off-by: tangzhongrui --- include/linux/cred.h | 2 +- kernel/groups.c | 8 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/cred.h b/include/linux/cred.h index 099058e..c3eb950 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -81,7 +81,7 @@ static inline int in_egroup_p(kgid_t grp) #endif extern int set_current_groups(struct group_info *); extern void set_groups(struct cred *, struct group_info *); -extern int groups_search(const struct group_info *, kgid_t); +extern bool groups_search(const struct group_info *, kgid_t); extern bool may_setgroups(void); /* diff --git a/kernel/groups.c b/kernel/groups.c index e357bc8..c1b5d86 100644 --- a/kernel/groups.c +++ b/kernel/groups.c @@ -93,12 +93,12 @@ static void groups_sort(struct group_info *group_info) } /* a simple bsearch */ -int groups_search(const struct group_info *group_info, kgid_t grp) +bool groups_search(const struct group_info *group_info, kgid_t grp) { unsigned int left, right; if (!group_info) - return 0; + return false; left = 0; right = group_info->ngroups; @@ -109,9 +109,9 @@ int groups_search(const struct group_info *group_info, kgid_t grp) else if (gid_lt(grp, group_info->gid[mid])) right = mid; else - return 1; + return true; } - return 0; + return false; } /** -- 1.8.3.1
[PATCH] arm64: dts: ls1088a: add DT node of watchdog
From: Zhang Ying-22455 There are eight cores in ls1088a and each core has an watchdog, ls1088a can use sp805-wdt driver, so we just add DT node for it. Signed-off-by: Zhang Ying-22455 --- arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 56 1 files changed, 56 insertions(+), 0 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi index bd80e9a..c21e4dd 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -292,6 +292,62 @@ status = "disabled"; }; + cluster1_core0_watchdog: wdt@c00 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xc00 0x0 0x1000>; + clocks = <&clockgen 4 3>, <&clockgen 4 3>; + clock-names = "apb_pclk", "wdog_clk"; + }; + + cluster1_core1_watchdog: wdt@c01 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xc01 0x0 0x1000>; + clocks = <&clockgen 4 3>, <&clockgen 4 3>; + clock-names = "apb_pclk", "wdog_clk"; + }; + + cluster1_core2_watchdog: wdt@c02 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xc02 0x0 0x1000>; + clocks = <&clockgen 4 3>, <&clockgen 4 3>; + clock-names = "apb_pclk", "wdog_clk"; + }; + + cluster1_core3_watchdog: wdt@c03 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xc03 0x0 0x1000>; + clocks = <&clockgen 4 3>, <&clockgen 4 3>; + clock-names = "apb_pclk", "wdog_clk"; + }; + + cluster2_core0_watchdog: wdt@c10 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xc10 0x0 0x1000>; + clocks = <&clockgen 4 3>, <&clockgen 4 3>; + clock-names = "apb_pclk", "wdog_clk"; + }; + + cluster2_core1_watchdog: wdt@c11 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xc11 0x0 0x1000>; + clocks = <&clockgen 4 3>, <&clockgen 4 3>; + clock-names = "apb_pclk", "wdog_clk"; + }; + + cluster2_core2_watchdog: wdt@c12 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xc12 0x0 0x1000>; + clocks = <&clockgen 4 3>, <&clockgen 4 3>; + clock-names = "apb_pclk", "wdog_clk"; + }; + + cluster2_core3_watchdog: wdt@c13 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xc13 0x0 0x1000>; + clocks = <&clockgen 4 3>, <&clockgen 4 3>; + clock-names = "apb_pclk", "wdog_clk"; + }; + gpio0: gpio@230 { compatible = "fsl,qoriq-gpio"; reg = <0x0 0x230 0x0 0x1>; -- 1.7.1
[PATCH v2 00/19] ARM: dts: aspeed: updates and new machines
This series of device tree patches for the ASPEED BMC machines moves all systems to use the soon to be merged clk driver, and updates machines to use all of the drivers we have upstream. v2: Address review from Arnd - Remove NUM_CLKS from dt header - Send VUART patch as a fix, drop it from this series - Add reasoning for breaking old kernel in the 'proper clock references' patch In addition it adds three new OpenBMC systems that have been developed in the OpenBMC kernel tree over the past year: two Power9 OpenPower systems, and a port by Google to a Quanta x86 server. I have boot tested these on Romulus and Palmetto, as well as boot tested all device trees in Qemu. Please review the boards you are familiar with. I will merge these in to the ASPEED ARM SoC tree for inclusion in 4.16. Andrew Jeffery (1): ARM: dts: aspeed: Add LPC and child devices Joel Stanley (16): dt-bindings: clock: Add ASPEED constants dt-bindings: gpio: Add ASPEED constants ARM: dts: aspeed: Add proper clock references ARM: dts: aspeed: Add MAC clocks ARM: dts: aspeed: Add watchdog clocks ARM: dts: aspeed: Add flash controller clocks ARM: dts: aspeed: Add clock phandle to GPIO ARM: dts: aspeed: Add PWM and tachometer node ARM: dts: aspeed: Add LPC Snoop device ARM: dts: aspeed: Remove skeleton.dtsi ARM: dts: aspeed: Update license headers ARM: dts: Add OpenBMC flash layout ARM: dts: aspeed: Sort ASPEED entries in makefile ARM: dts: aspeed: Add Witherspoon BMC machine ARM: dts: aspeed-romulus: Update Romulus system ARM: dts: aspeed-plametto: Add flash layout Rick Altherr (1): ARM: dts: aspeed: Add Qanta Q71L BMC machine Xo Wang (1): ARM: dts: aspeed: Add Ingrasys Zaius BMC machine arch/arm/boot/dts/Makefile | 8 +- arch/arm/boot/dts/aspeed-ast2500-evb.dts | 2 +- arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts| 3 +- arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts | 155 ++- arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts | 547 +++ arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts | 427 ++ arch/arm/boot/dts/aspeed-bmc-quanta-q71l.dts | 458 +++ arch/arm/boot/dts/aspeed-g4.dtsi | 164 --- arch/arm/boot/dts/aspeed-g5.dtsi | 155 --- arch/arm/boot/dts/openbmc-flash-layout.dtsi | 32 ++ include/dt-bindings/clock/aspeed-clock.h | 52 +++ include/dt-bindings/gpio/aspeed-gpio.h | 49 ++ 12 files changed, 1906 insertions(+), 146 deletions(-) create mode 100644 arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts create mode 100644 arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts create mode 100644 arch/arm/boot/dts/aspeed-bmc-quanta-q71l.dts create mode 100644 arch/arm/boot/dts/openbmc-flash-layout.dtsi create mode 100644 include/dt-bindings/clock/aspeed-clock.h create mode 100644 include/dt-bindings/gpio/aspeed-gpio.h -- 2.14.1
[PATCH] fsck.f2fs: check and fix i_namelen to avoid double free
Signed-off-by: Yunlong Song --- fsck/fsck.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/fsck/fsck.c b/fsck/fsck.c index 2212aa3..8ff4e4b 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -643,7 +643,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid, u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks); int ofs = get_extra_isize(node_blk); unsigned char *en; - int namelen; + int namelen, i_namelen; unsigned int idx = 0; int need_fix = 0; int ret; @@ -850,8 +850,21 @@ skip_blkcnt_fix: en = malloc(F2FS_NAME_LEN + 1); ASSERT(en); - namelen = convert_encrypted_name(node_blk->i.i_name, - le32_to_cpu(node_blk->i.i_namelen), + i_namelen = le32_to_cpu(node_blk->i.i_namelen); + namelen = strlen((const char *)node_blk->i.i_name); + if (i_namelen > F2FS_NAME_LEN) { + ASSERT_MSG("ino: 0x%x has i_namelen: 0x%x, " + "but has %d characters for name", + nid, i_namelen, namelen); + if (c.fix_on) { + FIX_MSG("[0x%x] i_namelen=0x%x -> 0x%x", nid, i_namelen, + namelen); + node_blk->i.i_namelen = cpu_to_le32(namelen); + need_fix = 1; + } + i_namelen = namelen; + } + namelen = convert_encrypted_name(node_blk->i.i_name, i_namelen, en, file_enc_name(&node_blk->i)); en[namelen] = '\0'; if (ftype == F2FS_FT_ORPHAN) -- 1.8.5.2
[PATCH v2 18/19] ARM: dts: aspeed-romulus: Update Romulus system
- Fix incorrect RAM size - Remove alias; these are now specified in the dtsi - Add newly upstreamed devices - Include OpenBMC flash layout Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts | 153 ++- 1 file changed, 148 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts b/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts index a7a9386f964d..bfdf643584df 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts @@ -7,17 +7,13 @@ model = "Romulus BMC"; compatible = "ibm,romulus-bmc", "aspeed,ast2500"; - aliases { - serial4 = &uart5; - }; - chosen { stdout-path = &uart5; bootargs = "console=ttyS4,115200 earlyprintk"; }; memory { - reg = <0x8000 0x4000>; + reg = <0x8000 0x2000>; }; reserved-memory { @@ -29,6 +25,73 @@ no-map; reg = <0xbf00 0x0100>; /* 16M */ }; + + flash_memory: region@9800 { + no-map; + reg = <0x9800 0x0400>; /* 64M */ + }; + }; + + leds { + compatible = "gpio-leds"; + + fault { + gpios = <&gpio ASPEED_GPIO(N, 2) GPIO_ACTIVE_LOW>; + }; + + identify { + gpios = <&gpio ASPEED_GPIO(N, 4) GPIO_ACTIVE_HIGH>; + }; + + power { + gpios = <&gpio ASPEED_GPIO(R, 5) GPIO_ACTIVE_LOW>; + }; + }; + + fsi: gpio-fsi { + compatible = "fsi-master-gpio", "fsi-master"; + #address-cells = <2>; + #size-cells = <0>; + + clock-gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>; + data-gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_HIGH>; + mux-gpios = <&gpio ASPEED_GPIO(A, 6) GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>; + trans-gpios = <&gpio ASPEED_GPIO(R, 2) GPIO_ACTIVE_HIGH>; + }; + + gpio-keys { + compatible = "gpio-keys"; + + checkstop { + label = "checkstop"; + gpios = <&gpio ASPEED_GPIO(J, 2) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; +}; + +&fmc { + status = "okay"; + + flash@0 { + status = "okay"; + label = "pnor"; + m25p,fast-read; +#include "openbmc-flash-layout.dtsi" + }; +}; + +&spi1 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1_default>; + + flash@0 { + status = "okay"; + label = "pnor"; + m25p,fast-read; }; }; @@ -38,6 +101,7 @@ status = "okay"; m25p,fast-read; label = "bmc"; +#include "openbmc-flash-layout.dtsi" }; }; @@ -53,6 +117,12 @@ }; }; +&lpc_ctrl { + status = "okay"; + memory-region = <&flash_memory>; + flash = <&spi1>; +}; + &uart1 { /* Rear RS-232 connector */ status = "okay"; @@ -81,6 +151,10 @@ pinctrl-0 = <&pinctrl_rmii1_default>; }; +&i2c1 { + status = "okay"; +}; + &i2c2 { status = "okay"; }; @@ -133,8 +207,77 @@ &i2c12 { status = "okay"; + + max31785@52 { + compatible = "maxim,max31785"; + reg = <0x52>; + }; +}; + +&gpio { + nic_func_mode0 { + gpio-hog; + gpios = ; + output-low; + line-name = "nic_func_mode0"; + }; + nic_func_mode1 { + gpio-hog; + gpios = ; + output-low; + line-name = "nic_func_mode1"; + }; }; &vuart { status = "okay"; }; + +&gfx { + status = "okay"; +}; + +&pinctrl { + aspeed,external-nodes = <&gfx &lhc>; +}; + +&pwm_tacho { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default>; + + fan@0 { + reg = <0x00>; + aspeed,fan-tach-ch = /bits/ 8 <0x08>; + }; + + fan@1 { + reg = <0x00>; + aspeed,fan-tach-ch = /bits/ 8 <0x09>; + }; + + fan@2 { + reg = <0x01>; + aspeed,fan-tach-ch = /bits/ 8 <0x0a>; + }; + + fan@3 { + reg = <0x01>; + aspeed,fan-tach-ch = /bits/ 8 <0x0b>; + }; + + fan@4 { + reg = <0x00>; + aspeed,fan-tach-ch = /bits/ 8 <0x0c>; + }; + + fan@5 { + reg = <0x00>; +
[PATCH v2 16/19] ARM: dts: aspeed: Add Ingrasys Zaius BMC machine
From: Xo Wang Zaius is a POWER9 platform announced at OpenPOWER Summit 2016. This adds basic DTS support for its AST2500 BMC. This adds the device tree description for most upstream components. It is a squashed commit of all of the patches from the OpenBMC kernel tree. Signed-off-by: Xo Wang Signed-off-by: Patrick Venture Signed-off-by: Robert Lippert Signed-off-by: Peter Hanson Signed-off-by: Jeremy Kerr Signed-off-by: CĂ©dric Le Goater Signed-off-by: Rick Altherr Signed-off-by: Joel Stanley --- arch/arm/boot/dts/Makefile | 4 +- arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts | 427 + 2 files changed, 429 insertions(+), 2 deletions(-) create mode 100644 arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 15a9207319c1..48c55f307aa9 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1105,6 +1105,6 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-ast2500-evb.dtb \ aspeed-bmc-opp-palmetto.dtb \ aspeed-bmc-opp-romulus.dtb \ - aspeed-bmc-opp-witherspoon.dtb - + aspeed-bmc-opp-witherspoon.dtb \ + aspeed-bmc-opp-zaius.dtb endif diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts b/arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts new file mode 100644 index ..90d77012495d --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts @@ -0,0 +1,427 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "aspeed-g5.dtsi" +#include + +/ { + model = "Zaius BMC"; + compatible = "ingrasys,zaius-bmc", "aspeed,ast2500"; + + chosen { + stdout-path = &uart5; + bootargs = "console=ttyS4,115200 earlyprintk"; + }; + + memory { + reg = <0x8000 0x4000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + flash_memory: region@9800 { + no-map; + reg = <0x9800 0x0400>; /* 64M */ + }; + }; + + onewire0 { + compatible = "w1-gpio"; + gpios = <&gpio ASPEED_GPIO(H, 0) GPIO_ACTIVE_HIGH>; + }; + + onewire1 { + compatible = "w1-gpio"; + gpios = <&gpio ASPEED_GPIO(H, 1) GPIO_ACTIVE_HIGH>; + }; + + onewire2 { + compatible = "w1-gpio"; + gpios = <&gpio ASPEED_GPIO(H, 2) GPIO_ACTIVE_HIGH>; + }; + + onewire3 { + compatible = "w1-gpio"; + gpios = <&gpio ASPEED_GPIO(H, 3) GPIO_ACTIVE_HIGH>; + }; + + gpio-keys { + compatible = "gpio-keys"; + + checkstop { + label = "checkstop"; + gpios = <&gpio ASPEED_GPIO(F, 7) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + sys_boot_status { + label = "System boot status"; + gpios = <&gpio ASPEED_GPIO(D, 5) GPIO_ACTIVE_LOW>; + }; + + attention { + label = "Attention"; + gpios = <&gpio ASPEED_GPIO(D, 6) GPIO_ACTIVE_LOW>; + }; + + plt_fault { + label = "Platform fault"; + gpios = <&gpio ASPEED_GPIO(D, 7) GPIO_ACTIVE_LOW>; + }; + + hdd_fault { + label = "Onboard drive fault"; + gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_LOW>; + }; + }; + + fsi: gpio-fsi { + compatible = "fsi-master-gpio", "fsi-master"; + #address-cells = <2>; + #size-cells = <0>; + + trans-gpios = <&gpio ASPEED_GPIO(O, 6) GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>; + clock-gpios = <&gpio ASPEED_GPIO(G, 0) GPIO_ACTIVE_HIGH>; + data-gpios = <&gpio ASPEED_GPIO(G, 1) GPIO_ACTIVE_HIGH>; + mux-gpios = <&gpio ASPEED_GPIO(P, 6) GPIO_ACTIVE_HIGH>; + }; + + iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>, + <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>, + <&adc 8>, <&adc 9>, <&adc 10>, <&adc 11>, + <&adc 13>, <&adc 14>, <&adc 15>; + }; + + iio-hwmon-battery { + compatible = "iio-hwmon"; + io-channels = <&adc 12>; + }; + +}; + +&fmc { + status = "okay"; + + flash@0 { + status = "okay"; + label = "bmc"; + m25p,fast-read; +#include "openbmc-flash-layout.dtsi" + }; +}; + +&spi1 { +
[PATCH v2 19/19] ARM: dts: aspeed-plametto: Add flash layout
The OpenBMC flash layout is used by Palmetto systems. Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts index a8f0c046e83e..cc18137386f2 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts @@ -34,6 +34,7 @@ status = "okay"; m25p,fast-read; label = "bmc"; +#include "openbmc-flash-layout.dtsi" }; }; -- 2.14.1
[PATCH v2 17/19] ARM: dts: aspeed: Add Qanta Q71L BMC machine
From: Rick Altherr The Qanta Q71L BMC is an ASPEED ast2400 based BMC that is part of a Qanta x86 server. This adds the device tree description for most upstream components. It is a squashed commit from the OpenBMC kernel tree. Signed-off-by: Peter Hanson Signed-off-by: Andrew Jeffery Signed-off-by: Patrick Venture Signed-off-by: Rick Altherr Signed-off-by: Joel Stanley --- arch/arm/boot/dts/Makefile | 3 +- arch/arm/boot/dts/aspeed-bmc-quanta-q71l.dts | 458 +++ 2 files changed, 460 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/aspeed-bmc-quanta-q71l.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 48c55f307aa9..5ab5d9169511 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1106,5 +1106,6 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-bmc-opp-palmetto.dtb \ aspeed-bmc-opp-romulus.dtb \ aspeed-bmc-opp-witherspoon.dtb \ - aspeed-bmc-opp-zaius.dtb + aspeed-bmc-opp-zaius.dtb \ + aspeed-bmc-quanta-q71l.dtb endif diff --git a/arch/arm/boot/dts/aspeed-bmc-quanta-q71l.dts b/arch/arm/boot/dts/aspeed-bmc-quanta-q71l.dts new file mode 100644 index ..2f40bab63149 --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-quanta-q71l.dts @@ -0,0 +1,458 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "aspeed-g4.dtsi" + +/ { + model = "Quanta Q71L BMC"; + compatible = "quanta,q71l-bmc", "aspeed,ast2400"; + + chosen { + stdout-path = &uart5; + bootargs = "console=ttyS4,115200 earlyprintk"; + }; + + memory { + reg = <0x4000 0x800>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + vga_memory: framebuffer@4780 { + no-map; + reg = <0x4780 0x0080>; /* 8MB */ + }; + }; + + leds { + compatible = "gpio-leds"; + + heartbeat { + gpios = <&gpio ASPEED_GPIO(B, 0) GPIO_ACTIVE_LOW>; + }; + + power { + gpios = <&gpio ASPEED_GPIO(B, 2) GPIO_ACTIVE_LOW>; + }; + + identify { + gpios = <&gpio ASPEED_GPIO(B, 3) GPIO_ACTIVE_LOW>; + }; + }; + + iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>, + <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>, + <&adc 8>, <&adc 9>, <&adc 10>; + }; + + iio-hwmon-battery { + compatible = "iio-hwmon"; + io-channels = <&adc 11>; + }; + + i2c1mux: i2cmux { + compatible = "i2c-mux-gpio"; + #address-cells = <1>; + #size-cells = <0>; + + /* mux-gpios = <&sgpio 10 GPIO_ACTIVE_HIGH> */ + i2c-parent = <&i2c1>; + }; +}; + +&fmc { + status = "okay"; + flash@0 { + status = "okay"; + label = "bmc"; + m25p,fast-read; +#include "openbmc-flash-layout.dtsi" + }; +}; + +&spi { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1_default>; + + flash@0 { + status = "okay"; + m25p,fast-read; + label = "pnor"; + }; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_vgahs_default &pinctrl_vgavs_default + &pinctrl_ddcclk_default &pinctrl_ddcdat_default>; +}; + +&lpc_snoop { + status = "okay"; + snoop-ports = <0x80>; +}; + +&mac0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rmii1_default>; + use-ncsi; +}; + +&mac1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>; +}; + +&uart5 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + /* temp2 inlet */ + tmp75@4c { + compatible = "ti,tmp75"; + reg = <0x4c>; + }; + + /* temp3 */ + tmp75@4e { + compatible = "ti,tmp75"; + reg = <0x4e>; + }; + + /* temp1 */ + tmp75@4f { + compatible = "ti,tmp75"; + reg = <0x4f>; + }; + + /* Baseboard FRU */ + eeprom@54 { + compatible = "atmel,24c64"; + reg = <0x54>; + }; + + /* FP FRU */ + eeprom@57 { + compatible = "atmel,24c64"; + reg = <0x57>; + }; +}; + +&i2c2 { + status = "okay"; + + /* 0: PCIe Slot 2, +*Slot 3, +*Slot 6, +*Slo
[PATCH v2 12/19] ARM: dts: aspeed: Update license headers
In b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to files with no license") these files had the GPL-2.0 licence added automatically. Update them to be GPL 2.0+ in line with other IBM kernel contributions. Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-ast2500-evb.dts | 2 +- arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts | 2 +- arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts | 2 +- arch/arm/boot/dts/aspeed-g4.dtsi | 2 +- arch/arm/boot/dts/aspeed-g5.dtsi | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-ast2500-evb.dts b/arch/arm/boot/dts/aspeed-ast2500-evb.dts index 602bc10fdaf4..3e6f38e5d5d0 100644 --- a/arch/arm/boot/dts/aspeed-ast2500-evb.dts +++ b/arch/arm/boot/dts/aspeed-ast2500-evb.dts @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ /dts-v1/; #include "aspeed-g5.dtsi" diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts index c786bc2f2919..a8f0c046e83e 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ /dts-v1/; #include "aspeed-g4.dtsi" diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts b/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts index 8067793129ea..a7a9386f964d 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ /dts-v1/; #include "aspeed-g5.dtsi" diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index 2d7ac577d6b5..9c175832babc 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ #include #include diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 030a760696fd..360329eab7c3 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ #include #include -- 2.14.1
[PATCH v2 15/19] ARM: dts: aspeed: Add Witherspoon BMC machine
The Witherspoon BMC is an ASPEED ast2500 based BMC that is part of an OpenPower Power9 server. This adds the device tree description for most upstream components. It is a squashed commit from the OpenBMC kernel tree. Signed-off-by: Brandon Wyman Signed-off-by: Matt Spinler Signed-off-by: Brad Bishop Signed-off-by: Edward A. James Signed-off-by: CĂ©dric Le Goater Signed-off-by: Andrew Jeffery Reviewed-by: Brandon Wyman Signed-off-by: Joel Stanley -- v2: Add Brandon's reviewed-by tag --- arch/arm/boot/dts/Makefile | 4 +- arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts | 547 +++ 2 files changed, 550 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 5d1e9d37bf3a..15a9207319c1 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1104,5 +1104,7 @@ dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-ast2500-evb.dtb \ aspeed-bmc-opp-palmetto.dtb \ - aspeed-bmc-opp-romulus.dtb + aspeed-bmc-opp-romulus.dtb \ + aspeed-bmc-opp-witherspoon.dtb + endif diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts b/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts new file mode 100644 index ..9a0937512e5b --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts @@ -0,0 +1,547 @@ +// SPDX-License-Identifier: GPL-2.0+ +/dts-v1/; +#include "aspeed-g5.dtsi" +#include + +/ { + model = "Witherspoon BMC"; + compatible = "ibm,witherspoon-bmc", "aspeed,ast2500"; + + chosen { + stdout-path = &uart5; + bootargs = "console=ttyS4,115200 earlyprintk"; + }; + + memory { + reg = <0x8000 0x2000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + flash_memory: region@9800 { + no-map; + reg = <0x9800 0x0400>; /* 64M */ + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <1000>; + + fan0-presence { + label = "fan0-presence"; + gpios = <&pca0 4 GPIO_ACTIVE_LOW>; + linux,code = <4>; + }; + + fan1-presence { + label = "fan1-presence"; + gpios = <&pca0 5 GPIO_ACTIVE_LOW>; + linux,code = <5>; + }; + + fan2-presence { + label = "fan2-presence"; + gpios = <&pca0 6 GPIO_ACTIVE_LOW>; + linux,code = <6>; + }; + + fan3-presence { + label = "fan3-presence"; + gpios = <&pca0 7 GPIO_ACTIVE_LOW>; + linux,code = <7>; + }; + }; + + leds { + compatible = "gpio-leds"; + + fan0 { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca0 0 GPIO_ACTIVE_LOW>; + }; + + fan1 { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca0 1 GPIO_ACTIVE_LOW>; + }; + + fan2 { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca0 2 GPIO_ACTIVE_LOW>; + }; + + fan3 { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca0 3 GPIO_ACTIVE_LOW>; + }; + + front-fault { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca0 13 GPIO_ACTIVE_LOW>; + }; + + front-power { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca0 14 GPIO_ACTIVE_LOW>; + }; + + front-id { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca0 15 GPIO_ACTIVE_LOW>; + }; + + rear-fault { + gpios = <&gpio ASPEED_GPIO(N, 2) GPIO_ACTIVE_LOW>; + }; + + rear-id { + gpios = <&gpio ASPEED_GPIO(N, 4) GPIO_ACTIVE_LOW>; + }; + + rear-power { + gpios = <&gpio ASPEED_GPIO(N, 3) GPI
[PATCH v2 14/19] ARM: dts: aspeed: Sort ASPEED entries in makefile
In preperation for adding more boards. Signed-off-by: Joel Stanley --- arch/arm/boot/dts/Makefile | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index d0381e9caf21..5d1e9d37bf3a 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1101,7 +1101,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt8127-moose.dtb \ mt8135-evbp1.dtb dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb -dtb-$(CONFIG_ARCH_ASPEED) += aspeed-bmc-opp-palmetto.dtb \ - aspeed-bmc-opp-romulus.dtb \ - aspeed-ast2500-evb.dtb +dtb-$(CONFIG_ARCH_ASPEED) += \ + aspeed-ast2500-evb.dtb \ + aspeed-bmc-opp-palmetto.dtb \ + aspeed-bmc-opp-romulus.dtb endif -- 2.14.1
[PATCH v2 13/19] ARM: dts: Add OpenBMC flash layout
This is a layout used by OpenBMC systems. It describes the fixed flash layout of a 32MB mtd device. Signed-off-by: Joel Stanley --- arch/arm/boot/dts/openbmc-flash-layout.dtsi | 32 + 1 file changed, 32 insertions(+) create mode 100644 arch/arm/boot/dts/openbmc-flash-layout.dtsi diff --git a/arch/arm/boot/dts/openbmc-flash-layout.dtsi b/arch/arm/boot/dts/openbmc-flash-layout.dtsi new file mode 100644 index ..63ad8db7a431 --- /dev/null +++ b/arch/arm/boot/dts/openbmc-flash-layout.dtsi @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0+ + +partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + u-boot@0 { + reg = <0x0 0x6>; + label = "u-boot"; + }; + + u-boot-env@6 { + reg = <0x6 0x2>; + label = "u-boot-env"; + }; + + kernel@8 { + reg = <0x8 0x44>; + label = "kernel"; + }; + + rofs@0c { + reg = <0x4c 0x174>; + label = "rofs"; + }; + + rwfs@1c0 { + reg = <0x1c0 0x40>; + label = "rwfs"; + }; +}; -- 2.14.1
[PATCH v2 11/19] ARM: dts: aspeed: Remove skeleton.dtsi
We don't require it for any of the ASPEED systems. Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-g4.dtsi | 1 - arch/arm/boot/dts/aspeed-g5.dtsi | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index b3580f37f507..2d7ac577d6b5 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "skeleton.dtsi" #include #include diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 50766f0629f8..030a760696fd 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "skeleton.dtsi" #include #include -- 2.14.1
[PATCH] fsck.f2fs: check nid range before use to avoid segmentation fault
Signed-off-by: Yunlong Song --- fsck/fsck.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fsck/fsck.c b/fsck/fsck.c index 11b8b0b..2212aa3 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -14,6 +14,15 @@ char *tree_mark; uint32_t tree_mark_size = 256; +static inline int check_nid_range(struct f2fs_sb_info *sbi, nid_t nid) +{ +if (nid < F2FS_ROOT_INO(sbi)) +return -EINVAL; +if (nid >= NM_I(sbi)->max_nid) +return -EINVAL; +return 0; +} + int f2fs_set_main_bitmap(struct f2fs_sb_info *sbi, u32 blk, int type) { struct f2fs_fsck *fsck = F2FS_FSCK(sbi); @@ -740,7 +749,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid, for (idx = 0; idx < 5; idx++) { u32 nid = le32_to_cpu(node_blk->i.i_nid[idx]); - if (nid != 0) { + if (nid != 0 && !check_nid_range(sbi, nid)) { struct node_info ni; get_node_info(sbi, nid, &ni); -- 1.8.5.2
[PATCH v2 07/19] ARM: dts: aspeed: Add flash controller clocks
Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-g4.dtsi | 2 ++ arch/arm/boot/dts/aspeed-g5.dtsi | 3 +++ 2 files changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index 2e3666d4fbeb..afac0ca0cb10 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -56,6 +56,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2400-fmc"; + clocks = <&syscon ASPEED_CLK_AHB>; status = "disabled"; interrupts = <19>; flash@0 { @@ -71,6 +72,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2400-spi"; + clocks = <&syscon ASPEED_CLK_AHB>; status = "disabled"; flash@0 { reg = < 0 >; diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 24bb2d16b900..f3689caf6fe2 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -56,6 +56,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2500-fmc"; + clocks = <&syscon ASPEED_CLK_AHB>; status = "disabled"; interrupts = <19>; flash@0 { @@ -81,6 +82,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2500-spi"; + clocks = <&syscon ASPEED_CLK_AHB>; status = "disabled"; flash@0 { reg = < 0 >; @@ -100,6 +102,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2500-spi"; + clocks = <&syscon ASPEED_CLK_AHB>; status = "disabled"; flash@0 { reg = < 0 >; -- 2.14.1
[PATCH v2 06/19] ARM: dts: aspeed: Add watchdog clocks
Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-g4.dtsi | 2 ++ arch/arm/boot/dts/aspeed-g5.dtsi | 3 +++ 2 files changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index cf407b4db630..2e3666d4fbeb 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -177,11 +177,13 @@ wdt1: watchdog@1e785000 { compatible = "aspeed,ast2400-wdt"; reg = <0x1e785000 0x1c>; + clocks = <&syscon ASPEED_CLK_APB>; }; wdt2: watchdog@1e785020 { compatible = "aspeed,ast2400-wdt"; reg = <0x1e785020 0x1c>; + clocks = <&syscon ASPEED_CLK_APB>; }; vuart: serial@1e787000 { diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index ab26156d6822..24bb2d16b900 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -219,16 +219,19 @@ wdt1: watchdog@1e785000 { compatible = "aspeed,ast2500-wdt"; reg = <0x1e785000 0x20>; + clocks = <&syscon ASPEED_CLK_APB>; }; wdt2: watchdog@1e785020 { compatible = "aspeed,ast2500-wdt"; reg = <0x1e785020 0x20>; + clocks = <&syscon ASPEED_CLK_APB>; }; wdt3: watchdog@1e785040 { compatible = "aspeed,ast2500-wdt"; reg = <0x1e785040 0x20>; + clocks = <&syscon ASPEED_CLK_APB>; status = "disabled"; }; -- 2.14.1
[PATCH v2 10/19] ARM: dts: aspeed: Add LPC Snoop device
LPC snoop hardware on the ASPEED BMC, used for monitoring host I/O port activity. Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-g4.dtsi | 7 +++ arch/arm/boot/dts/aspeed-g5.dtsi | 6 ++ 2 files changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index f6fee40c04c0..b3580f37f507 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -236,6 +236,13 @@ status = "disabled"; }; + lpc_snoop: lpc-snoop@0 { + compatible = "aspeed,ast2500-lpc-snoop"; + reg = <0x0 0x80>; + interrupts = <8>; + status = "disabled"; + }; + lhc: lhc@20 { compatible = "aspeed,ast2500-lhc"; reg = <0x20 0x24 0x48 0x8>; diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 96a9d2fe3f0d..50766f0629f8 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -287,6 +287,12 @@ status = "disabled"; }; + lpc_snoop: lpc-snoop@0 { + compatible = "aspeed,ast2500-lpc-snoop"; + reg = <0x0 0x80>; + interrupts = <8>; + status = "disabled"; + }; lhc: lhc@20 { compatible = "aspeed,ast2500-lhc"; -- 2.14.1
[PATCH v2 08/19] ARM: dts: aspeed: Add clock phandle to GPIO
This enables a feature where the driver can debounce inputs. Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-g4.dtsi | 1 + arch/arm/boot/dts/aspeed-g5.dtsi | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index afac0ca0cb10..fa52a01f50b5 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -144,6 +144,7 @@ reg = <0x1e78 0x1000>; interrupts = <20>; gpio-ranges = <&pinctrl 0 0 220>; + clocks = <&syscon ASPEED_CLK_APB>; interrupt-controller; }; diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index f3689caf6fe2..5e6db2aa5c23 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -187,6 +187,7 @@ reg = <0x1e78 0x1000>; interrupts = <20>; gpio-ranges = <&pinctrl 0 0 220>; + clocks = <&syscon ASPEED_CLK_APB>; interrupt-controller; }; -- 2.14.1
[PATCH v2 09/19] ARM: dts: aspeed: Add PWM and tachometer node
Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-g4.dtsi | 9 + arch/arm/boot/dts/aspeed-g5.dtsi | 9 + 2 files changed, 18 insertions(+) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index fa52a01f50b5..f6fee40c04c0 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -189,6 +189,15 @@ clocks = <&syscon ASPEED_CLK_APB>; }; + pwm_tacho: pwm-tacho-controller@1e786000 { + compatible = "aspeed,ast2400-pwm-tacho"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x1e786000 0x1000>; + clocks = <&syscon ASPEED_CLK_APB>; + status = "disabled"; + }; + vuart: serial@1e787000 { compatible = "aspeed,ast2400-vuart"; reg = <0x1e787000 0x40>; diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 5e6db2aa5c23..96a9d2fe3f0d 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -239,6 +239,15 @@ status = "disabled"; }; + pwm_tacho: pwm-tacho-controller@1e786000 { + compatible = "aspeed,ast2500-pwm-tacho"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x1e786000 0x1000>; + clocks = <&syscon ASPEED_CLK_APB>; + status = "disabled"; + }; + vuart: serial@1e787000 { compatible = "aspeed,ast2500-vuart"; reg = <0x1e787000 0x40>; -- 2.14.1
[PATCH v2 05/19] ARM: dts: aspeed: Add MAC clocks
Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-g4.dtsi | 2 ++ arch/arm/boot/dts/aspeed-g5.dtsi | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index c87883a7f250..cf407b4db630 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -91,6 +91,7 @@ compatible = "aspeed,ast2400-mac", "faraday,ftgmac100"; reg = <0x1e66 0x180>; interrupts = <2>; + clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>; status = "disabled"; }; @@ -98,6 +99,7 @@ compatible = "aspeed,ast2400-mac", "faraday,ftgmac100"; reg = <0x1e68 0x180>; interrupts = <3>; + clocks = <&syscon ASPEED_CLK_GATE_MAC2CLK>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 90bc09d93ea6..ab26156d6822 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -125,6 +125,7 @@ compatible = "aspeed,ast2500-mac", "faraday,ftgmac100"; reg = <0x1e66 0x180>; interrupts = <2>; + clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>; status = "disabled"; }; @@ -132,6 +133,7 @@ compatible = "aspeed,ast2500-mac", "faraday,ftgmac100"; reg = <0x1e68 0x180>; interrupts = <3>; + clocks = <&syscon ASPEED_CLK_GATE_MAC2CLK>; status = "disabled"; }; -- 2.14.1
[PATCH v2 04/19] ARM: dts: aspeed: Add proper clock references
This device tree will break existing kernels that do not have the clk patches applied (no clocksource, as we don't know the speed of the APB clock. You can boot if you pass a lpj value on the command line, but won't have a uart). Older device trees running with the newer kernel will function as well as pre-4.16 kernels. That is, that some IP blocks (i2c, pwm/tach, adc) will not work as the kernel lacks reset controller and clock enabling. This is being changed as existing device trees use fixed-clocks in order to boot without a clk driver. The newly added clk driver provides proper clock support, including gating, so we move the device trees over to properly request clocks. The SCU compatible string is updated as the g4-scu string made it into the tree before we decided on aspeed,astX000- as the format for the strings. The old string will be removed from the bindings in a future patch. Signed-off-by: Joel Stanley --- v2: - Add more detail to the commit message --- arch/arm/boot/dts/aspeed-g4.dtsi | 102 +++--- arch/arm/boot/dts/aspeed-g5.dtsi | 104 +++ 2 files changed, 82 insertions(+), 124 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index a3bc5da7d42c..c87883a7f250 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "skeleton.dtsi" +#include #include / { @@ -107,47 +108,12 @@ ranges; syscon: syscon@1e6e2000 { - compatible = "aspeed,g4-scu", "syscon", "simple-mfd"; + compatible = "aspeed,ast2400-scu", "syscon", "simple-mfd"; reg = <0x1e6e2000 0x1a8>; #address-cells = <1>; #size-cells = <0>; - -clk_clkin: clk_clkin { -#clock-cells = <0>; -compatible = "fixed-clock"; -clock-frequency = <4800>; -}; - -clk_hpll: clk_hpll@70 { -#clock-cells = <0>; -compatible = "aspeed,g4-hpll-clock", "fixed-clock"; -reg = <0x70>; -clocks = <&clk_clkin>; -clock-frequency = <38400>; -}; - -clk_ahb: clk_ahb@70 { -#clock-cells = <0>; -compatible = "aspeed,g4-ahb-clock", "fixed-clock"; -reg = <0x70>; -clocks = <&clk_hpll>; -clock-frequency = <19200>; -}; - -clk_apb: clk_apb@8 { -#clock-cells = <0>; -compatible = "aspeed,g4-apb-clock", "fixed-clock"; -reg = <0x08>; -clocks = <&clk_hpll>; -clock-frequency = <4800>; -}; - -clk_uart: clk_uart@2c{ -#clock-cells = <0>; -compatible = "aspeed,g4-uart-clock", "fixed-clock"; -reg = <0x2c>; -clock-frequency = <2400>; -}; + #clock-cells = <1>; + #reset-cells = <1>; pinctrl: pinctrl { compatible = "aspeed,g4-pinctrl"; @@ -157,7 +123,7 @@ adc: adc@1e6e9000 { compatible = "aspeed,ast2400-adc"; reg = <0x1e6e9000 0xb0>; - clocks = <&clk_apb>; + clocks = <&syscon ASPEED_CLK_APB>; #io-channel-cells = <1>; status = "disabled"; }; @@ -182,7 +148,7 @@ compatible = "aspeed,ast2400-timer"; reg = <0x1e782000 0x90>; interrupts = <16 17 18 35 36 37 38 39>; - clocks = <&clk_apb>; + clocks = <&syscon ASPEED_CLK_APB>; clock-names =
[PATCH v2 02/19] dt-bindings: gpio: Add ASPEED constants
These are used to by the device tree to map pin numbers to constants required by the GPIO bindings. Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-g4.dtsi | 1 + arch/arm/boot/dts/aspeed-g5.dtsi | 1 + include/dt-bindings/gpio/aspeed-gpio.h | 49 ++ 3 files changed, 51 insertions(+) create mode 100644 include/dt-bindings/gpio/aspeed-gpio.h diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index 45d815a86d42..100d092e6c07 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "skeleton.dtsi" +#include / { model = "Aspeed BMC"; diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 5c4ecdba3a6b..1f9d28313f82 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "skeleton.dtsi" +#include / { model = "Aspeed BMC"; diff --git a/include/dt-bindings/gpio/aspeed-gpio.h b/include/dt-bindings/gpio/aspeed-gpio.h new file mode 100644 index ..56fc4889b2c4 --- /dev/null +++ b/include/dt-bindings/gpio/aspeed-gpio.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * This header provides constants for binding aspeed,*-gpio. + * + * The first cell in Aspeed's GPIO specifier is the GPIO ID. The macros below + * provide names for this. + * + * The second cell contains standard flag values specified in gpio.h. + */ + +#ifndef _DT_BINDINGS_GPIO_ASPEED_GPIO_H +#define _DT_BINDINGS_GPIO_ASPEED_GPIO_H + +#include + +#define ASPEED_GPIO_PORT_A 0 +#define ASPEED_GPIO_PORT_B 1 +#define ASPEED_GPIO_PORT_C 2 +#define ASPEED_GPIO_PORT_D 3 +#define ASPEED_GPIO_PORT_E 4 +#define ASPEED_GPIO_PORT_F 5 +#define ASPEED_GPIO_PORT_G 6 +#define ASPEED_GPIO_PORT_H 7 +#define ASPEED_GPIO_PORT_I 8 +#define ASPEED_GPIO_PORT_J 9 +#define ASPEED_GPIO_PORT_K 10 +#define ASPEED_GPIO_PORT_L 11 +#define ASPEED_GPIO_PORT_M 12 +#define ASPEED_GPIO_PORT_N 13 +#define ASPEED_GPIO_PORT_O 14 +#define ASPEED_GPIO_PORT_P 15 +#define ASPEED_GPIO_PORT_Q 16 +#define ASPEED_GPIO_PORT_R 17 +#define ASPEED_GPIO_PORT_S 18 +#define ASPEED_GPIO_PORT_T 19 +#define ASPEED_GPIO_PORT_U 20 +#define ASPEED_GPIO_PORT_V 21 +#define ASPEED_GPIO_PORT_W 22 +#define ASPEED_GPIO_PORT_X 23 +#define ASPEED_GPIO_PORT_Y 24 +#define ASPEED_GPIO_PORT_Z 25 +#define ASPEED_GPIO_PORT_AA 26 +#define ASPEED_GPIO_PORT_AB 27 +#define ASPEED_GPIO_PORT_AC 28 + +#define ASPEED_GPIO(port, offset) \ + ((ASPEED_GPIO_PORT_##port * 8) + offset) + +#endif -- 2.14.1
[PATCH v2 01/19] dt-bindings: clock: Add ASPEED constants
These will be merged as part of the clock driver. This commit is included so the tree will build without the clock series being applied. Signed-off-by: Joel Stanley --- v2: - remove NUM_CLKS define. There's no need for it to be part of ABI --- include/dt-bindings/clock/aspeed-clock.h | 52 1 file changed, 52 insertions(+) create mode 100644 include/dt-bindings/clock/aspeed-clock.h diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h new file mode 100644 index ..d3558d897a4d --- /dev/null +++ b/include/dt-bindings/clock/aspeed-clock.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ + +#ifndef DT_BINDINGS_ASPEED_CLOCK_H +#define DT_BINDINGS_ASPEED_CLOCK_H + +#define ASPEED_CLK_GATE_ECLK 0 +#define ASPEED_CLK_GATE_GCLK 1 +#define ASPEED_CLK_GATE_MCLK 2 +#define ASPEED_CLK_GATE_VCLK 3 +#define ASPEED_CLK_GATE_BCLK 4 +#define ASPEED_CLK_GATE_DCLK 5 +#define ASPEED_CLK_GATE_REFCLK 6 +#define ASPEED_CLK_GATE_USBPORT2CLK7 +#define ASPEED_CLK_GATE_LCLK 8 +#define ASPEED_CLK_GATE_USBUHCICLK 9 +#define ASPEED_CLK_GATE_D1CLK 10 +#define ASPEED_CLK_GATE_YCLK 11 +#define ASPEED_CLK_GATE_USBPORT1CLK12 +#define ASPEED_CLK_GATE_UART1CLK 13 +#define ASPEED_CLK_GATE_UART2CLK 14 +#define ASPEED_CLK_GATE_UART5CLK 15 +#define ASPEED_CLK_GATE_ESPICLK16 +#define ASPEED_CLK_GATE_MAC1CLK17 +#define ASPEED_CLK_GATE_MAC2CLK18 +#define ASPEED_CLK_GATE_RSACLK 19 +#define ASPEED_CLK_GATE_UART3CLK 20 +#define ASPEED_CLK_GATE_UART4CLK 21 +#define ASPEED_CLK_GATE_SDCLKCLK 22 +#define ASPEED_CLK_GATE_LHCCLK 23 +#define ASPEED_CLK_HPLL24 +#define ASPEED_CLK_AHB 25 +#define ASPEED_CLK_APB 26 +#define ASPEED_CLK_UART27 +#define ASPEED_CLK_SDIO28 +#define ASPEED_CLK_ECLK29 +#define ASPEED_CLK_ECLK_MUX30 +#define ASPEED_CLK_LHCLK 31 +#define ASPEED_CLK_MAC 32 +#define ASPEED_CLK_BCLK33 +#define ASPEED_CLK_MPLL34 + +#define ASPEED_RESET_XDMA 0 +#define ASPEED_RESET_MCTP 1 +#define ASPEED_RESET_ADC 2 +#define ASPEED_RESET_JTAG_MASTER 3 +#define ASPEED_RESET_MIC 4 +#define ASPEED_RESET_PWM 5 +#define ASPEED_RESET_PCIVGA6 +#define ASPEED_RESET_I2C 7 +#define ASPEED_RESET_AHB 8 + +#endif -- 2.14.1
[PATCH v2 03/19] ARM: dts: aspeed: Add LPC and child devices
From: Andrew Jeffery Ensure the ordering is correct and add all of the children in the SoC device trees for the ast2400 and ast2500. Signed-off-by: Andrew Jeffery Signed-off-by: Joel Stanley --- arch/arm/boot/dts/aspeed-g4.dtsi | 35 +++ arch/arm/boot/dts/aspeed-g5.dtsi | 27 +-- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index 100d092e6c07..a3bc5da7d42c 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -226,6 +226,41 @@ status = "disabled"; }; + lpc: lpc@1e789000 { + compatible = "aspeed,ast2400-lpc", "simple-mfd"; + reg = <0x1e789000 0x1000>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1e789000 0x1000>; + + lpc_bmc: lpc-bmc@0 { + compatible = "aspeed,ast2400-lpc-bmc"; + reg = <0x0 0x80>; + }; + + lpc_host: lpc-host@80 { + compatible = "aspeed,ast2400-lpc-host", "simple-mfd", "syscon"; + reg = <0x80 0x1e0>; + reg-io-width = <4>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x80 0x1e0>; + + lpc_ctrl: lpc-ctrl@0 { + compatible = "aspeed,ast2400-lpc-ctrl"; + reg = <0x0 0x80>; + status = "disabled"; + }; + + lhc: lhc@20 { + compatible = "aspeed,ast2500-lhc"; + reg = <0x20 0x24 0x48 0x8>; + }; + }; + }; + uart2: serial@1e78d000 { compatible = "ns16550a"; reg = <0x1e78d000 0x20>; diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 1f9d28313f82..7861631940fe 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -266,6 +266,16 @@ status = "disabled"; }; + vuart: serial@1e787000 { + compatible = "aspeed,ast2500-vuart"; + reg = <0x1e787000 0x40>; + reg-shift = <2>; + interrupts = <10>; + clocks = <&clk_uart>; + no-loopback-test; + status = "disabled"; + }; + lpc: lpc@1e789000 { compatible = "aspeed,ast2500-lpc", "simple-mfd"; reg = <0x1e789000 0x1000>; @@ -289,6 +299,13 @@ reg-io-width = <4>; + lpc_ctrl: lpc-ctrl@0 { + compatible = "aspeed,ast2500-lpc-ctrl"; + reg = <0x0 0x80>; + status = "disabled"; + }; + + lhc: lhc@20 { compatible = "aspeed,ast2500-lhc"; reg = <0x20 0x24 0x48 0x8>; @@ -296,16 +313,6 @@ }; }; - vuart: serial@1e787000 { - compatible = "aspeed,ast2500-vuart"; - reg = <0x1e787000 0x40>; - reg-shift = <2>; - interrupts = <10>; - clocks = <&clk_uart>; - no-loopback-test; - status = "disabled"; - }; - uart2: serial@1e78d000 { compatible = "ns16550a"; reg = <0x1e78d000 0x20>; -- 2.14.1
Re: [PATCH] locking/lockdep: Remove the cross-release locking checks
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 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 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
[PATCH IMPROVEMENT] block, bfq: consider also past I/O in soft real-time detection
BFQ privileges the I/O of soft real-time applications, such as video players, to guarantee to these application a high bandwidth and a low latency. In this respect, it is not easy to correctly detect when an application is soft real-time. A particularly nasty false positive is that of an I/O-bound application that occasionally happens to meet all requirements to be deemed as soft real-time. After being detected as soft real-time, such an application monopolizes the device. Fortunately, BFQ will realize soon that the application is actually not soft real-time and suspend every privilege. Yet, the application may happen again to be wrongly detected as soft real-time, and so on. As highlighted by our tests, this problem causes BFQ to occasionally fail to guarantee a high responsiveness, in the presence of heavy background I/O workloads. The reason is that the background workload happens to be detected as soft real-time, more or less frequently, during the execution of the interactive task under test. To give an idea, because of this problem, Libreoffice Writer occasionally takes 8 seconds, instead of 3, to start up, if there are sequential reads and writes in the background, on a Kingston SSDNow V300. This commit addresses this issue by leveraging the following facts. The reason why some applications are detected as soft real-time despite all BFQ checks to avoid false positives, is simply that, during high CPU or storage-device load, I/O-bound applications may happen to do I/O slowly enough to meet all soft real-time requirements, and pass all BFQ extra checks. Yet, this happens only for limited time periods: slow-speed time intervals are usually interspersed between other time intervals during which these applications do I/O at a very high speed. To exploit these facts, this commit introduces a little change, in the detection of soft real-time behavior, to systematically consider also the recent past: the higher the speed was in the recent past, the later next I/O should arrive for the application to be considered as soft real-time. At the beginning of a slow-speed interval, the minimum arrival time allowed for the next I/O usually happens to still be so high, to fall *after* the end of the slow-speed period itself. As a consequence, the application does not risk to be deemed as soft real-time during the slow-speed interval. Then, during the next high-speed interval, the application cannot, evidently, be deemed as soft real-time (exactly because of its speed), and so on. This extra filtering proved to be rather effective: in the above test, the frequency of false positives became so low that the start-up time was 3 seconds in all iterations (apart from occasional outliers, caused by page-cache-management issues, which are out of the scope of this commit, and cannot be solved by an I/O scheduler). Signed-off-by: Paolo Valente Signed-off-by: Angelo Ruocco --- block/bfq-iosched.c | 115 1 file changed, 81 insertions(+), 34 deletions(-) diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index bcb6d21..a9e06217 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -2917,45 +2917,87 @@ static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq, * whereas soft_rt_next_start is set to infinity for applications that do * not. * - * Unfortunately, even a greedy application may happen to behave in an - * isochronous way if the CPU load is high. In fact, the application may - * stop issuing requests while the CPUs are busy serving other processes, - * then restart, then stop again for a while, and so on. In addition, if - * the disk achieves a low enough throughput with the request pattern - * issued by the application (e.g., because the request pattern is random - * and/or the device is slow), then the application may meet the above - * bandwidth requirement too. To prevent such a greedy application to be - * deemed as soft real-time, a further rule is used in the computation of - * soft_rt_next_start: soft_rt_next_start must be higher than the current - * time plus the maximum time for which the arrival of a request is waited - * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle. - * This filters out greedy applications, as the latter issue instead their - * next request as soon as possible after the last one has been completed - * (in contrast, when a batch of requests is completed, a soft real-time - * application spends some time processing data). + * Unfortunately, even a greedy (i.e., I/O-bound) application may + * happen to meet, occasionally or systematically, both the above + * bandwidth and isochrony requirements. This may happen at least in + * the following circumstances. First, if the CPU load is high. The + * application may stop issuing requests while the CPUs are busy + * serving other processes, then restart, then stop again for a while, + * and so on. The other circumstances are related to th
[PATCH IMPROVEMENT] block, bfq: consider recent past to reduce soft-real-time false positives
Hi, this patch reduces false positives in the detection of bfq_queues associated with soft real-time applications. As such, this patch reduces the damages caused by these false positives to other applications. The patch proved to be very effective, as detailed in the commit message. A sort of counterpart of this patch should follow soon, this time for false positives in the detection of cooperating processes (processes doing I/O close to each other). I guess it is evidently too late for 4.15, so, Jens, please consider this patch for 4.16. Of course if the patch turns out to be ok. Thanks, Paolo Paolo Valente (1): block, bfq: consider also past I/O in soft real-time detection block/bfq-iosched.c | 115 1 file changed, 81 insertions(+), 34 deletions(-) -- 2.10.0
Re: [PATCH] vfio: Simplify capability helper
On Wed, Dec 13, 2017 at 04:32:10PM +0100, Auger Eric wrote: > Hi, > > On 13/12/17 16:04, Auger Eric wrote: > > Hi Peter, > > > > On 13/12/17 07:49, Peter Xu wrote: > >> On Tue, Dec 12, 2017 at 12:59:39PM -0700, Alex Williamson wrote: > >>> The vfio_info_add_capability() helper requires the caller to pass a > >>> capability ID, which it then uses to fill in header fields, assuming > >>> hard coded versions. This makes for an awkward and rigid interface. > >>> The only thing we want this helper to do is allocate sufficient > >>> space in the caps buffer and chain this capability into the list. > >>> Reduce it to that simple task. > >>> > >>> Signed-off-by: Alex Williamson > >> > >> Reviewed-by: Peter Xu > >> > >> Though during review I had a question related to the function > >> msix_sparse_mmap_cap(): Is it possible that one PCI device BAR is very > >> small (e.g., 4K) that only contains the MSI-X table (and another small > >> PBA area)? If so, should we just mark that region unmappable instead > >> of setting vfio_region_info_cap_sparse_mmap.nr_areas to 1 in > >> msix_sparse_mmap_cap()? > >> > >>/* If MSI-X table is aligned to the start or end, only one area */ > >>if (((vdev->msix_offset & PAGE_MASK) == 0) || > >>(PAGE_ALIGN(vdev->msix_offset + vdev->msix_size) >= end)) > >>nr_areas = 1; > >> > >> Thanks, > >> > > if I understand the code correctly, if the MSI-X table exactly matches > > the BAR, a sparse mmap region is reported with offset/size = 0. Is that > > correct? > > > > Thanks > > > > Eric > > > looks fixed by > > [RFC PATCH kernel] vfio-pci: Fix sparse capability when no parts of MSIX > BAR can be mapped > > Sorry for the noise. Hi, Eric, Thanks for the link anyways. :) -- Peter Xu
Re: [PATCH] vfio: Simplify capability helper
On Wed, Dec 13, 2017 at 08:35:39AM -0700, Alex Williamson wrote: > On Wed, 13 Dec 2017 16:04:48 +0100 > Auger Eric wrote: > > > Hi Peter, > > > > On 13/12/17 07:49, Peter Xu wrote: > > > On Tue, Dec 12, 2017 at 12:59:39PM -0700, Alex Williamson wrote: > > >> The vfio_info_add_capability() helper requires the caller to pass a > > >> capability ID, which it then uses to fill in header fields, assuming > > >> hard coded versions. This makes for an awkward and rigid interface. > > >> The only thing we want this helper to do is allocate sufficient > > >> space in the caps buffer and chain this capability into the list. > > >> Reduce it to that simple task. > > >> > > >> Signed-off-by: Alex Williamson > > > > > > Reviewed-by: Peter Xu > > > > > > Though during review I had a question related to the function > > > msix_sparse_mmap_cap(): Is it possible that one PCI device BAR is very > > > small (e.g., 4K) that only contains the MSI-X table (and another small > > > PBA area)? If so, should we just mark that region unmappable instead > > > of setting vfio_region_info_cap_sparse_mmap.nr_areas to 1 in > > > msix_sparse_mmap_cap()? > > > > > > /* If MSI-X table is aligned to the start or end, only one area */ > > > if (((vdev->msix_offset & PAGE_MASK) == 0) || > > > (PAGE_ALIGN(vdev->msix_offset + vdev->msix_size) >= end)) > > > nr_areas = 1; > > > > > > Thanks, > > > > > if I understand the code correctly, if the MSI-X table exactly matches > > the BAR, a sparse mmap region is reported with offset/size = 0. Is that > > correct? > > Yes, and that was a compatibility choice when the sparse mmap was > added, retaining the per region mmap flag, but essentially excluding > the whole area with the sparse mmap. It seemed like it'd be easier for > userspace to understand the distinction. I see. > Now we're trying to remove > the whole mess and allow mmaps covering the MSI-X vector table because > it's a performance killer for systems where the page size is >4K. Yeah, I just noticed that. Thanks for explaining! -- Peter Xu
Re: [PATCH 0/4] Sunxi: Add SMP support on A83T
On Tue, Dec 12, 2017 at 09:24:25AM +0100, Maxime Ripard wrote: > Hi, > > On Mon, Dec 11, 2017 at 08:35:34PM +0100, Corentin Labbe wrote: > > On Mon, Dec 11, 2017 at 08:49:57AM +0100, Mylène Josserand wrote: > > > This series adds SMP support for Allwinner Sun8i-a83t > > > with MCPM (Multi-Cluster Power Management). > > > Series information: > > > - Based on last linux-next (next-20171211) > > > - Had dependencies on Chen Yu's patch that add MCPM > > > support: > > > https://patchwork.kernel.org/patch/6402801/ > > > > > > Patch 01: Convert the mcpm driver (initially for A80) to be able > > > to use it for A83T. This SoC has a bit flip that needs to be handled. > > > Patch 02: Add registers nodes (prcm, cpucfg and r_cpucfg) needed > > > for MCPM. > > > Patch 03: Add CCI-400 node for a83t. > > > Patch 04: Fix the use of virtual timers that hangs the kernel in > > > case of SMP support. > > > > As we discussed in private, Chen Yu's patch should be added in your series. > > Not really, she mentionned the dependency in the cover letter, and > it's a good way to do things too. Sure, you can do it your way, but > there's no preference. > If the goal of this series is to be applied, the dependency must be applied also. And since the dependency is 2 years old (and part of a serie which does not apply now), I think cherry picking the patch and send it for review is better. > > Furthermore, MCPM is not automaticaly selected via imply. > > Well, yes, is that an issue? > After reading the imply documentation, no. > > With all patchs I hit a bug: > > [0.898668] BUG: sleeping function called from invalid context at > > kernel/locking/mutex.c:238 > > I guess this is with CONFIG_PROVE_LOCKING enabled? > No, the BUG() printed is enabled by default > > [0.911162] in_atomic(): 1, irqs_disabled(): 0, pid: 1, name: swapper/0 > > [0.917776] CPU: 0 PID: 1 Comm: swapper/0 Not tainted > > 4.15.0-rc2-next-20171211+ #73 > > What are the changes you've made? > Just adding wens's patch and this series. > > [0.925418] Hardware name: Allwinner sun8i Family > > [0.930118] Backtrace: > > [0.932596] [] (dump_backtrace) from [] > > (show_stack+0x18/0x1c) > > [0.940158] r7:c0b261e4 r6:6013 r5: r4:c0b51958 > > [0.945820] [] (show_stack) from [] > > (dump_stack+0x8c/0xa0) > > [0.953045] [] (dump_stack) from [] > > (___might_sleep+0x150/0x170) > > [0.960779] r7:c0b261e4 r6: r5:00ee r4:ee844000 > > [0.966437] [] (___might_sleep) from [] > > (__might_sleep+0x68/0xa0) > > [0.974253] r4:c0861690 > > [0.976796] [] (__might_sleep) from [] > > (mutex_lock+0x24/0x68) > > [0.984269] r6:c0892f6c r5: r4:c0b1bb24 > > [0.988891] [] (mutex_lock) from [] > > (perf_pmu_register+0x24/0x3e4) > > [0.996795] r5: r4:ee98b014 > > [1.000375] [] (perf_pmu_register) from [] > > (cci_pmu_probe+0x340/0x484) > > [1.008631] r10:c0892f6c r9:c0bfd5f0 r8:eea19010 r7:c0b261e4 > > r6:c0b26240 r5:eea19000 > > [1.016447] r4:ee98b010 > > [1.018989] [] (cci_pmu_probe) from [] > > (platform_drv_probe+0x58/0xb8) > > [1.027158] r10: r9:c0b2610c r8: r7:fdfb > > r6:c0b2610c r5:ffed > > [1.034974] r4:eea19010 > > [1.037511] [] (platform_drv_probe) from [] > > (driver_probe_device+0x254/0x330) > > [1.046371] r7: r6:c0bff498 r5:c0bff494 r4:eea19010 > > [1.052026] [] (driver_probe_device) from [] > > (__device_attach_driver+0xa0/0xd4) > > [1.061062] r10: r9:c0bff470 r8: r7:0001 > > r6:eea19010 r5:ee845ac0 > > [1.068879] r4:c0b2610c r3: > > [1.072454] [] (__device_attach_driver) from [] > > (bus_for_each_drv+0x68/0x9c) > > [1.081228] r7:0001 r6:c045cb24 r5:ee845ac0 r4: > > [1.086883] [] (bus_for_each_drv) from [] > > (__device_attach+0xb8/0x11c) > > [1.095135] r6:c0b3e848 r5:eea19044 r4:eea19010 > > [1.099750] [] (__device_attach) from [] > > (device_initial_probe+0x14/0x18) > > [1.108263] r7:c0b0a4c8 r6:c0b3e848 r5:eea19010 r4:eea19018 > > [1.113919] [] (device_initial_probe) from [] > > (bus_probe_device+0x8c/0x94) > > [1.122523] [] (bus_probe_device) from [] > > (device_add+0x40c/0x5a0) > > [1.130429] r7:c0b0a4c8 r6:eea19010 r5:eea18a10 r4:eea19018 > > [1.136089] [] (device_add) from [] > > (of_device_add+0x3c/0x44) > > [1.143564] r10: r9: r8: r7:eedf21a4 > > r6:eea18a10 r5: > > [1.151380] r4:eea19000 > > [1.153915] [] (of_device_add) from [] > > (of_platform_device_create_pdata+0x7c/0xac) > > [1.163210] [] (of_platform_device_create_pdata) from > > [] (of_platform_bus_create+0xf4/0x1f0) > > [1.173372] r9: r8: r7:0001 r6: r5:eedf2154 > > r4: > > [1.181107] [] (of_platform_bus_create) from [] > > (of_platform_populate+0x74/0xd4) > > [1.190229] r10:0001 r9:eea18a10
Re: [PATCH 04/14] ARM: dts: dra76x: Create a common file with MMC/SD IOdelay data
Hi Tony, On Thursday 14 December 2017 08:45 PM, Tony Lindgren wrote: > * Kishon Vijay Abraham I [171214 13:44]: >> +&dra7_pmx_core { >> +mmc1_pins_default: mmc1_pins_default { >> +pinctrl-single,pins = < >> +DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_clk.clk */ >> +DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_cmd.cmd */ >> +DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_dat0.dat0 */ >> +DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_dat1.dat1 */ >> +DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_dat2.dat2 */ >> +DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_dat3.dat3 */ >> +>; >> +}; >> + >> +mmc1_pins_sdr12: mmc1_pins_sdr12 { >> +pinctrl-single,pins = < >> +DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_clk.clk */ >> +DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_cmd.cmd */ >> +DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_dat0.dat0 */ >> +DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_dat1.dat1 */ >> +DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_dat2.dat2 */ >> +DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) >> /* mmc1_dat3.dat3 */ >> +>; >> +}; > > Can't you just do: > > pinctrl-0 = <&mmc1_pins_default>; > pinctrl-1 = <&mmc1_pins_default>; > pinctrl-2 = <&mmc1_pins_hs>; > pinctrl-names = "default", "sdr12", "sdr25"; just wanted to make sure every mode has it's own pinctrl group so that it's easy to review. Initially we were thinking something like mmc1_pins_default_sdr12_sdr25. But if you'd prefer we just use mmc1_pins_default for all modes that uses default pinmux configuration, I can change it that way too. Thanks Kishon
Re: [PATCH net-next] net/ncsi: Don't take any action on HNCDSC AEN
Hi Sam, > The current HNCDSC handler takes the status flag from the AEN packet and > will update or change the current channel based on this flag and the > current channel status. > > However the flag from the HNCDSC packet merely represents the host link > state. While the state of the host interface is potentially interesting > information it should not affect the state of the NCSI link. Indeed the > NCSI specification makes no mention of any recommended action related to > the host network controller driver state. Yep, sounds good to me. If the link status does change, we should see an separate AEN for that event. Acked-by: Jeremy Kerr However: we're looking at some behaviour of Broadcom NICs at the moment, where the phy will be reset on link change events. We'd want to make sure that we're not just seeing the HNCDSC events for that too. I'd suggest we also get an Ack from Brian (CCed) to make sure we're not breaking that case. Cheers, Jeremy
RE: [PATCH v3 2/2] misc: Add Xilinx ZYNQMP VCU logicoreIP init driver
Hi Randy, Thanks a lot for the review. > -Original Message- > From: Randy Dunlap [mailto:rdun...@infradead.org] > Sent: Thursday, December 14, 2017 10:43 AM > To: Dhaval Rajeshbhai Shah ; a...@arndb.de; > gre...@linuxfoundation.org; pombreda...@nexb.com; robh...@kernel.org; > mark.rutl...@arm.com > Cc: devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; > michal.si...@xilinx.com; Hyun Kwon ; Dhaval Rajeshbhai > Shah > Subject: Re: [PATCH v3 2/2] misc: Add Xilinx ZYNQMP VCU logicoreIP init driver > > On 12/13/2017 09:55 PM, Dhaval Shah wrote: > > 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 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 | 629 > > > > 3 files changed, 645 insertions(+) > > create mode 100644 drivers/misc/xlnx_vcu.c > > > > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index > > f1a5c23..24ea516 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 > > Please indent the help text (below) by 2 additional spaces, as documented in > coding-style.rst. I will update this. > > > + 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 configure the frequency based on > > +the > >configures > I will update this. > > + clock information get from the logicoreIP register set. > > drop ^get^ > I will update this. > > + > > + If you say yes here you get support for the logcoreIP. > > 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..41819f0 > > --- /dev/null > > +++ b/drivers/misc/xlnx_vcu.c > > @@ -0,0 +1,629 @@ > > +// 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. */ > > [snip] > > > > +/** > > + * xvcu_read - Read from the VCU register space > > + * @iomem: vcu reg space base address > > + * @offset:vcu reg offset from base > > + * > > + * Return: Returns 32bit value from VCU register specified > > + * > > + */ > > +static u32 xvcu_read(void __iomem *iomem, u32 offset) > > You could inline the read() and write() functions... > I will check and will update if required. > > +{ > > + return ioread32(iomem + offset); > > +} > > + > > +/** > > + * xvcu_write - Write to the VCU register space > > + * @iomem: vcu reg space base address > > + * @offset:vcu reg offset from base > > + * @value: Value to write > > + */ > > +static void xvcu_write(void __iomem *iomem, u32 offset, u32 value) { > > + iowrit
[GIT PULL] xen: fixes for 4.15-rc4
Linus, Please git pull the following tag: git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git for-linus-4.15-rc4-tag xen: fixes for 4.15-rc4 It contains two minor fixes for running as Xen dom0: - when built as 32 bit kernel on large machines the Xen LAPIC emulation should report a rather modern LAPIC in order to support enough APIC-Ids - The Xen LAPIC emulation is needed for dom0 only, so build it only for kernels supporting to run as Xen dom0 Thanks. Juergen arch/x86/xen/apic.c | 2 +- drivers/xen/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Jan Beulich (2): x86/Xen: don't report ancient LAPIC version xen: XEN_ACPI_PROCESSOR is Dom0-only
[PATCH v2 5/6] phy: renesas: rcar-gen3-usb2: add rcar_gen3_role_swap_ops
This patch add rcar_gen3_role_swap_ops to support other feature (e.g. gpio handling) easily. Signed-off-by: Yoshihiro Shimoda --- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 51 +++- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index b121f07..f470fb3 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -83,11 +83,23 @@ #define RCAR_GEN3_PHY_HAS_DEDICATED_PINS 1 +struct rcar_gen3_chan; +struct rcar_gen3_role_swap_ops { + void (*init)(struct rcar_gen3_chan *ch); + void (*set_host)(struct rcar_gen3_chan *ch, int host); + bool (*is_host)(struct rcar_gen3_chan *ch); + void (*set_vbus_ctrl)(struct rcar_gen3_chan *ch, int enable); + bool (*check_id)(struct rcar_gen3_chan *ch); + void (*control_irq)(struct rcar_gen3_chan *ch, int enable); + irqreturn_t (*irq_handler)(struct rcar_gen3_chan *ch); +}; + struct rcar_gen3_chan { void __iomem *base; struct extcon_dev *extcon; struct phy *phy; struct regulator *vbus; + const struct rcar_gen3_role_swap_ops *rs_ops; struct work_struct work; bool extcon_host; bool has_otg_pins; @@ -203,17 +215,20 @@ static void rcar_gen3_phy_usb2_work(struct work_struct *work) static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host) { - has_otg_pins_set_host(ch, host); + if (ch->rs_ops && ch->rs_ops->set_host) + ch->rs_ops->set_host(ch, host); } static void rcar_gen3_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable) { - has_otg_pins_set_vbus_ctrl(ch, enable); + if (ch->rs_ops && ch->rs_ops->set_vbus_ctrl) + ch->rs_ops->set_vbus_ctrl(ch, enable); } static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable) { - has_otg_pins_control_irq(ch, enable); + if (ch->rs_ops && ch->rs_ops->control_irq) + ch->rs_ops->control_irq(ch, enable); } static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch) @@ -271,7 +286,10 @@ static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch) static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch) { - return has_otg_pins_check_id(ch); + if (ch->rs_ops && ch->rs_ops->check_id) + return ch->rs_ops->check_id(ch); + + return false; } static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch) @@ -284,7 +302,10 @@ static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch) static bool rcar_gen3_is_host(struct rcar_gen3_chan *ch) { - return has_otg_pins_is_host(ch); + if (ch->rs_ops && ch->rs_ops->is_host) + return ch->rs_ops->is_host(ch); + + return false; } static enum phy_mode rcar_gen3_get_phy_mode(struct rcar_gen3_chan *ch) @@ -350,7 +371,8 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr, static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch) { - has_otg_pins_init(ch); + if (ch->rs_ops && ch->rs_ops->init) + ch->rs_ops->init(ch); rcar_gen3_device_recognition(ch); } @@ -425,9 +447,10 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p) static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) { struct rcar_gen3_chan *ch = _ch; - irqreturn_t ret; + irqreturn_t ret = IRQ_NONE; - ret = has_otg_pins_irq_handler(ch); + if (ch->rs_ops && ch->rs_ops->irq_handler) + ret = ch->rs_ops->irq_handler(ch); if (ret == IRQ_HANDLED) rcar_gen3_device_recognition(ch); @@ -456,6 +479,16 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) EXTCON_NONE, }; +static const struct rcar_gen3_role_swap_ops has_otg_pins_ops = { + .init = has_otg_pins_init, + .set_host = has_otg_pins_set_host, + .is_host= has_otg_pins_is_host, + .set_vbus_ctrl = has_otg_pins_set_vbus_ctrl, + .check_id = has_otg_pins_check_id, + .control_irq= has_otg_pins_control_irq, + .irq_handler= has_otg_pins_irq_handler, +}; + static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -493,6 +526,8 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) int ret; channel->has_otg_pins = (uintptr_t)of_device_get_match_data(dev); + if (channel->has_otg_pins) + channel->rs_ops = &has_otg_pins_ops; channel->extcon = devm_extcon_dev_allocate(dev, rcar_gen3_phy_cable); if (IS_ERR(channel->extcon)) -- 1.9.1
Re: [PATCH v7 0/6] Mediatek MT2712 clock and scpsys support
On Tue, 2017-11-28 at 15:28 +0800, Weiyi Lu wrote: Hi Matthias, Just gentle ping. Many thanks. > This series is based on v4.15-rc1 and composed of > scpsys control (PATCH 1-4) and device tree (PATCH 5-6) > > changes since v6: > - Rebase to v4.15-rc1. > > changes since v5: > - Refine bus protection with proper variable name > and better implementation for the if statement. > > changes since v4: > - Refine scpsys and infracfg for bus protection by passing > a boolean flag to determine the register update method > > changes since v3: > - Rebase to v4.14-rc1. > > changes since v2: > - ensure the clocks used by clocksource driver are registered > before clocksource init() by using CLK_OF_DECLARE() > - correct the frequency of clk32k/clkrtc_ext/clkrtc_int > > changes since v1: > - Rebase to v4.13-next-soc. > - Refine scpsys and infracfg for bus protection. > > *** BLURB HERE *** > > Weiyi Lu (6): > dt-bindings: soc: add MT2712 power dt-bindings > soc: mediatek: extend bus protection API > soc: mediatek: add dependent clock jpgdec/audio for scpsys > soc: mediatek: add MT2712 scpsys support > arm: dts: mt2712: Add clock controller device nodes > arm: dts: Add power controller device node of MT2712 > > .../devicetree/bindings/soc/mediatek/scpsys.txt| 3 + > arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 131 +++ > drivers/soc/mediatek/mtk-infracfg.c| 26 +++- > drivers/soc/mediatek/mtk-scpsys.c | 140 > ++--- > include/dt-bindings/power/mt2712-power.h | 26 > include/linux/soc/mediatek/infracfg.h | 7 +- > 6 files changed, 311 insertions(+), 22 deletions(-) > create mode 100644 include/dt-bindings/power/mt2712-power.h >
[PATCH v2 6/6] phy: renesas: rcar-gen3-usb2: add gpio handling
Some R-Car SoCs (e.g. R-Car D3) doesn't have dedicated pins of VBUS and ID. So, they may be connected to gpio pins. To handle the gpio pins, this patch adds the handling of VBUS and ID pins instead of dedicated pins. Signed-off-by: Yoshihiro Shimoda --- .../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt | 2 + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 77 -- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt index 99b651b..999a6ef 100644 --- a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt @@ -27,6 +27,8 @@ channel as USB OTG: - interrupts: interrupt specifier for the PHY. - vbus-supply: Phandle to a regulator that provides power to the VBUS. This regulator will be managed during the PHY power on/off sequence. +- vbus-gpios: use gpio to control vbus instead of dedicated pin. +- id-gpios: use gpio to detect id instead of dedicated pin. Example (R-Car H3): diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index f470fb3..ea76973 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -100,9 +101,12 @@ struct rcar_gen3_chan { struct phy *phy; struct regulator *vbus; const struct rcar_gen3_role_swap_ops *rs_ops; + struct gpio_desc *gpio_vbus; + struct gpio_desc *gpio_id; struct work_struct work; bool extcon_host; bool has_otg_pins; + bool has_gpio; }; static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm) @@ -199,6 +203,36 @@ static void has_otg_pins_init(struct rcar_gen3_chan *ch) usb2_base + USB2_LINECTRL1); } +static void gpio_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable) +{ + gpiod_set_value(ch->gpio_vbus, enable); +} + +static bool gpio_check_id(struct rcar_gen3_chan *ch) +{ + return gpiod_get_value(ch->gpio_id); +} + +static void gpio_set_host(struct rcar_gen3_chan *ch, int host) +{ + /* In gpio ops, this driver will modify the extcon_host by sysfs */ + if (ch->extcon_host != !!host) { + ch->extcon_host = !!host; + schedule_work(&ch->work); + } +} + +static bool gpio_is_host(struct rcar_gen3_chan *ch) +{ + return ch->extcon_host; +} + +static irqreturn_t gpio_irq_handler(struct rcar_gen3_chan *ch) +{ + /* Nop because the driver will get gpio value after exited */ + return IRQ_HANDLED; +} + static void rcar_gen3_phy_usb2_work(struct work_struct *work) { struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan, @@ -323,7 +357,7 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr, bool is_b_device; enum phy_mode cur_mode, new_mode; - if (!ch->has_otg_pins || !ch->phy->init_count) + if (!(ch->has_otg_pins || ch->has_gpio) || !ch->phy->init_count) return -EIO; if (!strncmp(buf, "host", strlen("host"))) @@ -361,7 +395,7 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr, { struct rcar_gen3_chan *ch = dev_get_drvdata(dev); - if (!ch->has_otg_pins || !ch->phy->init_count) + if (!(ch->has_otg_pins || ch->has_gpio) || !ch->phy->init_count) return -EIO; return sprintf(buf, "%s\n", rcar_gen3_is_host(ch) ? "host" : @@ -388,7 +422,7 @@ static int rcar_gen3_phy_usb2_init(struct phy *p) writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET); /* Initialize otg part */ - if (channel->has_otg_pins) + if (channel->has_otg_pins || channel->has_gpio) rcar_gen3_init_otg(channel); return 0; @@ -489,6 +523,14 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) .irq_handler= has_otg_pins_irq_handler, }; +static const struct rcar_gen3_role_swap_ops gpio_ops = { + .set_host = gpio_set_host, + .is_host= gpio_is_host, + .set_vbus_ctrl = gpio_set_vbus_ctrl, + .check_id = gpio_check_id, + .irq_handler= gpio_irq_handler, +}; + static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -513,9 +555,30 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); - /* call request_irq for OTG */ + channel->gpio_vbus = devm_gpiod_get(dev, "vbus", GPIOD_OUT_LOW); + if (IS_ERR(channel->gpio_vbus) && + PTR_ERR(channel->gpio_vbus) == -EPROBE_DEFER) + return PTR_ERR(channel->gpio_vbus); + + channel->gpio_id = devm_gpiod_get
[PATCH v2 4/6] phy: renesas: rcar-gen3-usb2: use prefix "has_otg_pins_" for dedicated pins handling
To support gpio handling in the future, this patch clean-ups the code to use prefix "has_otg_pins_" functions. Signed-off-by: Yoshihiro Shimoda --- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 130 --- 1 file changed, 85 insertions(+), 45 deletions(-) diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index bca6162..b121f07 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -93,21 +93,21 @@ struct rcar_gen3_chan { bool has_otg_pins; }; -static void rcar_gen3_phy_usb2_work(struct work_struct *work) +static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm) { - struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan, -work); + void __iomem *usb2_base = ch->base; + u32 val = readl(usb2_base + USB2_LINECTRL1); - if (ch->extcon_host) { - extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, true); - extcon_set_state_sync(ch->extcon, EXTCON_USB, false); - } else { - extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, false); - extcon_set_state_sync(ch->extcon, EXTCON_USB, true); - } + dev_vdbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm); + val &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD); + if (dp) + val |= USB2_LINECTRL1_DP_RPD; + if (dm) + val |= USB2_LINECTRL1_DM_RPD; + writel(val, usb2_base + USB2_LINECTRL1); } -static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host) +static void has_otg_pins_set_host(struct rcar_gen3_chan *ch, int host) { void __iomem *usb2_base = ch->base; u32 val = readl(usb2_base + USB2_COMMCTRL); @@ -120,21 +120,27 @@ static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host) writel(val, usb2_base + USB2_COMMCTRL); } -static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm) +static bool has_otg_pins_is_host(struct rcar_gen3_chan *ch) +{ + return !(readl(ch->base + USB2_COMMCTRL) & USB2_COMMCTRL_OTG_PERI); +} + +static irqreturn_t has_otg_pins_irq_handler(struct rcar_gen3_chan *ch) { void __iomem *usb2_base = ch->base; - u32 val = readl(usb2_base + USB2_LINECTRL1); + u32 status = readl(usb2_base + USB2_OBINTSTA); + irqreturn_t ret = IRQ_NONE; - dev_vdbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm); - val &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD); - if (dp) - val |= USB2_LINECTRL1_DP_RPD; - if (dm) - val |= USB2_LINECTRL1_DM_RPD; - writel(val, usb2_base + USB2_LINECTRL1); + if (status & USB2_OBINT_BITS) { + dev_vdbg(&ch->phy->dev, "%s: %08x\n", __func__, status); + writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA); + ret = IRQ_HANDLED; + } + + return ret; } -static void rcar_gen3_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable) +static void has_otg_pins_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable) { void __iomem *usb2_base = ch->base; u32 val = readl(usb2_base + USB2_ADPCTRL); @@ -147,7 +153,7 @@ static void rcar_gen3_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable) writel(val, usb2_base + USB2_ADPCTRL); } -static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable) +static void has_otg_pins_control_irq(struct rcar_gen3_chan *ch, int enable) { void __iomem *usb2_base = ch->base; u32 val = readl(usb2_base + USB2_OBINTEN); @@ -159,6 +165,57 @@ static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable) writel(val, usb2_base + USB2_OBINTEN); } +static bool has_otg_pins_check_id(struct rcar_gen3_chan *ch) +{ + return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); +} + +static void has_otg_pins_init(struct rcar_gen3_chan *ch) +{ + void __iomem *usb2_base = ch->base; + u32 val; + + val = readl(usb2_base + USB2_VBCTRL); + writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); + writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA); + has_otg_pins_control_irq(ch, 1); + val = readl(usb2_base + USB2_ADPCTRL); + writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); + val = readl(usb2_base + USB2_LINECTRL1); + rcar_gen3_set_linectrl(ch, 0, 0); + writel(val | USB2_LINECTRL1_DPRPD_EN | USB2_LINECTRL1_DMRPD_EN, + usb2_base + USB2_LINECTRL1); +} + +static void rcar_gen3_phy_usb2_work(struct work_struct *work) +{ + struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan, +work); + + if (ch->extcon_host) { + extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, tr
[PATCH v2 1/6] phy: renesas: rcar-gen3-usb2: call INIT_WORK() anyway
In the future, the work struct will be used by non-irq related code. So, this patch moves the INIT_WORK() timing. Signed-off-by: Yoshihiro Shimoda --- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index 9c90e7d..c22d65a 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -431,10 +431,11 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) if (IS_ERR(channel->base)) return PTR_ERR(channel->base); + INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); + /* call request_irq for OTG */ irq = platform_get_irq(pdev, 0); if (irq >= 0) { - INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq, IRQF_SHARED, dev_name(dev), channel); if (irq < 0) -- 1.9.1
[PATCH v2 3/6] phy: renesas: rcar-gen3-usb2: change the function name to set_vbus_ctrl()
This patch changes the function name from rcar_gen3_enable_vbus_ctrl() to rcar_gen3_set_vbus_ctrl() because the fucntion both enables and disables. Signed-off-by: Yoshihiro Shimoda --- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index 480f912..bca6162 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -134,13 +134,13 @@ static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm) writel(val, usb2_base + USB2_LINECTRL1); } -static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) +static void rcar_gen3_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable) { void __iomem *usb2_base = ch->base; u32 val = readl(usb2_base + USB2_ADPCTRL); - dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, vbus); - if (vbus) + dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, enable); + if (enable) val |= USB2_ADPCTRL_DRVVBUS; else val &= ~USB2_ADPCTRL_DRVVBUS; @@ -163,7 +163,7 @@ static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch) { rcar_gen3_set_linectrl(ch, 1, 1); rcar_gen3_set_host_mode(ch, 1); - rcar_gen3_enable_vbus_ctrl(ch, 1); + rcar_gen3_set_vbus_ctrl(ch, 1); ch->extcon_host = true; schedule_work(&ch->work); @@ -173,7 +173,7 @@ static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch) { rcar_gen3_set_linectrl(ch, 0, 1); rcar_gen3_set_host_mode(ch, 0); - rcar_gen3_enable_vbus_ctrl(ch, 0); + rcar_gen3_set_vbus_ctrl(ch, 0); ch->extcon_host = false; schedule_work(&ch->work); @@ -189,7 +189,7 @@ static void rcar_gen3_init_for_b_host(struct rcar_gen3_chan *ch) rcar_gen3_set_linectrl(ch, 1, 1); rcar_gen3_set_host_mode(ch, 1); - rcar_gen3_enable_vbus_ctrl(ch, 0); + rcar_gen3_set_vbus_ctrl(ch, 0); val = readl(usb2_base + USB2_LINECTRL1); writel(val & ~USB2_LINECTRL1_OPMODE_NODRV, usb2_base + USB2_LINECTRL1); @@ -199,14 +199,14 @@ static void rcar_gen3_init_for_a_peri(struct rcar_gen3_chan *ch) { rcar_gen3_set_linectrl(ch, 0, 1); rcar_gen3_set_host_mode(ch, 0); - rcar_gen3_enable_vbus_ctrl(ch, 1); + rcar_gen3_set_vbus_ctrl(ch, 1); } static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch) { rcar_gen3_control_otg_irq(ch, 0); - rcar_gen3_enable_vbus_ctrl(ch, 0); + rcar_gen3_set_vbus_ctrl(ch, 0); rcar_gen3_init_for_host(ch); rcar_gen3_control_otg_irq(ch, 1); -- 1.9.1