diff --git a/AndroidKernel.mk b/AndroidKernel.mk index d48eecd6cb04ba377ac26e0f84101de2f662d73e..4424983cf4023da50163a3e5f09909a7ad63292c 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -26,7 +26,6 @@ TARGET_KERNEL_HEADER_ARCH := $(strip $(TARGET_KERNEL_HEADER_ARCH)) ifeq ($(TARGET_KERNEL_HEADER_ARCH),) KERNEL_HEADER_ARCH := $(KERNEL_ARCH) else -$(warning Forcing kernel header generation only for '$(TARGET_KERNEL_HEADER_ARCH)') KERNEL_HEADER_ARCH := $(TARGET_KERNEL_HEADER_ARCH) endif @@ -59,7 +58,6 @@ ifeq ($(KERNEL_LLVM_SUPPORT), true) $(warning "Using sdllvm" $(KERNEL_LLVM_BIN)) else KERNEL_LLVM_BIN := $(shell pwd)/$(CLANG) #Using aosp-llvm compiler - $(warning "Using aosp-llvm" $(KERNEL_LLVM_BIN)) endif endif @@ -70,9 +68,9 @@ KERNEL_GCC_NOANDROID_CHK := $(shell (echo "int main() {return 0;}" | $(KERNEL_CR real_cc := ifeq ($(KERNEL_LLVM_SUPPORT),true) ifeq ($(KERNEL_ARCH), arm64) - real_cc := REAL_CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=aarch64-linux-gnu- + real_cc := CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=aarch64-linux-gnu- else - real_cc := REAL_CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=arm-linux-gnueabihf + real_cc := CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=arm-linux-gnueabihf endif else ifeq ($(strip $(KERNEL_GCC_NOANDROID_CHK)),0) diff --git a/Makefile b/Makefile index bf0aff17b08ce3a4907247881629b0460c6ec173..e9be6949757faff281cd99c7e96dcddaf129c6b9 100644 --- a/Makefile +++ b/Makefile @@ -348,7 +348,7 @@ include scripts/Kbuild.include # Make variables (CC, etc...) AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld -REAL_CC = $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc LDGOLD = $(CROSS_COMPILE)ld.gold CPP = $(CC) -E AR = $(CROSS_COMPILE)ar @@ -364,10 +364,6 @@ PERL = perl PYTHON = python CHECK = sparse -# Use the wrapper for the compiler. This wrapper scans for new -# warnings and causes the build to stop upon encountering them -CC = $(PYTHON) $(srctree)/scripts/gcc-wrapper.py $(REAL_CC) - CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ -Wbitwise -Wno-return-void $(CF) NOSTDINC_FLAGS = @@ -535,7 +531,6 @@ KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier) KBUILD_CFLAGS += $(call cc-disable-warning, gnu) KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS += $(call cc-disable-warning, duplicate-decl-specifier) -KBUILD_CFLAGS += -Wno-undefined-optimized KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare KBUILD_CFLAGS += $(call cc-option, -Wno-sometimes-uninitialized) KBUILD_CFLAGS += -Wno-asm-operand-widths diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index 6011a1b57b4b5b20c038655fd30e3ca8894f7e03..c4dacd7a1e84a33991888023d7a032a7e245b7c7 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -355,7 +355,7 @@ CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y CONFIG_POWER_RESET_QCOM=y -CONFIG_QCOM_DLOAD_MODE=y +CONFIG_QCOM_DLOAD_MODE=n CONFIG_QPNP_FG=y CONFIG_SMB135X_CHARGER=y CONFIG_SMB1355_SLAVE_CHARGER=y diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 2b05d83fb8f611865129b7b6e38a7a2ee23559f5..2088db4518027ead3187e7f37358c0219f73a5db 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -917,6 +917,9 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, (unsigned int)map->attr); map->refs = 2; } + VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd))); + if (err) + goto bail; VERIFY(err, !IS_ERR_OR_NULL(map->handle = ion_import_dma_buf_fd(fl->apps->client, fd))); if (err) @@ -947,9 +950,6 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, if (map->attr & FASTRPC_ATTR_NOVA && !sess->smmu.coherent) map->uncached = 1; - VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd))); - if (err) - goto bail; VERIFY(err, !IS_ERR_OR_NULL(map->attach = dma_buf_attach(map->buf, sess->smmu.dev))); if (err) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index cb9f4e46607e70d97f415b9dfae1dfa3ccc22d00..f2adbb7286465723632a8dc71f39a27c8ad6bb36 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2022, 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 @@ -1619,7 +1619,6 @@ static int diag_send_dci_pkt(struct diag_cmd_reg_t *entry, return -EIO; } - mutex_lock(&driver->dci_mutex); /* prepare DCI packet */ header.start = CONTROL_CHAR; header.version = 1; @@ -1638,7 +1637,6 @@ static int diag_send_dci_pkt(struct diag_cmd_reg_t *entry, diag_update_pkt_buffer(driver->apps_dci_buf, write_len, DCI_PKT_TYPE); diag_update_sleeping_process(entry->pid, DCI_PKT_TYPE); - mutex_unlock(&driver->dci_mutex); return DIAG_DCI_NO_ERROR; } @@ -1658,7 +1656,6 @@ static int diag_send_dci_pkt(struct diag_cmd_reg_t *entry, entry->proc); status = DIAG_DCI_SEND_DATA_FAIL; } - mutex_unlock(&driver->dci_mutex); return status; } @@ -1984,12 +1981,13 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) { int ret = DIAG_DCI_TABLE_ERR; int common_cmd = 0, header_len = 0; + int req_tag = 0; struct diag_pkt_header_t *header = NULL; unsigned char *temp = buf; unsigned char *req_buf = NULL; uint8_t retry_count = 0, max_retries = 3; uint32_t read_len = 0, req_len = len; - struct dci_pkt_req_entry_t *req_entry = NULL; + struct dci_pkt_req_entry_t *req_entry = NULL, *test_entry = NULL; struct diag_dci_client_tbl *dci_entry = NULL; struct dci_pkt_req_t req_hdr; struct diag_cmd_reg_t *reg_item; @@ -2093,6 +2091,7 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) mutex_unlock(&driver->dci_mutex); return DIAG_DCI_NO_REG; } + req_tag = req_entry->tag; mutex_unlock(&driver->dci_mutex); /* @@ -2100,14 +2099,14 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) * remote processor */ if (dci_entry->client_info.token > 0) { - ret = diag_send_dci_pkt_remote(req_buf, req_len, req_entry->tag, + ret = diag_send_dci_pkt_remote(req_buf, req_len, req_tag, dci_entry->client_info.token); return ret; } /* Check if it is a dedicated Apps command */ ret = diag_dci_process_apps_pkt(header, req_buf, req_len, - req_entry->tag, header_len); + req_tag, header_len); if ((ret == DIAG_DCI_NO_ERROR && !common_cmd) || ret < 0) return ret; @@ -2130,8 +2129,14 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) if (temp_entry) { reg_item = container_of(temp_entry, struct diag_cmd_reg_t, entry); - ret = diag_send_dci_pkt(reg_item, req_buf, req_len, - req_entry->tag); + mutex_lock(&driver->dci_mutex); + test_entry = diag_dci_get_request_entry(req_tag); + if (test_entry) + ret = diag_send_dci_pkt(reg_item, req_buf, req_len, + test_entry->tag); + else + ret = -EIO; + mutex_unlock(&driver->dci_mutex); } else { DIAG_LOG(DIAG_DEBUG_DCI, "Command not found: %02x %02x %02x\n", reg_entry.cmd_code, reg_entry.subsys_id, diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c index f40b24c852e3a81dfc8c6009508063d05550011e..0cda4bafcca245d0f0d28930c18d65a44afd78f3 100644 --- a/drivers/gpu/drm/drm_dp_cec.c +++ b/drivers/gpu/drm/drm_dp_cec.c @@ -113,7 +113,7 @@ static int drm_dp_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg) { struct drm_dp_aux *aux = cec_get_drvdata(adap); - unsigned int retries = min(5, attempts - 1); + unsigned int retries = min(2, attempts - 1); ssize_t err; err = drm_dp_dpcd_write(aux, DP_CEC_TX_MESSAGE_BUFFER, diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index e967eb6c9bc981c0f4bf4949b1bfb30d934225e4..373835f0fdbb89b29110b36adfc321c7f978f433 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -146,13 +147,6 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) dp = container_of(dw, struct dp_display_private, hdcp_cb_work); - dp_display_update_hdcp_info(dp); - - if (!dp_display_is_hdcp_enabled(dp)) - return; - - dp->link->hdcp_status.hdcp_state = HDCP_STATE_AUTHENTICATING; - rc = dp->catalog->ctrl.read_hdcp_status(&dp->catalog->ctrl); if (rc >= 0) { hdcp_auth_state = (rc >> 20) & 0x3; @@ -474,13 +468,15 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, bool hpd) { int ret = 0; + static int bootsplash_count; dp->dp_display.is_connected = hpd; if (!dp_display_framework_ready(dp)) { pr_err("%s: dp display framework not ready\n", __func__); - if (!dp->dp_display.is_bootsplash_en) { + if (!dp->dp_display.is_bootsplash_en && !bootsplash_count) { dp->dp_display.is_bootsplash_en = true; + bootsplash_count++; drm_client_dev_register(dp->dp_display.drm_dev); } return ret; @@ -796,7 +792,7 @@ static int dp_display_usbpd_attention_cb(struct device *dev) return -ENODEV; } - if (dp->usbpd->hpd_high && dp->usbpd->hpd_irq) + if (dp->usbpd->hpd_irq && dp->usbpd->hpd_high && !dp->power_on) drm_dp_cec_irq(dp->aux->drm_aux); if (dp->usbpd->hpd_irq && dp->usbpd->hpd_high && @@ -1150,6 +1146,11 @@ static int dp_display_post_enable(struct dp_display *dp_display) goto end; } + if (dp->dp_display.is_bootsplash_en) { + dp->dp_display.is_bootsplash_en = false; + goto end; + } + dp->panel->spd_config(dp->panel); if (dp->audio_supported) { @@ -1158,9 +1159,12 @@ static int dp_display_post_enable(struct dp_display *dp_display) dp->audio_status = dp->audio->on(dp->audio); } - if (dp->hdcp.feature_enabled && 0) { /* bootsplash check */ + dp_display_update_hdcp_info(dp); + + if (dp_display_is_hdcp_enabled(dp)) { cancel_delayed_work_sync(&dp->hdcp_cb_work); + dp->link->hdcp_status.hdcp_state = HDCP_STATE_AUTHENTICATING; queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ / 2); } diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c index 3ebac9001c0fdb580fabd5bc6995a44e5ebff56c..23dd0bcbfaa5d6d4ca7435d25b607082223d83d6 100644 --- a/drivers/gpu/drm/msm/dp/dp_link.c +++ b/drivers/gpu/drm/msm/dp/dp_link.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2018,2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -792,6 +793,8 @@ static int dp_link_parse_request(struct dp_link_private *link) pr_debug("device service irq vector = 0x%x\n", data); + drm_dp_cec_irq(link->aux->drm_aux); + if (!(data & DP_AUTOMATED_TEST_REQUEST)) { pr_debug("no test requested\n"); return 0; diff --git a/drivers/gpu/msm/a6xx_reg.h b/drivers/gpu/msm/a6xx_reg.h index e3a664e62577725179e62d550d70e07cb4ea2040..0dc9bc1f0a990cd6a3c31ef74707d8134a5616b0 100644 --- a/drivers/gpu/msm/a6xx_reg.h +++ b/drivers/gpu/msm/a6xx_reg.h @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -395,6 +396,8 @@ #define A6XX_RBBM_PERFCTR_RBBM_SEL_2 0x509 #define A6XX_RBBM_PERFCTR_RBBM_SEL_3 0x50A #define A6XX_RBBM_PERFCTR_GPU_BUSY_MASKED 0x50B +#define A6XX_RBBM_PERFCTR_SRAM_INIT_CMD 0x50e +#define A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS 0x50f #define A6XX_RBBM_ISDB_CNT 0x533 diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index be168688ae8d97e1189eeda1020dc1ba12d732a6..284dba3f1c5dbceb072fe56a6d5b2b588ea4bc32 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -1,4 +1,5 @@ /* Copyright (c) 2002,2007-2018,2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -1426,6 +1427,8 @@ static int adreno_probe(struct platform_device *pdev) adreno_debugfs_init(adreno_dev); adreno_profile_init(adreno_dev); + adreno_dev->perfcounter = false; + adreno_sysfs_init(adreno_dev); kgsl_pwrscale_init(&pdev->dev, CONFIG_QCOM_ADRENO_DEFAULT_GOVERNOR); diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 43125221826ab4e78adb3b5205c1920adbea2be7..ea8ad562234a834e161f4c2c4a8c08f81cef1dc3 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -1,4 +1,5 @@ /* Copyright (c) 2008-2018,2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -34,6 +35,9 @@ #define DEVICE_3D_NAME "kgsl-3d" #define DEVICE_3D0_NAME "kgsl-3d0" +/* Index to preemption scratch buffer to store KMD postamble */ +#define KMD_POSTAMBLE_IDX 100 + /* ADRENO_DEVICE - Given a kgsl_device return the adreno device struct */ #define ADRENO_DEVICE(device) \ container_of(device, struct adreno_device, dev) @@ -251,6 +255,9 @@ struct adreno_gpudev; /* Time to allow preemption to complete (in ms) */ #define ADRENO_PREEMPT_TIMEOUT 10000 +#define PREEMPT_SCRATCH_ADDR(dev, id) \ + ((dev)->preempt.scratch.gpuaddr + (id * sizeof(u64))) + #define ADRENO_INT_BIT(a, _bit) (((a)->gpucore->gpudev->int_bits) ? \ (adreno_get_int(a, _bit) < 0 ? 0 : \ BIT(adreno_get_int(a, _bit))) : 0) @@ -287,6 +294,7 @@ enum adreno_preempt_states { * skipsaverestore: To skip saverestore during L1 preemption (for 6XX) * usesgmem: enable GMEM save/restore across preemption (for 6XX) * count: Track the number of preemptions triggered + * @postamble_len: Number of dwords in KMD postamble pm4 packet */ struct adreno_preemption { atomic_t state; @@ -298,6 +306,7 @@ struct adreno_preemption { bool skipsaverestore; bool usesgmem; unsigned int count; + u32 postamble_len; }; @@ -578,6 +587,11 @@ struct adreno_device { bool gpuhtw_llc_slice_enable; unsigned int zap_loaded; unsigned int soc_hw_rev; + /* + * @perfcounter: Flag to clear perfcounters across contexts and + * controls perfcounter ioctl read + */ + bool perfcounter; }; /** diff --git a/drivers/gpu/msm/adreno_a6xx_preempt.c b/drivers/gpu/msm/adreno_a6xx_preempt.c index 32740a0189091c465964debf95487f89b47727ab..a5068687185e3e93f5263575fe2e76647a737593 100644 --- a/drivers/gpu/msm/adreno_a6xx_preempt.c +++ b/drivers/gpu/msm/adreno_a6xx_preempt.c @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2018,2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -544,13 +545,27 @@ unsigned int a6xx_preemption_pre_ibsubmit( if (context) { struct adreno_context *drawctxt = ADRENO_CONTEXT(context); struct adreno_ringbuffer *rb = drawctxt->rb; - uint64_t dest = adreno_dev->preempt.scratch.gpuaddr + - sizeof(u64) * rb->id; + uint64_t dest = PREEMPT_SCRATCH_ADDR(adreno_dev, rb->id); *cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2); cmds += cp_gpuaddr(adreno_dev, cmds, dest); *cmds++ = lower_32_bits(gpuaddr); *cmds++ = upper_32_bits(gpuaddr); + + /* + * Add a KMD post amble to clear the perf counters during + * preemption + */ + if (!adreno_dev->perfcounter) { + u64 kmd_postamble_addr = + PREEMPT_SCRATCH_ADDR(adreno_dev, KMD_POSTAMBLE_IDX); + + *cmds++ = cp_type7_packet(CP_SET_AMBLE, 3); + *cmds++ = lower_32_bits(kmd_postamble_addr); + *cmds++ = upper_32_bits(kmd_postamble_addr); + *cmds++ = ((CP_KMD_AMBLE_TYPE << 20) | GENMASK(22, 20)) + | (adreno_dev->preempt.postamble_len | GENMASK(19, 0)); + } } return (unsigned int) (cmds - cmds_orig); @@ -563,8 +578,7 @@ unsigned int a6xx_preemption_post_ibsubmit(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb = adreno_dev->cur_rb; if (rb) { - uint64_t dest = adreno_dev->preempt.scratch.gpuaddr + - sizeof(u64) * rb->id; + uint64_t dest = PREEMPT_SCRATCH_ADDR(adreno_dev, rb->id); *cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2); cmds += cp_gpuaddr(adreno_dev, cmds, dest); @@ -769,6 +783,33 @@ int a6xx_preemption_init(struct adreno_device *adreno_dev) addr += A6XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE; } + /* + * First 8 dwords of the preemption scratch buffer is used to store the + * address for CP to save/restore VPC data. Reserve 11 dwords in the + * preemption scratch buffer from index KMD_POSTAMBLE_IDX for KMD + * postamble pm4 packets + */ + if (!adreno_dev->perfcounter) { + u32 *postamble = preempt->scratch.hostptr + + (KMD_POSTAMBLE_IDX * sizeof(u64)); + u32 count = 0; + + postamble[count++] = cp_type7_packet(CP_REG_RMW, 3); + postamble[count++] = A6XX_RBBM_PERFCTR_SRAM_INIT_CMD; + postamble[count++] = 0x0; + postamble[count++] = 0x1; + + postamble[count++] = cp_type7_packet(CP_WAIT_REG_MEM, 6); + postamble[count++] = 0x3; + postamble[count++] = A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS; + postamble[count++] = 0x0; + postamble[count++] = 0x1; + postamble[count++] = 0x1; + postamble[count++] = 0x0; + + preempt->postamble_len = count; + } + ret = a6xx_preemption_iommu_init(adreno_dev); err: diff --git a/drivers/gpu/msm/adreno_compat.c b/drivers/gpu/msm/adreno_compat.c index 1f806dabea2531fa53f807c3e61119c3b94051a4..3b15d0318a193c276792097713cca43c01a89f3f 100644 --- a/drivers/gpu/msm/adreno_compat.c +++ b/drivers/gpu/msm/adreno_compat.c @@ -1,4 +1,5 @@ /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -260,6 +261,14 @@ static long adreno_ioctl_perfcounter_read_compat( struct kgsl_perfcounter_read_compat *read32 = data; struct kgsl_perfcounter_read read; + /* + * When performance counter zapping is enabled, the counters are cleared + * across context switches. Reading the counters when they are zapped is + * not permitted. + */ + if (!adreno_dev->perfcounter) + return -EPERM; + read.reads = (struct kgsl_perfcounter_read_group __user *) (uintptr_t)read32->reads; read.count = read32->count; diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index b4bc750a9c1ae4f92144643aea4ca4484a6a79c8..d3d9675375d8da5dc1a0af1a22eb3d11194643b3 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -1155,7 +1155,8 @@ static inline bool _verify_ib(struct kgsl_device_private *dev_priv, } /* Make sure that the address is mapped */ - if (!kgsl_mmu_gpuaddr_in_range(private->pagetable, ib->gpuaddr)) { + if (!kgsl_mmu_gpuaddr_in_range(private->pagetable, ib->gpuaddr, + ib->size)) { pr_context(device, context, "ctxt %d invalid ib gpuaddr %llX\n", context->id, ib->gpuaddr); return false; diff --git a/drivers/gpu/msm/adreno_ioctl.c b/drivers/gpu/msm/adreno_ioctl.c index ff9a69a291308d47ca393c7fbf24867174ff820f..04ae62abe3b868afc1a987f0bcfdf22cc2ae5d1c 100644 --- a/drivers/gpu/msm/adreno_ioctl.c +++ b/drivers/gpu/msm/adreno_ioctl.c @@ -1,4 +1,5 @@ /* Copyright (c) 2002,2007-2018,2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -141,6 +142,14 @@ static long adreno_ioctl_perfcounter_read(struct kgsl_device_private *dev_priv, struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_priv->device); struct kgsl_perfcounter_read *read = data; + /* + * When performance counter zapping is enabled, the counters are cleared + * across context switches. Reading the counters when they are zapped is + * not permitted. + */ + if (!adreno_dev->perfcounter) + return -EPERM; + return (long) adreno_perfcounter_read_group(adreno_dev, read->reads, read->count); } diff --git a/drivers/gpu/msm/adreno_iommu.c b/drivers/gpu/msm/adreno_iommu.c index db6dff212b6478477353c61a7b61e01ca899b24c..032a19c1d37acd7a3574760e6dba4db47178c8dc 100644 --- a/drivers/gpu/msm/adreno_iommu.c +++ b/drivers/gpu/msm/adreno_iommu.c @@ -1,4 +1,5 @@ /* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -13,6 +14,7 @@ #include "adreno.h" #include "kgsl_sharedmem.h" #include "a3xx_reg.h" +#include "a6xx_reg.h" #include "adreno_pm4types.h" #define A5XX_PFP_PER_PROCESS_UCODE_VER 0x5FF064 @@ -586,6 +588,12 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device, cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds); cmds += cp_wait_for_me(adreno_dev, cmds); + /* Clear performance counters during contect switches */ + if (!adreno_dev->perfcounter) { + *cmds++ = cp_type4_packet(A6XX_RBBM_PERFCTR_SRAM_INIT_CMD, 1); + *cmds++ = 0x1; + } + /* CP switches the pagetable and flushes the Caches */ *cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 4); *cmds++ = lower_32_bits(ttbr0); @@ -605,6 +613,17 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device, cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds); + /* Wait for performance counter clear to finish */ + if (!adreno_dev->perfcounter) { + *cmds++ = cp_type7_packet(CP_WAIT_REG_MEM, 6); + *cmds++ = 0x3; + *cmds++ = A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS; + *cmds++ = 0x0; + *cmds++ = 0x1; + *cmds++ = 0x1; + *cmds++ = 0x0; + } + return cmds - cmds_orig; } diff --git a/drivers/gpu/msm/adreno_perfcounter.c b/drivers/gpu/msm/adreno_perfcounter.c index 50207509d7839edcb9e6f5ac84538c9d7c89d0a0..c62bdba1f23d1589b6bbd767150412612b32ecf6 100644 --- a/drivers/gpu/msm/adreno_perfcounter.c +++ b/drivers/gpu/msm/adreno_perfcounter.c @@ -1,4 +1,5 @@ /* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -143,7 +144,8 @@ void adreno_perfcounter_restore(struct adreno_device *adreno_dev) struct adreno_perfcount_group *group; unsigned int counter, groupid; - if (counters == NULL) + /* Do not save/restore if not requested */ + if (counters == NULL || !adreno_dev->perfcounter) return; for (groupid = 0; groupid < counters->group_count; groupid++) { @@ -177,7 +179,8 @@ inline void adreno_perfcounter_save(struct adreno_device *adreno_dev) unsigned int counter, groupid; int ret = 0; - if (counters == NULL) + /* Do not save/restore if not requested */ + if (counters == NULL || !adreno_dev->perfcounter) return; if (gpudev->oob_set) diff --git a/drivers/gpu/msm/adreno_pm4types.h b/drivers/gpu/msm/adreno_pm4types.h index cf30a834546b6b84834e099ecda0dba41835bb31..f36c713d0ddd6bfc1b434690545731e2345d1594 100644 --- a/drivers/gpu/msm/adreno_pm4types.h +++ b/drivers/gpu/msm/adreno_pm4types.h @@ -1,4 +1,5 @@ /* Copyright (c) 2002,2007-2017,2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -55,6 +56,9 @@ /* switches SMMU pagetable, used on a5xx only */ #define CP_SMMU_TABLE_UPDATE 0x53 +/* Designate command streams to be executed before/after state restore */ +#define CP_SET_AMBLE 0x55 + /* Set internal CP registers, used to indicate context save data addresses */ #define CP_SET_PSEUDO_REGISTER 0x56 @@ -162,6 +166,9 @@ #define CP_LOADSTATE_STATETYPE_SHIFT 0x00000000 #define CP_LOADSTATE_EXTSRCADDR_SHIFT 0x00000002 +/* Used to define amble type in SET_AMBLE packet to execute during preemption */ +#define CP_KMD_AMBLE_TYPE 3 + static inline uint pm4_calc_odd_parity_bit(uint val) { return (0x9669 >> (0xf & ((val) ^ diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c index c37a3c2f703e70f692b893234281982deef9ce61..78020d66e284f9b9e812e5a8f6e6d14ee0c95ed6 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.c +++ b/drivers/gpu/msm/adreno_ringbuffer.c @@ -1,4 +1,5 @@ /* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -555,7 +556,7 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb, if (gpudev->preemption_pre_ibsubmit && adreno_is_preemption_enabled(adreno_dev)) - total_sizedwords += 27; + total_sizedwords += 31; if (gpudev->preemption_post_ibsubmit && adreno_is_preemption_enabled(adreno_dev)) diff --git a/drivers/gpu/msm/adreno_sysfs.c b/drivers/gpu/msm/adreno_sysfs.c index a7aa93927a6cb2bbcece727a6c56675805031266..9c10edd0a84351a073d877f99dcf9bd3de547920 100644 --- a/drivers/gpu/msm/adreno_sysfs.c +++ b/drivers/gpu/msm/adreno_sysfs.c @@ -1,4 +1,5 @@ /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -353,6 +354,31 @@ static unsigned int _preempt_count_show(struct adreno_device *adreno_dev) return preempt->count; } +static unsigned int _perfcounter_show(struct adreno_device *adreno_dev) +{ + return adreno_dev->perfcounter; +} + +static int _perfcounter_store(struct adreno_device *adreno_dev, + unsigned int val) +{ + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + + if (adreno_dev->perfcounter == val) + return 0; + + mutex_lock(&device->mutex); + + /* Power down the GPU before changing the state */ + kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND); + adreno_dev->perfcounter = val; + kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER); + + mutex_unlock(&device->mutex); + + return 0; +} + static ssize_t _sysfs_store_u32(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -457,6 +483,7 @@ static ADRENO_SYSFS_BOOL(hwcg); static ADRENO_SYSFS_BOOL(throttling); static ADRENO_SYSFS_BOOL(ifpc); static ADRENO_SYSFS_RO_U32(ifpc_count); +static ADRENO_SYSFS_BOOL(perfcounter); @@ -480,6 +507,7 @@ static const struct device_attribute *_attr_list[] = { &adreno_attr_ifpc.attr, &adreno_attr_ifpc_count.attr, &adreno_attr_preempt_count.attr, + &adreno_attr_perfcounter.attr, NULL, }; @@ -637,8 +665,11 @@ int adreno_sysfs_init(struct adreno_device *adreno_dev) ret = kgsl_create_device_sysfs_files(device->dev, _attr_list); /* Add the PPD directory and files */ - if (ret == 0) + if (ret == 0) { + /* Notify userspace */ + kobject_uevent(&device->dev->kobj, KOBJ_ADD); ppd_sysfs_init(adreno_dev); + } return 0; } diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 5d76314cd809fd1a6b260ffa33412275bb909dfc..aeeebeb5e4aa23aa0e2b48fcdbfda17c4c6d5fae 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1257,7 +1257,7 @@ kgsl_sharedmem_find(struct kgsl_process_private *private, uint64_t gpuaddr) if (!private) return NULL; - if (!kgsl_mmu_gpuaddr_in_range(private->pagetable, gpuaddr)) + if (!kgsl_mmu_gpuaddr_in_range(private->pagetable, gpuaddr, 0)) return NULL; spin_lock(&private->mem_lock); @@ -2243,15 +2243,6 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable, } #ifdef CONFIG_DMA_SHARED_BUFFER -static int match_file(const void *p, struct file *file, unsigned int fd) -{ - /* - * We must return fd + 1 because iterate_fd stops searching on - * non-zero return, but 0 is a valid fd. - */ - return (p == file) ? (fd + 1) : 0; -} - static void _setup_cache_mode(struct kgsl_mem_entry *entry, struct vm_area_struct *vma) { @@ -2289,8 +2280,6 @@ static int kgsl_setup_dmabuf_useraddr(struct kgsl_device *device, vma = find_vma(current->mm, hostptr); if (vma && vma->vm_file) { - int fd; - ret = check_vma_flags(vma, entry->memdesc.flags); if (ret) { up_read(¤t->mm->mmap_sem); @@ -2306,10 +2295,13 @@ static int kgsl_setup_dmabuf_useraddr(struct kgsl_device *device, return -EFAULT; } - /* Look for the fd that matches this the vma file */ - fd = iterate_fd(current->files, 0, match_file, vma->vm_file); - if (fd != 0) - dmabuf = dma_buf_get(fd - 1); + /* + * Take a refcount because dma_buf_put() decrements the + * refcount + */ + get_file(vma->vm_file); + + dmabuf = vma->vm_file->private_data; } if (IS_ERR_OR_NULL(dmabuf)) { diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 399eb6d8d1d7cdc7f4a322f8a51d54ed794755aa..32335893c561ad5b04fa2a4684253ad6a3bf794c 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -2567,20 +2567,21 @@ static int kgsl_iommu_svm_range(struct kgsl_pagetable *pagetable, } static bool kgsl_iommu_addr_in_range(struct kgsl_pagetable *pagetable, - uint64_t gpuaddr) + uint64_t gpuaddr, uint64_t size) { struct kgsl_iommu_pt *pt = pagetable->priv; if (gpuaddr == 0) return false; - if (gpuaddr >= pt->va_start && gpuaddr < pt->va_end) + if (gpuaddr >= pt->va_start && (gpuaddr + size) < pt->va_end) return true; - if (gpuaddr >= pt->compat_va_start && gpuaddr < pt->compat_va_end) + if (gpuaddr >= pt->compat_va_start && + (gpuaddr + size) < pt->compat_va_end) return true; - if (gpuaddr >= pt->svm_start && gpuaddr < pt->svm_end) + if (gpuaddr >= pt->svm_start && (gpuaddr + size) < pt->svm_end) return true; return false; diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index 456c0e1dacfe489007ff82680f6dc724ab2ddf7f..eaff74339c653dc3dbba243708a0c6ed65922fbd 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -613,10 +613,11 @@ enum kgsl_mmutype kgsl_mmu_get_mmutype(struct kgsl_device *device) EXPORT_SYMBOL(kgsl_mmu_get_mmutype); bool kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pagetable, - uint64_t gpuaddr) + uint64_t gpuaddr, uint64_t size) { if (PT_OP_VALID(pagetable, addr_in_range)) - return pagetable->pt_ops->addr_in_range(pagetable, gpuaddr); + return pagetable->pt_ops->addr_in_range(pagetable, + gpuaddr, size); return false; } @@ -652,7 +653,7 @@ EXPORT_SYMBOL(kgsl_mmu_get_qtimer_global_entry); */ static bool nommu_gpuaddr_in_range(struct kgsl_pagetable *pagetable, - uint64_t gpuaddr) + uint64_t gpuaddr, uint64_t size) { return (gpuaddr != 0) ? true : false; } diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h index 430a14081d35fbc04677d41ab2adf8776e05455c..f75475f7e65fc466be3e37653e40cc0a247f3036 100644 --- a/drivers/gpu/msm/kgsl_mmu.h +++ b/drivers/gpu/msm/kgsl_mmu.h @@ -102,7 +102,8 @@ struct kgsl_mmu_pt_ops { int (*set_svm_region)(struct kgsl_pagetable *, uint64_t, uint64_t); int (*svm_range)(struct kgsl_pagetable *, uint64_t *, uint64_t *, uint64_t); - bool (*addr_in_range)(struct kgsl_pagetable *pagetable, uint64_t); + bool (*addr_in_range)(struct kgsl_pagetable *pagetable, + uint64_t, uint64_t); int (*mmu_map_offset)(struct kgsl_pagetable *pt, uint64_t virtaddr, uint64_t virtoffset, struct kgsl_memdesc *memdesc, uint64_t physoffset, @@ -194,7 +195,8 @@ unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr); unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu, u64 ttbr0, uint64_t addr); enum kgsl_mmutype kgsl_mmu_get_mmutype(struct kgsl_device *device); -bool kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pt, uint64_t gpuaddr); +bool kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pt, uint64_t gpuaddr, + uint64_t size); int kgsl_mmu_get_region(struct kgsl_pagetable *pagetable, uint64_t gpuaddr, uint64_t size); diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 7e492394273259080b772fa7dfb7fbeffe0f4df5..849f5a359e30c688f171409ff2133343f1bb9bea 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -176,14 +176,14 @@ config HID_CHERRY config HID_CHICONY tristate "Chicony devices" - depends on HID + depends on USB_HID default !EXPERT ---help--- Support for Chicony Tactical pad and special keys on Chicony keyboards. config HID_CORSAIR tristate "Corsair devices" - depends on HID && USB && LEDS_CLASS + depends on USB_HID && LEDS_CLASS ---help--- Support for Corsair devices that are not fully compliant with the HID standard. @@ -194,7 +194,7 @@ config HID_CORSAIR config HID_PRODIKEYS tristate "Prodikeys PC-MIDI Keyboard support" - depends on HID && SND + depends on USB_HID && SND select SND_RAWMIDI ---help--- Support for Prodikeys PC-MIDI Keyboard device support. @@ -421,7 +421,7 @@ config HID_LENOVO config HID_LOGITECH tristate "Logitech devices" - depends on HID + depends on USB_HID default !EXPERT ---help--- Support for Logitech devices that are not fully compliant with HID standard. @@ -741,7 +741,7 @@ config HID_SAITEK config HID_SAMSUNG tristate "Samsung InfraRed remote control or keyboards" - depends on HID + depends on USB_HID ---help--- Support for Samsung InfraRed remote control or keyboards. diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index f04ed9aabc3f9fea0baf5b074acd83b6d07527c6..f11948ddf642e72c934167aa9e25571cb1ef7b7c 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c @@ -61,8 +61,12 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, static __u8 *ch_switch12_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - + struct usb_interface *intf; + + if (!hid_is_usb(hdev)) + return rdesc; + + intf = to_usb_interface(hdev->dev.parent); if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { /* Change usage maximum and logical maximum from 0x7fff to * 0x2fff, so they don't exceed HID_MAX_USAGES */ diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c index 9ba5d98a118042a52dc40b895c3b2e8df67c0b39..d8cf08b6b31c65dab3ef72dd1ea3a48377a59dda 100644 --- a/drivers/hid/hid-corsair.c +++ b/drivers/hid/hid-corsair.c @@ -553,7 +553,12 @@ static int corsair_probe(struct hid_device *dev, const struct hid_device_id *id) int ret; unsigned long quirks = id->driver_data; struct corsair_drvdata *drvdata; - struct usb_interface *usbif = to_usb_interface(dev->dev.parent); + struct usb_interface *usbif; + + if (!hid_is_usb(dev)) + return -EINVAL; + + usbif = to_usb_interface(dev->dev.parent); drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata), GFP_KERNEL); diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c index 5eea6fe0d7bd8181082599a4ed0f05eda3268d5c..c3ecac13e62035a0ff761da030494e4d20d7e00f 100644 --- a/drivers/hid/hid-elo.c +++ b/drivers/hid/hid-elo.c @@ -230,6 +230,9 @@ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id) struct elo_priv *priv; int ret; + if (!hid_is_usb(hdev)) + return -EINVAL; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/hid/hid-holtek-kbd.c b/drivers/hid/hid-holtek-kbd.c index ab9da597106fa5f49d4a12c07cbfff76ad33088d..2f8eb663974445f88d18e56e3d07a61b9a5385bb 100644 --- a/drivers/hid/hid-holtek-kbd.c +++ b/drivers/hid/hid-holtek-kbd.c @@ -143,12 +143,17 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type, static int holtek_kbd_probe(struct hid_device *hdev, const struct hid_device_id *id) { - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - int ret = hid_parse(hdev); + struct usb_interface *intf; + int ret; + + if (!hid_is_usb(hdev)) + return -EINVAL; + ret = hid_parse(hdev); if (!ret) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + intf = to_usb_interface(hdev->dev.parent); if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) { struct hid_input *hidinput; list_for_each_entry(hidinput, &hdev->inputs, list) { diff --git a/drivers/hid/hid-holtek-mouse.c b/drivers/hid/hid-holtek-mouse.c index 78b3a0c767751534c16167846cfb3571641ce6af..96db7e96fcea9940c8a7848f9438d1cedb630908 100644 --- a/drivers/hid/hid-holtek-mouse.c +++ b/drivers/hid/hid-holtek-mouse.c @@ -65,6 +65,29 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, return rdesc; } +static int holtek_mouse_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + int ret; + + if (!hid_is_usb(hdev)) + return -EINVAL; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "hid parse failed: %d\n", ret); + return ret; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hw start failed: %d\n", ret); + return ret; + } + + return 0; +} + static const struct hid_device_id holtek_mouse_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, @@ -86,6 +109,7 @@ static struct hid_driver holtek_mouse_driver = { .name = "holtek_mouse", .id_table = holtek_mouse_devices, .report_fixup = holtek_mouse_report_fixup, + .probe = holtek_mouse_probe, }; module_hid_driver(holtek_mouse_driver); diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 7e55d3f755dd569bd2c904d83e40710afc53f0d3..f8d1d481c83849bdc59b67c9082860c8cb4e46e7 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -714,12 +714,18 @@ static int lg_raw_event(struct hid_device *hdev, struct hid_report *report, static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) { - struct usb_interface *iface = to_usb_interface(hdev->dev.parent); - __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; + struct usb_interface *iface; + __u8 iface_num; unsigned int connect_mask = HID_CONNECT_DEFAULT; struct lg_drv_data *drv_data; int ret; + if (!hid_is_usb(hdev)) + return -EINVAL; + + iface = to_usb_interface(hdev->dev.parent); + iface_num = iface->cur_altsetting->desc.bInterfaceNumber; + /* G29 only work with the 1st interface */ if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) && (iface_num != 0)) { diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index 762f33817dd0d4a4fe04bbfe6761ec2412d19e0c..7c3e42efbc5672bb7d3a7ee3a0554a8b5af5e48d 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -803,12 +803,18 @@ static int pk_raw_event(struct hid_device *hdev, struct hid_report *report, static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + struct usb_interface *intf; + unsigned short ifnum; unsigned long quirks = id->driver_data; struct pk_device *pk; struct pcmidi_snd *pm = NULL; + if (!hid_is_usb(hdev)) + return -EINVAL; + + intf = to_usb_interface(hdev->dev.parent); + ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + pk = kzalloc(sizeof(*pk), GFP_KERNEL); if (pk == NULL) { hid_err(hdev, "can't alloc descriptor\n"); diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c index 329c5d1270f94331e609b01d48361e4575772bab..fb545a11214f05e6b6cce667dc1f5fa28b39a5e0 100644 --- a/drivers/hid/hid-roccat-arvo.c +++ b/drivers/hid/hid-roccat-arvo.c @@ -347,6 +347,9 @@ static int arvo_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index 02db537f8f3eaf79e50ed9126559735d7c6e388d..c07a7ea8a6873174fda73aade07c07694eca0f53 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c @@ -327,6 +327,9 @@ static int isku_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index bf4675a2739657cf735d74aeea2477ef181fe090..e102e06ad14c16ea0fab5cf19ebbb174835fa0ff 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -743,6 +743,9 @@ static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id) { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 09e8fc72aa1d4a683f2e467baf3c9a5d5abe6518..b63de4c5b5dd38bac877141d04f45ba7fd3117ec 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c @@ -434,6 +434,9 @@ static int koneplus_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-konepure.c b/drivers/hid/hid-roccat-konepure.c index 07de2f9014c67f914209a5dfc08185892955bd79..ef9508822e5f0b788efefa430c1d0c64e450e252 100644 --- a/drivers/hid/hid-roccat-konepure.c +++ b/drivers/hid/hid-roccat-konepure.c @@ -136,6 +136,9 @@ static int konepure_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index 317c9c2c0a7ce9d019ece767a140a451ad249379..6256c211398a199fd29413cf285392df109528ba 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c @@ -504,6 +504,9 @@ static int kovaplus_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-lua.c b/drivers/hid/hid-roccat-lua.c index ac1a7313e25964c2e9922d2b9d43a71f41c1c40b..13ae2a7d176d34acb196a960d405d3837246ac54 100644 --- a/drivers/hid/hid-roccat-lua.c +++ b/drivers/hid/hid-roccat-lua.c @@ -163,6 +163,9 @@ static int lua_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index b30aa7b82bf8729def53a7a0632ad8100d57e67f..027aa9d0ec1f27b89ad289f9a0661a91e63e3600 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c @@ -452,6 +452,9 @@ static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id) { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-ryos.c b/drivers/hid/hid-roccat-ryos.c index 47cc8f30ff6d4fa4784dd96f7b31d2de8ecb9944..fda4a396a12e82a1e795f1c1c488f182723f51e9 100644 --- a/drivers/hid/hid-roccat-ryos.c +++ b/drivers/hid/hid-roccat-ryos.c @@ -144,6 +144,9 @@ static int ryos_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c index 6dbf6e04dce75c82dd32109d46b330d5a60cd043..0230fb54f08a5c44757712b2dcfd497eddd0554d 100644 --- a/drivers/hid/hid-roccat-savu.c +++ b/drivers/hid/hid-roccat-savu.c @@ -116,6 +116,9 @@ static int savu_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c index 7cbb067d4a9e399f62b57b54830d384956037cbc..89bb2260367f3ce3c77bf73873b9b0bcc6ef111c 100644 --- a/drivers/hid/hid-samsung.c +++ b/drivers/hid/hid-samsung.c @@ -157,6 +157,9 @@ static int samsung_probe(struct hid_device *hdev, int ret; unsigned int cmask = HID_CONNECT_DEFAULT; + if (!hid_is_usb(hdev)) + return -EINVAL; + ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c index 1509d7287ff3e60e79c845214e47e901fae650f8..b3f2e40b1c5bd43ac4258d889e0a9566177d8df8 100644 --- a/drivers/hid/hid-uclogic.c +++ b/drivers/hid/hid-uclogic.c @@ -791,6 +791,9 @@ static int uclogic_tablet_enable(struct hid_device *hdev) __u8 *p; s32 v; + if (!hid_is_usb(hdev)) + return -EINVAL; + /* * Read string descriptor containing tablet parameters. The specific * string descriptor and data were discovered by sniffing the Windows diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 850527d5fab1b9832d7847156dd11db9ee480afd..12918f15f651518d6248910c930a87ca320b1c50 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -871,7 +871,7 @@ static int i2c_hid_power(struct hid_device *hid, int lvl) return 0; } -static struct hid_ll_driver i2c_hid_ll_driver = { +struct hid_ll_driver i2c_hid_ll_driver = { .parse = i2c_hid_parse, .start = i2c_hid_start, .stop = i2c_hid_stop, @@ -881,6 +881,7 @@ static struct hid_ll_driver i2c_hid_ll_driver = { .output_report = i2c_hid_output_report, .raw_request = i2c_hid_raw_request, }; +EXPORT_SYMBOL_GPL(i2c_hid_ll_driver); static int i2c_hid_init_irq(struct i2c_client *client) { diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 7a136847c8b267dee66efd1015c2116516febe65..5e6d32251d0908e6e2b832b90a9f62f8664f0f85 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -374,7 +374,7 @@ static int uhid_hid_output_report(struct hid_device *hid, __u8 *buf, return uhid_hid_output_raw(hid, buf, count, HID_OUTPUT_REPORT); } -static struct hid_ll_driver uhid_hid_driver = { +struct hid_ll_driver uhid_hid_driver = { .start = uhid_hid_start, .stop = uhid_hid_stop, .open = uhid_hid_open, @@ -383,6 +383,7 @@ static struct hid_ll_driver uhid_hid_driver = { .raw_request = uhid_hid_raw_request, .output_report = uhid_hid_output_report, }; +EXPORT_SYMBOL_GPL(uhid_hid_driver); #ifdef CONFIG_COMPAT diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 7838343eb37c541d698a7e78ff265e789fda7c98..3dd129561c1441b9f74b0a143235d613d5425ebc 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -1261,7 +1261,7 @@ static int usbhid_idle(struct hid_device *hid, int report, int idle, return hid_set_idle(dev, ifnum, report, idle); } -static struct hid_ll_driver usb_hid_driver = { +struct hid_ll_driver usb_hid_driver = { .parse = usbhid_parse, .start = usbhid_start, .stop = usbhid_stop, @@ -1274,6 +1274,7 @@ static struct hid_ll_driver usb_hid_driver = { .output_report = usbhid_output_report, .idle = usbhid_idle, }; +EXPORT_SYMBOL_GPL(usb_hid_driver); static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) { diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index e8b90b534f08e88d38ba54f6bd8fe8119ad38a30..b74fcda49a2232249f2ad0d197ea046c514d86c2 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -506,7 +506,7 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, * Skip the query for this type and modify defaults based on * interface number. */ - if (features->type == WIRELESS) { + if (features->type == WIRELESS && intf) { if (intf->cur_altsetting->desc.bInterfaceNumber == 0) features->device_type = WACOM_DEVICETYPE_WL_MONITOR; else @@ -2115,6 +2115,9 @@ static void wacom_wireless_work(struct work_struct *work) wacom_destroy_battery(wacom); + if (!usbdev) + return; + /* Stylus interface */ hdev1 = usb_get_intfdata(usbdev->config->interface[1]); wacom1 = hid_get_drvdata(hdev1); @@ -2354,8 +2357,6 @@ static void wacom_remote_work(struct work_struct *work) static int wacom_probe(struct hid_device *hdev, const struct hid_device_id *id) { - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - struct usb_device *dev = interface_to_usbdev(intf); struct wacom *wacom; struct wacom_wac *wacom_wac; struct wacom_features *features; @@ -2388,8 +2389,14 @@ static int wacom_probe(struct hid_device *hdev, wacom_wac->hid_data.inputmode = -1; wacom_wac->mode_report = -1; - wacom->usbdev = dev; - wacom->intf = intf; + if (hid_is_usb(hdev)) { + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct usb_device *dev = interface_to_usbdev(intf); + + wacom->usbdev = dev; + wacom->intf = intf; + } + mutex_init(&wacom->lock); INIT_WORK(&wacom->wireless_work, wacom_wireless_work); INIT_WORK(&wacom->battery_work, wacom_battery_work); diff --git a/drivers/media/platform/msm/camera/cam_core/cam_subdev.c b/drivers/media/platform/msm/camera/cam_core/cam_subdev.c index d690508b85c0e403725faeb22234c0091a6d8c42..bf732dd9a31e0fce7e31572d4b559f44461e05e4 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_subdev.c +++ b/drivers/media/platform/msm/camera/cam_core/cam_subdev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -60,8 +60,10 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, switch (cmd) { case VIDIOC_CAM_CONTROL: + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); rc = cam_node_handle_ioctl(node, (struct cam_control *) arg); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); break; default: CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd, diff --git a/drivers/media/platform/msm/camera/cam_fd/cam_fd_dev.c b/drivers/media/platform/msm/camera/cam_fd/cam_fd_dev.c index d5068ca26971bb7b57af98358530fc6d2e3b16ba..e8f74546a5ba404b83f657700e61c8df7322fe05 100644 --- a/drivers/media/platform/msm/camera/cam_fd/cam_fd_dev.c +++ b/drivers/media/platform/msm/camera/cam_fd/cam_fd_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -50,8 +50,11 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, { struct cam_fd_dev *fd_dev = &g_fd_dev; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + if (!fd_dev->probe_done) { CAM_ERR(CAM_FD, "FD Dev not initialized, fd_dev=%pK", fd_dev); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return -ENODEV; } @@ -60,6 +63,8 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt); mutex_unlock(&fd_dev->lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c b/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c index 2ea7738cbdef565b9bdd9e7ce0c5ff8570bad3f5..6d78cfbfcdcd1633cdac79e44ca34312f1c68767 100644 --- a/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c +++ b/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021The 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 @@ -82,6 +82,8 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, struct cam_node *node = v4l2_get_subdevdata(sd); int rc = 0; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_icp_dev.icp_lock); if (g_icp_dev.open_cnt >= 1) { CAM_ERR(CAM_ICP, "ICP subdev is already opened"); @@ -104,6 +106,7 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, g_icp_dev.open_cnt++; end: mutex_unlock(&g_icp_dev.icp_lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return rc; } diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c index c7e5d3836fda391998e80092fb51980954046f97..847d81481c498f8b4906119fe659448e83569b61 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -59,10 +59,14 @@ static const struct of_device_id cam_isp_dt_match[] = { static int cam_isp_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_isp_dev.isp_mutex); g_isp_dev.open_cnt++; mutex_unlock(&g_isp_dev.isp_mutex); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c index 14892224e41233a55b0f3acf96d7907bdcadbdfc..d772294848c6f4880e9e5ebbc953594f2d7b593c 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -57,11 +57,14 @@ static const struct of_device_id cam_jpeg_dt_match[] = { static int cam_jpeg_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); mutex_lock(&g_jpeg_dev.jpeg_mutex); g_jpeg_dev.open_cnt++; mutex_unlock(&g_jpeg_dev.jpeg_mutex); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c b/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c index 6b1250aea71453d162831bd0702cf232fbfa64f2..ac1b1b4adcc92cf0b136edd9094aa77985d99910 100644 --- a/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c +++ b/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -65,9 +65,12 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd, { struct cam_lrme_dev *lrme_dev = g_lrme_dev; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + if (!lrme_dev) { CAM_ERR(CAM_LRME, "LRME Dev not initialized, dev=%pK", lrme_dev); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return -ENODEV; } @@ -75,6 +78,8 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd, lrme_dev->open_cnt++; mutex_unlock(&lrme_dev->lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } 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 fb921600d952de93813defb0c4c56e6a7edfa5d2..9ccb8f2824c30d60590194c406d1e048a0f94557 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 @@ -1,4 +1,5 @@ /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -1274,10 +1275,13 @@ static int __cam_req_mgr_create_subdevs( * */ static void __cam_req_mgr_destroy_subdev( - struct cam_req_mgr_connected_device *l_device) + struct cam_req_mgr_connected_device **l_device) { - kfree(l_device); - l_device = NULL; + CAM_DBG(CAM_CRM, "*l_device %pK", *l_device); + if (*(l_device) != NULL) { + kfree(*(l_device)); + *l_device = NULL; + } } /** @@ -2374,7 +2378,7 @@ static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link) "Unlink for all devices was not successful"); /* Free memory holding data of linked devs */ - __cam_req_mgr_destroy_subdev(link->l_dev); + __cam_req_mgr_destroy_subdev(&link->l_dev); /* Destroy the link handle */ rc = cam_destroy_device_hdl(link->link_hdl); @@ -2403,8 +2407,12 @@ int cam_req_mgr_destroy_session( mutex_lock(&g_crm_core_dev->crm_lock); cam_session = (struct cam_req_mgr_core_session *) cam_get_device_priv(ses_info->session_hdl); - if (!cam_session) { - CAM_ERR(CAM_CRM, "failed to get session priv"); + if (!cam_session || + (cam_session->session_hdl != ses_info->session_hdl)) { + CAM_ERR(CAM_CRM, "ses:%s ses_info->ses_hdl:%x ses->ses_hdl:%x", + CAM_IS_NULL_TO_STR(cam_session), ses_info->session_hdl, + (!cam_session) ? + CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl); rc = -ENOENT; goto end; @@ -2465,8 +2473,12 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) /* session hdl's priv data is cam session struct */ cam_session = (struct cam_req_mgr_core_session *) cam_get_device_priv(link_info->session_hdl); - if (!cam_session) { - CAM_DBG(CAM_CRM, "NULL pointer"); + if (!cam_session || + (cam_session->session_hdl != link_info->session_hdl)) { + CAM_ERR(CAM_CRM, "ses:%s link_info->ses_hdl:%x ses->ses_hdl:%x", + CAM_IS_NULL_TO_STR(cam_session), link_info->session_hdl, + (!cam_session) ? + CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl); mutex_unlock(&g_crm_core_dev->crm_lock); return -EINVAL; } @@ -2537,7 +2549,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) mutex_unlock(&g_crm_core_dev->crm_lock); return rc; setup_failed: - __cam_req_mgr_destroy_subdev(link->l_dev); + __cam_req_mgr_destroy_subdev(&link->l_dev); create_subdev_failed: cam_destroy_device_hdl(link->link_hdl); link_info->link_hdl = 0; @@ -2565,16 +2577,23 @@ int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info) /* session hdl's priv data is cam session struct */ cam_session = (struct cam_req_mgr_core_session *) cam_get_device_priv(unlink_info->session_hdl); - if (!cam_session) { - CAM_ERR(CAM_CRM, "NULL pointer"); + if (!cam_session || + (cam_session->session_hdl != unlink_info->session_hdl)) { + CAM_ERR(CAM_CRM, "ses:%s unlink->ses_hdl:%x ses->ses_hdl:%x", + CAM_IS_NULL_TO_STR(cam_session), + unlink_info->session_hdl, + (!cam_session) ? + CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl); mutex_unlock(&g_crm_core_dev->crm_lock); return -EINVAL; } /* link hdl's priv data is core_link struct */ link = cam_get_device_priv(unlink_info->link_hdl); - if (!link) { - CAM_ERR(CAM_CRM, "NULL pointer"); + if (!link || (link->link_hdl != unlink_info->link_hdl)) { + CAM_ERR(CAM_CRM, "link:%s unlink->link_hdl:%x lnk->lnk_hdl:%x", + CAM_IS_NULL_TO_STR(link), unlink_info->link_hdl, + (!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl); rc = -EINVAL; goto done; } @@ -2606,8 +2625,10 @@ int cam_req_mgr_schedule_request( mutex_lock(&g_crm_core_dev->crm_lock); link = (struct cam_req_mgr_core_link *) cam_get_device_priv(sched_req->link_hdl); - if (!link) { - CAM_DBG(CAM_CRM, "link ptr NULL %x", sched_req->link_hdl); + if (!link || (link->link_hdl != sched_req->link_hdl)) { + CAM_ERR(CAM_CRM, "lnk:%s schd_req->lnk_hdl:%x lnk->lnk_hdl:%x", + CAM_IS_NULL_TO_STR(link), sched_req->link_hdl, + (!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl); rc = -EINVAL; goto end; } @@ -2673,8 +2694,12 @@ int cam_req_mgr_sync_config( /* session hdl's priv data is cam session struct */ cam_session = (struct cam_req_mgr_core_session *) cam_get_device_priv(sync_info->session_hdl); - if (!cam_session) { - CAM_ERR(CAM_CRM, "NULL pointer"); + if (!cam_session || + (cam_session->session_hdl != sync_info->session_hdl)) { + CAM_ERR(CAM_CRM, "ses:%s sync_info->ses_hdl:%x ses->ses_hdl:%x", + CAM_IS_NULL_TO_STR(cam_session), sync_info->session_hdl, + (!cam_session) ? + CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl); mutex_unlock(&g_crm_core_dev->crm_lock); return -EINVAL; } @@ -2686,15 +2711,21 @@ int cam_req_mgr_sync_config( /* only two links existing per session in dual cam use case*/ link1 = cam_get_device_priv(sync_info->link_hdls[0]); - if (!link1) { - CAM_ERR(CAM_CRM, "link1 NULL pointer"); + if (!link1 || (link1->link_hdl != sync_info->link_hdls[0])) { + CAM_ERR(CAM_CRM, "lnk:%s sync_info->lnk_hdl[0]:%x lnk1_hdl:%x", + CAM_IS_NULL_TO_STR(link1), sync_info->link_hdls[0], + (!link1) ? + CAM_REQ_MGR_DEFAULT_HDL_VAL : link1->link_hdl); rc = -EINVAL; goto done; } link2 = cam_get_device_priv(sync_info->link_hdls[1]); - if (!link2) { - CAM_ERR(CAM_CRM, "link2 NULL pointer"); + if (!link2 || (link2->link_hdl != sync_info->link_hdls[1])) { + CAM_ERR(CAM_CRM, "lnk:%s sync_info->lnk_hdl[1]:%x lnk2_hdl:%x", + CAM_IS_NULL_TO_STR(link2), sync_info->link_hdls[1], + (!link2) ? + CAM_REQ_MGR_DEFAULT_HDL_VAL : link2->link_hdl); rc = -EINVAL; goto done; } @@ -2748,8 +2779,11 @@ int cam_req_mgr_flush_requests( /* session hdl's priv data is cam session struct */ session = (struct cam_req_mgr_core_session *) cam_get_device_priv(flush_info->session_hdl); - if (!session) { - CAM_ERR(CAM_CRM, "Invalid session %x", flush_info->session_hdl); + if (!session || (session->session_hdl != flush_info->session_hdl)) { + CAM_ERR(CAM_CRM, "ses:%s flush->ses_hdl:%x ses->ses_hdl:%x", + CAM_IS_NULL_TO_STR(session), flush_info->session_hdl, + (!session) ? + CAM_REQ_MGR_DEFAULT_HDL_VAL : session->session_hdl); rc = -EINVAL; goto end; } @@ -2761,8 +2795,10 @@ int cam_req_mgr_flush_requests( link = (struct cam_req_mgr_core_link *) cam_get_device_priv(flush_info->link_hdl); - if (!link) { - CAM_DBG(CAM_CRM, "link ptr NULL %x", flush_info->link_hdl); + if (!link || (link->link_hdl != flush_info->link_hdl)) { + CAM_ERR(CAM_CRM, "lnk:%s flush->lnk_hdl:%x lnk->lnk_hdl:%x", + CAM_IS_NULL_TO_STR(link), flush_info->link_hdl, + (!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl); rc = -EINVAL; goto end; } @@ -2819,9 +2855,11 @@ int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control) for (i = 0; i < control->num_links; i++) { link = (struct cam_req_mgr_core_link *) cam_get_device_priv(control->link_hdls[i]); - if (!link) { - CAM_ERR(CAM_CRM, "Link(%d) is NULL on session 0x%x", - i, control->session_hdl); + if (!link || (link->link_hdl != control->link_hdls[i])) { + CAM_ERR(CAM_CRM, "lnk:%s ctrl->lnk_hdl:%x lnk_hdl:%x", + CAM_IS_NULL_TO_STR(link), control->link_hdls[i], + (!link) ? + CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl); rc = -EINVAL; break; } 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 073796b601c7f6064079f224709fbfe761719871..939b063efcdf7fbfde552682e30b199e92595aba 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 @@ -1,4 +1,5 @@ /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -23,6 +24,7 @@ #define CAM_REQ_MGR_WATCHDOG_TIMEOUT 5000 #define CAM_REQ_MGR_SCHED_REQ_TIMEOUT 1000 #define CAM_REQ_MGR_SIMULATE_SCHED_REQ 30 +#define CAM_REQ_MGR_DEFAULT_HDL_VAL 0 #define FORCE_DISABLE_RECOVERY 2 #define FORCE_ENABLE_RECOVERY 1 diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c index cb60ef4abb5acb6191fcfd93bbe29ad74a3b2d4f..d919c9ed4f332ec39a827ac7d0bbc43ac2ea0adf 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -33,6 +34,8 @@ static struct cam_req_mgr_device g_dev; struct kmem_cache *g_cam_req_mgr_timer_cachep; +DECLARE_RWSEM(rwsem_lock); + static int cam_media_device_setup(struct device *dev) { int rc; @@ -98,10 +101,28 @@ static void cam_v4l2_device_cleanup(void) g_dev.v4l2_dev = NULL; } +void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock) +{ + if (lock == CAM_SUBDEV_LOCK) + down_read(&rwsem_lock); + else if (lock == CAM_SUBDEV_UNLOCK) + up_read(&rwsem_lock); +} + +static void cam_req_mgr_rwsem_write_op(enum cam_subdev_rwsem lock) +{ + if (lock == CAM_SUBDEV_LOCK) + down_write(&rwsem_lock); + else if (lock == CAM_SUBDEV_UNLOCK) + up_write(&rwsem_lock); +} + static int cam_req_mgr_open(struct file *filep) { int rc; + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_dev.cam_lock); if (g_dev.open_cnt >= 1) { rc = -EALREADY; @@ -127,12 +148,14 @@ static int cam_req_mgr_open(struct file *filep) } mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return rc; mem_mgr_init_fail: v4l2_fh_release(filep); end: mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return rc; } @@ -158,10 +181,13 @@ static int cam_req_mgr_close(struct file *filep) struct v4l2_fh *vfh = filep->private_data; struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_dev.cam_lock); if (g_dev.open_cnt <= 0) { mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return -EINVAL; } @@ -188,6 +214,8 @@ static int cam_req_mgr_close(struct file *filep) cam_mem_mgr_deinit(); mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); + return 0; } @@ -536,6 +564,18 @@ void cam_register_subdev_fops(struct v4l2_file_operations *fops) } EXPORT_SYMBOL(cam_register_subdev_fops); +bool cam_req_mgr_is_open(void) +{ + bool crm_status; + + mutex_lock(&g_dev.cam_lock); + crm_status = g_dev.open_cnt ? true : false; + mutex_unlock(&g_dev.cam_lock); + + return crm_status; +} +EXPORT_SYMBOL(cam_req_mgr_is_open); + int cam_register_subdev(struct cam_subdev *csd) { struct v4l2_subdev *sd; diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c index dda04f8e516417eb4bc8dafef6e13a4d597ce34f..f5c8a1fed1c4874f0d51763fc5a424caa0b44958 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_util.c @@ -21,6 +21,7 @@ #include #include "cam_req_mgr_util.h" #include "cam_debug_util.h" +#include "cam_subdev.h" static struct cam_req_mgr_util_hdl_tbl *hdl_tbl; static DEFINE_SPINLOCK(hdl_tbl_lock); @@ -166,6 +167,14 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) int idx; int rand = 0; int32_t handle; + bool crm_active; + + crm_active = cam_req_mgr_is_open(); + if (!crm_active) { + CAM_ERR(CAM_ICP, "CRM is not ACTIVE"); + spin_unlock_bh(&hdl_tbl_lock); + return -EINVAL; + } spin_lock_bh(&hdl_tbl_lock); if (!hdl_tbl) { diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_subdev.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_subdev.h index 8cd3214674d5faf984c017a1dfb22ec954014cad..8a3790b29895e167f9db0e9820b9560ed9c59fd6 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_subdev.h +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_subdev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -23,6 +23,11 @@ #define CAM_SUBDEVICE_EVENT_MAX 30 +enum cam_subdev_rwsem { + CAM_SUBDEV_LOCK = 1, + CAM_SUBDEV_UNLOCK, +}; + /** * struct cam_subdev - describes a camera sub-device * @@ -112,4 +117,21 @@ int cam_register_subdev(struct cam_subdev *sd); */ int cam_unregister_subdev(struct cam_subdev *sd); +/** + * cam_req_mgr_rwsem_read_op() + * + * @brief : API to acquire read semaphore lock to platform framework. + * + * @lock : value indicates to lock or unlock the read lock + */ +void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock); + +/** + * cam_req_mgr_is_open() + * + * @brief: This common utility function returns the crm active status + * + */ +bool cam_req_mgr_is_open(void); + #endif /* _CAM_SUBDEV_H_ */ 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 8519115cb437a77f966ca932c1714ea836a7dae5..a9c5ff7b5df1dde57ecfb83b0f2a6e2e055351e6 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 @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 2021 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 @@ -748,6 +748,11 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, actuator_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (actuator_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_ACTUATOR, "Can not create device handle"); + goto release_mutex; + } a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle; a_ctrl->bridge_intf.session_hdl = actuator_acq_dev.session_handle; 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 9a1188537dd7a6ed5933a55c00ce209b9be2a0a4..eea8886f0693e7ad1a42e9fddb5f8b53414677bd 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 @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 2021 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 @@ -629,6 +629,12 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, csiphy_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (csiphy_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_CSIPHY, "Can not create device handle"); + goto release_mutex; + } + bridge_intf = &csiphy_dev->bridge_intf; bridge_intf->device_hdl[csiphy_acq_params.combo_mode] = csiphy_acq_dev.device_handle; 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 20976afd9c2201651c431551cd531301c44f1fca..b6607613d77579f00e1726a912f08ddb343015b7 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 @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 2021 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 @@ -360,6 +360,10 @@ static int32_t cam_eeprom_get_dev_handle(struct cam_eeprom_ctrl_t *e_ctrl, eeprom_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (eeprom_acq_dev.device_handle <= 0) { + CAM_ERR(CAM_EEPROM, "Can not create device handle"); + return -EFAULT; + } e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle; e_ctrl->bridge_intf.session_hdl = eeprom_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c index cdd6a98d2bf1ceb30609cb1616c22275329d2a95..54d33effb71d00140b0fee22c050016a8649cddb 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 2021 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 @@ -74,6 +74,11 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, flash_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (flash_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_FLASH, "Can not create device handle"); + goto release_mutex; + } fctrl->bridge_intf.device_hdl = flash_acq_dev.device_handle; fctrl->bridge_intf.session_hdl = 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 281b25482864ed48d25ad013c481cfc277627790..aea012bef79441a88ef4f41d0c2f3a0b3c2973fe 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 @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 2021 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 @@ -93,6 +93,10 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl, ois_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (ois_acq_dev.device_handle <= 0) { + CAM_ERR(CAM_OIS, "Can not create device handle"); + return -EFAULT; + } o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle; o_ctrl->bridge_intf.session_hdl = ois_acq_dev.session_handle; 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 2dbcaa6a799099440c13f9f22bb5ac88cce6460e..9db1f1cdeff2b5262d1e25fb3bf10ed661ee791e 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 @@ -723,6 +723,11 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, sensor_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (sensor_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_SENSOR, "Can not create device handle"); + goto release_mutex; + } s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle; s_ctrl->bridge_intf.session_hdl = sensor_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h index 81bc47b0bc616685d990fdc97829971ea729a15d..cb54a2a883d979c19c57c266bef68680c670b30d 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h +++ b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -13,6 +14,8 @@ #ifndef _CAM_DEBUG_UTIL_H_ #define _CAM_DEBUG_UTIL_H_ +#define CAM_IS_NULL_TO_STR(ptr) ((ptr) ? "Non-NULL" : "NULL") + #define CAM_CDM (1 << 0) #define CAM_CORE (1 << 1) #define CAM_CPAS (1 << 2) diff --git a/drivers/media/platform/msm/camera_v2/fd/Makefile b/drivers/media/platform/msm/camera_v2/fd/Makefile index 8d01d3a8708dc53c117d31478cfb79a58e5f9339..a1d33dad11fce10014cb67480046bed2292aea59 100644 --- a/drivers/media/platform/msm/camera_v2/fd/Makefile +++ b/drivers/media/platform/msm/camera_v2/fd/Makefile @@ -1,4 +1,3 @@ -GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc) ccflags-y += -Idrivers/media/video/msm ccflags-y += -Idrivers/media/platform/msm/camera_v2/common ccflags-y += -Idrivers/media/platform/msm/camera_v2 diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile b/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile index 0b8dc1db225c01e3f5949734c1c3a048d3e897b0..72808f94c54b92b4aa896b0320d5f57e2408b37e 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile +++ b/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile @@ -1,5 +1,3 @@ -GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc) - ccflags-y += -Idrivers/media/platform/msm/camera_v2/jpeg_10 ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io ccflags-y += -Idrivers/media/platform/msm/camera_v2/common diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile b/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile index 21cbadbd6425e44ec7e0f7b47868f9beefaa7264..239b664b78d5268fbbcd81d0f244b5856116a860 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile +++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile @@ -1,4 +1,3 @@ -GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc) ccflags-y += -Idrivers/media/video/msm ccflags-y += -Idrivers/media/platform/msm/camera_v2/common obj-$(CONFIG_MSM_JPEGDMA) += msm_jpeg_dma_dev.o msm_jpeg_dma_hw.o diff --git a/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c b/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c index b1f4fe87e8fadcda0398389c2e46c81904a8078e..8c39d4295a2f45a1de9e38e0ad27fa3002eb94dd 100644 --- a/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c +++ b/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c @@ -243,35 +243,34 @@ int cam_cdm_stream_ops_internal(void *hw_priv, return -EINVAL; core = (struct cam_cdm *)cdm_hw->core_info; + mutex_lock(&cdm_hw->hw_mutex); client_idx = CAM_CDM_GET_CLIENT_IDX(*handle); client = core->clients[client_idx]; if (!client) { CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client, *handle); + mutex_unlock(&cdm_hw->hw_mutex); return -EINVAL; } cam_cdm_get_client_refcount(client); if (*handle != client->handle) { CAM_ERR(CAM_CDM, "client id given handle=%x invalid", *handle); - cam_cdm_put_client_refcount(client); - return -EINVAL; + rc = -EINVAL; + goto end; } if (operation == true) { if (true == client->stream_on) { CAM_ERR(CAM_CDM, "Invalid CDM client is already streamed ON"); - cam_cdm_put_client_refcount(client); - return rc; + goto end; } } else { if (client->stream_on == false) { CAM_ERR(CAM_CDM, "Invalid CDM client is already streamed Off"); - cam_cdm_put_client_refcount(client); - return rc; + goto end; } } - mutex_lock(&cdm_hw->hw_mutex); if (operation == true) { if (!cdm_hw->open_count) { struct cam_ahb_vote ahb_vote; diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_subdev.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_subdev.c index 6511a188e3b8e921b3646621305eb7b154904b36..bf732dd9a31e0fce7e31572d4b559f44461e05e4 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_subdev.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_subdev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -60,8 +60,10 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, switch (cmd) { case VIDIOC_CAM_CONTROL: + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); rc = cam_node_handle_ioctl(node, (struct cam_control *) arg); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); break; default: CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd, diff --git a/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_dev.c b/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_dev.c index d5068ca26971bb7b57af98358530fc6d2e3b16ba..e8f74546a5ba404b83f657700e61c8df7322fe05 100644 --- a/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_fd/cam_fd_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -50,8 +50,11 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, { struct cam_fd_dev *fd_dev = &g_fd_dev; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + if (!fd_dev->probe_done) { CAM_ERR(CAM_FD, "FD Dev not initialized, fd_dev=%pK", fd_dev); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return -ENODEV; } @@ -60,6 +63,8 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt); mutex_unlock(&fd_dev->lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_subdev.c b/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_subdev.c index 699ad5f2a0b4b3edf3718bb48f8272eb4bb72c2f..0e352703a0bc93f3cfb357e8f3d2faf08be24e1a 100644 --- a/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_subdev.c +++ b/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_subdev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021The 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 @@ -82,6 +82,8 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, struct cam_node *node = v4l2_get_subdevdata(sd); int rc = 0; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_icp_dev.icp_lock); if (g_icp_dev.open_cnt >= 1) { CAM_ERR(CAM_ICP, "ICP subdev is already opened"); @@ -104,6 +106,7 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, g_icp_dev.open_cnt++; end: mutex_unlock(&g_icp_dev.icp_lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return rc; } diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_dev.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_dev.c index d8b7a7b5e73e838f5f8e589a293cbe2d1eb28599..9d964364072ca3310e2d60f6d3d5597b28112583 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -58,10 +58,14 @@ static const struct of_device_id cam_isp_dt_match[] = { static int cam_isp_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_isp_dev.isp_mutex); g_isp_dev.open_cnt++; mutex_unlock(&g_isp_dev.isp_mutex); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_dev.c b/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_dev.c index 14892224e41233a55b0f3acf96d7907bdcadbdfc..d772294848c6f4880e9e5ebbc953594f2d7b593c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_jpeg/cam_jpeg_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -57,11 +57,14 @@ static const struct of_device_id cam_jpeg_dt_match[] = { static int cam_jpeg_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); mutex_lock(&g_jpeg_dev.jpeg_mutex); g_jpeg_dev.open_cnt++; mutex_unlock(&g_jpeg_dev.jpeg_mutex); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_dev.c b/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_dev.c index 6b1250aea71453d162831bd0702cf232fbfa64f2..ac1b1b4adcc92cf0b136edd9094aa77985d99910 100644 --- a/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_lrme/cam_lrme_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -65,9 +65,12 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd, { struct cam_lrme_dev *lrme_dev = g_lrme_dev; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + if (!lrme_dev) { CAM_ERR(CAM_LRME, "LRME Dev not initialized, dev=%pK", lrme_dev); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return -ENODEV; } @@ -75,6 +78,8 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd, lrme_dev->open_cnt++; mutex_unlock(&lrme_dev->lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c index eb3d0de873b3c2b10bb64086fa3272285650e811..a41f2d5a6d0e08fc60798672b88b8c6ea842b17b 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c @@ -1,4 +1,5 @@ /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -1614,10 +1615,13 @@ static int __cam_req_mgr_create_subdevs( * */ static void __cam_req_mgr_destroy_subdev( - struct cam_req_mgr_connected_device *l_device) + struct cam_req_mgr_connected_device **l_device) { - kfree(l_device); - l_device = NULL; + CAM_DBG(CAM_CRM, "*l_device %pK", *l_device); + if (*(l_device) != NULL) { + kfree(*(l_device)); + *l_device = NULL; + } } /** @@ -2806,7 +2810,7 @@ static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link) __cam_req_mgr_destroy_link_info(link); /* Free memory holding data of linked devs */ - __cam_req_mgr_destroy_subdev(link->l_dev); + __cam_req_mgr_destroy_subdev(&link->l_dev); /* Destroy the link handle */ rc = cam_destroy_device_hdl(link->link_hdl); @@ -2969,7 +2973,7 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info) mutex_unlock(&g_crm_core_dev->crm_lock); return rc; setup_failed: - __cam_req_mgr_destroy_subdev(link->l_dev); + __cam_req_mgr_destroy_subdev(&link->l_dev); create_subdev_failed: cam_destroy_device_hdl(link->link_hdl); link_info->u.link_info_v1.link_hdl = -1; @@ -3078,7 +3082,7 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info) mutex_unlock(&g_crm_core_dev->crm_lock); return rc; setup_failed: - __cam_req_mgr_destroy_subdev(link->l_dev); + __cam_req_mgr_destroy_subdev(&link->l_dev); create_subdev_failed: cam_destroy_device_hdl(link->link_hdl); link_info->u.link_info_v2.link_hdl = -1; diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c index 5d4d9fcc47ab1855cfa0040ed9ee1671ec05787b..fe62f630376f61a12e6fa43e5ff726cbd0b414c6 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -33,6 +34,8 @@ static struct cam_req_mgr_device g_dev; struct kmem_cache *g_cam_req_mgr_timer_cachep; +DECLARE_RWSEM(rwsem_lock); + static int cam_media_device_setup(struct device *dev) { int rc; @@ -98,10 +101,28 @@ static void cam_v4l2_device_cleanup(void) g_dev.v4l2_dev = NULL; } +void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock) +{ + if (lock == CAM_SUBDEV_LOCK) + down_read(&rwsem_lock); + else if (lock == CAM_SUBDEV_UNLOCK) + up_read(&rwsem_lock); +} + +static void cam_req_mgr_rwsem_write_op(enum cam_subdev_rwsem lock) +{ + if (lock == CAM_SUBDEV_LOCK) + down_write(&rwsem_lock); + else if (lock == CAM_SUBDEV_UNLOCK) + up_write(&rwsem_lock); +} + static int cam_req_mgr_open(struct file *filep) { int rc; + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_dev.cam_lock); if (g_dev.open_cnt >= 1) { rc = -EALREADY; @@ -127,12 +148,14 @@ static int cam_req_mgr_open(struct file *filep) } mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return rc; mem_mgr_init_fail: v4l2_fh_release(filep); end: mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return rc; } @@ -158,10 +181,13 @@ static int cam_req_mgr_close(struct file *filep) struct v4l2_fh *vfh = filep->private_data; struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_dev.cam_lock); if (g_dev.open_cnt <= 0) { mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return -EINVAL; } @@ -188,6 +214,8 @@ static int cam_req_mgr_close(struct file *filep) cam_mem_mgr_deinit(); mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); + return 0; } @@ -586,6 +614,18 @@ void cam_register_subdev_fops(struct v4l2_file_operations *fops) } EXPORT_SYMBOL(cam_register_subdev_fops); +bool cam_req_mgr_is_open(void) +{ + bool crm_status; + + mutex_lock(&g_dev.cam_lock); + crm_status = g_dev.open_cnt ? true : false; + mutex_unlock(&g_dev.cam_lock); + + return crm_status; +} +EXPORT_SYMBOL(cam_req_mgr_is_open); + int cam_register_subdev(struct cam_subdev *csd) { struct v4l2_subdev *sd; diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c index 8c2a3d424ccdb6239db70e7bb49bdced98ca8dff..343ae97bad42224c184aaef89211a79beb3cf487 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c @@ -21,6 +21,7 @@ #include #include "cam_req_mgr_util.h" #include "cam_debug_util.h" +#include "cam_subdev.h" static struct cam_req_mgr_util_hdl_tbl *hdl_tbl; static DEFINE_SPINLOCK(hdl_tbl_lock); @@ -166,6 +167,14 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) int idx; int rand = 0; int32_t handle; + bool crm_active; + + crm_active = cam_req_mgr_is_open(); + if (!crm_active) { + CAM_ERR(CAM_ICP, "CRM is not ACTIVE"); + spin_unlock_bh(&hdl_tbl_lock); + return -EINVAL; + } spin_lock_bh(&hdl_tbl_lock); if (!hdl_tbl) { diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_subdev.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_subdev.h index c9fa904e64af5802cc45b7dd7820760ffe7b06ce..8a3790b29895e167f9db0e9820b9560ed9c59fd6 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_subdev.h +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_subdev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2021 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 @@ -23,6 +23,11 @@ #define CAM_SUBDEVICE_EVENT_MAX 30 +enum cam_subdev_rwsem { + CAM_SUBDEV_LOCK = 1, + CAM_SUBDEV_UNLOCK, +}; + /** * struct cam_subdev - describes a camera sub-device * @@ -112,4 +117,21 @@ int cam_register_subdev(struct cam_subdev *sd); */ int cam_unregister_subdev(struct cam_subdev *sd); +/** + * cam_req_mgr_rwsem_read_op() + * + * @brief : API to acquire read semaphore lock to platform framework. + * + * @lock : value indicates to lock or unlock the read lock + */ +void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock); + +/** + * cam_req_mgr_is_open() + * + * @brief: This common utility function returns the crm active status + * + */ +bool cam_req_mgr_is_open(void); + #endif /* _CAM_SUBDEV_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c index 51375809b6e25fea38a8cf3ccb25e2d265b57d0a..ac89ab02b9749324e6eab2f5fb88a4031a6bdf49 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -790,6 +790,11 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, bridge_params.dev_id = CAM_ACTUATOR; actuator_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (actuator_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_ACTUATOR, "Can not create device handle"); + goto release_mutex; + } a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle; a_ctrl->bridge_intf.session_hdl = actuator_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index b8605596aa6c198e5b93aabb45e1afdc5a433ab3..b269b431be0c0671d957ae654ea7a8e8cc5ce083 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 2021 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 @@ -738,6 +738,12 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, csiphy_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (csiphy_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_CSIPHY, "Can not create device handle"); + goto release_mutex; + } + bridge_intf = &csiphy_dev->bridge_intf; bridge_intf->device_hdl[csiphy_acq_params.combo_mode] = csiphy_acq_dev.device_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index bcd3823a357c33d9574de2851f70fcb513cb6c0d..53a84bcd24ce5443a6369fa53a1aac36dccb81bc 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 2021 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 @@ -360,6 +360,10 @@ static int32_t cam_eeprom_get_dev_handle(struct cam_eeprom_ctrl_t *e_ctrl, bridge_params.dev_id = CAM_EEPROM; eeprom_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (eeprom_acq_dev.device_handle <= 0) { + CAM_ERR(CAM_EEPROM, "Can not create device handle"); + return -EFAULT; + } e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle; e_ctrl->bridge_intf.session_hdl = eeprom_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c index f4c9d254df7cd02ef72911d49084a01a51c08283..7fde31ac798c7fca090d264e75d2fd31254457fd 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 2021 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 @@ -74,6 +74,11 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, bridge_params.dev_id = CAM_FLASH; flash_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (flash_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_FLASH, "Can not create device handle"); + goto release_mutex; + } fctrl->bridge_intf.device_hdl = flash_acq_dev.device_handle; fctrl->bridge_intf.session_hdl = diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c index c8d3a1a0a49bc4848daed13d0713b1e5d9d7fb55..d46d76d6b19e33f17bcb6732f311a681528c7c91 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c @@ -94,6 +94,10 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl, bridge_params.dev_id = CAM_OIS; ois_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (ois_acq_dev.device_handle <= 0) { + CAM_ERR(CAM_OIS, "Can not create device handle"); + return -EFAULT; + } o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle; o_ctrl->bridge_intf.session_hdl = ois_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c index 0ed36d143265885d2be4bee06e478f7c944c36da..7f372bf9bd8826065772712d34b2ce0104498a25 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -800,6 +800,11 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, bridge_params.dev_id = CAM_SENSOR; sensor_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (sensor_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_SENSOR, "Can not create device handle"); + goto release_mutex; + } s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle; s_ctrl->bridge_intf.session_hdl = sensor_acq_dev.session_handle; diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_sync.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_sync.c index c5be3549d8f66744b6d60d3b3deea91ab0b2c85e..fb23c681898c7ed649715dcc1a211777c24c47a2 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_sync.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_sync.c @@ -1,4 +1,5 @@ /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -151,6 +152,11 @@ static void sde_rot_fence_release(struct fence *fence) struct sde_rot_fence *f = to_sde_rot_fence(fence); unsigned long flags; + if (fence->ops->get_driver_name != &sde_rot_fence_get_driver_name) { + pr_debug("invalid parameters\n"); + return; + } + spin_lock_irqsave(fence->lock, flags); if (!list_empty(&f->fence_list)) list_del(&f->fence_list); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 5ce804d3f29d8758d94e906e942801b9f171ee41..3ee6161a61f11925ffec9ce93c737e1c9017c3f4 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -6508,25 +6508,24 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, struct vb2_v4l2_buffer *vbuf; struct vb2_buffer *vb; unsigned long dma_planes[VB2_MAX_PLANES] = {0}; - struct msm_vidc_buffer *mbuf; + struct msm_vidc_buffer *mbuf = NULL; bool found = false; - int i; + int i = 0, planes = 0; if (!inst || !vb2) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return NULL; } - for (i = 0; i < vb2->num_planes; i++) { + for (planes = 0; planes < vb2->num_planes; planes++) { /* * always compare dma_buf addresses which is guaranteed * to be same across the processes (duplicate fds). */ - dma_planes[i] = (unsigned long)msm_smem_get_dma_buf( - vb2->planes[i].m.fd); - if (!dma_planes[i]) - return NULL; - msm_smem_put_dma_buf((struct dma_buf *)dma_planes[i]); + dma_planes[planes] = (unsigned long)msm_smem_get_dma_buf( + vb2->planes[planes].m.fd); + if (!dma_planes[planes]) + goto put_ref; } mutex_lock(&inst->registeredbufs.lock); @@ -6614,22 +6613,21 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, if (!found) list_add_tail(&mbuf->list, &inst->registeredbufs.list); - mutex_unlock(&inst->registeredbufs.lock); +exit: if (rc == -EEXIST) { print_vidc_buffer(VIDC_DBG, "qbuf upon rbr", inst, mbuf); - return ERR_PTR(rc); + } else if (rc) { + dprintk(VIDC_ERR, "%s: rc %d\n", __func__, rc); + msm_comm_unmap_vidc_buffer(inst, mbuf); + if (!found) + kref_put_mbuf(mbuf); } - - return mbuf; - -exit: - dprintk(VIDC_ERR, "%s: rc %d\n", __func__, rc); - msm_comm_unmap_vidc_buffer(inst, mbuf); - if (!found) - kref_put_mbuf(mbuf); mutex_unlock(&inst->registeredbufs.lock); +put_ref: + while (planes) + msm_smem_put_dma_buf((struct dma_buf *)dma_planes[--planes]); - return ERR_PTR(rc); + return rc ? ERR_PTR(rc) : mbuf; } void msm_comm_put_vidc_buffer(struct msm_vidc_inst *inst, diff --git a/drivers/power/supply/qcom/fg-alg.c b/drivers/power/supply/qcom/fg-alg.c index 09c3fc47f0130aab3442ffd159b511a005fa9ac5..12652e6e8225ee91101a2c6fb1da08711c6a090c 100644 --- a/drivers/power/supply/qcom/fg-alg.c +++ b/drivers/power/supply/qcom/fg-alg.c @@ -813,7 +813,7 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) } if (!valid) { - *val = -EINVAL; + *val = -1; return 0; } @@ -824,7 +824,7 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) } if (charge_status != POWER_SUPPLY_STATUS_CHARGING) { - *val = -EINVAL; + *val = -1; return 0; } @@ -1145,7 +1145,7 @@ int ttf_get_time_to_empty(struct ttf *ttf, int *val) } if (!valid) { - *val = -EINVAL; + *val = -1; return 0; } @@ -1156,7 +1156,7 @@ int ttf_get_time_to_empty(struct ttf *ttf, int *val) } if (charge_status == POWER_SUPPLY_STATUS_CHARGING) { - *val = -EINVAL; + *val = -1; return 0; } diff --git a/drivers/soc/qcom/smcinvoke.c b/drivers/soc/qcom/smcinvoke.c index b99d6133aaea644ab0459aa16213cdb6a20e0a35..86a4b7cf57aff4836bb8be63b2ac3af840f40be0 100644 --- a/drivers/soc/qcom/smcinvoke.c +++ b/drivers/soc/qcom/smcinvoke.c @@ -2,6 +2,7 @@ * SMC Invoke driver * * Copyright (c) 2016-2017,2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -173,9 +174,9 @@ static int get_fd_from_tzhandle(uint32_t tzhandle, int64_t *fd) goto out; *fd = unused_fd; - fd_install(*fd, f); ((struct smcinvoke_tzobj_context *) (f->private_data))->tzhandle = tzhandle; + fd_install(*fd, f); return 0; out: if (unused_fd >= 0) diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c index f2597e376d43e8a22996744544e8d18b9674f1ad..5e989d1ef4bb1b1a1eb90475943ac66e98c8643b 100644 --- a/drivers/soc/qcom/spcom.c +++ b/drivers/soc/qcom/spcom.c @@ -116,7 +116,7 @@ /* * After both sides get CONNECTED, - * there is a race between one side queueing rx buffer and the other side + * there is a race between one side queuing rx buffer and the other side * trying to call glink_tx() , this race is only on the 1st tx. * Do tx retry with some delay to allow the other side to queue rx buffer. */ @@ -2584,6 +2584,12 @@ static int spcom_create_channel_chardev(const char *name) void *priv; struct cdev *cdev; + if (!name || strnlen(name, SPCOM_CHANNEL_NAME_SIZE) == + SPCOM_CHANNEL_NAME_SIZE) { + pr_err("invalid channel name\n"); + return -EINVAL; + } + pr_debug("Add channel [%s].\n", name); ch = spcom_find_channel_by_name(name); @@ -2605,7 +2611,12 @@ static int spcom_create_channel_chardev(const char *name) spcom_dev->channel_count++; devt = spcom_dev->device_no + spcom_dev->channel_count; priv = ch; - dev = device_create(cls, parent, devt, priv, name); + + /* + * Pass channel name as formatted string to avoid abuse by using a + * formatted string as channel name + */ + dev = device_create(cls, parent, devt, priv, "%s", name); if (IS_ERR(dev)) { pr_err("device_create failed.\n"); kfree(cdev); diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c index 1a8e68ee0ce2a0969a830a4a1a4fe7ccd73c348b..64caa376bba79ff0526eef7110d862915282c427 100644 --- a/drivers/staging/media/cec/cec-adap.c +++ b/drivers/staging/media/cec/cec-adap.c @@ -544,7 +544,7 @@ EXPORT_SYMBOL_GPL(cec_transmit_done); void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status) { - switch (status) { + switch (status & ~CEC_TX_STATUS_MAX_RETRIES) { case CEC_TX_STATUS_OK: cec_transmit_done(adap, status, 0, 0, 0, 0); return; diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 7f3cc5c0d2903bb26a04cf71e70a924a552e0628..8e6d9732b5e6f7826a88cee002d0475bc9ae33d7 100755 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2053,6 +2053,9 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (w_index != 0x5 || (w_value >> 8)) break; interface = w_value & 0xFF; + if (interface >= MAX_CONFIG_INTERFACES || + !os_desc_cfg->interface[interface]) + break; buf[6] = w_index; if (w_length == 0x0A) { count = count_ext_prop(os_desc_cfg, diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index 038993d20bcb8c392dc631f4a9a9be5e01d380dd..9305af25e805c827fe0c56c1162f9ec8b5457699 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -650,14 +650,17 @@ static int rndis_set_response(struct rndis_params *params, rndis_set_cmplt_type *resp; rndis_resp_t *r; + BufLength = le32_to_cpu(buf->InformationBufferLength); + BufOffset = le32_to_cpu(buf->InformationBufferOffset); + if ((BufLength > RNDIS_MAX_TOTAL_SIZE) || + (BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE)) + return -EINVAL; + r = rndis_add_response(params, sizeof(rndis_set_cmplt_type)); if (!r) return -ENOMEM; resp = (rndis_set_cmplt_type *)r->buf; - BufLength = le32_to_cpu(buf->InformationBufferLength); - BufOffset = le32_to_cpu(buf->InformationBufferOffset); - #ifdef VERBOSE_DEBUG pr_debug("%s: Length: %d\n", __func__, BufLength); pr_debug("%s: Offset: %d\n", __func__, BufOffset); diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 93f0cfb303173a806db348c3528e5982ad3301be..08e833b090f3bb1a080de9aadec0ef50dbe28207 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1833,8 +1833,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) spin_lock_irq (&dev->lock); value = -EINVAL; if (dev->buf) { + spin_unlock_irq(&dev->lock); kfree(kbuf); - goto fail; + return value; } dev->buf = kbuf; @@ -1882,8 +1883,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) value = usb_gadget_probe_driver(&gadgetfs_driver); if (value != 0) { - kfree (dev->buf); - dev->buf = NULL; + spin_lock_irq(&dev->lock); + goto fail; } else { /* at this point "good" hardware has for the first time * let the USB the host see us. alternatively, if users @@ -1900,6 +1901,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) return value; fail: + dev->config = NULL; + dev->hs_config = NULL; + dev->dev = NULL; spin_unlock_irq (&dev->lock); pr_debug ("%s: %s fail %Zd, %p\n", shortname, __func__, value, dev); kfree (dev->buf); diff --git a/drivers/video/fbdev/msm/mdp3.c b/drivers/video/fbdev/msm/mdp3.c index 108141036a1cc2b383762c84e17eac1a82c4ed2a..c2ba98e4d8f41a1fe4541d7952a8672a8a9be0ba 100644 --- a/drivers/video/fbdev/msm/mdp3.c +++ b/drivers/video/fbdev/msm/mdp3.c @@ -1,4 +1,5 @@ /* Copyright (c) 2013-2019,2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (C) 2007 Google Incorporated * * This software is licensed under the terms of the GNU General Public @@ -1401,17 +1402,12 @@ int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data, int client) &data->len, fb_num); if (ret) { pr_err("mdss_fb_get_phys_info() failed\n"); - fdput(f); - memset(&f, 0, sizeof(struct fd)); } } else { pr_err("invalid FB_MAJOR\n"); - fdput(f); ret = -EINVAL; } data->srcp_f = f; - if (!ret) - goto done; } else if (iclient) { data->srcp_dma_buf = dma_buf_get(img->memory_id); if (IS_ERR(data->srcp_dma_buf)) { @@ -1494,7 +1490,6 @@ int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data, int client) data->mapped = true; data->skip_detach = false; } -done: if (client == MDP3_CLIENT_PPP || client == MDP3_CLIENT_DMA_P) { data->addr += data->tab_clone->sgl->length; data->len -= data->tab_clone->sgl->length; diff --git a/drivers/video/fbdev/msm/mdss_sync.c b/drivers/video/fbdev/msm/mdss_sync.c index 8fe9461af47a07ea968ed2a7726ff0658c75c4e0..e0dc101a30c2085e8592f7d17b9b7c2fbb507462 100644 --- a/drivers/video/fbdev/msm/mdss_sync.c +++ b/drivers/video/fbdev/msm/mdss_sync.c @@ -1,4 +1,5 @@ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -131,6 +132,13 @@ static void mdss_fence_release(struct fence *fence) struct mdss_timeline *tl = to_mdss_timeline(fence); pr_debug("%s for fence %s\n", __func__, f->name); + + if (!fence || (fence->ops->get_driver_name != + &mdss_fence_get_driver_name)) { + pr_debug("invalid parameters\n"); + return; + } + spin_lock(&tl->list_lock); if (!list_empty(&f->fence_list)) list_del(&f->fence_list); @@ -421,7 +429,10 @@ int mdss_wait_sync_fence(struct mdss_fence *fence, */ struct mdss_fence *mdss_get_fd_sync_fence(int fd) { - return (struct mdss_fence *) sync_file_get_fence(fd); + struct fence *fence = NULL; + + fence = sync_file_get_fence(fd); + return to_mdss_fence(fence); } /* @@ -464,11 +475,18 @@ int mdss_get_sync_fence_fd(struct mdss_fence *fence) */ const char *mdss_get_sync_fence_name(struct mdss_fence *fence) { + struct fence *input_fence = NULL; + if (!fence) { pr_err("invalid parameters\n"); return NULL; } + input_fence = (struct fence *) &fence->base; + + if (input_fence->ops->get_driver_name != &mdss_fence_get_driver_name) + return input_fence->ops->get_driver_name(input_fence); + return fence->name; } #endif diff --git a/include/linux/hid.h b/include/linux/hid.h index 877bb9aaca18e9cfd09dce3f9b717aaec8a6f5cf..bc3627b5ed65fb956b9b3931d3f28ad0658e5cf4 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -763,6 +763,22 @@ struct hid_ll_driver { int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); }; +extern struct hid_ll_driver i2c_hid_ll_driver; +extern struct hid_ll_driver hidp_hid_driver; +extern struct hid_ll_driver uhid_hid_driver; +extern struct hid_ll_driver usb_hid_driver; + +static inline bool hid_is_using_ll_driver(struct hid_device *hdev, + struct hid_ll_driver *driver) +{ + return hdev->ll_driver == driver; +} + +static inline bool hid_is_usb(struct hid_device *hdev) +{ + return hid_is_using_ll_driver(hdev, &usb_hid_driver); +} + #define PM_HINT_FULLON 1<<5 #define PM_HINT_NORMAL 1<<1 diff --git a/lib/Makefile b/lib/Makefile index 977e03f9984b9fe674fd4bc00a806520a8d23c8d..0fd0adf1c0f38a7d3df15cb39c959f48cc835bbc 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -2,6 +2,9 @@ # Makefile for some libs needed in the kernel. # +PERL = PERL5LIB=$(srctree)/../../prebuilts/tools-lineage/common/perl-base \ + $(srctree)/../../prebuilts/tools-lineage/linux-x86/bin/perl + ifdef CONFIG_FUNCTION_TRACER ORIG_CFLAGS := $(KBUILD_CFLAGS) KBUILD_CFLAGS = $(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS)) @@ -227,7 +230,7 @@ $(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \ $(call cmd,build_OID_registry) quiet_cmd_build_OID_registry = GEN $@ - cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@ + cmd_build_OID_registry = $(PERL) $(srctree)/$(src)/build_OID_registry $< $@ clean-files += oid_registry_data.c diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 552e00b07196e3a7a5ab0cfd91bd3297e3152089..0c1702b6a2b9de6dc73f3bfb94c7589ba240de18 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -734,7 +734,7 @@ static void hidp_stop(struct hid_device *hid) hid->claimed = 0; } -static struct hid_ll_driver hidp_hid_driver = { +struct hid_ll_driver hidp_hid_driver = { .parse = hidp_parse, .start = hidp_start, .stop = hidp_stop, @@ -743,6 +743,7 @@ static struct hid_ll_driver hidp_hid_driver = { .raw_request = hidp_raw_request, .output_report = hidp_output_report, }; +EXPORT_SYMBOL_GPL(hidp_hid_driver); /* This function sets up the hid device. It does not add it to the HID system. That is done in hidp_add_connection(). */ diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 02c1736c0b8977d87e47b2fb6520a89369be4106..b7e5f2917340ad52b52c705d5918aed6bc60d6c2 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -2684,6 +2684,7 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u rv = 1; } else if (im) { if (src_addr) { + spin_lock_bh(&im->lock); for (psf = im->sources; psf; psf = psf->sf_next) { if (psf->sf_inaddr == src_addr) break; @@ -2694,6 +2695,7 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u im->sfcount[MCAST_EXCLUDE]; else rv = im->sfcount[MCAST_EXCLUDE] != 0; + spin_unlock_bh(&im->lock); } else rv = 1; /* unspecified source; tentatively allow */ } diff --git a/scripts/gcc-wrapper.py b/scripts/gcc-wrapper.py deleted file mode 100755 index 3d1d6fbcaa049d45e494a53d202576d33d4762ba..0000000000000000000000000000000000000000 --- a/scripts/gcc-wrapper.py +++ /dev/null @@ -1,95 +0,0 @@ -#! /usr/bin/env python2 -# -*- coding: utf-8 -*- - -# Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of The Linux Foundation nor -# the names of its contributors may be used to endorse or promote -# products derived from this software without specific prior written -# permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Invoke gcc, looking for warnings, and causing a failure if there are -# non-whitelisted warnings. - -import errno -import re -import os -import sys -import subprocess - -# Note that gcc uses unicode, which may depend on the locale. TODO: -# force LANG to be set to en_US.UTF-8 to get consistent warnings. - -allowed_warnings = set([ - ]) - -# Capture the name of the object file, can find it. -ofile = None - -warning_re = re.compile(r'''(.*/|)([^/]+\.[a-z]+:\d+):(\d+:)? warning:''') -def interpret_warning(line): - """Decode the message from gcc. The messages we care about have a filename, and a warning""" - line = line.rstrip('\n') - m = warning_re.match(line) - if m and m.group(2) not in allowed_warnings: - print >> sys.stderr, "error, forbidden warning:", m.group(2) - - # If there is a warning, remove any object if it exists. - if ofile: - try: - os.remove(ofile) - except OSError: - pass - sys.exit(1) - -def run_gcc(): - args = sys.argv[1:] - # Look for -o - try: - i = args.index('-o') - global ofile - ofile = args[i+1] - except (ValueError, IndexError): - pass - - compiler = sys.argv[0] - - try: - proc = subprocess.Popen(args, stderr=subprocess.PIPE) - for line in proc.stderr: - print >> sys.stderr, line, - interpret_warning(line) - - result = proc.wait() - except OSError as e: - result = e.errno - if result == errno.ENOENT: - print >> sys.stderr, args[0] + ':',e.strerror - print >> sys.stderr, 'Is your PATH set correctly?' - else: - print >> sys.stderr, ' '.join(args), str(e) - - return result - -if __name__ == '__main__': - status = run_gcc() - sys.exit(status)