Merge "drm/msm/sde: signal retire fence at ctl start timeout"
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
index 7454863..240bc5b 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
@@ -384,6 +384,9 @@
--> 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 2c2319f..934335f 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/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi
index 70dc3ae..c1bf404 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi
@@ -391,7 +391,7 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <100>;
- gpio = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+ gpio = <&tlmm 83 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -401,7 +401,7 @@
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;
regulator-enable-ramp-delay = <100>;
- gpio = <&tlmm 83 GPIO_ACTIVE_HIGH>;
+ gpio = <&tlmm 96 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index c744253..7571661 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -1389,6 +1389,7 @@
"eth_rgmii_clk", "eth_slave_ahb_clk";
qcom,phy-intr-redirect = <&tlmm 84 GPIO_ACTIVE_LOW>;
qcom,phy-reset = <&tlmm 85 GPIO_ACTIVE_LOW>;
+ qcom,phy-reset-delay-msecs = <10>;
vreg_rgmii-supply = <&vreg_rgmii>;
vreg_emac_phy-supply = <&vreg_emac_phy>;
vreg_rgmii_io_pads-supply = <&vreg_rgmii_io_pads>;
diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig
index 5c68a44..8e386d3 100755
--- a/arch/arm/configs/msm8909-perf_defconfig
+++ b/arch/arm/configs/msm8909-perf_defconfig
@@ -331,6 +331,11 @@
CONFIG_MSM_ISPIF=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
+CONFIG_FB_MSM=y
+CONFIG_FB_MSM_MDSS=y
+CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS=y
+CONFIG_FB_MSM_MDSS_MDP3=y
+CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_SOUND=y
@@ -382,7 +387,6 @@
CONFIG_RTC_DRV_QPNP=y
CONFIG_DMADEVICES=y
CONFIG_QCOM_SPS_DMA=y
-CONFIG_SYNC_FILE=y
CONFIG_UIO=y
CONFIG_UIO_MSM_SHAREDMEM=y
CONFIG_STAGING=y
@@ -394,6 +398,7 @@
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_QPNP_REVID=y
CONFIG_USB_BAM=y
+CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig
old mode 100755
new mode 100644
index 575cf5e..5f69894
--- a/arch/arm/configs/msm8909_defconfig
+++ b/arch/arm/configs/msm8909_defconfig
@@ -355,6 +355,11 @@
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
CONFIG_FB_VIRTUAL=y
+CONFIG_FB_MSM=y
+CONFIG_FB_MSM_MDSS=y
+CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS=y
+CONFIG_FB_MSM_MDSS_MDP3=y
+CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_LOGO=y
@@ -422,7 +427,6 @@
CONFIG_RTC_DRV_QPNP=y
CONFIG_DMADEVICES=y
CONFIG_QCOM_SPS_DMA=y
-CONFIG_SYNC_FILE=y
CONFIG_UIO=y
CONFIG_UIO_MSM_SHAREDMEM=y
CONFIG_STAGING=y
@@ -436,6 +440,7 @@
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_QPNP_REVID=y
CONFIG_USB_BAM=y
+CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
index 8efa0c5..103ef7f 100644
--- a/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
+++ b/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-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
@@ -19,6 +19,7 @@
#include "apq8009-audio-external_codec.dtsi"
#include "msm8909-pm8916-camera.dtsi"
#include "msm8909-pm8916-camera-sensor-robot-som.dtsi"
+#include "dsi-panel-osd-disp-fwvga-video.dtsi"
/ {
model = "Qualcomm Technologies, Inc. APQ8009 Robot SOM refboard";
@@ -192,10 +193,6 @@
vin-supply = <&otg_vreg_5p0>;
};
- mdss_mdp: qcom,mdss_mdp@1a00000 {
- status = "disabled";
- };
-
bluetooth: bt_qca9379 {
compatible = "qca,qca9379";
qca,bt-reset-gpio = <&msm_gpio 47 0>; /* BT_EN */
@@ -372,3 +369,70 @@
&ext_codec {
status = "okay";
};
+
+&rpm_bus {
+ rpm-regulator-ldoa4 {
+ status = "okay";
+ pm8916_l4: regulator-l4 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ qcom,init-voltage = <2050000>;
+ regulator-always-on;
+ status = "okay";
+ };
+ };
+};
+
+&mdss_dsi0_pll {
+ status = "okay";
+};
+
+&mdss_mdp {
+ qcom,mdss-pref-prim-intf = "dsi";
+ status = "okay";
+};
+
+&dsi_osd_disp_fwvga_video {
+ qcom,mdss-dsi-pwm-gpio = <&pm8916_mpps 4 0>;
+};
+
+&pmx_mdss {
+ mdss_dsi_active: mdss_dsi_active {
+ mux {
+ pins = "gpio28", "gpio37";
+ };
+ };
+
+ mdss_dsi_suspend: mdss_dsi_suspend {
+ mux {
+ pins = "gpio28", "gpio37";
+ };
+ };
+};
+
+&mdss_dsi0 {
+ qcom,dsi-pref-prim-pan = <&dsi_osd_disp_fwvga_video>;
+
+ pinctrl-names = "mdss_default", "mdss_sleep";
+ pinctrl-0 = <&mdss_dsi_active &mdss_dsi_select_gpio>;
+ pinctrl-1 = <&mdss_dsi_suspend &mdss_dsi_select_gpio>;
+
+ qcom,platform-reset-gpio = <&msm_gpio 28 0>;
+ qcom,platform-bklight-en-gpio = <&msm_gpio 37 0>;
+
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l6>;
+ status = "okay";
+};
+
+&pm8916_mpps {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ext_fep_wled_pwr_en_default>;
+ ext_fep_wled_pwr_en_default: ext_fep_wled_pwr_en_default {
+ pins = "mpp4"; /* MPP_4 */
+ function = "digital"; /* Digital */
+ output-high; /* Output */
+ power-source = <1>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-osd-disp-fwvga-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-osd-disp-fwvga-video.dtsi
index 0967a50..5692a69 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-osd-disp-fwvga-video.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-osd-disp-fwvga-video.dtsi
@@ -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
@@ -28,7 +28,7 @@
qcom,mdss-dsi-h-sync-skew = <0>;
qcom,mdss-dsi-v-back-porch = <10>;
qcom,mdss-dsi-v-front-porch = <10>;
- qcom,mdss-dsi-v-pulse-width = <20>;
+ qcom,mdss-dsi-v-pulse-width = <5>;
qcom,mdss-dsi-h-left-border = <0>;
qcom,mdss-dsi-h-right-border = <0>;
qcom,mdss-dsi-v-top-border = <0>;
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 9c0ffc5..4d74933 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/msm8909-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi
index 656385d..f7746c1 100644
--- a/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi
@@ -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
@@ -289,7 +289,7 @@
};
};
- pmx_mdss {
+ pmx_mdss: pmx_mdss {
mdss_dsi_active: mdss_dsi_active {
mux {
pins = "gpio25", "gpio37";
@@ -343,6 +343,20 @@
};
};
+ mdss_dsi_select_gpio: mdss_dsi_select_gpio {
+ mux {
+ pins = "gpio70";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio70";
+ drive-strength = <8>;
+ bias-pull-down;
+ output-low;
+ };
+ };
+
spi0 {
spi0_default: spi0_default {
mux {
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 3fecf16..57cd8f0 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/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index b095b027..bff977d 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 @@
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 @@
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 @@
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 @@
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 @@
!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 @@
}
/*
- * 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 @@
}
/*
- * 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 a4dc901..8e0c321 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 @@
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.c b/drivers/gpu/msm/kgsl.c
index 2b83d44..66102af 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -3337,12 +3337,16 @@
unsigned int cmd, void *data)
{
struct kgsl_process_private *process = dev_priv->process_priv;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_sparse_phys_alloc *param = data;
struct kgsl_mem_entry *entry;
uint64_t flags;
int ret;
int id;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
ret = _sparse_alloc_param_sanity_check(param->size, param->pagesize);
if (ret)
return ret;
@@ -3422,9 +3426,13 @@
unsigned int cmd, void *data)
{
struct kgsl_process_private *process = dev_priv->process_priv;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_sparse_phys_free *param = data;
struct kgsl_mem_entry *entry;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
entry = kgsl_sharedmem_find_id_flags(process, param->id,
KGSL_MEMFLAGS_SPARSE_PHYS);
if (entry == NULL)
@@ -3454,10 +3462,14 @@
unsigned int cmd, void *data)
{
struct kgsl_process_private *private = dev_priv->process_priv;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_sparse_virt_alloc *param = data;
struct kgsl_mem_entry *entry;
int ret;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
ret = _sparse_alloc_param_sanity_check(param->size, param->pagesize);
if (ret)
return ret;
@@ -3498,9 +3510,13 @@
unsigned int cmd, void *data)
{
struct kgsl_process_private *process = dev_priv->process_priv;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_sparse_virt_free *param = data;
struct kgsl_mem_entry *entry = NULL;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
entry = kgsl_sharedmem_find_id_flags(process, param->id,
KGSL_MEMFLAGS_SPARSE_VIRT);
if (entry == NULL)
@@ -3847,6 +3863,7 @@
unsigned int cmd, void *data)
{
struct kgsl_process_private *private = dev_priv->process_priv;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_sparse_bind *param = data;
struct kgsl_sparse_binding_object obj;
struct kgsl_mem_entry *virt_entry;
@@ -3855,6 +3872,9 @@
int ret = 0;
int i = 0;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
ptr = (void __user *) (uintptr_t) param->list;
if (param->size > sizeof(struct kgsl_sparse_binding_object) ||
@@ -3910,6 +3930,9 @@
long result;
unsigned int i = 0;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
/* Make sure sparse and syncpoint count isn't too big */
if (param->numsparse > KGSL_MAX_SPARSE ||
param->numsyncs > KGSL_MAX_SYNCPOINTS)
@@ -4665,6 +4688,9 @@
/* Initialize logging first, so that failures below actually print. */
kgsl_device_debugfs_init(device);
+ /* Disable the sparse ioctl invocation as they are not used */
+ device->flags &= ~KGSL_FLAG_SPARSE;
+
status = kgsl_pwrctrl_init(device);
if (status)
goto error;
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 1fa2717..b9f5017 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 @@
#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_device.h b/drivers/gpu/msm/kgsl_device.h
index 6ae38a3..229e206 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.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
@@ -66,6 +66,7 @@
};
#define KGSL_FLAG_WAKE_ON_TOUCH BIT(0)
+#define KGSL_FLAG_SPARSE BIT(1)
/*
* "list" of event types for ftrace symbolic magic
diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c
index 40b49c3..1bfc905 100644
--- a/drivers/gpu/msm/kgsl_drawobj.c
+++ b/drivers/gpu/msm/kgsl_drawobj.c
@@ -598,13 +598,29 @@
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 87e1431..d023170 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 @@
*
* 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 @@
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 @@
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_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;
- memdesc->gpuaddr = KGSL_IOMMU_GLOBAL_MEM_BASE(mmu) + global_pt_alloc;
+ if (WARN_ON(size > KGSL_IOMMU_GLOBAL_MEM_SIZE))
+ return;
+
+ 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/hid/hid-core.c b/drivers/hid/hid-core.c
index d030731..81efba5 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -200,14 +200,13 @@
* Add a usage to the temporary parser table.
*/
-static int hid_add_usage(struct hid_parser *parser, unsigned usage, u8 size)
+static int hid_add_usage(struct hid_parser *parser, unsigned usage)
{
if (parser->local.usage_index >= HID_MAX_USAGES) {
hid_err(parser->device, "usage index exceeded\n");
return -1;
}
parser->local.usage[parser->local.usage_index] = usage;
- parser->local.usage_size[parser->local.usage_index] = size;
parser->local.collection_index[parser->local.usage_index] =
parser->collection_stack_ptr ?
parser->collection_stack[parser->collection_stack_ptr - 1] : 0;
@@ -464,7 +463,10 @@
return 0;
}
- return hid_add_usage(parser, data, item->size);
+ if (item->size <= 2)
+ data = (parser->global.usage_page << 16) + data;
+
+ return hid_add_usage(parser, data);
case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
@@ -473,6 +475,9 @@
return 0;
}
+ if (item->size <= 2)
+ data = (parser->global.usage_page << 16) + data;
+
parser->local.usage_minimum = data;
return 0;
@@ -483,6 +488,9 @@
return 0;
}
+ if (item->size <= 2)
+ data = (parser->global.usage_page << 16) + data;
+
count = data - parser->local.usage_minimum;
if (count + parser->local.usage_index >= HID_MAX_USAGES) {
/*
@@ -502,7 +510,7 @@
}
for (n = parser->local.usage_minimum; n <= data; n++)
- if (hid_add_usage(parser, n, item->size)) {
+ if (hid_add_usage(parser, n)) {
dbg_hid("hid_add_usage failed\n");
return -1;
}
@@ -517,22 +525,6 @@
}
/*
- * Concatenate Usage Pages into Usages where relevant:
- * As per specification, 6.2.2.8: "When the parser encounters a main item it
- * concatenates the last declared Usage Page with a Usage to form a complete
- * usage value."
- */
-
-static void hid_concatenate_usage_page(struct hid_parser *parser)
-{
- int i;
-
- for (i = 0; i < parser->local.usage_index; i++)
- if (parser->local.usage_size[i] <= 2)
- parser->local.usage[i] += parser->global.usage_page << 16;
-}
-
-/*
* Process a main item.
*/
@@ -541,8 +533,6 @@
__u32 data;
int ret;
- hid_concatenate_usage_page(parser);
-
data = item_udata(item);
switch (item->tag) {
@@ -756,8 +746,6 @@
__u32 data;
int i;
- hid_concatenate_usage_page(parser);
-
data = item_udata(item);
switch (item->tag) {
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 42f5a84..1f19f58 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 @@
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 @@
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 2d8c6e0..84a190a 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 @@
* @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_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 @@
* @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_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 @@
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_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 11bad5d..d7500a1 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 @@
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 e1809b2..022641f 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_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 2afdafb0..19e3230 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 @@
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 @@
* @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 @@
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 2578fb9..322b7e6 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 @@
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 @@
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 @@
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 @@
}
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 b2994d5..4d10ea6 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 @@
}
+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 94f26de..679b2cf 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 @@
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 @@
*/
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 31607ac..5d4d9fc 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 @@
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 934bc76..3327418 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_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 @@
* @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_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 @@
* @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 @@
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 @@
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 bba12cf..fd113ae 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 @@
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 47d441f..136eaf0 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 @@
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 8a76b64..7c5321f 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -2676,7 +2676,8 @@
if (!IS_ERR_OR_NULL(data->client.ihandle)) {
ion_unmap_kernel(qseecom.ion_clnt, data->client.ihandle);
ion_free(qseecom.ion_clnt, data->client.ihandle);
- data->client.ihandle = NULL;
+ memset((void *)&data->client,
+ 0, sizeof(struct qseecom_client_handle));
}
return ret;
}
@@ -3434,6 +3435,33 @@
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 +3821,8 @@
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 0d9b6f0..e7a3946 100644
--- a/drivers/nfc/nq-nci.c
+++ b/drivers/nfc/nq-nci.c
@@ -150,6 +150,15 @@
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 @@
{
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 @@
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 @@
}
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 @@
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 @@
"%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 @@
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 87715c2..d17897d 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 @@
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 06833ef..4b7a1d8 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 @@
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 @@
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 05fb9ab..c35e385 100644
--- a/drivers/soc/qcom/bg_rsb.c
+++ b/drivers/soc/qcom/bg_rsb.c
@@ -139,6 +139,7 @@
bool is_cnfgrd;
bool blk_rsb_cmnds;
+ bool pending_enable;
};
static void *bgrsb_drv;
@@ -406,6 +407,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
if (!dev->is_cnfgrd) {
+ bgrsb_handle_cmd_in_ssr(dev, arr);
kfree(arr);
return -ENOMEDIUM;
}
@@ -875,6 +938,7 @@
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/icnss.c b/drivers/soc/qcom/icnss.c
index 4691257..f7bd0d9 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -1402,7 +1402,7 @@
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 4f3c264..aed5ab4 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 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 @@
}
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/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 83df750..b9a560b 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -324,7 +324,7 @@
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 @@
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 @@
* 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 @@
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/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index 0c71938..53f9bea 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -857,6 +857,8 @@
dev_err(dev, "failed to map buffer\n");
return -EFAULT;
}
+
+ req->dma_mapped = 1;
}
return 0;
@@ -881,9 +883,10 @@
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->num_mapped_sgs = 0;
- } else if (req->dma != DMA_ERROR_CODE) {
+ } else if (req->dma_mapped) {
dma_unmap_single(dev, req->dma, req->length,
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ req->dma_mapped = 0;
}
}
EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev);
diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c
index 7eb8c70..4f8015d 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
@@ -46,6 +46,7 @@
if (ctrl->pwm_bl == NULL || IS_ERR(ctrl->pwm_bl)) {
pr_err("%s: Error: lpg_chan=%d pwm request failed",
__func__, ctrl->pwm_lpg_chan);
+ ctrl->pwm_bl = NULL;
}
ctrl->pwm_enabled = 0;
}
@@ -662,6 +663,12 @@
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 +2106,7 @@
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 +2124,14 @@
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 be6d44f..0fa242e 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 @@
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/include/linux/diagchar.h b/include/linux/diagchar.h
index d33071c..e04e291 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -148,7 +148,7 @@
* a new RANGE of SSIDs to the msg_mask_tbl.
*/
#define MSG_MASK_TBL_CNT 26
-#define APPS_EVENT_LAST_ID 0xCAA
+#define APPS_EVENT_LAST_ID 0xCB4
#define MSG_SSID_0 0
#define MSG_SSID_0_LAST 130
@@ -922,7 +922,7 @@
/* LOG CODES */
static const uint32_t log_code_last_tbl[] = {
0x0, /* EQUIP ID 0 */
- 0x1C9A, /* EQUIP ID 1 */
+ 0x1CB2, /* EQUIP ID 1 */
0x0, /* EQUIP ID 2 */
0x0, /* EQUIP ID 3 */
0x4910, /* EQUIP ID 4 */
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 04bdf54..fab65b6 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -374,7 +374,6 @@
struct hid_local {
unsigned usage[HID_MAX_USAGES]; /* usage array */
- u8 usage_size[HID_MAX_USAGES]; /* usage size array */
unsigned collection_index[HID_MAX_USAGES]; /* collection index array */
unsigned usage_index;
unsigned usage_minimum;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 418978e..3aad8b5 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -148,6 +148,7 @@
* by adding a zero length packet as needed;
* @short_not_ok: When reading data, makes short packets be
* treated as errors (queue stops advancing till cleanup).
+ * @dma_mapped: Indicates if request has been mapped to DMA (internal)
* @complete: Function called when request completes, so this request and
* its buffer may be re-used. The function will always be called with
* interrupts disabled, and it must not sleep.
@@ -204,6 +205,7 @@
unsigned no_interrupt:1;
unsigned zero:1;
unsigned short_not_ok:1;
+ unsigned dma_mapped:1;
void (*complete)(struct usb_ep *ep,
struct usb_request *req);
diff --git a/include/uapi/media/cam_defs.h b/include/uapi/media/cam_defs.h
index e69fe7a..c0f2f2e 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 @@
#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 defed87..4a479b0 100644
--- a/include/uapi/media/cam_req_mgr.h
+++ b/include/uapi/media/cam_req_mgr.h
@@ -247,6 +247,7 @@
#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 0f64fce..08c60d1 100644
--- a/lib/mpi/longlong.h
+++ b/lib/mpi/longlong.h
@@ -176,8 +176,8 @@
#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 @@
#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 @@
"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