diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2018-06-29 05:34:52 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-06-29 05:34:52 -0700 |
commit | 03b691947c4401cd384e560913a56d64555092ef (patch) | |
tree | 9c60bb220fbdde01c445461f3240f6e3dcd14905 | |
parent | a4b61022610155326e32017e2f8b1f6ffcffb241 (diff) | |
parent | 72d0ee06a84d7a3993e429e437a2a3cf275438d4 (diff) |
Merge "Merge 2a645f513b1c671b1f0a2dc3ccfbcb0f7d44a632 on remote branch"LA.UM.6.3.r4-04300-sdm845.0
40 files changed, 575 insertions, 240 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index d673a69b61b4..a28ce591b28e 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -1079,10 +1079,8 @@ int blkcg_init_queue(struct request_queue *q) if (preloaded) radix_tree_preload_end(); - if (IS_ERR(blkg)) { - blkg_free(new_blkg); + if (IS_ERR(blkg)) return PTR_ERR(blkg); - } q->root_blkg = blkg; q->root_rl.blkg = blkg; diff --git a/crypto/hmac.c b/crypto/hmac.c index 72e38c098bb3..ba07fb6221ae 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -194,11 +194,15 @@ static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb) salg = shash_attr_alg(tb[1], 0, 0); if (IS_ERR(salg)) return PTR_ERR(salg); + alg = &salg->base; + /* The underlying hash algorithm must be unkeyed */ err = -EINVAL; + if (crypto_shash_alg_has_setkey(salg)) + goto out_put_alg; + ds = salg->digestsize; ss = salg->statesize; - alg = &salg->base; if (ds > alg->cra_blocksize || ss < alg->cra_blocksize) goto out_put_alg; diff --git a/crypto/shash.c b/crypto/shash.c index 4d8a671d1614..9bd5044d467b 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -24,11 +24,12 @@ static const struct crypto_type crypto_shash_type; -static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, - unsigned int keylen) +int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, + unsigned int keylen) { return -ENOSYS; } +EXPORT_SYMBOL_GPL(shash_no_setkey); static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, unsigned int keylen) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index a56fa2a1e9aa..7394aac91d9e 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -83,7 +83,8 @@ static ssize_t driver_override_store(struct device *_dev, struct amba_device *dev = to_amba_device(_dev); char *driver_override, *old = dev->driver_override, *cp; - if (count > PATH_MAX) + /* We need to keep extra room for a newline */ + if (count >= (PAGE_SIZE - 1)) return -EINVAL; driver_override = kstrndup(buf, count, GFP_KERNEL); diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 235f60b4c5dc..53be4ad4dd9d 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -341,6 +341,7 @@ struct fastrpc_file { int qos_request; struct mutex map_mutex; struct mutex fl_map_mutex; + int refcount; }; static struct fastrpc_apps gfa; @@ -1430,9 +1431,18 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) if (map && (map->attr & FASTRPC_ATTR_COHERENT)) continue; - if (rpra[i].buf.len && ctx->overps[oix]->mstart) - dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv), - uint64_to_ptr(rpra[i].buf.pv + rpra[i].buf.len)); + if (rpra && rpra[i].buf.len && ctx->overps[oix]->mstart) { + if (map && map->handle) + msm_ion_do_cache_op(ctx->fl->apps->client, + map->handle, + uint64_to_ptr(rpra[i].buf.pv), + rpra[i].buf.len, + ION_IOC_CLEAN_INV_CACHES); + else + dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv), + uint64_to_ptr(rpra[i].buf.pv + + rpra[i].buf.len)); + } } PERF_END); for (i = bufs; rpra && i < bufs + handles; i++) { @@ -1441,11 +1451,6 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) rpra[i].dma.offset = (uint32_t)(uintptr_t)lpra[i].buf.pv; } - if (!ctx->fl->sctx->smmu.coherent) { - PERF(ctx->fl->profile, ctx->fl->perf.flush, - dmac_flush_range((char *)rpra, (char *)rpra + ctx->used); - PERF_END); - } bail: return err; } @@ -1531,14 +1536,33 @@ static void inv_args_pre(struct smq_invoke_ctx *ctx) if (buf_page_start(ptr_to_uint64((void *)rpra)) == buf_page_start(rpra[i].buf.pv)) continue; - if (!IS_CACHE_ALIGNED((uintptr_t)uint64_to_ptr(rpra[i].buf.pv))) - dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv), - (char *)(uint64_to_ptr(rpra[i].buf.pv + 1))); + if (!IS_CACHE_ALIGNED((uintptr_t) + uint64_to_ptr(rpra[i].buf.pv))) { + if (map && map->handle) + msm_ion_do_cache_op(ctx->fl->apps->client, + map->handle, + uint64_to_ptr(rpra[i].buf.pv), + sizeof(uintptr_t), + ION_IOC_CLEAN_INV_CACHES); + else + dmac_flush_range( + uint64_to_ptr(rpra[i].buf.pv), (char *) + uint64_to_ptr(rpra[i].buf.pv + 1)); + } + end = (uintptr_t)uint64_to_ptr(rpra[i].buf.pv + rpra[i].buf.len); - if (!IS_CACHE_ALIGNED(end)) - dmac_flush_range((char *)end, - (char *)end + 1); + if (!IS_CACHE_ALIGNED(end)) { + if (map && map->handle) + msm_ion_do_cache_op(ctx->fl->apps->client, + map->handle, + uint64_to_ptr(end), + sizeof(uintptr_t), + ION_IOC_CLEAN_INV_CACHES); + else + dmac_flush_range((char *)end, + (char *)end + 1); + } } } @@ -1547,7 +1571,6 @@ static void inv_args(struct smq_invoke_ctx *ctx) int i, inbufs, outbufs; uint32_t sc = ctx->sc; remote_arg64_t *rpra = ctx->rpra; - int used = ctx->used; inbufs = REMOTE_SCALARS_INBUFS(sc); outbufs = REMOTE_SCALARS_OUTBUFS(sc); @@ -1578,8 +1601,6 @@ static void inv_args(struct smq_invoke_ctx *ctx) + rpra[i].buf.len)); } - if (rpra) - dmac_inv_range(rpra, (char *)rpra + used); } static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, @@ -1903,6 +1924,8 @@ static int fastrpc_init_process(struct fastrpc_file *fl, if (!strcmp(proc_name, "audiopd")) { fl->spdname = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME; VERIFY(err, !fastrpc_mmap_remove_pdr(fl)); + if (err) + goto bail; } if (!me->staticpd_flags) { @@ -2514,7 +2537,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl) fastrpc_mmap_free(lmap, 1); } while (lmap); mutex_unlock(&fl->fl_map_mutex); - if (fl->ssrcount == fl->apps->channel[cid].ssrcount) + if (fl->refcount && (fl->ssrcount == fl->apps->channel[cid].ssrcount)) kref_put_mutex(&fl->apps->channel[cid].kref, fastrpc_channel_close, &fl->apps->smd_mutex); if (fl->sctx) @@ -2792,6 +2815,7 @@ static int fastrpc_channel_open(struct fastrpc_file *fl) } } fl->ssrcount = me->channel[cid].ssrcount; + fl->refcount = 1; if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) || (me->channel[cid].chan == NULL)) { VERIFY(err, 0 == fastrpc_glink_register(cid, me)); @@ -2856,6 +2880,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->debugfs_file = debugfs_file; memset(&fl->perf, 0, sizeof(fl->perf)); fl->qos_request = 0; + fl->refcount = 0; filp->private_data = fl; mutex_init(&fl->map_mutex); mutex_init(&fl->fl_map_mutex); @@ -3002,6 +3027,28 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, if (err) goto bail; break; + case FASTRPC_IOCTL_MMAP_64: + K_COPY_FROM_USER(err, 0, &p.mmap, param, + sizeof(p.mmap)); + if (err) + goto bail; + VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap))); + if (err) + goto bail; + K_COPY_TO_USER(err, 0, param, &p.mmap, sizeof(p.mmap)); + if (err) + goto bail; + break; + case FASTRPC_IOCTL_MUNMAP_64: + K_COPY_FROM_USER(err, 0, &p.munmap, param, + sizeof(p.munmap)); + if (err) + goto bail; + VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl, + &p.munmap))); + if (err) + goto bail; + break; case FASTRPC_IOCTL_MUNMAP_FD: K_COPY_FROM_USER(err, 0, &p.munmap_fd, param, sizeof(p.munmap_fd)); diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c index 0f07483eaf1d..804cedade655 100644 --- a/drivers/char/adsprpc_compat.c +++ b/drivers/char/adsprpc_compat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -39,6 +39,10 @@ _IOWR('R', 11, struct compat_fastrpc_ioctl_invoke_crc) #define COMPAT_FASTRPC_IOCTL_CONTROL \ _IOWR('R', 12, struct compat_fastrpc_ioctl_control) +#define COMPAT_FASTRPC_IOCTL_MMAP_64 \ + _IOWR('R', 14, struct compat_fastrpc_ioctl_mmap_64) +#define COMPAT_FASTRPC_IOCTL_MUNMAP_64 \ + _IOWR('R', 15, struct compat_fastrpc_ioctl_munmap_64) struct compat_remote_buf { compat_uptr_t pv; /* buffer pointer */ @@ -82,11 +86,24 @@ struct compat_fastrpc_ioctl_mmap { compat_uptr_t vaddrout; /* dsps virtual address */ }; +struct compat_fastrpc_ioctl_mmap_64 { + compat_int_t fd; /* ion fd */ + compat_uint_t flags; /* flags for dsp to map with */ + compat_u64 vaddrin; /* optional virtual address */ + compat_size_t size; /* size */ + compat_u64 vaddrout; /* dsps virtual address */ +}; + struct compat_fastrpc_ioctl_munmap { compat_uptr_t vaddrout; /* address to unmap */ compat_size_t size; /* size */ }; +struct compat_fastrpc_ioctl_munmap_64 { + compat_u64 vaddrout; /* address to unmap */ + compat_size_t size; /* size */ +}; + struct compat_fastrpc_ioctl_init { compat_uint_t flags; /* one of FASTRPC_INIT_* macros */ compat_uptr_t file; /* pointer to elf file */ @@ -206,6 +223,28 @@ static int compat_get_fastrpc_ioctl_mmap( return err; } +static int compat_get_fastrpc_ioctl_mmap_64( + struct compat_fastrpc_ioctl_mmap_64 __user *map32, + struct fastrpc_ioctl_mmap __user *map) +{ + compat_uint_t u; + compat_int_t i; + compat_size_t s; + compat_u64 p; + int err; + + err = get_user(i, &map32->fd); + err |= put_user(i, &map->fd); + err |= get_user(u, &map32->flags); + err |= put_user(u, &map->flags); + err |= get_user(p, &map32->vaddrin); + err |= put_user(p, &map->vaddrin); + err |= get_user(s, &map32->size); + err |= put_user(s, &map->size); + + return err; +} + static int compat_put_fastrpc_ioctl_mmap( struct compat_fastrpc_ioctl_mmap __user *map32, struct fastrpc_ioctl_mmap __user *map) @@ -219,6 +258,19 @@ static int compat_put_fastrpc_ioctl_mmap( return err; } +static int compat_put_fastrpc_ioctl_mmap_64( + struct compat_fastrpc_ioctl_mmap_64 __user *map32, + struct fastrpc_ioctl_mmap __user *map) +{ + compat_u64 p; + int err; + + err = get_user(p, &map->vaddrout); + err |= put_user(p, &map32->vaddrout); + + return err; +} + static int compat_get_fastrpc_ioctl_munmap( struct compat_fastrpc_ioctl_munmap __user *unmap32, struct fastrpc_ioctl_munmap __user *unmap) @@ -235,6 +287,22 @@ static int compat_get_fastrpc_ioctl_munmap( return err; } +static int compat_get_fastrpc_ioctl_munmap_64( + struct compat_fastrpc_ioctl_munmap_64 __user *unmap32, + struct fastrpc_ioctl_munmap __user *unmap) +{ + compat_u64 p; + compat_size_t s; + int err; + + err = get_user(p, &unmap32->vaddrout); + err |= put_user(p, &unmap->vaddrout); + err |= get_user(s, &unmap32->size); + err |= put_user(s, &unmap->size); + + return err; +} + static int compat_get_fastrpc_ioctl_perf( struct compat_fastrpc_ioctl_perf __user *perf32, struct fastrpc_ioctl_perf __user *perf) @@ -355,6 +423,27 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap(map32, map)); return err; } + case COMPAT_FASTRPC_IOCTL_MMAP_64: + { + struct compat_fastrpc_ioctl_mmap_64 __user *map32; + struct fastrpc_ioctl_mmap __user *map; + long ret; + + map32 = compat_ptr(arg); + VERIFY(err, NULL != (map = compat_alloc_user_space( + sizeof(*map)))); + if (err) + return -EFAULT; + VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap_64(map32, map)); + if (err) + return err; + ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MMAP_64, + (unsigned long)map); + if (ret) + return ret; + VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap_64(map32, map)); + return err; + } case COMPAT_FASTRPC_IOCTL_MUNMAP: { struct compat_fastrpc_ioctl_munmap __user *unmap32; @@ -372,6 +461,23 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, return filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MUNMAP, (unsigned long)unmap); } + case COMPAT_FASTRPC_IOCTL_MUNMAP_64: + { + struct compat_fastrpc_ioctl_munmap_64 __user *unmap32; + struct fastrpc_ioctl_munmap __user *unmap; + + unmap32 = compat_ptr(arg); + VERIFY(err, NULL != (unmap = compat_alloc_user_space( + sizeof(*unmap)))); + if (err) + return -EFAULT; + VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap_64(unmap32, + unmap)); + if (err) + return err; + return filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MUNMAP_64, + (unsigned long)unmap); + } case COMPAT_FASTRPC_IOCTL_INIT: /* fall through */ case COMPAT_FASTRPC_IOCTL_INIT_ATTRS: diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index bb7b654693b9..2bc5e094f189 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -19,6 +19,8 @@ #define FASTRPC_IOCTL_INVOKE _IOWR('R', 1, struct fastrpc_ioctl_invoke) #define FASTRPC_IOCTL_MMAP _IOWR('R', 2, struct fastrpc_ioctl_mmap) #define FASTRPC_IOCTL_MUNMAP _IOWR('R', 3, struct fastrpc_ioctl_munmap) +#define FASTRPC_IOCTL_MMAP_64 _IOWR('R', 14, struct fastrpc_ioctl_mmap_64) +#define FASTRPC_IOCTL_MUNMAP_64 _IOWR('R', 15, struct fastrpc_ioctl_munmap_64) #define FASTRPC_IOCTL_INVOKE_FD _IOWR('R', 4, struct fastrpc_ioctl_invoke_fd) #define FASTRPC_IOCTL_SETMODE _IOWR('R', 5, uint32_t) #define FASTRPC_IOCTL_INIT _IOWR('R', 6, struct fastrpc_ioctl_init) @@ -203,6 +205,11 @@ struct fastrpc_ioctl_munmap { size_t size; /* size */ }; +struct fastrpc_ioctl_munmap_64 { + uint64_t vaddrout; /* address to unmap */ + size_t size; /* size */ +}; + struct fastrpc_ioctl_mmap { int fd; /* ion fd */ uint32_t flags; /* flags for dsp to map with */ @@ -211,6 +218,14 @@ struct fastrpc_ioctl_mmap { uintptr_t vaddrout; /* dsps virtual address */ }; +struct fastrpc_ioctl_mmap_64 { + int fd; /* ion fd */ + uint32_t flags; /* flags for dsp to map with */ + uint64_t vaddrin; /* optional virtual address */ + size_t size; /* size */ + uint64_t vaddrout; /* dsps virtual address */ +}; + struct fastrpc_ioctl_munmap_fd { int fd; /* fd */ uint32_t flags; /* control flags */ diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c index c4e6107836f5..cd65e0f52591 100644 --- a/drivers/char/diag/diagfwd_peripheral.c +++ b/drivers/char/diag/diagfwd_peripheral.c @@ -1115,8 +1115,11 @@ void *diagfwd_request_write_buf(struct diagfwd_info *fwd_info) int index; unsigned long flags; + if (!fwd_info) + return NULL; spin_lock_irqsave(&fwd_info->write_buf_lock, flags); - for (index = 0 ; index < NUM_WRITE_BUFFERS; index++) { + for (index = 0; (index < NUM_WRITE_BUFFERS) && fwd_info->buf_ptr[index]; + index++) { if (!atomic_read(&(fwd_info->buf_ptr[index]->in_busy))) { atomic_set(&(fwd_info->buf_ptr[index]->in_busy), 1); buf = fwd_info->buf_ptr[index]->data; @@ -1552,7 +1555,8 @@ int diagfwd_write_buffer_done(struct diagfwd_info *fwd_info, const void *ptr) if (!fwd_info || !ptr) return found; spin_lock_irqsave(&fwd_info->write_buf_lock, flags); - for (index = 0; index < NUM_WRITE_BUFFERS; index++) { + for (index = 0; (index < NUM_WRITE_BUFFERS) && fwd_info->buf_ptr[index]; + index++) { if (fwd_info->buf_ptr[index]->data == ptr) { atomic_set(&fwd_info->buf_ptr[index]->in_busy, 0); found = 1; diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c index 48ce65f4b769..7a96cff4b910 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder.c @@ -80,6 +80,11 @@ /* Maximum number of VSYNC wait attempts for RSC state transition */ #define MAX_RSC_WAIT 5 +#define TOPOLOGY_DUALPIPE_MERGE_MODE(x) \ + (((x) == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE) || \ + ((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE) || \ + ((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC)) + /** * enum sde_enc_rc_events - events for resource control state machine * @SDE_ENC_RC_EVENT_KICKOFF: @@ -3291,13 +3296,14 @@ void sde_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc) static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys) { void *dither_cfg; - int ret = 0, rc; + int ret = 0, rc, i = 0; size_t len = 0; enum sde_rm_topology_name topology; struct drm_encoder *drm_enc; struct msm_mode_info mode_info; struct msm_display_dsc_info *dsc = NULL; struct sde_encoder_virt *sde_enc; + struct sde_hw_pingpong *hw_pp; if (!phys || !phys->connector || !phys->hw_pp || !phys->hw_pp->ops.setup_dither || !phys->parent) @@ -3320,12 +3326,24 @@ static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys) /* disable dither for 10 bpp or 10bpc dsc config */ if (dsc->bpp == 10 || dsc->bpc == 10) { phys->hw_pp->ops.setup_dither(phys->hw_pp, NULL, 0); + return; + } + + ret = sde_connector_get_dither_cfg(phys->connector, + phys->connector->state, &dither_cfg, &len); + if (ret) + return; + + if (TOPOLOGY_DUALPIPE_MERGE_MODE(topology)) { + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { + hw_pp = sde_enc->hw_pp[i]; + if (hw_pp) { + phys->hw_pp->ops.setup_dither(hw_pp, dither_cfg, + len); + } + } } else { - ret = sde_connector_get_dither_cfg(phys->connector, - phys->connector->state, &dither_cfg, &len); - if (!ret) - phys->hw_pp->ops.setup_dither(phys->hw_pp, - dither_cfg, len); + phys->hw_pp->ops.setup_dither(phys->hw_pp, dither_cfg, len); } } diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 18a06a41d371..fa13f629d998 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -1982,6 +1982,7 @@ static int a6xx_wait_for_lowest_idle(struct adreno_device *adreno_dev) unsigned int reg, reg1; unsigned long t; uint64_t ts1, ts2, ts3; + unsigned long start_jiffies, end_jiffies; if (!kgsl_gmu_isenabled(device)) return 0; @@ -1989,6 +1990,9 @@ static int a6xx_wait_for_lowest_idle(struct adreno_device *adreno_dev) ts1 = read_AO_counter(device); t = jiffies + msecs_to_jiffies(GMU_IDLE_TIMEOUT); + start_jiffies = jiffies; + +retry: do { kgsl_gmu_regread(device, A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE, ®); @@ -2001,9 +2005,22 @@ static int a6xx_wait_for_lowest_idle(struct adreno_device *adreno_dev) usleep_range(10, 100); } while (!time_after(jiffies, t)); + end_jiffies = jiffies; ts2 = read_AO_counter(device); - /* Check one last time */ + /* + * If AO counter values indicates that loop has exited + * earlier then expected timeout value. Retry till we + * reach the expected timeout value. + */ + if ((((ts2 - ts1) * 10) / 192) < (GMU_IDLE_TIMEOUT * USEC_PER_MSEC)) { + dev_err_ratelimited(&gmu->pdev->dev, + "Invalid wait loop exit: %08x %llx %llx %x %lx %lx %lx\n", + reg, ts1, ts2, reg1, t, start_jiffies, end_jiffies); + goto retry; + } + + /* Check one last time */ kgsl_gmu_regread(device, A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE, ®); kgsl_gmu_regread(device, A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, ®1); @@ -2011,8 +2028,8 @@ static int a6xx_wait_for_lowest_idle(struct adreno_device *adreno_dev) return 0; ts3 = read_AO_counter(device); - WARN(1, "Timeout waiting for lowest idle: %08x %llx %llx %llx %x\n", - reg, ts1, ts2, ts3, reg1); + WARN(1, "Timeout waiting for lowest idle: %08x %llx %llx %llx %x %lx %lx %lx\n", + reg, ts1, ts2, ts3, reg1, t, start_jiffies, end_jiffies); return -ETIMEDOUT; } diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.c b/drivers/media/platform/msm/camera/cam_core/cam_context.c index 8beffc4903fa..891b73872e23 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_context.c +++ b/drivers/media/platform/msm/camera/cam_core/cam_context.c @@ -355,7 +355,7 @@ int cam_context_handle_start_dev(struct cam_context *ctx, { int rc = 0; - if (!ctx->state_machine) { + if (!ctx || !ctx->state_machine) { CAM_ERR(CAM_CORE, "Context is not ready"); return -EINVAL; } @@ -384,7 +384,7 @@ int cam_context_handle_stop_dev(struct cam_context *ctx, { int rc = 0; - if (!ctx->state_machine) { + if (!ctx || !ctx->state_machine) { CAM_ERR(CAM_CORE, "Context is not ready"); return -EINVAL; } diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index 50cdc7d69ea6..7b02aac2ad0a 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -504,6 +504,18 @@ static void __cam_isp_ctx_send_sof_timestamp( } +static int __cam_isp_ctx_reg_upd_in_epoch_state( + struct cam_isp_context *ctx_isp, void *evt_data) +{ + if (ctx_isp->frame_id == 1) + CAM_DBG(CAM_ISP, "Reg update for early PCR"); + else + CAM_WARN(CAM_ISP, + "Unexpected reg update in activated substate:%d for frame_id:%lld", + ctx_isp->substate_activated, ctx_isp->frame_id); + return 0; +} + static int __cam_isp_ctx_reg_upd_in_activated_state( struct cam_isp_context *ctx_isp, void *evt_data) { @@ -1119,7 +1131,7 @@ static struct cam_isp_ctx_irq_ops .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_epoch, - NULL, + __cam_isp_ctx_reg_upd_in_epoch_state, __cam_isp_ctx_notify_sof_in_actived_state, __cam_isp_ctx_notify_eof_in_actived_state, __cam_isp_ctx_buf_done_in_epoch, diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 12c37863a3a5..c1aa501e229d 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -1367,6 +1367,7 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, uint32_t num_rdi_port_per_in = 0; uint32_t total_pix_port = 0; uint32_t total_rdi_port = 0; + uint32_t in_port_length = 0; CAM_DBG(CAM_ISP, "Enter..."); @@ -1427,9 +1428,27 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, isp_resource[i].res_hdl, isp_resource[i].length); + in_port_length = sizeof(struct cam_isp_in_port_info); + + if (in_port_length > isp_resource[i].length) { + CAM_ERR(CAM_ISP, "buffer size is not enough"); + rc = -EINVAL; + goto free_res; + } + in_port = memdup_user((void __user *)isp_resource[i].res_hdl, isp_resource[i].length); if (!IS_ERR(in_port)) { + in_port_length = sizeof(struct cam_isp_in_port_info) + + (in_port->num_out_res - 1) * + sizeof(struct cam_isp_out_port_info); + if (in_port_length > isp_resource[i].length) { + CAM_ERR(CAM_ISP, "buffer size is not enough"); + rc = -EINVAL; + kfree(in_port); + goto free_res; + } + rc = cam_ife_mgr_acquire_hw_for_ctx(ife_ctx, in_port, &num_pix_port_per_in, &num_rdi_port_per_in); total_pix_port += num_pix_port_per_in; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c index 90c80066b4b1..8bc9bd23a039 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c @@ -204,6 +204,9 @@ static int cam_vfe_camif_resource_start( { struct cam_vfe_mux_camif_data *rsrc_data; uint32_t val = 0; + uint32_t epoch0_irq_mask; + uint32_t epoch1_irq_mask; + uint32_t computed_epoch_line_cfg; if (!camif_res) { CAM_ERR(CAM_ISP, "Error! Invalid input arguments"); @@ -243,9 +246,16 @@ static int cam_vfe_camif_resource_start( rsrc_data->common_reg->module_ctrl[ CAM_VFE_TOP_VER2_MODULE_STATS]->cgc_ovd); - /* epoch config with 20 line */ - cam_io_w_mb(rsrc_data->reg_data->epoch_line_cfg, + /* epoch config */ + epoch0_irq_mask = ((rsrc_data->last_line - rsrc_data->first_line) / 2) + + rsrc_data->first_line; + epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg & 0xFFFF; + computed_epoch_line_cfg = (epoch0_irq_mask << 16) | epoch1_irq_mask; + cam_io_w_mb(computed_epoch_line_cfg, rsrc_data->mem_base + rsrc_data->camif_reg->epoch_irq); + CAM_DBG(CAM_ISP, "first_line:%u last_line:%u epoch_line_cfg: 0x%x", + rsrc_data->first_line, rsrc_data->last_line, + computed_epoch_line_cfg); camif_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c index 5d6045bb3e08..be0ca184113c 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c @@ -34,11 +34,12 @@ struct cam_vfe_top_ver2_priv { struct cam_vfe_top_ver2_common_data common_data; struct cam_isp_resource_node mux_rsrc[CAM_VFE_TOP_VER2_MUX_MAX]; unsigned long hw_clk_rate; - struct cam_axi_vote to_be_applied_axi_vote; struct cam_axi_vote applied_axi_vote; - uint32_t counter_to_update_axi_vote; struct cam_axi_vote req_axi_vote[CAM_VFE_TOP_VER2_MUX_MAX]; unsigned long req_clk_rate[CAM_VFE_TOP_VER2_MUX_MAX]; + struct cam_axi_vote last_vote[CAM_VFE_TOP_VER2_MUX_MAX * + CAM_VFE_DELAY_BW_REDUCTION_NUM_FRAMES]; + uint32_t last_counter; enum cam_vfe_bw_control_action axi_vote_control[CAM_VFE_TOP_VER2_MUX_MAX]; }; @@ -128,6 +129,7 @@ static int cam_vfe_top_set_axi_bw_vote( bool start_stop) { struct cam_axi_vote sum = {0, 0}; + struct cam_axi_vote to_be_applied_axi_vote = {0, 0}; int i, rc = 0; struct cam_hw_soc_info *soc_info = top_priv->common_data.soc_info; @@ -156,6 +158,11 @@ static int cam_vfe_top_set_axi_bw_vote( sum.uncompressed_bw, sum.compressed_bw); + top_priv->last_vote[top_priv->last_counter] = sum; + top_priv->last_counter = (top_priv->last_counter + 1) % + (CAM_VFE_TOP_VER2_MUX_MAX * + CAM_VFE_DELAY_BW_REDUCTION_NUM_FRAMES); + if ((top_priv->applied_axi_vote.uncompressed_bw == sum.uncompressed_bw) && (top_priv->applied_axi_vote.compressed_bw == @@ -163,77 +170,60 @@ static int cam_vfe_top_set_axi_bw_vote( CAM_DBG(CAM_ISP, "BW config unchanged %llu %llu", top_priv->applied_axi_vote.uncompressed_bw, top_priv->applied_axi_vote.compressed_bw); - top_priv->counter_to_update_axi_vote = 0; return 0; } - if ((top_priv->to_be_applied_axi_vote.uncompressed_bw != - sum.uncompressed_bw) || - (top_priv->to_be_applied_axi_vote.compressed_bw != - sum.compressed_bw)) { - // we got a new bw value to apply - top_priv->counter_to_update_axi_vote = 0; - - top_priv->to_be_applied_axi_vote.uncompressed_bw = - sum.uncompressed_bw; - top_priv->to_be_applied_axi_vote.compressed_bw = - sum.compressed_bw; - } - if (start_stop == true) { - CAM_DBG(CAM_ISP, - "New bw in start/stop, applying bw now, counter=%d", - top_priv->counter_to_update_axi_vote); - top_priv->counter_to_update_axi_vote = 0; - apply_bw_update = true; - } else if ((top_priv->to_be_applied_axi_vote.uncompressed_bw < - top_priv->applied_axi_vote.uncompressed_bw) || - (top_priv->to_be_applied_axi_vote.compressed_bw < - top_priv->applied_axi_vote.compressed_bw)) { - if (top_priv->counter_to_update_axi_vote >= + /* need to vote current request immediately */ + to_be_applied_axi_vote = sum; + /* Reset everything, we can start afresh */ + memset(top_priv->last_vote, 0x0, sizeof(struct cam_axi_vote) * (CAM_VFE_TOP_VER2_MUX_MAX * - CAM_VFE_DELAY_BW_REDUCTION_NUM_FRAMES)) { - CAM_DBG(CAM_ISP, - "New bw is less, applying bw now, counter=%d", - top_priv->counter_to_update_axi_vote); - top_priv->counter_to_update_axi_vote = 0; - apply_bw_update = true; - } else { - CAM_DBG(CAM_ISP, - "New bw is less, Defer applying bw, counter=%d", - top_priv->counter_to_update_axi_vote); - - top_priv->counter_to_update_axi_vote++; - apply_bw_update = false; - } + CAM_VFE_DELAY_BW_REDUCTION_NUM_FRAMES)); + top_priv->last_counter = 0; + top_priv->last_vote[top_priv->last_counter] = sum; + top_priv->last_counter = (top_priv->last_counter + 1) % + (CAM_VFE_TOP_VER2_MUX_MAX * + CAM_VFE_DELAY_BW_REDUCTION_NUM_FRAMES); } else { - CAM_DBG(CAM_ISP, - "New bw is more, applying bw now, counter=%d", - top_priv->counter_to_update_axi_vote); - top_priv->counter_to_update_axi_vote = 0; - apply_bw_update = true; + /* + * Find max bw request in last few frames. This will the bw + *that we want to vote to CPAS now. + */ + for (i = 0; i < (CAM_VFE_TOP_VER2_MUX_MAX * + CAM_VFE_DELAY_BW_REDUCTION_NUM_FRAMES); i++) { + if (to_be_applied_axi_vote.compressed_bw < + top_priv->last_vote[i].compressed_bw) + to_be_applied_axi_vote.compressed_bw = + top_priv->last_vote[i].compressed_bw; + + if (to_be_applied_axi_vote.uncompressed_bw < + top_priv->last_vote[i].uncompressed_bw) + to_be_applied_axi_vote.uncompressed_bw = + top_priv->last_vote[i].uncompressed_bw; + } } - CAM_DBG(CAM_ISP, - "counter=%d, apply_bw_update=%d", - top_priv->counter_to_update_axi_vote, - apply_bw_update); + if ((to_be_applied_axi_vote.uncompressed_bw != + top_priv->applied_axi_vote.uncompressed_bw) || + (to_be_applied_axi_vote.compressed_bw != + top_priv->applied_axi_vote.compressed_bw)) + apply_bw_update = true; + + CAM_DBG(CAM_ISP, "apply_bw_update=%d", apply_bw_update); if (apply_bw_update == true) { rc = cam_cpas_update_axi_vote( soc_private->cpas_handle, - &top_priv->to_be_applied_axi_vote); + &to_be_applied_axi_vote); if (!rc) { top_priv->applied_axi_vote.uncompressed_bw = - top_priv-> - to_be_applied_axi_vote.uncompressed_bw; + to_be_applied_axi_vote.uncompressed_bw; top_priv->applied_axi_vote.compressed_bw = - top_priv-> to_be_applied_axi_vote.compressed_bw; } else { CAM_ERR(CAM_ISP, "BW request failed, rc=%d", rc); } - top_priv->counter_to_update_axi_vote = 0; } return rc; @@ -706,11 +696,12 @@ int cam_vfe_top_ver2_init( } vfe_top->top_priv = top_priv; top_priv->hw_clk_rate = 0; - top_priv->to_be_applied_axi_vote.compressed_bw = 0; - top_priv->to_be_applied_axi_vote.uncompressed_bw = 0; top_priv->applied_axi_vote.compressed_bw = 0; top_priv->applied_axi_vote.uncompressed_bw = 0; - top_priv->counter_to_update_axi_vote = 0; + memset(top_priv->last_vote, 0x0, sizeof(struct cam_axi_vote) * + (CAM_VFE_TOP_VER2_MUX_MAX * + CAM_VFE_DELAY_BW_REDUCTION_NUM_FRAMES)); + top_priv->last_counter = 0; for (i = 0, j = 0; i < CAM_VFE_TOP_VER2_MUX_MAX; i++) { top_priv->mux_rsrc[i].res_type = CAM_ISP_RESOURCE_VFE_IN; diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 15bc97d30c60..b27d4f8ec47a 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -770,13 +770,6 @@ static int cam_jpeg_mgr_flush(void *hw_mgr_priv, } else { CAM_ERR(CAM_JPEG, "process_cmd null "); } - rc = hw_mgr->devices[dev_type][0]->hw_ops.process_cmd( - hw_mgr->devices[dev_type][0]->hw_priv, - CAM_JPEG_CMD_SET_IRQ_CB, - &irq_cb, sizeof(irq_cb)); - if (rc) - CAM_ERR(CAM_JPEG, - "CMD_SET_IRQ_CB failed %d", rc); if (hw_mgr->devices[dev_type][0]->hw_ops.stop) { rc = hw_mgr->devices[dev_type][0]->hw_ops.stop( diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c index 898997aa173b..a60661e04cd3 100644 --- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c @@ -879,6 +879,7 @@ static int cam_lrme_mgr_hw_prepare_update(void *hw_mgr_priv, if (args->num_in_map_entries == 0 || args->num_out_map_entries == 0) { CAM_ERR(CAM_LRME, "Error in port number in %d, out %d", args->num_in_map_entries, args->num_out_map_entries); + rc = -EINVAL; goto error; } diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index ff18fa741ade..4602d6c135a5 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -163,6 +163,34 @@ static void __cam_req_mgr_dec_idx(int32_t *val, int32_t step, int32_t max_val) } /** + * __cam_req_mgr_validate_inject_delay() + * + * @brief : Check if any pd device is introducing inject delay + * @tbl : cam_req_mgr_req_tbl + * @curr_idx : slot idx + * + * @return : 0 for success, negative for failure + */ +static int __cam_req_mgr_validate_inject_delay( + struct cam_req_mgr_req_tbl *tbl, + int32_t curr_idx) +{ + struct cam_req_mgr_tbl_slot *slot = NULL; + + while (tbl) { + slot = &tbl->slot[curr_idx]; + if (slot->inject_delay > 0) { + slot->inject_delay--; + return -EAGAIN; + } + __cam_req_mgr_dec_idx(&curr_idx, tbl->pd_delta, + tbl->num_slots); + tbl = tbl->next; + } + return 0; +} + +/** * __cam_req_mgr_traverse() * * @brief : Traverse through pd tables, it will internally cover all linked @@ -201,14 +229,17 @@ static int __cam_req_mgr_traverse(struct cam_req_mgr_traverse *traverse_data) tbl->skip_traverse, traverse_data->in_q->slot[curr_idx].status, traverse_data->in_q->slot[curr_idx].skip_idx); - if ((slot->inject_delay > 0) && - (traverse_data->self_link == true)) { - CAM_DBG(CAM_CRM, "Injecting Delay of one frame"); - apply_data[tbl->pd].req_id = -1; - slot->inject_delay--; - /* This pd table is not ready to proceed with asked idx */ - SET_FAILURE_BIT(traverse_data->result, tbl->pd); - return -EAGAIN; + if ((traverse_data->self_link == true) && + (!traverse_data->inject_delay_chk)) { + rc = __cam_req_mgr_validate_inject_delay(tbl, curr_idx); + if (rc) { + CAM_DBG(CAM_CRM, "Injecting Delay of one frame"); + apply_data[tbl->pd].req_id = -1; + /* This pd tbl not ready to proceed with asked idx */ + SET_FAILURE_BIT(traverse_data->result, tbl->pd); + return -EAGAIN; + } + traverse_data->inject_delay_chk = true; } /* Check if req is ready or in skip mode or pd tbl is in skip mode */ @@ -520,6 +551,7 @@ static int __cam_req_mgr_check_link_is_ready(struct cam_req_mgr_core_link *link, traverse_data.result = 0; traverse_data.validate_only = validate_only; traverse_data.self_link = self_link; + traverse_data.inject_delay_chk = false; traverse_data.open_req_cnt = link->open_req_cnt; /* * Traverse through all pd tables, if result is success, diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h index 73ffb81dd953..025c16aacfdf 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h @@ -126,15 +126,16 @@ enum cam_req_mgr_link_state { /** * struct cam_req_mgr_traverse - * @idx : slot index - * @result : contains which all tables were able to apply successfully - * @tbl : pointer of pipeline delay based request table - * @apply_data : pointer which various tables will update during traverse - * @in_q : input request queue pointer - * @validate_only : Whether to validate only and/or update settings - * @self_link : To indicate whether the check is for the given link or the - * other sync link - * @open_req_cnt : Count of open requests yet to be serviced in the kernel. + * @idx : slot index + * @result : contains which all tables were able to apply successfully + * @tbl : pointer of pipeline delay based request table + * @apply_data : pointer which various tables will update during traverse + * @in_q : input request queue pointer + * @validate_only : Whether to validate only and/or update settings + * @self_link : To indicate whether the check is for the given link or + * the other sync link + * @inject_delay_chk : if inject delay has been validated for all pd devices + * @open_req_cnt : Count of open requests yet to be serviced in the kernel. */ struct cam_req_mgr_traverse { int32_t idx; @@ -144,7 +145,8 @@ struct cam_req_mgr_traverse { struct cam_req_mgr_req_queue *in_q; bool validate_only; bool self_link; - int32_t open_req_cnt; + bool inject_delay_chk; + int32_t open_req_cnt; }; /** diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c index 966b573b5493..066efd6fa3e7 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c @@ -59,11 +59,11 @@ static void cam_req_mgr_workq_put_task(struct crm_workq_task *task) (struct cam_req_mgr_core_workq *)task->parent; unsigned long flags = 0; - WORKQ_ACQUIRE_LOCK(workq, flags); list_del_init(&task->entry); task->cancel = 0; task->process_cb = NULL; task->priv = NULL; + WORKQ_ACQUIRE_LOCK(workq, flags); list_add_tail(&task->entry, &workq->task.empty_head); atomic_add(1, &workq->task.free_cnt); @@ -127,28 +127,6 @@ static void cam_req_mgr_process_workq(struct work_struct *w) } } -void crm_workq_clear_q(struct cam_req_mgr_core_workq *workq) -{ - int32_t i = CRM_TASK_PRIORITY_0; - struct crm_workq_task *task, *task_save; - - CAM_DBG(CAM_CRM, "pending_cnt %d", - atomic_read(&workq->task.pending_cnt)); - - while (i < CRM_TASK_PRIORITY_MAX) { - if (!list_empty(&workq->task.process_head[i])) { - list_for_each_entry_safe(task, task_save, - &workq->task.process_head[i], entry) { - cam_req_mgr_workq_put_task(task); - CAM_WARN(CAM_CRM, "flush task %pK, %d, cnt %d", - task, i, atomic_read( - &workq->task.free_cnt)); - } - } - i++; - } -} - int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task, void *priv, int32_t prio) { @@ -167,10 +145,6 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task, rc = -EINVAL; goto end; } - if (!workq->job) { - rc = -EINVAL; - goto end; - } if (task->cancel == 1) { cam_req_mgr_workq_put_task(task); @@ -184,16 +158,21 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task, ? prio : CRM_TASK_PRIORITY_0; WORKQ_ACQUIRE_LOCK(workq, flags); + if (!workq->job) { + rc = -EINVAL; + WORKQ_RELEASE_LOCK(workq, flags); + goto end; + } + list_add_tail(&task->entry, &workq->task.process_head[task->priority]); - WORKQ_RELEASE_LOCK(workq, flags); atomic_add(1, &workq->task.pending_cnt); CAM_DBG(CAM_CRM, "enq task %pK pending_cnt %d", task, atomic_read(&workq->task.pending_cnt)); queue_work(workq->job, &workq->work); - + WORKQ_RELEASE_LOCK(workq, flags); end: return rc; } @@ -252,8 +231,7 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks, task = &crm_workq->task.pool[i]; task->parent = (void *)crm_workq; /* Put all tasks in free pool */ - list_add_tail(&task->entry, - &crm_workq->task.process_head[CRM_TASK_PRIORITY_0]); + INIT_LIST_HEAD(&task->entry); cam_req_mgr_workq_put_task(task); } *workq = crm_workq; @@ -266,13 +244,18 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks, void cam_req_mgr_workq_destroy(struct cam_req_mgr_core_workq **crm_workq) { + unsigned long flags = 0; + struct workqueue_struct *job; CAM_DBG(CAM_CRM, "destroy workque %pK", crm_workq); if (*crm_workq) { - crm_workq_clear_q(*crm_workq); + WORKQ_ACQUIRE_LOCK(*crm_workq, flags); if ((*crm_workq)->job) { - destroy_workqueue((*crm_workq)->job); + job = (*crm_workq)->job; (*crm_workq)->job = NULL; - } + WORKQ_RELEASE_LOCK(*crm_workq, flags); + destroy_workqueue(job); + } else + WORKQ_RELEASE_LOCK(*crm_workq, flags); kfree((*crm_workq)->task.pool); kfree(*crm_workq); *crm_workq = NULL; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c index 2f74765f1437..a34d70c50a94 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -603,7 +603,11 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl) { - int rc; + int rc = 0; + struct cam_actuator_soc_private *soc_private = + (struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private; + struct cam_sensor_power_ctrl_t *power_info = + &soc_private->power_info; if (a_ctrl->cam_act_state == CAM_ACTUATOR_INIT) return; @@ -612,6 +616,7 @@ void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl) rc = cam_actuator_power_down(a_ctrl); if (rc < 0) CAM_ERR(CAM_ACTUATOR, "Actuator Power down failed"); + a_ctrl->cam_act_state = CAM_ACTUATOR_ACQUIRE; } if (a_ctrl->cam_act_state >= CAM_ACTUATOR_ACQUIRE) { @@ -622,6 +627,12 @@ void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl) a_ctrl->bridge_intf.link_hdl = -1; a_ctrl->bridge_intf.session_hdl = -1; } + + kfree(power_info->power_setting); + kfree(power_info->power_down_setting); + power_info->power_setting = NULL; + power_info->power_down_setting = NULL; + a_ctrl->cam_act_state = CAM_ACTUATOR_INIT; } diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index dbbac08a5879..2688cd57db89 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -614,6 +614,13 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, if (csiphy_dev->acquire_count == 0) csiphy_dev->csiphy_state = CAM_CSIPHY_INIT; + + if (csiphy_dev->config_count == 0) { + CAM_DBG(CAM_CSIPHY, "reset csiphy_info"); + csiphy_dev->csiphy_info.lane_mask = 0; + csiphy_dev->csiphy_info.lane_cnt = 0; + csiphy_dev->csiphy_info.combo_mode = 0; + } } break; case CAM_CONFIG_DEV: { diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_0_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_0_hwreg.h index 3f743fca3ea6..324509340054 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_0_hwreg.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_0_hwreg.h @@ -152,7 +152,7 @@ struct csiphy_reg_t {0x0008, 0x00, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0060, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0060, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { @@ -168,7 +168,7 @@ struct csiphy_reg_t {0x070C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0760, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0760, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0764, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { @@ -183,7 +183,7 @@ struct csiphy_reg_t {0x0208, 0x00, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0260, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0260, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0264, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { @@ -198,7 +198,7 @@ struct csiphy_reg_t {0x0408, 0x00, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0460, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0460, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { @@ -214,7 +214,7 @@ struct csiphy_reg_t {0x060C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0638, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0660, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0660, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0664, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, }, }; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 6523607f0274..7f94f8d8c80d 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -315,8 +315,8 @@ int32_t cam_eeprom_parse_read_memory_map(struct device_node *of_node, power_down: cam_eeprom_power_down(e_ctrl); data_mem_free: - kfree(e_ctrl->cal_data.mapdata); - kfree(e_ctrl->cal_data.map); + vfree(e_ctrl->cal_data.mapdata); + vfree(e_ctrl->cal_data.map); e_ctrl->cal_data.num_data = 0; e_ctrl->cal_data.num_map = 0; e_ctrl->cam_eeprom_state = CAM_EEPROM_ACQUIRE; @@ -543,9 +543,9 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl, (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private; struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info; - e_ctrl->cal_data.map = kcalloc((MSM_EEPROM_MEMORY_MAP_MAX_SIZE * - MSM_EEPROM_MAX_MEM_MAP_CNT), - (sizeof(struct cam_eeprom_memory_map_t)), GFP_KERNEL); + e_ctrl->cal_data.map = vzalloc((MSM_EEPROM_MEMORY_MAP_MAX_SIZE * + MSM_EEPROM_MAX_MEM_MAP_CNT) * + (sizeof(struct cam_eeprom_memory_map_t))); if (!e_ctrl->cal_data.map) { rc = -ENOMEM; CAM_ERR(CAM_EEPROM, "failed"); @@ -738,8 +738,8 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) return rc; } rc = cam_eeprom_get_cal_data(e_ctrl, csl_packet); - kfree(e_ctrl->cal_data.mapdata); - kfree(e_ctrl->cal_data.map); + vfree(e_ctrl->cal_data.mapdata); + vfree(e_ctrl->cal_data.map); e_ctrl->cal_data.num_data = 0; e_ctrl->cal_data.num_map = 0; CAM_DBG(CAM_EEPROM, @@ -754,7 +754,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) } e_ctrl->cal_data.mapdata = - kzalloc(e_ctrl->cal_data.num_data, GFP_KERNEL); + vzalloc(e_ctrl->cal_data.num_data); if (!e_ctrl->cal_data.mapdata) { rc = -ENOMEM; CAM_ERR(CAM_EEPROM, "failed"); @@ -779,8 +779,12 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) rc = cam_eeprom_get_cal_data(e_ctrl, csl_packet); rc = cam_eeprom_power_down(e_ctrl); e_ctrl->cam_eeprom_state = CAM_EEPROM_ACQUIRE; - kfree(e_ctrl->cal_data.mapdata); - kfree(e_ctrl->cal_data.map); + vfree(e_ctrl->cal_data.mapdata); + vfree(e_ctrl->cal_data.map); + kfree(power_info->power_setting); + kfree(power_info->power_down_setting); + power_info->power_setting = NULL; + power_info->power_down_setting = NULL; e_ctrl->cal_data.num_data = 0; e_ctrl->cal_data.num_map = 0; break; @@ -791,11 +795,13 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) power_down: cam_eeprom_power_down(e_ctrl); memdata_free: - kfree(e_ctrl->cal_data.mapdata); + vfree(e_ctrl->cal_data.mapdata); error: kfree(power_info->power_setting); kfree(power_info->power_down_setting); - kfree(e_ctrl->cal_data.map); + power_info->power_setting = NULL; + power_info->power_down_setting = NULL; + vfree(e_ctrl->cal_data.map); e_ctrl->cal_data.num_data = 0; e_ctrl->cal_data.num_map = 0; e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT; @@ -830,6 +836,8 @@ void cam_eeprom_shutdown(struct cam_eeprom_ctrl_t *e_ctrl) kfree(power_info->power_setting); kfree(power_info->power_down_setting); + power_info->power_setting = NULL; + power_info->power_down_setting = NULL; } e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c index 196df084d40b..dfcb9fcba4b7 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c @@ -636,7 +636,11 @@ pwr_dwn: void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl) { - int rc; + int rc = 0; + struct cam_ois_soc_private *soc_private = + (struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private; + struct cam_sensor_power_ctrl_t *power_info = + &soc_private->power_info; if (o_ctrl->cam_ois_state == CAM_OIS_INIT) return; @@ -645,6 +649,7 @@ void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl) rc = cam_ois_power_down(o_ctrl); if (rc < 0) CAM_ERR(CAM_OIS, "OIS Power down failed"); + o_ctrl->cam_ois_state = CAM_OIS_ACQUIRE; } if (o_ctrl->cam_ois_state >= CAM_OIS_ACQUIRE) { @@ -656,6 +661,11 @@ void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->bridge_intf.session_hdl = -1; } + kfree(power_info->power_setting); + kfree(power_info->power_down_setting); + power_info->power_setting = NULL; + power_info->power_down_setting = NULL; + o_ctrl->cam_ois_state = CAM_OIS_INIT; } diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c index d58834c3d719..2133932dde57 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -518,6 +518,8 @@ void cam_sensor_shutdown(struct cam_sensor_ctrl_t *s_ctrl) kfree(power_info->power_setting); kfree(power_info->power_down_setting); + power_info->power_setting = NULL; + power_info->power_down_setting = NULL; s_ctrl->streamon_count = 0; s_ctrl->streamoff_count = 0; @@ -584,24 +586,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, "Already Sensor Probed in the slot"); break; } - /* Allocate memory for power up setting */ - pu = kzalloc(sizeof(struct cam_sensor_power_setting) * - MAX_POWER_CONFIG, GFP_KERNEL); - if (!pu) { - rc = -ENOMEM; - goto release_mutex; - } - - pd = kzalloc(sizeof(struct cam_sensor_power_setting) * - MAX_POWER_CONFIG, GFP_KERNEL); - if (!pd) { - kfree(pu); - rc = -ENOMEM; - goto release_mutex; - } - - power_info->power_setting = pu; - power_info->power_down_setting = pd; if (cmd->handle_type == CAM_HANDLE_MEM_HANDLE) { @@ -618,6 +602,9 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, return -EINVAL; } + pu = power_info->power_setting; + pd = power_info->power_down_setting; + /* Parse and fill vreg params for powerup settings */ rc = msm_camera_fill_vreg_params( &s_ctrl->soc_info, diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index 10d29c91f03e..73a0cf71071e 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -860,8 +860,10 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, return rc; free_power_down_settings: kfree(power_info->power_down_setting); + power_info->power_down_setting = NULL; free_power_settings: kfree(power_info->power_setting); + power_info->power_setting = NULL; return rc; } @@ -1304,7 +1306,9 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl, CAM_DBG(CAM_SENSOR, "index: %d", index); power_setting = &ctrl->power_setting[index]; if (!power_setting) { - CAM_ERR(CAM_SENSOR, "Invalid power up settings"); + CAM_ERR(CAM_SENSOR, + "Invalid power up settings for index %d", + index); return -EINVAL; } @@ -1548,7 +1552,7 @@ power_up_failed: if (ret) CAM_ERR(CAM_SENSOR, "cannot set pin to suspend state"); cam_res_mgr_shared_pinctrl_select_state(false); - pinctrl_put(ctrl->pinctrl_info.pinctrl); + devm_pinctrl_put(ctrl->pinctrl_info.pinctrl); cam_res_mgr_shared_pinctrl_put(); } @@ -1594,11 +1598,6 @@ static int cam_config_mclk_reg(struct cam_sensor_power_ctrl_t *ctrl, pd = &ctrl->power_down_setting[index]; - if (!pd) { - CAM_ERR(CAM_SENSOR, "Invalid power down setting"); - return -EINVAL; - } - for (j = 0; j < num_vreg; j++) { if (!strcmp(soc_info->rgltr_name[j], "cam_clk")) { @@ -1641,7 +1640,7 @@ int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl, { int index = 0, ret = 0, num_vreg = 0, i; struct cam_sensor_power_setting *pd = NULL; - struct cam_sensor_power_setting *ps; + struct cam_sensor_power_setting *ps = NULL; struct msm_camera_gpio_num_info *gpio_num_info = NULL; CAM_DBG(CAM_SENSOR, "Enter"); @@ -1661,6 +1660,13 @@ int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl, for (index = 0; index < ctrl->power_down_setting_size; index++) { CAM_DBG(CAM_SENSOR, "index %d", index); pd = &ctrl->power_down_setting[index]; + if (!pd) { + CAM_ERR(CAM_SENSOR, + "Invalid power down settings for index %d", + index); + return -EINVAL; + } + ps = NULL; CAM_DBG(CAM_SENSOR, "type %d", pd->seq_type); switch (pd->seq_type) { @@ -1760,7 +1766,7 @@ int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl, CAM_ERR(CAM_SENSOR, "cannot set pin to suspend state"); cam_res_mgr_shared_pinctrl_select_state(false); - pinctrl_put(ctrl->pinctrl_info.pinctrl); + devm_pinctrl_put(ctrl->pinctrl_info.pinctrl); cam_res_mgr_shared_pinctrl_put(); } diff --git a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c index ecfc5665085b..5cd30082fd55 100644 --- a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c +++ b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c @@ -3343,6 +3343,7 @@ static int cam_smmu_probe(struct platform_device *pdev) rc = cam_populate_smmu_context_banks(dev, CAM_ARM_SMMU); if (rc < 0) { CAM_ERR(CAM_SMMU, "Error: populating context banks"); + cam_smmu_release_cb(pdev); return -ENOMEM; } return rc; diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c index 43d17d9c9612..36a1b98eb4f2 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1075,6 +1075,7 @@ error_m2m_init: mutex_unlock(&rot_dev->lock); error_lock: kfree(ctx); + ctx = NULL; return ERR_PTR(ret); } @@ -1087,10 +1088,18 @@ error_lock: static int sde_rotator_ctx_release(struct sde_rotator_ctx *ctx, struct file *file) { - struct sde_rotator_device *rot_dev = ctx->rot_dev; - u32 session_id = ctx->session_id; + struct sde_rotator_device *rot_dev; + u32 session_id; struct list_head *curr, *next; + if (!ctx) { + SDEROT_DBG("ctx is NULL\n"); + return -EINVAL; + } + + rot_dev = ctx->rot_dev; + session_id = ctx->session_id; + ATRACE_END(ctx->kobj.name); SDEDEV_DBG(rot_dev->dev, "release s:%d\n", session_id); diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index 384255d7ad00..71e076badc9a 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -89,7 +89,7 @@ #define TIMESTAMP_AFTER BIT(3) #define POST_CMD_DELAY BIT(4) -#define SPI_CORE2X_VOTE (10000) +#define SPI_CORE2X_VOTE (7600) /* GSI CONFIG0 TRE Params */ /* Flags bit fields */ #define GSI_LOOPBACK_EN (BIT(0)) @@ -756,9 +756,8 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi) u32 max_speed = spi->cur_msg->spi->max_speed_hz; struct se_geni_rsc *rsc = &mas->spi_rsc; - /* Adjust the AB/IB based on the max speed of the slave.*/ + /* Adjust the IB based on the max speed of the slave.*/ rsc->ib = max_speed * DEFAULT_BUS_WIDTH; - rsc->ab = max_speed * DEFAULT_BUS_WIDTH; if (mas->shared_se) { struct se_geni_rsc *rsc; int ret = 0; diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index e3985f6fc660..37b6ad4235f5 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -756,8 +756,10 @@ static void ion_system_heap_destroy_pools(struct ion_page_pool **pools) { int i; for (i = 0; i < num_orders; i++) - if (pools[i]) + if (pools[i]) { ion_page_pool_destroy(pools[i]); + pools[i] = NULL; + } } /** diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 18b187f90b49..9a049b9e9fcc 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -413,7 +413,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd, dwc3_trace(trace_dwc3_gadget, "Command Timed Out"); dev_err(dwc->dev, "%s command timeout for %s\n", dwc3_gadget_ep_cmd_string(cmd), dep->name); - if (!(cmd & DWC3_DEPCMD_ENDTRANSFER)) { + if (cmd != DWC3_DEPCMD_ENDTRANSFER) { dwc->ep_cmd_timeout_cnt++; dwc3_notify_event(dwc, DWC3_CONTROLLER_RESTART_USB_SESSION); diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c index 0e86d287e1a0..9076ce243652 100644 --- a/drivers/usb/gadget/function/f_cdev.c +++ b/drivers/usb/gadget/function/f_cdev.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2013-2018, The Linux Foundation. All rights reserved. * Linux Foundation chooses to take subject only to the GPLv2 license terms, * and distributes only under these terms. * @@ -1251,6 +1251,7 @@ ssize_t f_cdev_write(struct file *file, ret = -EFAULT; } else { req->length = xfer_size; + req->zero = 1; ret = usb_ep_queue(in, req, GFP_KERNEL); if (ret) { pr_err("EP QUEUE failed:%d\n", ret); diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index f6d9af3efa45..cac57358f7af 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -80,6 +80,14 @@ int ahash_register_instance(struct crypto_template *tmpl, struct ahash_instance *inst); void ahash_free_instance(struct crypto_instance *inst); +int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, + unsigned int keylen); + +static inline bool crypto_shash_alg_has_setkey(struct shash_alg *alg) +{ + return alg->setkey != shash_no_setkey; +} + int crypto_init_ahash_spawn(struct crypto_ahash_spawn *spawn, struct hash_alg_common *alg, struct crypto_instance *inst); diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 1fc076420d1e..1811f8e7ddf4 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -431,8 +431,8 @@ static void hidp_del_timer(struct hidp_session *session) del_timer(&session->timer); } -static void hidp_process_report(struct hidp_session *session, - int type, const u8 *data, int len, int intr) +static void hidp_process_report(struct hidp_session *session, int type, + const u8 *data, unsigned int len, int intr) { if (len > HID_MAX_BUFFER_SIZE) len = HID_MAX_BUFFER_SIZE; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4e6c4394a96a..4fa6434872f4 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1260,14 +1260,16 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, v6_cork->tclass = ipc6->tclass; if (rt->dst.flags & DST_XFRM_TUNNEL) mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? - rt->dst.dev->mtu : dst_mtu(&rt->dst); + READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst); else mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? - rt->dst.dev->mtu : dst_mtu(rt->dst.path); + READ_ONCE(rt->dst.dev->mtu) : dst_mtu(rt->dst.path); if (np->frag_size < mtu) { if (np->frag_size) mtu = np->frag_size; } + if (mtu < IPV6_MIN_MTU) + return -EINVAL; cork->base.fragsize = mtu; if (dst_allfrag(rt->dst.path)) cork->base.flags |= IPCORK_ALLFRAG; @@ -1798,11 +1800,13 @@ struct sk_buff *ip6_make_skb(struct sock *sk, cork.base.flags = 0; cork.base.addr = 0; cork.base.opt = NULL; + cork.base.dst = NULL; v6_cork.opt = NULL; err = ip6_setup_cork(sk, &cork, &v6_cork, ipc6, rt, fl6); - if (err) + if (err) { + ip6_cork_release(&cork, &v6_cork); return ERR_PTR(err); - + } if (ipc6->dontfrag < 0) ipc6->dontfrag = inet6_sk(sk)->dontfrag; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index e7f6657269e0..1c406833b04c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1686,7 +1686,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) match->flags = flags; INIT_LIST_HEAD(&match->list); spin_lock_init(&match->lock); - atomic_set(&match->sk_ref, 0); + refcount_set(&match->sk_ref, 0); fanout_init_data(match); match->prot_hook.type = po->prot_hook.type; match->prot_hook.dev = po->prot_hook.dev; @@ -1703,17 +1703,19 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) match->prot_hook.type == po->prot_hook.type && match->prot_hook.dev == po->prot_hook.dev) { err = -ENOSPC; - if (atomic_read(&match->sk_ref) < PACKET_FANOUT_MAX) { + if (refcount_read(&match->sk_ref) < PACKET_FANOUT_MAX) { __dev_remove_pack(&po->prot_hook); po->fanout = match; - atomic_inc(&match->sk_ref); + po->rollover = rollover; + rollover = NULL; + refcount_set(&match->sk_ref, refcount_read(&match->sk_ref) + 1); __fanout_link(sk, po); err = 0; } } spin_unlock(&po->bind_lock); - if (err && !atomic_read(&match->sk_ref)) { + if (err && !refcount_read(&match->sk_ref)) { list_del(&match->list); kfree(match); } @@ -1742,7 +1744,7 @@ static struct packet_fanout *fanout_release(struct sock *sk) if (f) { po->fanout = NULL; - if (atomic_dec_and_test(&f->sk_ref)) + if (refcount_dec_and_test(&f->sk_ref)) list_del(&f->list); else f = NULL; diff --git a/net/packet/internal.h b/net/packet/internal.h index 9ee46314b7d7..94d1d405a116 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h @@ -1,6 +1,8 @@ #ifndef __PACKET_INTERNAL_H__ #define __PACKET_INTERNAL_H__ +#include <linux/refcount.h> + struct packet_mclist { struct packet_mclist *next; int ifindex; @@ -86,7 +88,7 @@ struct packet_fanout { struct list_head list; struct sock *arr[PACKET_FANOUT_MAX]; spinlock_t lock; - atomic_t sk_ref; + refcount_t sk_ref; struct packet_type prot_hook ____cacheline_aligned_in_smp; }; diff --git a/scripts/build-all.py b/scripts/build-all.py index bd468cd4bb4e..4a60ebc71d09 100755 --- a/scripts/build-all.py +++ b/scripts/build-all.py @@ -59,12 +59,8 @@ if not os.environ.get('CROSS_COMPILE'): def check_kernel(): """Ensure that PWD is a kernel directory""" - have_defconfig = any([ - os.path.isfile('arch/arm64/configs/msm_defconfig'), - os.path.isfile('arch/arm64/configs/sdm845_defconfig')]) - - if not all([os.path.isfile('MAINTAINERS'), have_defconfig]): - fail("This doesn't seem to be an MSM kernel dir") + if not os.path.isfile('MAINTAINERS'): + fail("This doesn't seem to be a kernel dir") def check_build(): """Ensure that the build directory is present.""" diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 5030fcf23681..cb7f8f730c6d 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -250,11 +250,12 @@ static int construct_key(struct key *key, const void *callout_info, * The keyring selected is returned with an extra reference upon it which the * caller must release. */ -static void construct_get_dest_keyring(struct key **_dest_keyring) +static int construct_get_dest_keyring(struct key **_dest_keyring) { struct request_key_auth *rka; const struct cred *cred = current_cred(); struct key *dest_keyring = *_dest_keyring, *authkey; + int ret; kenter("%p", dest_keyring); @@ -263,6 +264,8 @@ static void construct_get_dest_keyring(struct key **_dest_keyring) /* the caller supplied one */ key_get(dest_keyring); } else { + bool do_perm_check = true; + /* use a default keyring; falling through the cases until we * find one that we actually have */ switch (cred->jit_keyring) { @@ -277,8 +280,10 @@ static void construct_get_dest_keyring(struct key **_dest_keyring) dest_keyring = key_get(rka->dest_keyring); up_read(&authkey->sem); - if (dest_keyring) + if (dest_keyring) { + do_perm_check = false; break; + } } case KEY_REQKEY_DEFL_THREAD_KEYRING: @@ -313,11 +318,29 @@ static void construct_get_dest_keyring(struct key **_dest_keyring) default: BUG(); } + + /* + * Require Write permission on the keyring. This is essential + * because the default keyring may be the session keyring, and + * joining a keyring only requires Search permission. + * + * However, this check is skipped for the "requestor keyring" so + * that /sbin/request-key can itself use request_key() to add + * keys to the original requestor's destination keyring. + */ + if (dest_keyring && do_perm_check) { + ret = key_permission(make_key_ref(dest_keyring, 1), + KEY_NEED_WRITE); + if (ret) { + key_put(dest_keyring); + return ret; + } + } } *_dest_keyring = dest_keyring; kleave(" [dk %d]", key_serial(dest_keyring)); - return; + return 0; } /* @@ -443,11 +466,15 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx, if (ctx->index_key.type == &key_type_keyring) return ERR_PTR(-EPERM); - user = key_user_lookup(current_fsuid()); - if (!user) - return ERR_PTR(-ENOMEM); + ret = construct_get_dest_keyring(&dest_keyring); + if (ret) + goto error; - construct_get_dest_keyring(&dest_keyring); + user = key_user_lookup(current_fsuid()); + if (!user) { + ret = -ENOMEM; + goto error_put_dest_keyring; + } ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key); key_user_put(user); @@ -462,7 +489,7 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx, } else if (ret == -EINPROGRESS) { ret = 0; } else { - goto couldnt_alloc_key; + goto error_put_dest_keyring; } key_put(dest_keyring); @@ -472,8 +499,9 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx, construction_failed: key_negate_and_link(key, key_negative_timeout, NULL, NULL); key_put(key); -couldnt_alloc_key: +error_put_dest_keyring: key_put(dest_keyring); +error: kleave(" = %d", ret); return ERR_PTR(ret); } |