Merge tag 'LA.BR.1.3.6-04710-8976.0' of https://source.codeaurora.org/quic/la/kernel/msm-3.10 into HEAD

"LA.BR.1.3.6-04710-8976.0"
This commit is contained in:
LuK1337 2017-09-15 11:27:24 +02:00
commit 97104ad488
39 changed files with 556 additions and 275 deletions

View File

@ -1857,7 +1857,9 @@ long diagchar_ioctl(struct file *filp,
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_EVENT_STATUS:
mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_event_status(ioarg);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_CLEAR_LOGS:
mutex_lock(&driver->dci_mutex);

View File

@ -2061,6 +2061,10 @@ static int _sha_complete(struct qce_device *pce_dev)
uint32_t result_dump_status;
areq = (struct ahash_request *) pce_dev->areq;
if (!areq) {
pr_err("sha operation error. areq is NULL\n");
return -ENXIO;
}
qce_dma_unmap_sg(pce_dev->pdev, areq->src, pce_dev->src_nents,
DMA_TO_DEVICE);
memcpy(digest, (char *)(&pce_dev->ce_sps.result->auth_iv[0]),
@ -5513,6 +5517,5 @@ int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
}
EXPORT_SYMBOL(qce_hw_support);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Crypto Engine driver");

View File

@ -3613,6 +3613,7 @@ static int _sha1_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
unsigned int len)
{
struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(&tfm->base);
int ret = 0;
memset(&sha_ctx->authkey[0], 0, SHA1_BLOCK_SIZE);
if (len <= SHA1_BLOCK_SIZE) {
memcpy(&sha_ctx->authkey[0], key, len);
@ -3620,16 +3621,19 @@ static int _sha1_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
} else {
sha_ctx->alg = QCE_HASH_SHA1;
sha_ctx->diglen = SHA1_DIGEST_SIZE;
_sha_hmac_setkey(tfm, key, len);
ret = _sha_hmac_setkey(tfm, key, len);
if (ret)
pr_err("SHA1 hmac setkey failed\n");
sha_ctx->authkey_in_len = SHA1_BLOCK_SIZE;
}
return 0;
return ret;
}
static int _sha256_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
unsigned int len)
{
struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(&tfm->base);
int ret = 0;
memset(&sha_ctx->authkey[0], 0, SHA256_BLOCK_SIZE);
if (len <= SHA256_BLOCK_SIZE) {
@ -3638,11 +3642,13 @@ static int _sha256_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
} else {
sha_ctx->alg = QCE_HASH_SHA256;
sha_ctx->diglen = SHA256_DIGEST_SIZE;
_sha_hmac_setkey(tfm, key, len);
ret = _sha_hmac_setkey(tfm, key, len);
if (ret)
pr_err("SHA256 hmac setkey failed\n");
sha_ctx->authkey_in_len = SHA256_BLOCK_SIZE;
}
return 0;
return ret;
}
static int _sha_hmac_init_ihash(struct ahash_request *req,

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2017, The Linux Foundation. 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 and
@ -107,6 +107,7 @@ static void _kgsl_cmdbatch_timer(unsigned long data)
struct kgsl_device *device;
struct kgsl_cmdbatch *cmdbatch = (struct kgsl_cmdbatch *) data;
struct kgsl_cmdbatch_sync_event *event;
unsigned long flags;
if (cmdbatch == NULL || cmdbatch->context == NULL)
return;
@ -121,14 +122,14 @@ static void _kgsl_cmdbatch_timer(unsigned long data)
kgsl_context_dump(cmdbatch->context);
clear_bit(CMDBATCH_FLAG_FENCE_LOG, &cmdbatch->priv);
spin_lock(&cmdbatch->lock);
spin_lock_irqsave(&cmdbatch->lock, flags);
/* Print all the fences */
list_for_each_entry(event, &cmdbatch->synclist, node) {
if (KGSL_CMD_SYNCPOINT_TYPE_FENCE == event->type &&
event->handle && event->handle->fence)
kgsl_sync_fence_log(event->handle->fence);
}
spin_unlock(&cmdbatch->lock);
spin_unlock_irqrestore(&cmdbatch->lock, flags);
dev_err(device->dev, "--gpu syncpoint deadlock print end--\n");
}
@ -184,15 +185,15 @@ static void kgsl_cmdbatch_sync_expire(struct kgsl_device *device,
struct kgsl_cmdbatch_sync_event *event)
{
struct kgsl_cmdbatch_sync_event *e, *tmp;
unsigned long flags;
int sched = 0;
int removed = 0;
/*
* We may have cmdbatch timer running, which also uses same lock,
* take a lock with software interrupt disabled (bh) to avoid
* spin lock recursion.
* cmdbatch timer or event callback might run at this time in interrupt
* context and uses same lock. So use irq-save version of spin lock.
*/
spin_lock_bh(&event->cmdbatch->lock);
spin_lock_irqsave(&event->cmdbatch->lock, flags);
/*
* sync events that are contained by a cmdbatch which has been
@ -207,8 +208,9 @@ static void kgsl_cmdbatch_sync_expire(struct kgsl_device *device,
}
}
event->handle = NULL;
sched = list_empty(&event->cmdbatch->synclist) ? 1 : 0;
spin_unlock_bh(&event->cmdbatch->lock);
spin_unlock_irqrestore(&event->cmdbatch->lock, flags);
/* If the list is empty delete the canary timer */
if (sched)
@ -269,19 +271,22 @@ void kgsl_cmdbatch_destroy(struct kgsl_cmdbatch *cmdbatch)
struct kgsl_cmdbatch_sync_event *event, *tmpsync;
LIST_HEAD(cancel_synclist);
int sched = 0;
unsigned long flags;
if (IS_ERR_OR_NULL(cmdbatch))
return;
/* Zap the canary timer */
del_timer_sync(&cmdbatch->timer);
/* non-bh because we just destroyed timer */
spin_lock(&cmdbatch->lock);
/*
* callback might run in interrupt context
* so need to use irqsave version of spinlocks.
*/
spin_lock_irqsave(&cmdbatch->lock, flags);
/* Empty the synclist before canceling events */
list_splice_init(&cmdbatch->synclist, &cancel_synclist);
spin_unlock(&cmdbatch->lock);
spin_unlock_irqrestore(&cmdbatch->lock, flags);
/*
* Finish canceling events outside the cmdbatch spinlock and
@ -303,8 +308,15 @@ void kgsl_cmdbatch_destroy(struct kgsl_cmdbatch *cmdbatch)
kgsl_cmdbatch_sync_func, event);
} else if (event->type == KGSL_CMD_SYNCPOINT_TYPE_FENCE) {
/* Put events that are successfully canceled */
if (kgsl_sync_fence_async_cancel(event->handle))
spin_lock_irqsave(&cmdbatch->lock, flags);
if (kgsl_sync_fence_async_cancel(event->handle)) {
event->handle = NULL;
spin_unlock_irqrestore(&cmdbatch->lock, flags);
kgsl_cmdbatch_sync_event_put(event);
} else {
spin_unlock_irqrestore(&cmdbatch->lock, flags);
}
}
/* Put events that have been removed from the synclist */
@ -365,7 +377,7 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device,
{
struct kgsl_cmd_syncpoint_fence *sync = priv;
struct kgsl_cmdbatch_sync_event *event;
unsigned long flags;
event = kzalloc(sizeof(*event), GFP_KERNEL);
if (event == NULL)
return -ENOMEM;
@ -392,11 +404,6 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device,
kref_get(&event->refcount);
/* non-bh because, we haven't started cmdbatch timer yet */
spin_lock(&cmdbatch->lock);
list_add(&event->node, &cmdbatch->synclist);
spin_unlock(&cmdbatch->lock);
/*
* Increment the reference count for the async callback.
* Decrement when the callback is successfully canceled, when
@ -404,6 +411,10 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device,
*/
kref_get(&event->refcount);
spin_lock_irqsave(&cmdbatch->lock, flags);
list_add(&event->node, &cmdbatch->synclist);
event->handle = kgsl_sync_fence_async_wait(sync->fd,
kgsl_cmdbatch_sync_fence_func, event);
@ -411,17 +422,14 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device,
int ret = PTR_ERR(event->handle);
event->handle = NULL;
/* Failed to add the event to the async callback */
kgsl_cmdbatch_sync_event_put(event);
/* Remove event from the synclist */
spin_lock(&cmdbatch->lock);
list_del(&event->node);
spin_unlock(&cmdbatch->lock);
spin_unlock_irqrestore(&cmdbatch->lock, flags);
/* Put for event removal from the synclist */
kgsl_cmdbatch_sync_event_put(event);
/* Event no longer needed by this function */
/* Unable to add event to the async callback so a put */
kgsl_cmdbatch_sync_event_put(event);
/* Put since event no longer needed by this function */
kgsl_cmdbatch_sync_event_put(event);
/*
@ -435,6 +443,7 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device,
}
trace_syncpoint_fence(cmdbatch, event->handle->name);
spin_unlock_irqrestore(&cmdbatch->lock, flags);
/*
* Event was successfully added to the synclist, the async

View File

@ -1767,7 +1767,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
if (r)
goto out;
param->data_size = sizeof(*param);
param->data_size = offsetof(struct dm_ioctl, data);
r = fn(param, input_param_size);
if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) &&

View File

@ -369,6 +369,7 @@ static int msm_fd_open(struct file *file)
ctx->vb2_q.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
ctx->vb2_q.io_modes = VB2_USERPTR;
ctx->vb2_q.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
mutex_init(&ctx->lock);
ret = vb2_queue_init(&ctx->vb2_q);
if (ret < 0) {
dev_err(device->dev, "Error queue init\n");
@ -402,7 +403,9 @@ static int msm_fd_release(struct file *file)
{
struct fd_ctx *ctx = msm_fd_ctx_from_fh(file->private_data);
mutex_lock(&ctx->lock);
vb2_queue_release(&ctx->vb2_q);
mutex_unlock(&ctx->lock);
vfree(ctx->stats);
@ -428,7 +431,9 @@ static unsigned int msm_fd_poll(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(file->private_data);
unsigned int ret;
mutex_lock(&ctx->lock);
ret = vb2_poll(&ctx->vb2_q, file, wait);
mutex_unlock(&ctx->lock);
if (atomic_read(&ctx->subscribed_for_event)) {
poll_wait(file, &ctx->fh.wait, wait);
@ -666,9 +671,9 @@ static int msm_fd_reqbufs(struct file *file,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
mutex_lock(&ctx->fd_device->recovery_lock);
mutex_lock(&ctx->lock);
ret = vb2_reqbufs(&ctx->vb2_q, req);
mutex_unlock(&ctx->fd_device->recovery_lock);
mutex_unlock(&ctx->lock);
return ret;
}
@ -684,9 +689,9 @@ static int msm_fd_qbuf(struct file *file, void *fh,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
mutex_lock(&ctx->fd_device->recovery_lock);
mutex_lock(&ctx->lock);
ret = vb2_qbuf(&ctx->vb2_q, pb);
mutex_unlock(&ctx->fd_device->recovery_lock);
mutex_unlock(&ctx->lock);
return ret;
}
@ -703,9 +708,9 @@ static int msm_fd_dqbuf(struct file *file,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
mutex_lock(&ctx->fd_device->recovery_lock);
mutex_lock(&ctx->lock);
ret = vb2_dqbuf(&ctx->vb2_q, pb, file->f_flags & O_NONBLOCK);
mutex_unlock(&ctx->fd_device->recovery_lock);
mutex_unlock(&ctx->lock);
return ret;
}
@ -721,7 +726,9 @@ static int msm_fd_streamon(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
int ret;
mutex_lock(&ctx->lock);
ret = vb2_streamon(&ctx->vb2_q, buf_type);
mutex_unlock(&ctx->lock);
if (ret < 0)
dev_err(ctx->fd_device->dev, "Stream on fails\n");
@ -740,7 +747,9 @@ static int msm_fd_streamoff(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
int ret;
mutex_lock(&ctx->lock);
ret = vb2_streamoff(&ctx->vb2_q, buf_type);
mutex_unlock(&ctx->lock);
if (ret < 0)
dev_err(ctx->fd_device->dev, "Stream off fails\n");

View File

@ -153,6 +153,8 @@ struct fd_ctx {
struct msm_fd_mem_pool mem_pool;
struct msm_fd_stats *stats;
struct msm_fd_buf_handle work_buf;
struct completion *wait_stop_stream;
struct mutex lock;
};
/*

View File

@ -91,7 +91,8 @@ struct msm_isp_bufq *msm_isp_get_bufq(
uint32_t bufq_index = bufq_handle & 0xFF;
if ((bufq_handle == 0) ||
(bufq_index > buf_mgr->num_buf_q))
(bufq_index >= buf_mgr->num_buf_q) ||
(bufq_index >= BUF_MGR_NUM_BUF_Q))
return NULL;
bufq = &buf_mgr->bufq[bufq_index];

View File

View File

@ -31,7 +31,6 @@
#include "msm_sd.h"
#include <media/msmb_generic_buf_mgr.h>
static struct v4l2_device *msm_v4l2_dev;
static struct list_head ordered_sd_list;
@ -140,7 +139,7 @@ typedef int (*msm_queue_find_func)(void *d1, void *d2);
#define msm_queue_find(queue, type, member, func, data) ({\
unsigned long flags; \
struct msm_queue_head *__q = (queue); \
type *node = 0; \
type *node = NULL; \
typeof(node) __ret = NULL; \
msm_queue_find_func __f = (func); \
spin_lock_irqsave(&__q->lock, flags); \
@ -256,22 +255,46 @@ void msm_delete_stream(unsigned int session_id, unsigned int stream_id)
struct msm_session *session = NULL;
struct msm_stream *stream = NULL;
unsigned long flags;
int try_count = 0;
session = msm_queue_find(msm_session_q, struct msm_session,
list, __msm_queue_find_session, &session_id);
if (!session)
return;
stream = msm_queue_find(&session->stream_q, struct msm_stream,
list, __msm_queue_find_stream, &stream_id);
if (!stream)
return;
spin_lock_irqsave(&(session->stream_q.lock), flags);
list_del_init(&stream->list);
session->stream_q.len--;
kfree(stream);
stream = NULL;
spin_unlock_irqrestore(&(session->stream_q.lock), flags);
while (1) {
if (try_count > 5) {
pr_err("%s : not able to delete stream %d\n",
__func__, __LINE__);
break;
}
write_lock(&session->stream_rwlock);
try_count++;
stream = msm_queue_find(&session->stream_q, struct msm_stream,
list, __msm_queue_find_stream, &stream_id);
if (!stream) {
write_unlock(&session->stream_rwlock);
return;
}
if (msm_vb2_get_stream_state(stream) != 1) {
write_unlock(&session->stream_rwlock);
continue;
}
spin_lock_irqsave(&(session->stream_q.lock), flags);
list_del_init(&stream->list);
session->stream_q.len--;
kfree(stream);
stream = NULL;
spin_unlock_irqrestore(&(session->stream_q.lock), flags);
write_unlock(&session->stream_rwlock);
break;
}
}
@ -338,6 +361,11 @@ static void msm_add_sd_in_position(struct msm_sd_subdev *msm_subdev,
struct msm_sd_subdev *temp_sd;
list_for_each_entry(temp_sd, sd_list, list) {
if (temp_sd == msm_subdev) {
pr_err("%s :Fail to add the same sd %d\n",
__func__, __LINE__);
return;
}
if (msm_subdev->close_seq < temp_sd->close_seq) {
list_add_tail(&msm_subdev->list, &temp_sd->list);
return;
@ -399,6 +427,7 @@ int msm_create_session(unsigned int session_id, struct video_device *vdev)
msm_enqueue(msm_session_q, &session->list);
mutex_init(&session->lock);
mutex_init(&session->close_lock);
rwlock_init(&session->stream_rwlock);
return 0;
}
@ -929,17 +958,25 @@ static struct v4l2_file_operations msm_fops = {
#endif
};
struct msm_stream *msm_get_stream(unsigned int session_id,
unsigned int stream_id)
struct msm_session *msm_get_session(unsigned int session_id)
{
struct msm_session *session;
struct msm_stream *stream;
session = msm_queue_find(msm_session_q, struct msm_session,
list, __msm_queue_find_session, &session_id);
if (!session)
return ERR_PTR(-EINVAL);
return session;
}
EXPORT_SYMBOL(msm_get_session);
struct msm_stream *msm_get_stream(struct msm_session *session,
unsigned int stream_id)
{
struct msm_stream *stream;
stream = msm_queue_find(&session->stream_q, struct msm_stream,
list, __msm_queue_find_stream, &stream_id);
@ -993,6 +1030,33 @@ struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q)
return NULL;
}
struct msm_session *msm_get_session_from_vb2q(struct vb2_queue *q)
{
struct msm_session *session;
struct msm_stream *stream;
unsigned long flags1;
unsigned long flags2;
spin_lock_irqsave(&msm_session_q->lock, flags1);
list_for_each_entry(session, &(msm_session_q->list), list) {
spin_lock_irqsave(&(session->stream_q.lock), flags2);
list_for_each_entry(
stream, &(session->stream_q.list), list) {
if (stream->vb2_q == q) {
spin_unlock_irqrestore
(&(session->stream_q.lock), flags2);
spin_unlock_irqrestore
(&msm_session_q->lock, flags1);
return session;
}
}
spin_unlock_irqrestore(&(session->stream_q.lock), flags2);
}
spin_unlock_irqrestore(&msm_session_q->lock, flags1);
return NULL;
}
EXPORT_SYMBOL(msm_get_session_from_vb2q);
static struct v4l2_subdev *msm_sd_find(const char *name)
{
unsigned long flags;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, 2017 The Linux Foundation. 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 and
@ -108,6 +108,7 @@ struct msm_session {
struct msm_queue_head stream_q;
struct mutex lock;
struct mutex close_lock;
rwlock_t stream_rwlock;
};
void msm_pm_qos_update_request(int val);
@ -121,10 +122,12 @@ int msm_create_stream(unsigned int session_id,
void msm_delete_stream(unsigned int session_id, unsigned int stream_id);
int msm_create_command_ack_q(unsigned int session_id, unsigned int stream_id);
void msm_delete_command_ack_q(unsigned int session_id, unsigned int stream_id);
struct msm_stream *msm_get_stream(unsigned int session_id,
struct msm_session *msm_get_session(unsigned int session_id);
struct msm_stream *msm_get_stream(struct msm_session *session,
unsigned int stream_id);
struct vb2_queue *msm_get_stream_vb2q(unsigned int session_id,
unsigned int stream_id);
struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q);
struct msm_session *msm_get_session_from_vb2q(struct vb2_queue *q);
struct msm_session *msm_session_find(unsigned int session_id);
#endif /*_MSM_H */

View File

@ -205,8 +205,8 @@ static void msm_buf_mngr_sd_shutdown(struct msm_buf_mngr_device *dev,
if (!list_empty(&dev->buf_qhead)) {
list_for_each_entry_safe(bufs,
save, &dev->buf_qhead, entry) {
pr_info("%s: Delete invalid bufs =%lx, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n",
__func__, (unsigned long)bufs, session->session,
pr_info("%s: Delete invalid bufs =%pK, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n",
__func__, (void *)bufs, session->session,
bufs->session_id, bufs->stream_id,
bufs->vb2_buf->v4l2_buf.index);
if (session->session == bufs->session_id) {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, 2017 The Linux Foundation. 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 and
@ -43,16 +43,24 @@ static int msm_vb2_queue_setup(struct vb2_queue *q,
int msm_vb2_buf_init(struct vb2_buffer *vb)
{
struct msm_stream *stream;
struct msm_session *session;
struct msm_vb2_buffer *msm_vb2_buf;
session = msm_get_session_from_vb2q(vb->vb2_queue);
if (IS_ERR_OR_NULL(session))
return -EINVAL;
read_lock(&session->stream_rwlock);
stream = msm_get_stream_from_vb2q(vb->vb2_queue);
if (!stream) {
pr_err("%s: Couldn't find stream\n", __func__);
read_unlock(&session->stream_rwlock);
return -EINVAL;
}
msm_vb2_buf = container_of(vb, struct msm_vb2_buffer, vb2_buf);
msm_vb2_buf->in_freeq = 0;
read_unlock(&session->stream_rwlock);
return 0;
}
@ -60,6 +68,7 @@ static void msm_vb2_buf_queue(struct vb2_buffer *vb)
{
struct msm_vb2_buffer *msm_vb2;
struct msm_stream *stream;
struct msm_session *session;
unsigned long flags;
msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf);
@ -69,21 +78,30 @@ static void msm_vb2_buf_queue(struct vb2_buffer *vb)
return;
}
session = msm_get_session_from_vb2q(vb->vb2_queue);
if (IS_ERR_OR_NULL(session))
return;
read_lock(&session->stream_rwlock);
stream = msm_get_stream_from_vb2q(vb->vb2_queue);
if (!stream) {
pr_err("%s:%d] NULL stream", __func__, __LINE__);
read_unlock(&session->stream_rwlock);
return;
}
spin_lock_irqsave(&stream->stream_lock, flags);
list_add_tail(&msm_vb2->list, &stream->queued_list);
spin_unlock_irqrestore(&stream->stream_lock, flags);
read_unlock(&session->stream_rwlock);
}
static int msm_vb2_buf_finish(struct vb2_buffer *vb)
{
struct msm_vb2_buffer *msm_vb2;
struct msm_stream *stream;
struct msm_session *session;
unsigned long flags;
struct msm_vb2_buffer *msm_vb2_entry, *temp;
@ -94,9 +112,16 @@ static int msm_vb2_buf_finish(struct vb2_buffer *vb)
return -EINVAL;
}
session = msm_get_session_from_vb2q(vb->vb2_queue);
if (IS_ERR_OR_NULL(session))
return -EINVAL;
read_lock(&session->stream_rwlock);
stream = msm_get_stream_from_vb2q(vb->vb2_queue);
if (!stream) {
pr_err("%s:%d] NULL stream", __func__, __LINE__);
read_unlock(&session->stream_rwlock);
return -EINVAL;
}
@ -109,6 +134,7 @@ static int msm_vb2_buf_finish(struct vb2_buffer *vb)
}
}
spin_unlock_irqrestore(&stream->stream_lock, flags);
read_unlock(&session->stream_rwlock);
return 0;
}
@ -116,6 +142,7 @@ static void msm_vb2_buf_cleanup(struct vb2_buffer *vb)
{
struct msm_vb2_buffer *msm_vb2;
struct msm_stream *stream;
struct msm_session *session;
unsigned long flags;
msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf);
@ -125,17 +152,43 @@ static void msm_vb2_buf_cleanup(struct vb2_buffer *vb)
return;
}
session = msm_get_session_from_vb2q(vb->vb2_queue);
if (IS_ERR_OR_NULL(session))
return;
read_lock(&session->stream_rwlock);
stream = msm_get_stream_from_vb2q(vb->vb2_queue);
if (!stream) {
pr_err("%s:%d] NULL stream", __func__, __LINE__);
pr_err_ratelimited("%s:%d] NULL stream", __func__, __LINE__);
read_unlock(&session->stream_rwlock);
return;
}
spin_lock_irqsave(&stream->stream_lock, flags);
INIT_LIST_HEAD(&stream->queued_list);
spin_unlock_irqrestore(&stream->stream_lock, flags);
read_unlock(&session->stream_rwlock);
}
int msm_vb2_get_stream_state(struct msm_stream *stream)
{
struct msm_vb2_buffer *msm_vb2, *temp;
unsigned long flags;
int rc = 1;
spin_lock_irqsave(&stream->stream_lock, flags);
list_for_each_entry_safe(msm_vb2, temp, &(stream->queued_list), list) {
if (msm_vb2->in_freeq != 0) {
rc = 0;
break;
}
}
spin_unlock_irqrestore(&stream->stream_lock, flags);
return rc;
}
EXPORT_SYMBOL(msm_vb2_get_stream_state);
static struct vb2_ops msm_vb2_get_q_op = {
.queue_setup = msm_vb2_queue_setup,
.buf_init = msm_vb2_buf_init,
@ -188,14 +241,23 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id,
unsigned int stream_id)
{
struct msm_stream *stream;
struct msm_session *session;
struct vb2_buffer *vb2_buf = NULL;
struct msm_vb2_buffer *msm_vb2 = NULL;
unsigned long flags;
stream = msm_get_stream(session_id, stream_id);
if (IS_ERR_OR_NULL(stream))
session = msm_get_session(session_id);
if (IS_ERR_OR_NULL(session))
return NULL;
read_lock(&session->stream_rwlock);
stream = msm_get_stream(session, stream_id);
if (IS_ERR_OR_NULL(stream)) {
read_unlock(&session->stream_rwlock);
return NULL;
}
spin_lock_irqsave(&stream->stream_lock, flags);
if (!stream->vb2_q) {
@ -218,6 +280,7 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id,
vb2_buf = NULL;
end:
spin_unlock_irqrestore(&stream->stream_lock, flags);
read_unlock(&session->stream_rwlock);
return vb2_buf;
}
@ -225,14 +288,24 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id,
unsigned int stream_id)
{
struct msm_stream *stream;
struct msm_session *session;
struct msm_vb2_buffer *msm_vb2;
struct vb2_buffer *vb2_buf = NULL;
int rc = 0;
unsigned long flags;
stream = msm_get_stream(session_id, stream_id);
if (IS_ERR_OR_NULL(stream))
session = msm_get_session(session_id);
if (IS_ERR_OR_NULL(session))
return -EINVAL;
read_lock(&session->stream_rwlock);
stream = msm_get_stream(session, stream_id);
if (IS_ERR_OR_NULL(stream)) {
read_unlock(&session->stream_rwlock);
return -EINVAL;
}
spin_lock_irqsave(&stream->stream_lock, flags);
if (vb) {
list_for_each_entry(msm_vb2, &(stream->queued_list), list) {
@ -244,6 +317,7 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id,
pr_err("VB buffer is INVALID vb=%pK, ses_id=%d, str_id=%d\n",
vb, session_id, stream_id);
spin_unlock_irqrestore(&stream->stream_lock, flags);
read_unlock(&session->stream_rwlock);
return -EINVAL;
}
msm_vb2 =
@ -259,6 +333,7 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id,
rc = -EINVAL;
}
spin_unlock_irqrestore(&stream->stream_lock, flags);
read_unlock(&session->stream_rwlock);
return rc;
}
@ -268,12 +343,22 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id,
unsigned long flags;
struct msm_vb2_buffer *msm_vb2;
struct msm_stream *stream;
struct msm_session *session;
struct vb2_buffer *vb2_buf = NULL;
int rc = 0;
stream = msm_get_stream(session_id, stream_id);
if (IS_ERR_OR_NULL(stream))
session = msm_get_session(session_id);
if (IS_ERR_OR_NULL(session))
return 0;
read_lock(&session->stream_rwlock);
stream = msm_get_stream(session, stream_id);
if (IS_ERR_OR_NULL(stream)) {
read_unlock(&session->stream_rwlock);
return -EINVAL;
}
spin_lock_irqsave(&stream->stream_lock, flags);
if (vb) {
list_for_each_entry(msm_vb2, &(stream->queued_list), list) {
@ -285,6 +370,7 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id,
pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%pK\n",
session_id, stream_id, vb);
spin_unlock_irqrestore(&stream->stream_lock, flags);
read_unlock(&session->stream_rwlock);
return -EINVAL;
}
msm_vb2 =
@ -302,6 +388,7 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id,
rc = -EINVAL;
}
spin_unlock_irqrestore(&stream->stream_lock, flags);
read_unlock(&session->stream_rwlock);
return rc;
}
@ -309,12 +396,22 @@ static int msm_vb2_flush_buf(int session_id, unsigned int stream_id)
{
unsigned long flags;
struct msm_vb2_buffer *msm_vb2;
struct msm_session *session;
struct msm_stream *stream;
struct vb2_buffer *vb2_buf = NULL;
stream = msm_get_stream(session_id, stream_id);
if (IS_ERR_OR_NULL(stream))
session = msm_get_session(session_id);
if (IS_ERR_OR_NULL(session))
return -EINVAL;
read_lock(&session->stream_rwlock);
stream = msm_get_stream(session, stream_id);
if (IS_ERR_OR_NULL(stream)) {
read_unlock(&session->stream_rwlock);
return -EINVAL;
}
spin_lock_irqsave(&stream->stream_lock, flags);
list_for_each_entry(msm_vb2, &(stream->queued_list), list) {
vb2_buf = &(msm_vb2->vb2_buf);
@ -323,6 +420,7 @@ static int msm_vb2_flush_buf(int session_id, unsigned int stream_id)
msm_vb2->in_freeq = 0;
}
spin_unlock_irqrestore(&stream->stream_lock, flags);
read_unlock(&session->stream_rwlock);
return 0;
}
@ -342,4 +440,3 @@ int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req)
return 0;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2013, 2017 The Linux Foundation. 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 and
@ -66,5 +66,6 @@ struct msm_stream {
struct vb2_ops *msm_vb2_get_q_ops(void);
struct vb2_mem_ops *msm_vb2_get_q_mem_ops(void);
int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req_sd);
int msm_vb2_get_stream_state(struct msm_stream *stream);
#endif /*_MSM_VB_H */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2014,2016-2017 The Linux Foundation. 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 and
@ -17,7 +17,8 @@
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#define S_I2C_DBG(fmt, args...) pr_debug(fmt, ##args)
#define MAX_I2C_ADDR_TYPE_SIZE (MSM_CAMERA_I2C_3B_ADDR + 1)
#define MAX_I2C_DATA_TYPE_SIZE (MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA + 1)
#define I2C_COMPARE_MATCH 0
#define I2C_COMPARE_MISMATCH 1
#define I2C_POLL_MAX_ITERATION 20
@ -27,7 +28,7 @@ int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
enum msm_camera_i2c_data_type data_type)
{
int32_t rc = -EFAULT;
unsigned char buf[client->addr_type+data_type];
unsigned char buf[MAX_I2C_ADDR_TYPE_SIZE + MAX_I2C_DATA_TYPE_SIZE];
struct msm_camera_cci_ctrl cci_ctrl;
if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2015,2017 The Linux Foundation. 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 and
@ -108,7 +108,11 @@ static int32_t msm_sensor_driver_create_i2c_v4l_subdev
s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
s_ctrl->sensordata->sensor_info->session_id = session_id;
s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
msm_sd_register(&s_ctrl->msm_sd);
rc = msm_sd_register(&s_ctrl->msm_sd);
if (rc < 0) {
pr_err("failed: msm_sd_register rc %d", rc);
return rc;
}
CDBG("%s:%d\n", __func__, __LINE__);
return rc;
}
@ -138,7 +142,11 @@ static int32_t msm_sensor_driver_create_v4l_subdev
s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
msm_sd_register(&s_ctrl->msm_sd);
rc = msm_sd_register(&s_ctrl->msm_sd);
if (rc < 0) {
pr_err("failed: msm_sd_register rc %d", rc);
return rc;
}
msm_sensor_v4l2_subdev_fops = v4l2_subdev_fops;
#ifdef CONFIG_COMPAT
msm_sensor_v4l2_subdev_fops.compat_ioctl32 =
@ -926,12 +934,6 @@ CSID_TG:
pr_err("%s probe succeeded", slave_info->sensor_name);
/*
Set probe succeeded flag to 1 so that no other camera shall
* probed on this slot
*/
s_ctrl->is_probe_succeed = 1;
/*
* Update the subdevice id of flash-src based on availability in kernel.
*/
@ -984,6 +986,11 @@ CSID_TG:
msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name);
/*
* Set probe succeeded flag to 1 so that no other camera shall
* probed on this slot
*/
s_ctrl->is_probe_succeed = 1;
return rc;
camera_power_down:

View File

@ -427,11 +427,13 @@ static long msm_ois_subdev_ioctl(struct v4l2_subdev *sd,
pr_err("o_ctrl->i2c_client.i2c_func_tbl NULL\n");
return -EINVAL;
} else {
mutex_lock(o_ctrl->ois_mutex);
rc = msm_ois_power_down(o_ctrl);
if (rc < 0) {
pr_err("%s:%d OIS Power down failed\n",
__func__, __LINE__);
}
mutex_unlock(o_ctrl->ois_mutex);
return msm_ois_close(sd, NULL);
}
default:
@ -596,6 +598,10 @@ static long msm_ois_subdev_do_ioctl(
parg = &ois_data;
break;
}
break;
case VIDIOC_MSM_OIS_CFG:
pr_err("%s: invalid cmd 0x%x received\n", __func__, cmd);
return -EINVAL;
}
rc = msm_ois_subdev_ioctl(sd, cmd, parg);

View File

@ -1057,6 +1057,8 @@ static int audio_aio_async_write(struct q6audio_aio *audio,
struct audio_client *ac;
struct audio_aio_write_param param;
memset(&param, 0, sizeof(param));
if (!audio || !buf_node) {
pr_err("%s NULL pointer audio=[0x%pK], buf_node=[0x%pK]\n",
__func__, audio, buf_node);

View File

@ -6206,11 +6206,16 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
void *cmd_buf = NULL;
size_t cmd_len;
struct sglist_info *table = data->sglistinfo_ptr;
void *req_ptr = NULL;
void *resp_ptr = NULL;
ret = __qseecom_qteec_validate_msg(data, req);
if (ret)
return ret;
req_ptr = req->req_ptr;
resp_ptr = req->resp_ptr;
/* find app_id & img_name from list */
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
@ -6230,6 +6235,11 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
return -ENOENT;
}
req->req_ptr = (void *)__qseecom_uvirt_to_kvirt(data,
(uintptr_t)req->req_ptr);
req->resp_ptr = (void *)__qseecom_uvirt_to_kvirt(data,
(uintptr_t)req->resp_ptr);
if ((cmd_id == QSEOS_TEE_OPEN_SESSION) ||
(cmd_id == QSEOS_TEE_REQUEST_CANCELLATION)) {
ret = __qseecom_update_qteec_req_buf(
@ -6241,10 +6251,10 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
if (qseecom.qsee_version < QSEE_VERSION_40) {
ireq.app_id = data->client.app_id;
ireq.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
(uintptr_t)req->req_ptr);
(uintptr_t)req_ptr);
ireq.req_len = req->req_len;
ireq.resp_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
(uintptr_t)req->resp_ptr);
(uintptr_t)resp_ptr);
ireq.resp_len = req->resp_len;
ireq.sglistinfo_ptr = (uint32_t)virt_to_phys(table);
ireq.sglistinfo_len = SGLISTINFO_TABLE_SIZE;
@ -6255,10 +6265,10 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
} else {
ireq_64bit.app_id = data->client.app_id;
ireq_64bit.req_ptr = (uint64_t)__qseecom_uvirt_to_kphys(data,
(uintptr_t)req->req_ptr);
(uintptr_t)req_ptr);
ireq_64bit.req_len = req->req_len;
ireq_64bit.resp_ptr = (uint64_t)__qseecom_uvirt_to_kphys(data,
(uintptr_t)req->resp_ptr);
(uintptr_t)resp_ptr);
ireq_64bit.resp_len = req->resp_len;
if ((data->client.app_arch == ELFCLASS32) &&
((ireq_64bit.req_ptr >=

View File

@ -149,7 +149,6 @@ static DEFINE_SPINLOCK(pci_link_down_lock);
#define FW_IMAGE_MISSION (0x02)
#define FW_IMAGE_BDATA (0x03)
#define FW_IMAGE_PRINT (0x04)
#define FW_SETUP_DELAY 2000
#define SEG_METADATA (0x01)
#define SEG_NON_PAGED (0x02)
@ -270,10 +269,8 @@ static struct cnss_data {
u32 fw_dma_size;
u32 fw_seg_count;
struct segment_memory fw_seg_mem[MAX_NUM_OF_SEGMENTS];
atomic_t fw_store_in_progress;
/* Firmware setup complete lock */
struct mutex fw_setup_stat_lock;
struct completion fw_setup_complete;
void *bdata_cpu;
dma_addr_t bdata_dma;
u32 bdata_dma_size;
@ -1187,15 +1184,6 @@ int cnss_get_fw_image(struct image_desc_info *image_desc_info)
!penv->fw_seg_count || !penv->bdata_seg_count)
return -EINVAL;
/* Check for firmware setup trigger by usersapce is in progress
* and wait for complition of firmware setup.
*/
if (atomic_read(&penv->fw_store_in_progress)) {
wait_for_completion_timeout(&penv->fw_setup_complete,
msecs_to_jiffies(FW_SETUP_DELAY));
}
mutex_lock(&penv->fw_setup_stat_lock);
image_desc_info->fw_addr = penv->fw_dma;
image_desc_info->fw_size = penv->fw_dma_size;
@ -1293,7 +1281,9 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev,
goto err_pcie_suspend;
}
mutex_lock(&penv->fw_setup_stat_lock);
cnss_wlan_fw_mem_alloc(pdev);
mutex_unlock(&penv->fw_setup_stat_lock);
ret = device_create_file(&penv->pldev->dev, &dev_attr_wlan_setup);
@ -1546,17 +1536,11 @@ static ssize_t fw_image_setup_store(struct device *dev,
if (!penv)
return -ENODEV;
if (atomic_read(&penv->fw_store_in_progress)) {
pr_info("%s: Firmware setup in progress\n", __func__);
return 0;
}
atomic_set(&penv->fw_store_in_progress, 1);
init_completion(&penv->fw_setup_complete);
mutex_lock(&penv->fw_setup_stat_lock);
pr_info("%s: Firmware setup in progress\n", __func__);
if (kstrtoint(buf, 0, &val)) {
atomic_set(&penv->fw_store_in_progress, 0);
complete(&penv->fw_setup_complete);
mutex_unlock(&penv->fw_setup_stat_lock);
return -EINVAL;
}
@ -1567,8 +1551,7 @@ static ssize_t fw_image_setup_store(struct device *dev,
if (ret != 0) {
pr_err("%s: Invalid parsing of FW image files %d",
__func__, ret);
atomic_set(&penv->fw_store_in_progress, 0);
complete(&penv->fw_setup_complete);
mutex_unlock(&penv->fw_setup_stat_lock);
return -EINVAL;
}
penv->fw_image_setup = val;
@ -1578,9 +1561,8 @@ static ssize_t fw_image_setup_store(struct device *dev,
penv->bmi_test = val;
}
atomic_set(&penv->fw_store_in_progress, 0);
complete(&penv->fw_setup_complete);
pr_info("%s: Firmware setup completed\n", __func__);
mutex_unlock(&penv->fw_setup_stat_lock);
return count;
}
@ -1665,17 +1647,21 @@ int cnss_get_codeswap_struct(struct codeswap_codeseg_info *swap_seg)
{
struct codeswap_codeseg_info *cnss_seg_info = penv->cnss_seg_info;
mutex_lock(&penv->fw_setup_stat_lock);
if (!cnss_seg_info) {
swap_seg = NULL;
mutex_unlock(&penv->fw_setup_stat_lock);
return -ENOENT;
}
if (!atomic_read(&penv->fw_available)) {
pr_debug("%s: fw is not available\n", __func__);
mutex_unlock(&penv->fw_setup_stat_lock);
return -ENOENT;
}
*swap_seg = *cnss_seg_info;
mutex_unlock(&penv->fw_setup_stat_lock);
return 0;
}
@ -1694,15 +1680,6 @@ static void cnss_wlan_memory_expansion(void)
u_int32_t total_length = 0;
struct pci_dev *pdev;
/* Check for firmware setup trigger by usersapce is in progress
* and wait for complition of firmware setup.
*/
if (atomic_read(&penv->fw_store_in_progress)) {
wait_for_completion_timeout(&penv->fw_setup_complete,
msecs_to_jiffies(FW_SETUP_DELAY));
}
mutex_lock(&penv->fw_setup_stat_lock);
pdev = penv->pdev;
dev = &pdev->dev;
@ -2447,6 +2424,7 @@ static int cnss_probe(struct platform_device *pdev)
penv->vreg_info.wlan_reg = NULL;
penv->vreg_info.state = VREG_OFF;
penv->pci_register_again = false;
mutex_init(&penv->fw_setup_stat_lock);
ret = cnss_wlan_get_resources(pdev);
if (ret)
@ -2602,8 +2580,6 @@ skip_ramdump:
memset(phys_to_virt(0), 0, SZ_4K);
#endif
atomic_set(&penv->fw_store_in_progress, 0);
mutex_init(&penv->fw_setup_stat_lock);
ret = device_create_file(dev, &dev_attr_fw_image_setup);
if (ret) {
pr_err("cnss: fw_image_setup sys file creation failed\n");

View File

@ -1023,7 +1023,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
goto error;
}
if (rt_tbl->cookie != IPA_COOKIE) {
if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
@ -1044,7 +1044,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
}
INIT_LIST_HEAD(&entry->link);
entry->rule = *rule;
entry->cookie = IPA_COOKIE;
entry->cookie = IPA_FLT_COOKIE;
entry->rt_tbl = rt_tbl;
entry->tbl = tbl;
if (add_rear) {
@ -1063,13 +1063,19 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
goto ipa_insert_failed;
}
*rule_hdl = id;
entry->id = id;
IPADBG("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
return 0;
ipa_insert_failed:
tbl->rule_cnt--;
if (entry->rt_tbl)
entry->rt_tbl->ref_cnt--;
list_del(&entry->link);
kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
error:
return -EPERM;
}
@ -1085,7 +1091,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl)
return -EINVAL;
}
if (entry->cookie != IPA_COOKIE) {
if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@ -1117,7 +1123,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
goto error;
}
if (entry->cookie != IPA_COOKIE) {
if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
goto error;
}
@ -1138,7 +1144,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
goto error;
}
if (rt_tbl->cookie != IPA_COOKIE) {
if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}

View File

@ -480,7 +480,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
{
struct ipa_hdr_entry *hdr_entry;
struct ipa_hdr_proc_ctx_entry *entry;
struct ipa_hdr_proc_ctx_offset_entry *offset;
struct ipa_hdr_proc_ctx_offset_entry *offset = NULL;
u32 bin;
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
int id;
@ -495,7 +495,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
}
hdr_entry = ipa_id_find(proc_ctx->hdr_hdl);
if (!hdr_entry || (hdr_entry->cookie != IPA_COOKIE)) {
if (!hdr_entry || (hdr_entry->cookie != IPA_HDR_COOKIE)) {
IPAERR("hdr_hdl is invalid\n");
return -EINVAL;
}
@ -512,7 +512,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
entry->hdr = hdr_entry;
if (add_ref_hdr)
hdr_entry->ref_cnt++;
entry->cookie = IPA_COOKIE;
entry->cookie = IPA_PROC_HDR_COOKIE;
needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
sizeof(struct ipa_hdr_proc_ctx_add_hdr_seq) :
@ -564,6 +564,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
goto ipa_insert_failed;
}
entry->id = id;
proc_ctx->proc_ctx_hdl = id;
@ -571,6 +572,13 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
return 0;
ipa_insert_failed:
if (offset)
list_move(&offset->link,
&htbl->head_free_offset_list[offset->bin]);
entry->offset_entry = NULL;
list_del(&entry->link);
htbl->proc_ctx_cnt--;
bad_len:
hdr_entry->ref_cnt--;
entry->cookie = 0;
@ -582,7 +590,7 @@ bad_len:
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
{
struct ipa_hdr_entry *entry;
struct ipa_hdr_offset_entry *offset;
struct ipa_hdr_offset_entry *offset = NULL;
u32 bin;
struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
int id;
@ -613,7 +621,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
entry->type = hdr->type;
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
entry->eth2_ofst = hdr->eth2_ofst;
entry->cookie = IPA_COOKIE;
entry->cookie = IPA_HDR_COOKIE;
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
bin = IPA_HDR_BIN0;
@ -696,6 +704,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
goto ipa_insert_failed;
}
entry->id = id;
hdr->hdr_hdl = id;
@ -720,10 +729,19 @@ fail_add_proc_ctx:
entry->ref_cnt--;
hdr->hdr_hdl = 0;
ipa_id_remove(id);
ipa_insert_failed:
if (entry->is_hdr_proc_ctx) {
dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
entry->hdr_len, DMA_TO_DEVICE);
} else {
if (offset)
list_move(&offset->link,
&htbl->head_free_offset_list[offset->bin]);
entry->offset_entry = NULL;
}
htbl->hdr_cnt--;
list_del(&entry->link);
dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
entry->hdr_len, DMA_TO_DEVICE);
bad_hdr_len:
entry->cookie = 0;
kmem_cache_free(ipa_ctx->hdr_cache, entry);
@ -738,7 +756,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl,
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
entry = ipa_id_find(proc_ctx_hdl);
if (!entry || (entry->cookie != IPA_COOKIE)) {
if (!entry || (entry->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@ -789,7 +807,7 @@ int __ipa_del_hdr(u32 hdr_hdl, bool by_user)
return -EINVAL;
}
if (!entry || (entry->cookie != IPA_COOKIE)) {
if (!entry || (entry->cookie != IPA_HDR_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@ -1354,7 +1372,7 @@ int ipa_put_hdr(u32 hdr_hdl)
goto bail;
}
if (entry == NULL || entry->cookie != IPA_COOKIE) {
if (entry == NULL || entry->cookie != IPA_HDR_COOKIE) {
IPAERR("bad params\n");
result = -EINVAL;
goto bail;

View File

@ -33,6 +33,12 @@
#define DRV_NAME "ipa"
#define NAT_DEV_NAME "ipaNatTable"
#define IPA_COOKIE 0x57831603
#define IPA_RT_RULE_COOKIE 0x57831604
#define IPA_RT_TBL_COOKIE 0x57831605
#define IPA_FLT_COOKIE 0x57831606
#define IPA_HDR_COOKIE 0x57831607
#define IPA_PROC_HDR_COOKIE 0x57831608
#define MTU_BYTE 1500
#define IPA_MAX_NUM_PIPES 0x14
@ -183,8 +189,8 @@ struct ipa_mem_buffer {
*/
struct ipa_flt_entry {
struct list_head link;
struct ipa_flt_rule rule;
u32 cookie;
struct ipa_flt_rule rule;
struct ipa_flt_tbl *tbl;
struct ipa_rt_tbl *rt_tbl;
u32 hw_len;
@ -209,13 +215,13 @@ struct ipa_flt_entry {
*/
struct ipa_rt_tbl {
struct list_head link;
u32 cookie;
struct list_head head_rt_rule_list;
char name[IPA_RESOURCE_NAME_MAX];
u32 idx;
u32 rule_cnt;
u32 ref_cnt;
struct ipa_rt_tbl_set *set;
u32 cookie;
bool in_sys;
u32 sz;
struct ipa_mem_buffer curr_mem;
@ -246,6 +252,7 @@ struct ipa_rt_tbl {
*/
struct ipa_hdr_entry {
struct list_head link;
u32 cookie;
u8 hdr[IPA_HDR_MAX_SIZE];
u32 hdr_len;
char name[IPA_RESOURCE_NAME_MAX];
@ -255,7 +262,6 @@ struct ipa_hdr_entry {
dma_addr_t phys_base;
struct ipa_hdr_proc_ctx_entry *proc_ctx;
struct ipa_hdr_offset_entry *offset_entry;
u32 cookie;
u32 ref_cnt;
int id;
u8 is_eth2_ofst_valid;
@ -340,10 +346,10 @@ struct ipa_hdr_proc_ctx_add_hdr_cmd_seq {
*/
struct ipa_hdr_proc_ctx_entry {
struct list_head link;
u32 cookie;
enum ipa_hdr_proc_type type;
struct ipa_hdr_proc_ctx_offset_entry *offset_entry;
struct ipa_hdr_entry *hdr;
u32 cookie;
u32 ref_cnt;
int id;
bool user_deleted;
@ -399,8 +405,8 @@ struct ipa_flt_tbl {
*/
struct ipa_rt_entry {
struct list_head link;
struct ipa_rt_rule rule;
u32 cookie;
struct ipa_rt_rule rule;
struct ipa_rt_tbl *tbl;
struct ipa_hdr_entry *hdr;
struct ipa_hdr_proc_ctx_entry *proc_ctx;

View File

@ -880,7 +880,7 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
INIT_LIST_HEAD(&entry->link);
strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
entry->set = set;
entry->cookie = IPA_COOKIE;
entry->cookie = IPA_RT_TBL_COOKIE;
entry->in_sys = (ip == IPA_IP_v4) ?
!ipa_ctx->ip4_rt_tbl_lcl : !ipa_ctx->ip6_rt_tbl_lcl;
set->tbl_cnt++;
@ -893,12 +893,16 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
goto ipa_insert_failed;
}
entry->id = id;
}
return entry;
ipa_insert_failed:
set->tbl_cnt--;
list_del(&entry->link);
fail_rt_idx_alloc:
entry->cookie = 0;
kmem_cache_free(ipa_ctx->rt_tbl_cache, entry);
@ -911,7 +915,7 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
enum ipa_ip_type ip = IPA_IP_MAX;
u32 id;
if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad parms\n");
return -EINVAL;
}
@ -925,8 +929,10 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
ip = IPA_IP_v4;
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
else
else {
WARN_ON(1);
return -EPERM;
}
if (!entry->in_sys) {
list_del(&entry->link);
@ -965,13 +971,14 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
if (rule->hdr_hdl) {
hdr = ipa_id_find(rule->hdr_hdl);
if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
} else if (rule->hdr_proc_ctx_hdl) {
proc_ctx = ipa_id_find(rule->hdr_proc_ctx_hdl);
if ((proc_ctx == NULL) || (proc_ctx->cookie != IPA_COOKIE)) {
if ((proc_ctx == NULL) ||
(proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid proc ctx\n");
goto error;
}
@ -979,7 +986,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
tbl = __ipa_add_rt_tbl(ip, name);
if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad params\n");
goto error;
}
@ -1000,7 +1007,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
goto error;
}
INIT_LIST_HEAD(&entry->link);
entry->cookie = IPA_COOKIE;
entry->cookie = IPA_RT_RULE_COOKIE;
entry->rule = *rule;
entry->tbl = tbl;
entry->hdr = hdr;
@ -1090,7 +1097,7 @@ int __ipa_del_rt_rule(u32 rule_hdl)
return -EINVAL;
}
if (entry->cookie != IPA_COOKIE) {
if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@ -1328,7 +1335,7 @@ int ipa_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup)
}
mutex_lock(&ipa_ctx->lock);
entry = __ipa_find_rt_tbl(lookup->ip, lookup->name);
if (entry && entry->cookie == IPA_COOKIE) {
if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
if (entry->ref_cnt == ((u32)~0U)) {
IPAERR("fail: ref count crossed limit\n");
goto ret;
@ -1372,7 +1379,7 @@ int ipa_put_rt_tbl(u32 rt_tbl_hdl)
goto ret;
}
if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
IPAERR("bad parms\n");
result = -EINVAL;
goto ret;
@ -1382,8 +1389,11 @@ int ipa_put_rt_tbl(u32 rt_tbl_hdl)
ip = IPA_IP_v4;
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
else
else {
WARN_ON(1);
result = -EINVAL;
goto ret;
}
entry->ref_cnt--;
if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
@ -1411,7 +1421,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
if (rtrule->rule.hdr_hdl) {
hdr = ipa_id_find(rtrule->rule.hdr_hdl);
if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
@ -1423,7 +1433,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
goto error;
}
if (entry->cookie != IPA_COOKIE) {
if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
goto error;
}

View File

@ -70,6 +70,7 @@ static void *subsys_notify_handle;
u32 apps_to_ipa_hdl, ipa_to_apps_hdl; /* get handler from ipa */
static struct mutex ipa_to_apps_pipe_handle_guard;
static struct mutex add_mux_channel_lock;
static int wwan_add_ul_flt_rule_to_ipa(void);
static int wwan_del_ul_flt_rule_to_ipa(void);
static void ipa_wwan_msg_free_cb(void*, u32, u32);
@ -1374,9 +1375,11 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
rmnet_mux_val.mux_id);
return rc;
}
mutex_lock(&add_mux_channel_lock);
if (rmnet_index >= MAX_NUM_OF_MUX_CHANNEL) {
IPAWANERR("Exceed mux_channel limit(%d)\n",
rmnet_index);
mutex_unlock(&add_mux_channel_lock);
return -EFAULT;
}
IPAWANDBG("ADD_MUX_CHANNEL(%d, name: %s)\n",
@ -1404,6 +1407,7 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
IPAWANERR("device %s reg IPA failed\n",
extend_ioctl_data.u.
rmnet_mux_val.vchannel_name);
mutex_unlock(&add_mux_channel_lock);
return -ENODEV;
}
mux_channel[rmnet_index].mux_channel_set = true;
@ -1416,6 +1420,7 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
mux_channel[rmnet_index].ul_flt_reg = false;
}
rmnet_index++;
mutex_unlock(&add_mux_channel_lock);
break;
case RMNET_IOCTL_SET_EGRESS_DATA_FORMAT:
IPAWANDBG("get RMNET_IOCTL_SET_EGRESS_DATA_FORMAT\n");
@ -2739,6 +2744,7 @@ static int __init ipa_wwan_init(void)
mutex_init(&ipa_to_apps_pipe_handle_guard);
ipa_to_apps_hdl = -1;
mutex_init(&add_mux_channel_lock);
ipa_qmi_init();
@ -2749,19 +2755,21 @@ static int __init ipa_wwan_init(void)
return platform_driver_register(&rmnet_ipa_driver);
else
return (int)PTR_ERR(subsys_notify_handle);
}
}
static void __exit ipa_wwan_cleanup(void)
{
int ret;
ipa_qmi_cleanup();
mutex_destroy(&ipa_to_apps_pipe_handle_guard);
mutex_destroy(&add_mux_channel_lock);
ret = subsys_notif_unregister_notifier(subsys_notify_handle,
&ssr_notifier);
if (ret)
IPAWANERR(
"Error subsys_notif_unregister_notifier system %s, ret=%d\n",
SUBSYS_MODEM, ret);
platform_driver_unregister(&rmnet_ipa_driver);
}

View File

@ -816,13 +816,13 @@ out:
up_read(&pil_pm_rwsem);
if (ret) {
if (priv->region) {
if (desc->clear_fw_region && priv->region_start)
pil_clear_segment(desc);
dma_free_attrs(desc->dev, priv->region_size,
priv->region, priv->region_start,
&desc->attrs);
priv->region = NULL;
}
if (desc->clear_fw_region && priv->region_start)
pil_clear_segment(desc);
pil_release_mmap(desc);
}
return ret;

View File

@ -1,6 +1,6 @@
/* drivers/soc/qcom/smp2p_spinlock_test.c
*
* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2015, 2017 The Linux Foundation. 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 and
@ -516,7 +516,7 @@ static void smp2p_ut_remote_spinlock_ssr(struct seq_file *s)
int spinlock_owner = 0;
struct workqueue_struct *ws = NULL;
struct rmt_spinlock_work_item work_item;
struct rmt_spinlock_work_item work_item = { .has_locked = false };
seq_printf(s, " Running %s Test\n",
__func__);

View File

@ -14,9 +14,9 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
@ -26,6 +26,7 @@
#include <linux/cpu.h>
#include <linux/cpu_pm.h>
#include <linux/platform_device.h>
#include <linux/sched/rt.h>
#include <soc/qcom/scm.h>
#include <soc/qcom/memory_dump.h>
#include <soc/qcom/watchdog.h>
@ -53,7 +54,6 @@
#define SCM_SVC_SEC_WDOG_DIS 0x7
#define MAX_CPU_CTX_SIZE 2048
static struct workqueue_struct *wdog_wq;
static struct msm_watchdog_data *wdog_data;
static int cpu_idle_pc_state[NR_CPUS];
@ -76,12 +76,13 @@ struct msm_watchdog_data {
void *scm_regsave;
cpumask_t alive_mask;
struct mutex disable_lock;
struct work_struct init_dogwork_struct;
struct delayed_work dogwork_struct;
bool irq_ppi;
struct msm_watchdog_data __percpu **wdog_cpu_dd;
struct notifier_block panic_blk;
bool enabled;
struct task_struct *watchdog_task;
struct timer_list pet_timer;
struct completion pet_complete;
};
/*
@ -120,9 +121,6 @@ module_param(WDT_HZ, long, 0);
static int ipi_opt_en;
module_param(ipi_opt_en, int, 0);
static void pet_watchdog_work(struct work_struct *work);
static void init_watchdog_work(struct work_struct *work);
static void dump_cpu_alive_mask(struct msm_watchdog_data *wdog_dd)
{
static char alive_mask_buf[MASK_SIZE];
@ -204,7 +202,7 @@ static void wdog_disable(struct msm_watchdog_data *wdog_dd)
smp_mb();
atomic_notifier_chain_unregister(&panic_notifier_list,
&wdog_dd->panic_blk);
cancel_delayed_work_sync(&wdog_dd->dogwork_struct);
del_timer_sync(&wdog_dd->pet_timer);
/* may be suspended after the first write above */
__raw_writel(0, wdog_dd->base + WDT0_EN);
mb();
@ -212,20 +210,6 @@ static void wdog_disable(struct msm_watchdog_data *wdog_dd)
pr_info("MSM Apps Watchdog deactivated.\n");
}
struct wdog_disable_work_data {
struct work_struct work;
struct completion complete;
struct msm_watchdog_data *wdog_dd;
};
static void wdog_disable_work(struct work_struct *work)
{
struct wdog_disable_work_data *work_data =
container_of(work, struct wdog_disable_work_data, work);
wdog_disable(work_data->wdog_dd);
complete(&work_data->complete);
}
static ssize_t wdog_disable_get(struct device *dev,
struct device_attribute *attr, char *buf)
{
@ -244,7 +228,6 @@ static ssize_t wdog_disable_set(struct device *dev,
{
int ret;
u8 disable;
struct wdog_disable_work_data work_data;
struct msm_watchdog_data *wdog_dd = dev_get_drvdata(dev);
ret = kstrtou8(buf, 10, &disable);
@ -276,11 +259,7 @@ static ssize_t wdog_disable_set(struct device *dev,
mutex_unlock(&wdog_dd->disable_lock);
return -EIO;
}
work_data.wdog_dd = wdog_dd;
init_completion(&work_data.complete);
INIT_WORK_ONSTACK(&work_data.work, wdog_disable_work);
queue_work(wdog_wq, &work_data.work);
wait_for_completion(&work_data.complete);
wdog_disable(wdog_dd);
mutex_unlock(&wdog_dd->disable_lock);
} else {
pr_err("invalid operation, only disable = 1 supported\n");
@ -360,24 +339,37 @@ static void ping_other_cpus(struct msm_watchdog_data *wdog_dd)
}
}
static void pet_watchdog_work(struct work_struct *work)
static void pet_task_wakeup(unsigned long data)
{
unsigned long delay_time;
struct delayed_work *delayed_work = to_delayed_work(work);
struct msm_watchdog_data *wdog_dd = container_of(delayed_work,
struct msm_watchdog_data,
dogwork_struct);
delay_time = msecs_to_jiffies(wdog_dd->pet_time);
if (enable) {
if (wdog_dd->do_ipi_ping)
ping_other_cpus(wdog_dd);
pet_watchdog(wdog_dd);
struct msm_watchdog_data *wdog_dd =
(struct msm_watchdog_data *)data;
complete(&wdog_dd->pet_complete);
}
static __ref int watchdog_kthread(void *arg)
{
struct msm_watchdog_data *wdog_dd =
(struct msm_watchdog_data *)arg;
unsigned long delay_time = 0;
struct sched_param param = {.sched_priority = MAX_RT_PRIO-1};
sched_setscheduler(current, SCHED_FIFO, &param);
while (!kthread_should_stop()) {
while (wait_for_completion_interruptible(
&wdog_dd->pet_complete) != 0)
;
INIT_COMPLETION(wdog_dd->pet_complete);
if (enable) {
delay_time = msecs_to_jiffies(wdog_dd->pet_time);
if (wdog_dd->do_ipi_ping)
ping_other_cpus(wdog_dd);
pet_watchdog(wdog_dd);
}
/* Check again before scheduling *
* Could have been changed on other cpu */
mod_timer(&wdog_dd->pet_timer, jiffies + delay_time);
}
/* Check again before scheduling *
* Could have been changed on other cpu */
if (enable)
queue_delayed_work(wdog_wq,
&wdog_dd->dogwork_struct, delay_time);
return 0;
}
static int wdog_cpu_pm_notify(struct notifier_block *self,
@ -406,7 +398,6 @@ static struct notifier_block wdog_cpu_pm_nb = {
static int msm_watchdog_remove(struct platform_device *pdev)
{
struct wdog_disable_work_data work_data;
struct msm_watchdog_data *wdog_dd =
(struct msm_watchdog_data *)platform_get_drvdata(pdev);
@ -415,18 +406,15 @@ static int msm_watchdog_remove(struct platform_device *pdev)
mutex_lock(&wdog_dd->disable_lock);
if (enable) {
work_data.wdog_dd = wdog_dd;
init_completion(&work_data.complete);
INIT_WORK_ONSTACK(&work_data.work, wdog_disable_work);
queue_work(wdog_wq, &work_data.work);
wait_for_completion(&work_data.complete);
wdog_disable(wdog_dd);
}
mutex_unlock(&wdog_dd->disable_lock);
device_remove_file(wdog_dd->dev, &dev_attr_disable);
if (wdog_dd->irq_ppi)
free_percpu(wdog_dd->wdog_cpu_dd);
printk(KERN_INFO "MSM Watchdog Exit - Deactivated\n");
destroy_workqueue(wdog_wq);
del_timer_sync(&wdog_dd->pet_timer);
kthread_stop(wdog_dd->watchdog_task);
kfree(wdog_dd);
return 0;
}
@ -596,11 +584,8 @@ out0:
}
static void init_watchdog_work(struct work_struct *work)
static void init_watchdog_data(struct msm_watchdog_data *wdog_dd)
{
struct msm_watchdog_data *wdog_dd = container_of(work,
struct msm_watchdog_data,
init_dogwork_struct);
unsigned long delay_time;
uint32_t val;
int error;
@ -650,8 +635,14 @@ static void init_watchdog_work(struct work_struct *work)
atomic_notifier_chain_register(&panic_notifier_list,
&wdog_dd->panic_blk);
mutex_init(&wdog_dd->disable_lock);
queue_delayed_work(wdog_wq, &wdog_dd->dogwork_struct,
delay_time);
init_completion(&wdog_dd->pet_complete);
wake_up_process(wdog_dd->watchdog_task);
init_timer(&wdog_dd->pet_timer);
wdog_dd->pet_timer.data = (unsigned long)wdog_dd;
wdog_dd->pet_timer.function = pet_task_wakeup;
wdog_dd->pet_timer.expires = jiffies + delay_time;
add_timer(&wdog_dd->pet_timer);
val = BIT(EN);
if (wdog_dd->wakeup_irq_enable)
val |= BIT(UNMASKED_INT_EN);
@ -779,12 +770,6 @@ static int msm_watchdog_probe(struct platform_device *pdev)
int ret;
struct msm_watchdog_data *wdog_dd;
wdog_wq = alloc_workqueue("wdog", WQ_HIGHPRI, 0);
if (!wdog_wq) {
pr_err("Failed to allocate watchdog workqueue\n");
return -EIO;
}
if (!pdev->dev.of_node || !enable)
return -ENODEV;
wdog_dd = kzalloc(sizeof(struct msm_watchdog_data), GFP_KERNEL);
@ -803,12 +788,15 @@ static int msm_watchdog_probe(struct platform_device *pdev)
wdog_dd->dev = &pdev->dev;
platform_set_drvdata(pdev, wdog_dd);
cpumask_clear(&wdog_dd->alive_mask);
INIT_WORK(&wdog_dd->init_dogwork_struct, init_watchdog_work);
INIT_DELAYED_WORK(&wdog_dd->dogwork_struct, pet_watchdog_work);
queue_work(wdog_wq, &wdog_dd->init_dogwork_struct);
wdog_dd->watchdog_task = kthread_create(watchdog_kthread, wdog_dd,
"msm_watchdog");
if (IS_ERR(wdog_dd->watchdog_task)) {
ret = PTR_ERR(wdog_dd->watchdog_task);
goto err;
}
init_watchdog_data(wdog_dd);
return 0;
err:
destroy_workqueue(wdog_wq);
kzfree(wdog_dd);
return ret;
}

View File

@ -1,6 +1,6 @@
/*
* drivers/gpu/ion/ion.c
* drivers/staging/android/ion/ion.c
*
* Copyright (C) 2011 Google, Inc.
* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
@ -2052,10 +2052,11 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
up_write(&dev->lock);
}
int ion_walk_heaps(struct ion_client *client, int heap_id, void *data,
int ion_walk_heaps(struct ion_client *client, int heap_id,
enum ion_heap_type type, void *data,
int (*f)(struct ion_heap *heap, void *data))
{
int ret_val = -EINVAL;
int ret_val = 0;
struct ion_heap *heap;
struct ion_device *dev = client->dev;
/*
@ -2064,7 +2065,8 @@ int ion_walk_heaps(struct ion_client *client, int heap_id, void *data,
*/
down_write(&dev->lock);
plist_for_each_entry(heap, &dev->heaps, node) {
if (ION_HEAP(heap->id) != heap_id)
if (ION_HEAP(heap->id) != heap_id ||
type != heap->type)
continue;
ret_val = f(heap, data);
break;

View File

@ -1,8 +1,8 @@
/*
* drivers/gpu/ion/ion_priv.h
* drivers/staging/android/ion/ion_priv.h
*
* Copyright (C) 2011 Google, Inc.
* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@ -442,7 +442,8 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
void ion_pages_sync_for_device(struct device *dev, struct page *page,
size_t size, enum dma_data_direction dir);
int ion_walk_heaps(struct ion_client *client, int heap_id, void *data,
int ion_walk_heaps(struct ion_client *client, int heap_id,
enum ion_heap_type type, void *data,
int (*f)(struct ion_heap *heap, void *data));
struct ion_handle *ion_handle_get_by_id(struct ion_client *client,

View File

@ -761,16 +761,28 @@ long msm_ion_custom_ioctl(struct ion_client *client,
}
case ION_IOC_PREFETCH:
{
ion_walk_heaps(client, data.prefetch_data.heap_id,
int ret;
ret = ion_walk_heaps(client, data.prefetch_data.heap_id,
ION_HEAP_TYPE_SECURE_DMA,
(void *)data.prefetch_data.len,
ion_secure_cma_prefetch);
if (ret)
return ret;
break;
}
case ION_IOC_DRAIN:
{
ion_walk_heaps(client, data.prefetch_data.heap_id,
int ret;
ret = ion_walk_heaps(client, data.prefetch_data.heap_id,
ION_HEAP_TYPE_SECURE_DMA,
(void *)data.prefetch_data.len,
ion_secure_cma_drain_pool);
if (ret)
return ret;
break;
}

View File

@ -1087,6 +1087,13 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
void __user *argp = (void __user *)arg;
long ret = 0;
memset(&var, 0, sizeof(var));
memset(&fix, 0, sizeof(fix));
memset(&con2fb, 0, sizeof(con2fb));
memset(&cmap_from, 0, sizeof(cmap_from));
memset(&cmap, 0, sizeof(cmap));
memset(&event, 0, sizeof(event));
switch (cmd) {
case FBIOGET_VSCREENINFO:
if (!lock_fb_info(info))

View File

@ -37,6 +37,7 @@
#define MDP_PPP_MAX_BPP 4
#define MDP_PPP_DYNAMIC_FACTOR 3
#define MDP_PPP_MAX_READ_WRITE 3
#define MDP_PPP_MAX_WIDTH 0xFFF
#define ENABLE_SOLID_FILL 0x2
#define DISABLE_SOLID_FILL 0x0
#define BLEND_LATENCY 3
@ -148,6 +149,11 @@ int mdp3_ppp_get_img(struct mdp_img *img, struct mdp_blit_req *req,
return -EINVAL;
}
if (img->width > MDP_PPP_MAX_WIDTH) {
pr_err("%s incorrect width %d\n", __func__, img->width);
return -EINVAL;
}
fb_data.flags = img->priv;
fb_data.memory_id = img->memory_id;
fb_data.offset = 0;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, The Linux Foundation. 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 and
@ -1244,8 +1244,9 @@ static void mdss_mdp_handoff_programmable_fetch(struct mdss_mdp_ctl *ctl,
MDSS_MDP_REG_INTF_HSYNC_CTL) >> 16;
v_total_handoff = mdp_video_read(ctx,
MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0)/h_total_handoff;
ctl->prg_fet = v_total_handoff -
((fetch_start_handoff - 1)/h_total_handoff);
if (h_total_handoff)
ctl->prg_fet = v_total_handoff -
((fetch_start_handoff - 1)/h_total_handoff);
pr_debug("programmable fetch lines %d start:%d\n",
ctl->prg_fet, fetch_start_handoff);
}

View File

@ -4004,9 +4004,16 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd)
while (remsd) {
struct softnet_data *next = remsd->rps_ipi_next;
if (cpu_online(remsd->cpu))
if (cpu_online(remsd->cpu)) {
__smp_call_function_single(remsd->cpu,
&remsd->csd, 0);
} else {
pr_err("%s(), cpu was offline and IPI was not "
"delivered so clean up NAPI", __func__);
rps_lock(remsd);
remsd->backlog.state = 0;
rps_unlock(remsd);
}
remsd = next;
}
} else
@ -6015,6 +6022,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
if (action != CPU_DEAD && action != CPU_DEAD_FROZEN)
return NOTIFY_OK;
local_irq_disable();
cpu = smp_processor_id();
sd = &per_cpu(softnet_data, cpu);

View File

@ -366,6 +366,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
[NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
[NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
[NL80211_ATTR_LOCAL_MESH_POWER_MODE] = {. type = NLA_U32 },
[NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
[NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
[NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },

View File

@ -401,6 +401,9 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es
if (up->replay_window > up->bmp_len * sizeof(__u32) * 8)
return -EINVAL;
if (up->replay_window > up->bmp_len * sizeof(__u32) * 8)
return -EINVAL;
return 0;
}

View File

@ -155,7 +155,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"VIRT ENABLE", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@ -183,7 +183,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"VIRT STRENGTH", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@ -211,7 +211,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"VIRT OUT_TYPE", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@ -239,7 +239,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"VIRT GAIN_ADJUST", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@ -318,7 +318,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_ENABLE", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -346,7 +346,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_MODE", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -374,7 +374,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_PRESET", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -402,7 +402,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_WET_MIX", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -430,7 +430,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_GAIN_ADJUST", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -458,7 +458,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_ROOM_LEVEL", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -486,7 +486,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_ROOM_HF_LEVEL", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -514,7 +514,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_DECAY_TIME", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -542,7 +542,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_DECAY_HF_RATIO", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -570,7 +570,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_REFLECTIONS_LEVEL", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -598,7 +598,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_REFLECTIONS_DELAY", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -626,7 +626,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_LEVEL", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -654,7 +654,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_DELAY", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -682,7 +682,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_DIFFUSION", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -710,7 +710,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"REVERB_DENSITY", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@ -790,7 +790,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"BASS_BOOST_ENABLE", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_BASS_BOOST;
*updt_params++ =
@ -818,7 +818,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"BASS_BOOST_MODE", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_BASS_BOOST;
*updt_params++ =
@ -846,7 +846,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"BASS_BOOST_STRENGTH", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_BASS_BOOST;
*updt_params++ =
@ -924,7 +924,7 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"PBE_ENABLE", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_PBE;
*updt_params++ =
@ -950,7 +950,7 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"PBE_PARAM", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_PBE;
*updt_params++ =
@ -1035,7 +1035,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"EQ_ENABLE", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@ -1103,7 +1103,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"EQ_CONFIG", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@ -1154,7 +1154,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"EQ_BAND_INDEX", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@ -1186,7 +1186,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
MAX_INBAND_PARAM_SZ,
"EQ_SINGLE_BAND_FREQ", rc);
if (rc != 0)
break;
goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@ -1276,7 +1276,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac,
"VOLUME/VOLUME2_GAIN_2CH",
rc);
if (rc != 0)
break;
goto invalid_config;
if (instance == SOFT_VOLUME_INSTANCE_2)
*updt_params++ =
ASM_MODULE_ID_VOL_CTRL2;
@ -1325,7 +1325,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac,
"VOLUME/VOLUME2_GAIN_MASTER",
rc);
if (rc != 0)
break;
goto invalid_config;
if (instance == SOFT_VOLUME_INSTANCE_2)
*updt_params++ =
ASM_MODULE_ID_VOL_CTRL2;

View File

@ -65,6 +65,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
struct snd_soc_codec *codec;
struct snd_soc_dapm_context *dapm;
struct snd_soc_jack_pin *pin;
unsigned int sync = 0;
int enable;
trace_snd_soc_jack_report(jack, mask, status);
@ -92,12 +93,16 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
snd_soc_dapm_enable_pin(dapm, pin->pin);
else
snd_soc_dapm_disable_pin(dapm, pin->pin);
/* we need to sync for this case only */
sync = 1;
}
/* Report before the DAPM sync to help users updating micbias status */
blocking_notifier_call_chain(&jack->notifier, jack->status, jack);
snd_soc_dapm_sync(dapm);
if (sync)
snd_soc_dapm_sync(dapm);
snd_jack_report(jack->jack, jack->status);