diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2019-09-23 02:36:09 -0700 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2019-09-23 02:36:09 -0700 |
commit | 0c755962c9cc4a8f7e9d90e81246e6f0eb651cce (patch) | |
tree | 6a30ae200159fcf6cfb886868f4636988e751404 | |
parent | 1f01db5a42ccd3123517a9d5730024719abf095d (diff) | |
parent | d097c6e0662d48d12f4f0d90bbe21a94e5331468 (diff) |
Merge d097c6e0662d48d12f4f0d90bbe21a94e5331468 on remote branchLA.UM.8.3.r1-06100-sdm845.0
Change-Id: Ic0e50a706acb12aff7e3373ea909e6e149486af2
56 files changed, 968 insertions, 145 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index 67060d309164..2f91abe04b0f 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -152,6 +152,9 @@ SoCs: - QM215 compatible = "qcom, qm215" +- QCM2150 + compatible = "qcom, qcm2150" + - MDM9640 compatible = "qcom,mdm9640" @@ -378,6 +381,7 @@ compatible = "qcom,sdm439-qrd" compatible = "qcom,sda439-cdp" compatible = "qcom,sda439-mtp" compatible = "qcom,qm215-qrd" +compatible = "qcom,qcm2150-qrd" compatible = "qcom,msm8953-rumi" compatible = "qcom,msm8953-sim" compatible = "qcom,msm8953-cdp" diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt index 745486301824..240bc5b4f292 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt @@ -384,6 +384,9 @@ the fps window. --> Sleep value (in ms) - qcom,partial-update-enabled: Boolean used to enable partial panel update for command mode panels. +- qcom,partial-update-addr-offset: An array of two values indicate the panel + column, row address offset value. + Two default values are 0. - qcom,mdss-dsi-horizontal-line-idle: List of width ranges (EC - SC) in pixels indicating additional idle time in dsi clock cycles that is needed to compensate for smaller line width. diff --git a/arch/arm/boot/dts/qcom/sdx-audio-lpass.dtsi b/arch/arm/boot/dts/qcom/sdx-audio-lpass.dtsi index 2c2319f7c886..934335fc9a99 100644 --- a/arch/arm/boot/dts/qcom/sdx-audio-lpass.dtsi +++ b/arch/arm/boot/dts/qcom/sdx-audio-lpass.dtsi @@ -84,7 +84,7 @@ compress: qcom,msm-compress-dsp { compatible = "qcom,msm-compress-dsp"; - qcom,adsp-version = "MDSP 1.2"; + qcom,adsp-version = "MDSP 2.8"; }; qcom,msm-dai-stub { diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 51578892cda8..06956b06410a 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -351,7 +351,8 @@ dtbo-$(CONFIG_ARCH_MSM8917) += msm8917-mtp-overlay.dtbo \ apq8017-cdp-overlay.dtbo \ apq8017-cdp-wcd-rome-overlay.dtbo -dtbo-$(CONFIG_ARCH_QM215) +=qm215-qrd-overlay.dtbo +dtbo-$(CONFIG_ARCH_QM215) +=qm215-qrd-overlay.dtbo \ + qcm2150-qrd-overlay.dtbo dtbo-$(CONFIG_ARCH_QM215) +=qm215-qrd-smb1360-overlay.dtbo dtbo-$(CONFIG_ARCH_MSM8953) += msm8953-mtp-overlay.dtbo \ @@ -434,6 +435,7 @@ apq8017-cdp-wcd-rome-overlay.dtbo-base := apq8017-pmi8950.dtb \ apq8017-pmi8937.dtb qm215-qrd-overlay.dtbo-base := qm215.dtb +qcm2150-qrd-overlay.dtbo-base := qcm2150.dtb qm215-qrd-smb1360-overlay.dtbo-base := qm215.dtb msm8953-mtp-overlay.dtbo-base := sdm450.dtb \ @@ -583,7 +585,8 @@ dtb-$(CONFIG_ARCH_MSM8917) += msm8917-pmi8950-mtp.dtb \ msm8917-pmi8940-cdp.dtb \ msm8917-pmi8940-rcm.dtb -dtb-$(CONFIG_ARCH_QM215) += qm215-qrd.dtb +dtb-$(CONFIG_ARCH_QM215) += qm215-qrd.dtb \ + qcm2150-qrd.dtb dtb-$(CONFIG_ARCH_QM215) += qm215-qrd-smb1360.dtb dtb-$(CONFIG_ARCH_MSM8909) += msm8909-pm8916-mtp.dtb \ @@ -641,6 +644,7 @@ dtb-$(CONFIG_ARCH_SDM439) += sdm439-mtp.dtb \ sdm439-external-codec-mtp.dtb \ sdm439-rcm.dtb \ qm215-qrd.dtb \ + qcm2150-qrd.dtb \ qm215-qrd-smb1360.dtb dtb-$(CONFIG_ARCH_SDM429) += sdm429-mtp.dtb \ diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-truly-rm69090-qvga-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-truly-rm69090-qvga-cmd.dtsi index 9c0ffc5ffdbe..4d7493360c91 100644 --- a/arch/arm64/boot/dts/qcom/dsi-panel-truly-rm69090-qvga-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/dsi-panel-truly-rm69090-qvga-cmd.dtsi @@ -40,8 +40,11 @@ qcom,mdss-dsi-pixel-packing = "tight"; qcom,mdss-dsi-pixel-alignment = <0>; qcom,mdss-dsi-on-command = [ + 15 01 00 00 00 00 02 FE 01 + 15 01 00 00 00 00 02 6A 03 15 01 00 00 00 00 02 FE 00 15 01 00 00 00 00 02 35 00 + 15 01 00 00 00 00 02 53 20 15 01 00 00 00 00 02 51 80 39 01 00 00 00 00 05 2A 00 10 01 7F 39 01 00 00 00 00 05 2B 00 00 01 BF @@ -59,6 +62,8 @@ 05 01 00 00 00 00 01 39 /* Idle-Mode On */ ]; qcom,mdss-dsi-idle-off-command = [ + 15 01 00 00 00 00 02 FE 00 + 15 01 00 00 00 00 02 53 20 05 01 00 00 00 00 01 38 /* Idle-Mode Off */ ]; qcom,mdss-dsi-idle-on-command-state = "dsi_hs_mode"; diff --git a/arch/arm64/boot/dts/qcom/qcm2150-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/qcm2150-qrd-overlay.dts new file mode 100644 index 000000000000..d8101504af9b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcm2150-qrd-overlay.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +/plugin/; + +#include "qcm2150-qrd.dtsi" + +/ { + model = "QRD"; + qcom,board-id = <0x01000b 4>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcm2150-qrd.dts b/arch/arm64/boot/dts/qcom/qcm2150-qrd.dts new file mode 100644 index 000000000000..5d1e1c5fdd46 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcm2150-qrd.dts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcm2150.dtsi" +#include "qcm2150-qrd.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCM2150 QRD"; + compatible = "qcom,qcm2150-qrd", "qcom,qcm2150", "qcom,qrd"; + qcom,board-id = <0x01000b 4>; + qcom,pmic-id = <0x010016 0x25 0x0 0x0>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcm2150-qrd.dtsi b/arch/arm64/boot/dts/qcom/qcm2150-qrd.dtsi new file mode 100644 index 000000000000..05af319cf83a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcm2150-qrd.dtsi @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2019, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "qm215-qrd.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCM2150 QRD"; +}; diff --git a/arch/arm64/boot/dts/qcom/qcm2150.dts b/arch/arm64/boot/dts/qcom/qcm2150.dts new file mode 100644 index 000000000000..179d0edc2696 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcm2150.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "qcm2150.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCM2150"; + compatible = "qcom,qcm2150"; + qcom,pmic-name = "PM8916"; +}; diff --git a/arch/arm64/boot/dts/qcom/qcm2150.dtsi b/arch/arm64/boot/dts/qcom/qcm2150.dtsi new file mode 100644 index 000000000000..eac04e1f6ba1 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcm2150.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "qm215.dtsi" +#include "qm215-pm8916.dtsi" +#include "qm215-audio.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. QCM2150"; + compatible = "qcom,qcm2150"; + qcom,msm-id = <436 0x0>; + qcom,msm-name = "QCM2150"; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi index 0f73bd92b512..9014166c228a 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi @@ -233,7 +233,7 @@ &secure_mem { alignment = <0 0x400000>; - size = <0 0x400000>; + size = <0 0x800000>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi index 3fecf16aefb0..57cd8f00a707 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi @@ -89,6 +89,9 @@ /delete-property/ qcom,mdss-dsi-panel-timings; qcom,mdss-dsi-panel-timings-phy-12nm = [04 04 01 08 00 03 01 0D]; qcom,panel-supply-entries = <&dsi_pm660_panel_pwr_supply>; + qcom,partial-update-enabled; + qcom,partial-update-addr-offset = <0x10 0>; + qcom,panel-roi-alignment = <2 2 4 2 20 2>; qcom,esd-check-enabled; qcom,mdss-dsi-panel-status-check-mode = "te_signal_check"; }; diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index dba81f9977fa..f62d96dcf636 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -744,15 +744,14 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags) } if (map->flags == ADSP_MMAP_HEAP_ADDR || map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) { - unsigned long dma_attrs = 0; if (me->dev == NULL) { pr_err("failed to free remote heap allocation\n"); return; } if (map->phys) { - dma_attrs |= - DMA_ATTR_SKIP_ZEROING | DMA_ATTR_NO_KERNEL_MAPPING; + unsigned long dma_attrs = DMA_ATTR_SKIP_ZEROING | + DMA_ATTR_NO_KERNEL_MAPPING; dma_free_attrs(me->dev, map->size, (void *)map->va, (dma_addr_t)map->phys, dma_attrs); } @@ -2451,29 +2450,34 @@ static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys, { int err = 0; struct fastrpc_apps *me = &gfa; + int tgid = 0; int destVM[1] = {VMID_HLOS}; int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC}; if (flags == ADSP_MMAP_HEAP_ADDR) { struct fastrpc_ioctl_invoke_crc ioctl; struct scm_desc desc = {0}; - remote_arg_t ra[1]; - int err = 0; + remote_arg_t ra[2]; + struct { uint8_t skey; } routargs; - ra[0].buf.pv = (void *)&routargs; - ra[0].buf.len = sizeof(routargs); + if (fl == NULL) + goto bail; + tgid = fl->tgid; + ra[0].buf.pv = (void *)&tgid; + ra[0].buf.len = sizeof(tgid); + ra[1].buf.pv = (void *)&routargs; + ra[1].buf.len = sizeof(routargs); ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL; - ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 0, 1); + ioctl.inv.sc = REMOTE_SCALARS_MAKE(9, 1, 1); ioctl.inv.pra = ra; ioctl.fds = NULL; ioctl.attrs = NULL; ioctl.crc = NULL; - if (fl == NULL) - goto bail; + VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c index 560f0df41839..d99f984208b7 100644 --- a/drivers/char/diag/diagfwd_peripheral.c +++ b/drivers/char/diag/diagfwd_peripheral.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, 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 @@ -1436,9 +1436,6 @@ int diagfwd_channel_close(struct diagfwd_info *fwd_info) if (!fwd_info) return -EIO; - if (fwd_info->type == TYPE_CNTL) - flush_workqueue(driver->cntl_wq); - mutex_lock(&driver->diagfwd_channel_mutex[fwd_info->peripheral]); fwd_info->ch_open = 0; if (fwd_info && fwd_info->c_ops && fwd_info->c_ops->close) diff --git a/drivers/char/diag/diagfwd_socket.c b/drivers/char/diag/diagfwd_socket.c index d7d73668b7b8..3451aba1784f 100644 --- a/drivers/char/diag/diagfwd_socket.c +++ b/drivers/char/diag/diagfwd_socket.c @@ -496,7 +496,7 @@ static void __socket_close_channel(struct diag_socket_info *info) if (!atomic_read(&info->opened)) return; - if ((bootup_req[info->peripheral] == PEPIPHERAL_SSR_UP) && + if ((bootup_req[info->peripheral] == PERIPHERAL_SSR_UP) && (info->port_type == PORT_TYPE_SERVER)) { DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "diag: %s is up, stopping cleanup: bootup_req = %d\n", @@ -504,9 +504,10 @@ static void __socket_close_channel(struct diag_socket_info *info) return; } - memset(&info->remote_addr, 0, sizeof(struct sockaddr_msm_ipc)); - diagfwd_channel_close(info->fwd_ctxt); - + if (info->type != TYPE_CNTL) { + memset(&info->remote_addr, 0, sizeof(struct sockaddr_msm_ipc)); + diagfwd_channel_close(info->fwd_ctxt); + } atomic_set(&info->opened, 0); /* Don't close the server. Server should always remain open */ @@ -955,6 +956,7 @@ static int restart_notifier_cb(struct notifier_block *this, unsigned long code, void *_cmd) { struct restart_notifier_block *notifier; + struct diag_socket_info *info = NULL; notifier = container_of(this, struct restart_notifier_block, nb); @@ -964,22 +966,31 @@ static int restart_notifier_cb(struct notifier_block *this, unsigned long code, return NOTIFY_DONE; } - mutex_lock(&driver->diag_notifier_mutex); DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s: ssr for processor %d ('%s')\n", __func__, notifier->processor, notifier->name); + info = &socket_cntl[notifier->processor]; switch (code) { case SUBSYS_BEFORE_SHUTDOWN: DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "diag: %s: SUBSYS_BEFORE_SHUTDOWN\n", __func__); - bootup_req[notifier->processor] = PEPIPHERAL_SSR_DOWN; + mutex_lock(&driver->diag_notifier_mutex); + bootup_req[notifier->processor] = PERIPHERAL_SSR_DOWN; + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, + "diag: bootup_req[%s] = %d\n", + notifier->name, (int)bootup_req[notifier->processor]); + mutex_unlock(&driver->diag_notifier_mutex); break; case SUBSYS_AFTER_SHUTDOWN: DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "diag: %s: SUBSYS_AFTER_SHUTDOWN\n", __func__); + mutex_lock(&driver->diag_notifier_mutex); + memset(&info->remote_addr, 0, sizeof(struct sockaddr_msm_ipc)); + diagfwd_channel_close(info->fwd_ctxt); + mutex_unlock(&driver->diag_notifier_mutex); break; case SUBSYS_BEFORE_POWERUP: @@ -990,11 +1001,20 @@ static int restart_notifier_cb(struct notifier_block *this, unsigned long code, case SUBSYS_AFTER_POWERUP: DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "diag: %s: SUBSYS_AFTER_POWERUP\n", __func__); + mutex_lock(&driver->diag_notifier_mutex); if (!bootup_req[notifier->processor]) { - bootup_req[notifier->processor] = PEPIPHERAL_SSR_DOWN; + bootup_req[notifier->processor] = PERIPHERAL_SSR_DOWN; + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, + "diag: bootup_req[%s] = %d\n", + notifier->name, (int)bootup_req[notifier->processor]); + mutex_unlock(&driver->diag_notifier_mutex); break; } - bootup_req[notifier->processor] = PEPIPHERAL_SSR_UP; + bootup_req[notifier->processor] = PERIPHERAL_SSR_UP; + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, + "diag: bootup_req[%s] = %d\n", + notifier->name, (int)bootup_req[notifier->processor]); + mutex_unlock(&driver->diag_notifier_mutex); break; default: @@ -1002,10 +1022,6 @@ static int restart_notifier_cb(struct notifier_block *this, unsigned long code, "diag: code: %lu\n", code); break; } - mutex_unlock(&driver->diag_notifier_mutex); - DIAG_LOG(DIAG_DEBUG_PERIPHERALS, - "diag: bootup_req[%s] = %d\n", - notifier->name, (int)bootup_req[notifier->processor]); return NOTIFY_DONE; } @@ -1165,8 +1181,12 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len, if (read_len <= 0) goto fail; - if (!atomic_read(&info->opened) && - info->port_type == PORT_TYPE_SERVER) { + if (info->type == TYPE_CNTL) { + memcpy(&info->remote_addr, &src_addr, sizeof(src_addr)); + if (!atomic_read(&info->opened)) + __socket_open_channel(info); + } else if (!atomic_read(&info->opened) && + info->port_type == PORT_TYPE_SERVER) { /* * This is the first packet from the client. Copy its * address to the connection object. Consider this diff --git a/drivers/char/diag/diagfwd_socket.h b/drivers/char/diag/diagfwd_socket.h index c42be06aa976..128c2be4e9fd 100644 --- a/drivers/char/diag/diagfwd_socket.h +++ b/drivers/char/diag/diagfwd_socket.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, 2019, 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 @@ -24,9 +24,9 @@ #define PORT_TYPE_SERVER 0 #define PORT_TYPE_CLIENT 1 -#define PEPIPHERAL_AFTER_BOOT 0 -#define PEPIPHERAL_SSR_DOWN 1 -#define PEPIPHERAL_SSR_UP 2 +#define PERIPHERAL_AFTER_BOOT 0 +#define PERIPHERAL_SSR_DOWN 1 +#define PERIPHERAL_SSR_UP 2 #define CNTL_CMD_NEW_SERVER 4 #define CNTL_CMD_REMOVE_SERVER 5 diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c index b095b0276f66..bff977d967f5 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.c +++ b/drivers/gpu/msm/adreno_ringbuffer.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2019, 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 @@ -302,6 +302,11 @@ static int _adreno_ringbuffer_probe(struct adreno_device *adreno_dev, PAGE_SIZE, 0, KGSL_MEMDESC_PRIVILEGED, "pagetable_desc"); if (ret) return ret; + + /* allocate a chunk of memory to create user profiling IB1s */ + kgsl_allocate_global(KGSL_DEVICE(adreno_dev), &rb->profile_desc, + PAGE_SIZE, KGSL_MEMFLAGS_GPUREADONLY, 0, "profile_desc"); + return kgsl_allocate_global(KGSL_DEVICE(adreno_dev), &rb->buffer_desc, KGSL_RB_SIZE, KGSL_MEMFLAGS_GPUREADONLY, 0, "ringbuffer"); @@ -316,7 +321,7 @@ int adreno_ringbuffer_probe(struct adreno_device *adreno_dev, bool nopreempt) if (!adreno_is_a3xx(adreno_dev)) { status = kgsl_allocate_global(device, &device->scratch, - PAGE_SIZE, 0, 0, "scratch"); + PAGE_SIZE, 0, KGSL_MEMDESC_RANDOM, "scratch"); if (status != 0) return status; } @@ -347,7 +352,7 @@ static void _adreno_ringbuffer_close(struct adreno_device *adreno_dev, kgsl_free_global(device, &rb->pagetable_desc); kgsl_free_global(device, &rb->preemption_desc); - + kgsl_free_global(device, &rb->profile_desc); kgsl_free_global(device, &rb->buffer_desc); kgsl_del_event_group(&rb->events); memset(rb, 0, sizeof(struct adreno_ringbuffer)); @@ -840,6 +845,37 @@ static inline int _get_alwayson_counter(struct adreno_device *adreno_dev, return (unsigned int)(p - cmds); } +/* This is the maximum possible size for 64 bit targets */ +#define PROFILE_IB_DWORDS 4 +#define PROFILE_IB_SLOTS (PAGE_SIZE / (PROFILE_IB_DWORDS << 2)) + +static int set_user_profiling(struct adreno_device *adreno_dev, + struct adreno_ringbuffer *rb, u32 *cmds, u64 gpuaddr) +{ + int dwords, index = 0; + u64 ib_gpuaddr; + u32 *ib; + + if (!rb->profile_desc.hostptr) + return 0; + + ib = ((u32 *) rb->profile_desc.hostptr) + + (rb->profile_index * PROFILE_IB_DWORDS); + ib_gpuaddr = rb->profile_desc.gpuaddr + + (rb->profile_index * (PROFILE_IB_DWORDS << 2)); + + dwords = _get_alwayson_counter(adreno_dev, ib, gpuaddr); + + /* Make an indirect buffer for the request */ + cmds[index++] = cp_mem_packet(adreno_dev, CP_INDIRECT_BUFFER_PFE, 2, 1); + index += cp_gpuaddr(adreno_dev, &cmds[index], ib_gpuaddr); + cmds[index++] = dwords; + + rb->profile_index = (rb->profile_index + 1) % PROFILE_IB_SLOTS; + + return index; +} + /* adreno_rindbuffer_submitcmd - submit userspace IBs to the GPU */ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev, struct kgsl_drawobj_cmd *cmdobj, @@ -940,14 +976,12 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev, !adreno_is_a3xx(adreno_dev) && (cmdobj->profiling_buf_entry != NULL)) { user_profiling = true; - dwords += 6; /* - * REG_TO_MEM packet on A5xx and above needs another ordinal. - * Add 2 more dwords since we do profiling before and after. + * User side profiling uses two IB1s, one before with 4 dwords + * per INDIRECT_BUFFER_PFE call */ - if (!ADRENO_LEGACY_PM4(adreno_dev)) - dwords += 2; + dwords += 8; /* * we want to use an adreno_submit_time struct to get the @@ -1006,11 +1040,11 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev, } /* - * Add cmds to read the GPU ticks at the start of command obj and + * Add IB1 to read the GPU ticks at the start of command obj and * write it into the appropriate command obj profiling buffer offset */ if (user_profiling) { - cmds += _get_alwayson_counter(adreno_dev, cmds, + cmds += set_user_profiling(adreno_dev, rb, cmds, cmdobj->profiling_buffer_gpuaddr + offsetof(struct kgsl_drawobj_profiling_buffer, gpu_ticks_submitted)); @@ -1058,11 +1092,11 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev, } /* - * Add cmds to read the GPU ticks at the end of command obj and + * Add IB1 to read the GPU ticks at the end of command obj and * write it into the appropriate command obj profiling buffer offset */ if (user_profiling) { - cmds += _get_alwayson_counter(adreno_dev, cmds, + cmds += set_user_profiling(adreno_dev, rb, cmds, cmdobj->profiling_buffer_gpuaddr + offsetof(struct kgsl_drawobj_profiling_buffer, gpu_ticks_retired)); diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h index a4dc901cf0b6..8e0c32108f96 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.h +++ b/drivers/gpu/msm/adreno_ringbuffer.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2019, 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 @@ -135,6 +135,18 @@ struct adreno_ringbuffer { unsigned long sched_timer; enum adreno_dispatcher_starve_timer_states starve_timer_state; spinlock_t preempt_lock; + /** + * @profile_desc: global memory to construct IB1s to do user side + * profiling + */ + struct kgsl_memdesc profile_desc; + /** + * @profile_index: Pointer to the next "slot" in profile_desc for a user + * profiling IB1. This allows for PAGE_SIZE / 16 = 256 simultaneous + * commands per ringbuffer with user profiling enabled + * enough. + */ + u32 profile_index; }; /* Returns the current ringbuffer */ diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h index 1fa27175064e..b9f5017fac77 100644 --- a/drivers/gpu/msm/kgsl.h +++ b/drivers/gpu/msm/kgsl.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2019, 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 @@ -197,6 +197,8 @@ struct kgsl_memdesc_ops { #define KGSL_MEMDESC_TZ_LOCKED BIT(7) /* The memdesc is allocated through contiguous memory */ #define KGSL_MEMDESC_CONTIG BIT(8) +/* For global buffers, randomly assign an address from the region */ +#define KGSL_MEMDESC_RANDOM BIT(9) /** * struct kgsl_memdesc - GPU memory object descriptor diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c index 40b49c397a18..1bfc9050bb47 100644 --- a/drivers/gpu/msm/kgsl_drawobj.c +++ b/drivers/gpu/msm/kgsl_drawobj.c @@ -598,13 +598,29 @@ static void add_profiling_buffer(struct kgsl_device *device, return; } - cmdobj->profiling_buf_entry = entry; - if (id != 0) + if (!id) { + cmdobj->profiling_buffer_gpuaddr = gpuaddr; + } else { + u64 off = offset + sizeof(struct kgsl_drawobj_profiling_buffer); + + /* + * Make sure there is enough room in the object to store the + * entire profiling buffer object + */ + if (off < offset || off >= entry->memdesc.size) { + dev_err(device->dev, + "ignore invalid profile offset ctxt %d id %d offset %lld gpuaddr %llx size %lld\n", + drawobj->context->id, id, offset, gpuaddr, size); + kgsl_mem_entry_put(entry); + return; + } + cmdobj->profiling_buffer_gpuaddr = entry->memdesc.gpuaddr + offset; - else - cmdobj->profiling_buffer_gpuaddr = gpuaddr; + } + + cmdobj->profiling_buf_entry = entry; } /** diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 87e143191c29..d023170a5de4 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, 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 @@ -20,6 +20,7 @@ #include <linux/msm_kgsl.h> #include <linux/ratelimit.h> #include <linux/of_platform.h> +#include <linux/random.h> #include <soc/qcom/scm.h> #include <soc/qcom/secure_buffer.h> #include <linux/compat.h> @@ -93,15 +94,8 @@ static struct kmem_cache *addr_entry_cache; * * Here we define an array and a simple allocator to keep track of the currently * active global entries. Each entry is assigned a unique address inside of a - * MMU implementation specific "global" region. The addresses are assigned - * sequentially and never re-used to avoid having to go back and reprogram - * existing pagetables. The entire list of active entries are mapped and - * unmapped into every new pagetable as it is created and destroyed. - * - * Because there are relatively few entries and they are defined at boot time we - * don't need to go over the top to define a dynamic allocation scheme. It will - * be less wasteful to pick a static number with a little bit of growth - * potential. + * MMU implementation specific "global" region. We use a simple bitmap based + * allocator for the region to allow for both fixed and dynamic addressing. */ #define GLOBAL_PT_ENTRIES 32 @@ -111,10 +105,13 @@ struct global_pt_entry { char name[32]; }; +#define GLOBAL_MAP_PAGES (KGSL_IOMMU_GLOBAL_MEM_SIZE >> PAGE_SHIFT) + static struct global_pt_entry global_pt_entries[GLOBAL_PT_ENTRIES]; +static DECLARE_BITMAP(global_map, GLOBAL_MAP_PAGES); + static int secure_global_size; static int global_pt_count; -uint64_t global_pt_alloc; static struct kgsl_memdesc gpu_qdss_desc; static struct kgsl_memdesc gpu_qtimer_desc; @@ -211,6 +208,12 @@ static void kgsl_iommu_remove_global(struct kgsl_mmu *mmu, for (i = 0; i < global_pt_count; i++) { if (global_pt_entries[i].memdesc == memdesc) { + u64 offset = memdesc->gpuaddr - + KGSL_IOMMU_GLOBAL_MEM_BASE(mmu); + + bitmap_clear(global_map, offset >> PAGE_SHIFT, + kgsl_memdesc_footprint(memdesc) >> PAGE_SHIFT); + memdesc->gpuaddr = 0; memdesc->priv &= ~KGSL_MEMDESC_GLOBAL; global_pt_entries[i].memdesc = NULL; @@ -222,19 +225,43 @@ static void kgsl_iommu_remove_global(struct kgsl_mmu *mmu, static void kgsl_iommu_add_global(struct kgsl_mmu *mmu, struct kgsl_memdesc *memdesc, const char *name) { + u32 bit, start = 0; + u64 size = kgsl_memdesc_footprint(memdesc); + if (memdesc->gpuaddr != 0) return; - /*Check that we can fit the global allocations */ - if (WARN_ON(global_pt_count >= GLOBAL_PT_ENTRIES) || - WARN_ON((global_pt_alloc + memdesc->size) >= - KGSL_IOMMU_GLOBAL_MEM_SIZE)) + if (WARN_ON(global_pt_count >= GLOBAL_PT_ENTRIES)) + return; + + if (WARN_ON(size > KGSL_IOMMU_GLOBAL_MEM_SIZE)) return; - memdesc->gpuaddr = KGSL_IOMMU_GLOBAL_MEM_BASE(mmu) + global_pt_alloc; + if (memdesc->priv & KGSL_MEMDESC_RANDOM) { + u32 range = GLOBAL_MAP_PAGES - (size >> PAGE_SHIFT); + + start = get_random_int() % range; + } + + while (start >= 0) { + bit = bitmap_find_next_zero_area(global_map, GLOBAL_MAP_PAGES, + start, size >> PAGE_SHIFT, 0); + + if (bit < GLOBAL_MAP_PAGES) + break; + + start--; + } + + if (WARN_ON(start < 0)) + return; + + memdesc->gpuaddr = + KGSL_IOMMU_GLOBAL_MEM_BASE(mmu) + (bit << PAGE_SHIFT); + + bitmap_set(global_map, bit, size >> PAGE_SHIFT); memdesc->priv |= KGSL_MEMDESC_GLOBAL; - global_pt_alloc += memdesc->size; global_pt_entries[global_pt_count].memdesc = memdesc; strlcpy(global_pt_entries[global_pt_count].name, name, diff --git a/drivers/i2c/busses/i2c-msm-v2.c b/drivers/i2c/busses/i2c-msm-v2.c index 631169b4081d..ad999a27c92a 100644 --- a/drivers/i2c/busses/i2c-msm-v2.c +++ b/drivers/i2c/busses/i2c-msm-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2019, 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 @@ -2144,8 +2144,12 @@ static bool i2c_msm_xfer_next_buf(struct i2c_msm_ctrl *ctrl) { struct i2c_msm_xfer_buf *cur_buf = &ctrl->xfer.cur_buf; struct i2c_msg *cur_msg = ctrl->xfer.msgs + cur_buf->msg_idx; - int bc_rem = cur_msg->len - cur_buf->end_idx; + int bc_rem = 0; + if (!cur_msg) + return false; + + bc_rem = cur_msg->len - cur_buf->end_idx; if (cur_buf->is_init && cur_buf->end_idx && bc_rem) { /* not the first buffer in a message */ @@ -2321,17 +2325,12 @@ i2c_msm_frmwrk_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) struct i2c_msm_ctrl *ctrl = i2c_get_adapdata(adap); struct i2c_msm_xfer *xfer = &ctrl->xfer; - if (num < 1) { + if (IS_ERR_OR_NULL(msgs) || num < 1) { dev_err(ctrl->dev, - "error on number of msgs(%d) received\n", num); + "Error on msgs Accessing invalid message pointer or message buffer\n"); return -EINVAL; } - if (IS_ERR_OR_NULL(msgs)) { - dev_err(ctrl->dev, " error on msgs Accessing invalid pointer location\n"); - return PTR_ERR(msgs); - } - /* if system is suspended just bail out */ if (ctrl->pwr_state == I2C_MSM_PM_SYS_SUSPENDED) { dev_err(ctrl->dev, diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_loader.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_loader.c index 9f3f586467cc..c7dbafa5e31a 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_loader.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_loader.c @@ -751,7 +751,7 @@ static int upgrade_firmware_from_class(struct device *dev) parade_debug(dev, DEBUG_LEVEL_2, "%s: Enabling firmware class loader\n", __func__); - retval = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, + retval = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, CY_FW_MANUAL_UPGRADE_FILE_NAME, dev, GFP_KERNEL, dev, _cyttsp5_firmware_cont); if (retval < 0) { diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h b/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h index 69870ef62976..9502c7a08f9a 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h @@ -168,7 +168,7 @@ enum PARADE_DEBUG_LEVEL { #else #define CY_HID_OUTPUT_TIMEOUT 200 #endif -#define CY_HID_OUTPUT_START_BOOTLOADER_TIMEOUT 2000 +#define CY_HID_OUTPUT_START_BOOTLOADER_TIMEOUT 200 #define CY_HID_OUTPUT_USER_TIMEOUT 8000 #define CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT 3000 #define CY_HID_OUTPUT_CALIBRATE_IDAC_TIMEOUT 5000 diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index 35e25b38474b..e63c79abcdbb 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -3651,6 +3651,8 @@ STREAM_BUFF_END: } else { ioctl_cmd = VIDIOC_MSM_BUF_MNGR_IOCTL_CMD; idx = MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX; + buff_mgr_info.index = + frame_info.output_buffer_info[0].index; } rc = msm_cpp_buffer_ops(cpp_dev, ioctl_cmd, idx, &buff_mgr_info); @@ -4364,6 +4366,8 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file, memset(&k64_frame_info, 0, sizeof(k64_frame_info)); k64_frame_info.identity = k32_frame_info.identity; k64_frame_info.frame_id = k32_frame_info.frame_id; + k64_frame_info.output_buffer_info[0].index = + k32_frame_info.output_buffer_info[0].index; kp_ioctl.ioctl_ptr = (__force void __user *)&k64_frame_info; diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c index 42f5a840de46..1f19f58e33e4 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c @@ -233,6 +233,28 @@ int cam_context_handle_crm_process_evt(struct cam_context *ctx, return rc; } +int cam_context_handle_crm_dump_req(struct cam_context *ctx, + struct cam_req_mgr_dump_info *dump) +{ + int rc = 0; + + if (!ctx->state_machine) { + CAM_ERR(CAM_CORE, "Context is not ready"); + return -EINVAL; + } + mutex_lock(&ctx->ctx_mutex); + if (ctx->state_machine[ctx->state].crm_ops.dump_req) { + rc = ctx->state_machine[ctx->state].crm_ops.dump_req(ctx, + dump); + } else { + CAM_ERR(CAM_CORE, "No crm dump req in dev %d, state %d", + ctx->dev_hdl, ctx->state); + } + mutex_unlock(&ctx->ctx_mutex); + + return rc; +} + int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova, uint32_t buf_info) { @@ -501,6 +523,33 @@ int cam_context_handle_stop_dev(struct cam_context *ctx, return rc; } +int cam_context_handle_dump_dev(struct cam_context *ctx, + struct cam_dump_req_cmd *cmd) +{ + int rc = 0; + + if (!ctx || !ctx->state_machine) { + CAM_ERR(CAM_CORE, "Context is not ready"); + return -EINVAL; + } + + if (!cmd) { + CAM_ERR(CAM_CORE, "Invalid stop device command payload"); + return -EINVAL; + } + + mutex_lock(&ctx->ctx_mutex); + if (ctx->state_machine[ctx->state].ioctl_ops.dump_dev) + rc = ctx->state_machine[ctx->state].ioctl_ops.dump_dev( + ctx, cmd); + else + CAM_WARN(CAM_CORE, "No dump device in dev %d, name %s state %d", + ctx->dev_hdl, ctx->dev_name, ctx->state); + mutex_unlock(&ctx->ctx_mutex); + + return rc; +} + int cam_context_init(struct cam_context *ctx, const char *dev_name, uint64_t dev_id, diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context.h b/drivers/media/platform/msm/camera_v3/cam_core/cam_context.h index 2d8c6e0ae819..84a190a4c5a6 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context.h +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context.h @@ -92,6 +92,7 @@ struct cam_ctx_request { * @flush_dev: Function pointer for flush device * @acquire_hw: Function pointer for acquire hw * @release_hw: Function pointer for release hw + * @dump_dev: Function pointer for dump dev * */ struct cam_ctx_ioctl_ops { @@ -109,6 +110,9 @@ struct cam_ctx_ioctl_ops { struct cam_flush_dev_cmd *cmd); int (*acquire_hw)(struct cam_context *ctx, void *args); int (*release_hw)(struct cam_context *ctx, void *args); + int (*dump_dev)(struct cam_context *ctx, + struct cam_dump_req_cmd *cmd); + }; /** @@ -120,6 +124,7 @@ struct cam_ctx_ioctl_ops { * @apply_req: Apply setting for the context * @flush_req: Flush request to remove request ids * @process_evt: Handle event notification from CRM.(optional) + * @dump_req: Dump information for the issue request * */ struct cam_ctx_crm_ops { @@ -135,6 +140,8 @@ struct cam_ctx_crm_ops { struct cam_req_mgr_flush_request *flush); int (*process_evt)(struct cam_context *ctx, struct cam_req_mgr_link_evt_data *evt_data); + int (*dump_req)(struct cam_context *ctx, + struct cam_req_mgr_dump_info *dump); }; @@ -305,6 +312,18 @@ int cam_context_handle_crm_process_evt(struct cam_context *ctx, struct cam_req_mgr_link_evt_data *process_evt); /** + * cam_context_handle_crm_dump_req() + * + * @brief: Handle CRM dump request + * + * @ctx: Object pointer for cam_context + * @dump: Request to dump + * + */ +int cam_context_handle_crm_dump_req(struct cam_context *ctx, + struct cam_req_mgr_dump_info *dump); + +/** * cam_context_dump_pf_info() * * @brief: Handle dump active request request command @@ -413,6 +432,19 @@ int cam_context_handle_start_dev(struct cam_context *ctx, int cam_context_handle_stop_dev(struct cam_context *ctx, struct cam_start_stop_dev_cmd *cmd); + +/** + * cam_context_handle_dump_dev() + * + * @brief: Handle dump device command + * + * @ctx: Object pointer for cam_context + * @cmd: Dump device command payload + * + */ +int cam_context_handle_dump_dev(struct cam_context *ctx, + struct cam_dump_req_cmd *cmd); + /** * cam_context_deinit() * diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c index 11bad5dd4647..d7500a138803 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c @@ -1039,3 +1039,43 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx, end: return rc; } + +int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx, + struct cam_dump_req_cmd *cmd) +{ + int rc = 0; + struct cam_hw_dump_args dump_args; + + if (!ctx || !cmd) { + CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd); + return -EINVAL; + } + if (!ctx->hw_mgr_intf) { + CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", + ctx->dev_name, ctx->ctx_id); + return -EFAULT; + } + memset(&dump_args, 0, sizeof(dump_args)); + if (ctx->hw_mgr_intf->hw_dump) { + dump_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map; + dump_args.buf_handle = cmd->buf_handle; + dump_args.offset = cmd->offset; + dump_args.request_id = cmd->issue_req_id; + rc = ctx->hw_mgr_intf->hw_dump( + ctx->hw_mgr_intf->hw_mgr_priv, + &dump_args); + if (rc) { + CAM_ERR(CAM_CTXT, "[%s][%d] handle[%u] failed", + ctx->dev_name, ctx->ctx_id, dump_args.buf_handle); + return rc; + } + CAM_INFO(CAM_CTXT, "[%s] ctx: %d Filled Length %d", + ctx->dev_name, ctx->ctx_id, + dump_args.offset - cmd->offset); + /* Drivers update offest upto which the buffer is written*/ + cmd->offset = dump_args.offset; + } else { + CAM_INFO(CAM_CTXT, "%s hw dump not registered", ctx->dev_name); + } + return rc; +} diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.h b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.h index e1809b2fa436..022641f064ea 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.h +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -36,5 +36,6 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx, int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx, struct cam_packet *packet, unsigned long iova, uint32_t buf_info, bool *mem_found); - +int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx, + struct cam_dump_req_cmd *cmd); #endif /* _CAM_CONTEXT_UTILS_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h b/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h index 2afdafb03184..19e3230d9011 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h @@ -272,6 +272,21 @@ struct cam_hw_reset_args { void *ctxt_to_hw_map; }; +/** + * struct cam_hw_dump_args - Dump arguments + * + * @request_id: request_id + * @buf_handle: Buffer handle + * @offset: Buffer offset. This is updated by the drivers. + * @ctxt_to_hw_map: HW context from the acquire + */ +struct cam_hw_dump_args { + uint64_t request_id; + uint32_t buf_handle; + int32_t offset; + void *ctxt_to_hw_map; +}; + /* enum cam_hw_mgr_command - Hardware manager command type */ enum cam_hw_mgr_command { CAM_HW_MGR_CMD_INTERNAL, @@ -324,6 +339,7 @@ struct cam_hw_cmd_args { * @hw_close: Function pointer for HW deinit * @hw_flush: Function pointer for HW flush * @hw_reset: Function pointer for HW reset + * @hw_dump: Function pointer for HW dump * */ struct cam_hw_mgr_intf { @@ -345,6 +361,7 @@ struct cam_hw_mgr_intf { int (*hw_close)(void *hw_priv, void *hw_close_args); int (*hw_flush)(void *hw_priv, void *hw_flush_args); int (*hw_reset)(void *hw_priv, void *hw_reset_args); + int (*hw_dump)(void *hw_priv, void *hw_dump_args); }; #endif /* _CAM_HW_MGR_INTF_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_node.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_node.c index 2578fb93a615..322b7e68da69 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_node.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_node.c @@ -330,6 +330,39 @@ static int __cam_node_handle_flush_dev(struct cam_node *node, return rc; } +static int __cam_node_handle_dump_dev(struct cam_node *node, + struct cam_dump_req_cmd *dump) +{ + struct cam_context *ctx = NULL; + int rc; + + if (!dump) + return -EINVAL; + + if (dump->dev_handle <= 0) { + CAM_ERR(CAM_CORE, "Invalid device handle for context"); + return -EINVAL; + } + + if (dump->session_handle <= 0) { + CAM_ERR(CAM_CORE, "Invalid session handle for context"); + return -EINVAL; + } + + ctx = (struct cam_context *)cam_get_device_priv(dump->dev_handle); + if (!ctx) { + CAM_ERR(CAM_CORE, "Can not get context for handle %d", + dump->dev_handle); + return -EINVAL; + } + + rc = cam_context_handle_dump_dev(ctx, dump); + if (rc) + CAM_ERR(CAM_CORE, "Flush failure for node %s", node->name); + + return rc; +} + static int __cam_node_handle_release_dev(struct cam_node *node, struct cam_release_dev_cmd *release) { @@ -531,6 +564,25 @@ static int __cam_node_crm_process_evt( return cam_context_handle_crm_process_evt(ctx, evt_data); } +static int __cam_node_crm_dump_req(struct cam_req_mgr_dump_info *dump) +{ + struct cam_context *ctx = NULL; + + if (!dump) { + CAM_ERR(CAM_CORE, "Invalid dump request payload"); + return -EINVAL; + } + + ctx = (struct cam_context *) cam_get_device_priv(dump->dev_hdl); + if (!ctx) { + CAM_ERR(CAM_CORE, "Can not get context for handle %d", + dump->dev_hdl); + return -EINVAL; + } + + return cam_context_handle_crm_dump_req(ctx, dump); +} + int cam_node_deinit(struct cam_node *node) { if (node) @@ -586,6 +638,7 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf, node->crm_node_intf.link_setup = __cam_node_crm_link_setup; node->crm_node_intf.flush_req = __cam_node_crm_flush_req; node->crm_node_intf.process_evt = __cam_node_crm_process_evt; + node->crm_node_intf.dump_req = __cam_node_crm_dump_req; mutex_init(&node->list_mutex); INIT_LIST_HEAD(&node->free_ctx_list); @@ -827,6 +880,28 @@ release_kfree: } break; } + case CAM_DUMP_REQ: { + struct cam_dump_req_cmd dump; + + if (copy_from_user(&dump, u64_to_user_ptr(cmd->handle), + sizeof(dump))) { + rc = -EFAULT; + } else { + rc = __cam_node_handle_dump_dev(node, &dump); + if (rc) { + CAM_ERR(CAM_CORE, + "Dump device %s failed(rc = %d) ", + node->name, rc); + } else if (copy_to_user(u64_to_user_ptr(cmd->handle), + &dump, sizeof(dump))) { + CAM_ERR(CAM_CORE, + "Dump device %s copy_to_user fail", + node->name); + rc = -EFAULT; + } + } + break; + } default: CAM_ERR(CAM_CORE, "Unknown op code %d", cmd->op_code); rc = -EINVAL; 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 b2994d52d83c..4d10ea65818e 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 @@ -3454,9 +3454,73 @@ end: } +int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req) +{ + int rc = 0; + struct cam_req_mgr_core_link *link = NULL; + struct cam_req_mgr_core_session *session = NULL; + struct cam_req_mgr_dump_info info; + struct cam_req_mgr_connected_device *device = NULL; + int i; + + if (!dump_req) { + CAM_ERR(CAM_CRM, "dump req is NULL"); + rc = -EFAULT; + goto end; + } + + mutex_lock(&g_crm_core_dev->crm_lock); + /* session hdl's priv data is cam session struct */ + session = (struct cam_req_mgr_core_session *) + cam_get_device_priv(dump_req->session_handle); + if (!session) { + CAM_ERR(CAM_CRM, "Invalid session %x", + dump_req->session_handle); + rc = -EINVAL; + goto end; + } + if (session->num_links <= 0) { + CAM_WARN(CAM_CRM, "No active links in session %x", + dump_req->session_handle); + goto end; + } + + link = (struct cam_req_mgr_core_link *) + cam_get_device_priv(dump_req->link_hdl); + if (!link) { + CAM_DBG(CAM_CRM, "link ptr NULL %x", dump_req->link_hdl); + rc = -EINVAL; + goto end; + } + info.offset = dump_req->offset; + for (i = 0; i < link->num_devs; i++) { + device = &link->l_dev[i]; + info.link_hdl = dump_req->link_hdl; + info.dev_hdl = device->dev_hdl; + info.req_id = dump_req->issue_req_id; + info.buf_handle = dump_req->buf_handle; + if (device->ops && device->ops->dump_req) { + rc = device->ops->dump_req(&info); + if (rc) { + CAM_ERR(CAM_REQ, "Fail dump req %lld dev %d", + info.req_id, + device->dev_hdl); + } + } + } + dump_req->offset = info.offset; + CAM_INFO(CAM_REQ, "req %lld, offset %u", + dump_req->issue_req_id, dump_req->offset); +end: + mutex_unlock(&g_crm_core_dev->crm_lock); + return 0; + +} + int cam_req_mgr_core_device_init(void) { int i; + CAM_DBG(CAM_CRM, "Enter g_crm_core_dev %pK", g_crm_core_dev); if (g_crm_core_dev) { diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h index 94f26dee8917..679b2cf4a5a2 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h @@ -56,6 +56,7 @@ enum crm_workq_task_type { CRM_WORKQ_TASK_NOTIFY_FREEZE, CRM_WORKQ_TASK_SCHED_REQ, CRM_WORKQ_TASK_FLUSH_REQ, + CRM_WORKQ_TASK_DUMP_REQ, CRM_WORKQ_TASK_INVALID, }; @@ -485,4 +486,11 @@ void cam_req_mgr_handle_core_shutdown(void); */ int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control); +/** + * cam_req_mgr_dump_request() + * @brief: Dumps the request information + * @dump_req: Dump request + */ +int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req); + #endif 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 31607ac6391f..5d4d9fcc47ab 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 @@ -473,6 +473,31 @@ static long cam_private_ioctl(struct file *file, void *fh, rc = -EINVAL; } break; + + case CAM_REQ_MGR_REQUEST_DUMP: { + struct cam_dump_req_cmd cmd; + + if (k_ioctl->size != sizeof(cmd)) + return -EINVAL; + + if (copy_from_user(&cmd, + u64_to_user_ptr(k_ioctl->handle), + sizeof(struct cam_dump_req_cmd))) { + rc = -EFAULT; + break; + } + + rc = cam_req_mgr_dump_request(&cmd); + if (!rc) + if (copy_to_user( + u64_to_user_ptr(k_ioctl->handle), + &cmd, sizeof(struct cam_dump_req_cmd))) { + rc = -EFAULT; + break; + } + } + break; + default: return -ENOIOCTLCMD; } diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h index 934bc76014a5..33274186fc15 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h @@ -26,6 +26,7 @@ struct cam_req_mgr_core_dev_link_setup; struct cam_req_mgr_apply_request; struct cam_req_mgr_flush_request; struct cam_req_mgr_link_evt_data; +struct cam_req_mgr_dump_info; #define SKIP_NEXT_FRAME 0x100 @@ -52,6 +53,7 @@ typedef int (*cam_req_mgr_add_req)(struct cam_req_mgr_add_request *); * @cam_req_mgr_apply_req : CRM asks device to apply certain request id. * @cam_req_mgr_flush_req : Flush or cancel request * cam_req_mgr_process_evt : generic events + * cam_req_mgr_dump_req : dump request */ typedef int (*cam_req_mgr_get_dev_info) (struct cam_req_mgr_device_info *); typedef int (*cam_req_mgr_link_setup)( @@ -59,6 +61,7 @@ typedef int (*cam_req_mgr_link_setup)( typedef int (*cam_req_mgr_apply_req)(struct cam_req_mgr_apply_request *); typedef int (*cam_req_mgr_flush_req)(struct cam_req_mgr_flush_request *); typedef int (*cam_req_mgr_process_evt)(struct cam_req_mgr_link_evt_data *); +typedef int (*cam_req_mgr_dump_req)(struct cam_req_mgr_dump_info *); /** * @brief : cam_req_mgr_crm_cb - func table @@ -81,6 +84,7 @@ struct cam_req_mgr_crm_cb { * @apply_req : payload to apply request id on a device linked * @flush_req : payload to flush request * @process_evt : payload to generic event + * @dump_req : payload to dump request */ struct cam_req_mgr_kmd_ops { cam_req_mgr_get_dev_info get_dev_info; @@ -88,6 +92,7 @@ struct cam_req_mgr_kmd_ops { cam_req_mgr_apply_req apply_req; cam_req_mgr_flush_req flush_req; cam_req_mgr_process_evt process_evt; + cam_req_mgr_dump_req dump_req; }; /** @@ -338,4 +343,25 @@ struct cam_req_mgr_send_request { int32_t link_hdl; struct cam_req_mgr_req_queue *in_q; }; + +/** + * struct cam_req_mgr_dump_info + * @req_id : request id to cancel + * @link_hdl : link identifier + * @dev_hdl : device handle for cross check + * @buf_handle : buf handle + * @offset : offset of buffere + * @error_type : error type + * + */ +struct cam_req_mgr_dump_info { + uint64_t req_id; + int32_t link_hdl; + int32_t dev_hdl; + uint32_t buf_handle; + int32_t offset; + int32_t error_type; +}; + + #endif diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_common_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_common_util.c index bba12cf106df..fd113aeb1dc5 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_common_util.c +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_common_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -55,3 +55,22 @@ uint32_t cam_common_util_remove_duplicate_arr(int32_t *arr, uint32_t num) return wr_idx; } + +uint64_t cam_common_util_get_time_diff(struct timeval *t1, struct timeval *t2) +{ + uint64_t diff = 0; + + diff = (t1->tv_sec - t2->tv_sec) * 1000000 + + (t1->tv_usec - t2->tv_usec); + return diff; +} + +void cam_common_util_get_curr_timestamp(struct timeval *time_stamp) +{ + struct timespec ts; + + get_monotonic_boottime(&ts); + time_stamp->tv_sec = ts.tv_sec; + time_stamp->tv_usec = ts.tv_nsec/1000; +} + diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_common_util.h b/drivers/media/platform/msm/camera_v3/cam_utils/cam_common_util.h index 47d441fe3aa1..136eaf013695 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_common_util.h +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_common_util.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -52,4 +52,26 @@ int cam_common_util_get_string_index(const char **strings, uint32_t cam_common_util_remove_duplicate_arr(int32_t *array, uint32_t num); +/** + * cam_common_util_get_time_diff() + * + * @brief Get the time difference between 2 timestamps in usecs + * + * @t1: Pointer to the later time + * @t2: Pointer to the prev time + * + * @return: differnce in usecs + */ +uint64_t cam_common_util_get_time_diff(struct timeval *t1, struct timeval *t2); + +/** + * cam_comomon_util_get_curr_timestamp() + * + * @brief Get the current timestamp + * + * @time_stamp: Pointer to the time + * + * @return: void + */ +void cam_common_util_get_curr_timestamp(struct timeval *time_stamp); #endif /* _CAM_COMMON_UTIL_H_ */ diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 8a76b649f09c..14a355401c60 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -3434,6 +3434,33 @@ int __boundary_checks_offset(struct qseecom_send_modfd_cmd_req *req, return 0; } +static int __boundary_checks_offset_64(struct qseecom_send_modfd_cmd_req *req, + struct qseecom_send_modfd_listener_resp *lstnr_resp, + struct qseecom_dev_handle *data, int i) +{ + + if ((data->type != QSEECOM_LISTENER_SERVICE) && + (req->ifd_data[i].fd > 0)) { + if ((req->cmd_req_len < sizeof(uint64_t)) || + (req->ifd_data[i].cmd_buf_offset > + req->cmd_req_len - sizeof(uint64_t))) { + pr_err("Invalid offset (req len) 0x%x\n", + req->ifd_data[i].cmd_buf_offset); + return -EINVAL; + } + } else if ((data->type == QSEECOM_LISTENER_SERVICE) && + (lstnr_resp->ifd_data[i].fd > 0)) { + if ((lstnr_resp->resp_len < sizeof(uint64_t)) || + (lstnr_resp->ifd_data[i].cmd_buf_offset > + lstnr_resp->resp_len - sizeof(uint64_t))) { + pr_err("Invalid offset (lstnr resp len) 0x%x\n", + lstnr_resp->ifd_data[i].cmd_buf_offset); + return -EINVAL; + } + } + return 0; +} + static int __qseecom_update_cmd_buf(void *msg, bool cleanup, struct qseecom_dev_handle *data) { @@ -3793,7 +3820,8 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup, if (sg_ptr->nents == 1) { uint64_t *update_64bit; - if (__boundary_checks_offset(req, lstnr_resp, data, i)) + if (__boundary_checks_offset_64(req, lstnr_resp, + data, i)) goto err; /* 64bit app uses 64bit address */ update_64bit = (uint64_t *) field; diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 0d9b6f0e49b0..e7a3946f6881 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -150,6 +150,15 @@ static irqreturn_t nqx_dev_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +static int is_data_available_for_read(struct nqx_dev *nqx_dev) +{ + int ret; + + nqx_enable_irq(nqx_dev); + ret = wait_event_interruptible(nqx_dev->read_wq, !nqx_dev->irq_enabled); + return ret; +} + static ssize_t nfc_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) { @@ -679,7 +688,6 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev) { int ret = 0; - int gpio_retry_count = 0; unsigned char raw_nci_reset_cmd[] = {0x20, 0x00, 0x01, 0x00}; unsigned char raw_nci_init_cmd[] = {0x20, 0x01, 0x00}; unsigned char nci_get_version_cmd[] = {0x00, 0x04, 0xF1, @@ -690,7 +698,6 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev) unsigned char init_rsp_len = 0; unsigned int enable_gpio = nqx_dev->en_gpio; -reset_enable_gpio: /* making sure that the NFCC starts in a clean state. */ gpio_set_value(enable_gpio, 0);/* ULPM: Disable */ /* hardware dependent delay */ @@ -746,8 +753,11 @@ reset_enable_gpio: } goto err_nfcc_reset_failed; } - /* hardware dependent delay */ - msleep(30); + ret = is_data_available_for_read(nqx_dev); + if (ret < 0) { + nqx_disable_irq(nqx_dev); + goto err_nfcc_hw_check; + } /* Read Response of RESET command */ ret = i2c_master_recv(client, nci_reset_rsp, @@ -755,11 +765,10 @@ reset_enable_gpio: if (ret < 0) { dev_err(&client->dev, "%s: - i2c_master_recv Error\n", __func__); - gpio_retry_count = gpio_retry_count + 1; - if (gpio_retry_count < MAX_RETRY_COUNT) - goto reset_enable_gpio; goto err_nfcc_hw_check; } + + /* send NCI CORE INIT CMD */ ret = nqx_standby_write(nqx_dev, raw_nci_init_cmd, sizeof(raw_nci_init_cmd)); if (ret < 0) { @@ -767,8 +776,12 @@ reset_enable_gpio: "%s: - i2c_master_send failed for Core INIT\n", __func__); goto err_nfcc_core_init_fail; } - /* hardware dependent delay */ - msleep(30); + ret = is_data_available_for_read(nqx_dev); + if (ret < 0) { + nqx_disable_irq(nqx_dev); + goto err_nfcc_hw_check; + } + /* Read Response of INIT command */ ret = i2c_master_recv(client, nci_init_rsp, sizeof(nci_init_rsp)); @@ -822,6 +835,11 @@ err_nfcc_reset_failed: dev_dbg(&client->dev, "%s: ## NFCC == PN66T ##\n", __func__); break; + case NFCC_SN100_A: + case NFCC_SN100_B: + dev_dbg(&client->dev, + "%s: ## NFCC == SN100x ##\n", __func__); + break; default: dev_err(&client->dev, "%s: - NFCC HW not Supported\n", __func__); diff --git a/drivers/nfc/nq-nci.h b/drivers/nfc/nq-nci.h index 87715c2e6237..d17897db7bab 100644 --- a/drivers/nfc/nq-nci.h +++ b/drivers/nfc/nq-nci.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, 2019 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 @@ -48,6 +48,8 @@ enum nfcc_chip_variant { NFCC_NQ_220 = 0x58, /**< NFCC NQ220 */ NFCC_NQ_310 = 0x40, /**< NFCC NQ310 */ NFCC_NQ_330 = 0x51, /**< NFCC NQ330 */ + NFCC_SN100_A = 0xa3, /**< NFCC SN100_A */ + NFCC_SN100_B = 0xa4, /**< NFCC SN100_B */ NFCC_PN66T = 0x18, /**< NFCC PN66T */ NFCC_NOT_SUPPORTED = 0xFF /**< NFCC is not supported */ }; diff --git a/drivers/rtc/qpnp-rtc.c b/drivers/rtc/qpnp-rtc.c index 06833efa7baa..4b7a1d8e764e 100644 --- a/drivers/rtc/qpnp-rtc.c +++ b/drivers/rtc/qpnp-rtc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2015, 2017-2019,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 @@ -597,7 +597,7 @@ static int qpnp_rtc_probe(struct platform_device *pdev) rtc_ops = &qpnp_rtc_rw_ops; dev_set_drvdata(&pdev->dev, rtc_dd); - + device_init_wakeup(&pdev->dev, 1); /* Register the RTC device */ rtc_dd->rtc = rtc_device_register("qpnp_rtc", &pdev->dev, rtc_ops, THIS_MODULE); @@ -627,6 +627,7 @@ static int qpnp_rtc_probe(struct platform_device *pdev) fail_req_irq: rtc_device_unregister(rtc_dd->rtc); fail_rtc_enable: + device_init_wakeup(&pdev->dev, 0); dev_set_drvdata(&pdev->dev, NULL); return rc; diff --git a/drivers/soc/qcom/bg_rsb.c b/drivers/soc/qcom/bg_rsb.c index 05fb9ab019c2..c35e385a6833 100644 --- a/drivers/soc/qcom/bg_rsb.c +++ b/drivers/soc/qcom/bg_rsb.c @@ -139,6 +139,7 @@ struct bgrsb_priv { bool is_cnfgrd; bool blk_rsb_cmnds; + bool pending_enable; }; static void *bgrsb_drv; @@ -406,6 +407,8 @@ static void bgrsb_bgdown_work(struct work_struct *work) struct bgrsb_priv *dev = container_of(work, struct bgrsb_priv, bg_down_work); + mutex_lock(&dev->rsb_state_mutex); + if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) { if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15) == 0) dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED; @@ -428,6 +431,8 @@ static void bgrsb_bgdown_work(struct work_struct *work) if (dev->is_calibrd) dev->calibration_needed = true; } + + mutex_unlock(&dev->rsb_state_mutex); } static void bgrsb_glink_bgdown_work(struct work_struct *work) @@ -436,17 +441,19 @@ static void bgrsb_glink_bgdown_work(struct work_struct *work) struct bgrsb_priv *dev = container_of(work, struct bgrsb_priv, rsb_glink_down_work); + mutex_lock(&dev->rsb_state_mutex); + if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) { rc = bgrsb_enable(dev, false); if (rc != 0) { pr_err("Failed to send disable command to BG\n"); - return; + goto unlock; } if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15) != 0) { pr_err("Failed to un-vote LDO-15\n"); - return; + goto unlock; } dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED; @@ -468,6 +475,9 @@ static void bgrsb_glink_bgdown_work(struct work_struct *work) glink_close(dev->handle); dev->handle = NULL; pr_debug("BG Glink Close connection\n"); + +unlock: + mutex_unlock(&dev->rsb_state_mutex); } static int bgrsb_tx_msg(struct bgrsb_priv *dev, void *msg, size_t len) @@ -558,6 +568,7 @@ static void bgrsb_bgup_work(struct work_struct *work) struct bgrsb_priv *dev = container_of(work, struct bgrsb_priv, bg_up_work); + mutex_lock(&dev->rsb_state_mutex); if (bgrsb_ldo_work(dev, BGRSB_ENABLE_LDO11) == 0) { rc = wait_event_timeout(dev->link_state_wait, @@ -565,20 +576,24 @@ static void bgrsb_bgup_work(struct work_struct *work) msecs_to_jiffies(TIMEOUT_MS)); if (rc == 0) { pr_err("Glink channel connection time out\n"); - return; + goto unlock; } rc = bgrsb_configr_rsb(dev, true); if (rc != 0) { pr_err("BG failed to configure RSB %d\n", rc); if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO11) == 0) dev->bgrsb_current_state = BGRSB_STATE_INIT; - return; + goto unlock; } dev->is_cnfgrd = true; dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED; pr_debug("RSB Cofigured\n"); + if (dev->pending_enable) + queue_work(dev->bgrsb_wq, &dev->rsb_up_work); } +unlock: + mutex_unlock(&dev->rsb_state_mutex); } static void bgrsb_glink_bgup_work(struct work_struct *work) @@ -587,6 +602,7 @@ static void bgrsb_glink_bgup_work(struct work_struct *work) struct bgrsb_priv *dev = container_of(work, struct bgrsb_priv, rsb_glink_up_work); + mutex_lock(&dev->rsb_state_mutex); if (bgrsb_ldo_work(dev, BGRSB_ENABLE_LDO11) == 0) { INIT_WORK(&dev->glink_work, bgrsb_glink_open_work); @@ -597,19 +613,25 @@ static void bgrsb_glink_bgup_work(struct work_struct *work) msecs_to_jiffies(TIMEOUT_MS)); if (rc == 0) { pr_err("Glink channel connection time out\n"); - return; + goto unlock; } rc = bgrsb_configr_rsb(dev, true); if (rc != 0) { pr_err("BG Glink failed to configure RSB %d\n", rc); if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO11) == 0) dev->bgrsb_current_state = BGRSB_STATE_INIT; - return; + goto unlock; } dev->is_cnfgrd = true; dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED; pr_debug("Glink RSB Cofigured\n"); + + if (dev->pending_enable) + queue_work(dev->bgrsb_wq, &dev->rsb_up_work); } + +unlock: + mutex_unlock(&dev->rsb_state_mutex); } /** @@ -625,6 +647,8 @@ static int ssr_bgrsb_cb(struct notifier_block *this, switch (opcode) { case SUBSYS_BEFORE_SHUTDOWN: + if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) + dev->pending_enable = true; queue_work(dev->bgrsb_wq, &dev->bg_down_work); break; case SUBSYS_AFTER_POWERUP: @@ -669,8 +693,13 @@ static void bgrsb_enable_rsb(struct work_struct *work) rsb_up_work); mutex_lock(&dev->rsb_state_mutex); + if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) { + pr_debug("RSB is already enabled\n"); + goto unlock; + } if (dev->bgrsb_current_state != BGRSB_STATE_RSB_CONFIGURED) { pr_err("BG is not yet configured for RSB\n"); + dev->pending_enable = true; goto unlock; } @@ -685,6 +714,7 @@ static void bgrsb_enable_rsb(struct work_struct *work) } } dev->bgrsb_current_state = BGRSB_STATE_RSB_ENABLED; + dev->pending_enable = false; pr_debug("RSB Enabled\n"); if (dev->calibration_needed) { @@ -703,6 +733,7 @@ static void bgrsb_disable_rsb(struct work_struct *work) rsb_down_work); mutex_lock(&dev->rsb_state_mutex); + dev->pending_enable = false; if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) { rc = bgrsb_enable(dev, false); @@ -730,9 +761,11 @@ static void bgrsb_calibration(struct work_struct *work) container_of(work, struct bgrsb_priv, rsb_calibration_work); + mutex_lock(&dev->rsb_state_mutex); + if (!dev->is_cnfgrd) { pr_err("RSB is not configured\n"); - return; + goto unlock; } req.cmd_id = 0x03; @@ -741,7 +774,7 @@ static void bgrsb_calibration(struct work_struct *work) rc = bgrsb_tx_msg(dev, &req, 5); if (rc != 0) { pr_err("Failed to send resolution value to BG\n"); - return; + goto unlock; } req.cmd_id = 0x04; @@ -750,10 +783,13 @@ static void bgrsb_calibration(struct work_struct *work) rc = bgrsb_tx_msg(dev, &req, 5); if (rc != 0) { pr_err("Failed to send interval value to BG\n"); - return; + goto unlock; } dev->is_calibrd = true; pr_debug("RSB Calibbered\n"); + +unlock: + mutex_unlock(&dev->rsb_state_mutex); } static void bgrsb_buttn_configration(struct work_struct *work) @@ -764,9 +800,10 @@ static void bgrsb_buttn_configration(struct work_struct *work) container_of(work, struct bgrsb_priv, bttn_configr_work); + mutex_lock(&dev->rsb_state_mutex); if (!dev->is_cnfgrd) { pr_err("RSB is not configured\n"); - return; + goto unlock; } req.cmd_id = 0x05; @@ -775,11 +812,36 @@ static void bgrsb_buttn_configration(struct work_struct *work) rc = bgrsb_tx_msg(dev, &req, 5); if (rc != 0) { pr_err("Failed to send button configuration cmnd to BG\n"); - return; + goto unlock; } dev->bttn_configs = 0; pr_debug("Button configured\n"); + +unlock: + mutex_unlock(&dev->rsb_state_mutex); +} + +static int bgrsb_handle_cmd_in_ssr(struct bgrsb_priv *dev, char *str) +{ + long val; + int ret; + char *tmp; + + tmp = strsep(&str, ":"); + if (!tmp) + return -EINVAL; + + ret = kstrtol(tmp, 10, &val); + if (ret < 0) + return ret; + + if (val == BGRSB_POWER_ENABLE) + dev->pending_enable = true; + else if (val == BGRSB_POWER_DISABLE) + dev->pending_enable = false; + + return 0; } static int split_bg_work(struct bgrsb_priv *dev, char *str) @@ -868,6 +930,7 @@ static int store_enable(struct device *pdev, struct device_attribute *attr, } if (!dev->is_cnfgrd) { + bgrsb_handle_cmd_in_ssr(dev, arr); kfree(arr); return -ENOMEDIUM; } @@ -875,6 +938,7 @@ static int store_enable(struct device *pdev, struct device_attribute *attr, rc = split_bg_work(dev, arr); if (rc != 0) pr_err("Not able to process request\n"); + kfree(arr); return count; } diff --git a/drivers/soc/qcom/bgcom_spi.c b/drivers/soc/qcom/bgcom_spi.c index 8ef2c06cb80b..7e58fb7e9cc4 100644 --- a/drivers/soc/qcom/bgcom_spi.c +++ b/drivers/soc/qcom/bgcom_spi.c @@ -1078,7 +1078,6 @@ static int bgcom_pm_suspend(struct device *dev) if (ret == 0) { bg_spi->bg_state = BGCOM_STATE_SUSPEND; atomic_set(&bg_is_spi_active, 0); - disable_irq(bg_irq); } pr_info("suspended with : %d\n", ret); return ret; @@ -1094,8 +1093,6 @@ static int bgcom_pm_resume(struct device *dev) clnt_handle.bg_spi = spi; atomic_set(&bg_is_spi_active, 1); ret = bgcom_resume(&clnt_handle); - if (ret == 0) - enable_irq(bg_irq); pr_info("Bgcom resumed with : %d\n", ret); return ret; } diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 469125717eb5..f7bd0d922ae0 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -1402,7 +1402,7 @@ static int wlfw_msa_mem_info_send_sync_msg(void) for (i = 0; i < resp.mem_region_info_len; i++) { if (resp.mem_region_info[i].size > penv->msa_mem_size || - resp.mem_region_info[i].region_addr > max_mapped_addr || + resp.mem_region_info[i].region_addr >= max_mapped_addr || resp.mem_region_info[i].region_addr < penv->msa_pa || resp.mem_region_info[i].size + resp.mem_region_info[i].region_addr > max_mapped_addr) { diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index 4f3c264e1bf0..aed5ab4fb623 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -908,6 +908,7 @@ int send_single(struct rpmh_client *rc, enum rpmh_state state, u32 addr, */ int rpmh_flush(struct rpmh_client *rc) { + DEFINE_RPMH_MSG_ONSTACK(rc, 0, NULL, NULL, rpm_msg); struct rpmh_req *p; struct rpmh_mbox *rpm = rc->rpmh; int ret; @@ -930,6 +931,13 @@ int rpmh_flush(struct rpmh_client *rc) } spin_unlock_irqrestore(&rpm->lock, flags); + /* Invalidate sleep and wake TCS */ + rpm_msg.msg.invalidate = true; + rpm_msg.msg.is_complete = false; + ret = mbox_write_controller_data(rc->chan, &rpm_msg.msg); + if (ret) + return ret; + /* First flush the cached passthru's */ ret = flush_passthru(rc); if (ret) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index c9489e3e97a8..e82b6ef1cfe7 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -643,6 +643,9 @@ static struct msm_soc_info cpu_of_id[] = { /* QM215 ID */ [386] = {MSM_CPU_QM215, "QM215"}, + /* QCM2150 ID */ + [436] = {MSM_CPU_QCM2150, "QCM2150"}, + /* SDM429W IDs*/ [416] = {MSM_CPU_SDM429W, "SDM429W"}, /* Uninitialized IDs are not known to run Linux. @@ -1644,6 +1647,10 @@ static void * __init setup_dummy_socinfo(void) dummy_socinfo.id = 386; strlcpy(dummy_socinfo.build_id, "qm215 - ", sizeof(dummy_socinfo.build_id)); + } else if (early_machine_is_qcm2150()) { + dummy_socinfo.id = 436; + strlcpy(dummy_socinfo.build_id, "qcm2150 - ", + sizeof(dummy_socinfo.build_id)); } strlcat(dummy_socinfo.build_id, "Dummy socinfo", diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 83df7508024e..b9a560bfc7bf 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -324,7 +324,7 @@ struct dwc3_msm { u64 dummy_gsi_db; dma_addr_t dummy_gsi_db_dma; - u64 dummy_gevntcnt; + u64 *dummy_gevntcnt; dma_addr_t dummy_gevntcnt_dma; }; @@ -931,7 +931,7 @@ static void gsi_get_channel_info(struct usb_ep *ep, ch_info->gevntcount_hi_addr = (u32)((u64)mdwc->dummy_gevntcnt_dma >> 32); dev_dbg(dwc->dev, "Dummy GEVNTCNT Addr %pK: %llx %x (LSB)\n", - &mdwc->dummy_gevntcnt, + mdwc->dummy_gevntcnt, (unsigned long long)mdwc->dummy_gevntcnt_dma, (u32)mdwc->dummy_gevntcnt_dma); } @@ -2159,14 +2159,14 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, * Set-up dummy GEVNTCOUNT address to be passed on to GSI for * normal (non HW-accelerated) EPs. */ - mdwc->dummy_gevntcnt_dma = dma_map_single(dwc->sysdev, - &mdwc->dummy_gevntcnt, - sizeof(mdwc->dummy_gevntcnt), - DMA_FROM_DEVICE); - if (dma_mapping_error(dwc->sysdev, mdwc->dummy_gevntcnt_dma)) { - dev_err(dwc->dev, "failed to map dummy geventcount\n"); + mdwc->dummy_gevntcnt = + kzalloc(sizeof(*mdwc->dummy_gevntcnt), GFP_KERNEL); + if (!mdwc->dummy_gevntcnt) { mdwc->dummy_gevntcnt_dma = (dma_addr_t)NULL; + break; } + + mdwc->dummy_gevntcnt_dma = virt_to_phys(mdwc->dummy_gevntcnt); break; case DWC3_GSI_EVT_BUF_SETUP: dev_dbg(mdwc->dev, "DWC3_GSI_EVT_BUF_SETUP\n"); @@ -2241,10 +2241,8 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, evt->buf, evt->dma); } if (mdwc->dummy_gevntcnt_dma) { - dma_unmap_single(dwc->sysdev, mdwc->dummy_gevntcnt_dma, - sizeof(mdwc->dummy_gevntcnt), - DMA_FROM_DEVICE); mdwc->dummy_gevntcnt_dma = (dma_addr_t)NULL; + kfree(mdwc->dummy_gevntcnt); } if (mdwc->dummy_gsi_db_dma) { dma_unmap_single(dwc->sysdev, mdwc->dummy_gsi_db_dma, diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index c0c8a88fcc1c..f7903ad7309c 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2018, Linux Foundation. All rights reserved. +/* Copyright (c) 2009-2019, 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 @@ -879,6 +879,8 @@ static void msm_usb_phy_reset(struct msm_otg *motg) mb(); } +static void msm_chg_block_on(struct msm_otg *); + static int msm_otg_reset(struct usb_phy *phy) { struct msm_otg *motg = container_of(phy, struct msm_otg, phy); @@ -977,6 +979,9 @@ static int msm_otg_reset(struct usb_phy *phy) */ msm_usb_bam_enable(CI_CTRL, false); + if (phy->otg->state == OTG_STATE_UNDEFINED && motg->rm_pulldown) + msm_chg_block_on(motg); + return 0; } @@ -2458,6 +2463,7 @@ static void msm_chg_block_on(struct msm_otg *motg) u32 func_ctrl; /* put the controller in non-driving mode */ + msm_otg_dbg_log_event(&motg->phy, "PHY NON DRIVE", 0, 0); func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; @@ -2487,12 +2493,36 @@ static void msm_chg_block_off(struct msm_otg *motg) ulpi_write(phy, 0x6, 0xB); /* put the controller in normal mode */ + msm_otg_dbg_log_event(&motg->phy, "PHY MODE NORMAL", 0, 0); func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NORMAL; ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL); } +static void msm_otg_set_mode_nondriving(struct msm_otg *motg, + bool mode_nondriving) +{ + clk_prepare_enable(motg->xo_clk); + clk_prepare_enable(motg->phy_csr_clk); + clk_prepare_enable(motg->core_clk); + clk_prepare_enable(motg->pclk); + + msm_otg_exit_phy_retention(motg); + + if (mode_nondriving) + msm_chg_block_on(motg); + else + msm_chg_block_off(motg); + + msm_otg_enter_phy_retention(motg); + + clk_disable_unprepare(motg->pclk); + clk_disable_unprepare(motg->core_clk); + clk_disable_unprepare(motg->phy_csr_clk); + clk_disable_unprepare(motg->xo_clk); +} + #define MSM_CHG_DCD_TIMEOUT (750 * HZ/1000) /* 750 msec */ #define MSM_CHG_DCD_POLL_TIME (50 * HZ/1000) /* 50 msec */ #define MSM_CHG_PRIMARY_DET_TIME (50 * HZ/1000) /* TVDPSRC_ON */ @@ -3320,6 +3350,8 @@ static int msm_otg_dpdm_regulator_enable(struct regulator_dev *rdev) } } + msm_otg_set_mode_nondriving(motg, true); + return ret; } @@ -3328,6 +3360,8 @@ static int msm_otg_dpdm_regulator_disable(struct regulator_dev *rdev) int ret = 0; struct msm_otg *motg = rdev_get_drvdata(rdev); + msm_otg_set_mode_nondriving(motg, false); + if (motg->rm_pulldown) { ret = msm_hsusb_ldo_enable(motg, USB_PHY_REG_3P3_OFF); if (!ret) { diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index 7eb8c708d0f9..19de5dabdd3d 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 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 @@ -662,6 +662,12 @@ static int mdss_dsi_set_col_page_addr(struct mdss_panel_data *pdata, return 0; } + if (pinfo->partial_update_col_addr_offset) + roi.x += pinfo->partial_update_col_addr_offset; + + if (pinfo->partial_update_row_addr_offset) + roi.y += pinfo->partial_update_row_addr_offset; + if (pinfo->dcs_cmd_by_left) { if (left_or_both && ctrl->ndx == DSI_CTRL_RIGHT) { /* 2A/2B sent by left already */ @@ -2099,6 +2105,7 @@ error: static int mdss_dsi_parse_panel_features(struct device_node *np, struct mdss_dsi_ctrl_pdata *ctrl) { + u32 value[2]; struct mdss_panel_info *pinfo; if (!np || !ctrl) { @@ -2116,6 +2123,14 @@ static int mdss_dsi_parse_panel_features(struct device_node *np, pinfo->partial_update_enabled); ctrl->set_col_page_addr = mdss_dsi_set_col_page_addr; if (pinfo->partial_update_enabled) { + int rc = of_property_read_u32_array(np, + "qcom,partial-update-addr-offset", + value, 2); + pinfo->partial_update_col_addr_offset = + (!rc ? value[0] : 0); + pinfo->partial_update_row_addr_offset = + (!rc ? value[1] : 0); + pinfo->partial_update_roi_merge = of_property_read_bool(np, "qcom,partial-update-roi-merge"); diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index be6d44f0196a..0fa242eb1122 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2019, 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 @@ -690,6 +690,8 @@ struct mdss_panel_info { bool esd_rdy; bool partial_update_supported; /* value from dts if pu is supported */ bool partial_update_enabled; /* is pu currently allowed */ + u32 partial_update_col_addr_offset; /* panel column addr offset */ + u32 partial_update_row_addr_offset; /* panel row addr offset */ u32 dcs_cmd_by_left; u32 partial_update_roi_merge; struct ion_handle *splash_ihdl; diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c index 837a3de08f65..9f38e7fe08d3 100755 --- a/fs/crypto/keyinfo.c +++ b/fs/crypto/keyinfo.c @@ -606,8 +606,6 @@ int fscrypt_get_encryption_info(struct inode *inode) if (res) goto out; - memzero_explicit(crypt_info->ci_raw_key, - sizeof(crypt_info->ci_raw_key)); do_ice: if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) == NULL) crypt_info = NULL; diff --git a/include/soc/qcom/socinfo.h b/include/soc/qcom/socinfo.h index f6fc1e0d5fea..855c13dc32bf 100644 --- a/include/soc/qcom/socinfo.h +++ b/include/soc/qcom/socinfo.h @@ -144,6 +144,8 @@ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,mdm9650") #define early_machine_is_qm215() \ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,qm215") +#define early_machine_is_qcm2150() \ + of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,qcm2150") #else #define of_board_is_sim() 0 #define of_board_is_rumi() 0 @@ -204,6 +206,7 @@ #define early_machine_is_sdm429w() 0 #define early_machine_is_mdm9650() 0 #define early_machine_is_qm215() 0 +#define early_machine_is_qcm2150() 0 #define early_machine_is_sdm712() 0 #endif @@ -289,6 +292,7 @@ enum msm_cpu { MSM_CPU_SDM429W, MSM_CPU_9650, MSM_CPU_QM215, + MSM_CPU_QCM2150, }; struct msm_soc_info { diff --git a/include/uapi/media/cam_defs.h b/include/uapi/media/cam_defs.h index e69fe7ab5f96..c0f2f2ed29ec 100644 --- a/include/uapi/media/cam_defs.h +++ b/include/uapi/media/cam_defs.h @@ -21,6 +21,7 @@ #define CAM_COMMON_OPCODE_BASE_v2 0x150 #define CAM_ACQUIRE_HW (CAM_COMMON_OPCODE_BASE_v2 + 0x1) #define CAM_RELEASE_HW (CAM_COMMON_OPCODE_BASE_v2 + 0x2) +#define CAM_DUMP_REQ (CAM_COMMON_OPCODE_BASE_v2 + 0x3) #define CAM_EXT_OPCODE_BASE 0x200 #define CAM_CONFIG_DEV_EXTERNAL (CAM_EXT_OPCODE_BASE + 0x1) @@ -207,6 +208,30 @@ struct cam_iommu_handle { #define CAM_PACKET_DEV_LRME 17 #define CAM_PACKET_DEV_MAX 18 +/** + * struct cam_dump_req_cmd - + * Dump the information of issue req id + * + * @issue_req_id : Issue Request Id + * @session_handle : Session Handle + * @link_hdl : link handle + * @dev_handle : Device Handle + * @error_type : Error Type + * @buf_handle : Buffer Handle + * @offset : offset for the buffer + * @reserved : Reserved + */ +struct cam_dump_req_cmd { + int64_t issue_req_id; + int32_t session_handle; + int32_t link_hdl; + int32_t dev_handle; + int32_t error_type; + uint32_t buf_handle; + int32_t offset; + uint32_t reserved; +}; + /* constants */ #define CAM_PACKET_MAX_PLANES 3 diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h index defed877b52d..4a479b09e455 100644 --- a/include/uapi/media/cam_req_mgr.h +++ b/include/uapi/media/cam_req_mgr.h @@ -247,6 +247,7 @@ struct cam_req_mgr_link_control { #define CAM_REQ_MGR_CACHE_OPS (CAM_COMMON_OPCODE_MAX + 12) #define CAM_REQ_MGR_LINK_CONTROL (CAM_COMMON_OPCODE_MAX + 13) #define CAM_REQ_MGR_LINK_V2 (CAM_COMMON_OPCODE_MAX + 14) +#define CAM_REQ_MGR_REQUEST_DUMP (CAM_COMMON_OPCODE_MAX + 15) /* end of cam_req_mgr opcodes */ #define CAM_MEM_FLAG_HW_READ_WRITE (1<<0) diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h index 0f64fcee4ccd..08c60d10747f 100644 --- a/lib/mpi/longlong.h +++ b/lib/mpi/longlong.h @@ -176,8 +176,8 @@ extern UDItype __udiv_qrnnd(UDItype *, UDItype, UDItype, UDItype); #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("adds %1, %4, %5\n" \ "adc %0, %2, %3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "%r" ((USItype)(al)), \ @@ -185,15 +185,15 @@ extern UDItype __udiv_qrnnd(UDItype *, UDItype, UDItype, UDItype); #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subs %1, %4, %5\n" \ "sbc %0, %2, %3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "r" ((USItype)(al)), \ "rI" ((USItype)(bl))) #if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__ #define umul_ppmm(xh, xl, a, b) \ - __asm__ ("%@ Inlined umul_ppmm\n" \ + __asm__ ("@ Inlined umul_ppmm\n" \ "mov %|r0, %2, lsr #16 @ AAAA\n" \ "mov %|r2, %3, lsr #16 @ BBBB\n" \ "bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \ @@ -206,19 +206,19 @@ extern UDItype __udiv_qrnnd(UDItype *, UDItype, UDItype, UDItype); "addcs %|r2, %|r2, #65536\n" \ "adds %1, %|r1, %|r0, lsl #16\n" \ "adc %0, %|r2, %|r0, lsr #16" \ - : "=&r" ((USItype)(xh)), \ - "=r" ((USItype)(xl)) \ + : "=&r" (xh), \ + "=r" (xl) \ : "r" ((USItype)(a)), \ "r" ((USItype)(b)) \ : "r0", "r1", "r2") #else #define umul_ppmm(xh, xl, a, b) \ - __asm__ ("%@ Inlined umul_ppmm\n" \ - "umull %r1, %r0, %r2, %r3" \ - : "=&r" ((USItype)(xh)), \ - "=&r" ((USItype)(xl)) \ + __asm__ ("@ Inlined umul_ppmm\n" \ + "umull %1, %0, %2, %3" \ + : "=&r" (xh), \ + "=&r" (xl) \ : "r" ((USItype)(a)), \ - "r" ((USItype)(b)) \ + "r" ((USItype)(b)) \ : "r0", "r1") #endif #define UMUL_TIME 20 diff --git a/mm/memblock.c b/mm/memblock.c index 3b7d23cdbaee..abaed7ae1597 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -929,7 +929,7 @@ void __init_memblock __next_mem_range(u64 *idx, int nid, ulong flags, r = &type_b->regions[idx_b]; r_start = idx_b ? r[-1].base + r[-1].size : 0; r_end = idx_b < type_b->cnt ? - r->base : ULLONG_MAX; + r->base : (phys_addr_t)ULLONG_MAX; /* * if idx_b advanced past idx_a, @@ -1045,7 +1045,7 @@ void __init_memblock __next_mem_range_rev(u64 *idx, int nid, ulong flags, r = &type_b->regions[idx_b]; r_start = idx_b ? r[-1].base + r[-1].size : 0; r_end = idx_b < type_b->cnt ? - r->base : ULLONG_MAX; + r->base : (phys_addr_t)ULLONG_MAX; /* * if idx_b advanced past idx_a, * break out to advance idx_a |