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

"LA.BR.1.3.6-05410-8976.0"
This commit is contained in:
LuK1337 2018-02-06 13:11:45 +01:00
commit 39a771baad
56 changed files with 665 additions and 295 deletions

View File

@ -46,7 +46,7 @@ static inline int in_exception_text(unsigned long ptr)
return in ? : __in_irqentry_text(ptr); return in ? : __in_irqentry_text(ptr);
} }
extern void get_pct_hook_init(void); extern void get_timer_count_hook_init(void);
extern void __init early_trap_init(void *); extern void __init early_trap_init(void *);
extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs); extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs);

View File

@ -770,12 +770,13 @@ late_initcall(arm_mrc_hook_init);
#endif #endif
static int get_pct_trap(struct pt_regs *regs, unsigned int instr) static int get_timer_count_trap(struct pt_regs *regs, unsigned int instr)
{ {
u64 cntpct; u64 cval;
unsigned int res; unsigned int res;
int rd = (instr >> 12) & 0xF; int rd = (instr >> 12) & 0xF;
int rn = (instr >> 16) & 0xF; int rn = (instr >> 16) & 0xF;
int read_virtual = (instr >> 4) & 1;
res = arm_check_condition(instr, regs->ARM_cpsr); res = arm_check_condition(instr, regs->ARM_cpsr);
if (res == ARM_OPCODE_CONDTEST_FAIL) { if (res == ARM_OPCODE_CONDTEST_FAIL) {
@ -785,26 +786,27 @@ static int get_pct_trap(struct pt_regs *regs, unsigned int instr)
if (rd == 15 || rn == 15) if (rd == 15 || rn == 15)
return 1; return 1;
cntpct = arch_counter_get_cntpct(); cval = read_virtual ?
regs->uregs[rd] = cntpct; arch_counter_get_cntvct() : arch_counter_get_cntpct();
regs->uregs[rn] = cntpct >> 32; regs->uregs[rd] = cval;
regs->uregs[rn] = cval >> 32;
regs->ARM_pc += 4; regs->ARM_pc += 4;
return 0; return 0;
} }
static struct undef_hook get_pct_hook = { static struct undef_hook get_timer_count_hook = {
.instr_mask = 0x0ff00fff, .instr_mask = 0x0ff00fef,
.instr_val = 0x0c500f0e, .instr_val = 0x0c500f0e,
.cpsr_mask = MODE_MASK, .cpsr_mask = MODE_MASK,
.cpsr_val = USR_MODE, .cpsr_val = USR_MODE,
.fn = get_pct_trap, .fn = get_timer_count_trap,
}; };
void get_pct_hook_init(void) void get_timer_count_hook_init(void)
{ {
register_undef_hook(&get_pct_hook); register_undef_hook(&get_timer_count_hook);
} }
EXPORT_SYMBOL(get_pct_hook_init); EXPORT_SYMBOL(get_timer_count_hook_init);
void __bad_xchg(volatile void *ptr, int size) void __bad_xchg(volatile void *ptr, int size)
{ {

View File

@ -54,4 +54,44 @@
#define ESR_EL1_EC_BKPT32 (0x38) #define ESR_EL1_EC_BKPT32 (0x38)
#define ESR_EL1_EC_BRK64 (0x3C) #define ESR_EL1_EC_BRK64 (0x3C)
/* ISS field definitions for System instruction traps */
#define ESR_ELx_SYS64_ISS_RES0_SHIFT 22
#define ESR_ELx_SYS64_ISS_RES0_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_RES0_SHIFT)
#define ESR_ELx_SYS64_ISS_DIR_MASK 0x1
#define ESR_ELx_SYS64_ISS_DIR_READ 0x1
#define ESR_ELx_SYS64_ISS_DIR_WRITE 0x0
#define ESR_ELx_SYS64_ISS_RT_SHIFT 5
#define ESR_ELx_SYS64_ISS_RT_MASK (UL(0x1f) << ESR_ELx_SYS64_ISS_RT_SHIFT)
#define ESR_ELx_SYS64_ISS_CRM_SHIFT 1
#define ESR_ELx_SYS64_ISS_CRM_MASK (UL(0xf) << ESR_ELx_SYS64_ISS_CRM_SHIFT)
#define ESR_ELx_SYS64_ISS_CRN_SHIFT 10
#define ESR_ELx_SYS64_ISS_CRN_MASK (UL(0xf) << ESR_ELx_SYS64_ISS_CRN_SHIFT)
#define ESR_ELx_SYS64_ISS_OP1_SHIFT 14
#define ESR_ELx_SYS64_ISS_OP1_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_OP1_SHIFT)
#define ESR_ELx_SYS64_ISS_OP2_SHIFT 17
#define ESR_ELx_SYS64_ISS_OP2_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_OP2_SHIFT)
#define ESR_ELx_SYS64_ISS_OP0_SHIFT 20
#define ESR_ELx_SYS64_ISS_OP0_MASK (UL(0x3) << ESR_ELx_SYS64_ISS_OP0_SHIFT)
#define ESR_ELx_SYS64_ISS_SYS_MASK (ESR_ELx_SYS64_ISS_OP0_MASK | \
ESR_ELx_SYS64_ISS_OP1_MASK | \
ESR_ELx_SYS64_ISS_OP2_MASK | \
ESR_ELx_SYS64_ISS_CRN_MASK | \
ESR_ELx_SYS64_ISS_CRM_MASK)
#define ESR_ELx_SYS64_ISS_SYS_VAL(op0, op1, op2, crn, crm) \
(((op0) << ESR_ELx_SYS64_ISS_OP0_SHIFT) | \
((op1) << ESR_ELx_SYS64_ISS_OP1_SHIFT) | \
((op2) << ESR_ELx_SYS64_ISS_OP2_SHIFT) | \
((crn) << ESR_ELx_SYS64_ISS_CRN_SHIFT) | \
((crm) << ESR_ELx_SYS64_ISS_CRM_SHIFT))
#define ESR_ELx_SYS64_ISS_SYS_OP_MASK (ESR_ELx_SYS64_ISS_SYS_MASK | \
ESR_ELx_SYS64_ISS_DIR_MASK)
#define ESR_ELx_SYS64_ISS_SYS_CNTVCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \
ESR_ELx_SYS64_ISS_DIR_READ)
#define ESR_ELx_SYS64_ISS_SYS_CNTFRQ (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 0, 14, 0) | \
ESR_ELx_SYS64_ISS_DIR_READ)
#endif /* __ASM_ESR_H */ #endif /* __ASM_ESR_H */

View File

@ -40,5 +40,5 @@ static inline int in_exception_text(unsigned long ptr)
ptr < (unsigned long)&__exception_text_end; ptr < (unsigned long)&__exception_text_end;
} }
static inline void get_pct_hook_init(void) {} static inline void get_timer_count_hook_init(void) {}
#endif #endif

View File

@ -378,7 +378,7 @@ el0_sync:
cmp x24, #ESR_EL1_EC_FP_EXC64 // FP/ASIMD exception cmp x24, #ESR_EL1_EC_FP_EXC64 // FP/ASIMD exception
b.eq el0_fpsimd_exc b.eq el0_fpsimd_exc
cmp x24, #ESR_EL1_EC_SYS64 // configurable trap cmp x24, #ESR_EL1_EC_SYS64 // configurable trap
b.eq el0_undef b.eq el0_sys
cmp x24, #ESR_EL1_EC_SP_ALIGN // stack alignment exception cmp x24, #ESR_EL1_EC_SP_ALIGN // stack alignment exception
b.eq el0_sp_pc b.eq el0_sp_pc
cmp x24, #ESR_EL1_EC_PC_ALIGN // pc alignment exception cmp x24, #ESR_EL1_EC_PC_ALIGN // pc alignment exception
@ -491,6 +491,15 @@ el0_undef:
enable_dbg_and_irq enable_dbg_and_irq
mov x0, sp mov x0, sp
b do_undefinstr b do_undefinstr
el0_sys:
/*
* System instructions, for trapped cache maintenance instructions
*/
enable_dbg
enable_irq
mov x0, x25
mov x1, sp
b do_sysinstr
el0_dbg: el0_dbg:
/* /*
* Debug exception handling * Debug exception handling

View File

@ -32,8 +32,11 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <asm/arch_timer.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/barrier.h>
#include <asm/debug-monitors.h> #include <asm/debug-monitors.h>
#include <asm/esr.h>
#include <asm/traps.h> #include <asm/traps.h>
#include <asm/stacktrace.h> #include <asm/stacktrace.h>
#include <asm/exception.h> #include <asm/exception.h>
@ -428,6 +431,38 @@ die_sig:
arm64_notify_die("Oops - undefined instruction", regs, &info, 0); arm64_notify_die("Oops - undefined instruction", regs, &info, 0);
} }
static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
{
int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
isb();
if (rt != 31)
regs->regs[rt] = arch_counter_get_cntvct();
regs->pc += 4;
}
static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs)
{
int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
if (rt != 31)
asm volatile("mrs %0, cntfrq_el0" : "=r" (regs->regs[rt]));
regs->pc += 4;
}
asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
{
if ((esr & ESR_ELx_SYS64_ISS_SYS_OP_MASK) == ESR_ELx_SYS64_ISS_SYS_CNTVCT) {
cntvct_read_handler(esr, regs);
return;
} else if ((esr & ESR_ELx_SYS64_ISS_SYS_OP_MASK) == ESR_ELx_SYS64_ISS_SYS_CNTFRQ) {
cntfrq_read_handler(esr, regs);
return;
}
do_undefinstr(regs);
}
long compat_arm_syscall(struct pt_regs *regs); long compat_arm_syscall(struct pt_regs *regs);
asmlinkage long do_ni_syscall(struct pt_regs *regs) asmlinkage long do_ni_syscall(struct pt_regs *regs)

View File

@ -213,13 +213,27 @@ static int ath3k_load_firmware(struct usb_device *udev,
{ {
u8 *send_buf; u8 *send_buf;
int err, pipe, len, size, sent = 0; int err, pipe, len, size, sent = 0;
int count = firmware->size; int count;
BT_DBG("udev %p", udev); BT_DBG("udev %p", udev);
if (!firmware || !firmware->data || firmware->size <= 0) {
err = -EINVAL;
BT_ERR("Not a valid FW file");
return err;
}
count = firmware->size;
if (count < FW_HDR_SIZE) {
err = -EINVAL;
BT_ERR("ath3k loading invalid size of file");
return err;
}
pipe = usb_sndctrlpipe(udev, 0); pipe = usb_sndctrlpipe(udev, 0);
send_buf = kmalloc(BULK_SIZE, GFP_KERNEL); send_buf = kzalloc(BULK_SIZE, GFP_KERNEL);
if (!send_buf) { if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware"); BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM; return -ENOMEM;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2017, 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 * 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 * it under the terms of the GNU General Public License version 2 and
@ -54,6 +54,7 @@
#define RPC_TIMEOUT (5 * HZ) #define RPC_TIMEOUT (5 * HZ)
#define BALIGN 32 #define BALIGN 32
#define NUM_CHANNELS 1 /*8 compute 2 cpz 1 modem*/ #define NUM_CHANNELS 1 /*8 compute 2 cpz 1 modem*/
#define FASTRPC_CTX_MAGIC (0xbeeddeed)
#define IS_CACHE_ALIGNED(x) (((x) & ((L1_CACHE_BYTES)-1)) == 0) #define IS_CACHE_ALIGNED(x) (((x) & ((L1_CACHE_BYTES)-1)) == 0)
@ -69,11 +70,11 @@ static inline uint64_t buf_page_offset(uint64_t buf)
return offset; return offset;
} }
static inline int buf_num_pages(uint64_t buf, ssize_t len) static inline uint64_t buf_num_pages(uint64_t buf, size_t len)
{ {
uint64_t start = buf_page_start(buf) >> PAGE_SHIFT; uint64_t start = buf_page_start(buf) >> PAGE_SHIFT;
uint64_t end = (((uint64_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT; uint64_t end = (((uint64_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
int nPages = end - start + 1; uint64_t nPages = end - start + 1;
return nPages; return nPages;
} }
@ -102,7 +103,7 @@ struct fastrpc_buf {
struct fastrpc_file *fl; struct fastrpc_file *fl;
void *virt; void *virt;
dma_addr_t phys; dma_addr_t phys;
ssize_t size; size_t size;
struct ion_handle *handle; struct ion_handle *handle;
struct ion_client *client; struct ion_client *client;
}; };
@ -129,11 +130,12 @@ struct smq_invoke_ctx {
int *fds; int *fds;
struct fastrpc_mmap **maps; struct fastrpc_mmap **maps;
struct fastrpc_buf *buf; struct fastrpc_buf *buf;
ssize_t used; size_t used;
struct fastrpc_file *fl; struct fastrpc_file *fl;
uint32_t sc; uint32_t sc;
struct overlap *overs; struct overlap *overs;
struct overlap **overps; struct overlap **overps;
unsigned int magic;
}; };
struct fastrpc_ctx_lst { struct fastrpc_ctx_lst {
@ -184,9 +186,9 @@ struct fastrpc_mmap {
struct sg_table *table; struct sg_table *table;
struct dma_buf_attachment *attach; struct dma_buf_attachment *attach;
uintptr_t phys; uintptr_t phys;
ssize_t size; size_t size;
uintptr_t va; uintptr_t va;
ssize_t len; size_t len;
int refs; int refs;
uintptr_t raddr; uintptr_t raddr;
struct ion_handle *handle; struct ion_handle *handle;
@ -229,7 +231,7 @@ static const struct fastrpc_channel_info gcinfo[NUM_CHANNELS] = {
static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache) static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
{ {
int err = 0; int err = 0;
struct fastrpc_file *fl = buf == 0 ? 0 : buf->fl; struct fastrpc_file *fl = buf == NULL ? NULL : buf->fl;
if (!fl) if (!fl)
return; return;
if (cache) { if (cache) {
@ -254,7 +256,8 @@ static void fastrpc_buf_list_free(struct fastrpc_file *fl)
struct fastrpc_buf *buf, *free; struct fastrpc_buf *buf, *free;
do { do {
struct hlist_node *n; struct hlist_node *n;
free = 0;
free = NULL;
spin_lock(&fl->hlock); spin_lock(&fl->hlock);
hlist_for_each_entry_safe(buf, n, &fl->bufs, hn) { hlist_for_each_entry_safe(buf, n, &fl->bufs, hn) {
hlist_del_init(&buf->hn); hlist_del_init(&buf->hn);
@ -283,10 +286,10 @@ static void fastrpc_mmap_add(struct fastrpc_mmap *map)
} }
static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va, static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
ssize_t len, struct fastrpc_mmap **ppmap) size_t len, struct fastrpc_mmap **ppmap)
{ {
struct fastrpc_mmap *match = 0, *map; struct fastrpc_mmap *match = NULL, *map = NULL;
struct hlist_node *n; struct hlist_node *n = NULL;
struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa;
spin_lock(&me->hlock); spin_lock(&me->hlock);
hlist_for_each_entry_safe(map, n, &me->maps, hn) { hlist_for_each_entry_safe(map, n, &me->maps, hn) {
@ -324,7 +327,7 @@ static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
static void fastrpc_mmap_free(struct fastrpc_mmap *map) static void fastrpc_mmap_free(struct fastrpc_mmap *map)
{ {
struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa;
struct fastrpc_file *fl; struct fastrpc_file *fl = NULL;
if (!map) if (!map)
return; return;
if (map->flags == ADSP_MMAP_HEAP_ADDR) { if (map->flags == ADSP_MMAP_HEAP_ADDR) {
@ -359,12 +362,12 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map)
kfree(map); kfree(map);
} }
static int fastrpc_buf_alloc(struct fastrpc_file *fl, ssize_t size, static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
struct fastrpc_buf **obuf) struct fastrpc_buf **obuf)
{ {
int err = 0; int err = 0;
struct fastrpc_buf *buf = 0, *fr = 0; struct fastrpc_buf *buf = NULL, *fr = NULL;
struct hlist_node *n; struct hlist_node *n = NULL;
size_t len = 0; size_t len = 0;
VERIFY(err, size > 0); VERIFY(err, size > 0);
@ -384,7 +387,7 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, ssize_t size,
*obuf = fr; *obuf = fr;
return 0; return 0;
} }
VERIFY(err, buf = kzalloc(sizeof(*buf), GFP_KERNEL)); VERIFY(err, NULL != (buf = kzalloc(sizeof(*buf), GFP_KERNEL)));
if (err) if (err)
goto bail; goto bail;
INIT_HLIST_NODE(&buf->hn); INIT_HLIST_NODE(&buf->hn);
@ -392,7 +395,7 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, ssize_t size,
buf->handle = NULL; buf->handle = NULL;
buf->client = NULL; buf->client = NULL;
buf->fl = fl; buf->fl = fl;
buf->virt = 0; buf->virt = NULL;
buf->phys = 0; buf->phys = 0;
buf->size = size; buf->size = size;
@ -422,8 +425,8 @@ static int context_restore_interrupted(struct fastrpc_file *fl,
struct smq_invoke_ctx **po) struct smq_invoke_ctx **po)
{ {
int err = 0; int err = 0;
struct smq_invoke_ctx *ctx = 0, *ictx = 0; struct smq_invoke_ctx *ctx = NULL, *ictx = NULL;
struct hlist_node *n; struct hlist_node *n = NULL;
struct fastrpc_ioctl_invoke *invoke = &invokefd->inv; struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
spin_lock(&fl->hlock); spin_lock(&fl->hlock);
hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) { hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
@ -475,7 +478,7 @@ static int context_build_overlap(struct smq_invoke_ctx *ctx)
ctx->overs[i].raix = i; ctx->overs[i].raix = i;
ctx->overps[i] = &ctx->overs[i]; ctx->overps[i] = &ctx->overs[i];
} }
sort(ctx->overps, nbufs, sizeof(*ctx->overps), overlap_ptr_cmp, 0); sort(ctx->overps, nbufs, sizeof(*ctx->overps), overlap_ptr_cmp, NULL);
max.start = 0; max.start = 0;
max.end = 0; max.end = 0;
for (i = 0; i < nbufs; ++i) { for (i = 0; i < nbufs; ++i) {
@ -504,7 +507,8 @@ bail:
#define K_COPY_FROM_USER(err, kernel, dst, src, size) \ #define K_COPY_FROM_USER(err, kernel, dst, src, size) \
do {\ do {\
if (!(kernel))\ if (!(kernel))\
VERIFY(err, 0 == copy_from_user((dst), (src),\ VERIFY(err, 0 == copy_from_user((dst),\
(void const __user *)(src),\
(size)));\ (size)));\
else\ else\
memmove((dst), (src), (size));\ memmove((dst), (src), (size));\
@ -513,8 +517,8 @@ bail:
#define K_COPY_TO_USER(err, kernel, dst, src, size) \ #define K_COPY_TO_USER(err, kernel, dst, src, size) \
do {\ do {\
if (!(kernel))\ if (!(kernel))\
VERIFY(err, 0 == copy_to_user((dst), (src),\ VERIFY(err, 0 == copy_to_user((void __user *)(dst), \
(size)));\ (src), (size)));\
else\ else\
memmove((dst), (src), (size));\ memmove((dst), (src), (size));\
} while (0) } while (0)
@ -527,7 +531,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
struct smq_invoke_ctx **po) struct smq_invoke_ctx **po)
{ {
int err = 0, bufs, size = 0; int err = 0, bufs, size = 0;
struct smq_invoke_ctx *ctx = 0; struct smq_invoke_ctx *ctx = NULL;
struct fastrpc_ctx_lst *clst = &fl->clst; struct fastrpc_ctx_lst *clst = &fl->clst;
struct fastrpc_ioctl_invoke *invoke = &invokefd->inv; struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
@ -538,7 +542,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
sizeof(*ctx->overs) * (bufs) + sizeof(*ctx->overs) * (bufs) +
sizeof(*ctx->overps) * (bufs); sizeof(*ctx->overps) * (bufs);
VERIFY(err, ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)); VERIFY(err, NULL != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)));
if (err) if (err)
goto bail; goto bail;
@ -551,7 +555,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
ctx->overs = (struct overlap *)(&ctx->fds[bufs]); ctx->overs = (struct overlap *)(&ctx->fds[bufs]);
ctx->overps = (struct overlap **)(&ctx->overs[bufs]); ctx->overps = (struct overlap **)(&ctx->overs[bufs]);
K_COPY_FROM_USER(err, kernel, ctx->lpra, invoke->pra, K_COPY_FROM_USER(err, kernel, (void *)ctx->lpra, invoke->pra,
bufs * sizeof(*ctx->lpra)); bufs * sizeof(*ctx->lpra));
if (err) if (err)
goto bail; goto bail;
@ -572,6 +576,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
ctx->pid = current->pid; ctx->pid = current->pid;
ctx->tgid = current->tgid; ctx->tgid = current->tgid;
init_completion(&ctx->work); init_completion(&ctx->work);
ctx->magic = FASTRPC_CTX_MAGIC;
spin_lock(&fl->hlock); spin_lock(&fl->hlock);
hlist_add_head(&ctx->hn, &clst->pending); hlist_add_head(&ctx->hn, &clst->pending);
@ -606,6 +611,7 @@ static void context_free(struct smq_invoke_ctx *ctx)
for (i = 0; i < nbufs; ++i) for (i = 0; i < nbufs; ++i)
fastrpc_mmap_free(ctx->maps[i]); fastrpc_mmap_free(ctx->maps[i]);
fastrpc_buf_free(ctx->buf, 1); fastrpc_buf_free(ctx->buf, 1);
ctx->magic = 0;
kfree(ctx); kfree(ctx);
} }
@ -652,10 +658,10 @@ static void context_list_ctor(struct fastrpc_ctx_lst *me)
static void fastrpc_context_list_dtor(struct fastrpc_file *fl) static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
{ {
struct fastrpc_ctx_lst *clst = &fl->clst; struct fastrpc_ctx_lst *clst = &fl->clst;
struct smq_invoke_ctx *ictx = 0, *ctxfree; struct smq_invoke_ctx *ictx = NULL, *ctxfree = NULL;
struct hlist_node *n; struct hlist_node *n;
do { do {
ctxfree = 0; ctxfree = NULL;
spin_lock(&fl->hlock); spin_lock(&fl->hlock);
hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) { hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) {
hlist_del_init(&ictx->hn); hlist_del_init(&ictx->hn);
@ -667,7 +673,7 @@ static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
context_free(ctxfree); context_free(ctxfree);
} while (ctxfree); } while (ctxfree);
do { do {
ctxfree = 0; ctxfree = NULL;
spin_lock(&fl->hlock); spin_lock(&fl->hlock);
hlist_for_each_entry_safe(ictx, n, &clst->pending, hn) { hlist_for_each_entry_safe(ictx, n, &clst->pending, hn) {
hlist_del_init(&ictx->hn); hlist_del_init(&ictx->hn);
@ -686,7 +692,7 @@ static void fastrpc_file_list_dtor(struct fastrpc_apps *me)
struct fastrpc_file *fl, *free; struct fastrpc_file *fl, *free;
struct hlist_node *n; struct hlist_node *n;
do { do {
free = 0; free = NULL;
spin_lock(&me->hlock); spin_lock(&me->hlock);
hlist_for_each_entry_safe(fl, n, &me->drivers, hn) { hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
hlist_del_init(&fl->hn); hlist_del_init(&fl->hn);
@ -700,7 +706,7 @@ static void fastrpc_file_list_dtor(struct fastrpc_apps *me)
} }
static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, uintptr_t va, static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, uintptr_t va,
ssize_t len, int mflags, struct fastrpc_mmap **ppmap); size_t len, int mflags, struct fastrpc_mmap **ppmap);
static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
{ {
@ -713,20 +719,20 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
int outbufs = REMOTE_SCALARS_OUTBUFS(sc); int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
int bufs = inbufs + outbufs; int bufs = inbufs + outbufs;
uintptr_t args; uintptr_t args;
ssize_t rlen = 0, copylen = 0, metalen = 0; size_t rlen = 0, copylen = 0, metalen = 0;
int i, inh, oix; int i, inh, oix;
int err = 0; int err = 0;
int mflags = 0; int mflags = 0;
/* calculate size of the metadata */ /* calculate size of the metadata */
rpra = 0; rpra = NULL;
list = smq_invoke_buf_start(rpra, sc); list = smq_invoke_buf_start(rpra, sc);
pages = smq_phy_page_start(sc, list); pages = smq_phy_page_start(sc, list);
ipage = pages; ipage = pages;
for (i = 0; i < bufs; ++i) { for (i = 0; i < bufs; ++i) {
uintptr_t buf = (uintptr_t)lpra[i].buf.pv; uintptr_t buf = (uintptr_t)lpra[i].buf.pv;
ssize_t len = lpra[i].buf.len; size_t len = lpra[i].buf.len;
if (ctx->fds[i] > 0) { if (ctx->fds[i] > 0) {
VERIFY(err, !fastrpc_mmap_create(ctx->fl, VERIFY(err, !fastrpc_mmap_create(ctx->fl,
ctx->fds[i], buf, len, mflags, ctx->fds[i], buf, len, mflags,
@ -738,12 +744,13 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
} }
ipage += 1; ipage += 1;
} }
metalen = copylen = (ssize_t)&ipage[0]; metalen = copylen = (size_t)&ipage[0];
/* calculate len requreed for copying */ /* calculate len requreed for copying */
for (oix = 0; oix < inbufs + outbufs; ++oix) { for (oix = 0; oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix; int i = ctx->overps[oix]->raix;
uintptr_t mstart, mend; uintptr_t mstart, mend;
ssize_t len = lpra[i].buf.len; size_t len = lpra[i].buf.len;
if (!len) if (!len)
continue; continue;
if (ctx->maps[i]) if (ctx->maps[i])
@ -776,7 +783,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
ipage = pages; ipage = pages;
args = (uintptr_t)ctx->buf->virt + metalen; args = (uintptr_t)ctx->buf->virt + metalen;
for (i = 0; i < bufs; ++i) { for (i = 0; i < bufs; ++i) {
ssize_t len = lpra[i].buf.len; size_t len = lpra[i].buf.len;
list[i].num = 0; list[i].num = 0;
list[i].pgidx = 0; list[i].pgidx = 0;
if (!len) if (!len)
@ -789,7 +796,8 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
for (i = 0; i < inbufs + outbufs; ++i) { for (i = 0; i < inbufs + outbufs; ++i) {
struct fastrpc_mmap *map = ctx->maps[i]; struct fastrpc_mmap *map = ctx->maps[i];
uint64_t buf = ptr_to_uint64(lpra[i].buf.pv); uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
ssize_t len = lpra[i].buf.len; size_t len = lpra[i].buf.len;
rpra[i].buf.pv = 0; rpra[i].buf.pv = 0;
rpra[i].buf.len = len; rpra[i].buf.len = len;
if (!len) if (!len)
@ -797,7 +805,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
if (map) { if (map) {
struct vm_area_struct *vma; struct vm_area_struct *vma;
uintptr_t offset; uintptr_t offset;
int num = buf_num_pages(buf, len); uint64_t num = buf_num_pages(buf, len);
int idx = list[i].pgidx; int idx = list[i].pgidx;
VERIFY(err, NULL != (vma = find_vma(current->mm, VERIFY(err, NULL != (vma = find_vma(current->mm,
@ -817,9 +825,9 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
for (oix = 0; oix < inbufs + outbufs; ++oix) { for (oix = 0; oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix; int i = ctx->overps[oix]->raix;
struct fastrpc_mmap *map = ctx->maps[i]; struct fastrpc_mmap *map = ctx->maps[i];
ssize_t mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart; size_t mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
uint64_t buf; uint64_t buf;
ssize_t len = lpra[i].buf.len; size_t len = lpra[i].buf.len;
if (!len) if (!len)
continue; continue;
if (map) if (map)
@ -887,7 +895,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
goto bail; goto bail;
} else { } else {
fastrpc_mmap_free(ctx->maps[i]); fastrpc_mmap_free(ctx->maps[i]);
ctx->maps[i] = 0; ctx->maps[i] = NULL;
} }
} }
num = REMOTE_SCALARS_OUTHANDLES(sc); num = REMOTE_SCALARS_OUTHANDLES(sc);
@ -1007,15 +1015,23 @@ static void fastrpc_read_handler(int cid)
{ {
struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa;
struct smq_invoke_rsp rsp = {0}; struct smq_invoke_rsp rsp = {0};
int ret = 0; struct smq_invoke_ctx *ctx;
int ret = 0, err = 0;
do { do {
ret = smd_read_from_cb(me->channel[cid].chan, &rsp, ret = smd_read_from_cb(me->channel[cid].chan, &rsp,
sizeof(rsp)); sizeof(rsp));
if (ret != sizeof(rsp)) if (ret != sizeof(rsp))
break; break;
ctx = (struct smq_invoke_ctx *)(uint64_to_ptr(rsp.ctx));
VERIFY(err, (ctx && ctx->magic == FASTRPC_CTX_MAGIC));
if (err)
goto bail;
context_notify_user(uint64_to_ptr(rsp.ctx), rsp.retval); context_notify_user(uint64_to_ptr(rsp.ctx), rsp.retval);
} while (ret == sizeof(rsp)); } while (ret == sizeof(rsp));
bail:
if (err)
pr_err("adsprpc: invalid response or context\n");
} }
static void smd_event_handler(void *priv, unsigned event) static void smd_event_handler(void *priv, unsigned event)
@ -1053,7 +1069,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
uint32_t kernel, uint32_t kernel,
struct fastrpc_ioctl_invoke_fd *invokefd) struct fastrpc_ioctl_invoke_fd *invokefd)
{ {
struct smq_invoke_ctx *ctx = 0; struct smq_invoke_ctx *ctx = NULL;
struct fastrpc_ioctl_invoke *invoke = &invokefd->inv; struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
int cid = fl->cid; int cid = fl->cid;
int interrupted = 0; int interrupted = 0;
@ -1127,7 +1143,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
ioctl.inv.handle = 1; ioctl.inv.handle = 1;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0); ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
ioctl.inv.pra = ra; ioctl.inv.pra = ra;
ioctl.fds = 0; ioctl.fds = NULL;
VERIFY(err, !(err = fastrpc_internal_invoke(fl, VERIFY(err, !(err = fastrpc_internal_invoke(fl,
FASTRPC_MODE_PARALLEL, 1, &ioctl))); FASTRPC_MODE_PARALLEL, 1, &ioctl)));
if (err) if (err)
@ -1206,7 +1222,7 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
ioctl.inv.handle = 1; ioctl.inv.handle = 1;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0); ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
ioctl.inv.pra = ra; ioctl.inv.pra = ra;
ioctl.fds = 0; ioctl.fds = NULL;
VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
FASTRPC_MODE_PARALLEL, 1, &ioctl))); FASTRPC_MODE_PARALLEL, 1, &ioctl)));
return err; return err;
@ -1252,7 +1268,7 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
else else
ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1); ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
ioctl.inv.pra = ra; ioctl.inv.pra = ra;
ioctl.fds = 0; ioctl.fds = NULL;
VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
FASTRPC_MODE_PARALLEL, 1, &ioctl))); FASTRPC_MODE_PARALLEL, 1, &ioctl)));
map->raddr = (uintptr_t)routargs.vaddrout; map->raddr = (uintptr_t)routargs.vaddrout;
@ -1289,7 +1305,7 @@ static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl,
ioctl.inv.handle = 1; ioctl.inv.handle = 1;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 0, 1); ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 0, 1);
ioctl.inv.pra = ra; ioctl.inv.pra = ra;
ioctl.fds = 0; ioctl.fds = NULL;
VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
FASTRPC_MODE_PARALLEL, 1, &ioctl))); FASTRPC_MODE_PARALLEL, 1, &ioctl)));
@ -1316,7 +1332,7 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl,
struct { struct {
int pid; int pid;
uintptr_t vaddrout; uintptr_t vaddrout;
ssize_t size; size_t size;
} inargs; } inargs;
if (map->flags == ADSP_MMAP_HEAP_ADDR) { if (map->flags == ADSP_MMAP_HEAP_ADDR) {
VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, map)); VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, map));
@ -1336,7 +1352,7 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl,
else else
ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0); ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
ioctl.inv.pra = ra; ioctl.inv.pra = ra;
ioctl.fds = 0; ioctl.fds = NULL;
VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
FASTRPC_MODE_PARALLEL, 1, &ioctl))); FASTRPC_MODE_PARALLEL, 1, &ioctl)));
@ -1347,8 +1363,8 @@ bail:
static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl) static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
{ {
struct fastrpc_mmap *match = 0, *map; struct fastrpc_mmap *match = NULL, *map = NULL;
struct hlist_node *n; struct hlist_node *n = NULL;
int err = 0; int err = 0;
struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa;
spin_lock(&me->hlock); spin_lock(&me->hlock);
@ -1372,7 +1388,7 @@ bail:
} }
static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va, static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
ssize_t len, struct fastrpc_mmap **ppmap); size_t len, struct fastrpc_mmap **ppmap);
static void fastrpc_mmap_add(struct fastrpc_mmap *map); static void fastrpc_mmap_add(struct fastrpc_mmap *map);
@ -1380,7 +1396,7 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl,
struct fastrpc_ioctl_munmap *ud) struct fastrpc_ioctl_munmap *ud)
{ {
int err = 0; int err = 0;
struct fastrpc_mmap *map = 0; struct fastrpc_mmap *map = NULL;
if (!fastrpc_mmap_remove(fl, ud->vaddrout, ud->size, if (!fastrpc_mmap_remove(fl, ud->vaddrout, ud->size,
&map)) { &map)) {
@ -1396,10 +1412,10 @@ bail:
} }
static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, uintptr_t va, static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, uintptr_t va,
ssize_t len, int mflags, struct fastrpc_mmap **ppmap) size_t len, int mflags, struct fastrpc_mmap **ppmap)
{ {
struct fastrpc_mmap *match = 0, *map; struct fastrpc_mmap *match = NULL, *map = NULL;
struct hlist_node *n; struct hlist_node *n = NULL;
if (mflags == ADSP_MMAP_HEAP_ADDR) { if (mflags == ADSP_MMAP_HEAP_ADDR) {
struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa;
@ -1434,10 +1450,10 @@ static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, uintptr_t va,
return -ENOTTY; return -ENOTTY;
} }
static int dma_alloc_memory(phys_addr_t *region_start, ssize_t size) static int dma_alloc_memory(phys_addr_t *region_start, size_t size)
{ {
struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa;
void *vaddr = 0; void *vaddr = NULL;
DEFINE_DMA_ATTRS(attrs); DEFINE_DMA_ATTRS(attrs);
dma_set_attr(DMA_ATTR_SKIP_ZEROING, &attrs); dma_set_attr(DMA_ATTR_SKIP_ZEROING, &attrs);
@ -1453,10 +1469,10 @@ static int dma_alloc_memory(phys_addr_t *region_start, ssize_t size)
} }
static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, uintptr_t va, static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, uintptr_t va,
ssize_t len, int mflags, struct fastrpc_mmap **ppmap) size_t len, int mflags, struct fastrpc_mmap **ppmap)
{ {
int err = 0; int err = 0;
struct fastrpc_mmap *map = 0; struct fastrpc_mmap *map = NULL;
struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa;
unsigned long ionflag = 0; unsigned long ionflag = 0;
size_t pa_len = 0; size_t pa_len = 0;
@ -1476,7 +1492,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, uintptr_t va,
map->fd = fd; map->fd = fd;
if (mflags == ADSP_MMAP_HEAP_ADDR) { if (mflags == ADSP_MMAP_HEAP_ADDR) {
map->apps = me; map->apps = me;
map->fl = 0; map->fl = NULL;
VERIFY(err, !dma_alloc_memory(&region_start, len)); VERIFY(err, !dma_alloc_memory(&region_start, len));
if (err) if (err)
goto bail; goto bail;
@ -1511,7 +1527,7 @@ bail:
static int fastrpc_internal_mmap(struct fastrpc_file *fl, static int fastrpc_internal_mmap(struct fastrpc_file *fl,
struct fastrpc_ioctl_mmap *ud) struct fastrpc_ioctl_mmap *ud)
{ {
struct fastrpc_mmap *map = 0; struct fastrpc_mmap *map = NULL;
int err = 0; int err = 0;
if (!fastrpc_mmap_find(fl, ud->fd, (uintptr_t)ud->vaddrin, ud->size, if (!fastrpc_mmap_find(fl, ud->fd, (uintptr_t)ud->vaddrin, ud->size,
ud->flags, &map)) ud->flags, &map))
@ -1539,7 +1555,7 @@ static void fastrpc_channel_close(struct kref *kref)
ctx = container_of(kref, struct fastrpc_chan_ctx, kref); ctx = container_of(kref, struct fastrpc_chan_ctx, kref);
smd_close(ctx->chan); smd_close(ctx->chan);
ctx->chan = 0; ctx->chan = NULL;
mutex_unlock(&me->smd_mutex); mutex_unlock(&me->smd_mutex);
cid = ctx - &me->channel[0]; cid = ctx - &me->channel[0];
pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name, pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
@ -1551,7 +1567,7 @@ static void fastrpc_context_list_dtor(struct fastrpc_file *fl);
static int fastrpc_file_free(struct fastrpc_file *fl) static int fastrpc_file_free(struct fastrpc_file *fl)
{ {
struct hlist_node *n; struct hlist_node *n;
struct fastrpc_mmap *map = 0; struct fastrpc_mmap *map = NULL;
int cid; int cid;
if (!fl) if (!fl)
@ -1577,7 +1593,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl)
static int fastrpc_device_release(struct inode *inode, struct file *file) static int fastrpc_device_release(struct inode *inode, struct file *file)
{ {
fastrpc_file_free((struct fastrpc_file *)file->private_data); fastrpc_file_free((struct fastrpc_file *)file->private_data);
file->private_data = 0; file->private_data = NULL;
return 0; return 0;
} }
@ -1586,7 +1602,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
int cid = MINOR(inode->i_rdev); int cid = MINOR(inode->i_rdev);
int err = 0; int err = 0;
struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa;
struct fastrpc_file *fl = 0; struct fastrpc_file *fl = NULL;
VERIFY(err, fl = kzalloc(sizeof(*fl), GFP_KERNEL)); VERIFY(err, fl = kzalloc(sizeof(*fl), GFP_KERNEL));
if (err) if (err)
@ -1608,7 +1624,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
fl->ssrcount = me->channel[cid].ssrcount; fl->ssrcount = me->channel[cid].ssrcount;
if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) || if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) ||
(me->channel[cid].chan == 0)) { (me->channel[cid].chan == NULL)) {
VERIFY(err, !smd_named_open_on_edge(FASTRPC_SMD_GUID, VERIFY(err, !smd_named_open_on_edge(FASTRPC_SMD_GUID,
gcinfo[cid].channel, gcinfo[cid].channel,
&me->channel[cid].chan, &me->channel[cid].chan,
@ -1657,7 +1673,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
p.invokefd.fds = 0; p.invokefd.fds = 0;
size = (ioctl_num == FASTRPC_IOCTL_INVOKE) ? size = (ioctl_num == FASTRPC_IOCTL_INVOKE) ?
sizeof(p.invokefd.inv) : sizeof(p.invokefd); sizeof(p.invokefd.inv) : sizeof(p.invokefd);
VERIFY(err, 0 == copy_from_user(&p.invokefd, param, size)); K_COPY_FROM_USER(err, 0, &p.invokefd, param, size);
if (err) if (err)
goto bail; goto bail;
VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, fl->mode, VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, fl->mode,
@ -1666,20 +1682,20 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
goto bail; goto bail;
break; break;
case FASTRPC_IOCTL_MMAP: case FASTRPC_IOCTL_MMAP:
VERIFY(err, 0 == copy_from_user(&p.mmap, param, K_COPY_FROM_USER(err, 0, &p.mmap, param,
sizeof(p.mmap))); sizeof(p.mmap));
if (err) if (err)
goto bail; goto bail;
VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap))); VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap)));
if (err) if (err)
goto bail; goto bail;
VERIFY(err, 0 == copy_to_user(param, &p.mmap, sizeof(p.mmap))); K_COPY_TO_USER(err, 0, param, &p.mmap, sizeof(p.mmap));
if (err) if (err)
goto bail; goto bail;
break; break;
case FASTRPC_IOCTL_MUNMAP: case FASTRPC_IOCTL_MUNMAP:
VERIFY(err, 0 == copy_from_user(&p.munmap, param, K_COPY_FROM_USER(err, 0, &p.munmap, param,
sizeof(p.munmap))); sizeof(p.munmap));
if (err) if (err)
goto bail; goto bail;
VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl, VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
@ -1699,8 +1715,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
} }
break; break;
case FASTRPC_IOCTL_INIT: case FASTRPC_IOCTL_INIT:
VERIFY(err, 0 == copy_from_user(&p.init, param, K_COPY_FROM_USER(err, 0, &p.init, param, sizeof(p.init));
sizeof(p.init)));
if (err) if (err)
goto bail; goto bail;
VERIFY(err, 0 == fastrpc_init_process(fl, &p.init)); VERIFY(err, 0 == fastrpc_init_process(fl, &p.init));
@ -1731,7 +1746,7 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
ctx->ssrcount++; ctx->ssrcount++;
if (ctx->chan) { if (ctx->chan) {
smd_close(ctx->chan); smd_close(ctx->chan);
ctx->chan = 0; ctx->chan = NULL;
pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name, pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
MAJOR(me->dev_no), cid); MAJOR(me->dev_no), cid);
} }
@ -1779,10 +1794,10 @@ static struct platform_driver adsp_memory_driver = {
static int __init fastrpc_device_init(void) static int __init fastrpc_device_init(void)
{ {
struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa;
struct device_node *node; struct device_node *node = NULL;
struct platform_device *pdev; struct platform_device *pdev = NULL;
struct iommu_group *group; struct iommu_group *group = NULL;
struct iommu_domain *domain; struct iommu_domain *domain = NULL;
int err = 0, i; int err = 0, i;
memset(me, 0, sizeof(*me)); memset(me, 0, sizeof(*me));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014 The Linux Foundation. All rights reserved. * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -33,7 +33,7 @@
struct compat_remote_buf { struct compat_remote_buf {
compat_uptr_t pv; /* buffer pointer */ compat_uptr_t pv; /* buffer pointer */
compat_ssize_t len; /* length of buffer */ compat_size_t len; /* length of buffer */
}; };
union compat_remote_arg { union compat_remote_arg {
@ -56,13 +56,13 @@ struct compat_fastrpc_ioctl_mmap {
compat_int_t fd; /* ion fd */ compat_int_t fd; /* ion fd */
compat_uint_t flags; /* flags for dsp to map with */ compat_uint_t flags; /* flags for dsp to map with */
compat_uptr_t vaddrin; /* optional virtual address */ compat_uptr_t vaddrin; /* optional virtual address */
compat_ssize_t size; /* size */ compat_size_t size; /* size */
compat_uptr_t vaddrout; /* dsps virtual address */ compat_uptr_t vaddrout; /* dsps virtual address */
}; };
struct compat_fastrpc_ioctl_munmap { struct compat_fastrpc_ioctl_munmap {
compat_uptr_t vaddrout; /* address to unmap */ compat_uptr_t vaddrout; /* address to unmap */
compat_ssize_t size; /* size */ compat_size_t size; /* size */
}; };
struct compat_fastrpc_ioctl_init { struct compat_fastrpc_ioctl_init {
@ -81,7 +81,7 @@ static int compat_get_fastrpc_ioctl_invoke(
unsigned int cmd) unsigned int cmd)
{ {
compat_uint_t u, sc; compat_uint_t u, sc;
compat_ssize_t s; compat_size_t s;
compat_uptr_t p; compat_uptr_t p;
struct fastrpc_ioctl_invoke_fd *inv; struct fastrpc_ioctl_invoke_fd *inv;
union compat_remote_arg *pra32; union compat_remote_arg *pra32;
@ -164,7 +164,7 @@ static int compat_get_fastrpc_ioctl_mmap(
{ {
compat_uint_t u; compat_uint_t u;
compat_int_t i; compat_int_t i;
compat_ssize_t s; compat_size_t s;
compat_uptr_t p; compat_uptr_t p;
int err; int err;
@ -198,7 +198,7 @@ static int compat_get_fastrpc_ioctl_munmap(
struct fastrpc_ioctl_munmap __user *unmap) struct fastrpc_ioctl_munmap __user *unmap)
{ {
compat_uptr_t p; compat_uptr_t p;
compat_ssize_t s; compat_size_t s;
int err; int err;
err = get_user(p, &unmap32->vaddrout); err = get_user(p, &unmap32->vaddrout);

View File

@ -1,5 +1,5 @@
/* /*
* 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 * 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 * it under the terms of the GNU General Public License version 2 and
@ -93,7 +93,7 @@ do {\
struct remote_buf64 { struct remote_buf64 {
uint64_t pv; uint64_t pv;
int64_t len; uint64_t len;
}; };
union remote_arg64 { union remote_arg64 {
@ -126,25 +126,25 @@ struct fastrpc_ioctl_invoke_fd {
struct fastrpc_ioctl_init { struct fastrpc_ioctl_init {
uint32_t flags; /* one of FASTRPC_INIT_* macros */ uint32_t flags; /* one of FASTRPC_INIT_* macros */
uintptr_t __user file; /* pointer to elf file */ uintptr_t file; /* pointer to elf file */
int32_t filelen; /* elf file length */ uint32_t filelen; /* elf file length */
int32_t filefd; /* ION fd for the file */ int32_t filefd; /* ION fd for the file */
uintptr_t __user mem; /* mem for the PD */ uintptr_t mem; /* mem for the PD */
int32_t memlen; /* mem length */ uint32_t memlen; /* mem length */
int32_t memfd; /* ION fd for the mem */ int32_t memfd; /* ION fd for the mem */
}; };
struct fastrpc_ioctl_munmap { struct fastrpc_ioctl_munmap {
uintptr_t vaddrout; /* address to unmap */ uintptr_t vaddrout; /* address to unmap */
ssize_t size; /* size */ size_t size; /* size */
}; };
struct fastrpc_ioctl_mmap { struct fastrpc_ioctl_mmap {
int fd; /* ion fd */ int fd; /* ion fd */
uint32_t flags; /* flags for dsp to map with */ uint32_t flags; /* flags for dsp to map with */
uintptr_t __user *vaddrin; /* optional virtual address */ uintptr_t vaddrin; /* optional virtual address */
ssize_t size; /* size */ size_t size; /* size */
uintptr_t vaddrout; /* dsps virtual address */ uintptr_t vaddrout; /* dsps virtual address */
}; };
@ -183,14 +183,15 @@ struct smq_invoke_rsp {
static inline struct smq_invoke_buf *smq_invoke_buf_start(remote_arg64_t *pra, static inline struct smq_invoke_buf *smq_invoke_buf_start(remote_arg64_t *pra,
uint32_t sc) uint32_t sc)
{ {
int len = REMOTE_SCALARS_LENGTH(sc); unsigned int len = REMOTE_SCALARS_LENGTH(sc);
return (struct smq_invoke_buf *)(&pra[len]); return (struct smq_invoke_buf *)(&pra[len]);
} }
static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc, static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc,
struct smq_invoke_buf *buf) struct smq_invoke_buf *buf)
{ {
int nTotal = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc); uint32_t nTotal = REMOTE_SCALARS_INBUFS(sc)+REMOTE_SCALARS_OUTBUFS(sc);
return (struct smq_phy_page *)(&buf[nTotal]); return (struct smq_phy_page *)(&buf[nTotal]);
} }

View File

@ -20,6 +20,7 @@
#include "diagfwd_cntl.h" #include "diagfwd_cntl.h"
#include "diag_masks.h" #include "diag_masks.h"
#include "diagfwd_peripheral.h" #include "diagfwd_peripheral.h"
#include "diag_ipc_logging.h"
#define ALL_EQUIP_ID 100 #define ALL_EQUIP_ID 100
#define ALL_SSID -1 #define ALL_SSID -1
@ -1464,6 +1465,16 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count)
if (!buf || count == 0) if (!buf || count == 0)
return -EINVAL; return -EINVAL;
mutex_lock(&driver->diag_maskclear_mutex);
if (driver->mask_clear) {
DIAG_LOG(DIAG_DEBUG_USERSPACE,
"diag:%s: count = %zu\n", __func__, count);
mutex_unlock(&driver->diag_maskclear_mutex);
return -EIO;
}
mutex_unlock(&driver->diag_maskclear_mutex);
mutex_lock(&driver->msg_mask_lock); mutex_lock(&driver->msg_mask_lock);
mutex_lock(&msg_mask.lock); mutex_lock(&msg_mask.lock);
mask = (struct diag_msg_mask_t *)(msg_mask.ptr); mask = (struct diag_msg_mask_t *)(msg_mask.ptr);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -215,6 +215,12 @@ static void usb_connect_work_fn(struct work_struct *work)
*/ */
static void usb_disconnect(struct diag_usb_info *ch) static void usb_disconnect(struct diag_usb_info *ch)
{ {
if (!ch)
return;
if (!atomic_read(&ch->connected) && driver->usb_connected)
diag_clear_masks();
if (ch && ch->ops && ch->ops->close) if (ch && ch->ops && ch->ops->close)
ch->ops->close(ch->ctxt, DIAG_USB_MODE); ch->ops->close(ch->ctxt, DIAG_USB_MODE);
} }

View File

@ -433,6 +433,8 @@ struct diagchar_dev {
struct class *diagchar_class; struct class *diagchar_class;
struct device *diag_dev; struct device *diag_dev;
int ref_count; int ref_count;
int mask_clear;
struct mutex diag_maskclear_mutex;
struct mutex diagchar_mutex; struct mutex diagchar_mutex;
struct mutex diag_file_mutex; struct mutex diag_file_mutex;
wait_queue_head_t wait_q; wait_queue_head_t wait_q;
@ -582,6 +584,7 @@ void diag_ws_on_copy_complete(int type);
void diag_ws_reset(int type); void diag_ws_reset(int type);
void diag_ws_release(void); void diag_ws_release(void);
void chk_logging_wakeup(void); void chk_logging_wakeup(void);
void diag_clear_masks(void);
int diag_cmd_add_reg(struct diag_cmd_reg_entry_t *new_entry, uint8_t proc, int diag_cmd_add_reg(struct diag_cmd_reg_entry_t *new_entry, uint8_t proc,
int pid); int pid);
struct diag_cmd_reg_entry_t *diag_cmd_search( struct diag_cmd_reg_entry_t *diag_cmd_search(

View File

@ -354,6 +354,27 @@ fail:
return -ENOMEM; return -ENOMEM;
} }
void diag_clear_masks(void)
{
int ret;
char cmd_disable_log_mask[] = { 0x73, 0, 0, 0, 0, 0, 0, 0};
char cmd_disable_msg_mask[] = { 0x7D, 0x05, 0, 0, 0, 0, 0, 0};
char cmd_disable_event_mask[] = { 0x60, 0};
DIAG_LOG(DIAG_DEBUG_USERSPACE,
"diag: %s: masks clear request upon USB Disconnection\n",
__func__);
ret = diag_process_apps_masks(cmd_disable_log_mask,
sizeof(cmd_disable_log_mask));
ret = diag_process_apps_masks(cmd_disable_msg_mask,
sizeof(cmd_disable_msg_mask));
ret = diag_process_apps_masks(cmd_disable_event_mask,
sizeof(cmd_disable_event_mask));
DIAG_LOG(DIAG_DEBUG_USERSPACE,
"diag:%s: masks cleared successfully\n", __func__);
}
static void diag_close_logging_process(int pid) static void diag_close_logging_process(int pid)
{ {
uint8_t i; uint8_t i;
@ -432,6 +453,11 @@ static void diag_close_logging_process(int pid)
break; break;
} }
} }
diag_clear_masks();
mutex_lock(&driver->diag_maskclear_mutex);
driver->mask_clear = 1;
mutex_unlock(&driver->diag_maskclear_mutex);
if (switch_flag) { if (switch_flag) {
diag_switch_logging(USB_MODE); diag_switch_logging(USB_MODE);
@ -513,8 +539,15 @@ static int diag_remove_client_entry(struct file *file)
} }
static int diagchar_close(struct inode *inode, struct file *file) static int diagchar_close(struct inode *inode, struct file *file)
{ {
DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: process exit %s\n", current->comm); int ret;
return diag_remove_client_entry(file);
DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: process exit %s\n",
current->comm);
ret = diag_remove_client_entry(file);
mutex_lock(&driver->diag_maskclear_mutex);
driver->mask_clear = 0;
mutex_unlock(&driver->diag_maskclear_mutex);
return ret;
} }
void diag_record_stats(int type, int flag) void diag_record_stats(int type, int flag)
@ -3070,6 +3103,7 @@ static int __init diagchar_init(void)
non_hdlc_data.len = 0; non_hdlc_data.len = 0;
mutex_init(&driver->hdlc_disable_mutex); mutex_init(&driver->hdlc_disable_mutex);
mutex_init(&driver->diagchar_mutex); mutex_init(&driver->diagchar_mutex);
mutex_init(&driver->diag_maskclear_mutex);
mutex_init(&driver->diag_file_mutex); mutex_init(&driver->diag_file_mutex);
mutex_init(&driver->delayed_rsp_mutex); mutex_init(&driver->delayed_rsp_mutex);
mutex_init(&apps_data_mutex); mutex_init(&apps_data_mutex);

View File

@ -1170,8 +1170,6 @@ static int diagfwd_mux_open(int id, int mode)
static int diagfwd_mux_close(int id, int mode) static int diagfwd_mux_close(int id, int mode)
{ {
uint8_t i;
switch (mode) { switch (mode) {
case DIAG_USB_MODE: case DIAG_USB_MODE:
driver->usb_connected = 0; driver->usb_connected = 0;
@ -1187,15 +1185,16 @@ static int diagfwd_mux_close(int id, int mode)
(mode == DIAG_MEMORY_DEVICE_MODE && (mode == DIAG_MEMORY_DEVICE_MODE &&
driver->logging_mode == USB_MODE)) { driver->logging_mode == USB_MODE)) {
/* /*
* In this case the channel must not be closed. This case * This case indicates that the USB is removed
* indicates that the USB is removed but there is a client * but there is a client running in background
* running in background with Memory Device mode * with Memory Device mode.
*/ */
} else { } else {
for (i = 0; i < NUM_PERIPHERALS; i++) { /*
diagfwd_close(i, TYPE_DATA); * With clearing of masks on ODL exit and
diagfwd_close(i, TYPE_CMD); * USB disconnection, closing of the channel is
} * not needed.This enables read and drop of stale packets.
*/
/* Re enable HDLC encoding */ /* Re enable HDLC encoding */
pr_debug("diag: In %s, re-enabling HDLC encoding\n", pr_debug("diag: In %s, re-enabling HDLC encoding\n",
__func__); __func__);

View File

@ -502,6 +502,7 @@ void diagfwd_peripheral_exit(void)
uint8_t peripheral; uint8_t peripheral;
uint8_t type; uint8_t type;
struct diagfwd_info *fwd_info = NULL; struct diagfwd_info *fwd_info = NULL;
int transport = 0;
diag_smd_exit(); diag_smd_exit();
diag_socket_exit(); diag_socket_exit();
@ -524,7 +525,10 @@ void diagfwd_peripheral_exit(void)
driver->diagfwd_dci_cmd[peripheral] = NULL; driver->diagfwd_dci_cmd[peripheral] = NULL;
} }
kfree(early_init_info); for (transport = 0; transport < NUM_TRANSPORT; transport++) {
kfree(early_init_info[transport]);
early_init_info[transport] = NULL;
}
} }
int diagfwd_cntl_register(uint8_t transport, uint8_t peripheral, void *ctxt, int diagfwd_cntl_register(uint8_t transport, uint8_t peripheral, void *ctxt,

View File

@ -82,6 +82,14 @@ config ARM_ARCH_TIMER_EVTSTREAM
This must be disabled for hardware validation purposes to detect any This must be disabled for hardware validation purposes to detect any
hardware anomalies of missing events. hardware anomalies of missing events.
config ARM_ARCH_TIMER_VCT_ACCESS
bool "Support for ARM architected timer virtual counter access in userspace"
default n
depends on ARM_ARCH_TIMER
help
This option enables support for reading the ARM architected timer's
virtual counter in userspace.
config CLKSRC_METAG_GENERIC config CLKSRC_METAG_GENERIC
def_bool y if METAG def_bool y if METAG
help help

View File

@ -313,14 +313,18 @@ static void arch_counter_set_user_access(void)
{ {
u32 cntkctl = arch_timer_get_cntkctl(); u32 cntkctl = arch_timer_get_cntkctl();
/* Disable user access to the timers */ /* Disable user access to the timers and the physical counter */
/* Also disable virtual event stream */ /* Also disable virtual event stream */
cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
| ARCH_TIMER_USR_VT_ACCESS_EN | ARCH_TIMER_USR_VT_ACCESS_EN
| ARCH_TIMER_VIRT_EVT_EN); | ARCH_TIMER_VIRT_EVT_EN
| ARCH_TIMER_USR_PCT_ACCESS_EN);
/* Enable user access to the virtual and physical counters */ /* Enable user access to the virtual counter */
cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN | ARCH_TIMER_USR_PCT_ACCESS_EN; if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS))
cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
else
cntkctl &= ~ARCH_TIMER_USR_VCT_ACCESS_EN;
arch_timer_set_cntkctl(cntkctl); arch_timer_set_cntkctl(cntkctl);
} }
@ -790,7 +794,7 @@ static void __init arch_timer_mem_init(struct device_node *np)
arch_timer_detect_rate(base, np); arch_timer_detect_rate(base, np);
arch_timer_mem_register(base, irq); arch_timer_mem_register(base, irq);
arch_timer_common_init(); arch_timer_common_init();
get_pct_hook_init(); get_timer_count_hook_init();
} }
CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
arch_timer_mem_init); arch_timer_mem_init);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -980,14 +980,12 @@ failed:
void free_cluster_node(struct lpm_cluster *cluster) void free_cluster_node(struct lpm_cluster *cluster)
{ {
struct list_head *list;
int i; int i;
struct lpm_cluster *cl, *m;
list_for_each(list, &cluster->child) { list_for_each_entry_safe(cl, m, &cluster->child, list) {
struct lpm_cluster *n; list_del(&cl->list);
n = list_entry(list, typeof(*n), list); free_cluster_node(cl);
list_del(list);
free_cluster_node(n);
}; };
if (cluster->cpu) { if (cluster->cpu) {

View File

@ -1124,7 +1124,7 @@ static ssize_t write_logsync(struct file *file, const char __user *buf,
uint64_t seq_num = 0; uint64_t seq_num = 0;
int ret; int ret;
if (copy_from_user(lbuf, buf, sizeof(lbuf))) if (copy_from_user(lbuf, buf, sizeof(lbuf) - 1))
return -EFAULT; return -EFAULT;
ret = sscanf(lbuf, "%llu", &seq_num); ret = sscanf(lbuf, "%llu", &seq_num);

View File

@ -111,6 +111,11 @@ static int32_t msm_actuator_piezo_set_default_focus(
struct msm_camera_i2c_reg_setting reg_setting; struct msm_camera_i2c_reg_setting reg_setting;
CDBG("Enter\n"); CDBG("Enter\n");
if (a_ctrl->i2c_reg_tbl == NULL) {
pr_err("failed. i2c reg tabl is NULL");
return -EFAULT;
}
if (a_ctrl->curr_step_pos != 0) { if (a_ctrl->curr_step_pos != 0) {
a_ctrl->i2c_tbl_index = 0; a_ctrl->i2c_tbl_index = 0;
a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl, a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
@ -593,6 +598,11 @@ static int32_t msm_actuator_piezo_move_focus(
return -EFAULT; return -EFAULT;
} }
if (a_ctrl->i2c_reg_tbl == NULL) {
pr_err("failed. i2c reg tabl is NULL");
return -EFAULT;
}
if (dest_step_position > a_ctrl->total_steps) { if (dest_step_position > a_ctrl->total_steps) {
pr_err("Step pos greater than total steps = %d\n", pr_err("Step pos greater than total steps = %d\n",
dest_step_position); dest_step_position);
@ -655,6 +665,10 @@ static int32_t msm_actuator_move_focus(
pr_err("Invalid direction = %d\n", dir); pr_err("Invalid direction = %d\n", dir);
return -EFAULT; return -EFAULT;
} }
if (a_ctrl->i2c_reg_tbl == NULL) {
pr_err("failed. i2c reg tabl is NULL");
return -EFAULT;
}
if (dest_step_pos > a_ctrl->total_steps) { if (dest_step_pos > a_ctrl->total_steps) {
pr_err("Step pos greater than total steps = %d\n", pr_err("Step pos greater than total steps = %d\n",
dest_step_pos); dest_step_pos);
@ -1218,6 +1232,18 @@ static int32_t msm_actuator_set_position(
return -EFAULT; return -EFAULT;
} }
if (!a_ctrl || !a_ctrl->func_tbl ||
!a_ctrl->func_tbl->actuator_parse_i2c_params ||
!a_ctrl->i2c_reg_tbl) {
pr_err("failed. NULL actuator pointers.");
return -EFAULT;
}
if (a_ctrl->actuator_state != ACT_ENABLE_STATE) {
pr_err("failed. Invalid actuator state.");
return -EFAULT;
}
a_ctrl->i2c_tbl_index = 0; a_ctrl->i2c_tbl_index = 0;
for (index = 0; index < set_pos->number_of_steps; index++) { for (index = 0; index < set_pos->number_of_steps; index++) {
next_lens_position = set_pos->pos[index]; next_lens_position = set_pos->pos[index];
@ -1307,12 +1333,10 @@ static int32_t msm_actuator_set_param(struct msm_actuator_ctrl_t *a_ctrl,
a_ctrl->region_size = set_info->af_tuning_params.region_size; a_ctrl->region_size = set_info->af_tuning_params.region_size;
a_ctrl->pwd_step = set_info->af_tuning_params.pwd_step; a_ctrl->pwd_step = set_info->af_tuning_params.pwd_step;
a_ctrl->total_steps = set_info->af_tuning_params.total_steps;
if (copy_from_user(&a_ctrl->region_params, if (copy_from_user(&a_ctrl->region_params,
(void *)set_info->af_tuning_params.region_params, (void *)set_info->af_tuning_params.region_params,
a_ctrl->region_size * sizeof(struct region_params_t))) { a_ctrl->region_size * sizeof(struct region_params_t))) {
a_ctrl->total_steps = 0;
pr_err("Error copying region_params\n"); pr_err("Error copying region_params\n");
return -EFAULT; return -EFAULT;
} }
@ -1345,6 +1369,7 @@ static int32_t msm_actuator_set_param(struct msm_actuator_ctrl_t *a_ctrl,
(a_ctrl->i2c_reg_tbl != NULL)) { (a_ctrl->i2c_reg_tbl != NULL)) {
kfree(a_ctrl->i2c_reg_tbl); kfree(a_ctrl->i2c_reg_tbl);
} }
a_ctrl->i2c_reg_tbl = NULL; a_ctrl->i2c_reg_tbl = NULL;
a_ctrl->i2c_reg_tbl = a_ctrl->i2c_reg_tbl =
kzalloc(sizeof(struct msm_camera_i2c_reg_array) * kzalloc(sizeof(struct msm_camera_i2c_reg_array) *
@ -1354,6 +1379,8 @@ static int32_t msm_actuator_set_param(struct msm_actuator_ctrl_t *a_ctrl,
return -ENOMEM; return -ENOMEM;
} }
a_ctrl->total_steps = set_info->af_tuning_params.total_steps;
if (copy_from_user(&a_ctrl->reg_tbl, if (copy_from_user(&a_ctrl->reg_tbl,
(void *)set_info->actuator_params.reg_tbl_params, (void *)set_info->actuator_params.reg_tbl_params,
a_ctrl->reg_tbl_size * a_ctrl->reg_tbl_size *

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2015,2017 The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -749,6 +749,21 @@ int32_t msm_sensor_driver_probe(void *setting,
} }
} }
if (strlen(slave_info->sensor_name) >= MAX_SENSOR_NAME ||
strlen(slave_info->eeprom_name) >= MAX_SENSOR_NAME ||
strlen(slave_info->actuator_name) >= MAX_SENSOR_NAME ||
strlen(slave_info->ois_name) >= MAX_SENSOR_NAME) {
pr_err("failed: name len greater than 32.\n");
pr_err("sensor name len:%zu, eeprom name len: %zu.\n",
strlen(slave_info->sensor_name),
strlen(slave_info->eeprom_name));
pr_err("actuator name len: %zu, ois name len:%zu.\n",
strlen(slave_info->actuator_name),
strlen(slave_info->ois_name));
rc = -EINVAL;
goto free_slave_info;
}
/* Print slave info */ /* Print slave info */
CDBG("camera id %d Slave addr 0x%X addr_type %d\n", CDBG("camera id %d Slave addr 0x%X addr_type %d\n",
slave_info->camera_id, slave_info->slave_addr, slave_info->camera_id, slave_info->slave_addr,

View File

@ -161,7 +161,6 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
pr_err("%s: Read buffer Allocation failed rc = %d\n", pr_err("%s: Read buffer Allocation failed rc = %d\n",
__func__, rc); __func__, rc);
rc = -ENOMEM; rc = -ENOMEM;
mutex_unlock(&effects->lock);
goto readbuf_fail; goto readbuf_fail;
} }
atomic_set(&effects->out_count, effects->config.output.num_buf); atomic_set(&effects->out_count, effects->config.output.num_buf);
@ -176,7 +175,6 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
if (rc < 0) { if (rc < 0) {
pr_err("%s: pcm read block config failed\n", __func__); pr_err("%s: pcm read block config failed\n", __func__);
rc = -EINVAL; rc = -EINVAL;
mutex_unlock(&effects->lock);
goto cfg_fail; goto cfg_fail;
} }
pr_debug("%s: dec: sample_rate: %d, num_channels: %d, bit_width: %d\n", pr_debug("%s: dec: sample_rate: %d, num_channels: %d, bit_width: %d\n",
@ -191,7 +189,6 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
pr_err("%s: pcm write format block config failed\n", pr_err("%s: pcm write format block config failed\n",
__func__); __func__);
rc = -EINVAL; rc = -EINVAL;
mutex_unlock(&effects->lock);
goto cfg_fail; goto cfg_fail;
} }
@ -325,6 +322,7 @@ ioctl_fail:
readbuf_fail: readbuf_fail:
q6asm_audio_client_buf_free_contiguous(IN, q6asm_audio_client_buf_free_contiguous(IN,
effects->ac); effects->ac);
mutex_unlock(&effects->lock);
return rc; return rc;
cfg_fail: cfg_fail:
q6asm_audio_client_buf_free_contiguous(IN, q6asm_audio_client_buf_free_contiguous(IN,
@ -332,6 +330,7 @@ cfg_fail:
q6asm_audio_client_buf_free_contiguous(OUT, q6asm_audio_client_buf_free_contiguous(OUT,
effects->ac); effects->ac);
effects->buf_alloc = 0; effects->buf_alloc = 0;
mutex_unlock(&effects->lock);
return rc; return rc;
} }

View File

@ -251,6 +251,33 @@ out:
DEFINE_SIMPLE_ATTRIBUTE(mmc_max_clock_fops, mmc_max_clock_get, DEFINE_SIMPLE_ATTRIBUTE(mmc_max_clock_fops, mmc_max_clock_get,
mmc_max_clock_set, "%llu\n"); mmc_max_clock_set, "%llu\n");
static int mmc_err_state_get(void *data, u64 *val)
{
struct mmc_host *host = data;
if (!host)
return -EINVAL;
*val = host->err_occurred ? 1 : 0;
return 0;
}
static int mmc_err_state_clear(void *data, u64 val)
{
struct mmc_host *host = data;
if (!host)
return -EINVAL;
host->err_occurred = false;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(mmc_err_state, mmc_err_state_get,
mmc_err_state_clear, "%llu\n");
void mmc_add_host_debugfs(struct mmc_host *host) void mmc_add_host_debugfs(struct mmc_host *host)
{ {
struct dentry *root; struct dentry *root;
@ -277,6 +304,10 @@ void mmc_add_host_debugfs(struct mmc_host *host)
&mmc_max_clock_fops)) &mmc_max_clock_fops))
goto err_node; goto err_node;
if (!debugfs_create_file("err_state", S_IRUSR | S_IWUSR, root, host,
&mmc_err_state))
goto err_node;
#ifdef CONFIG_MMC_CLKGATE #ifdef CONFIG_MMC_CLKGATE
if (!debugfs_create_u32("clk_delay", (S_IRUSR | S_IWUSR), if (!debugfs_create_u32("clk_delay", (S_IRUSR | S_IWUSR),
root, &host->clk_delay)) root, &host->clk_delay))

View File

@ -172,6 +172,8 @@ static void sdhci_dumpregs(struct sdhci_host *host)
readl(host->ioaddr + SDHCI_ADMA_ADDRESS_LOW)); readl(host->ioaddr + SDHCI_ADMA_ADDRESS_LOW));
} }
host->mmc->err_occurred = true;
if (host->ops->dump_vendor_regs) if (host->ops->dump_vendor_regs)
host->ops->dump_vendor_regs(host); host->ops->dump_vendor_regs(host);
sdhci_dump_state(host); sdhci_dump_state(host);

View File

@ -1219,12 +1219,13 @@ skip_cudev_init:
"%s%d", rmnet_dev_names[i], "%s%d", rmnet_dev_names[i],
n); n);
if (IS_ERR(dev->devicep)) { if (IS_ERR(dev->devicep)) {
long status = PTR_ERR(dev->devicep);
pr_err("%s: device_create() returned %ld\n", pr_err("%s: device_create() returned %ld\n",
__func__, PTR_ERR(dev->devicep)); __func__, status);
cdev_del(&dev->cdev); cdev_del(&dev->cdev);
free_rmnet_ctrl_udev(dev->cudev); free_rmnet_ctrl_udev(dev->cudev);
kfree(dev); kfree(dev);
return PTR_ERR(dev->devicep); return status;
} }
/*create /sys/class/hsicctl/hsicctlx/modem_wait*/ /*create /sys/class/hsicctl/hsicctlx/modem_wait*/

View File

@ -26,14 +26,17 @@
prefix_type, rowsize, \ prefix_type, rowsize, \
groupsize, buf, len, ascii) groupsize, buf, len, ascii)
#define FW_ADDR_CHECK(ioaddr, val, msg) do { \ static bool wil_fw_addr_check(struct wil6210_priv *wil,
ioaddr = wmi_buffer(wil, val); \ void __iomem **ioaddr, __le32 val,
if (!ioaddr) { \ u32 size, const char *msg)
wil_err_fw(wil, "bad " msg ": 0x%08x\n", \ {
le32_to_cpu(val)); \ *ioaddr = wmi_buffer_block(wil, val, size);
return -EINVAL; \ if (!(*ioaddr)) {
} \ wil_err_fw(wil, "bad %s: 0x%08x\n", msg, le32_to_cpu(val));
} while (0) return false;
}
return true;
}
/** /**
* wil_fw_verify - verify firmware file validity * wil_fw_verify - verify firmware file validity
@ -138,7 +141,8 @@ static int fw_handle_data(struct wil6210_priv *wil, const void *data,
return -EINVAL; return -EINVAL;
} }
FW_ADDR_CHECK(dst, d->addr, "address"); if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address"))
return -EINVAL;
wil_dbg_fw(wil, "write [0x%08x] <== %zu bytes\n", le32_to_cpu(d->addr), wil_dbg_fw(wil, "write [0x%08x] <== %zu bytes\n", le32_to_cpu(d->addr),
s); s);
wil_memcpy_toio_32(dst, d->data, s); wil_memcpy_toio_32(dst, d->data, s);
@ -170,7 +174,8 @@ static int fw_handle_fill(struct wil6210_priv *wil, const void *data,
return -EINVAL; return -EINVAL;
} }
FW_ADDR_CHECK(dst, d->addr, "address"); if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address"))
return -EINVAL;
v = le32_to_cpu(d->value); v = le32_to_cpu(d->value);
wil_dbg_fw(wil, "fill [0x%08x] <== 0x%08x, %zu bytes\n", wil_dbg_fw(wil, "fill [0x%08x] <== 0x%08x, %zu bytes\n",
@ -219,7 +224,8 @@ static int fw_handle_direct_write(struct wil6210_priv *wil, const void *data,
u32 v = le32_to_cpu(block[i].value); u32 v = le32_to_cpu(block[i].value);
u32 x, y; u32 x, y;
FW_ADDR_CHECK(dst, block[i].addr, "address"); if (!wil_fw_addr_check(wil, &dst, block[i].addr, 0, "address"))
return -EINVAL;
x = ioread32(dst); x = ioread32(dst);
y = (x & m) | (v & ~m); y = (x & m) | (v & ~m);
@ -285,10 +291,15 @@ static int fw_handle_gateway_data(struct wil6210_priv *wil, const void *data,
wil_dbg_fw(wil, "gw write record [%3d] blocks, cmd 0x%08x\n", wil_dbg_fw(wil, "gw write record [%3d] blocks, cmd 0x%08x\n",
n, gw_cmd); n, gw_cmd);
FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0,
FW_ADDR_CHECK(gwa_val, d->gateway_value_addr, "gateway_value_addr"); "gateway_addr_addr") ||
FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); !wil_fw_addr_check(wil, &gwa_val, d->gateway_value_addr, 0,
FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); "gateway_value_addr") ||
!wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0,
"gateway_cmd_addr") ||
!wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0,
"gateway_ctrl_address"))
return -EINVAL;
wil_dbg_fw(wil, "gw addresses: addr 0x%08x val 0x%08x" wil_dbg_fw(wil, "gw addresses: addr 0x%08x val 0x%08x"
" cmd 0x%08x ctl 0x%08x\n", " cmd 0x%08x ctl 0x%08x\n",
@ -344,12 +355,19 @@ static int fw_handle_gateway_data4(struct wil6210_priv *wil, const void *data,
wil_dbg_fw(wil, "gw4 write record [%3d] blocks, cmd 0x%08x\n", wil_dbg_fw(wil, "gw4 write record [%3d] blocks, cmd 0x%08x\n",
n, gw_cmd); n, gw_cmd);
FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0,
"gateway_addr_addr"))
return -EINVAL;
for (k = 0; k < ARRAY_SIZE(block->value); k++) for (k = 0; k < ARRAY_SIZE(block->value); k++)
FW_ADDR_CHECK(gwa_val[k], d->gateway_value_addr[k], if (!wil_fw_addr_check(wil, &gwa_val[k],
"gateway_value_addr"); d->gateway_value_addr[k],
FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); 0, "gateway_value_addr"))
FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); return -EINVAL;
if (!wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0,
"gateway_cmd_addr") ||
!wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0,
"gateway_ctrl_address"))
return -EINVAL;
wil_dbg_fw(wil, "gw4 addresses: addr 0x%08x cmd 0x%08x ctl 0x%08x\n", wil_dbg_fw(wil, "gw4 addresses: addr 0x%08x cmd 0x%08x ctl 0x%08x\n",
le32_to_cpu(d->gateway_addr_addr), le32_to_cpu(d->gateway_addr_addr),

View File

@ -677,6 +677,7 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r);
int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); int wil_find_cid(struct wil6210_priv *wil, const u8 *mac);
void wil_set_ethtoolops(struct net_device *ndev); void wil_set_ethtoolops(struct net_device *ndev);
void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr, u32 size);
void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr); void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr);
void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr);
int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,

View File

@ -113,13 +113,15 @@ static u32 wmi_addr_remap(u32 x)
/** /**
* Check address validity for WMI buffer; remap if needed * Check address validity for WMI buffer; remap if needed
* @ptr - internal (linker) fw/ucode address * @ptr - internal (linker) fw/ucode address
* @size - if non zero, validate the block does not
* exceed the device memory (bar)
* *
* Valid buffer should be DWORD aligned * Valid buffer should be DWORD aligned
* *
* return address for accessing buffer from the host; * return address for accessing buffer from the host;
* if buffer is not valid, return NULL. * if buffer is not valid, return NULL.
*/ */
void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_) void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr_, u32 size)
{ {
u32 off; u32 off;
u32 ptr = le32_to_cpu(ptr_); u32 ptr = le32_to_cpu(ptr_);
@ -134,10 +136,17 @@ void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_)
off = HOSTADDR(ptr); off = HOSTADDR(ptr);
if (off > WIL6210_MEM_SIZE - 4) if (off > WIL6210_MEM_SIZE - 4)
return NULL; return NULL;
if (size && ((off + size > WIL6210_MEM_SIZE) || (off + size < off)))
return NULL;
return wil->csr + off; return wil->csr + off;
} }
void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_)
{
return wmi_buffer_block(wil, ptr_, 0);
}
/** /**
* Check address validity * Check address validity
*/ */

View File

@ -187,6 +187,8 @@ static DEFINE_SPINLOCK(reg_spinlock);
#define WCNSS_USR_WLAN_MAC_ADDR (WCNSS_USR_CTRL_MSG_START + 3) #define WCNSS_USR_WLAN_MAC_ADDR (WCNSS_USR_CTRL_MSG_START + 3)
#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" #define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
#define SHOW_MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x\n"
#define WCNSS_USER_MAC_ADDR_LENGTH 18
/* message types */ /* message types */
#define WCNSS_CTRL_MSG_START 0x01000000 #define WCNSS_CTRL_MSG_START 0x01000000
@ -430,23 +432,28 @@ static struct {
static ssize_t wcnss_wlan_macaddr_store(struct device *dev, static ssize_t wcnss_wlan_macaddr_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count) struct device_attribute *attr, const char *buf, size_t count)
{ {
char macAddr[WLAN_MAC_ADDR_SIZE]; int index;
int macAddr[WLAN_MAC_ADDR_SIZE];
if (!penv) if (!penv)
return -ENODEV; return -ENODEV;
pr_debug("%s: Receive MAC Addr From user space: %s\n", __func__, buf); if (WCNSS_USER_MAC_ADDR_LENGTH != strlen(buf)) {
dev_err(dev, "%s: Invalid MAC addr length\n", __func__);
return -EINVAL;
}
if (WLAN_MAC_ADDR_SIZE != sscanf(buf, MAC_ADDRESS_STR, if (WLAN_MAC_ADDR_SIZE != sscanf(buf, MAC_ADDRESS_STR,
(int *)&macAddr[0], (int *)&macAddr[1], &macAddr[0], &macAddr[1], &macAddr[2],
(int *)&macAddr[2], (int *)&macAddr[3], &macAddr[3], &macAddr[4], &macAddr[5])) {
(int *)&macAddr[4], (int *)&macAddr[5])) {
pr_err("%s: Failed to Copy MAC\n", __func__); pr_err("%s: Failed to Copy MAC\n", __func__);
return -EINVAL; return -EINVAL;
} }
memcpy(penv->wlan_nv_macAddr, macAddr, sizeof(penv->wlan_nv_macAddr)); for (index = 0; index < WLAN_MAC_ADDR_SIZE; index++) {
memcpy(&penv->wlan_nv_macAddr[index],
(char *)&macAddr[index], sizeof(char));
}
pr_info("%s: Write MAC Addr:" MAC_ADDRESS_STR "\n", __func__, pr_info("%s: Write MAC Addr:" MAC_ADDRESS_STR "\n", __func__,
penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1], penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1],
@ -462,7 +469,7 @@ static ssize_t wcnss_wlan_macaddr_show(struct device *dev,
if (!penv) if (!penv)
return -ENODEV; return -ENODEV;
return scnprintf(buf, PAGE_SIZE, MAC_ADDRESS_STR, return scnprintf(buf, PAGE_SIZE, SHOW_MAC_ADDRESS_STR,
penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1], penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1],
penv->wlan_nv_macAddr[2], penv->wlan_nv_macAddr[3], penv->wlan_nv_macAddr[2], penv->wlan_nv_macAddr[3],
penv->wlan_nv_macAddr[4], penv->wlan_nv_macAddr[5]); penv->wlan_nv_macAddr[4], penv->wlan_nv_macAddr[5]);

View File

@ -821,8 +821,17 @@ int __ipa_del_hdr(u32 hdr_hdl, bool by_user)
return -EINVAL; return -EINVAL;
} }
if (by_user) if (by_user) {
if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) {
IPADBG("Trying to delete hdr %s offset=%u\n",
entry->name, entry->offset_entry->offset);
if (!entry->offset_entry->offset) {
IPAERR("User cannot delete default header\n");
return -EPERM;
}
}
entry->user_deleted = true; entry->user_deleted = true;
}
if (--entry->ref_cnt) { if (--entry->ref_cnt) {
IPADBG("hdr_hdl %x ref_cnt %d\n", hdr_hdl, entry->ref_cnt); IPADBG("hdr_hdl %x ref_cnt %d\n", hdr_hdl, entry->ref_cnt);
@ -1149,8 +1158,19 @@ int ipa_reset_hdr(void)
&ipa_ctx->hdr_tbl.head_hdr_entry_list, link) { &ipa_ctx->hdr_tbl.head_hdr_entry_list, link) {
/* do not remove the default header */ /* do not remove the default header */
if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) {
continue; IPADBG("Trying to remove hdr %s offset=%u\n",
entry->name, entry->offset_entry->offset);
if (!entry->offset_entry->offset) {
if (entry->is_hdr_proc_ctx) {
mutex_unlock(&ipa_ctx->lock);
WARN_ON(1);
return -EFAULT;
}
IPADBG("skip default header\n");
continue;
}
}
if (ipa_id_find(entry->id) == NULL) { if (ipa_id_find(entry->id) == NULL) {
WARN_ON(1); WARN_ON(1);

View File

@ -27,6 +27,7 @@ struct msm_bus_floor_client_type {
}; };
static struct class *bus_floor_class; static struct class *bus_floor_class;
static DEFINE_RT_MUTEX(msm_bus_floor_vote_lock);
#define MAX_VOTER_NAME (50) #define MAX_VOTER_NAME (50)
#define DEFAULT_NODE_WIDTH (8) #define DEFAULT_NODE_WIDTH (8)
#define DBG_NAME(s) (strnstr(s, "-", 7) + 1) #define DBG_NAME(s) (strnstr(s, "-", 7) + 1)
@ -64,18 +65,22 @@ static ssize_t bus_floor_active_only_store(struct device *dev,
{ {
struct msm_bus_floor_client_type *cl; struct msm_bus_floor_client_type *cl;
rt_mutex_lock(&msm_bus_floor_vote_lock);
cl = dev_get_drvdata(dev); cl = dev_get_drvdata(dev);
if (!cl) { if (!cl) {
pr_err("%s: Can't find cl", __func__); pr_err("%s: Can't find cl", __func__);
rt_mutex_unlock(&msm_bus_floor_vote_lock);
return 0; return 0;
} }
if (sscanf(buf, "%d", &cl->active_only) != 1) { if (sscanf(buf, "%d", &cl->active_only) != 1) {
pr_err("%s:return error", __func__); pr_err("%s:return error", __func__);
rt_mutex_unlock(&msm_bus_floor_vote_lock);
return -EINVAL; return -EINVAL;
} }
rt_mutex_unlock(&msm_bus_floor_vote_lock);
return n; return n;
} }
@ -100,20 +105,24 @@ static ssize_t bus_floor_vote_store(struct device *dev,
struct msm_bus_floor_client_type *cl; struct msm_bus_floor_client_type *cl;
int ret = 0; int ret = 0;
rt_mutex_lock(&msm_bus_floor_vote_lock);
cl = dev_get_drvdata(dev); cl = dev_get_drvdata(dev);
if (!cl) { if (!cl) {
pr_err("%s: Can't find cl", __func__); pr_err("%s: Can't find cl", __func__);
rt_mutex_unlock(&msm_bus_floor_vote_lock);
return 0; return 0;
} }
if (sscanf(buf, "%llu", &cl->cur_vote_hz) != 1) { if (sscanf(buf, "%llu", &cl->cur_vote_hz) != 1) {
pr_err("%s:return error", __func__); pr_err("%s:return error", __func__);
rt_mutex_unlock(&msm_bus_floor_vote_lock);
return -EINVAL; return -EINVAL;
} }
ret = msm_bus_floor_vote_context(dev_name(dev), cl->cur_vote_hz, ret = msm_bus_floor_vote_context(dev_name(dev), cl->cur_vote_hz,
cl->active_only); cl->active_only);
rt_mutex_unlock(&msm_bus_floor_vote_lock);
return n; return n;
} }
@ -126,15 +135,18 @@ static ssize_t bus_floor_vote_store_api(struct device *dev,
char name[10]; char name[10];
u64 vote_khz = 0; u64 vote_khz = 0;
rt_mutex_lock(&msm_bus_floor_vote_lock);
cl = dev_get_drvdata(dev); cl = dev_get_drvdata(dev);
if (!cl) { if (!cl) {
pr_err("%s: Can't find cl", __func__); pr_err("%s: Can't find cl", __func__);
rt_mutex_unlock(&msm_bus_floor_vote_lock);
return 0; return 0;
} }
if (sscanf(buf, "%9s %llu", name, &vote_khz) != 2) { if (sscanf(buf, "%9s %llu", name, &vote_khz) != 2) {
pr_err("%s:return error", __func__); pr_err("%s:return error", __func__);
rt_mutex_unlock(&msm_bus_floor_vote_lock);
return -EINVAL; return -EINVAL;
} }
@ -142,6 +154,7 @@ static ssize_t bus_floor_vote_store_api(struct device *dev,
__func__, name, vote_khz); __func__, name, vote_khz);
ret = msm_bus_floor_vote(name, vote_khz); ret = msm_bus_floor_vote(name, vote_khz);
rt_mutex_unlock(&msm_bus_floor_vote_lock);
return n; return n;
} }

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2015, 2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -707,7 +707,7 @@ static inline u32 bam_get_register_offset(void *base, enum bam_regs reg,
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return SPS_ERROR; return SPS_ERROR;
} }
@ -756,7 +756,7 @@ static inline u32 bam_read_reg(void *base, enum bam_regs reg, u32 param)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return SPS_ERROR; return SPS_ERROR;
} }
@ -767,7 +767,7 @@ static inline u32 bam_read_reg(void *base, enum bam_regs reg, u32 param)
return offset; return offset;
} }
val = ioread32(dev->base + offset); val = ioread32(dev->base + offset);
SPS_DBG(dev, "sps:bam 0x%p(va) offset 0x%x reg 0x%x r_val 0x%x.\n", SPS_DBG(dev, "sps:bam 0x%pK(va) offset 0x%x reg 0x%x r_val 0x%x.\n",
dev->base, offset, reg, val); dev->base, offset, reg, val);
return val; return val;
} }
@ -788,7 +788,7 @@ static inline u32 bam_read_reg_field(void *base, enum bam_regs reg, u32 param,
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return SPS_ERROR; return SPS_ERROR;
} }
@ -802,7 +802,7 @@ static inline u32 bam_read_reg_field(void *base, enum bam_regs reg, u32 param,
val = ioread32(dev->base + offset); val = ioread32(dev->base + offset);
val &= mask; /* clear other bits */ val &= mask; /* clear other bits */
val >>= shift; val >>= shift;
SPS_DBG(dev, "sps:bam 0x%p(va) read reg 0x%x mask 0x%x r_val 0x%x.\n", SPS_DBG(dev, "sps:bam 0x%pK(va) read reg 0x%x mask 0x%x r_val 0x%x.\n",
dev->base, offset, mask, val); dev->base, offset, mask, val);
return val; return val;
} }
@ -823,7 +823,7 @@ static inline void bam_write_reg(void *base, enum bam_regs reg,
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return; return;
} }
@ -834,7 +834,7 @@ static inline void bam_write_reg(void *base, enum bam_regs reg,
return; return;
} }
iowrite32(val, dev->base + offset); iowrite32(val, dev->base + offset);
SPS_DBG(dev, "sps:bam 0x%p(va) write reg 0x%x w_val 0x%x.\n", SPS_DBG(dev, "sps:bam 0x%pK(va) write reg 0x%x w_val 0x%x.\n",
dev->base, offset, val); dev->base, offset, val);
} }
@ -854,7 +854,7 @@ static inline void bam_write_reg_field(void *base, enum bam_regs reg,
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return; return;
} }
@ -870,7 +870,7 @@ static inline void bam_write_reg_field(void *base, enum bam_regs reg,
tmp &= ~mask; /* clear written bits */ tmp &= ~mask; /* clear written bits */
val = tmp | (val << shift); val = tmp | (val << shift);
iowrite32(val, dev->base + offset); iowrite32(val, dev->base + offset);
SPS_DBG(dev, "sps:bam 0x%p(va) write reg 0x%x w_val 0x%x.\n", SPS_DBG(dev, "sps:bam 0x%pK(va) write reg 0x%x w_val 0x%x.\n",
dev->base, offset, val); dev->base, offset, val);
} }
@ -888,28 +888,28 @@ int bam_init(void *base, u32 ee,
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return SPS_ERROR; return SPS_ERROR;
} }
SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).ee=%d.", __func__, SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).ee=%d.", __func__,
BAM_ID(dev), dev->base, ee); BAM_ID(dev), dev->base, ee);
ver = bam_read_reg_field(base, REVISION, 0, BAM_REVISION); ver = bam_read_reg_field(base, REVISION, 0, BAM_REVISION);
if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) { if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) {
SPS_ERR(dev, "sps:bam 0x%p(va) Invalid BAM REVISION 0x%x.\n", SPS_ERR(dev, "sps:bam 0x%pK(va) Invalid BAM REVISION 0x%x.\n",
dev->base, ver); dev->base, ver);
return -ENODEV; return -ENODEV;
} else } else
SPS_DBG(dev, "sps:REVISION of BAM 0x%p is 0x%x.\n", SPS_DBG(dev, "sps:REVISION of BAM 0x%pK is 0x%x.\n",
dev->base, ver); dev->base, ver);
if (summing_threshold == 0) { if (summing_threshold == 0) {
summing_threshold = 4; summing_threshold = 4;
SPS_ERR(dev, SPS_ERR(dev,
"sps:bam 0x%p(va) summing_threshold is zero,use default 4.\n", "sps:bam 0x%pK(va) summing_threshold is zero,use default 4.\n",
dev->base); dev->base);
} }
@ -1009,12 +1009,12 @@ int bam_security_init(void *base, u32 ee, u32 vmid, u32 pipe_mask)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return SPS_ERROR; return SPS_ERROR;
} }
SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).", __func__, SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).", __func__,
BAM_ID(dev), dev->base); BAM_ID(dev), dev->base);
/* /*
@ -1025,14 +1025,14 @@ int bam_security_init(void *base, u32 ee, u32 vmid, u32 pipe_mask)
num_pipes = bam_read_reg_field(base, NUM_PIPES, 0, BAM_NUM_PIPES); num_pipes = bam_read_reg_field(base, NUM_PIPES, 0, BAM_NUM_PIPES);
if (version < 3 || version > 0x1F) { if (version < 3 || version > 0x1F) {
SPS_ERR(dev, SPS_ERR(dev,
"sps:bam 0x%p(va) security is not supported for this BAM version 0x%x.\n", "sps:bam 0x%pK(va) security is not supported for this BAM version 0x%x.\n",
dev->base, version); dev->base, version);
return -ENODEV; return -ENODEV;
} }
if (num_pipes > BAM_MAX_PIPES) { if (num_pipes > BAM_MAX_PIPES) {
SPS_ERR(dev, SPS_ERR(dev,
"sps:bam 0x%p(va) the number of pipes is more than the maximum number allowed.\n", "sps:bam 0x%pK(va) the number of pipes is more than the maximum number allowed.\n",
dev->base); dev->base);
return -ENODEV; return -ENODEV;
} }
@ -1080,12 +1080,12 @@ int bam_check(void *base, u32 *version, u32 ee, u32 *num_pipes)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return SPS_ERROR; return SPS_ERROR;
} }
SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).", SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).",
__func__, BAM_ID(dev), dev->base); __func__, BAM_ID(dev), dev->base);
if (!enhd_pipe) if (!enhd_pipe)
@ -1094,7 +1094,7 @@ int bam_check(void *base, u32 *version, u32 ee, u32 *num_pipes)
enabled = bam_get_pipe_attr(base, ee, true); enabled = bam_get_pipe_attr(base, ee, true);
if (!enabled) { if (!enabled) {
SPS_ERR(dev, "sps:%s:bam 0x%p(va) is not enabled.\n", SPS_ERR(dev, "sps:%s:bam 0x%pK(va) is not enabled.\n",
__func__, dev->base); __func__, dev->base);
return -ENODEV; return -ENODEV;
} }
@ -1110,7 +1110,7 @@ int bam_check(void *base, u32 *version, u32 ee, u32 *num_pipes)
/* Check BAM version */ /* Check BAM version */
if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) { if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) {
SPS_ERR(dev, "sps:%s:bam 0x%p(va) Invalid BAM version 0x%x.\n", SPS_ERR(dev, "sps:%s:bam 0x%pK(va) Invalid BAM version 0x%x.\n",
__func__, dev->base, ver); __func__, dev->base, ver);
return -ENODEV; return -ENODEV;
} }
@ -1127,11 +1127,11 @@ void bam_exit(void *base, u32 ee)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return; return;
} }
SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).ee=%d.", SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).ee=%d.",
__func__, BAM_ID(dev), dev->base, ee); __func__, BAM_ID(dev), dev->base, ee);
bam_write_reg_field(base, IRQ_SRCS_MSK_EE, ee, BAM_IRQ, 0); bam_write_reg_field(base, IRQ_SRCS_MSK_EE, ee, BAM_IRQ, 0);
@ -1155,7 +1155,7 @@ void bam_output_register_content(void *base, u32 ee)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return; return;
} }
@ -1166,7 +1166,7 @@ void bam_output_register_content(void *base, u32 ee)
num_pipes = bam_read_reg_field(base, NUM_PIPES, 0, num_pipes = bam_read_reg_field(base, NUM_PIPES, 0,
BAM_NUM_PIPES); BAM_NUM_PIPES);
SPS_INFO(dev, "sps:bam %pa 0x%p(va) has %d pipes.", SPS_INFO(dev, "sps:bam %pa 0x%pK(va) has %d pipes.",
BAM_ID(dev), dev->base, num_pipes); BAM_ID(dev), dev->base, num_pipes);
pipe_attr = enhd_pipe ? pipe_attr = enhd_pipe ?
@ -1193,7 +1193,7 @@ u32 bam_check_irq_source(void *base, u32 ee, u32 mask,
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return SPS_ERROR; return SPS_ERROR;
} }
@ -1205,13 +1205,13 @@ u32 bam_check_irq_source(void *base, u32 ee, u32 mask,
status = bam_read_reg(base, IRQ_STTS, 0); status = bam_read_reg(base, IRQ_STTS, 0);
if (status & IRQ_STTS_BAM_ERROR_IRQ) { if (status & IRQ_STTS_BAM_ERROR_IRQ) {
SPS_ERR(dev, "sps:bam %pa 0x%p(va);bam irq status=" SPS_ERR(dev, "sps:bam %pa 0x%pK(va);bam irq status="
"0x%x.\nsps: BAM_ERROR_IRQ\n", "0x%x.\nsps: BAM_ERROR_IRQ\n",
BAM_ID(dev), dev->base, status); BAM_ID(dev), dev->base, status);
bam_output_register_content(base, ee); bam_output_register_content(base, ee);
*cb_case = SPS_CALLBACK_BAM_ERROR_IRQ; *cb_case = SPS_CALLBACK_BAM_ERROR_IRQ;
} else if (status & IRQ_STTS_BAM_HRESP_ERR_IRQ) { } else if (status & IRQ_STTS_BAM_HRESP_ERR_IRQ) {
SPS_ERR(dev, "sps:bam %pa 0x%p(va);bam irq status=" SPS_ERR(dev, "sps:bam %pa 0x%pK(va);bam irq status="
"0x%x.\nsps: BAM_HRESP_ERR_IRQ\n", "0x%x.\nsps: BAM_HRESP_ERR_IRQ\n",
BAM_ID(dev), dev->base, status); BAM_ID(dev), dev->base, status);
bam_output_register_content(base, ee); bam_output_register_content(base, ee);
@ -1219,13 +1219,13 @@ u32 bam_check_irq_source(void *base, u32 ee, u32 mask,
#ifdef CONFIG_SPS_SUPPORT_NDP_BAM #ifdef CONFIG_SPS_SUPPORT_NDP_BAM
} else if (status & IRQ_STTS_BAM_TIMER_IRQ) { } else if (status & IRQ_STTS_BAM_TIMER_IRQ) {
SPS_DBG1(dev, SPS_DBG1(dev,
"sps:bam 0x%p(va);receive BAM_TIMER_IRQ\n", "sps:bam 0x%pK(va);receive BAM_TIMER_IRQ\n",
dev->base); dev->base);
*cb_case = SPS_CALLBACK_BAM_TIMER_IRQ; *cb_case = SPS_CALLBACK_BAM_TIMER_IRQ;
#endif #endif
} else } else
SPS_INFO(dev, SPS_INFO(dev,
"sps:bam %pa 0x%p(va);bam irq status=0x%x.\n", "sps:bam %pa 0x%pK(va);bam irq status=0x%x.\n",
BAM_ID(dev), dev->base, status); BAM_ID(dev), dev->base, status);
bam_write_reg(base, IRQ_CLR, 0, status); bam_write_reg(base, IRQ_CLR, 0, status);
@ -1243,11 +1243,11 @@ void bam_pipe_reset(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return; return;
} }
SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe); __func__, BAM_ID(dev), dev->base, pipe);
bam_write_reg(base, P_RST, pipe, 1); bam_write_reg(base, P_RST, pipe, 1);
@ -1264,11 +1264,11 @@ void bam_disable_pipe(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return; return;
} }
SPS_DBG2(dev, "sps:%s:bam=0x%p(va).pipe=%d.", __func__, base, pipe); SPS_DBG2(dev, "sps:%s:bam=0x%pK(va).pipe=%d.", __func__, base, pipe);
bam_write_reg_field(base, P_CTRL, pipe, P_EN, 0); bam_write_reg_field(base, P_CTRL, pipe, P_EN, 0);
wmb(); /* ensure pipe is disabled */ wmb(); /* ensure pipe is disabled */
} }
@ -1281,20 +1281,20 @@ bool bam_pipe_check_zlt(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return false; return false;
} }
if (bam_read_reg_field(base, P_HALT, pipe, P_HALT_P_LAST_DESC_ZLT)) { if (bam_read_reg_field(base, P_HALT, pipe, P_HALT_P_LAST_DESC_ZLT)) {
SPS_DBG(dev, SPS_DBG(dev,
"sps:%s:bam=0x%p(va).pipe=%d: the last desc is ZLT.", "sps:%s:bam=0x%pK(va).pipe=%d: the last desc is ZLT.",
__func__, base, pipe); __func__, base, pipe);
return true; return true;
} }
SPS_DBG(dev, SPS_DBG(dev,
"sps:%s:bam=0x%p(va).pipe=%d: the last desc is not ZLT.", "sps:%s:bam=0x%pK(va).pipe=%d: the last desc is not ZLT.",
__func__, base, pipe); __func__, base, pipe);
return false; return false;
} }
@ -1307,20 +1307,20 @@ bool bam_pipe_check_pipe_empty(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return false; return false;
} }
if (bam_read_reg_field(base, P_HALT, pipe, P_HALT_P_PIPE_EMPTY)) { if (bam_read_reg_field(base, P_HALT, pipe, P_HALT_P_PIPE_EMPTY)) {
SPS_DBG(dev, SPS_DBG(dev,
"sps:%s:bam=0x%p(va).pipe=%d: desc FIFO is empty.", "sps:%s:bam=0x%pK(va).pipe=%d: desc FIFO is empty.",
__func__, base, pipe); __func__, base, pipe);
return true; return true;
} }
SPS_DBG(dev, SPS_DBG(dev,
"sps:%s:bam=0x%p(va).pipe=%d: desc FIFO is not empty.", "sps:%s:bam=0x%pK(va).pipe=%d: desc FIFO is not empty.",
__func__, base, pipe); __func__, base, pipe);
return false; return false;
} }
@ -1334,11 +1334,11 @@ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param,
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return SPS_ERROR; return SPS_ERROR;
} }
SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe); __func__, BAM_ID(dev), dev->base, pipe);
/* Reset the BAM pipe */ /* Reset the BAM pipe */
@ -1372,7 +1372,7 @@ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param,
bam_write_reg_field(base, P_CTRL, pipe, P_LOCK_GROUP, bam_write_reg_field(base, P_CTRL, pipe, P_LOCK_GROUP,
param->lock_group); param->lock_group);
SPS_DBG(dev, "sps:bam=0x%p(va).pipe=%d.lock_group=%d.\n", SPS_DBG(dev, "sps:bam=0x%pK(va).pipe=%d.lock_group=%d.\n",
dev->base, pipe, param->lock_group); dev->base, pipe, param->lock_group);
#endif #endif
@ -1388,7 +1388,7 @@ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param,
bam_write_reg(base, P_EVNT_DEST_ADDR, pipe, peer_dest_addr); bam_write_reg(base, P_EVNT_DEST_ADDR, pipe, peer_dest_addr);
SPS_DBG2(dev, "sps:bam=0x%p(va).pipe=%d.peer_bam=0x%x." SPS_DBG2(dev, "sps:bam=0x%pK(va).pipe=%d.peer_bam=0x%x."
"peer_pipe=%d.\n", "peer_pipe=%d.\n",
dev->base, pipe, dev->base, pipe,
(u32) param->peer_phys_addr, (u32) param->peer_phys_addr,
@ -1424,11 +1424,11 @@ void bam_pipe_exit(void *base, u32 pipe, u32 ee)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return; return;
} }
SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe); __func__, BAM_ID(dev), dev->base, pipe);
bam_write_reg(base, P_IRQ_EN, pipe, 0); bam_write_reg(base, P_IRQ_EN, pipe, 0);
@ -1449,15 +1449,15 @@ void bam_pipe_enable(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return; return;
} }
SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe); __func__, BAM_ID(dev), dev->base, pipe);
if (bam_read_reg_field(base, P_CTRL, pipe, P_EN)) if (bam_read_reg_field(base, P_CTRL, pipe, P_EN))
SPS_DBG2(dev, "sps:bam=0x%p(va).pipe=%d is already enabled.\n", SPS_DBG2(dev, "sps:bam=0x%pK(va).pipe=%d is already enabled.\n",
dev->base, pipe); dev->base, pipe);
else else
bam_write_reg_field(base, P_CTRL, pipe, P_EN, 1); bam_write_reg_field(base, P_CTRL, pipe, P_EN, 1);
@ -1472,11 +1472,11 @@ void bam_pipe_disable(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return; return;
} }
SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe); __func__, BAM_ID(dev), dev->base, pipe);
bam_write_reg_field(base, P_CTRL, pipe, P_EN, 0); bam_write_reg_field(base, P_CTRL, pipe, P_EN, 0);
@ -1501,11 +1501,11 @@ void bam_pipe_set_irq(void *base, u32 pipe, enum bam_enable irq_en,
struct sps_bam *dev = to_sps_bam_dev(base); struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) { if ((dev == NULL) || (&dev->base != base)) {
SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base); __func__, base);
return; return;
} }
SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe); __func__, BAM_ID(dev), dev->base, pipe);
if (src_mask & BAM_PIPE_IRQ_RST_ERROR) { if (src_mask & BAM_PIPE_IRQ_RST_ERROR) {
if (enhd_pipe) if (enhd_pipe)

View File

@ -912,7 +912,7 @@ static int sps_device_init(void)
goto exit_err; goto exit_err;
} }
SPS_DBG3(sps, "sps:bamdma_bam.phys=%pa.virt=0x%p.", SPS_DBG3(sps, "sps:bamdma_bam.phys=%pa.virt=0x%pK.",
&bamdma_props.phys_addr, &bamdma_props.phys_addr,
bamdma_props.virt_addr); bamdma_props.virt_addr);
@ -927,7 +927,7 @@ static int sps_device_init(void)
goto exit_err; goto exit_err;
} }
SPS_DBG3(sps, "sps:bamdma_dma.phys=%pa.virt=0x%p.", SPS_DBG3(sps, "sps:bamdma_dma.phys=%pa.virt=0x%pK.",
&bamdma_props.periph_phys_addr, &bamdma_props.periph_phys_addr,
bamdma_props.periph_virt_addr); bamdma_props.periph_virt_addr);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2015, 2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -495,12 +495,12 @@ int sps_bam_enable(struct sps_bam *dev)
if (dev->props.logging_number > 0) if (dev->props.logging_number > 0)
dev->props.logging_number--; dev->props.logging_number--;
SPS_INFO(dev, SPS_INFO(dev,
"sps:BAM %pa (va:0x%p) enabled: ver:0x%x, number of pipes:%d\n", "sps:BAM %pa (va:0x%pK) enabled: ver:0x%x, number of pipes:%d\n",
BAM_ID(dev), dev->base, dev->version, BAM_ID(dev), dev->base, dev->version,
dev->props.num_pipes); dev->props.num_pipes);
} else } else
SPS_DBG3(dev, SPS_DBG3(dev,
"sps:BAM %pa (va:0x%p) enabled: ver:0x%x, number of pipes:%d\n", "sps:BAM %pa (va:0x%pK) enabled: ver:0x%x, number of pipes:%d\n",
BAM_ID(dev), dev->base, dev->version, BAM_ID(dev), dev->base, dev->version,
dev->props.num_pipes); dev->props.num_pipes);
@ -2075,7 +2075,7 @@ int sps_bam_pipe_get_event(struct sps_bam *dev,
if (pipe->sys.no_queue) { if (pipe->sys.no_queue) {
SPS_ERR(dev, SPS_ERR(dev,
"sps:Invalid connection for event: BAM %pa pipe %d context 0x%p\n", "sps:Invalid connection for event: BAM %pa pipe %d context 0x%pK\n",
BAM_ID(dev), pipe_index, pipe); BAM_ID(dev), pipe_index, pipe);
notify->event_id = SPS_EVENT_INVALID; notify->event_id = SPS_EVENT_INVALID;
return SPS_ERROR; return SPS_ERROR;

View File

@ -1,4 +1,5 @@
/* Copyright (c) 2011-2013, 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2013, 2015, 2017, The Linux Foundation.
* All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -129,7 +130,7 @@ int sps_mem_init(phys_addr_t pipemem_phys_base, u32 pipemem_size)
iomem_offset = 0; iomem_offset = 0;
SPS_DBG(sps, SPS_DBG(sps,
"sps:sps_mem_init.iomem_phys=%pa,iomem_virt=0x%p.", "sps:sps_mem_init.iomem_phys=%pa,iomem_virt=0x%pK.",
&iomem_phys, iomem_virt); &iomem_phys, iomem_virt);
} }

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2015, 2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -723,8 +723,7 @@ int sps_rm_state_change(struct sps_pipe *pipe, u32 state)
state == SPS_STATE_ALLOCATE) { state == SPS_STATE_ALLOCATE) {
if (sps_rm_alloc(pipe)) { if (sps_rm_alloc(pipe)) {
SPS_ERR(pipe->bam, SPS_ERR(pipe->bam,
"sps:Fail to allocate resource for" "sps:Fail to allocate resource for BAM 0x%pK pipe %d.\n",
" BAM 0x%p pipe %d.\n",
pipe->bam, pipe->pipe_index); pipe->bam, pipe->pipe_index);
return SPS_ERROR; return SPS_ERROR;
} }
@ -745,7 +744,7 @@ int sps_rm_state_change(struct sps_pipe *pipe, u32 state)
result = sps_bam_pipe_connect(pipe, &params); result = sps_bam_pipe_connect(pipe, &params);
if (result) { if (result) {
SPS_ERR(pipe->bam, SPS_ERR(pipe->bam,
"sps:Failed to connect BAM 0x%p pipe %d", "sps:Failed to connect BAM 0x%pK pipe %d",
pipe->bam, pipe->pipe_index); pipe->bam, pipe->pipe_index);
return SPS_ERROR; return SPS_ERROR;
} }

View File

@ -113,7 +113,8 @@ static ssize_t ufs_qcom_dbg_testbus_cfg_write(struct file *file,
unsigned long flags; unsigned long flags;
struct ufs_hba *hba = host->hba; struct ufs_hba *hba = host->hba;
cnt = simple_write_to_buffer(configuration, TESTBUS_CFG_BUFF_LINE_SIZE, cnt = simple_write_to_buffer(configuration,
TESTBUS_CFG_BUFF_LINE_SIZE - 1,
&buff_pos, ubuf, cnt); &buff_pos, ubuf, cnt);
if (cnt < 0) { if (cnt < 0) {
dev_err(host->hba->dev, "%s: failed to read user data\n", dev_err(host->hba->dev, "%s: failed to read user data\n",

View File

@ -99,23 +99,23 @@ static ssize_t rsc_ops_write(struct file *fp, const char __user *user_buffer,
cmp += pos; cmp += pos;
if (sscanf(cmp, "%5s %n", key_str, &pos) != 1) { if (sscanf(cmp, "%5s %n", key_str, &pos) != 1) {
pr_err("Invalid number of arguments passed\n"); pr_err("Invalid number of arguments passed\n");
goto err; goto err_request;
} }
if (strlen(key_str) > 4) { if (strlen(key_str) > 4) {
pr_err("Key value cannot be more than 4 charecters"); pr_err("Key value cannot be more than 4 charecters");
goto err; goto err_request;
} }
key = string_to_uint(key_str); key = string_to_uint(key_str);
if (!key) { if (!key) {
pr_err("Key values entered incorrectly\n"); pr_err("Key values entered incorrectly\n");
goto err; goto err_request;
} }
cmp += pos; cmp += pos;
if (sscanf(cmp, "%u %n", &data, &pos) != 1) { if (sscanf(cmp, "%u %n", &data, &pos) != 1) {
pr_err("Invalid number of arguments passed\n"); pr_err("Invalid number of arguments passed\n");
goto err; goto err_request;
} }
if (msm_rpm_add_kvp_data(req, key, if (msm_rpm_add_kvp_data(req, key,

View File

@ -974,6 +974,7 @@ err_subsys:
destroy_ramdump_device(d->ramdump_dev); destroy_ramdump_device(d->ramdump_dev);
err_ramdump: err_ramdump:
pil_desc_release(&d->desc); pil_desc_release(&d->desc);
platform_set_drvdata(pdev, NULL);
return rc; return rc;
} }

View File

@ -1524,6 +1524,11 @@ static int ion_sync_for_device(struct ion_client *client, int fd)
} }
buffer = dmabuf->priv; buffer = dmabuf->priv;
if ((buffer->flags & ION_FLAG_SECURE) || (get_secure_vmid(buffer->flags) > 0)) {
pr_err("%s: cannot sync a secure dmabuf\n", __func__);
dma_buf_put(dmabuf);
return -EINVAL;
}
dma_sync_sg_for_device(NULL, buffer->sg_table->sgl, dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
buffer->sg_table->nents, DMA_BIDIRECTIONAL); buffer->sg_table->nents, DMA_BIDIRECTIONAL);
dma_buf_put(dmabuf); dma_buf_put(dmabuf);

View File

@ -1,6 +1,6 @@
/* /*
* *
* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2015, 2018 The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -40,7 +40,7 @@ static bool is_cp_flag_present(unsigned long flags)
ION_FLAG_CP_CAMERA); ION_FLAG_CP_CAMERA);
} }
static int get_secure_vmid(unsigned long flags) int get_secure_vmid(unsigned long flags)
{ {
if (flags & ION_FLAG_CP_TOUCH) if (flags & ION_FLAG_CP_TOUCH)
return VMID_CP_TOUCH; return VMID_CP_TOUCH;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2014,2016 The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2014,2016,2018 The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -286,7 +286,7 @@ int ion_do_cache_op(struct ion_client *client, struct ion_handle *handle,
if (!ION_IS_CACHED(flags)) if (!ION_IS_CACHED(flags))
return 0; return 0;
if (flags & ION_FLAG_SECURE) if ((flags & ION_FLAG_SECURE) || (get_secure_vmid(flags) > 0))
return 0; return 0;
table = ion_sg_table(client, handle); table = ion_sg_table(client, handle);
@ -737,11 +737,11 @@ long msm_ion_custom_ioctl(struct ion_client *client,
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
start = (unsigned long) data.flush_data.vaddr; start = (unsigned long)data.flush_data.vaddr +
end = (unsigned long) data.flush_data.vaddr data.flush_data.offset;
+ data.flush_data.length; end = start + data.flush_data.length;
if (start && check_vaddr_bounds(start, end)) { if (check_vaddr_bounds(start, end)) {
pr_err("%s: virtual address %pK is out of bounds\n", pr_err("%s: virtual address %pK is out of bounds\n",
__func__, data.flush_data.vaddr); __func__, data.flush_data.vaddr);
ret = -EINVAL; ret = -EINVAL;

View File

@ -2,7 +2,7 @@
* drivers/gpu/ion/ion_priv.h * drivers/gpu/ion/ion_priv.h
* *
* Copyright (C) 2011 Google, Inc. * Copyright (C) 2011 Google, Inc.
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2014, 2018 The Linux Foundation. All rights reserved.
* *
* This software is licensed under the terms of the GNU General Public * This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and * License version 2, as published by the Free Software Foundation, and
@ -117,6 +117,7 @@ int ion_heap_allow_heap_secure(enum ion_heap_type type);
int ion_heap_allow_handle_secure(enum ion_heap_type type); int ion_heap_allow_handle_secure(enum ion_heap_type type);
int get_secure_vmid(unsigned long flags);
/** /**
* ion_create_chunked_sg_table - helper function to create sg table * ion_create_chunked_sg_table - helper function to create sg table
* with specified chunk size * with specified chunk size

View File

@ -2179,6 +2179,8 @@ extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
extern qsize_t *ext4_get_reserved_space(struct inode *inode); extern qsize_t *ext4_get_reserved_space(struct inode *inode);
extern void ext4_da_update_reserve_space(struct inode *inode, extern void ext4_da_update_reserve_space(struct inode *inode,
int used, int quota_claim); int used, int quota_claim);
extern int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk,
ext4_fsblk_t pblk, ext4_lblk_t len);
/* indirect.c */ /* indirect.c */
extern int ext4_ind_map_blocks(handle_t *handle, struct inode *inode, extern int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,

View File

@ -3027,16 +3027,12 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
{ {
ext4_fsblk_t ee_pblock; ext4_fsblk_t ee_pblock;
unsigned int ee_len; unsigned int ee_len;
int ret;
ee_len = ext4_ext_get_actual_len(ex); ee_len = ext4_ext_get_actual_len(ex);
ee_pblock = ext4_ext_pblock(ex); ee_pblock = ext4_ext_pblock(ex);
ret = sb_issue_zeroout(inode->i_sb, ee_pblock, ee_len, GFP_NOFS); return ext4_issue_zeroout(inode, le32_to_cpu(ex->ee_block), ee_pblock,
if (ret > 0) ee_len);
ret = 0;
return ret;
} }
/* /*

View File

@ -426,6 +426,18 @@ static int __check_block_validity(struct inode *inode, const char *func,
return 0; return 0;
} }
int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk, ext4_fsblk_t pblk,
ext4_lblk_t len)
{
int ret;
ret = sb_issue_zeroout(inode->i_sb, pblk, len, GFP_NOFS);
if (ret > 0)
ret = 0;
return ret;
}
#define check_block_validity(inode, map) \ #define check_block_validity(inode, map) \
__check_block_validity((inode), __func__, __LINE__, (map)) __check_block_validity((inode), __func__, __LINE__, (map))

View File

@ -473,6 +473,8 @@ struct mmc_host {
struct dentry *debugfs_root; struct dentry *debugfs_root;
bool err_occurred;
struct mmc_async_req *areq; /* active async req */ struct mmc_async_req *areq; /* active async req */
struct mmc_context_info context_info; /* async synchronization info */ struct mmc_context_info context_info; /* async synchronization info */

View File

@ -102,7 +102,7 @@ struct snd_pcm_ops {
#define SNDRV_PCM_IOCTL1_TRUE ((void *)1) #define SNDRV_PCM_IOCTL1_TRUE ((void *)1)
#define SNDRV_PCM_IOCTL1_RESET 0 #define SNDRV_PCM_IOCTL1_RESET 0
#define SNDRV_PCM_IOCTL1_INFO 1 /* 1 is absent slot. */
#define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2 #define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2
#define SNDRV_PCM_IOCTL1_GSTATE 3 #define SNDRV_PCM_IOCTL1_GSTATE 3
#define SNDRV_PCM_IOCTL1_FIFO_SIZE 4 #define SNDRV_PCM_IOCTL1_FIFO_SIZE 4
@ -399,6 +399,7 @@ struct snd_pcm_substream {
struct snd_pcm_ops *ops; struct snd_pcm_ops *ops;
/* -- runtime information -- */ /* -- runtime information -- */
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
spinlock_t runtime_lock;
/* -- timer section -- */ /* -- timer section -- */
struct snd_timer *timer; /* timer */ struct snd_timer *timer; /* timer */
unsigned timer_running: 1; /* time is running */ unsigned timer_running: 1; /* time is running */

View File

@ -491,6 +491,7 @@ int do_settimeofday(const struct timespec *tv)
struct timekeeper *tk = &timekeeper; struct timekeeper *tk = &timekeeper;
struct timespec ts_delta, xt; struct timespec ts_delta, xt;
unsigned long flags; unsigned long flags;
int ret = 0;
if (!timespec_valid_strict(tv)) if (!timespec_valid_strict(tv))
return -EINVAL; return -EINVAL;
@ -504,10 +505,15 @@ int do_settimeofday(const struct timespec *tv)
ts_delta.tv_sec = tv->tv_sec - xt.tv_sec; ts_delta.tv_sec = tv->tv_sec - xt.tv_sec;
ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec; ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec;
if (timespec_compare(&tk->wall_to_monotonic, &ts_delta) > 0) {
ret = -EINVAL;
goto out;
}
tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, ts_delta)); tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, ts_delta));
tk_set_xtime(tk, tv); tk_set_xtime(tk, tv);
out:
timekeeping_update(tk, true, true); timekeeping_update(tk, true, true);
write_seqcount_end(&timekeeper_seq); write_seqcount_end(&timekeeper_seq);
@ -516,7 +522,7 @@ int do_settimeofday(const struct timespec *tv)
/* signal hrtimers about time change */ /* signal hrtimers about time change */
clock_was_set(); clock_was_set();
return 0; return ret;
} }
EXPORT_SYMBOL(do_settimeofday); EXPORT_SYMBOL(do_settimeofday);
@ -543,7 +549,8 @@ int timekeeping_inject_offset(struct timespec *ts)
/* Make sure the proposed value is valid */ /* Make sure the proposed value is valid */
tmp = timespec_add(tk_xtime(tk), *ts); tmp = timespec_add(tk_xtime(tk), *ts);
if (!timespec_valid_strict(&tmp)) { if (timespec_compare(&tk->wall_to_monotonic, ts) > 0 ||
!timespec_valid_strict(&tmp)) {
ret = -EINVAL; ret = -EINVAL;
goto error; goto error;
} }

View File

@ -395,9 +395,8 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
greh = (const struct gre_base_hdr *)(skb->data + offset); greh = (const struct gre_base_hdr *)(skb->data + offset);
key = key_off ? *(__be32 *)(skb->data + key_off) : 0; key = key_off ? *(__be32 *)(skb->data + key_off) : 0;
t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr, t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,key, greh->protocol);
key, greh->protocol); if (!t)
if (t == NULL)
return; return;
switch (type) { switch (type) {

View File

@ -698,6 +698,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
} }
substream->group = &substream->self_group; substream->group = &substream->self_group;
spin_lock_init(&substream->self_group.lock); spin_lock_init(&substream->self_group.lock);
spin_lock_init(&substream->runtime_lock);
INIT_LIST_HEAD(&substream->self_group.substreams); INIT_LIST_HEAD(&substream->self_group.substreams);
list_add_tail(&substream->link_list, &substream->self_group.substreams); list_add_tail(&substream->link_list, &substream->self_group.substreams);
atomic_set(&substream->mmap_count, 0); atomic_set(&substream->mmap_count, 0);
@ -994,9 +995,11 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
void snd_pcm_detach_substream(struct snd_pcm_substream *substream) void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
{ {
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
unsigned long flags = 0;
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return; return;
spin_lock_irqsave(&substream->runtime_lock, flags);
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->private_free != NULL) if (runtime->private_free != NULL)
runtime->private_free(runtime); runtime->private_free(runtime);
@ -1013,6 +1016,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
put_pid(substream->pid); put_pid(substream->pid);
substream->pid = NULL; substream->pid = NULL;
substream->pstr->substream_opened--; substream->pstr->substream_opened--;
spin_unlock_irqrestore(&substream->runtime_lock, flags);
} }
static ssize_t show_pcm_class(struct device *dev, static ssize_t show_pcm_class(struct device *dev,

View File

@ -1830,8 +1830,6 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg) unsigned int cmd, void *arg)
{ {
switch (cmd) { switch (cmd) {
case SNDRV_PCM_IOCTL1_INFO:
return 0;
case SNDRV_PCM_IOCTL1_RESET: case SNDRV_PCM_IOCTL1_RESET:
return snd_pcm_lib_ioctl_reset(substream, arg); return snd_pcm_lib_ioctl_reset(substream, arg);
case SNDRV_PCM_IOCTL1_CHANNEL_INFO: case SNDRV_PCM_IOCTL1_CHANNEL_INFO:

View File

@ -96,7 +96,6 @@ static inline void snd_leave_user(mm_segment_t fs)
int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
{ {
struct snd_pcm_runtime *runtime;
struct snd_pcm *pcm = substream->pcm; struct snd_pcm *pcm = substream->pcm;
struct snd_pcm_str *pstr = substream->pstr; struct snd_pcm_str *pstr = substream->pstr;
@ -112,12 +111,7 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
info->subdevices_count = pstr->substream_count; info->subdevices_count = pstr->substream_count;
info->subdevices_avail = pstr->substream_count - pstr->substream_opened; info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
strlcpy(info->subname, substream->name, sizeof(info->subname)); strlcpy(info->subname, substream->name, sizeof(info->subname));
runtime = substream->runtime;
/* AB: FIXME!!! This is definitely nonsense */
if (runtime) {
info->sync = runtime->sync;
substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_INFO, info);
}
return 0; return 0;
} }

View File

@ -63,9 +63,16 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream)
static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer) static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer)
{ {
struct snd_pcm_substream *substream; struct snd_pcm_substream *substream;
unsigned long ret = 0, flags = 0;
substream = timer->private_data; substream = timer->private_data;
return substream->runtime ? substream->runtime->timer_resolution : 0; spin_lock_irqsave(&substream->runtime_lock, flags);
if (substream->runtime)
ret = substream->runtime->timer_resolution;
else
ret = 0;
spin_unlock_irqrestore(&substream->runtime_lock, flags);
return ret;
} }
static int snd_pcm_timer_start(struct snd_timer * timer) static int snd_pcm_timer_start(struct snd_timer * timer)

View File

@ -99,6 +99,7 @@ struct msm_compr_pdata {
bool use_dsp_gapless_mode; bool use_dsp_gapless_mode;
struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX]; struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX];
struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX]; struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX];
bool is_in_use[MSM_FRONTEND_DAI_MAX];
}; };
struct msm_compr_audio { struct msm_compr_audio {
@ -1053,11 +1054,16 @@ static int msm_compr_open(struct snd_compr_stream *cstream)
{ {
struct snd_compr_runtime *runtime = cstream->runtime; struct snd_compr_runtime *runtime = cstream->runtime;
struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct msm_compr_audio *prtd; struct msm_compr_audio *prtd = NULL;
struct msm_compr_pdata *pdata = struct msm_compr_pdata *pdata =
snd_soc_platform_get_drvdata(rtd->platform); snd_soc_platform_get_drvdata(rtd->platform);
pr_debug("%s\n", __func__); pr_debug("%s\n", __func__);
if (pdata->is_in_use[rtd->dai_link->be_id] == true) {
pr_err("%s: %s is already in use,err: %d ",
__func__, rtd->dai_link->cpu_dai_name, -EBUSY);
return -EBUSY;
}
prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL); prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL);
if (prtd == NULL) { if (prtd == NULL) {
pr_err("Failed to allocate memory for msm_compr_audio\n"); pr_err("Failed to allocate memory for msm_compr_audio\n");
@ -1069,7 +1075,7 @@ static int msm_compr_open(struct snd_compr_stream *cstream)
pdata->cstream[rtd->dai_link->be_id] = cstream; pdata->cstream[rtd->dai_link->be_id] = cstream;
pdata->audio_effects[rtd->dai_link->be_id] = pdata->audio_effects[rtd->dai_link->be_id] =
kzalloc(sizeof(struct msm_compr_audio_effects), GFP_KERNEL); kzalloc(sizeof(struct msm_compr_audio_effects), GFP_KERNEL);
if (!pdata->audio_effects[rtd->dai_link->be_id]) { if (pdata->audio_effects[rtd->dai_link->be_id] == NULL) {
pr_err("%s: Could not allocate memory for effects\n", __func__); pr_err("%s: Could not allocate memory for effects\n", __func__);
pdata->cstream[rtd->dai_link->be_id] = NULL; pdata->cstream[rtd->dai_link->be_id] = NULL;
kfree(prtd); kfree(prtd);
@ -1077,10 +1083,11 @@ static int msm_compr_open(struct snd_compr_stream *cstream)
} }
pdata->dec_params[rtd->dai_link->be_id] = pdata->dec_params[rtd->dai_link->be_id] =
kzalloc(sizeof(struct msm_compr_dec_params), GFP_KERNEL); kzalloc(sizeof(struct msm_compr_dec_params), GFP_KERNEL);
if (!pdata->dec_params[rtd->dai_link->be_id]) { if (pdata->dec_params[rtd->dai_link->be_id] == NULL) {
pr_err("%s: Could not allocate memory for dec params\n", pr_err("%s: Could not allocate memory for dec params\n",
__func__); __func__);
kfree(pdata->audio_effects[rtd->dai_link->be_id]); kfree(pdata->audio_effects[rtd->dai_link->be_id]);
pdata->audio_effects[rtd->dai_link->be_id] = NULL;
pdata->cstream[rtd->dai_link->be_id] = NULL; pdata->cstream[rtd->dai_link->be_id] = NULL;
kfree(prtd); kfree(prtd);
return -ENOMEM; return -ENOMEM;
@ -1090,7 +1097,9 @@ static int msm_compr_open(struct snd_compr_stream *cstream)
if (!prtd->audio_client) { if (!prtd->audio_client) {
pr_err("%s: Could not allocate memory for client\n", __func__); pr_err("%s: Could not allocate memory for client\n", __func__);
kfree(pdata->audio_effects[rtd->dai_link->be_id]); kfree(pdata->audio_effects[rtd->dai_link->be_id]);
pdata->audio_effects[rtd->dai_link->be_id] = NULL;
kfree(pdata->dec_params[rtd->dai_link->be_id]); kfree(pdata->dec_params[rtd->dai_link->be_id]);
pdata->dec_params[rtd->dai_link->be_id] = NULL;
pdata->cstream[rtd->dai_link->be_id] = NULL; pdata->cstream[rtd->dai_link->be_id] = NULL;
kfree(prtd); kfree(prtd);
return -ENOMEM; return -ENOMEM;
@ -1149,7 +1158,7 @@ static int msm_compr_open(struct snd_compr_stream *cstream)
} else { } else {
pr_err("%s: Unsupported stream type", __func__); pr_err("%s: Unsupported stream type", __func__);
} }
pdata->is_in_use[rtd->dai_link->be_id] = true;
return 0; return 0;
} }
@ -1244,11 +1253,15 @@ static int msm_compr_free(struct snd_compr_stream *cstream)
q6asm_audio_client_buf_free_contiguous(dir, ac); q6asm_audio_client_buf_free_contiguous(dir, ac);
q6asm_audio_client_free(ac); q6asm_audio_client_free(ac);
if (pdata->audio_effects[soc_prtd->dai_link->be_id] != NULL) {
kfree(pdata->audio_effects[soc_prtd->dai_link->be_id]); kfree(pdata->audio_effects[soc_prtd->dai_link->be_id]);
pdata->audio_effects[soc_prtd->dai_link->be_id] = NULL; pdata->audio_effects[soc_prtd->dai_link->be_id] = NULL;
kfree(pdata->dec_params[soc_prtd->dai_link->be_id]); }
pdata->dec_params[soc_prtd->dai_link->be_id] = NULL; if (pdata->dec_params[soc_prtd->dai_link->be_id] != NULL) {
kfree(pdata->dec_params[soc_prtd->dai_link->be_id]);
pdata->dec_params[soc_prtd->dai_link->be_id] = NULL;
}
pdata->is_in_use[soc_prtd->dai_link->be_id] = false;
kfree(prtd); kfree(prtd);
runtime->private_data = NULL; runtime->private_data = NULL;
@ -2786,6 +2799,7 @@ static int msm_compr_probe(struct snd_soc_platform *platform)
pdata->dec_params[i] = NULL; pdata->dec_params[i] = NULL;
pdata->cstream[i] = NULL; pdata->cstream[i] = NULL;
pdata->ch_map[i] = NULL; pdata->ch_map[i] = NULL;
pdata->is_in_use[i] = false;
} }
/* /*